Skip to content

Commit

Permalink
Add support for various hazmat tags (#1711)
Browse files Browse the repository at this point in the history
* Add separate hazmat categories

* Add support for OSMs `hazmat` tag

* Add support for OSMs `hazmat:water` tag
  • Loading branch information
otbutz authored and karussell committed Nov 1, 2019
1 parent 9c31116 commit 11a005a
Show file tree
Hide file tree
Showing 10 changed files with 238 additions and 2 deletions.
2 changes: 1 addition & 1 deletion config-example.yml
Expand Up @@ -15,7 +15,7 @@ graphhopper:

# Add additional information to every edge. Used for path details.
# If road_environment is added and elevation is enabled then also a tunnel and bridge interpolation is done, see #798.
# More options are: surface,max_width,max_height,max_weight,max_axle_load,max_length,toll,track_type
# More options are: surface,max_width,max_height,max_weight,max_axle_load,max_length,hazmat,hazmat_water,toll,track_type
graph.encoded_values: road_class,road_class_link,road_environment,max_speed,road_access

##### Elevation #####
Expand Down
Expand Up @@ -59,6 +59,10 @@ public EncodedValue create(String string) {
enc = new EnumEncodedValue<>(Toll.KEY, Toll.class);
} else if (TrackType.KEY.equals(name)) {
enc = new EnumEncodedValue<>(TrackType.KEY, TrackType.class);
} else if (Hazmat.KEY.equals(name)) {
enc = new EnumEncodedValue<>(Hazmat.KEY, Hazmat.class);
} else if (HazmatWater.KEY.equals(name)) {
enc = new EnumEncodedValue<>(HazmatWater.KEY, HazmatWater.class);
} else {
throw new IllegalArgumentException("DefaultEncodedValueFactory cannot find EncodedValue " + name);
}
Expand Down
22 changes: 22 additions & 0 deletions core/src/main/java/com/graphhopper/routing/profiles/Hazmat.java
@@ -0,0 +1,22 @@
package com.graphhopper.routing.profiles;

/**
* Defines general restrictions for the transport of hazardous materials.<br>
* If not tagged it will be {@link #YES}
*/
public enum Hazmat {
YES("yes"), NO("no");

public static final String KEY = "hazmat";

private final String name;

Hazmat(String name) {
this.name = name;
}

@Override
public String toString() {
return name;
}
}
@@ -0,0 +1,22 @@
package com.graphhopper.routing.profiles;

/**
* Defines general restrictions for the transport of goods through water protection areas.<br>
* If not tagged it will be {@link #YES}
*/
public enum HazmatWater {
YES("yes"), PERMISSIVE("permissive"), NO("no");

public static final String KEY = "hazmat_water";

private final String name;

HazmatWater(String name) {
this.name = name;
}

@Override
public String toString() {
return name;
}
}
Expand Up @@ -58,6 +58,10 @@ else if (name.equals(Toll.KEY))
return new OSMTollParser();
else if (name.equals(TrackType.KEY))
return new OSMTrackTypeParser();
else if (name.equals(Hazmat.KEY))
return new OSMHazmatParser();
else if (name.equals(HazmatWater.KEY))
return new OSMHazmatWaterParser();
throw new IllegalArgumentException("entry in encoder list not supported " + name);
}
}
@@ -0,0 +1,36 @@
package com.graphhopper.routing.util.parsers;

import java.util.List;

import com.graphhopper.reader.ReaderWay;
import com.graphhopper.routing.profiles.EncodedValue;
import com.graphhopper.routing.profiles.EncodedValueLookup;
import com.graphhopper.routing.profiles.EnumEncodedValue;
import com.graphhopper.routing.profiles.Hazmat;
import com.graphhopper.routing.util.EncodingManager.Access;
import com.graphhopper.storage.IntsRef;

public class OSMHazmatParser implements TagParser {

private final EnumEncodedValue<Hazmat> hazEnc;

public OSMHazmatParser() {
this.hazEnc = new EnumEncodedValue<>(Hazmat.KEY, Hazmat.class);
}

@Override
public void createEncodedValues(EncodedValueLookup lookup,
List<EncodedValue> registerNewEncodedValue) {
registerNewEncodedValue.add(hazEnc);
}

@Override
public IntsRef handleWayTags(IntsRef edgeFlags, ReaderWay readerWay, Access access,
long relationFlags) {
if (readerWay.hasTag("hazmat", "no")) {
hazEnc.setEnum(false, edgeFlags, Hazmat.NO);
}
return edgeFlags;
}

}
@@ -0,0 +1,38 @@
package com.graphhopper.routing.util.parsers;

import java.util.List;

import com.graphhopper.reader.ReaderWay;
import com.graphhopper.routing.profiles.EncodedValue;
import com.graphhopper.routing.profiles.EncodedValueLookup;
import com.graphhopper.routing.profiles.EnumEncodedValue;
import com.graphhopper.routing.profiles.HazmatWater;
import com.graphhopper.routing.util.EncodingManager.Access;
import com.graphhopper.storage.IntsRef;

