Changeset 8237 in josm
- Timestamp:
- 2015-04-19T22:21:21+02:00 (10 years ago)
- Location:
- trunk/src/org/openstreetmap/josm
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/org/openstreetmap/josm/data/osm/visitor/paint/relations/Multipolygon.java
r8126 r8237 286 286 public Collection<Long> getWayIds() { 287 287 return wayIds; 288 } 289 290 public List<Node> getNodes() { 291 return nodes; 288 292 } 289 293 … … 355 359 private final List<Way> innerWays = new ArrayList<>(); 356 360 private final List<Way> outerWays = new ArrayList<>(); 357 private final List<PolyData> innerPolygons = new ArrayList<>();358 private final List<PolyData> outerPolygons = new ArrayList<>();359 361 private final List<PolyData> combinedPolygons = new ArrayList<>(); 362 private final List<Node> openEnds = new ArrayList<>(); 360 363 361 364 private boolean incomplete; … … 391 394 } 392 395 396 final List<PolyData> innerPolygons = new ArrayList<>(); 397 final List<PolyData> outerPolygons = new ArrayList<>(); 393 398 createPolygons(innerWays, innerPolygons); 394 399 createPolygons(outerWays, outerPolygons); 395 400 if (!outerPolygons.isEmpty()) { 396 addInnerToOuters(); 401 addInnerToOuters(innerPolygons, outerPolygons); 397 402 } 398 403 } … … 414 419 for (JoinedWay jw: joinWays(waysToJoin)) { 415 420 result.add(new PolyData(jw)); 421 if (!jw.isClosed()) { 422 openEnds.add(jw.getNodes().get(0)); 423 openEnds.add(jw.getNodes().get(jw.getNodes().size() - 1)); 424 } 416 425 } 417 426 } … … 545 554 } 546 555 547 private final void addInnerToOuters() { 556 private final void addInnerToOuters(List<PolyData> innerPolygons, List<PolyData> outerPolygons) { 548 557 549 558 if (innerPolygons.isEmpty()) { … … 568 577 } 569 578 } 570 571 // Clear inner and outer polygons to reduce memory footprint572 innerPolygons.clear();573 outerPolygons.clear();574 579 } 575 580 … … 593 598 return combinedPolygons; 594 599 } 600 601 public List<PolyData> getInnerPolygons() { 602 final List<PolyData> innerPolygons = new ArrayList<>(); 603 createPolygons(innerWays, innerPolygons); 604 return innerPolygons; 605 } 606 607 public List<PolyData> getOuterPolygons() { 608 final List<PolyData> outerPolygons = new ArrayList<>(); 609 createPolygons(outerWays, outerPolygons); 610 return outerPolygons; 611 } 612 613 /** 614 * Returns the start and end node of non-closed rings. 615 * @return the start and end node of non-closed rings. 616 */ 617 public List<Node> getOpenEnds() { 618 return openEnds; 619 } 595 620 } -
trunk/src/org/openstreetmap/josm/data/validation/tests/MultipolygonTest.java
r8126 r8237 24 24 import org.openstreetmap.josm.data.osm.Way; 25 25 import org.openstreetmap.josm.data.osm.visitor.paint.relations.Multipolygon; 26 import org.openstreetmap.josm.data.osm.visitor.paint.relations.Multipolygon.JoinedWay;27 26 import org.openstreetmap.josm.data.osm.visitor.paint.relations.Multipolygon.PolyData.Intersection; 28 27 import org.openstreetmap.josm.data.osm.visitor.paint.relations.MultipolygonCache; … … 59 58 private static volatile ElemStyles styles; 60 59 61 private final List<List<Node>> nonClosedWays = new ArrayList<>();62 60 private final Set<String> keysCheckedByAnotherTest = new HashSet<>(); 63 61 … … 93 91 } 94 92 95 private List<List<Node>> joinWays(Collection<Way> ways) {96 List<List<Node>> result = new ArrayList<>();97 List<Way> waysToJoin = new ArrayList<>();98 for (Way way : ways) {99 if (way.isClosed()) {100 result.add(way.getNodes());101 } else {102 waysToJoin.add(way);103 }104 }105 106 for (JoinedWay jw : Multipolygon.joinWays(waysToJoin)) {107 if (!jw.isClosed()) {108 nonClosedWays.add(jw.getNodes());109 } else {110 result.add(jw.getNodes());111 }112 }113 return result;114 }115 116 93 private GeneralPath createPath(List<Node> nodes) { 117 94 GeneralPath result = new GeneralPath(); … … 124 101 } 125 102 126 private List<GeneralPath> createPolygons(List< List<Node>> joinedWays) {103 private List<GeneralPath> createPolygons(List<Multipolygon.PolyData> joinedWays) { 127 104 List<GeneralPath> result = new ArrayList<>(); 128 for ( List<Node>way : joinedWays) {129 result.add(createPath(way)); 105 for (Multipolygon.PolyData way : joinedWays) { 106 result.add(createPath(way.getNodes())); 130 107 } 131 108 return result; … … 165 142 @Override 166 143 public void visit(Relation r) { 167 nonClosedWays.clear();168 144 if (r.isMultipolygon()) { 169 145 checkMembersAndRoles(r); … … 205 181 } 206 182 207 List<List<Node>> innerWays = joinWays(polygon.getInnerWays()); // Side effect - sets nonClosedWays208 List<List<Node>> outerWays = joinWays(polygon.getOuterWays());209 183 if (styles != null && !"boundary".equals(r.get("type"))) { 210 184 AreaElemStyle area = ElemStyles.getAreaElemStyle(r, false); … … 260 234 } 261 235 262 List<Node> openNodes = new LinkedList<>(); 263 for (List<Node> w : nonClosedWays) { 264 if (w.size()<1) continue; 265 openNodes.add(w.get(0)); 266 openNodes.add(w.get(w.size() - 1)); 267 } 236 List<Node> openNodes = polygon.getOpenEnds(); 268 237 if (!openNodes.isEmpty()) { 269 238 List<OsmPrimitive> primitives = new LinkedList<>(); … … 276 245 277 246 // For painting is used Polygon class which works with ints only. For validation we need more precision 278 List<GeneralPath> outerPolygons = createPolygons( outerWays);279 for ( List<Node>pdInner :innerWays) {247 List<GeneralPath> outerPolygons = createPolygons(polygon.getOuterPolygons()); 248 for (Multipolygon.PolyData pdInner : polygon.getInnerPolygons()) { 280 249 boolean outside = true; 281 250 boolean crossing = false; 282 List<Node>outerWay = null;283 for (int i =0; i<outerWays.size(); i++) {251 Multipolygon.PolyData outerWay = null; 252 for (int i = 0; i < polygon.getOuterPolygons().size(); i++) { 284 253 GeneralPath outer = outerPolygons.get(i); 285 Intersection intersection = getPolygonIntersection(outer, pdInner); 254 Intersection intersection = getPolygonIntersection(outer, pdInner.getNodes()); 286 255 outside = outside & intersection == Intersection.OUTSIDE; 287 256 if (intersection == Intersection.CROSSING) { 288 257 crossing = true; 289 outerWay = outerWays.get(i);258 outerWay = polygon.getOuterPolygons().get(i); 290 259 } 291 260 } 292 261 if (outside || crossing) { 293 262 List<List<Node>> highlights = new ArrayList<>(); 294 highlights.add(pdInner); 263 highlights.add(pdInner.getNodes()); 295 264 if (outside) { 296 265 addError(r, new TestError(this, Severity.WARNING, tr("Multipolygon inner way is outside"), INNER_WAY_OUTSIDE, Collections.singletonList(r), highlights)); 297 } else if (crossing){298 highlights.add(outerWay); 266 } else { 267 highlights.add(outerWay.getNodes()); 299 268 addError(r, new TestError(this, Severity.WARNING, tr("Intersection between multipolygon ways"), CROSSING_WAYS, Collections.singletonList(r), highlights)); 300 269 } -
trunk/src/org/openstreetmap/josm/gui/mappaint/mapcss/Condition.java
r8206 r8237 9 9 import java.util.regex.Pattern; 10 10 11 import org.openstreetmap.josm.Main; 11 12 import org.openstreetmap.josm.data.osm.Node; 12 13 import org.openstreetmap.josm.data.osm.OsmPrimitive; … … 14 15 import org.openstreetmap.josm.data.osm.Tag; 15 16 import org.openstreetmap.josm.data.osm.Way; 17 import org.openstreetmap.josm.data.osm.visitor.paint.relations.MultipolygonCache; 16 18 import org.openstreetmap.josm.gui.mappaint.Cascade; 17 19 import org.openstreetmap.josm.gui.mappaint.ElemStyles; … … 410 412 case "righthandtraffic": 411 413 return ExpressionFactory.Functions.is_right_hand_traffic(e); 414 case "unclosed_multipolygon": 415 return e.osm instanceof Relation && ((Relation) e.osm).isMultipolygon() && 416 !MultipolygonCache.getInstance().get(Main.map.mapView, (Relation) e.osm).getOpenEnds().isEmpty(); 417 case "open_end": 418 // handling at org.openstreetmap.josm.gui.mappaint.mapcss.Selector.ChildOrParentSelector.MultipolygonOpenEndFinder 419 return true; 412 420 } 413 421 return false; -
trunk/src/org/openstreetmap/josm/gui/mappaint/mapcss/Selector.java
r8236 r8237 16 16 import org.openstreetmap.josm.data.osm.Way; 17 17 import org.openstreetmap.josm.data.osm.visitor.AbstractVisitor; 18 import org.openstreetmap.josm.data.osm.visitor.paint.relations.MultipolygonCache; 18 19 import org.openstreetmap.josm.gui.mappaint.Environment; 19 20 import org.openstreetmap.josm.gui.mappaint.Range; … … 219 220 } 220 221 222 private class MultipolygonOpenEndFinder extends AbstractFinder { 223 224 @Override 225 public void visit(Way w) { 226 w.visitReferrers(innerVisitor); 227 } 228 229 public MultipolygonOpenEndFinder(Environment e) { 230 super(e); 231 } 232 233 private final AbstractVisitor innerVisitor = new AbstractFinder(e) { 234 @Override 235 public void visit(Relation r) { 236 if (left.matches(e.withPrimitive(r))) { 237 final List<Node> openEnds = MultipolygonCache.getInstance().get(Main.map.mapView, r).getOpenEnds(); 238 final int openEndIndex = openEnds.indexOf((Node) e.osm); 239 if (openEndIndex >= 0) { 240 e.parent = r; 241 e.index = openEndIndex; 242 e.count = openEnds.size(); 243 } 244 } 245 } 246 }; 247 248 } 249 221 250 private final class CrossingFinder extends AbstractFinder { 222 251 private CrossingFinder(Environment e) { … … 337 366 } 338 367 } 368 } 369 } else if (ChildOrParentSelectorType.CHILD.equals(type) 370 && link.conds != null && !link.conds.isEmpty() 371 && link.conds.get(0) instanceof Condition.PseudoClassCondition 372 && "open_end".equals(((Condition.PseudoClassCondition) link.conds.get(0)).id)) { 373 if (e.osm instanceof Node) { 374 e.osm.visitReferrers(new MultipolygonOpenEndFinder(e)); 375 return e.parent != null; 339 376 } 340 377 } else if (ChildOrParentSelectorType.CHILD.equals(type)) {
Note:
See TracChangeset
for help on using the changeset viewer.