Skip to content

Commit c9f97ee

Browse files
boldtrnPeter
authored and
Peter
committed
Implemented conditional parsing if duration larger than 2 days, graphhopper#621 for graphhopper#374
1 parent 1053ab2 commit c9f97ee

18 files changed

+1163
-33
lines changed
Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
/*
2+
* Licensed to GraphHopper and Peter Karich under one or more contributor
3+
* license agreements. See the NOTICE file distributed with this work for
4+
* additional information regarding copyright ownership.
5+
*
6+
* GraphHopper licenses this file to you under the Apache License,
7+
* Version 2.0 (the "License"); you may not use this file except in
8+
* compliance with the License. You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing, software
13+
* distributed under the License is distributed on an "AS IS" BASIS,
14+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
* See the License for the specific language governing permissions and
16+
* limitations under the License.
17+
*/
18+
package com.graphhopper.reader.osm;
19+
20+
import com.graphhopper.reader.OSMWay;
21+
import com.graphhopper.reader.osm.conditional.ConditionalParser;
22+
import com.graphhopper.reader.osm.conditional.DateRange;
23+
import org.slf4j.Logger;
24+
import org.slf4j.LoggerFactory;
25+
26+
import java.util.Calendar;
27+
import java.util.List;
28+
import java.util.Set;
29+
30+
/**
31+
* Inspects the conditional tags of an OSMWay according to the given conditional tags.
32+
* <p>
33+
* @author Robin Boldt
34+
*/
35+
public class ConditionalTagsInspector
36+
{
37+
38+
private static final Logger logger = LoggerFactory.getLogger(ConditionalTagsInspector.class);
39+
40+
private final Calendar calendar;
41+
private final List<String> tagsToCheck;
42+
private final ConditionalParser restrictiveParser;
43+
private final ConditionalParser permitParser;
44+
private final boolean enabledLogs = false;
45+
46+
/**
47+
* Create with todays date
48+
*/
49+
public ConditionalTagsInspector( List<String> tagsToCheck, Set<String> restrictiveValues, Set<String> permittedValues )
50+
{
51+
this(Calendar.getInstance(), tagsToCheck, restrictiveValues, permittedValues);
52+
}
53+
54+
/**
55+
* Create with given date
56+
*/
57+
public ConditionalTagsInspector( Calendar date, List<String> tagsToCheck, Set<String> restrictiveValues, Set<String> permittedValues )
58+
{
59+
this.calendar = date;
60+
this.tagsToCheck = tagsToCheck;
61+
this.restrictiveParser = new ConditionalParser(restrictiveValues, enabledLogs);
62+
this.permitParser = new ConditionalParser(permittedValues, enabledLogs);
63+
}
64+
65+
public boolean isRestrictedWayConditionallyPermitted( OSMWay way )
66+
{
67+
return applies(way, true);
68+
}
69+
70+
public boolean isPermittedWayConditionallyRestricted( OSMWay way )
71+
{
72+
return applies(way, false);
73+
}
74+
75+
protected boolean applies( OSMWay way, boolean checkPermissiveValues )
76+
{
77+
for (String tagToCheck : tagsToCheck)
78+
{
79+
tagToCheck = tagToCheck + ":conditional";
80+
String val = way.getTag(tagToCheck);
81+
if (val != null && !val.isEmpty())
82+
{
83+
try
84+
{
85+
DateRange dateRange;
86+
if (checkPermissiveValues)
87+
dateRange = permitParser.getDateRange(val);
88+
else
89+
dateRange = restrictiveParser.getDateRange(val);
90+
91+
if (dateRange != null && dateRange.isInRange(calendar))
92+
return true;
93+
} catch (Exception e)
94+
{
95+
if (enabledLogs)
96+
logger.warn("Could not parse the conditional value:" + val + " of tag:" + tagToCheck + ". Exception:" + e.getMessage());
97+
}
98+
}
99+
}
100+
return false;
101+
}
102+
}
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
/*
2+
* Licensed to GraphHopper and Peter Karich under one or more contributor
3+
* license agreements. See the NOTICE file distributed with this work for
4+
* additional information regarding copyright ownership.
5+
*
6+
* GraphHopper licenses this file to you under the Apache License,
7+
* Version 2.0 (the "License"); you may not use this file except in
8+
* compliance with the License. You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing, software
13+
* distributed under the License is distributed on an "AS IS" BASIS,
14+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
* See the License for the specific language governing permissions and
16+
* limitations under the License.
17+
*/
18+
package com.graphhopper.reader.osm.conditional;
19+
20+
import org.slf4j.Logger;
21+
import org.slf4j.LoggerFactory;
22+
23+
import java.text.ParseException;
24+
import java.util.Set;
25+
26+
/**
27+
* Parses a conditional tag according to
28+
* http://wiki.openstreetmap.org/wiki/Conditional_restrictions.
29+
* <p>
30+
* @author Robin Boldt
31+
*/
32+
public class ConditionalParser
33+
{
34+
35+
private final Set<String> restrictedTags;
36+
private static final Logger logger = LoggerFactory.getLogger(ConditionalParser.class);
37+
private final boolean enabledLogs;
38+
39+
public ConditionalParser( Set<String> restrictedTags )
40+
{
41+
this(restrictedTags, false);
42+
}
43+
44+
public ConditionalParser( Set<String> restrictedTags, boolean enabledLogs )
45+
{
46+
this.restrictedTags = restrictedTags;
47+
this.enabledLogs = enabledLogs;
48+
}
49+
50+
public DateRange getDateRange( String conditionalTag ) throws ParseException
51+
{
52+
53+
if (conditionalTag == null || conditionalTag.isEmpty() || !conditionalTag.contains("@"))
54+
return null;
55+
56+
if (conditionalTag.contains(";"))
57+
{
58+
// TODO #374
59+
if (enabledLogs)
60+
logger.warn("We do not support multiple conditions yet: " + conditionalTag);
61+
return null;
62+
}
63+
64+
String[] conditionalArr = conditionalTag.split("@");
65+
66+
if (conditionalArr.length != 2)
67+
throw new IllegalStateException("could not split this condition: " + conditionalTag);
68+
69+
String restrictiveValue = conditionalArr[0].trim();
70+
if (!restrictedTags.contains(restrictiveValue))
71+
return null;
72+
73+
String conditional = conditionalArr[1];
74+
conditional = conditional.replace('(', ' ');
75+
conditional = conditional.replace(')', ' ');
76+
conditional = conditional.trim();
77+
78+
return DateRangeParser.parseDateRange(conditional);
79+
}
80+
81+
}
Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
package com.graphhopper.reader.osm.conditional;
2+
3+
import java.util.Calendar;
4+
5+
/**
6+
* This class represents a date range and is able to determine if a given date is in that range.
7+
*
8+
* @author Robin Boldt
9+
*/
10+
public class DateRange
11+
{
12+
private Calendar from;
13+
private Calendar to;
14+
15+
// Do not compare years
16+
boolean yearless = false;
17+
18+
boolean dayOnly = false;
19+
20+
boolean reverse = false;
21+
22+
// TODO Gets to complex? Create Factory?
23+
public DateRange( ParsedCalendar from, ParsedCalendar to )
24+
{
25+
Calendar fromCal = from.parsedCalendar;
26+
Calendar toCal = to.parsedCalendar;
27+
28+
// This should never happen
29+
if (fromCal.get(Calendar.ERA) != fromCal.get(Calendar.ERA))
30+
{
31+
throw new IllegalArgumentException("Different ERAs are not allowed. From:" + from + " To:" + to);
32+
}
33+
34+
if (from.isYearless() && to.isYearless())
35+
{
36+
yearless = true;
37+
}
38+
39+
if (from.isDayOnly() && to.isDayOnly())
40+
{
41+
dayOnly = true;
42+
}
43+
44+
if (fromCal.after(toCal))
45+
{
46+
if (!yearless && !dayOnly)
47+
{
48+
throw new IllegalArgumentException("From after to makes no sense, except for isYearless and isDayOnly DateRanges. From:" + from + " To:" + to);
49+
} else
50+
{
51+
reverse = true;
52+
}
53+
}
54+
55+
this.from = from.getMin();
56+
this.to = to.getMax();
57+
58+
}
59+
60+
public boolean isInRange( Calendar date )
61+
{
62+
if (!yearless && !dayOnly)
63+
return date.after(from) && date.before(to);
64+
65+
if(dayOnly){
66+
if(reverse){
67+
return (from.get(Calendar.DAY_OF_WEEK) <= date.get(Calendar.DAY_OF_WEEK) || date.get(Calendar.DAY_OF_WEEK) <= to.get(Calendar.DAY_OF_WEEK));
68+
}else{
69+
return (from.get(Calendar.DAY_OF_WEEK) <= date.get(Calendar.DAY_OF_WEEK) && date.get(Calendar.DAY_OF_WEEK) <= to.get(Calendar.DAY_OF_WEEK));
70+
}
71+
}
72+
73+
if (reverse)
74+
return isInRangeYearlessReverse(date);
75+
else
76+
return isInRangeYearless(date);
77+
}
78+
79+
private boolean isInRangeYearless( Calendar date )
80+
{
81+
if (from.get(Calendar.MONTH) < date.get(Calendar.MONTH) && date.get(Calendar.MONTH) < to.get(Calendar.MONTH))
82+
return true;
83+
if (from.get(Calendar.MONTH) == date.get(Calendar.MONTH) && to.get(Calendar.MONTH) == date.get(Calendar.MONTH))
84+
{
85+
if (from.get(Calendar.DAY_OF_MONTH) <= date.get(Calendar.DAY_OF_MONTH) && date.get(Calendar.DAY_OF_MONTH) <= to.get(Calendar.DAY_OF_MONTH))
86+
return true;
87+
else
88+
return false;
89+
}
90+
if (from.get(Calendar.MONTH) == date.get(Calendar.MONTH))
91+
{
92+
if (from.get(Calendar.DAY_OF_MONTH) <= date.get(Calendar.DAY_OF_MONTH))
93+
return true;
94+
else
95+
return false;
96+
}
97+
if (to.get(Calendar.MONTH) == date.get(Calendar.MONTH))
98+
{
99+
if (date.get(Calendar.DAY_OF_MONTH) <= to.get(Calendar.DAY_OF_MONTH))
100+
return true;
101+
else
102+
return false;
103+
}
104+
return false;
105+
}
106+
107+
private boolean isInRangeYearlessReverse( Calendar date )
108+
{
109+
if (from.get(Calendar.MONTH) < date.get(Calendar.MONTH) || date.get(Calendar.MONTH) < to.get(Calendar.MONTH))
110+
return true;
111+
if (from.get(Calendar.MONTH) == date.get(Calendar.MONTH) && to.get(Calendar.MONTH) == date.get(Calendar.MONTH))
112+
{
113+
if (from.get(Calendar.DAY_OF_MONTH) < date.get(Calendar.DAY_OF_MONTH) || date.get(Calendar.DAY_OF_MONTH) < to.get(Calendar.DAY_OF_MONTH))
114+
return true;
115+
else
116+
return false;
117+
}
118+
if (from.get(Calendar.MONTH) == date.get(Calendar.MONTH))
119+
{
120+
if (from.get(Calendar.DAY_OF_MONTH) <= date.get(Calendar.DAY_OF_MONTH))
121+
return true;
122+
else
123+
return false;
124+
}
125+
if (to.get(Calendar.MONTH) == date.get(Calendar.MONTH))
126+
{
127+
if (date.get(Calendar.DAY_OF_MONTH) >= to.get(Calendar.DAY_OF_MONTH))
128+
return true;
129+
else
130+
return false;
131+
}
132+
return false;
133+
}
134+
135+
136+
}

0 commit comments

Comments
 (0)