public class OSMHazmatWaterParser implements TagParser {

private final EnumEncodedValue<HazmatWater> hazWaterEnc;

public OSMHazmatWaterParser() {
this.hazWaterEnc = new EnumEncodedValue<>(HazmatWater.KEY, HazmatWater.class);
}

@Override
public void createEncodedValues(EncodedValueLookup lookup,
List<EncodedValue> registerNewEncodedValue) {
registerNewEncodedValue.add(hazWaterEnc);
}

@Override
public IntsRef handleWayTags(IntsRef edgeFlags, ReaderWay readerWay, Access access,
long relationFlags) {
if (readerWay.hasTag("hazmat:water", "no")) {
hazWaterEnc.setEnum(false, edgeFlags, HazmatWater.NO);
} else if (readerWay.hasTag("hazmat:water", "permissive")) {
hazWaterEnc.setEnum(false, edgeFlags, HazmatWater.PERMISSIVE);
}
return edgeFlags;
}

}
Expand Up @@ -63,7 +63,9 @@ public List<PathDetailsBuilder> createPathDetailsBuilders(List<String> requested
for (Map.Entry entry : Arrays.asList(new MapEntry<>(RoadClass.KEY, RoadClass.class),
new MapEntry<>(RoadEnvironment.KEY, RoadEnvironment.class), new MapEntry<>(Surface.KEY, Surface.class),
new MapEntry<>(RoadAccess.KEY, RoadAccess.class), new MapEntry<>(Toll.KEY, Toll.class),
new MapEntry<>(TrackType.KEY, TrackType.class), new MapEntry<>(Country.KEY, Country.class))) {
new MapEntry<>(TrackType.KEY, TrackType.class), new MapEntry<>(Hazmat.KEY, Hazmat.class),
new MapEntry<>(HazmatWater.KEY, HazmatWater.class),
new MapEntry<>(Country.KEY, Country.class))) {
String key = (String) entry.getKey();
if (requestedPathDetails.contains(key) && encoder.hasEncodedValue(key))
builders.add(new EnumDetails(key, encoder.getEnumEncodedValue(key, (Class<Enum>) entry.getValue())));
Expand Down
@@ -0,0 +1,54 @@
package com.graphhopper.routing.util.parsers;

import static com.graphhopper.routing.util.EncodingManager.Access.WAY;
import static org.junit.Assert.assertEquals;

import org.junit.Before;
import org.junit.Test;

import com.graphhopper.reader.ReaderWay;
import com.graphhopper.routing.profiles.EnumEncodedValue;
import com.graphhopper.routing.profiles.Hazmat;
import com.graphhopper.routing.util.EncodingManager;
import com.graphhopper.storage.IntsRef;

public class OSMHazmatParserTest {

private EncodingManager em;
private EnumEncodedValue<Hazmat> hazEnc;
private OSMHazmatParser parser;

@Before
public void setUp() {
parser = new OSMHazmatParser();
em = new EncodingManager.Builder().add(parser).build();
hazEnc = em.getEnumEncodedValue(Hazmat.KEY, Hazmat.class);
}

@Test
public void testSimpleTags() {
ReaderWay readerWay = new ReaderWay(1);
IntsRef intsRef = em.createEdgeFlags();
readerWay.setTag("hazmat", "no");
parser.handleWayTags(intsRef, readerWay, WAY, 0);
assertEquals(Hazmat.NO, hazEnc.getEnum(false, intsRef));

intsRef = em.createEdgeFlags();
readerWay.setTag("hazmat", "yes");
parser.handleWayTags(intsRef, readerWay, WAY, 0);
assertEquals(Hazmat.YES, hazEnc.getEnum(false, intsRef));

intsRef = em.createEdgeFlags();
readerWay.setTag("hazmat", "designated");
parser.handleWayTags(intsRef, readerWay, WAY, 0);
assertEquals(Hazmat.YES, hazEnc.getEnum(false, intsRef));
}

@Test
public void testNoNPE() {
ReaderWay readerWay = new ReaderWay(1);
IntsRef intsRef = em.createEdgeFlags();
parser.handleWayTags(intsRef, readerWay, WAY, 0);
assertEquals(Hazmat.YES, hazEnc.getEnum(false, intsRef));
}
}
@@ -0,0 +1,54 @@
package com.graphhopper.routing.util.parsers;

import static com.graphhopper.routing.util.EncodingManager.Access.WAY;
import static org.junit.Assert.assertEquals;

import org.junit.Before;
import org.junit.Test;

import com.graphhopper.reader.ReaderWay;
import com.graphhopper.routing.profiles.EnumEncodedValue;
import com.graphhopper.routing.profiles.HazmatWater;
import com.graphhopper.routing.util.EncodingManager;
import com.graphhopper.storage.IntsRef;

public class OSMHazmatWaterParserTest {

private EncodingManager em;
private EnumEncodedValue<HazmatWater> hazWaterEnc;
private OSMHazmatWaterParser parser;

@Before
public void setUp() {
parser = new OSMHazmatWaterParser();
em = new EncodingManager.Builder().add(parser).build();
hazWaterEnc = em.getEnumEncodedValue(HazmatWater.KEY, HazmatWater.class);
}

@Test
public void testSimpleTags() {
ReaderWay readerWay = new ReaderWay(1);
IntsRef intsRef = em.createEdgeFlags();
readerWay.setTag("hazmat:water", "no");
parser.handleWayTags(intsRef, readerWay, WAY, 0);
assertEquals(HazmatWater.NO, hazWaterEnc.getEnum(false, intsRef));

intsRef = em.createEdgeFlags();
readerWay.setTag("hazmat:water", "yes");
parser.handleWayTags(intsRef, readerWay, WAY, 0);
assertEquals(HazmatWater.YES, hazWaterEnc.getEnum(false, intsRef));

intsRef = em.createEdgeFlags();
readerWay.setTag("hazmat:water", "permissive");
parser.handleWayTags(intsRef, readerWay, WAY, 0);
assertEquals(HazmatWater.PERMISSIVE, hazWaterEnc.getEnum(false, intsRef));
}

@Test
public void testNoNPE() {
ReaderWay readerWay = new ReaderWay(1);
IntsRef intsRef = em.createEdgeFlags();
parser.handleWayTags(intsRef, readerWay, WAY, 0);
assertEquals(HazmatWater.YES, hazWaterEnc.getEnum(false, intsRef));
}
}

0 comments on commit 11a005a

Please sign in to comment.