Fed up of being routed in your car down city streets only to find the
way is blocked by a bollard? Well, if so, this is the patch for you.

If a way has a bollard on a point, the segments of the way that
connect to the bollard have access restrictions placed on them. By
default, a bollard implies: access=no, foot=yes, bicycle=yes.

Testing using mapsource shows that it generally works as expected
although if the destination cannot be reached by any other route, it
routes straight through the bollard rather than failing! If the
destination can be reached by some other route, even if the route is
really long, it will avoid the bollard.

I have chosen Garmin code 0x660f (pillar) for the bollard. On my etrex
it appears as a small dot in the way.

As usual, all feedback is welcome.

Cheers,

Mark
diff --git a/resources/styles/default/points b/resources/styles/default/points
index 1c3ae8f..28d1fc2 100644
--- a/resources/styles/default/points
+++ b/resources/styles/default/points
@@ -166,3 +166,5 @@ tourism=theme_park [0x2c01 resolution 20]
 tourism=viewpoint [0x2c04 resolution 20]
 tourism=wine_cellar [0x2c0a resolution 20]
 tourism=zoo [0x2c07 resolution 20]
+
+barrier=bollard [0x660f resolution 20]
diff --git a/src/uk/me/parabola/mkgmap/osmstyle/StyledConverter.java b/src/uk/me/parabola/mkgmap/osmstyle/StyledConverter.java
index aa5bab1..05f60ac 100644
--- a/src/uk/me/parabola/mkgmap/osmstyle/StyledConverter.java
+++ b/src/uk/me/parabola/mkgmap/osmstyle/StyledConverter.java
@@ -42,6 +42,7 @@ import uk.me.parabola.mkgmap.general.MapPoint;
 import uk.me.parabola.mkgmap.general.MapRoad;
 import uk.me.parabola.mkgmap.general.MapShape;
 import uk.me.parabola.mkgmap.general.RoadNetwork;
+import uk.me.parabola.mkgmap.reader.osm.CoordPOI;
 import uk.me.parabola.mkgmap.reader.osm.Element;
 import uk.me.parabola.mkgmap.reader.osm.GType;
 import uk.me.parabola.mkgmap.reader.osm.Node;
@@ -426,6 +427,88 @@ public class StyledConverter implements OsmConverter {
 			}
 		}
 
+		// process any Coords that have a POI associated with them
+		if("true".equals(way.getTag("mkgmap:way-has-pois"))) {
+			List<Coord> points = way.getPoints();
+			for(int i = 0; i < points.size(); ++i) {
+				Coord p = points.get(i);
+				// check if this point is a barrier and if so,
+				// transfer any access restrictions to the way
+				if(p instanceof CoordPOI) {
+					CoordPOI cp = (CoordPOI)p;
+					Node node = cp.getNode();
+					String barrier = node.getTag("barrier");
+					if(barrier != null) {
+
+						// split the way at a point after the barrier
+						// to limit the region that has restricted
+						// access (taking care not to produce a short
+						// arc)
+						if((i + 1) < points.size() &&
+						   !p.equals(points.get(i + 1)) &&
+						   ((i + 2) == points.size() ||
+							!points.get(i + 1).equals(points.get(i + 2)))) {
+							//log.warn("Splitting way " + way.getName() + " at point " + (i + 1) + " after " + barrier);
+							Way tail = splitWayAt(way, i + 1);
+							// recursively process tail of road
+							addRoad(tail, gt);
+						}
+
+						String access = node.getTag("access");
+						String foot = node.getTag("foot");
+						String bicycle = node.getTag("bicycle");
+						if("bollard".equals(barrier)) {
+							if(access == null)
+								access = "no";
+							if(foot == null)
+								foot = "yes";
+							if(bicycle == null)
+								bicycle = "yes";
+						}
+						else if("cycle_barrier".equals(barrier)) {
+							if(access == null)
+								access = "no";
+							if(foot == null)
+								foot = "yes";
+						}
+
+						if(access != null)
+							way.addTag("access", access);
+						if(foot != null)
+							way.addTag("foot", foot);
+						if(bicycle != null)
+							way.addTag("bicycle", bicycle);
+
+						log.info("Way " + way.getName() + " has " + barrier);
+					}
+				}
+
+				// if this is not the first point in the way, see if
+				// the next point is a barrier and if so, split the
+				// way here
+				if(i > 0 && (i + 1) < points.size()) {
+					Coord p1 = points.get(i + 1);
+					if(p1 instanceof CoordPOI) {
+						CoordPOI cp = (CoordPOI)p1;
+						Node node = cp.getNode();
+						String barrier = node.getTag("barrier");
+						if(barrier != null) {
+							// split the way at a point before the
+							// barrier to limit the region that has
+							// restricted access (taking care not to
+							// produce a short arc)
+							if(!p.equals(p1)) {
+								//log.warn("Splitting way " + way.getName() + " at point " + i + " before " + barrier);
+								Way tail = splitWayAt(way, i);
+								// recursively process tail of road
+								addRoad(tail, gt);
+							}
+						}
+					}
+				}
+			}
+		}
+
 		// if there is a bounding box, clip the way with it
 
 		List<Way> clippedWays = null;
