Ticket #13165: 13165_v4.patch
File 13165_v4.patch, 8.0 KB (added by , 5 years ago) |
---|
-
src/org/openstreetmap/josm/data/validation/tests/MapCSSTagChecker.java
94 94 public class MapCSSTagChecker extends Test.TagTest { 95 95 MapCSSTagCheckerIndex indexData; 96 96 final Set<OsmPrimitive> tested = new HashSet<>(); 97 final Map<IPrimitive, Area> mpAreaCache = new HashMap<>(); 97 98 98 99 /** 99 100 * A grouped MapCSSRule with multiple selectors for a single declaration. … … 708 709 MapCSSRuleIndex matchingRuleIndex = indexData.get(p); 709 710 710 711 Environment env = new Environment(p, new MultiCascade(), Environment.DEFAULT_LAYER, null); 712 env.mpAreaCache = mpAreaCache; 711 713 // the declaration indices are sorted, so it suffices to save the last used index 712 714 Declaration lastDeclUsed = null; 713 715 … … 774 776 return false; 775 777 } 776 778 777 private staticCollection<TestError> getErrorsForPrimitive(OsmPrimitive p, boolean includeOtherSeverity,779 private Collection<TestError> getErrorsForPrimitive(OsmPrimitive p, boolean includeOtherSeverity, 778 780 Collection<Set<TagCheck>> checksCol) { 781 // this variant is only used by the assertion tests 779 782 final List<TestError> r = new ArrayList<>(); 780 783 final Environment env = new Environment(p, new MultiCascade(), Environment.DEFAULT_LAYER, null); 784 env.mpAreaCache = mpAreaCache; 781 785 for (Set<TagCheck> schecks : checksCol) { 782 786 for (TagCheck check : schecks) { 783 787 boolean ignoreError = Severity.OTHER == check.getSeverity() && !includeOtherSeverity; … … 991 995 indexData = new MapCSSTagCheckerIndex(checks, includeOtherSeverityChecks(), MapCSSTagCheckerIndex.ALL_TESTS); 992 996 } 993 997 tested.clear(); 998 mpAreaCache.clear(); 994 999 } 995 1000 996 1001 @Override … … 1025 1030 super.endTest(); 1026 1031 // no need to keep the index, it is quickly build and doubles the memory needs 1027 1032 indexData = null; 1033 mpAreaCache.clear(); 1028 1034 } 1029 1035 } -
src/org/openstreetmap/josm/gui/mappaint/Environment.java
76 76 public Map<IPrimitive, Area> intersections; 77 77 78 78 /** 79 * Cache for multipolygon areas, can be null, used with CrossingFinder 80 */ 81 public Map<IPrimitive, Area> mpAreaCache; 82 83 /** 79 84 * Creates a new uninitialized environment. 80 85 */ 81 86 public Environment() { … … 126 131 this.context = other.getContext(); 127 132 this.children = other.children == null ? null : new LinkedHashSet<>(other.children); 128 133 this.intersections = other.intersections == null ? null : new HashMap<>(other.intersections); 134 this.mpAreaCache = other.mpAreaCache; // don't create a copy 129 135 } 130 136 131 137 /** -
src/org/openstreetmap/josm/gui/mappaint/mapcss/Selector.java
305 305 306 306 private CrossingFinder(Environment e) { 307 307 super(e); 308 CheckParameterUtil.ensureThat( e.osm instanceof IWay, "Only ways are supported");308 CheckParameterUtil.ensureThat(isArea(e.osm), "Only areas are supported"); 309 309 layer = OsmUtils.getLayer(e.osm); 310 310 } 311 311 312 312 @Override 313 public void visit(IWay<?> w) { 314 if (Objects.equals(layer, OsmUtils.getLayer(w)) 315 && left.matches(new Environment(w).withParent(e.osm)) 316 && e.osm instanceof IWay) { 317 if (area == null) { 318 area = Geometry.getAreaEastNorth(e.osm); 319 } 320 Pair<PolygonIntersection, Area> is = Geometry.polygonIntersectionResult( 321 Geometry.getAreaEastNorth(w), area, Geometry.INTERSECTION_EPS_EAST_NORTH); 322 if (Geometry.PolygonIntersection.CROSSING == is.a) { 323 addToChildren(e, w); 324 // store intersection area to improve highlight and zoom to problem 325 if (e.intersections == null) { 326 e.intersections = new HashMap<>(); 313 public void visit(Collection<? extends IPrimitive> primitives) { 314 List<? extends IPrimitive> toIgnore; 315 if (e.osm instanceof Relation) { 316 toIgnore = ((IRelation<?>) e.osm).getMemberPrimitivesList(); 317 } else 318 toIgnore = null; 319 for (IPrimitive p : primitives) { 320 if (isPrimitiveUsable(p) && Objects.equals(layer, OsmUtils.getLayer(p)) 321 && left.matches(new Environment(p).withParent(e.osm)) && isArea(p) 322 && (toIgnore == null || !toIgnore.contains(p))) { 323 if (area == null) { 324 area = getAreaEastNorth(e.osm, e); 327 325 } 328 e.intersections.put(w, is.b); 326 Pair<PolygonIntersection, Area> is = Geometry.polygonIntersectionResult(getAreaEastNorth(p, e), 327 area, Geometry.INTERSECTION_EPS_EAST_NORTH); 328 if (Geometry.PolygonIntersection.CROSSING == is.a) { 329 addToChildren(e, p); 330 // store intersection area to improve highlight and zoom to problem 331 if (e.intersections == null) { 332 e.intersections = new HashMap<>(); 333 } 334 e.intersections.put(p, is.b); 335 } 329 336 } 330 337 } 331 338 } … … 452 459 visitBBox(e, insideOrEqualFinder); 453 460 return ChildOrParentSelectorType.SUPERSET_OR_EQUAL == type ? e.children != null : e.children == null; 454 461 455 } else if (ChildOrParentSelectorType.CROSSING == type && e.osm instanceof IWay) {462 } else if (ChildOrParentSelectorType.CROSSING == type) { 456 463 e.parent = e.osm; 457 if (right instanceof OptimizedGeneralSelector 458 && e.osm.getDataSet() != null 459 && ((OptimizedGeneralSelector) right).matchesBase(OsmPrimitiveType.WAY)) { 464 if (e.osm.getDataSet() != null && isArea(e.osm)) { 460 465 final CrossingFinder crossingFinder = new CrossingFinder(e); 461 crossingFinder.visit(e.osm.getDataSet().searchWays(e.osm.getBBox())); 466 visitBBox(e, crossingFinder); 467 return e.children != null; 462 468 } 463 469 return e.children != null; 464 470 } else if (ChildOrParentSelectorType.SIBLING == type) { … … 538 544 return new ChildOrParentSelector(left, link, right.optimizedBaseCheck(), type); 539 545 } 540 546 547 private Area getAreaEastNorth(IPrimitive p, Environment e) { 548 if (e.mpAreaCache != null && p.isMultipolygon()) { 549 Area area = e.mpAreaCache.get(p); 550 if (area == null) { 551 area = Geometry.getAreaEastNorth(p); 552 e.mpAreaCache.put(p, area); 553 } 554 return area; 555 } 556 return Geometry.getAreaEastNorth(p); 557 } 558 541 559 @Override 542 560 public String toString() { 543 561 return left.toString() + ' ' + (ChildOrParentSelectorType.PARENT == type ? '<' : '>') + link + ' ' + right;