| 1 | Index: data/defaultpresets.xml
|
|---|
| 2 | ===================================================================
|
|---|
| 3 | --- data/defaultpresets.xml (revision 4181)
|
|---|
| 4 | +++ data/defaultpresets.xml (working copy)
|
|---|
| 5 | @@ -4122,6 +4122,8 @@
|
|---|
| 6 | <roles>
|
|---|
| 7 | <role key="outer" text="outer segment" requisite="required" type="way" />
|
|---|
| 8 | <role key="inner" text="inner segment" requisite="optional" type="way" />
|
|---|
| 9 | + <role key="enclave" text="enclave segment" requisite="optional" type="way" />
|
|---|
| 10 | + <role key="exclave" text="exclave segment" requisite="optional" type="way" />
|
|---|
| 11 | <role key="subarea" text="Sub area" requisite="optional" type="relation" />
|
|---|
| 12 | <role key="admin_centre" text="Administration centre" requisite="optional" type="node" />
|
|---|
| 13 | </roles>
|
|---|
| 14 | Index: src/org/openstreetmap/josm/data/osm/Relation.java
|
|---|
| 15 | ===================================================================
|
|---|
| 16 | --- src/org/openstreetmap/josm/data/osm/Relation.java (revision 4181)
|
|---|
| 17 | +++ src/org/openstreetmap/josm/data/osm/Relation.java (working copy)
|
|---|
| 18 | @@ -409,6 +409,10 @@
|
|---|
| 19 | return "multipolygon".equals(get("type"));
|
|---|
| 20 | }
|
|---|
| 21 |
|
|---|
| 22 | + public boolean isBoundary() {
|
|---|
| 23 | + return "boundary".equals(get("type"));
|
|---|
| 24 | + }
|
|---|
| 25 | +
|
|---|
| 26 | @Override
|
|---|
| 27 | public BBox getBBox() {
|
|---|
| 28 | RelationMember[] members = this.members;
|
|---|
| 29 | Index: src/org/openstreetmap/josm/data/osm/visitor/paint/MapPainter.java
|
|---|
| 30 | ===================================================================
|
|---|
| 31 | --- src/org/openstreetmap/josm/data/osm/visitor/paint/MapPainter.java (revision 4181)
|
|---|
| 32 | +++ src/org/openstreetmap/josm/data/osm/visitor/paint/MapPainter.java (working copy)
|
|---|
| 33 | @@ -33,6 +33,7 @@
|
|---|
| 34 | import org.openstreetmap.josm.data.osm.Relation;
|
|---|
| 35 | import org.openstreetmap.josm.data.osm.RelationMember;
|
|---|
| 36 | import org.openstreetmap.josm.data.osm.Way;
|
|---|
| 37 | +import org.openstreetmap.josm.data.osm.visitor.paint.relations.Boundary;
|
|---|
| 38 | import org.openstreetmap.josm.data.osm.visitor.paint.relations.Multipolygon;
|
|---|
| 39 | import org.openstreetmap.josm.data.osm.visitor.paint.relations.Multipolygon.PolyData;
|
|---|
| 40 | import org.openstreetmap.josm.gui.NavigatableComponent;
|
|---|
| 41 | @@ -688,7 +689,7 @@
|
|---|
| 42 | }
|
|---|
| 43 |
|
|---|
| 44 | public void drawArea(Relation r, Color color, BufferedImage fillImage, float fillImageAlpha, TextElement text) {
|
|---|
| 45 | - Multipolygon multipolygon = new Multipolygon(nc);
|
|---|
| 46 | + Multipolygon multipolygon = r.isBoundary() ? new Boundary(nc) : new Multipolygon(nc);
|
|---|
| 47 | multipolygon.load(r);
|
|---|
| 48 | if(!r.isDisabled() && !multipolygon.getOuterWays().isEmpty()) {
|
|---|
| 49 | for (PolyData pd : multipolygon.getCombinedPolygons()) {
|
|---|
| 50 | Index: src/org/openstreetmap/josm/data/osm/visitor/paint/relations/Boundary.java
|
|---|
| 51 | ===================================================================
|
|---|
| 52 | --- src/org/openstreetmap/josm/data/osm/visitor/paint/relations/Boundary.java (revision 0)
|
|---|
| 53 | +++ src/org/openstreetmap/josm/data/osm/visitor/paint/relations/Boundary.java (revision 0)
|
|---|
| 54 | @@ -0,0 +1,45 @@
|
|---|
| 55 | +// License: GPL. For details, see LICENSE file.
|
|---|
| 56 | +package org.openstreetmap.josm.data.osm.visitor.paint.relations;
|
|---|
| 57 | +
|
|---|
| 58 | +import org.openstreetmap.josm.Main;
|
|---|
| 59 | +import org.openstreetmap.josm.data.osm.Relation;
|
|---|
| 60 | +import org.openstreetmap.josm.gui.NavigatableComponent;
|
|---|
| 61 | +
|
|---|
| 62 | +public class Boundary extends Multipolygon {
|
|---|
| 63 | +
|
|---|
| 64 | + public Boundary(NavigatableComponent nc) {
|
|---|
| 65 | + super(nc);
|
|---|
| 66 | + }
|
|---|
| 67 | +
|
|---|
| 68 | + protected static class BoundaryRoleMatcher extends MultipolygonRoleMatcher {
|
|---|
| 69 | +
|
|---|
| 70 | + @Override
|
|---|
| 71 | + protected void initDefaults() {
|
|---|
| 72 | + super.initDefaults();
|
|---|
| 73 | + outerExactRoles.add("exclave");
|
|---|
| 74 | + innerExactRoles.add("enclave");
|
|---|
| 75 | + }
|
|---|
| 76 | + }
|
|---|
| 77 | +
|
|---|
| 78 | + @Override
|
|---|
| 79 | + public void load(Relation r) {
|
|---|
| 80 | + load(r, getBoundaryRoleMatcher());
|
|---|
| 81 | + }
|
|---|
| 82 | +
|
|---|
| 83 | + /*
|
|---|
| 84 | + * Init a private global matcher object which will listen to preference
|
|---|
| 85 | + * changes.
|
|---|
| 86 | + */
|
|---|
| 87 | + private static BoundaryRoleMatcher roleMatcher;
|
|---|
| 88 | + private static BoundaryRoleMatcher getBoundaryRoleMatcher() {
|
|---|
| 89 | + if (roleMatcher == null) {
|
|---|
| 90 | + roleMatcher = new BoundaryRoleMatcher();
|
|---|
| 91 | + if (Main.pref != null){
|
|---|
| 92 | + roleMatcher.initFromPreferences();
|
|---|
| 93 | + Main.pref.addPreferenceChangeListener(roleMatcher);
|
|---|
| 94 | + }
|
|---|
| 95 | + }
|
|---|
| 96 | + return roleMatcher;
|
|---|
| 97 | + }
|
|---|
| 98 | +
|
|---|
| 99 | +}
|
|---|
| 100 | Index: src/org/openstreetmap/josm/data/osm/visitor/paint/relations/Multipolygon.java
|
|---|
| 101 | ===================================================================
|
|---|
| 102 | --- src/org/openstreetmap/josm/data/osm/visitor/paint/relations/Multipolygon.java (revision 4181)
|
|---|
| 103 | +++ src/org/openstreetmap/josm/data/osm/visitor/paint/relations/Multipolygon.java (working copy)
|
|---|
| 104 | @@ -48,13 +48,13 @@
|
|---|
| 105 | * above.</p>
|
|---|
| 106 | *
|
|---|
| 107 | */
|
|---|
| 108 | - private static class MultipolygonRoleMatcher implements PreferenceChangedListener{
|
|---|
| 109 | - private final List<String> outerExactRoles = new ArrayList<String>();
|
|---|
| 110 | - private final List<String> outerRolePrefixes = new ArrayList<String>();
|
|---|
| 111 | - private final List<String> innerExactRoles = new ArrayList<String>();
|
|---|
| 112 | - private final List<String> innerRolePrefixes = new ArrayList<String>();
|
|---|
| 113 | + protected static class MultipolygonRoleMatcher implements PreferenceChangedListener{
|
|---|
| 114 | + protected final List<String> outerExactRoles = new ArrayList<String>();
|
|---|
| 115 | + protected final List<String> outerRolePrefixes = new ArrayList<String>();
|
|---|
| 116 | + protected final List<String> innerExactRoles = new ArrayList<String>();
|
|---|
| 117 | + protected final List<String> innerRolePrefixes = new ArrayList<String>();
|
|---|
| 118 |
|
|---|
| 119 | - private void initDefaults() {
|
|---|
| 120 | + protected void initDefaults() {
|
|---|
| 121 | outerExactRoles.clear();
|
|---|
| 122 | outerRolePrefixes.clear();
|
|---|
| 123 | innerExactRoles.clear();
|
|---|
| 124 | @@ -76,7 +76,7 @@
|
|---|
| 125 | }
|
|---|
| 126 | }
|
|---|
| 127 |
|
|---|
| 128 | - private void initFromPreferences() {
|
|---|
| 129 | + protected void initFromPreferences() {
|
|---|
| 130 | initDefaults();
|
|---|
| 131 | if (Main.pref == null) return;
|
|---|
| 132 | Collection<String> literals;
|
|---|
| 133 | @@ -136,7 +136,7 @@
|
|---|
| 134 | * changes.
|
|---|
| 135 | */
|
|---|
| 136 | private static MultipolygonRoleMatcher roleMatcher;
|
|---|
| 137 | - private static MultipolygonRoleMatcher getMultipoloygonRoleMatcher() {
|
|---|
| 138 | + private static MultipolygonRoleMatcher getMultipolygonRoleMatcher() {
|
|---|
| 139 | if (roleMatcher == null) {
|
|---|
| 140 | roleMatcher = new MultipolygonRoleMatcher();
|
|---|
| 141 | if (Main.pref != null){
|
|---|
| 142 | @@ -252,7 +252,10 @@
|
|---|
| 143 | }
|
|---|
| 144 |
|
|---|
| 145 | public void load(Relation r) {
|
|---|
| 146 | - MultipolygonRoleMatcher matcher = getMultipoloygonRoleMatcher();
|
|---|
| 147 | + load(r, getMultipolygonRoleMatcher());
|
|---|
| 148 | + }
|
|---|
| 149 | +
|
|---|
| 150 | + protected void load(Relation r, MultipolygonRoleMatcher matcher) {
|
|---|
| 151 |
|
|---|
| 152 | // Fill inner and outer list with valid ways
|
|---|
| 153 | for (RelationMember m : r.getMembers()) {
|
|---|
| 154 | Index: src/org/openstreetmap/josm/data/validation/tests/MultipolygonTest.java
|
|---|
| 155 | ===================================================================
|
|---|
| 156 | --- src/org/openstreetmap/josm/data/validation/tests/MultipolygonTest.java (revision 4181)
|
|---|
| 157 | +++ src/org/openstreetmap/josm/data/validation/tests/MultipolygonTest.java (working copy)
|
|---|
| 158 | @@ -15,6 +15,7 @@
|
|---|
| 159 | import org.openstreetmap.josm.data.osm.Relation;
|
|---|
| 160 | import org.openstreetmap.josm.data.osm.RelationMember;
|
|---|
| 161 | import org.openstreetmap.josm.data.osm.Way;
|
|---|
| 162 | +import org.openstreetmap.josm.data.osm.visitor.paint.relations.Boundary;
|
|---|
| 163 | import org.openstreetmap.josm.data.osm.visitor.paint.relations.Multipolygon;
|
|---|
| 164 | import org.openstreetmap.josm.data.osm.visitor.paint.relations.Multipolygon.JoinedWay;
|
|---|
| 165 | import org.openstreetmap.josm.data.osm.visitor.paint.relations.Multipolygon.PolyData.Intersection;
|
|---|
| 166 | @@ -127,10 +128,10 @@
|
|---|
| 167 | @Override
|
|---|
| 168 | public void visit(Relation r) {
|
|---|
| 169 | nonClosedWays.clear();
|
|---|
| 170 | - if (r.isMultipolygon()) {
|
|---|
| 171 | + if (r.isMultipolygon() || r.isBoundary()) {
|
|---|
| 172 | checkMembersAndRoles(r);
|
|---|
| 173 |
|
|---|
| 174 | - Multipolygon polygon = new Multipolygon(Main.map.mapView);
|
|---|
| 175 | + Multipolygon polygon = r.isBoundary() ? new Boundary(Main.map.mapView) : new Multipolygon(Main.map.mapView);
|
|---|
| 176 | polygon.load(r);
|
|---|
| 177 |
|
|---|
| 178 | if (polygon.getOuterWays().isEmpty()) {
|
|---|
| 179 | @@ -252,9 +253,11 @@
|
|---|
| 180 | for (RelationMember rm : r.getMembers()) {
|
|---|
| 181 | if (rm.isWay()) {
|
|---|
| 182 | if (!("inner".equals(rm.getRole()) || "outer".equals(rm.getRole()) || !rm.hasRole())) {
|
|---|
| 183 | - errors.add(new TestError(this, Severity.WARNING, tr("No useful role for multipolygon member"), WRONG_MEMBER_ROLE, rm.getMember()));
|
|---|
| 184 | + if (!(r.isBoundary() && ("enclave".equals(rm.getRole()) || "exclave".equals(rm.getRole())))) {
|
|---|
| 185 | + errors.add(new TestError(this, Severity.WARNING, tr("No useful role for multipolygon member"), WRONG_MEMBER_ROLE, rm.getMember()));
|
|---|
| 186 | + }
|
|---|
| 187 | }
|
|---|
| 188 | - } else {
|
|---|
| 189 | + } else if (r.isMultipolygon()) {
|
|---|
| 190 | errors.add(new TestError(this, Severity.WARNING, tr("Non-Way in multipolygon"), WRONG_MEMBER_TYPE, rm.getMember()));
|
|---|
| 191 | }
|
|---|
| 192 | }
|
|---|
| 193 | Index: src/org/openstreetmap/josm/gui/mappaint/ElemStyles.java
|
|---|
| 194 | ===================================================================
|
|---|
| 195 | --- src/org/openstreetmap/josm/gui/mappaint/ElemStyles.java (revision 4181)
|
|---|
| 196 | +++ src/org/openstreetmap/josm/gui/mappaint/ElemStyles.java (working copy)
|
|---|
| 197 | @@ -13,6 +13,7 @@
|
|---|
| 198 | import org.openstreetmap.josm.data.osm.OsmPrimitive;
|
|---|
| 199 | import org.openstreetmap.josm.data.osm.Relation;
|
|---|
| 200 | import org.openstreetmap.josm.data.osm.Way;
|
|---|
| 201 | +import org.openstreetmap.josm.data.osm.visitor.paint.relations.Boundary;
|
|---|
| 202 | import org.openstreetmap.josm.data.osm.visitor.paint.relations.Multipolygon;
|
|---|
| 203 | import org.openstreetmap.josm.gui.NavigatableComponent;
|
|---|
| 204 | import org.openstreetmap.josm.gui.mappaint.StyleCache.StyleList;
|
|---|
| 205 | @@ -93,10 +94,10 @@
|
|---|
| 206 |
|
|---|
| 207 | for (OsmPrimitive referrer : osm.getReferrers()) {
|
|---|
| 208 | Relation r = (Relation) referrer;
|
|---|
| 209 | - if (!drawMultipolygon || !r.isMultipolygon() || !r.isUsable()) {
|
|---|
| 210 | + if (!drawMultipolygon || !r.isMultipolygon() || !r.isBoundary() || !r.isUsable()) {
|
|---|
| 211 | continue;
|
|---|
| 212 | }
|
|---|
| 213 | - Multipolygon multipolygon = new Multipolygon(nc);
|
|---|
| 214 | + Multipolygon multipolygon = r.isBoundary() ? new Boundary(nc) : new Multipolygon(nc);
|
|---|
| 215 | multipolygon.load(r);
|
|---|
| 216 |
|
|---|
| 217 | if (multipolygon.getOuterWays().contains(osm)) {
|
|---|
| 218 | @@ -246,7 +247,7 @@
|
|---|
| 219 | } else if (osm instanceof Node) {
|
|---|
| 220 | addIfNotNull(sl, NodeElemStyle.create(env));
|
|---|
| 221 | } else if (osm instanceof Relation) {
|
|---|
| 222 | - if (((Relation)osm).isMultipolygon()) {
|
|---|
| 223 | + if (((Relation)osm).isMultipolygon() || ((Relation)osm).isBoundary()) {
|
|---|
| 224 | addIfNotNull(sl, AreaElemStyle.create(c));
|
|---|
| 225 | addIfNotNull(sl, LinePatternElemStyle.create(env));
|
|---|
| 226 | addIfNotNull(sl, LineElemStyle.createLine(env));
|
|---|
| 227 | Index: src/org/openstreetmap/josm/gui/mappaint/mapcss/Condition.java
|
|---|
| 228 | ===================================================================
|
|---|
| 229 | --- src/org/openstreetmap/josm/gui/mappaint/mapcss/Condition.java (revision 4181)
|
|---|
| 230 | +++ src/org/openstreetmap/josm/gui/mappaint/mapcss/Condition.java (working copy)
|
|---|
| 231 | @@ -274,7 +274,7 @@
|
|---|
| 232 | if (equal(id, "closed")) {
|
|---|
| 233 | if (e.osm instanceof Way && ((Way) e.osm).isClosed())
|
|---|
| 234 | return true;
|
|---|
| 235 | - if (e.osm instanceof Relation && ((Relation) e.osm).isMultipolygon())
|
|---|
| 236 | + if (e.osm instanceof Relation && (((Relation) e.osm).isMultipolygon() || ((Relation) e.osm).isBoundary()))
|
|---|
| 237 | return true;
|
|---|
| 238 | return false;
|
|---|
| 239 | } else if (equal(id, "modified"))
|
|---|
| 240 | Index: src/org/openstreetmap/josm/gui/mappaint/mapcss/Selector.java
|
|---|
| 241 | ===================================================================
|
|---|
| 242 | --- src/org/openstreetmap/josm/gui/mappaint/mapcss/Selector.java (revision 4181)
|
|---|
| 243 | +++ src/org/openstreetmap/josm/gui/mappaint/mapcss/Selector.java (working copy)
|
|---|
| 244 | @@ -270,7 +270,7 @@
|
|---|
| 245 | if (base.equals("area")) {
|
|---|
| 246 | if (e.osm instanceof Way)
|
|---|
| 247 | return true;
|
|---|
| 248 | - if (e.osm instanceof Relation && ((Relation) e.osm).isMultipolygon())
|
|---|
| 249 | + if (e.osm instanceof Relation && (((Relation) e.osm).isMultipolygon() || ((Relation) e.osm).isBoundary()))
|
|---|
| 250 | return true;
|
|---|
| 251 | }
|
|---|
| 252 | if (base.equals(OsmPrimitiveType.from(e.osm).getAPIName()))
|
|---|
| 253 | Index: src/org/openstreetmap/josm/gui/mappaint/xml/XmlStyleSource.java
|
|---|
| 254 | ===================================================================
|
|---|
| 255 | --- src/org/openstreetmap/josm/gui/mappaint/xml/XmlStyleSource.java (revision 4181)
|
|---|
| 256 | +++ src/org/openstreetmap/josm/gui/mappaint/xml/XmlStyleSource.java (working copy)
|
|---|
| 257 | @@ -49,6 +49,7 @@
|
|---|
| 258 | super(entry);
|
|---|
| 259 | }
|
|---|
| 260 |
|
|---|
| 261 | + @Override
|
|---|
| 262 | protected void init() {
|
|---|
| 263 | super.init();
|
|---|
| 264 | icons.clear();
|
|---|
| 265 | @@ -88,6 +89,7 @@
|
|---|
| 266 | }
|
|---|
| 267 | }
|
|---|
| 268 |
|
|---|
| 269 | + @Override
|
|---|
| 270 | public InputStream getSourceInputStream() throws IOException {
|
|---|
| 271 | MirroredInputStream in = new MirroredInputStream(url);
|
|---|
| 272 | InputStream zip = in.getZipEntry("xml", "style");
|
|---|
| 273 | @@ -295,7 +297,7 @@
|
|---|
| 274 | }
|
|---|
| 275 | }
|
|---|
| 276 | }
|
|---|
| 277 | - } else if (osm instanceof Way || (osm instanceof Relation && ((Relation)osm).isMultipolygon())) {
|
|---|
| 278 | + } else if (osm instanceof Way || (osm instanceof Relation && (((Relation)osm).isMultipolygon()) || ((Relation)osm).isBoundary())) {
|
|---|
| 279 | WayPrototypesRecord p = new WayPrototypesRecord();
|
|---|
| 280 | get(osm, pretendWayIsClosed || !(osm instanceof Way) || ((Way) osm).isClosed(), p, (useMinMaxScale ? scale : null), mc);
|
|---|
| 281 | if (p.line != null) {
|
|---|