Hi Chris,

> It's not a straightforward fix in the splitter however I'll see what I can 
> do. I think if I make the cache generation compulsory it will be possible 
> to handle this without too serious an impact on performance.

I understand that this would require deferring the writing of the nodes
until the whole input (nodes, ways, and relations) has been consumed.
I would greatly appreciate a fix.  After that, it would be time to have
the Geofabrik dumps corrected.

By the way, I think that you should restrict this inclusion of all nodes
only to select relation types (only multipolygons come to my mind).  For
instance, route relations (such as the international E road network)
should be clipped at the tile borders.

For what it is worth, here is my attempt at implementing this workaround:

MM> A fairly cheap work-around in mkgmap could be to discard those ways
MM> whose resolvable nodes completely fall outside the bounding box when
MM> some of the nodes cannot be resolved.

It did not make the warnings for the two other multipolygons go away.

        Marko
Index: src/uk/me/parabola/mkgmap/osmstyle/StyledConverter.java
===================================================================
--- src/uk/me/parabola/mkgmap/osmstyle/StyledConverter.java	(revision 1554)
+++ src/uk/me/parabola/mkgmap/osmstyle/StyledConverter.java	(working copy)
@@ -378,6 +378,13 @@ public class StyledConverter implements 
 		this.bbox = bbox;
 	}
 
+	/** Determine if a coordinate is within the bounding box.
+	 * @param co The coordinate
+	 * @return true if inside the bounding box. */
+	public boolean contains(Coord co) {
+		return bbox.contains(co);
+	}
+
 	public void end() {
 		Collection<List<RestrictionRelation>> lists = restrictions.values();
 		for (List<RestrictionRelation> l : lists) {
Index: src/uk/me/parabola/mkgmap/main/StyleTester.java
===================================================================
--- src/uk/me/parabola/mkgmap/main/StyleTester.java	(revision 1554)
+++ src/uk/me/parabola/mkgmap/main/StyleTester.java	(working copy)
@@ -277,6 +277,10 @@ public class StyleTester implements OsmC
 		converter.setBoundingBox(bbox);
 	}
 
+	public boolean contains(Coord co) {
+		return converter.contains(co);
+	}
+
 	public void end() {
 	}
 
Index: src/uk/me/parabola/mkgmap/reader/osm/xml/Osm5XmlHandler.java
===================================================================
--- src/uk/me/parabola/mkgmap/reader/osm/xml/Osm5XmlHandler.java	(revision 1555)
+++ src/uk/me/parabola/mkgmap/reader/osm/xml/Osm5XmlHandler.java	(working copy)
@@ -97,6 +97,8 @@ public class Osm5XmlHandler extends Defa
 	private Way currentWay;
 	private Node currentNodeInWay;
 	private boolean currentWayStartsWithFIXME;
+	private boolean currentWayHasUndefinedNodes;
+	private boolean currentWayHasNodesInArea;
 	private Relation currentRelation;
 	private long currentElementId;
 
@@ -414,6 +416,14 @@ public class Osm5XmlHandler extends Defa
 		} else if (mode == MODE_WAY) {
 			if (qName.equals("way")) {
 				mode = 0;
+				if (currentWayHasUndefinedNodes &&
+					!currentWayHasNodesInArea) {
+
+					// discard incomplete ways that have no nodes within the area
+					resetWay();
+					return;
+				}
+
 				String highway = currentWay.getTag("highway");
 				if(highway != null ||
 				   "ferry".equals(currentWay.getTag("route"))) {
@@ -521,9 +531,7 @@ public class Osm5XmlHandler extends Defa
 					currentWay.deleteTag("natural");
 					shoreline.add(currentWay);
 				}
-				currentNodeInWay = null;
-				currentWayStartsWithFIXME = false;
-				currentWay = null;
+				resetWay();
 				// ways are processed at the end of the document,
 				// may be changed by a Relation class
 			}
@@ -980,15 +988,22 @@ public class Osm5XmlHandler extends Defa
 	private void addWay(String sid) {
 		try {
 			long id = idVal(sid);
+			resetWay();
 			currentWay = new Way(id);
 			wayMap.put(id, currentWay);
-			currentNodeInWay = null;
-			currentWayStartsWithFIXME = false;
 		} catch (NumberFormatException e) {
 			// ignore bad numeric data.
 		}
 	}
 
+	private void resetWay() {
+		currentNodeInWay = null;
+		currentWayStartsWithFIXME = false;
+		currentWayHasUndefinedNodes = false;
+		currentWayHasNodesInArea = false;
+		currentWay = null;
+	}
+
 	private void addNodeToWay(long id) {
 		Coord co = coordMap.get(id);
 		currentNodeInWay = nodeMap.get(id);
@@ -1047,9 +1062,15 @@ public class Osm5XmlHandler extends Defa
 			co.incHighwayCount(); // nodes (way joins) will have highwayCount > 1
 			if (minimumArcLength != null || generateSea)
 				nodeIdMap.put(co, id);
+
+			if (converter.contains(co))
+				currentWayHasNodesInArea = true;
+		}
+		else if (currentWay != null) {
+			currentWayHasUndefinedNodes = true;
+			if (reportUndefinedNodes)
+				log.warn("Way " + currentWay.toBrowseURL() + " references undefined node " + id);
 		}
-		else if(reportUndefinedNodes && currentWay != null)
-			log.warn("Way " + currentWay.toBrowseURL() + " references undefined node " + id);
 	}
 
 	public void setConverter(OsmConverter converter) {
Index: src/uk/me/parabola/mkgmap/reader/osm/OsmConverter.java
===================================================================
--- src/uk/me/parabola/mkgmap/reader/osm/OsmConverter.java	(revision 1554)
+++ src/uk/me/parabola/mkgmap/reader/osm/OsmConverter.java	(working copy)
@@ -17,6 +17,7 @@
 package uk.me.parabola.mkgmap.reader.osm;
 
 import uk.me.parabola.imgfmt.app.Area;
+import uk.me.parabola.imgfmt.app.Coord;
 
 /**
  * @author Steve Ratcliffe
@@ -68,6 +69,11 @@ public interface OsmConverter {
 	 */
 	public void setBoundingBox(Area bbox);
 
+	/** Determine if a coordinate is within the bounding box.
+	 * @param co The coordinate
+	 * @return true if inside the bounding box. */
+	public boolean contains(Coord co);
+
 	/**
 	 * Called when all conversion has been done.
 	 */
_______________________________________________
mkgmap-dev mailing list
[email protected]
http://www.mkgmap.org.uk/mailman/listinfo/mkgmap-dev

Reply via email to