Hi,
the patch removes tags from ways not until all multipolygons are
processed. This fixes some problems if one way is a member of multiple
multipolygons and the multipolygons take their tags from their ways.
This is a result of the thread
http://www.mkgmap.org.uk/pipermail/mkgmap-dev/2010q3/008730.html.
Have fun!
WanMil
Index: src/uk/me/parabola/mkgmap/reader/osm/Element.java
===================================================================
--- src/uk/me/parabola/mkgmap/reader/osm/Element.java (revision 1667)
+++ src/uk/me/parabola/mkgmap/reader/osm/Element.java (working copy)
@@ -68,7 +68,7 @@
String toTagString() {
if (tags == null)
- return "";
+ return "[]";
StringBuilder sb = new StringBuilder();
sb.append('[');
@@ -76,7 +76,9 @@
sb.append(nameval);
sb.append(',');
}
- sb.setLength(sb.length()-1);
+ if (sb.length() > 1) {
+ sb.setLength(sb.length()-1);
+ }
sb.append(']');
return sb.toString();
}
Index: src/uk/me/parabola/mkgmap/reader/osm/MultiPolygonRelation.java
===================================================================
--- src/uk/me/parabola/mkgmap/reader/osm/MultiPolygonRelation.java (revision 1667)
+++ src/uk/me/parabola/mkgmap/reader/osm/MultiPolygonRelation.java (working copy)
@@ -20,6 +20,7 @@
import java.util.Queue;
import java.util.Set;
import java.util.TreeSet;
+import java.util.Map.Entry;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.logging.Level;
@@ -46,7 +47,9 @@
private final uk.me.parabola.imgfmt.app.Area bbox;
private Area bboxArea;
-
+
+ private final Map<Long, Set<String>> wayRemoveTags;
+
/**
* A point that has a lower or equal squared distance from
* a line is treated as if it lies one the line.<br/>
@@ -72,30 +75,35 @@
* The relation to base this one on.
* @param wayMap
* Map of all ways.
+ * @param wayRemoveTags
+ * Marks which tags should be removed from a way after the
+ * complete multipolygon processing has finished
*/
- public MultiPolygonRelation(Relation other, Map<Long, Way> wayMap,
+ public MultiPolygonRelation(Relation other, Map<Long, Way> wayMap,
+ Map<Long, Set<String>> wayRemoveTags,
uk.me.parabola.imgfmt.app.Area bbox) {
this.tileWayMap = wayMap;
this.bbox = bbox;
+ this.wayRemoveTags = wayRemoveTags;
setId(other.getId());
+ setName(other.getName());
+ copyTags(other);
if (log.isDebugEnabled()) {
- log.debug("Construct multipolygon", toBrowseURL());
+ log.debug("Construct multipolygon", toBrowseURL(), toTagString());
}
for (Map.Entry<String, Element> pair : other.getElements()) {
String role = pair.getKey();
Element el = pair.getValue();
if (log.isDebugEnabled()) {
- log.debug(" ", role, el.toBrowseURL());
+ log.debug(" ", role, el.toBrowseURL(), el.toTagString());
}
addElement(role, el);
roleMap.put(el.getId(), role);
}
- setName(other.getName());
- copyTags(other);
}
public boolean isBoundaryRelation() {
@@ -722,12 +730,8 @@
// has been replaced by the new cut polygon
// the original way should not appear
// so we remove all tags
- currentPolygon.polygon.removeAllTagsDeep();
- } else {
- // remove all polygons tags from the original ways
- // sometimes the ways seem to be auto-closed later on
- // in mkgmap
- currentPolygon.polygon.removePolygonTagsInOrgWays();
+ removeTagInOrgWays(currentPolygon.polygon, null, null);
+ currentPolygon.polygon.removeAllTags();
}
boolean useRelationTags = currentPolygon.outer
@@ -735,6 +739,8 @@
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");
@@ -1256,6 +1262,10 @@
private boolean hasPolygonTags(Element element) {
for (Map.Entry<String, String> tagEntry : element.getEntryIteratable()) {
+ if ("natural".equals(tagEntry.getKey()) && "coastline".equals(tagEntry.getValue())) {
+ // ignore natural=coastline
+ continue;
+ }
if (polygonTags.contains(tagEntry.getKey())) {
return true;
}
@@ -1272,7 +1282,7 @@
*/
private void createContainsMatrix(List<JoinedWay> polygonList) {
containsMatrix = new ArrayList<BitSet>();
- for (JoinedWay aPolygonList : polygonList) {
+ for (int i = 0; i < polygonList.size(); i++) {
containsMatrix.add(new BitSet());
}
@@ -1680,6 +1690,69 @@
}
}
+ /**
+ * Marks all tags of the original ways of the given JoinedWay that are also
+ * contained in the given tagElement for removal.
+ *
+ * @param tagElement an element contains the tags to be removed
+ * @param way a joined way
+ */
+ private void removeTagsInOrgWays(Element tagElement, JoinedWay way) {
+ for (Entry<String, String> tag : tagElement.getEntryIteratable()) {
+ removeTagInOrgWays(way, tag.getKey(), tag.getValue());
+ }
+ }
+
+ /**
+ * Mark the given tag of all original ways of the given JoinedWay.
+ *
+ * @param way a joined way
+ * @param tagname the tag to be removed (<code>null</code> means remove all tags)
+ * @param tagvalue the value of the tag to be removed (<code>null</code> means don't check the value)
+ */
+ private void removeTagInOrgWays(JoinedWay way, String tagname,
+ String tagvalue) {
+ for (Way w : way.getOriginalWays()) {
+ if (w instanceof JoinedWay) {
+ // remove the tags recursively
+ removeTagInOrgWays((JoinedWay) w, tagname, tagvalue);
+ continue;
+ }
+
+ boolean remove = false;
+ if (tagname == null) {
+ // remove all tags
+ remove = true;
+ } else if (tagvalue == null) {
+ // remove the tag without comparing the value
+ remove = way.getTag(tagname) != null;
+ } else if (tagvalue.equals(w.getTag(tagname))) {
+ remove = true;
+ }
+
+ if (remove) {
+ Set<String> tagListToRemove = this.wayRemoveTags.get(way
+ .getId());
+ if (tagListToRemove == null) {
+ tagListToRemove = new TreeSet<String>();
+ wayRemoveTags.put(way.getId(), tagListToRemove);
+ }
+ if (tagname == null) {
+ // remove all tags
+ for (Entry<String,String> tag : w.getEntryIteratable()) {
+ tagListToRemove.add(tag.getKey());
+ }
+ if (log.isDebugEnabled())
+ log.debug("Will remove all tags from",w.getId(),way.toTagString());
+ } else {
+ tagListToRemove.add(tagname);
+ if (log.isDebugEnabled())
+ log.debug("Will remove",tagname+"="+w.getTag(tagname),"from way",w.getId(),w.toTagString());
+ }
+ }
+ }
+ }
+
private static final boolean joinWayTagMerge = false;
/**
@@ -1816,34 +1889,6 @@
return originalWays;
}
- public void removePolygonTagsInOrgWays() {
- for (Way w : getOriginalWays()) {
- for (String polygonTag : polygonTags) {
- w.deleteTag(polygonTag);
- }
- }
- }
-
- public void removeAllTagsDeep() {
- removeOriginalTags();
- removeAllTags();
- }
-
- public void removeOriginalTags() {
- for (Way w : getOriginalWays()) {
- if (w instanceof JoinedWay) {
- ((JoinedWay) w).removeAllTagsDeep();
- } else {
- log.info("Before remove",w.toTagString());
- for (Map.Entry<String, String> wayTag : w
- .getEntryIteratable()) {
- w.deleteTag(wayTag.getKey());
- }
- log.info("After remove",w.toTagString());
- }
- }
- }
-
public String toString() {
StringBuilder sb = new StringBuilder(200);
sb.append(getId());
Index: src/uk/me/parabola/mkgmap/reader/osm/xml/Osm5XmlHandler.java
===================================================================
--- src/uk/me/parabola/mkgmap/reader/osm/xml/Osm5XmlHandler.java (revision 1667)
+++ src/uk/me/parabola/mkgmap/reader/osm/xml/Osm5XmlHandler.java (working copy)
@@ -35,6 +35,14 @@
import java.util.Set;
import java.util.SortedMap;
import java.util.TreeMap;
+import java.util.TreeSet;
+import java.util.Map.Entry;
+
+import org.xml.sax.Attributes;
+import org.xml.sax.ContentHandler;
+import org.xml.sax.SAXException;
+import org.xml.sax.SAXParseException;
+import org.xml.sax.helpers.DefaultHandler;
import uk.me.parabola.imgfmt.MapFailedException;
import uk.me.parabola.imgfmt.app.Area;
@@ -56,12 +64,6 @@
import uk.me.parabola.mkgmap.reader.osm.Way;
import uk.me.parabola.util.EnhancedProperties;
-import org.xml.sax.Attributes;
-import org.xml.sax.ContentHandler;
-import org.xml.sax.SAXException;
-import org.xml.sax.SAXParseException;
-import org.xml.sax.helpers.DefaultHandler;
-
/**
* Reads and parses the OSM XML format.
*
@@ -124,6 +126,8 @@
private HashMap<String,Set<String>> deletedTags;
private Map<String, String> usedTags;
+
+ private final Map<Long,Set<String>> mpWayRemoveTags = new HashMap<Long,Set<String>>();
public Osm5XmlHandler(EnhancedProperties props) {
if(props.getProperty("make-all-cycleways", false)) {
@@ -603,7 +607,7 @@
if (type != null) {
if ("multipolygon".equals(type)) {
Area mpBbox = (bbox != null ? bbox : ((MapDetails) collector).getBounds());
- currentRelation = new MultiPolygonRelation(currentRelation, wayMap, mpBbox);
+ currentRelation = new MultiPolygonRelation(currentRelation, wayMap, mpWayRemoveTags, mpBbox);
} else if("restriction".equals(type)) {
if(ignoreTurnRestrictions)
@@ -671,6 +675,18 @@
}
}
}
+
+ for (Entry<Long,Set<String>> wayTagsRemove : mpWayRemoveTags.entrySet()) {
+ Way w = wayMap.get(wayTagsRemove.getKey());
+ if (w==null) {
+ log.warn("Cannot find way",wayTagsRemove.getKey(),"to remove tags by multipolygon processing.");
+ continue;
+ }
+ for (String tagname : wayTagsRemove.getValue()) {
+ w.deleteTag(tagname);
+ }
+ }
+ mpWayRemoveTags.clear();
coordMap = null;
@@ -1576,7 +1592,7 @@
if(generateSeaUsingMP) {
Area mpBbox = (bbox != null ? bbox : ((MapDetails) collector).getBounds());
- seaRelation = new MultiPolygonRelation(seaRelation, wayMap, mpBbox);
+ seaRelation = new MultiPolygonRelation(seaRelation, wayMap, mpWayRemoveTags, mpBbox);
relationMap.put(multiId, seaRelation);
seaRelation.processElements();
}
_______________________________________________
mkgmap-dev mailing list
[email protected]
http://www.mkgmap.org.uk/mailman/listinfo/mkgmap-dev