diff --git a/core/src/main/java/com/graphhopper/reader/osm/ConditionalTagsInspector.java b/core/src/main/java/com/graphhopper/reader/osm/ConditionalTagsInspector.java new file mode 100644 index 00000000000..4c12a4bbbd4 --- /dev/null +++ b/core/src/main/java/com/graphhopper/reader/osm/ConditionalTagsInspector.java @@ -0,0 +1,102 @@ +/* + * Licensed to GraphHopper and Peter Karich under one or more contributor + * license agreements. See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + * + * GraphHopper licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.graphhopper.reader.osm; + +import com.graphhopper.reader.OSMWay; +import com.graphhopper.reader.osm.conditional.ConditionalParser; +import com.graphhopper.reader.osm.conditional.DateRange; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.Calendar; +import java.util.List; +import java.util.Set; + +/** + * Inspects the conditional tags of an OSMWay according to the given conditional tags. + *

+ * @author Robin Boldt + */ +public class ConditionalTagsInspector +{ + + private static final Logger logger = LoggerFactory.getLogger(ConditionalTagsInspector.class); + + private final Calendar calendar; + private final List tagsToCheck; + private final ConditionalParser restrictiveParser; + private final ConditionalParser permitParser; + private final boolean enabledLogs = false; + + /** + * Create with todays date + */ + public ConditionalTagsInspector( List tagsToCheck, Set restrictiveValues, Set permittedValues ) + { + this(Calendar.getInstance(), tagsToCheck, restrictiveValues, permittedValues); + } + + /** + * Create with given date + */ + public ConditionalTagsInspector( Calendar date, List tagsToCheck, Set restrictiveValues, Set permittedValues ) + { + this.calendar = date; + this.tagsToCheck = tagsToCheck; + this.restrictiveParser = new ConditionalParser(restrictiveValues, enabledLogs); + this.permitParser = new ConditionalParser(permittedValues, enabledLogs); + } + + public boolean isRestrictedWayConditionallyPermitted( OSMWay way ) + { + return applies(way, true); + } + + public boolean isPermittedWayConditionallyRestricted( OSMWay way ) + { + return applies(way, false); + } + + protected boolean applies( OSMWay way, boolean checkPermissiveValues ) + { + for (String tagToCheck : tagsToCheck) + { + tagToCheck = tagToCheck + ":conditional"; + String val = way.getTag(tagToCheck); + if (val != null && !val.isEmpty()) + { + try + { + DateRange dateRange; + if (checkPermissiveValues) + dateRange = permitParser.getDateRange(val); + else + dateRange = restrictiveParser.getDateRange(val); + + if (dateRange != null && dateRange.isInRange(calendar)) + return true; + } catch (Exception e) + { + if (enabledLogs) + logger.warn("Could not parse the conditional value:" + val + " of tag:" + tagToCheck + ". Exception:" + e.getMessage()); + } + } + } + return false; + } +} diff --git a/core/src/main/java/com/graphhopper/reader/osm/conditional/ConditionalParser.java b/core/src/main/java/com/graphhopper/reader/osm/conditional/ConditionalParser.java new file mode 100644 index 00000000000..67f518b51b5 --- /dev/null +++ b/core/src/main/java/com/graphhopper/reader/osm/conditional/ConditionalParser.java @@ -0,0 +1,81 @@ +/* + * Licensed to GraphHopper and Peter Karich under one or more contributor + * license agreements. See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + * + * GraphHopper licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.graphhopper.reader.osm.conditional; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.text.ParseException; +import java.util.Set; + +/** + * Parses a conditional tag according to + * http://wiki.openstreetmap.org/wiki/Conditional_restrictions. + *

+ * @author Robin Boldt + */ +public class ConditionalParser +{ + + private final Set restrictedTags; + private static final Logger logger = LoggerFactory.getLogger(ConditionalParser.class); + private final boolean enabledLogs; + + public ConditionalParser( Set restrictedTags ) + { + this(restrictedTags, false); + } + + public ConditionalParser( Set restrictedTags, boolean enabledLogs ) + { + this.restrictedTags = restrictedTags; + this.enabledLogs = enabledLogs; + } + + public DateRange getDateRange( String conditionalTag ) throws ParseException + { + + if (conditionalTag == null || conditionalTag.isEmpty() || !conditionalTag.contains("@")) + return null; + + if (conditionalTag.contains(";")) + { + // TODO #374 + if (enabledLogs) + logger.warn("We do not support multiple conditions yet: " + conditionalTag); + return null; + } + + String[] conditionalArr = conditionalTag.split("@"); + + if (conditionalArr.length != 2) + throw new IllegalStateException("could not split this condition: " + conditionalTag); + + String restrictiveValue = conditionalArr[0].trim(); + if (!restrictedTags.contains(restrictiveValue)) + return null; + + String conditional = conditionalArr[1]; + conditional = conditional.replace('(', ' '); + conditional = conditional.replace(')', ' '); + conditional = conditional.trim(); + + return DateRangeParser.parseDateRange(conditional); + } + +} diff --git a/core/src/main/java/com/graphhopper/reader/osm/conditional/DateRange.java b/core/src/main/java/com/graphhopper/reader/osm/conditional/DateRange.java new file mode 100644 index 00000000000..27d6a2693b5 --- /dev/null +++ b/core/src/main/java/com/graphhopper/reader/osm/conditional/DateRange.java @@ -0,0 +1,136 @@ +package com.graphhopper.reader.osm.conditional; + +import java.util.Calendar; + +/** + * This class represents a date range and is able to determine if a given date is in that range. + * + * @author Robin Boldt + */ +public class DateRange +{ + private Calendar from; + private Calendar to; + + // Do not compare years + boolean yearless = false; + + boolean dayOnly = false; + + boolean reverse = false; + + // TODO Gets to complex? Create Factory? + public DateRange( ParsedCalendar from, ParsedCalendar to ) + { + Calendar fromCal = from.parsedCalendar; + Calendar toCal = to.parsedCalendar; + + // This should never happen + if (fromCal.get(Calendar.ERA) != fromCal.get(Calendar.ERA)) + { + throw new IllegalArgumentException("Different ERAs are not allowed. From:" + from + " To:" + to); + } + + if (from.isYearless() && to.isYearless()) + { + yearless = true; + } + + if (from.isDayOnly() && to.isDayOnly()) + { + dayOnly = true; + } + + if (fromCal.after(toCal)) + { + if (!yearless && !dayOnly) + { + throw new IllegalArgumentException("From after to makes no sense, except for isYearless and isDayOnly DateRanges. From:" + from + " To:" + to); + } else + { + reverse = true; + } + } + + this.from = from.getMin(); + this.to = to.getMax(); + + } + + public boolean isInRange( Calendar date ) + { + if (!yearless && !dayOnly) + return date.after(from) && date.before(to); + + if(dayOnly){ + if(reverse){ + 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)); + }else{ + 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)); + } + } + + if (reverse) + return isInRangeYearlessReverse(date); + else + return isInRangeYearless(date); + } + + private boolean isInRangeYearless( Calendar date ) + { + if (from.get(Calendar.MONTH) < date.get(Calendar.MONTH) && date.get(Calendar.MONTH) < to.get(Calendar.MONTH)) + return true; + if (from.get(Calendar.MONTH) == date.get(Calendar.MONTH) && to.get(Calendar.MONTH) == date.get(Calendar.MONTH)) + { + 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)) + return true; + else + return false; + } + if (from.get(Calendar.MONTH) == date.get(Calendar.MONTH)) + { + if (from.get(Calendar.DAY_OF_MONTH) <= date.get(Calendar.DAY_OF_MONTH)) + return true; + else + return false; + } + if (to.get(Calendar.MONTH) == date.get(Calendar.MONTH)) + { + if (date.get(Calendar.DAY_OF_MONTH) <= to.get(Calendar.DAY_OF_MONTH)) + return true; + else + return false; + } + return false; + } + + private boolean isInRangeYearlessReverse( Calendar date ) + { + if (from.get(Calendar.MONTH) < date.get(Calendar.MONTH) || date.get(Calendar.MONTH) < to.get(Calendar.MONTH)) + return true; + if (from.get(Calendar.MONTH) == date.get(Calendar.MONTH) && to.get(Calendar.MONTH) == date.get(Calendar.MONTH)) + { + 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)) + return true; + else + return false; + } + if (from.get(Calendar.MONTH) == date.get(Calendar.MONTH)) + { + if (from.get(Calendar.DAY_OF_MONTH) <= date.get(Calendar.DAY_OF_MONTH)) + return true; + else + return false; + } + if (to.get(Calendar.MONTH) == date.get(Calendar.MONTH)) + { + if (date.get(Calendar.DAY_OF_MONTH) >= to.get(Calendar.DAY_OF_MONTH)) + return true; + else + return false; + } + return false; + } + + +} diff --git a/core/src/main/java/com/graphhopper/reader/osm/conditional/DateRangeParser.java b/core/src/main/java/com/graphhopper/reader/osm/conditional/DateRangeParser.java new file mode 100644 index 00000000000..d05e9a0cc27 --- /dev/null +++ b/core/src/main/java/com/graphhopper/reader/osm/conditional/DateRangeParser.java @@ -0,0 +1,117 @@ +/* + * Licensed to GraphHopper and Peter Karich under one or more contributor + * license agreements. See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + * + * GraphHopper licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.graphhopper.reader.osm.conditional; + +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Arrays; +import java.util.Calendar; +import java.util.List; + +/** + * Parses a DateRange. Currently only DateRanges that last at least one day are supported. The + * Syntax is allowed inputs is described here: http://wiki.openstreetmap.org/wiki/Key:opening_hours. + *

+ * @author Robin Boldt + */ +public class DateRangeParser +{ + static SimpleDateFormat yearMonthDayFormat = new SimpleDateFormat("yyyy MMM dd"); + static SimpleDateFormat monthDayFormat = new SimpleDateFormat("MMM dd"); + static SimpleDateFormat monthDay2Format = new SimpleDateFormat("dd.MM"); + static SimpleDateFormat yearMonthFormat = new SimpleDateFormat("yyyy MMM"); + static SimpleDateFormat monthFormat = new SimpleDateFormat("MMM"); + static SimpleDateFormat dayFormat = new SimpleDateFormat("E"); + static List dayNames = Arrays.asList(new String[] + { + "Su", "Mo", "Tu", "We", "Th", "Fr", "Sa" + }); + + public static ParsedCalendar parseDateString( String dateString ) throws ParseException + { + // Replace occurences of public holidays + dateString = dateString.replaceAll("(,( )*)?(PH|SH)", ""); + dateString = dateString.trim(); + Calendar calendar = Calendar.getInstance(); + ParsedCalendar parsedCalendar; + try + { + calendar.setTime(yearMonthDayFormat.parse(dateString)); + parsedCalendar = new ParsedCalendar(ParsedCalendar.ParseType.YEAR_MONTH_DAY, calendar); + } catch (ParseException e1) + { + try + { + calendar.setTime(monthDayFormat.parse(dateString)); + parsedCalendar = new ParsedCalendar(ParsedCalendar.ParseType.MONTH_DAY, calendar); + } catch (ParseException e2) + { + try + { + calendar.setTime(monthDay2Format.parse(dateString)); + parsedCalendar = new ParsedCalendar(ParsedCalendar.ParseType.MONTH_DAY, calendar); + } catch (ParseException e3) + { + try + { + calendar.setTime(yearMonthFormat.parse(dateString)); + parsedCalendar = new ParsedCalendar(ParsedCalendar.ParseType.YEAR_MONTH, calendar); + } catch (ParseException e4) + { + try + { + calendar.setTime(monthFormat.parse(dateString)); + parsedCalendar = new ParsedCalendar(ParsedCalendar.ParseType.MONTH, calendar); + } catch (ParseException e5) + { + int index = dayNames.indexOf(dateString); + if (index < 0) + throw new ParseException("Unparseable date: \"" + dateString + "\"", 0); + + // Ranges from 1-7 + calendar.set(Calendar.DAY_OF_WEEK, index + 1); + parsedCalendar = new ParsedCalendar(ParsedCalendar.ParseType.DAY, calendar); + } + + } + } + } + } + return parsedCalendar; + } + + public static DateRange parseDateRange( String dateRangeString ) throws ParseException + { + if (dateRangeString == null || dateRangeString.isEmpty()) + throw new IllegalArgumentException("Passing empty Strings is not allowed"); + + String[] dateArr = dateRangeString.split("-"); + if (dateArr.length > 2 || dateArr.length < 1) + throw new IllegalArgumentException("Only Strings containing two Date separated by a '-' or a single Date are allowed"); + + ParsedCalendar from = parseDateString(dateArr[0]); + ParsedCalendar to; + if (dateArr.length == 2) + to = parseDateString(dateArr[1]); + else + to = parseDateString(dateArr[0]); + + return new DateRange(from, to); + } + +} diff --git a/core/src/main/java/com/graphhopper/reader/osm/conditional/ParsedCalendar.java b/core/src/main/java/com/graphhopper/reader/osm/conditional/ParsedCalendar.java new file mode 100644 index 00000000000..f26dedd655b --- /dev/null +++ b/core/src/main/java/com/graphhopper/reader/osm/conditional/ParsedCalendar.java @@ -0,0 +1,90 @@ +/* + * Licensed to GraphHopper and Peter Karich under one or more contributor + * license agreements. See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + * + * GraphHopper licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.graphhopper.reader.osm.conditional; + +import java.util.Calendar; + +/** + * This class represents a parsed Date and the parse type. + * + * @author Robin Boldt + */ +public class ParsedCalendar +{ + public final ParseType parseType; + public final Calendar parsedCalendar; + + public ParsedCalendar( ParseType parseType, Calendar parsedCalendar ) + { + this.parseType = parseType; + this.parsedCalendar = parsedCalendar; + } + + public boolean isYearless() + { + return parseType == ParseType.MONTH || parseType == ParseType.MONTH_DAY; + } + + public boolean isDayless() + { + return parseType == ParseType.MONTH || parseType == ParseType.YEAR_MONTH; + } + + public boolean isDayOnly() + { + return parseType == ParseType.DAY; + } + + public Calendar getMax() + { + if (isDayless()) + { + parsedCalendar.set(Calendar.DAY_OF_MONTH, parsedCalendar.getActualMaximum(Calendar.DAY_OF_MONTH)); + } + parsedCalendar.set(Calendar.HOUR_OF_DAY, parsedCalendar.getActualMaximum(Calendar.HOUR_OF_DAY)); + parsedCalendar.set(Calendar.MINUTE, parsedCalendar.getActualMaximum(Calendar.MINUTE)); + parsedCalendar.set(Calendar.SECOND, parsedCalendar.getActualMaximum(Calendar.SECOND)); + parsedCalendar.set(Calendar.MILLISECOND, parsedCalendar.getActualMaximum(Calendar.MILLISECOND)); + + return parsedCalendar; + } + + public Calendar getMin() + { + if (isDayless()) + { + parsedCalendar.set(Calendar.DAY_OF_MONTH, parsedCalendar.getActualMinimum(Calendar.DAY_OF_MONTH)); + } + parsedCalendar.set(Calendar.HOUR_OF_DAY, parsedCalendar.getActualMinimum(Calendar.HOUR_OF_DAY)); + parsedCalendar.set(Calendar.MINUTE, parsedCalendar.getActualMinimum(Calendar.MINUTE)); + parsedCalendar.set(Calendar.SECOND, parsedCalendar.getActualMinimum(Calendar.SECOND)); + parsedCalendar.set(Calendar.MILLISECOND, parsedCalendar.getActualMinimum(Calendar.MILLISECOND)); + + return parsedCalendar; + } + + public enum ParseType + { + YEAR_MONTH_DAY, + YEAR_MONTH, + MONTH_DAY, + MONTH, + DAY + } + +} diff --git a/core/src/main/java/com/graphhopper/routing/util/AbstractFlagEncoder.java b/core/src/main/java/com/graphhopper/routing/util/AbstractFlagEncoder.java index 8cec00c00d4..d2d43ba5df9 100644 --- a/core/src/main/java/com/graphhopper/routing/util/AbstractFlagEncoder.java +++ b/core/src/main/java/com/graphhopper/routing/util/AbstractFlagEncoder.java @@ -17,6 +17,7 @@ */ package com.graphhopper.routing.util; +import com.graphhopper.reader.osm.ConditionalTagsInspector; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -83,6 +84,8 @@ public abstract class AbstractFlagEncoder implements FlagEncoder, TurnCostEncode protected final double speedFactor; private boolean registered; + protected ConditionalTagsInspector conditionalTagsInspector; + public AbstractFlagEncoder( PMap properties ) { throw new RuntimeException("This method must be overridden in derived classes"); @@ -820,4 +823,5 @@ public boolean supports( Class feature ) return false; } + } diff --git a/core/src/main/java/com/graphhopper/routing/util/BikeCommonFlagEncoder.java b/core/src/main/java/com/graphhopper/routing/util/BikeCommonFlagEncoder.java index 0374c21a58d..6ae39e15eb2 100644 --- a/core/src/main/java/com/graphhopper/routing/util/BikeCommonFlagEncoder.java +++ b/core/src/main/java/com/graphhopper/routing/util/BikeCommonFlagEncoder.java @@ -17,17 +17,17 @@ */ package com.graphhopper.routing.util; -import com.graphhopper.reader.OSMWay; import com.graphhopper.reader.OSMRelation; - -import static com.graphhopper.routing.util.PriorityCode.*; - +import com.graphhopper.reader.OSMWay; +import com.graphhopper.reader.osm.ConditionalTagsInspector; import com.graphhopper.util.Helper; import com.graphhopper.util.InstructionAnnotation; import com.graphhopper.util.Translation; import java.util.*; +import static com.graphhopper.routing.util.PriorityCode.*; + /** * Defines bit layout of bicycles (not motorcycles) for speed, access and relations (network). *

@@ -199,6 +199,8 @@ protected BikeCommonFlagEncoder( int speedBits, double speedFactor, int maxTurnC setCyclingNetworkPreference("deprecated", PriorityCode.AVOID_AT_ALL_COSTS.getValue()); setAvoidSpeedLimit(71); + + conditionalTagsInspector = new ConditionalTagsInspector(restrictions, restrictedValues, intendedValues); } @Override @@ -274,7 +276,7 @@ public long acceptWay( OSMWay way ) return 0; // check access restrictions - if (way.hasTag(restrictions, restrictedValues)) + if (way.hasTag(restrictions, restrictedValues) && !conditionalTagsInspector.isRestrictedWayConditionallyPermitted(way)) return 0; // do not accept railways (sometimes incorrectly mapped!) @@ -290,7 +292,11 @@ public long acceptWay( OSMWay way ) if (!allowedSacScale(sacScale)) return 0; } - return acceptBit; + + if (conditionalTagsInspector.isPermittedWayConditionallyRestricted(way)) + return 0; + else + return acceptBit; } boolean allowedSacScale( String sacScale ) diff --git a/core/src/main/java/com/graphhopper/routing/util/CarFlagEncoder.java b/core/src/main/java/com/graphhopper/routing/util/CarFlagEncoder.java index aaeee662bd2..eb416d8a4ac 100644 --- a/core/src/main/java/com/graphhopper/routing/util/CarFlagEncoder.java +++ b/core/src/main/java/com/graphhopper/routing/util/CarFlagEncoder.java @@ -17,13 +17,9 @@ */ package com.graphhopper.routing.util; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; - import com.graphhopper.reader.OSMRelation; import com.graphhopper.reader.OSMWay; +import com.graphhopper.reader.osm.ConditionalTagsInspector; import com.graphhopper.util.Helper; import com.graphhopper.util.PMap; @@ -135,6 +131,8 @@ public CarFlagEncoder( int speedBits, double speedFactor, int maxTurnCosts ) defaultSpeedMap.put("road", 20); // forestry stuff defaultSpeedMap.put("track", 15); + + conditionalTagsInspector = new ConditionalTagsInspector(restrictions, restrictedValues, intendedValues); } @Override @@ -180,6 +178,7 @@ protected double getSpeed( OSMWay way ) @Override public long acceptWay( OSMWay way ) { + // TODO: Ferries have conditionals, like opening hours or are closed during some time in the year String highwayValue = way.getTag("highway"); if (highwayValue == null) { @@ -212,7 +211,7 @@ public long acceptWay( OSMWay way ) String firstValue = way.getFirstPriorityTag(restrictions); if (!firstValue.isEmpty()) { - if (restrictedValues.contains(firstValue)) + if (restrictedValues.contains(firstValue) && !conditionalTagsInspector.isRestrictedWayConditionallyPermitted(way)) return 0; if (intendedValues.contains(firstValue)) return acceptBit; @@ -226,7 +225,10 @@ public long acceptWay( OSMWay way ) if (way.hasTag("railway") && !way.hasTag("railway", acceptedRailways)) return 0; - return acceptBit; + if (conditionalTagsInspector.isPermittedWayConditionallyRestricted(way)) + return 0; + else + return acceptBit; } @Override diff --git a/core/src/main/java/com/graphhopper/routing/util/FootFlagEncoder.java b/core/src/main/java/com/graphhopper/routing/util/FootFlagEncoder.java index 2e9252f9c3a..dc6ed4cb342 100644 --- a/core/src/main/java/com/graphhopper/routing/util/FootFlagEncoder.java +++ b/core/src/main/java/com/graphhopper/routing/util/FootFlagEncoder.java @@ -17,17 +17,15 @@ */ package com.graphhopper.routing.util; -import java.util.HashSet; -import java.util.Set; - import com.graphhopper.reader.OSMRelation; import com.graphhopper.reader.OSMWay; +import com.graphhopper.reader.osm.ConditionalTagsInspector; import com.graphhopper.util.PMap; -import static com.graphhopper.routing.util.PriorityCode.*; - import java.util.*; +import static com.graphhopper.routing.util.PriorityCode.*; + /** * Defines bit layout for pedestrians (speed, access, surface, ...). *

@@ -131,6 +129,8 @@ public FootFlagEncoder( int speedBits, double speedFactor ) hikingNetworkToCode.put("lwn", VERY_NICE.getValue()); maxPossibleSpeed = FERRY_SPEED; + + conditionalTagsInspector = new ConditionalTagsInspector(restrictions, restrictedValues, intendedValues); } @Override @@ -248,14 +248,17 @@ public long acceptWay( OSMWay way ) return 0; // check access restrictions - if (way.hasTag(restrictions, restrictedValues)) + if (way.hasTag(restrictions, restrictedValues) && !conditionalTagsInspector.isRestrictedWayConditionallyPermitted(way)) return 0; // do not accept railways (sometimes incorrectly mapped!) if (way.hasTag("railway") && !way.hasTag("railway", acceptedRailways)) return 0; - return acceptBit; + if (conditionalTagsInspector.isPermittedWayConditionallyRestricted(way)) + return 0; + else + return acceptBit; } @Override diff --git a/core/src/main/java/com/graphhopper/routing/util/MotorcycleFlagEncoder.java b/core/src/main/java/com/graphhopper/routing/util/MotorcycleFlagEncoder.java index bc21d6c9d02..7f824b537de 100644 --- a/core/src/main/java/com/graphhopper/routing/util/MotorcycleFlagEncoder.java +++ b/core/src/main/java/com/graphhopper/routing/util/MotorcycleFlagEncoder.java @@ -18,14 +18,15 @@ package com.graphhopper.routing.util; import com.graphhopper.reader.OSMWay; +import com.graphhopper.reader.osm.ConditionalTagsInspector; import com.graphhopper.util.BitUtil; import com.graphhopper.util.EdgeIteratorState; import com.graphhopper.util.PMap; -import static com.graphhopper.routing.util.PriorityCode.*; - import java.util.HashSet; +import static com.graphhopper.routing.util.PriorityCode.BEST; + /** * Defines bit layout for motorbikes *

@@ -117,6 +118,7 @@ public MotorcycleFlagEncoder( int speedBits, double speedFactor, int maxTurnCost // forestry stuff defaultSpeedMap.put("track", 15); + conditionalTagsInspector = new ConditionalTagsInspector(restrictions, restrictedValues, intendedValues); } @Override @@ -180,7 +182,7 @@ public long acceptWay( OSMWay way ) String firstValue = way.getFirstPriorityTag(restrictions); if (!firstValue.isEmpty()) { - if (restrictedValues.contains(firstValue)) + if (restrictedValues.contains(firstValue) && !conditionalTagsInspector.isRestrictedWayConditionallyPermitted(way)) return 0; if (intendedValues.contains(firstValue)) return acceptBit; @@ -194,7 +196,10 @@ public long acceptWay( OSMWay way ) if (way.hasTag("railway") && !way.hasTag("railway", acceptedRailways)) return 0; - return acceptBit; + if (conditionalTagsInspector.isPermittedWayConditionallyRestricted(way)) + return 0; + else + return acceptBit; } @Override diff --git a/core/src/test/java/com/graphhopper/reader/osm/CalendarBasedTest.java b/core/src/test/java/com/graphhopper/reader/osm/CalendarBasedTest.java new file mode 100644 index 00000000000..deb92248338 --- /dev/null +++ b/core/src/test/java/com/graphhopper/reader/osm/CalendarBasedTest.java @@ -0,0 +1,39 @@ +/* + * Licensed to GraphHopper and Peter Karich under one or more contributor + * license agreements. See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + * + * GraphHopper licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.graphhopper.reader.osm; + +import java.util.Calendar; + +/** + * Base Test for calendar based tasks. + * + * @author Robin Boldt + */ +public abstract class CalendarBasedTest +{ + + protected Calendar getCalendar( int year, int month, int day ) + { + Calendar calendar = Calendar.getInstance(); + calendar.set(Calendar.YEAR, year); + calendar.set(Calendar.MONTH, month); + calendar.set(Calendar.DAY_OF_MONTH, day); + return calendar; + } + +} diff --git a/core/src/test/java/com/graphhopper/reader/osm/ConditionalTagsInspectorTest.java b/core/src/test/java/com/graphhopper/reader/osm/ConditionalTagsInspectorTest.java new file mode 100644 index 00000000000..208900cedfe --- /dev/null +++ b/core/src/test/java/com/graphhopper/reader/osm/ConditionalTagsInspectorTest.java @@ -0,0 +1,133 @@ +/* + * Licensed to GraphHopper and Peter Karich under one or more contributor + * license agreements. See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + * + * GraphHopper licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.graphhopper.reader.osm; + +import com.graphhopper.reader.OSMWay; +import org.junit.Test; + +import java.util.*; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +/** + * @author Robin Boldt + */ +public class ConditionalTagsInspectorTest extends CalendarBasedTest +{ + @Test + public void testConditionalAccept() + { + Calendar cal = getCalendar(2014, Calendar.MARCH, 10); + ConditionalTagsInspector acceptor = new ConditionalTagsInspector(cal, getSampleConditionalTags(), getSampleRestrictedValues(), getSamplePermissiveValues()); + OSMWay way = new OSMWay(1); + way.setTag("vehicle:conditional", "no @ (Aug 10-Aug 14)"); + assertFalse(acceptor.isPermittedWayConditionallyRestricted(way)); + } + + @Test + public void testConditionalAcceptNextYear() + { + Calendar cal = getCalendar(2014, Calendar.MARCH, 10); + ConditionalTagsInspector acceptor = new ConditionalTagsInspector(cal, getSampleConditionalTags(), getSampleRestrictedValues(), getSamplePermissiveValues()); + OSMWay way = new OSMWay(1); + way.setTag("vehicle:conditional", "no @ (2013 Mar 1-2013 Mar 31)"); + assertFalse(acceptor.isPermittedWayConditionallyRestricted(way)); + } + + @Test + public void testConditionalReject() + { + Calendar cal = getCalendar(2014, Calendar.MARCH, 10); + ConditionalTagsInspector acceptor = new ConditionalTagsInspector(cal, getSampleConditionalTags(), getSampleRestrictedValues(), getSamplePermissiveValues()); + OSMWay way = new OSMWay(1); + way.setTag("vehicle:conditional", "no @ (Mar 10-Aug 14)"); + assertTrue(acceptor.isPermittedWayConditionallyRestricted(way)); + } + + @Test + public void testConditionalAllowance() + { + Calendar cal = getCalendar(2014, Calendar.MARCH, 10); + ConditionalTagsInspector acceptor = new ConditionalTagsInspector(cal, getSampleConditionalTags(), getSampleRestrictedValues(), getSamplePermissiveValues()); + OSMWay way = new OSMWay(1); + way.setTag("vehicle:conditional", "yes @ (Mar 10-Aug 14)"); + assertTrue(acceptor.isRestrictedWayConditionallyPermitted(way)); + } + + @Test + public void testConditionalAllowanceReject() + { + Calendar cal = getCalendar(2014, Calendar.MARCH, 10); + ConditionalTagsInspector acceptor = new ConditionalTagsInspector(cal, getSampleConditionalTags(), getSampleRestrictedValues(), getSamplePermissiveValues()); + OSMWay way = new OSMWay(1); + way.setTag("vehicle:conditional", "no @ (Mar 10-Aug 14)"); + assertTrue(acceptor.isPermittedWayConditionallyRestricted(way)); + } + + @Test + public void testConditionalSingleDay() + { + Calendar cal = getCalendar(2015, Calendar.DECEMBER, 27); + ConditionalTagsInspector acceptor = new ConditionalTagsInspector(cal, getSampleConditionalTags(), getSampleRestrictedValues(), getSamplePermissiveValues()); + OSMWay way = new OSMWay(1); + way.setTag("vehicle:conditional", "no @ (Su)"); + assertTrue(acceptor.isPermittedWayConditionallyRestricted(way)); + } + + @Test + public void testConditionalAllowanceSingleDay() + { + Calendar cal = getCalendar(2015, Calendar.DECEMBER, 27); + ConditionalTagsInspector acceptor = new ConditionalTagsInspector(cal, getSampleConditionalTags(), getSampleRestrictedValues(), getSamplePermissiveValues()); + OSMWay way = new OSMWay(1); + way.setTag("vehicle:conditional", "yes @ (Su)"); + assertTrue(acceptor.isRestrictedWayConditionallyPermitted(way)); + } + + private static Set getSampleRestrictedValues() + { + Set restrictedValues = new HashSet(); + restrictedValues.add("private"); + restrictedValues.add("agricultural"); + restrictedValues.add("forestry"); + restrictedValues.add("no"); + restrictedValues.add("restricted"); + restrictedValues.add("delivery"); + restrictedValues.add("military"); + restrictedValues.add("emergency"); + return restrictedValues; + } + + private static Set getSamplePermissiveValues() + { + Set restrictedValues = new HashSet(); + restrictedValues.add("yes"); + restrictedValues.add("permissive"); + return restrictedValues; + } + + private static List getSampleConditionalTags() + { + List conditionalTags = new ArrayList(); + conditionalTags.add("vehicle"); + conditionalTags.add("access"); + return conditionalTags; + } + +} diff --git a/core/src/test/java/com/graphhopper/reader/osm/conditional/ConditionalParserTest.java b/core/src/test/java/com/graphhopper/reader/osm/conditional/ConditionalParserTest.java new file mode 100644 index 00000000000..f401427ebfd --- /dev/null +++ b/core/src/test/java/com/graphhopper/reader/osm/conditional/ConditionalParserTest.java @@ -0,0 +1,80 @@ +/* + * Licensed to GraphHopper and Peter Karich under one or more contributor + * license agreements. See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + * + * GraphHopper licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.graphhopper.reader.osm.conditional; + +import com.graphhopper.reader.OSMWay; +import com.graphhopper.reader.osm.CalendarBasedTest; +import com.graphhopper.reader.osm.ConditionalTagsInspector; +import org.junit.Before; +import org.junit.Test; + +import java.text.ParseException; +import java.util.Calendar; +import java.util.HashSet; + +import static org.junit.Assert.*; + +/** + * @author Robin Boldt + */ +public class ConditionalParserTest extends CalendarBasedTest +{ + + ConditionalParser parser; + + @Before + public void setup() + { + HashSet restrictedValues = new HashSet(); + restrictedValues.add("private"); + restrictedValues.add("agricultural"); + restrictedValues.add("forestry"); + restrictedValues.add("no"); + restrictedValues.add("restricted"); + restrictedValues.add("delivery"); + restrictedValues.add("military"); + restrictedValues.add("emergency"); + + parser = new ConditionalParser(restrictedValues); + } + + @Test + public void testParseConditional() throws ParseException + { + DateRange dateRange = parser.getDateRange("no @ (2015 Sep 1-2015 Sep 30)"); + assertFalse(dateRange.isInRange(getCalendar(2015, Calendar.AUGUST, 31))); + assertTrue(dateRange.isInRange(getCalendar(2015, Calendar.SEPTEMBER, 30))); + } + + @Test + public void testParseAllowingCondition() throws ParseException + { + DateRange dateRange = parser.getDateRange("yes @ (2015 Sep 1-2015 Sep 30)"); + assertNull(dateRange); + } + + @Test + public void testParsingOfLeading0() throws ParseException + { + DateRange dateRange = parser.getDateRange("no @ (01.11. - 31.03.)"); + assertTrue(dateRange.isInRange(getCalendar(2015, Calendar.DECEMBER, 2))); + + dateRange = parser.getDateRange("no @ (01.11 - 31.03)"); + assertTrue(dateRange.isInRange(getCalendar(2015, Calendar.DECEMBER, 2))); + } +} diff --git a/core/src/test/java/com/graphhopper/reader/osm/conditional/DateRangeParserTest.java b/core/src/test/java/com/graphhopper/reader/osm/conditional/DateRangeParserTest.java new file mode 100644 index 00000000000..304b0411e24 --- /dev/null +++ b/core/src/test/java/com/graphhopper/reader/osm/conditional/DateRangeParserTest.java @@ -0,0 +1,209 @@ +/* + * Licensed to GraphHopper and Peter Karich under one or more contributor + * license agreements. See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + * + * GraphHopper licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.graphhopper.reader.osm.conditional; + +import com.graphhopper.reader.osm.CalendarBasedTest; +import org.junit.Test; + +import java.text.ParseException; +import java.util.Calendar; + +import static org.junit.Assert.*; + +/** + * @author Robin Boldt + */ +public class DateRangeParserTest extends CalendarBasedTest +{ + @Test + public void testParseConditional() throws ParseException + { + assertSameDate(2014, Calendar.DECEMBER, 15, "2014 Dec 15"); + assertSameDate(2015, Calendar.MARCH, 2, "2015 Mar 2"); + assertSameDate(2015, Calendar.MARCH, 1, "2015 Mar"); + assertSameDate(1970, Calendar.MARCH, 31, "Mar 31"); + assertSameDate(1970, Calendar.DECEMBER, 1, "Dec"); + } + + @Test + public void testParseSimpleDateRange() throws ParseException + { + DateRange dateRange = DateRangeParser.parseDateRange("2014 Aug 10-2014 Aug 14"); + assertFalse(dateRange.isInRange(getCalendar(2014, Calendar.AUGUST, 9))); + assertTrue(dateRange.isInRange(getCalendar(2014, Calendar.AUGUST, 10))); + assertTrue(dateRange.isInRange(getCalendar(2014, Calendar.AUGUST, 12))); + assertTrue(dateRange.isInRange(getCalendar(2014, Calendar.AUGUST, 14))); + assertFalse(dateRange.isInRange(getCalendar(2014, Calendar.AUGUST, 15))); + } + + @Test + public void testParseSimpleDateRangeWithoutYear() throws ParseException + { + DateRange dateRange = DateRangeParser.parseDateRange("Aug 10-Aug 14"); + assertFalse(dateRange.isInRange(getCalendar(2014, Calendar.AUGUST, 9))); + assertTrue(dateRange.isInRange(getCalendar(2014, Calendar.AUGUST, 10))); + assertTrue(dateRange.isInRange(getCalendar(2014, Calendar.AUGUST, 12))); + assertTrue(dateRange.isInRange(getCalendar(2014, Calendar.AUGUST, 14))); + assertFalse(dateRange.isInRange(getCalendar(2014, Calendar.AUGUST, 15))); + } + + @Test + public void testParseSimpleDateRangeWithoutYearAndDay() throws ParseException + { + DateRange dateRange = DateRangeParser.parseDateRange("Jul-Aug"); + assertFalse(dateRange.isInRange(getCalendar(2014, Calendar.JUNE, 9))); + assertTrue(dateRange.isInRange(getCalendar(2014, Calendar.JULY, 10))); + assertTrue(dateRange.isInRange(getCalendar(2014, Calendar.AUGUST, 12))); + assertFalse(dateRange.isInRange(getCalendar(2014, Calendar.SEPTEMBER, 14))); + } + + @Test + public void testParseSimpleDateRangeWithoutYearAndDay2() throws ParseException + { + DateRange dateRange = DateRangeParser.parseDateRange("Mar-Sep"); + assertFalse(dateRange.isInRange(getCalendar(2014, Calendar.FEBRUARY, 25))); + assertTrue(dateRange.isInRange(getCalendar(2014, Calendar.MARCH, 1))); + assertTrue(dateRange.isInRange(getCalendar(2014, Calendar.SEPTEMBER, 30))); + assertFalse(dateRange.isInRange(getCalendar(2014, Calendar.NOVEMBER, 1))); + } + + @Test + public void testParseReverseDateRange() throws ParseException + { + DateRange dateRange = DateRangeParser.parseDateRange("2014 Aug 14-2015 Mar 10"); + assertFalse(dateRange.isInRange(getCalendar(2014, Calendar.AUGUST, 13))); + assertTrue(dateRange.isInRange(getCalendar(2014, Calendar.AUGUST, 14))); + assertTrue(dateRange.isInRange(getCalendar(2015, Calendar.MARCH, 10))); + assertFalse(dateRange.isInRange(getCalendar(2015, Calendar.MARCH, 11))); + } + + @Test + public void testParseReverseDateRangeWithoutYear() throws ParseException + { + DateRange dateRange = DateRangeParser.parseDateRange("Aug 14-Aug 10"); + assertTrue(dateRange.isInRange(getCalendar(2014, Calendar.JANUARY, 9))); + assertTrue(dateRange.isInRange(getCalendar(2014, Calendar.AUGUST, 9))); + assertFalse(dateRange.isInRange(getCalendar(2014, Calendar.AUGUST, 10))); + assertFalse(dateRange.isInRange(getCalendar(2014, Calendar.AUGUST, 12))); + assertFalse(dateRange.isInRange(getCalendar(2014, Calendar.AUGUST, 14))); + assertTrue(dateRange.isInRange(getCalendar(2014, Calendar.AUGUST, 15))); + assertTrue(dateRange.isInRange(getCalendar(2014, Calendar.SEPTEMBER, 15))); + } + + @Test + public void testParseReverseDateRangeWithoutYearAndDay() throws ParseException + { + DateRange dateRange = DateRangeParser.parseDateRange("Sep-Mar"); + assertFalse(dateRange.isInRange(getCalendar(2014, Calendar.AUGUST, 31))); + assertTrue(dateRange.isInRange(getCalendar(2014, Calendar.SEPTEMBER, 1))); + assertTrue(dateRange.isInRange(getCalendar(2014, Calendar.DECEMBER, 24))); + assertTrue(dateRange.isInRange(getCalendar(2014, Calendar.JANUARY, 24))); + assertTrue(dateRange.isInRange(getCalendar(2014, Calendar.MARCH, 31))); + assertFalse(dateRange.isInRange(getCalendar(2014, Calendar.APRIL, 1))); + } + + @Test + public void testParseSingleDateRange() throws ParseException + { + DateRange dateRange = DateRangeParser.parseDateRange("2014 Sep 1"); + assertFalse(dateRange.isInRange(getCalendar(2014, Calendar.AUGUST, 31))); + assertTrue(dateRange.isInRange(getCalendar(2014, Calendar.SEPTEMBER, 1))); + assertFalse(dateRange.isInRange(getCalendar(2014, Calendar.SEPTEMBER, 30))); + assertFalse(dateRange.isInRange(getCalendar(2014, Calendar.OCTOBER, 1))); + assertFalse(dateRange.isInRange(getCalendar(2015, Calendar.SEPTEMBER, 1))); + } + + @Test + public void testParseSingleDateRangeWithoutDay() throws ParseException + { + DateRange dateRange = DateRangeParser.parseDateRange("2014 Sep"); + assertFalse(dateRange.isInRange(getCalendar(2014, Calendar.AUGUST, 31))); + assertTrue(dateRange.isInRange(getCalendar(2014, Calendar.SEPTEMBER, 1))); + assertTrue(dateRange.isInRange(getCalendar(2014, Calendar.SEPTEMBER, 30))); + assertFalse(dateRange.isInRange(getCalendar(2014, Calendar.OCTOBER, 1))); + assertFalse(dateRange.isInRange(getCalendar(2015, Calendar.SEPTEMBER, 1))); + } + + @Test + public void testParseSingleDateRangeWithoutYearAndDay() throws ParseException + { + DateRange dateRange = DateRangeParser.parseDateRange("Sep"); + assertFalse(dateRange.isInRange(getCalendar(2014, Calendar.AUGUST, 31))); + assertTrue(dateRange.isInRange(getCalendar(2014, Calendar.SEPTEMBER, 1))); + assertTrue(dateRange.isInRange(getCalendar(2014, Calendar.SEPTEMBER, 30))); + assertFalse(dateRange.isInRange(getCalendar(2014, Calendar.OCTOBER, 1))); + } + + @Test + public void testParseSingleDateRangeOneDayOnly() throws ParseException + { + DateRange dateRange = DateRangeParser.parseDateRange("Sa"); + assertFalse(dateRange.isInRange(getCalendar(2015, Calendar.DECEMBER, 25))); + assertTrue(dateRange.isInRange(getCalendar(2015, Calendar.DECEMBER, 26))); + assertFalse(dateRange.isInRange(getCalendar(2015, Calendar.DECEMBER, 27))); + } + + @Test + public void testParseSingleDateRangeOneDayOnlyIncludingPh() throws ParseException + { + DateRange dateRange = DateRangeParser.parseDateRange("Su, PH"); + assertFalse(dateRange.isInRange(getCalendar(2015, Calendar.DECEMBER, 26))); + assertTrue(dateRange.isInRange(getCalendar(2015, Calendar.DECEMBER, 27))); + assertFalse(dateRange.isInRange(getCalendar(2015, Calendar.DECEMBER, 28))); + } + + @Test + public void testParseSingleDateRangeDayOnly() throws ParseException + { + DateRange dateRange = DateRangeParser.parseDateRange("Mo-Fr"); + assertFalse(dateRange.isInRange(getCalendar(2015, Calendar.DECEMBER, 20))); + assertTrue(dateRange.isInRange(getCalendar(2015, Calendar.DECEMBER, 21))); + assertTrue(dateRange.isInRange(getCalendar(2015, Calendar.DECEMBER, 25))); + assertFalse(dateRange.isInRange(getCalendar(2015, Calendar.DECEMBER, 26))); + assertTrue(dateRange.isInRange(getCalendar(2015, Calendar.DECEMBER, 28))); + } + + @Test + public void testParseReverseDateRangeDayOnly() throws ParseException + { + // This is reverse since Sa=7 and So=1 + DateRange dateRange = DateRangeParser.parseDateRange("Sa-Su"); + assertFalse(dateRange.isInRange(getCalendar(2015, Calendar.DECEMBER, 25))); + assertTrue(dateRange.isInRange(getCalendar(2015, Calendar.DECEMBER, 26))); + assertTrue(dateRange.isInRange(getCalendar(2015, Calendar.DECEMBER, 27))); + assertFalse(dateRange.isInRange(getCalendar(2015, Calendar.DECEMBER, 28))); + } + + @Test(expected = ParseException.class) + public void testParseUnparsableDate() throws ParseException + { + DateRangeParser.parseDateRange("Sat"); + fail(); + } + + private void assertSameDate( int year, int month, int day, String dateString ) throws ParseException + { + Calendar expected = getCalendar(year, month, day); + ParsedCalendar actualParsed = DateRangeParser.parseDateString(dateString); + Calendar actual = actualParsed.parsedCalendar; + assertEquals(expected.get(Calendar.YEAR), actual.get(Calendar.YEAR)); + assertEquals(expected.get(Calendar.MONTH), actual.get(Calendar.MONTH)); + assertEquals(expected.get(Calendar.DAY_OF_MONTH), actual.get(Calendar.DAY_OF_MONTH)); + } + +} diff --git a/core/src/test/java/com/graphhopper/routing/util/AbstractBikeFlagEncoderTester.java b/core/src/test/java/com/graphhopper/routing/util/AbstractBikeFlagEncoderTester.java index 2f9d07c2155..83153f2fecd 100644 --- a/core/src/test/java/com/graphhopper/routing/util/AbstractBikeFlagEncoderTester.java +++ b/core/src/test/java/com/graphhopper/routing/util/AbstractBikeFlagEncoderTester.java @@ -19,20 +19,18 @@ import com.graphhopper.reader.OSMNode; import com.graphhopper.reader.OSMWay; - -import static com.graphhopper.routing.util.PriorityCode.*; - import com.graphhopper.util.Translation; +import org.junit.Before; +import org.junit.Test; -import static com.graphhopper.util.TranslationMapTest.SINGLETON; - +import java.text.SimpleDateFormat; +import java.util.Calendar; import java.util.Locale; +import static com.graphhopper.routing.util.PriorityCode.*; +import static com.graphhopper.util.TranslationMapTest.SINGLETON; import static org.junit.Assert.*; -import org.junit.Before; -import org.junit.Test; - /** * @author Peter Karich * @author ratrun @@ -174,6 +172,20 @@ public void testAccess() way.setTag("cycleway", "track"); way.setTag("railway", "abandoned"); assertTrue(encoder.acceptWay(way) > 0); + + Calendar calendar = Calendar.getInstance(); + SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy MMM dd"); + + way.clearTags(); + way.setTag("highway", "road"); + way.setTag("bicycle:conditional", "no @ (" + simpleDateFormat.format(calendar.getTime()) + ")"); + assertFalse(encoder.acceptWay(way) > 0); + + way.clearTags(); + way.setTag("highway", "road"); + way.setTag("access", "no"); + way.setTag("bicycle:conditional", "yes @ (" + simpleDateFormat.format(calendar.getTime()) + ")"); + assertTrue(encoder.acceptWay(way) > 0); } @Test diff --git a/core/src/test/java/com/graphhopper/routing/util/CarFlagEncoderTest.java b/core/src/test/java/com/graphhopper/routing/util/CarFlagEncoderTest.java index 40b4df9c82e..dbf97c91351 100644 --- a/core/src/test/java/com/graphhopper/routing/util/CarFlagEncoderTest.java +++ b/core/src/test/java/com/graphhopper/routing/util/CarFlagEncoderTest.java @@ -21,6 +21,9 @@ import com.graphhopper.reader.OSMWay; import org.junit.Test; +import java.text.SimpleDateFormat; +import java.util.Calendar; + import static org.junit.Assert.*; /** @@ -107,6 +110,20 @@ public void testAccess() way.setTag("highway", "service"); way.setTag("motor_vehicle", "emergency"); assertFalse(encoder.acceptWay(way) > 0); + + Calendar calendar = Calendar.getInstance(); + SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy MMM dd"); + + way.clearTags(); + way.setTag("highway", "road"); + way.setTag("access:conditional", "no @ ("+simpleDateFormat.format(calendar.getTime())+")"); + assertFalse(encoder.acceptWay(way) > 0); + + way.clearTags(); + way.setTag("highway", "road"); + way.setTag("access", "no"); + way.setTag("access:conditional", "yes @ ("+simpleDateFormat.format(calendar.getTime())+")"); + assertTrue(encoder.acceptWay(way) > 0); } @Test diff --git a/core/src/test/java/com/graphhopper/routing/util/FootFlagEncoderTest.java b/core/src/test/java/com/graphhopper/routing/util/FootFlagEncoderTest.java index e84f759031d..f91655a93b0 100644 --- a/core/src/test/java/com/graphhopper/routing/util/FootFlagEncoderTest.java +++ b/core/src/test/java/com/graphhopper/routing/util/FootFlagEncoderTest.java @@ -26,6 +26,9 @@ import org.junit.Test; +import java.text.SimpleDateFormat; +import java.util.Calendar; + import static org.junit.Assert.*; /** @@ -154,6 +157,20 @@ public void testAccess() assertTrue(footEncoder.acceptWay(way) > 0); way.setTag("foot", "no"); assertFalse(footEncoder.acceptWay(way) > 0); + + Calendar calendar = Calendar.getInstance(); + SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy MMM dd"); + + way.clearTags(); + way.setTag("highway", "footway"); + way.setTag("access:conditional", "no @ ("+simpleDateFormat.format(calendar.getTime())+")"); + assertFalse(footEncoder.acceptWay(way) > 0); + + way.clearTags(); + way.setTag("highway", "footway"); + way.setTag("access", "no"); + way.setTag("access:conditional", "yes @ ("+simpleDateFormat.format(calendar.getTime())+")"); + assertTrue(footEncoder.acceptWay(way) > 0); } @Test diff --git a/core/src/test/java/com/graphhopper/routing/util/MotorcycleFlagEncoderTest.java b/core/src/test/java/com/graphhopper/routing/util/MotorcycleFlagEncoderTest.java index 8e7934592f3..e78be6226d6 100644 --- a/core/src/test/java/com/graphhopper/routing/util/MotorcycleFlagEncoderTest.java +++ b/core/src/test/java/com/graphhopper/routing/util/MotorcycleFlagEncoderTest.java @@ -22,9 +22,11 @@ import com.graphhopper.util.EdgeIteratorState; import com.graphhopper.util.GHUtility; import com.graphhopper.util.Helper; -import com.graphhopper.util.PointList; import org.junit.Test; +import java.text.SimpleDateFormat; +import java.util.Calendar; + import static org.junit.Assert.*; /** @@ -50,6 +52,81 @@ private Graph initExampleGraph() return gs; } + @Test + public void testAccess() + { + OSMWay way = new OSMWay(1); + assertFalse(encoder.acceptWay(way) > 0); + way.setTag("highway", "service"); + assertTrue(encoder.acceptWay(way) > 0); + way.setTag("access", "no"); + assertFalse(encoder.acceptWay(way) > 0); + + way.clearTags(); + way.setTag("highway", "track"); + assertTrue(encoder.acceptWay(way) > 0); + + way.clearTags(); + way.setTag("highway", "service"); + way.setTag("access", "delivery"); + assertFalse(encoder.acceptWay(way) > 0); + + way.clearTags(); + way.setTag("highway", "unclassified"); + way.setTag("ford", "yes"); + assertFalse(encoder.acceptWay(way) > 0); + way.setTag("motorcycle", "yes"); + assertTrue(encoder.acceptWay(way) > 0); + + way.clearTags(); + way.setTag("route", "ferry"); + assertTrue(encoder.acceptWay(way) > 0); + assertTrue(encoder.isFerry(encoder.acceptWay(way))); + way.setTag("motorcycle", "no"); + assertFalse(encoder.acceptWay(way) > 0); + + way.clearTags(); + way.setTag("route", "ferry"); + way.setTag("foot", "yes"); + assertFalse(encoder.acceptWay(way) > 0); + assertFalse(encoder.isFerry(encoder.acceptWay(way))); + + way.clearTags(); + way.setTag("access", "yes"); + way.setTag("motor_vehicle", "no"); + assertFalse(encoder.acceptWay(way) > 0); + + way.clearTags(); + way.setTag("highway", "service"); + way.setTag("access", "yes"); + way.setTag("motor_vehicle", "no"); + assertFalse(encoder.acceptWay(way) > 0); + + way.clearTags(); + way.setTag("highway", "service"); + way.setTag("access", "emergency"); + assertFalse(encoder.acceptWay(way) > 0); + + way.clearTags(); + way.setTag("highway", "service"); + way.setTag("motor_vehicle", "emergency"); + assertFalse(encoder.acceptWay(way) > 0); + + Calendar calendar = Calendar.getInstance(); + SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy MMM dd"); + + way.clearTags(); + way.setTag("highway", "road"); + way.setTag("access:conditional", "no @ ("+simpleDateFormat.format(calendar.getTime())+")"); + assertFalse(encoder.acceptWay(way) > 0); + + way.clearTags(); + way.setTag("highway", "road"); + way.setTag("access", "no"); + way.setTag("access:conditional", "yes @ ("+simpleDateFormat.format(calendar.getTime())+")"); + assertTrue(encoder.acceptWay(way) > 0); + } + @Test public void testHandleWayTags() {