The patch fixes the following tagging:
polygon A: leisure=nature_reserve (the complete area)
polygon B: natural=water (only the inner area)
multipolygon relation: natural=wood and outer=polygon A and inner=polygon B (only the surrounding area) => See also thread http://www.mkgmap.org.uk/pipermail/mkgmap-dev/2010q3/009112.html

The patch fixes also problems with cascaded multipolygons.
MP1:
outer P1 [natural=wood]
inner P2 [natural=water]

MP2:
outer P2 [natural=water]
inner P3 [natural=sand]

Without this patch P2 was added twice to the map. Once with the complete polygon area and once with the cut out P3.

I think this patch will also make it possible to remove the unlovely tag-removal-map used by the multipolygons. But first I have to check that in deep.

Please test this patch carefully with some of your well known multipolygons! I would not be surprised by the patch containing some unwanted stuff...

WanMil
Index: src/uk/me/parabola/mkgmap/reader/osm/MultiPolygonRelation.java
===================================================================
--- src/uk/me/parabola/mkgmap/reader/osm/MultiPolygonRelation.java	(revision 1713)
+++ src/uk/me/parabola/mkgmap/reader/osm/MultiPolygonRelation.java	(working copy)
@@ -764,7 +764,7 @@
 			
 			// check if the polygon has tags and therefore should be processed
 			boolean processPolygon = currentPolygon.outer
-					|| hasTags(currentPolygon.polygon);
+					|| (holes.isEmpty()==false);
 
 			if (processPolygon) {
 				List<Way> singularOuterPolygons;
@@ -781,53 +781,53 @@
 						innerWays);
 				}
 				
-				if (currentPolygon.polygon.getOriginalWays().size() == 1) {
-					// the original way was a closed polygon which
-					// has been replaced by the new cut polygon
-					// the original way should not appear
-					// so we remove all tags
-					removeTagInOrgWays(currentPolygon.polygon, null, null);
-					currentPolygon.polygon.removeAllTags();
-				}
-
-				boolean useRelationTags = currentPolygon.outer
-						&& hasTags(this);
-				if (useRelationTags) {
-					// the multipolygon contains tags that overwhelm the
-					// tags of the outer polygon
-					removeTagsInOrgWays(this, currentPolygon.polygon);
-
-					for (Way p : singularOuterPolygons) {
-						p.copyTags(this);
-						p.deleteTag("type");
+				if (singularOuterPolygons.isEmpty()==false) {
+					// handle the tagging 
+					if (currentPolygon.outer && hasTags(this)) {
+						// use the tags of the multipolygon
+						for (Way p : singularOuterPolygons) {
+							// overwrite all tags
+							p.copyTags(this);
+							p.deleteTag("type");
+						}
+						// remove the multipolygon tags in the original ways of the current polygon
+						removeTagsInOrgWays(this, currentPolygon.polygon);
+					} else {
+						// use the tags of the original ways
+						currentPolygon.polygon.mergeTagsFromOrgWays();
+						for (Way p : singularOuterPolygons) {
+							// overwrite all tags
+							p.copyTags(currentPolygon.polygon);
+						}
+						// remove the current polygon tags in its original ways
+						removeTagsInOrgWays(currentPolygon.polygon, currentPolygon.polygon);
 					}
-				} 
-					
-				if (currentPolygon.outer && outmostPolygonProcessing) {
-					// this is the outer most polygon - copy its tags. They will be used
-					// later for tagging of the lines
+				
+					if (currentPolygon.outer && outmostPolygonProcessing) {
+						// this is the outer most polygon - copy its tags. They will be used
+						// later for tagging of the lines
 
-					// all cut polygons have the same tags - get the first way to copy them
-					if (singularOuterPolygons.isEmpty()==false) {
+						// all cut polygons have the same tags - get the first way to copy them
 						Way outerWay = singularOuterPolygons.get(0);
 						for (Entry<String, String> tag : outerWay.getEntryIteratable()) {
 							outerTags.put(tag.getKey(), tag.getValue());
 						}
 						outmostPolygonProcessing = false;
 					}
-				}
-
-				for (Way mpWay : singularOuterPolygons) {
-					// put the cut out polygons to the
-					// final way map
-					if (log.isDebugEnabled())
-						log.debug(mpWay.getId(),mpWay.toTagString());
 					
-					// mark this polygons so that only polygon style rules are applied
-					mpWay.addTag(STYLE_FILTER_TAG, STYLE_FILTER_POLYGON);
+					for (Way mpWay : singularOuterPolygons) {
+						// put the cut out polygons to the
+						// final way map
+						if (log.isDebugEnabled())
+							log.debug(mpWay.getId(),mpWay.toTagString());
 					
-					tileWayMap.put(mpWay.getId(), mpWay);
+						// mark this polygons so that only polygon style rules are applied
+						mpWay.addTag(STYLE_FILTER_TAG, STYLE_FILTER_POLYGON);
+					
+						tileWayMap.put(mpWay.getId(), mpWay);
+					}
 				}
+
 			}
 		}
 		
@@ -1367,15 +1367,6 @@
 		return w;
 	}
 
