Skip to content

Commit 2bf3b77

Browse files
author
Peter
committed
Merge pull request graphhopper#62 from graphhopper/improvesurface
improve bike and car speeds via surface
2 parents 1bdf343 + 90525e8 commit 2bf3b77

File tree

5 files changed

+141
-41
lines changed

5 files changed

+141
-41
lines changed

core/src/main/java/com/graphhopper/reader/OSMElement.java

Lines changed: 21 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -151,25 +151,35 @@ public void setTag(String name, String value) {
151151

152152
/**
153153
* Chaeck that the object has a given tag with a given value.
154-
*
155-
* @param name
156-
* @param value
157-
* @return
158154
*/
159-
public boolean hasTag(String name, String value) {
155+
public boolean hasTag(String key, String value) {
160156
if (tags == null)
161157
return false;
162158

163-
String val = tags.get(name);
159+
String val = tags.get(key);
164160
return value.equals(val);
165161
}
166162

167163
/**
168-
* Check that a given tag has one of a list of values
169-
*
170-
* @param key
171-
* @param values
172-
* @return
164+
* Check that a given tag has one of the specified values.
165+
*/
166+
public boolean hasTag(String key, String... values) {
167+
if (tags == null)
168+
return false;
169+
170+
String osmValue = tags.get(key);
171+
if (osmValue == null)
172+
return false;
173+
174+
for (String val : values) {
175+
if (val.equals(osmValue))
176+
return true;
177+
}
178+
return false;
179+
}
180+
181+
/**
182+
* Check that a given tag has one of the specified values.
173183
*/
174184
public final boolean hasTag(String key, Set<String> values) {
175185
if (tags == null)

core/src/main/java/com/graphhopper/routing/util/BikeFlagEncoder.java

Lines changed: 55 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
package com.graphhopper.routing.util;
2020

2121
import com.graphhopper.reader.OSMWay;
22+
import com.graphhopper.util.Helper;
2223

2324
import java.util.HashMap;
2425
import java.util.HashSet;
@@ -52,12 +53,11 @@ public class BikeFlagEncoder extends AbstractFlagEncoder {
5253
add("residential");
5354
}
5455
};
55-
private static final Map<String, Integer> SPEED = new BikeSpeed();
5656
private HashSet<String> intended = new HashSet<String>();
5757
private HashSet<String> oppositeLanes = new HashSet<String>();
5858

5959
public BikeFlagEncoder() {
60-
super(8, 2, SPEED.get("cycleway"), SPEED.get("road"));
60+
super(8, 2, HIGHWAY_SPEED.get("cycleway"), HIGHWAY_SPEED.get("road"));
6161

6262
// strict set, usually vehicle and agricultural/forestry are ignored by cyclists
6363
restrictions = new String[]{"bicycle", "access"};
@@ -75,14 +75,6 @@ public BikeFlagEncoder() {
7575
oppositeLanes.add("opposite_track");
7676
}
7777

78-
public int getSpeed(String string) {
79-
// TODO use surface for speed!
80-
Integer speed = SPEED.get(string);
81-
if (speed == null)
82-
throw new IllegalStateException("bike, no speed found for:" + string);
83-
return speed;
84-
}
85-
8678
@Override public String toString() {
8779
return "BIKE";
8880
}
@@ -128,9 +120,8 @@ public int handleWayTags(int allowed, OSMWay way) {
128120
if ((allowed & ferryBit) == 0) {
129121
// http://wiki.openstreetmap.org/wiki/Cycleway
130122
// http://wiki.openstreetmap.org/wiki/Map_Features#Cycleway
131-
String highwayValue = way.getTag("highway");
132-
int speed = getSpeed(highwayValue);
133-
if ((way.hasTag("oneway", oneways) || way.hasTag("junction","roundabout"))
123+
int speed = getSpeed(way);
124+
if ((way.hasTag("oneway", oneways) || way.hasTag("junction", "roundabout"))
134125
&& !way.hasTag("oneway:bicycle", "no")
135126
&& !way.hasTag("cycleway", oppositeLanes)) {
136127

@@ -153,23 +144,65 @@ public boolean isSaveHighway(String highwayValue) {
153144
return saveHighwayTags.contains(highwayValue);
154145
}
155146

156-
private static class BikeSpeed extends HashMap<String, Integer> {
157-
147+
int getSpeed(OSMWay way) {
148+
String s = way.getTag("surface");
149+
if (!Helper.isEmpty(s)) {
150+
Integer sInt = SURFACE_SPEED.get(s);
151+
if (sInt != null)
152+
return sInt;
153+
}
154+
String tt = way.getTag("tracktype");
155+
if (!Helper.isEmpty(tt)) {
156+
Integer tInt = TRACKTYPE_SPEED.get(tt);
157+
if (tInt != null)
158+
return tInt;
159+
}
160+
String highway = way.getTag("highway");
161+
if (!Helper.isEmpty(tt)) {
162+
Integer hwInt = HIGHWAY_SPEED.get(highway);
163+
if (hwInt != null)
164+
return hwInt;
165+
}
166+
return 10;
167+
}
168+
private static final Map<String, Integer> TRACKTYPE_SPEED = new HashMap<String, Integer>() {
158169
{
159-
put("living_street", 5);
170+
put("grade1", 16); // paved
171+
put("grade2", 12); // now unpaved ...
172+
put("grade3", 12);
173+
put("grade4", 10);
174+
put("grade5", 8); // like sand/grass
175+
}
176+
};
177+
private static final Map<String, Integer> SURFACE_SPEED = new HashMap<String, Integer>() {
178+
{
179+
put("asphalt", 18);
180+
put("concrete", 18);
181+
put("paved", 16);
182+
put("unpaved", 12);
183+
put("gravel", 12);
184+
put("ground", 12);
185+
put("dirt", 10);
186+
put("paving_stones", 8);
187+
put("grass", 8);
188+
}
189+
};
190+
private static final Map<String, Integer> HIGHWAY_SPEED = new HashMap<String, Integer>() {
191+
{
192+
put("living_street", 6);
160193
put("bridleway", 10);
161194

162-
put("cycleway", 10);
195+
put("cycleway", 14);
163196
put("path", 10);
164197
put("road", 10);
165198
put("track", 10);
166199

167-
put("trunk", 20);
168-
put("primary", 20);
169-
put("secondary", 20);
170-
put("tertiary", 20);
200+
put("trunk", 18);
201+
put("primary", 18);
202+
put("secondary", 18);
203+
put("tertiary", 18);
171204
put("unclassified", 10);
172205
put("residential", 10);
173206
}
174-
}
207+
};
175208
}

core/src/main/java/com/graphhopper/routing/util/CarFlagEncoder.java

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -20,15 +20,15 @@
2020

2121
import com.graphhopper.reader.OSMWay;
2222
import java.util.HashMap;
23+
import java.util.HashSet;
2324
import java.util.Map;
25+
import java.util.Set;
2426

2527
/**
2628
* @author Peter Karich
2729
*/
2830
public class CarFlagEncoder extends AbstractFlagEncoder {
2931

30-
private static final Map<String, Integer> SPEED = new CarSpeed();
31-
3232
public CarFlagEncoder() {
3333
super(0, 2, SPEED.get("secondary"), SPEED.get("motorway"));
3434
restrictions = new String[]{"motorcar", "motor_vehicle", "vehicle", "access"};
@@ -47,7 +47,7 @@ public boolean isService(int flags) {
4747
return getSpeedPart(flags) * factor == SPEED.get("service");
4848
}
4949

50-
public int getSpeed(String string) {
50+
int getSpeed(String string) {
5151
Integer speed = SPEED.get(string);
5252
if (speed == null)
5353
throw new IllegalStateException("car, no speed found for:" + string);
@@ -93,6 +93,10 @@ public int handleWayTags(int allowed, OSMWay way) {
9393
if (maxspeed > 0 && speed > maxspeed)
9494
speed = maxspeed;
9595

96+
// limit speed to max 30 km/h if bad surface
97+
if (speed > 30 && way.hasTag("surface", BAD_SURFACE))
98+
speed = 30;
99+
96100
// usually used with a node, this does not work as intended
97101
// if( "toll_booth".equals( osmProperties.get( "barrier" ) ) )
98102
if (way.hasTag("oneway", oneways) || way.hasTag("junction", "roundabout")) {
@@ -114,14 +118,24 @@ public int handleWayTags(int allowed, OSMWay way) {
114118
@Override public String toString() {
115119
return "CAR";
116120
}
117-
121+
private static final Set<String> BAD_SURFACE = new HashSet<String>() {
122+
{
123+
add("cobblestone");
124+
add("grass_paver");
125+
add("gravel");
126+
add("sand");
127+
add("paving_stones");
128+
add("dirt");
129+
add("ground");
130+
add("grass");
131+
}
132+
};
118133
/**
119134
* A map which associates string to speed. Get some impression:
120135
* http://www.itoworld.com/map/124#fullscreen
121136
* http://wiki.openstreetmap.org/wiki/OSM_tags_for_routing/Maxspeed
122137
*/
123-
private static class CarSpeed extends HashMap<String, Integer> {
124-
138+
private static final Map<String, Integer> SPEED = new HashMap<String, Integer>() {
125139
{
126140
// autobahn
127141
put("motorway", 100);
@@ -148,5 +162,5 @@ private static class CarSpeed extends HashMap<String, Integer> {
148162
// forestry stuff
149163
put("track", 20);
150164
}
151-
}
165+
};
152166
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
/*
2+
* Licensed to Peter Karich under one or more contributor license
3+
* agreements. See the NOTICE file distributed with this work for
4+
* additional information regarding copyright ownership.
5+
*
6+
* Peter Karich licenses this file to you under the Apache License,
7+
* Version 2.0 (the "License"); you may not use this file except
8+
* in compliance with the License. You may obtain a copy of the
9+
* License at
10+
*
11+
* http://www.apache.org/licenses/LICENSE-2.0
12+
*
13+
* Unless required by applicable law or agreed to in writing, software
14+
* distributed under the License is distributed on an "AS IS" BASIS,
15+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16+
* See the License for the specific language governing permissions and
17+
* limitations under the License.
18+
*/
19+
package com.graphhopper.reader;
20+
21+
import org.junit.Test;
22+
import static org.junit.Assert.*;
23+
24+
/**
25+
*
26+
* @author Peter Karich
27+
*/
28+
public class OSMElementTest {
29+
30+
@Test
31+
public void testHasTag() {
32+
OSMElement instance = new OSMWay();
33+
instance.setTag("surface", "something");
34+
assertTrue(instance.hasTag("surface", "now", "something"));
35+
assertFalse(instance.hasTag("surface", "now", "not"));
36+
}
37+
}

core/src/test/java/com/graphhopper/routing/util/BikeFlagEncoderTest.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
*/
1919
package com.graphhopper.routing.util;
2020

21+
import com.graphhopper.reader.OSMWay;
2122
import org.junit.Test;
2223
import static org.junit.Assert.*;
2324

@@ -32,6 +33,11 @@ public void testGetSpeed() {
3233
BikeFlagEncoder instance = new BikeFlagEncoder();
3334
int result = instance.flags(10, true);
3435
assertEquals(10, instance.getSpeed(result));
35-
assertEquals(10, instance.getSpeed("cycleway"));
36+
OSMWay way = new OSMWay();
37+
way.setTag("highway", "road");
38+
assertEquals(10, instance.getSpeed(way));
39+
40+
way.setTag("surface", "paved");
41+
assertEquals(16, instance.getSpeed(way));
3642
}
3743
}

0 commit comments

Comments
 (0)