Ignore:
Timestamp:
2019-05-11T11:15:49+02:00 (5 years ago)
Author:
GerdP
Message:

fix #17695

  • add support to find multipolygon inside polygon or multipolygon with ContainsFinder
  • add some unit tests
  • performance_1: improve isPolygonInsideMultiPolygon() by using the areas calculated

in MultipolygonBuilder.joinWays() instead of calling getArea() again.

  • performance_2: improve isPolygonInsideMultiPolygon() by first checking bounding boxes (helps with complex MP containing many inners as it avoids the Area.intersect() method)
  • performance_3: implement new methods to reuse result of complex method MultipolygonBuilder.joinWays() in ContainsFinder
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/org/openstreetmap/josm/gui/mappaint/mapcss/Selector.java

    r15068 r15069  
    55
    66import java.text.MessageFormat;
     7import java.util.ArrayList;
    78import java.util.Collection;
    89import java.util.Collections;
     
    313314
    314315        private class ContainsFinder extends AbstractFinder {
     316            protected List<IPrimitive> toCheck;
     317
    315318            protected ContainsFinder(Environment e) {
    316319                super(e);
     
    319322
    320323            @Override
    321             public void visit(INode n) {
    322                 if (left.matches(new Environment(n).withParent(e.osm))
    323                     && ((e.osm instanceof IWay && Geometry.nodeInsidePolygon(n, ((IWay<?>) e.osm).getNodes()))
    324                             || (e.osm instanceof Relation && (
    325                                     (Relation) e.osm).isMultipolygon() && Geometry.isNodeInsideMultiPolygon(n, (Relation) e.osm, null)))) {
    326                     addToChildren(e, n);
    327                 }
    328             }
    329 
    330             @Override
    331             public void visit(IWay<?> w) {
    332                 if (left.matches(new Environment(w).withParent(e.osm))
    333                     && ((e.osm instanceof IWay && Geometry.PolygonIntersection.FIRST_INSIDE_SECOND.equals(
    334                             Geometry.polygonIntersection(w.getNodes(), ((IWay<?>) e.osm).getNodes())))
    335                             || (e.osm instanceof Relation && (
    336                                     (Relation) e.osm).isMultipolygon()
    337                                     && Geometry.isPolygonInsideMultiPolygon(w.getNodes(), (Relation) e.osm, null)))) {
    338                     addToChildren(e, w);
     324            public void visit(Collection<? extends IPrimitive> primitives) {
     325                for (IPrimitive p : primitives) {
     326                    if (p != e.osm && isPrimitiveUsable(p) && left.matches(new Environment(p).withParent(e.osm))) {
     327                        if (toCheck == null) {
     328                            toCheck = new ArrayList<>();
     329                        }
     330                        toCheck.add(p);
     331                    }
     332                }
     333            }
     334
     335            void execGeometryTests() {
     336                if (toCheck == null || toCheck.isEmpty())
     337                    return;
     338
     339                if (e.osm instanceof IWay) {
     340                    for (IPrimitive p : Geometry.filterInsidePolygon(toCheck, (IWay<?>) e.osm)) {
     341                        addToChildren(e, p);
     342                    }
     343                } else if (e.osm instanceof Relation) {
     344                    for (IPrimitive p : Geometry.filterInsideMultipolygon(toCheck, (Relation) e.osm)) {
     345                        addToChildren(e, p);
     346                    }
    339347                }
    340348            }
     
    364372                        containsFinder.visit(e.osm.getDataSet().searchWays(e.osm.getBBox()));
    365373                    }
     374                    if (((OptimizedGeneralSelector) left).matchesBase(OsmPrimitiveType.RELATION)) {
     375                        containsFinder.visit(e.osm.getDataSet().searchRelations(e.osm.getBBox()));
     376                    }
    366377                } else {
    367378                    // use slow test
    368379                    containsFinder.visit(e.osm.getDataSet().allPrimitives());
    369380                }
    370 
     381                containsFinder.execGeometryTests();
    371382                return e.children != null;
    372383
Note: See TracChangeset for help on using the changeset viewer.