Hi

A while ago I noticed that mkgmap doesn't handle the case where the
inner or outer of a multipolygon relation is a multipolygon.

It doesn't handle it in two ways:

1/ During the reading of relations, if the relation references another
relation that hasn't been read yet, it is added to a deferred list and
when the second one is defined, the element is added to the first.
However, for multiPolygons, the processing is performed as each one is
read.

2/ In MultiPolygonRelation, an inner or outer that is a multipolygon
relation is not handled; instead the warning "Non way member in role"
is generated.

The above warning is also generated for members with role "subarea";
these should be ignored without warning.

I've attached a patch to generated warnings in case 1/ and to improve
the warnings in case 2/. In the longer term it should be implemented.

I was surprised how few inner/outer as multipolygon there are in
OSM/British Isles. Maybe it isn't well supported by the various map
generating software packages and so people don't use it.

Regards
Ticker

Index: src/uk/me/parabola/mkgmap/reader/osm/ElementSaver.java
===================================================================
--- src/uk/me/parabola/mkgmap/reader/osm/ElementSaver.java	(revision 4175)
+++ src/uk/me/parabola/mkgmap/reader/osm/ElementSaver.java	(working copy)
@@ -161,8 +161,17 @@
 
 			List<Map.Entry<String,Relation>> entries = deferredRelationMap.remove(id);
 			if (entries != null)
-				for (Map.Entry<String,Relation> entry : entries)
+				for (Map.Entry<String,Relation> entry : entries) {
+					if (rel instanceof MultiPolygonRelation &&
+					    (entry.getKey().equals("inner") || entry.getKey().equals("outer")))
+						// defining a multipolygon relation that has earlier been
+						// referenced in another multipolygon (inner/outer) and deferred.
+						// Unfortunately the earlier relation has been processed
+						// and adding this as member doesn't work.
+						// Would need to rework deferring to handle this.
+						log.error("deferRelation MKGMAP UNIMPLEMENTED: adding", entry.getKey(), rel, "to", entry.getValue(), "but it has already been processed");
 					entry.getValue().addElement(entry.getKey(), rel);
+				}
 		}
 	}
 
@@ -339,6 +348,10 @@
 	}
 
 	public void deferRelation(long id, Relation rel, String role) {
+//		if (role.equals("inner") || role.equals("outer"))
+//			log.error("deferRelation for inner/outer not implemented", id, rel, role);
+// It is better to flag this when the missing relation is defined, so that if it never is, ie an outer
+// not in this map tile, no error is flagged
 		// The relation may be defined later in the input.
 		// Defer the lookup.
 		Map.Entry<String,Relation> entry =
Index: src/uk/me/parabola/mkgmap/reader/osm/MultiPolygonRelation.java
===================================================================
--- src/uk/me/parabola/mkgmap/reader/osm/MultiPolygonRelation.java	(revision 4175)
+++ src/uk/me/parabola/mkgmap/reader/osm/MultiPolygonRelation.java	(working copy)
@@ -747,6 +747,7 @@
 		ArrayList<Way> allWays = new ArrayList<>();
 
 		for (Map.Entry<String, Element> r_e : getElements()) {
+			String role = r_e.getKey();
 			if (r_e.getValue() instanceof Way) {
 				if (((Way)r_e.getValue()).getPoints().isEmpty()) {
 					log.warn("Way",r_e.getValue(),"has no points and cannot be used for the multipolygon",toBrowseURL());
@@ -753,11 +754,21 @@
 				} else {
 					allWays.add((Way) r_e.getValue());
 				}
-			} else if (r_e.getValue() instanceof Node == false || 
-					("admin_centre".equals(r_e.getKey()) == false && "label".equals(r_e.getKey()) == false)) {
-				log.warn("Non way member in role", r_e.getKey(), r_e.getValue().toBrowseURL(),
+			} else if (r_e.getValue() instanceof MultiPolygonRelation) {
+				if ("outer".equals(role) || "inner".equals(role))
+// should also have clause "|| role.isEmpty()" - old OSM; normally implying "outer", but generates lots of errors
+					log.error("Multipolygon MKGMAP UNIMPLEMENTED member in role", role, r_e.getValue().toBrowseURL(),
+						 "in multipolygon", toBrowseURL(), toTagString());
+				else if ("subarea".equals(role) == false)  // ignore these
+					log.warn("MultiPolygon member in role", role, r_e.getValue().toBrowseURL(),
 						"in multipolygon", toBrowseURL(), toTagString());
-			}
+			} else if (r_e.getValue() instanceof Node) {
+				if ("admin_centre".equals(role) == false && "label".equals(role) == false)
+					log.warn("Node member in role", role, r_e.getValue().toBrowseURL(),
+						"in multipolygon", toBrowseURL(), toTagString());
+			} else
+			    	log.warn("Unknown member in role", role, r_e.getValue().toBrowseURL(),
+						"in multipolygon", toBrowseURL(), toTagString());
 		}
 		return allWays;
 	}
Index: src/uk/me/parabola/mkgmap/reader/osm/Relation.java
===================================================================
--- src/uk/me/parabola/mkgmap/reader/osm/Relation.java	(revision 4175)
+++ src/uk/me/parabola/mkgmap/reader/osm/Relation.java	(working copy)
@@ -41,7 +41,7 @@
 	}
 	
 	public String toString() {
-		return "RELATION: " + getId();
+		return "RELATION: " + getId() + " type=" + getTag("type");
 	}
 
 	/**
_______________________________________________
mkgmap-dev mailing list
[email protected]
http://www.mkgmap.org.uk/mailman/listinfo/mkgmap-dev

Reply via email to