This is something that was briefly discussed not too long ago and the
idea is that a road's speed or class can be modified by the
presence of a POI that defines new values for either/both of them. This,
hopefully, will make ways that have stuff like traffic signals and
crossings, etc. less attractive to route over.

The values are specified using mkgmap:road-speed and mkgmap:road-class
tags added to the POI.

These tags expect an integer value, optionally preceded by a + or -
which make the adjustment relative to the original value.

For example, mkgmap:road-speed=3 sets the speed to 3 and
mkgmap:road-speed=-1 reduces the speed by 1 from whatever value it had
before.

Here's some possible rules for the points file:

highway=traffic_signals { add mkgmap:road-speed = '-1' }
highway=crossing { add mkgmap:road-speed = '-1' }
highway=mini_roundabout { add mkgmap:road-speed = '1' }

The region of the way that has its speed/class modified is limited to
the closest points either side of the POI. Not sure if that's the right
thing to do yet. Needs playing with.

You need to specify the --link-pois-to-ways option to enable this
functionality.

All feedback welcome.

Mark
diff --git a/src/uk/me/parabola/mkgmap/osmstyle/StyledConverter.java b/src/uk/me/parabola/mkgmap/osmstyle/StyledConverter.java
index 5e8e3f3..e0c42b2 100644
--- a/src/uk/me/parabola/mkgmap/osmstyle/StyledConverter.java
+++ b/src/uk/me/parabola/mkgmap/osmstyle/StyledConverter.java
@@ -629,15 +629,64 @@ public class StyledConverter implements OsmConverter {
 				}
 			}
 
-			// at this time, we are only looking for POIs that have
-			// the "access" tag defined - if they do, copy the access
-			// permissions to the way - what we want to achieve is
-			// modifying the way's access permissions where it passes
-			// through the POI without affecting the rest of the way
-			// too much - to that end we split the way before and
-			// after the POI - if necessary, extra points are inserted
-			// before and after the POI to limit the size of the
-			// affected region
+			// now look for POIs that modify the way's road class or
+			// speed
+			for(int i = 0; i < points.size(); ++i) {
+				Coord p = points.get(i);
+				if(p instanceof CoordPOI) {
+					CoordPOI cp = (CoordPOI)p;
+					Node node = cp.getNode();
+					String roadClass = node.getTag("mkgmap:road-class");
+					String roadSpeed = node.getTag("mkgmap:road-speed");
+					if(roadClass != null || roadSpeed != null) {
+						// if the way has more than one point
+						// following this one, split the way at the
+						// next point to limit the size of the
+						// affected region
+						if((i + 2) < points.size() &&
+						   safeToSplitWay(points, i + 1, i, points.size() - 1)) {
+							Way tail = splitWayAt(way, i + 1);
+							// recursively process tail of way
+							addRoad(tail, gt);
+						}
+						// we can't modify the road class or type in
+						// the GType as that's global so for now just
+						// transfer the tags to the way
+						if(roadClass != null)
+							way.addTag("mkgmap:road-class", roadClass);
+						if(roadSpeed != null)
+							way.addTag("mkgmap:road-speed", roadSpeed);
+					}
+				}
+
+				// if this isn't the first (or last) point in the way
+				// and the next point modifies the way's speed/class,
+				// split the way at this point to limit the size of
+				// the affected region
+				if(i > 0 &&
+				   (i + 1) < points.size() &&
+				   points.get(i + 1) instanceof CoordPOI) {
+					CoordPOI cp = (CoordPOI)points.get(i + 1);
+					Node node = cp.getNode();
+					if(node.getTag("mkgmap:road-class") != null ||
+					   node.getTag("mkgmap:road-speed") != null) {
+						if(safeToSplitWay(points, i, i - 1, points.size() - 1)) {
+							Way tail = splitWayAt(way, i);
+							// recursively process tail of way
+							addRoad(tail, gt);
+						}
+					}
+				}
+			}
+
+			// now look for POIs that have the "access" tag defined -
+			// if they do, copy the access permissions to the way -
+			// what we want to achieve is modifying the way's access
+			// permissions where it passes through the POI without
+			// affecting the rest of the way too much - to that end we
+			// split the way before and after the POI - if necessary,
+			// extra points are inserted before and after the POI to
+			// limit the size of the affected region
 
 			final double stubSegmentLength = 25; // metres
 			for(int i = 0; i < points.size(); ++i) {
@@ -991,24 +1040,63 @@ public class StyledConverter implements OsmConverter {
 
 		MapRoad road = new MapRoad(way.getId(), line);
 
-		// set road parameters.
-		road.setRoadClass(gt.getRoadClass());
-		if (way.isBoolTag("oneway")) {
-			road.setDirection(true);
-			road.setOneway();
+		// set road parameters 
+
+		// road class (can be overriden by mkgmap:road-class tag)
+		int roadClass = gt.getRoadClass();
+		String val = way.getTag("mkgmap:road-class");
+		if(val != null) {
+			if(val.startsWith("-")) {
+				roadClass -= Integer.decode(val.substring(1));
+			}
+			else if(val.startsWith("+")) {
+				roadClass += Integer.decode(val.substring(1));
+			}
+			else {
+				roadClass = Integer.decode(val);
+			}
+			if(roadClass > 4)
+				roadClass = 4;
+			else if(roadClass < 0)
+				roadClass = 0;
+			log.info("POI changing road class of " + way.getName() + " (" + way.getId() + ") to " + roadClass + " at " + points.get(0));
 		}
+		road.setRoadClass(roadClass);
 
-		int speedIdx = -1;
+		// road speed (can be overriden by maxspeed (OSM) tag or
+		// mkgmap:road-speed tag)
+		int roadSpeed = gt.getRoadSpeed();
 		if(!ignoreMaxspeeds) {
 			// maxspeed attribute overrides default for road type
 			String maxSpeed = way.getTag("maxspeed");
 			if(maxSpeed != null) {
-				speedIdx = getSpeedIdx(maxSpeed);
-				log.info(debugWayName + " maxspeed=" + maxSpeed + ", speedIndex=" + speedIdx);
+				roadSpeed = getSpeedIdx(maxSpeed);
+				log.info(debugWayName + " maxspeed=" + maxSpeed + ", speedIndex=" + roadSpeed);
 			}
 		}
-
-		road.setSpeed(speedIdx >= 0? speedIdx : gt.getRoadSpeed());
+		val = way.getTag("mkgmap:road-speed");
+		if(val != null) {
+			if(val.startsWith("-")) {
+				roadSpeed -= Integer.decode(val.substring(1));
+			}
+			else if(val.startsWith("+")) {
+				roadSpeed += Integer.decode(val.substring(1));
+			}
+			else {
+				roadSpeed = Integer.decode(val);
+			}
+			if(roadSpeed > 7)
+				roadSpeed = 7;
+			else if(roadSpeed < 0)
+				roadSpeed = 0;
+			log.info("POI changing road speed of " + way.getName() + " (" + way.getId() + ") to " + roadSpeed + " at " + points.get(0));
+		}
+		road.setSpeed(roadSpeed);
+		
+		if (way.isBoolTag("oneway")) {
+			road.setDirection(true);
+			road.setOneway();
+		}
 
 		boolean[] noAccess = new boolean[RoadNetwork.NO_MAX];
 		String highwayType = way.getTag("highway");
_______________________________________________
mkgmap-dev mailing list
mkgmap-dev@lists.mkgmap.org.uk
http://www.mkgmap.org.uk/mailman/listinfo/mkgmap-dev

Reply via email to