Index: data/defaultpresets.xml =================================================================== --- data/defaultpresets.xml (revision 4181) +++ data/defaultpresets.xml (working copy) @@ -4122,6 +4122,8 @@ + + Index: src/org/openstreetmap/josm/data/osm/Relation.java =================================================================== --- src/org/openstreetmap/josm/data/osm/Relation.java (revision 4181) +++ src/org/openstreetmap/josm/data/osm/Relation.java (working copy) @@ -409,6 +409,10 @@ return "multipolygon".equals(get("type")); } + public boolean isBoundary() { + return "boundary".equals(get("type")); + } + @Override public BBox getBBox() { RelationMember[] members = this.members; Index: src/org/openstreetmap/josm/data/osm/visitor/paint/MapPainter.java =================================================================== --- src/org/openstreetmap/josm/data/osm/visitor/paint/MapPainter.java (revision 4181) +++ src/org/openstreetmap/josm/data/osm/visitor/paint/MapPainter.java (working copy) @@ -33,6 +33,7 @@ import org.openstreetmap.josm.data.osm.Relation; import org.openstreetmap.josm.data.osm.RelationMember; import org.openstreetmap.josm.data.osm.Way; +import org.openstreetmap.josm.data.osm.visitor.paint.relations.Boundary; import org.openstreetmap.josm.data.osm.visitor.paint.relations.Multipolygon; import org.openstreetmap.josm.data.osm.visitor.paint.relations.Multipolygon.PolyData; import org.openstreetmap.josm.gui.NavigatableComponent; @@ -688,7 +689,7 @@ } public void drawArea(Relation r, Color color, BufferedImage fillImage, float fillImageAlpha, TextElement text) { - Multipolygon multipolygon = new Multipolygon(nc); + Multipolygon multipolygon = r.isBoundary() ? new Boundary(nc) : new Multipolygon(nc); multipolygon.load(r); if(!r.isDisabled() && !multipolygon.getOuterWays().isEmpty()) { for (PolyData pd : multipolygon.getCombinedPolygons()) { Index: src/org/openstreetmap/josm/data/osm/visitor/paint/relations/Boundary.java =================================================================== --- src/org/openstreetmap/josm/data/osm/visitor/paint/relations/Boundary.java (revision 0) +++ src/org/openstreetmap/josm/data/osm/visitor/paint/relations/Boundary.java (revision 0) @@ -0,0 +1,45 @@ +// License: GPL. For details, see LICENSE file. +package org.openstreetmap.josm.data.osm.visitor.paint.relations; + +import org.openstreetmap.josm.Main; +import org.openstreetmap.josm.data.osm.Relation; +import org.openstreetmap.josm.gui.NavigatableComponent; + +public class Boundary extends Multipolygon { + + public Boundary(NavigatableComponent nc) { + super(nc); + } + + protected static class BoundaryRoleMatcher extends MultipolygonRoleMatcher { + + @Override + protected void initDefaults() { + super.initDefaults(); + outerExactRoles.add("exclave"); + innerExactRoles.add("enclave"); + } + } + + @Override + public void load(Relation r) { + load(r, getBoundaryRoleMatcher()); + } + + /* + * Init a private global matcher object which will listen to preference + * changes. + */ + private static BoundaryRoleMatcher roleMatcher; + private static BoundaryRoleMatcher getBoundaryRoleMatcher() { + if (roleMatcher == null) { + roleMatcher = new BoundaryRoleMatcher(); + if (Main.pref != null){ + roleMatcher.initFromPreferences(); + Main.pref.addPreferenceChangeListener(roleMatcher); + } + } + return roleMatcher; + } + +} Index: src/org/openstreetmap/josm/data/osm/visitor/paint/relations/Multipolygon.java =================================================================== --- src/org/openstreetmap/josm/data/osm/visitor/paint/relations/Multipolygon.java (revision 4181) +++ src/org/openstreetmap/josm/data/osm/visitor/paint/relations/Multipolygon.java (working copy) @@ -48,13 +48,13 @@ * above.

* */ - private static class MultipolygonRoleMatcher implements PreferenceChangedListener{ - private final List outerExactRoles = new ArrayList(); - private final List outerRolePrefixes = new ArrayList(); - private final List innerExactRoles = new ArrayList(); - private final List innerRolePrefixes = new ArrayList(); + protected static class MultipolygonRoleMatcher implements PreferenceChangedListener{ + protected final List outerExactRoles = new ArrayList(); + protected final List outerRolePrefixes = new ArrayList(); + protected final List innerExactRoles = new ArrayList(); + protected final List innerRolePrefixes = new ArrayList(); - private void initDefaults() { + protected void initDefaults() { outerExactRoles.clear(); outerRolePrefixes.clear(); innerExactRoles.clear(); @@ -76,7 +76,7 @@ } } - private void initFromPreferences() { + protected void initFromPreferences() { initDefaults(); if (Main.pref == null) return; Collection literals; @@ -136,7 +136,7 @@ * changes. */ private static MultipolygonRoleMatcher roleMatcher; - private static MultipolygonRoleMatcher getMultipoloygonRoleMatcher() { + private static MultipolygonRoleMatcher getMultipolygonRoleMatcher() { if (roleMatcher == null) { roleMatcher = new MultipolygonRoleMatcher(); if (Main.pref != null){ @@ -252,7 +252,10 @@ } public void load(Relation r) { - MultipolygonRoleMatcher matcher = getMultipoloygonRoleMatcher(); + load(r, getMultipolygonRoleMatcher()); + } + + protected void load(Relation r, MultipolygonRoleMatcher matcher) { // Fill inner and outer list with valid ways for (RelationMember m : r.getMembers()) { Index: src/org/openstreetmap/josm/data/validation/tests/MultipolygonTest.java =================================================================== --- src/org/openstreetmap/josm/data/validation/tests/MultipolygonTest.java (revision 4181) +++ src/org/openstreetmap/josm/data/validation/tests/MultipolygonTest.java (working copy) @@ -15,6 +15,7 @@ import org.openstreetmap.josm.data.osm.Relation; import org.openstreetmap.josm.data.osm.RelationMember; import org.openstreetmap.josm.data.osm.Way; +import org.openstreetmap.josm.data.osm.visitor.paint.relations.Boundary; import org.openstreetmap.josm.data.osm.visitor.paint.relations.Multipolygon; import org.openstreetmap.josm.data.osm.visitor.paint.relations.Multipolygon.JoinedWay; import org.openstreetmap.josm.data.osm.visitor.paint.relations.Multipolygon.PolyData.Intersection; @@ -127,10 +128,10 @@ @Override public void visit(Relation r) { nonClosedWays.clear(); - if (r.isMultipolygon()) { + if (r.isMultipolygon() || r.isBoundary()) { checkMembersAndRoles(r); - Multipolygon polygon = new Multipolygon(Main.map.mapView); + Multipolygon polygon = r.isBoundary() ? new Boundary(Main.map.mapView) : new Multipolygon(Main.map.mapView); polygon.load(r); if (polygon.getOuterWays().isEmpty()) { @@ -252,9 +253,11 @@ for (RelationMember rm : r.getMembers()) { if (rm.isWay()) { if (!("inner".equals(rm.getRole()) || "outer".equals(rm.getRole()) || !rm.hasRole())) { - errors.add(new TestError(this, Severity.WARNING, tr("No useful role for multipolygon member"), WRONG_MEMBER_ROLE, rm.getMember())); + if (!(r.isBoundary() && ("enclave".equals(rm.getRole()) || "exclave".equals(rm.getRole())))) { + errors.add(new TestError(this, Severity.WARNING, tr("No useful role for multipolygon member"), WRONG_MEMBER_ROLE, rm.getMember())); + } } - } else { + } else if (r.isMultipolygon()) { errors.add(new TestError(this, Severity.WARNING, tr("Non-Way in multipolygon"), WRONG_MEMBER_TYPE, rm.getMember())); } } Index: src/org/openstreetmap/josm/gui/mappaint/ElemStyles.java =================================================================== --- src/org/openstreetmap/josm/gui/mappaint/ElemStyles.java (revision 4181) +++ src/org/openstreetmap/josm/gui/mappaint/ElemStyles.java (working copy) @@ -13,6 +13,7 @@ import org.openstreetmap.josm.data.osm.OsmPrimitive; import org.openstreetmap.josm.data.osm.Relation; import org.openstreetmap.josm.data.osm.Way; +import org.openstreetmap.josm.data.osm.visitor.paint.relations.Boundary; import org.openstreetmap.josm.data.osm.visitor.paint.relations.Multipolygon; import org.openstreetmap.josm.gui.NavigatableComponent; import org.openstreetmap.josm.gui.mappaint.StyleCache.StyleList; @@ -93,10 +94,10 @@ for (OsmPrimitive referrer : osm.getReferrers()) { Relation r = (Relation) referrer; - if (!drawMultipolygon || !r.isMultipolygon() || !r.isUsable()) { + if (!drawMultipolygon || !r.isMultipolygon() || !r.isBoundary() || !r.isUsable()) { continue; } - Multipolygon multipolygon = new Multipolygon(nc); + Multipolygon multipolygon = r.isBoundary() ? new Boundary(nc) : new Multipolygon(nc); multipolygon.load(r); if (multipolygon.getOuterWays().contains(osm)) { @@ -246,7 +247,7 @@ } else if (osm instanceof Node) { addIfNotNull(sl, NodeElemStyle.create(env)); } else if (osm instanceof Relation) { - if (((Relation)osm).isMultipolygon()) { + if (((Relation)osm).isMultipolygon() || ((Relation)osm).isBoundary()) { addIfNotNull(sl, AreaElemStyle.create(c)); addIfNotNull(sl, LinePatternElemStyle.create(env)); addIfNotNull(sl, LineElemStyle.createLine(env)); Index: src/org/openstreetmap/josm/gui/mappaint/mapcss/Condition.java =================================================================== --- src/org/openstreetmap/josm/gui/mappaint/mapcss/Condition.java (revision 4181) +++ src/org/openstreetmap/josm/gui/mappaint/mapcss/Condition.java (working copy) @@ -274,7 +274,7 @@ if (equal(id, "closed")) { if (e.osm instanceof Way && ((Way) e.osm).isClosed()) return true; - if (e.osm instanceof Relation && ((Relation) e.osm).isMultipolygon()) + if (e.osm instanceof Relation && (((Relation) e.osm).isMultipolygon() || ((Relation) e.osm).isBoundary())) return true; return false; } else if (equal(id, "modified")) Index: src/org/openstreetmap/josm/gui/mappaint/mapcss/Selector.java =================================================================== --- src/org/openstreetmap/josm/gui/mappaint/mapcss/Selector.java (revision 4181) +++ src/org/openstreetmap/josm/gui/mappaint/mapcss/Selector.java (working copy) @@ -270,7 +270,7 @@ if (base.equals("area")) { if (e.osm instanceof Way) return true; - if (e.osm instanceof Relation && ((Relation) e.osm).isMultipolygon()) + if (e.osm instanceof Relation && (((Relation) e.osm).isMultipolygon() || ((Relation) e.osm).isBoundary())) return true; } if (base.equals(OsmPrimitiveType.from(e.osm).getAPIName())) Index: src/org/openstreetmap/josm/gui/mappaint/xml/XmlStyleSource.java =================================================================== --- src/org/openstreetmap/josm/gui/mappaint/xml/XmlStyleSource.java (revision 4181) +++ src/org/openstreetmap/josm/gui/mappaint/xml/XmlStyleSource.java (working copy) @@ -49,6 +49,7 @@ super(entry); } + @Override protected void init() { super.init(); icons.clear(); @@ -88,6 +89,7 @@ } } + @Override public InputStream getSourceInputStream() throws IOException { MirroredInputStream in = new MirroredInputStream(url); InputStream zip = in.getZipEntry("xml", "style"); @@ -295,7 +297,7 @@ } } } - } else if (osm instanceof Way || (osm instanceof Relation && ((Relation)osm).isMultipolygon())) { + } else if (osm instanceof Way || (osm instanceof Relation && (((Relation)osm).isMultipolygon()) || ((Relation)osm).isBoundary())) { WayPrototypesRecord p = new WayPrototypesRecord(); get(osm, pretendWayIsClosed || !(osm instanceof Way) || ((Way) osm).isClosed(), p, (useMinMaxScale ? scale : null), mc); if (p.line != null) {