-	private boolean hasTags(JoinedWay way) {
-		for (Way segment : way.getOriginalWays()) {
-			if (hasTags(segment)) {
-				return true;
-			}
-		}
-		return false;
-	}
-
 	private boolean hasTags(Element element) {
 		for (Map.Entry<String, String> tagEntry : element.getEntryIteratable()) {
 			if ("type".equals(tagEntry.getKey()) == false) {
@@ -1421,9 +1412,6 @@
 			BitSet containsColumns = containsMatrix.get(rowIndex);
 			BitSet finishedCol = finishedMatrix.get(rowIndex);
 
-			if (log.isDebugEnabled())
-				log.debug("check polygon", rowIndex);
-
 			// get all non calculated columns of the matrix
 			for (int colIndex = finishedCol.nextClearBit(0); colIndex >= 0
 					&& colIndex < polygonList.size(); colIndex = finishedCol
@@ -1467,9 +1455,18 @@
 			log.debug("createMatrix for", polygonList.size(), "polygons took",
 				(t2 - t1), "ms");
 
-			log.debug("Containsmatrix");
+			log.debug("Containsmatrix:");
+			int i = 0;
+			boolean noContained = true;
 			for (BitSet b : containsMatrix) {
-				log.debug(b);
+				if (b.isEmpty()==false) {
+					log.debug(i,"contains",b);
+					noContained = false;
+				}
+				i++;
+			}
+			if (noContained) {
+				log.debug("Matrix is empty");
 			}
 		}
 	}
@@ -1890,8 +1887,6 @@
 		}
 	}
 
-	private static final boolean joinWayTagMerge = false;
-	
 	/**
 	 * This is a helper class that stores that gives access to the original
 	 * segments of a joined way.
@@ -1982,10 +1977,6 @@
 					log.debug("Joined", this.getId(), "with", way.getId());
 				}
 				this.originalWays.add(way);
-				addTagsOf(way);
-				if (getName() == null && way.getName() != null) {
-					setName(way.getName());
-				}
 			}
 		}
 
@@ -1998,27 +1989,38 @@
 			return closedArtificially;
 		}
 
-		private void addTagsOf(Way way) {
-			boolean merge = (joinWayTagMerge || getOriginalWays().size()<=1);
-			if (merge) {
-				for (Map.Entry<String, String> tag : way.getEntryIteratable()) {
-					addTag(tag.getKey(), tag.getValue());
-				}
-			} else {
-				// only use tags that are in both ways
-				for (Map.Entry<String, String> tag : this.getEntryIteratable()) {
-					String wayTagValue = way.getTag(tag.getKey());
-					if (!tag.getValue().equals(wayTagValue)) {
-						// the tags are different
-						if (log.isDebugEnabled()) {
-							log.debug("Remove differing tag",tag.getKey(),getId()+"="+tag.getValue(),way.getId()+"="+wayTagValue);
-						}
-						if (wayTagValue!= null) {
-							deleteTag(tag.getKey());
+		/**
+		 * Tags this way with a merge of the tags of all original ways.
+		 */
+		public void mergeTagsFromOrgWays() {
+			if (log.isDebugEnabled()) {
+				log.debug("Way",getId(),"merge tags from",getOriginalWays().size(),"ways");
+			}
+			boolean first = true;
+			for (Way way : getOriginalWays()) {
+				if (first) {
+					// the tags of the first way are copied completely 
+					for (Map.Entry<String, String> tag : way.getEntryIteratable()) {
+						addTag(tag.getKey(), tag.getValue());
+					}
+					if (log.isDebugEnabled()) {
+						log.debug("Copy all tags from the first way", way.getId(), toTagString());
+					}
+				} else {
+					// for all other ways all non matching tags are removed
+					for (Map.Entry<String, String> tag : this.getEntryIteratable()) {
+						String wayTagValue = way.getTag(tag.getKey());
+						if (!tag.getValue().equals(wayTagValue)) {
+							// the tags are different
+							if (log.isDebugEnabled()) {
+								log.debug("Remove differing tag",tag.getKey(),getId()+"="+tag.getValue(),way.getId()+"="+wayTagValue);
+							}
+							if (wayTagValue!= null) {
+								deleteTag(tag.getKey());
+							}
 						}
 					}
 				}
-				
 			}
 		}
 
_______________________________________________
mkgmap-dev mailing list
[email protected]
http://www.mkgmap.org.uk/mailman/listinfo/mkgmap-dev

Reply via email to