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