Skip to content

Commit

Permalink
Implementation for seasonal_restricted encoded value as suggested in g…
Browse files Browse the repository at this point in the history
  • Loading branch information
ratrun committed Aug 5, 2023
1 parent b5c6c1b commit ea147ae
Show file tree
Hide file tree
Showing 9 changed files with 138 additions and 7 deletions.
2 changes: 2 additions & 0 deletions core/src/main/java/com/graphhopper/GraphHopper.java
Original file line number Diff line number Diff line change
Expand Up @@ -646,6 +646,8 @@ protected OSMParsers buildOSMParsers(Map<String, String> vehiclesByName, List<St
// all these defaults and just use the config as the single source of truth
if (!encodedValueStrings.contains(Roundabout.KEY))
osmParsers.addWayTagParser(new OSMRoundaboutParser(encodingManager.getBooleanEncodedValue(Roundabout.KEY)));
if (!encodedValueStrings.contains(SeasonalRestricted.KEY))
osmParsers.addWayTagParser(new OSMSeasonalRestrictedParser(encodingManager.getBooleanEncodedValue(SeasonalRestricted.KEY)));
if (!encodedValueStrings.contains(RoadClass.KEY))
osmParsers.addWayTagParser(new OSMRoadClassParser(encodingManager.getEnumEncodedValue(RoadClass.KEY, RoadClass.class)));
if (!encodedValueStrings.contains(RoadClassLink.KEY))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,11 @@ public ConditionalOSMTagInspector(Calendar value, List<String> tagsToCheck,
this(Arrays.asList(new DateRangeParser(value)), tagsToCheck, restrictiveValues, permittedValues, false);
}

public ConditionalOSMTagInspector(List<String> tagsToCheck,
Set<String> restrictiveValues, Set<String> permittedValues) {
this(null, tagsToCheck, restrictiveValues, permittedValues, false);
}

public ConditionalOSMTagInspector(List<? extends ConditionalValueParser> valueParsers, List<String> tagsToCheck,
Set<String> restrictiveValues, Set<String> permittedValues, boolean enabledLogs) {
this.tagsToCheck = new ArrayList<>(tagsToCheck.size());
Expand All @@ -54,9 +59,11 @@ public ConditionalOSMTagInspector(List<? extends ConditionalValueParser> valuePa
boolean logUnsupportedFeatures = false;
this.permitParser = new ConditionalParser(permittedValues, logUnsupportedFeatures);
this.restrictiveParser = new ConditionalParser(restrictiveValues, logUnsupportedFeatures);
for (ConditionalValueParser cvp : valueParsers) {
permitParser.addConditionalValueParser(cvp);
restrictiveParser.addConditionalValueParser(cvp);
if (valueParsers != null) {
for (ConditionalValueParser cvp : valueParsers) {
permitParser.addConditionalValueParser(cvp);
restrictiveParser.addConditionalValueParser(cvp);
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@

import java.text.ParseException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
import java.util.Set;

Expand Down Expand Up @@ -108,6 +107,9 @@ public boolean checkCondition(String conditionalTag) throws ParseException {
if (conditionalTag == null || conditionalTag.isEmpty() || !conditionalTag.contains("@"))
return false;

if (valueParsers.size() == 0)
return true;

if (conditionalTag.contains(";")) {
if (enabledLogs)
logger.warn("We do not support multiple conditions yet: " + conditionalTag);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ public class DefaultEncodedValueFactory implements EncodedValueFactory {
public EncodedValue create(String name, PMap properties) {
if (Roundabout.KEY.equals(name)) {
return Roundabout.create();
} else if (SeasonalRestricted.KEY.equals(name)) {
return SeasonalRestricted.create();
} else if (GetOffBike.KEY.equals(name)) {
return GetOffBike.create();
} else if (RoadClass.KEY.equals(name)) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/*
* Licensed to GraphHopper GmbH under one or more contributor
* license agreements. See the NOTICE file distributed with this work for
* additional information regarding copyright ownership.
*
* GraphHopper GmbH 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.routing.ev;

public class SeasonalRestricted {
public static final String KEY = "seasonal_restricted";

public static BooleanEncodedValue create() {
return new SimpleBooleanEncodedValue(KEY);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,8 @@ private void addDefaultEncodedValues() {
RoadEnvironment.KEY,
MaxSpeed.KEY,
RoadAccess.KEY,
FerrySpeed.KEY
FerrySpeed.KEY,
SeasonalRestricted.KEY
));
if (em.getVehicles().stream().anyMatch(vehicle -> vehicle.contains("bike") || vehicle.contains("mtb") || vehicle.contains("racingbike"))) {
keys.add(BikeNetwork.KEY);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package com.graphhopper.routing.util.parsers;

import com.graphhopper.reader.ReaderWay;
import com.graphhopper.reader.osm.conditional.ConditionalOSMTagInspector;
import com.graphhopper.reader.osm.conditional.ConditionalTagInspector;
import com.graphhopper.routing.ev.BooleanEncodedValue;
import com.graphhopper.routing.ev.EdgeIntAccess;
import com.graphhopper.storage.IntsRef;

import java.util.*;

/**
* This parser scans different OSM conditional tags to identify if a way has only conditional access
*/
public class OSMSeasonalRestrictedParser implements TagParser {

private final BooleanEncodedValue seasonalRestrictedEnc;
private final ConditionalTagInspector acceptor = new ConditionalOSMTagInspector(getConditionalTags(), getSampleRestrictedValues(), new HashSet<>());

/**
* @param seasonalRestrictedEnc used to find out if way access is conditional
*/
public OSMSeasonalRestrictedParser(BooleanEncodedValue seasonalRestrictedEnc) {
this.seasonalRestrictedEnc = seasonalRestrictedEnc;
}

private static Set<String> getSampleRestrictedValues() {
Set<String> restrictedValues = new HashSet<>();
restrictedValues.add("no");
restrictedValues.add("restricted");
return restrictedValues;
}

private static List<String> getConditionalTags() {
List<String> conditionalTags = new ArrayList<>();
conditionalTags.add("vehicle");
conditionalTags.add("access");
return conditionalTags;
}

@Override
public void handleWayTags(int edgeId, EdgeIntAccess edgeIntAccess, ReaderWay way, IntsRef relationFlags) {
boolean isSeasonalRestricted = acceptor.isPermittedWayConditionallyRestricted(way);
seasonalRestrictedEnc.setBool(false, edgeId, edgeIntAccess, isSeasonalRestricted);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -518,7 +518,7 @@ public void testNothingHappensWhenFlagEncodersAreChangedForLoad() {
setGraphHopperLocation(ghLoc);
instance.load();
assertEquals(5, instance.getBaseGraph().getNodes());
assertEquals("foot_access,foot_average_speed,foot_priority,car_access,car_average_speed,foot_subnetwork,car_subnetwork,roundabout,road_class,road_class_link,road_environment,max_speed,road_access,ferry_speed,foot_network",
assertEquals("foot_access,foot_average_speed,foot_priority,car_access,car_average_speed,foot_subnetwork,car_subnetwork,roundabout,road_class,road_class_link,road_environment,max_speed,road_access,ferry_speed,seasonal_restricted,foot_network",
instance.getEncodingManager().getEncodedValues().stream().map(EncodedValue::getName).collect(Collectors.joining(",")));
}

Expand Down Expand Up @@ -558,7 +558,7 @@ public void testFailsForWrongEVConfig() {
setOSMFile(testOsm3);
instance.load();
assertEquals(5, instance.getBaseGraph().getNodes());
assertEquals("foot_access,foot_average_speed,foot_priority,car_access,car_average_speed,foot_subnetwork,car_subnetwork,roundabout,road_class,road_class_link,road_environment,max_speed,road_access,ferry_speed,foot_network", instance.getEncodingManager().getEncodedValues().stream().map(EncodedValue::getName).collect(Collectors.joining(",")));
assertEquals("foot_access,foot_average_speed,foot_priority,car_access,car_average_speed,foot_subnetwork,car_subnetwork,roundabout,road_class,road_class_link,road_environment,max_speed,road_access,ferry_speed,seasonal_restricted,foot_network", instance.getEncodingManager().getEncodedValues().stream().map(EncodedValue::getName).collect(Collectors.joining(",")));
}

@Test
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package com.graphhopper.routing.util.parsers;

import com.graphhopper.reader.ReaderWay;
import com.graphhopper.routing.ev.*;
import com.graphhopper.storage.IntsRef;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

import static org.junit.jupiter.api.Assertions.*;

public class OSMSeasonalRestrictedParserTest {
private BooleanEncodedValue seasonalRestrictedEnc;
private OSMSeasonalRestrictedParser parser;

@BeforeEach
public void setUp() {
seasonalRestrictedEnc = SeasonalRestricted.create();
seasonalRestrictedEnc.init(new EncodedValue.InitializerConfig());
parser = new OSMSeasonalRestrictedParser(seasonalRestrictedEnc);
}

@Test
public void testSeasonalRestrictedTags() {
IntsRef relFlags = new IntsRef(2);

ReaderWay readerWay = new ReaderWay(1);
EdgeIntAccess edgeIntAccess = new ArrayEdgeIntAccess(1);
int edgeId = 0;
readerWay.setTag("highway", "primary");
parser.handleWayTags(edgeId, edgeIntAccess, readerWay, relFlags);
assertFalse(seasonalRestrictedEnc.getBool(false, edgeId, edgeIntAccess));

readerWay.setTag("access:conditional", "no @ Winter");
parser.handleWayTags(edgeId, edgeIntAccess, readerWay, relFlags);
assertTrue(seasonalRestrictedEnc.getBool(false, edgeId, edgeIntAccess));

readerWay.setTag("access:conditional", "no @ Nov-Apr");
parser.handleWayTags(edgeId, edgeIntAccess, readerWay, relFlags);
assertTrue(seasonalRestrictedEnc.getBool(false, edgeId, edgeIntAccess));

readerWay.setTag("access:conditional", "no @ (Nov-Apr; May 19:30-06:00; Jun-Aug 20:30-05:30; Sep-Oct 19:30-06:00)");
parser.handleWayTags(edgeId, edgeIntAccess, readerWay, relFlags);
assertTrue(seasonalRestrictedEnc.getBool(false, edgeId, edgeIntAccess));
}
}

0 comments on commit ea147ae

Please sign in to comment.