Skip to content

Commit e96c62b

Browse files
authored
Add lanes encoded value (graphhopper#2317)
1 parent ca00ef6 commit e96c62b

File tree

6 files changed

+157
-2
lines changed

6 files changed

+157
-2
lines changed

config-example.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ graphhopper:
1818
# Add additional information to every edge. Used for path details (#1548), better instructions (#1844) and tunnel/bridge interpolation (#798).
1919
# Default values are: road_class,road_class_link,road_environment,max_speed,road_access (since #1805)
2020
# More are: surface,max_width,max_height,max_weight,max_axle_load,max_length,hazmat,hazmat_tunnel,hazmat_water,toll,track_type,
21-
# mtb_rating, hiking_rating, horse_rating
21+
# mtb_rating,hiking_rating,horse_rating,lanes
2222
# graph.encoded_values: surface,toll,track_type
2323

2424
##### Routing Profiles ####
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
/*
2+
* Licensed to GraphHopper GmbH 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 GmbH 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+
19+
package com.graphhopper.routing.ev;
20+
21+
public class Lanes {
22+
public static final String KEY = "lanes";
23+
24+
public static IntEncodedValue create() {
25+
return new UnsignedIntEncodedValue(KEY, 3, false);
26+
}
27+
}

core/src/main/java/com/graphhopper/routing/util/parsers/DefaultTagParserFactory.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,8 @@ else if (name.equals(HazmatTunnel.KEY))
6464
return new OSMHazmatTunnelParser();
6565
else if (name.equals(HazmatWater.KEY))
6666
return new OSMHazmatWaterParser();
67+
else if (name.equals(Lanes.KEY))
68+
return new OSMLanesParser();
6769
else if (name.equals(MtbRating.KEY))
6870
return new OSMMtbRatingParser();
6971
else if (name.equals(HikeRating.KEY))
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
/*
2+
* Licensed to GraphHopper GmbH 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 GmbH 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+
19+
package com.graphhopper.routing.util.parsers;
20+
21+
import com.graphhopper.reader.ReaderWay;
22+
import com.graphhopper.routing.ev.EncodedValue;
23+
import com.graphhopper.routing.ev.EncodedValueLookup;
24+
import com.graphhopper.routing.ev.IntEncodedValue;
25+
import com.graphhopper.routing.ev.Lanes;
26+
import com.graphhopper.storage.IntsRef;
27+
28+
import java.util.List;
29+
30+
/**
31+
* https://wiki.openstreetmap.org/wiki/Key:lanes
32+
*/
33+
public class OSMLanesParser implements TagParser {
34+
private final IntEncodedValue lanesEnc;
35+
36+
public OSMLanesParser() {
37+
this.lanesEnc = Lanes.create();
38+
}
39+
40+
@Override
41+
public void createEncodedValues(EncodedValueLookup lookup, List<EncodedValue> registerNewEncodedValue) {
42+
registerNewEncodedValue.add(lanesEnc);
43+
}
44+
45+
@Override
46+
public IntsRef handleWayTags(IntsRef edgeFlags, ReaderWay way, boolean ferry, IntsRef relationFlags) {
47+
int laneCount = 1;
48+
if (way.hasTag("lanes")) {
49+
String noLanes = way.getTag("lanes");
50+
String[] noLanesTok = noLanes.split(";|\\.");
51+
if (noLanesTok.length > 0) {
52+
try {
53+
int noLanesInt = Integer.parseInt(noLanesTok[0]);
54+
// there was a proposal with negative lanes but I cannot find it
55+
if (noLanesInt < 0)
56+
laneCount = 1;
57+
else if (noLanesInt > 6)
58+
laneCount = 6;
59+
else
60+
laneCount = noLanesInt;
61+
} catch (NumberFormatException ex) {
62+
// ignore if no number
63+
}
64+
}
65+
}
66+
lanesEnc.setInt(false, edgeFlags, laneCount);
67+
return edgeFlags;
68+
}
69+
}

core/src/main/java/com/graphhopper/util/details/PathDetailsBuilderFactory.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ public List<PathDetailsBuilder> createPathDetailsBuilders(List<String> requested
8181
builders.add(new EnumDetails<>(key, evl.getEnumEncodedValue(key, Enum.class)));
8282
}
8383

84-
for (String key : Arrays.asList(MtbRating.KEY, HikeRating.KEY, HorseRating.KEY)) {
84+
for (String key : Arrays.asList(MtbRating.KEY, HikeRating.KEY, HorseRating.KEY, Lanes.KEY)) {
8585
if (requestedPathDetails.contains(key) && evl.hasEncodedValue(key))
8686
builders.add(new IntDetails(key, evl.getIntEncodedValue(key)));
8787
}
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
/*
2+
* Licensed to GraphHopper GmbH 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 GmbH 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+
19+
package com.graphhopper.routing.util.parsers;
20+
21+
import com.graphhopper.reader.ReaderWay;
22+
import com.graphhopper.routing.ev.Lanes;
23+
import com.graphhopper.routing.util.EncodingManager;
24+
import com.graphhopper.storage.IntsRef;
25+
import org.junit.jupiter.api.Assertions;
26+
import org.junit.jupiter.api.BeforeEach;
27+
import org.junit.jupiter.api.Test;
28+
29+
class OSMLanesParserTest {
30+
31+
private OSMLanesParser parser;
32+
private EncodingManager em;
33+
34+
@BeforeEach
35+
void setup() {
36+
parser = new OSMLanesParser();
37+
em = new EncodingManager.Builder().add(parser).build();
38+
}
39+
40+
@Test
41+
void basic() {
42+
ReaderWay readerWay = new ReaderWay(1);
43+
IntsRef intsRef = em.createEdgeFlags();
44+
readerWay.setTag("lanes", "4");
45+
parser.handleWayTags(intsRef, readerWay, false, em.createRelationFlags());
46+
Assertions.assertEquals(4, em.getIntEncodedValue(Lanes.KEY).getInt(false, intsRef));
47+
}
48+
49+
@Test
50+
void notTagged() {
51+
ReaderWay readerWay = new ReaderWay(1);
52+
IntsRef intsRef = em.createEdgeFlags();
53+
parser.handleWayTags(intsRef, readerWay, false, em.createRelationFlags());
54+
Assertions.assertEquals(1, em.getIntEncodedValue(Lanes.KEY).getInt(false, intsRef));
55+
}
56+
57+
}

0 commit comments

Comments
 (0)