diff --git a/src/uk/me/parabola/mkgmap/reader/osm/CoordPOI.java b/src/uk/me/parabola/mkgmap/reader/osm/CoordPOI.java
new file mode 100644
index 0000000..409965b
--- /dev/null
+++ b/src/uk/me/parabola/mkgmap/reader/osm/CoordPOI.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2008 Steve Ratcliffe
+ * 
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 2 as
+ *  published by the Free Software Foundation.
+ * 
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ * 
+ * 
+ * Author: Steve Ratcliffe
+ * Create date: 13-Jul-2008
+ */
+package uk.me.parabola.mkgmap.reader.osm;
+
+import uk.me.parabola.imgfmt.app.Coord;
+
+/**
+ * A coordinate that has a POI
+ *
+ * @author Steve Ratcliffe
+ */
+public class CoordPOI extends Coord {
+	private final Node node;
+
+	/**
+	 * Construct from co-ordinates that are already in map-units.
+	 *
+	 * @param latitude The latitude in map units.
+	 * @param longitude The longitude in map units.
+	 * @param node The Node that represents the POI.
+	 */
+	public CoordPOI(int latitude, int longitude, Node node) {
+		super(latitude, longitude);
+		this.node = node;
+	}
+
+	public Node getNode() {
+		return node;
+	}
+}
diff --git a/src/uk/me/parabola/mkgmap/reader/osm/xml/Osm5XmlHandler.java b/src/uk/me/parabola/mkgmap/reader/osm/xml/Osm5XmlHandler.java
index 2e8ccbb..cd2dfba 100644
--- a/src/uk/me/parabola/mkgmap/reader/osm/xml/Osm5XmlHandler.java
+++ b/src/uk/me/parabola/mkgmap/reader/osm/xml/Osm5XmlHandler.java
@@ -29,6 +29,7 @@ import uk.me.parabola.imgfmt.app.Exit;
 import uk.me.parabola.log.Logger;
 import uk.me.parabola.mkgmap.general.MapDetails;
 import uk.me.parabola.mkgmap.general.RoadNetwork;
+import uk.me.parabola.mkgmap.reader.osm.CoordPOI;
 import uk.me.parabola.mkgmap.reader.osm.Element;
 import uk.me.parabola.mkgmap.reader.osm.GeneralRelation;
 import uk.me.parabola.mkgmap.reader.osm.MultiPolygonRelation;
@@ -636,6 +637,19 @@ class Osm5XmlHandler extends DefaultHandler {
 		Coord co = coordMap.get(id);
 		//co.incCount();
 		if (co != null) {
+			// if this Coord is also a POI, replace it with an equivalent
+			// CoordPOI that contains a reference to the POI's Node so we
+			// can access the POI's tags
+			Node node = nodeMap.get(id);
+			if(node != null) {
+				if(!(co instanceof CoordPOI)) {
+					co = new CoordPOI(co.getLatitude(), co.getLongitude(), node);
+					coordMap.put(id, co);
+				}
+				// flag this Way as having a CoordPOI so it will be
+				// processed later
+				currentWay.addTag("mkgmap:way-has-pois", "true");
+			}
 			currentWay.addPoint(co);
 			if(minimumArcLength != null)
 				nodeIdMap.put(co, id);
_______________________________________________
mkgmap-dev mailing list
mkgmap-dev@lists.mkgmap.org.uk
http://www.mkgmap.org.uk/mailman/listinfo/mkgmap-dev

Reply via email to