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