Ticket #10391: 0005-new-selectors.patch

File 0005-new-selectors.patch, 7.5 KB (added by GerdP, 7 years ago)

first approach to implement new selectors

  • src/org/openstreetmap/josm/gui/mappaint/mapcss/MapCSSParser.jj

     
    217217|   < FULLSTOP: "." >
    218218|   < DEG: "°" >
    219219|   < ELEMENT_OF: "∈" >
     220|   < SUBSET_OR_EQUAL: "⊆" >
     221|   < NOT_SUBSET_OR_EQUAL: "⊈" >
     222|   < SUPERSET_OR_EQUAL: "⊇" >
     223|   < NOT_SUPERSET_OR_EQUAL: "⊉" >
    220224|   < CROSSING: "⧉" >
    221225|   < PERCENT: "%" >
    222226|   < COMMENT_START: "/*" > : COMMENT
     
    692696            |
    693697                <ELEMENT_OF> { type = Selector.ChildOrParentSelectorType.ELEMENT_OF; }
    694698            |
     699                <SUBSET_OR_EQUAL> { type = Selector.ChildOrParentSelectorType.SUBSET_OR_EQUAL; }
     700            |
     701                <NOT_SUBSET_OR_EQUAL> { type = Selector.ChildOrParentSelectorType.NOT_SUBSET_OR_EQUAL; }
     702            |
     703                <SUPERSET_OR_EQUAL> { type = Selector.ChildOrParentSelectorType.SUPERSET_OR_EQUAL; }
     704            |
     705                <NOT_SUPERSET_OR_EQUAL> { type = Selector.ChildOrParentSelectorType.NOT_SUPERSET_OR_EQUAL; }
     706            |
    695707                <CROSSING> { type = Selector.ChildOrParentSelectorType.CROSSING; }
    696708            )
    697709            w()
  • src/org/openstreetmap/josm/gui/mappaint/mapcss/Selector.java

     
    117117     * @see ChildOrParentSelector
    118118     */
    119119    enum ChildOrParentSelectorType {
    120         CHILD, PARENT, ELEMENT_OF, CROSSING, SIBLING
     120        CHILD, PARENT, ELEMENT_OF, SUBSET_OR_EQUAL, NOT_SUBSET_OR_EQUAL, SUPERSET_OR_EQUAL, NOT_SUPERSET_OR_EQUAL, CROSSING, SIBLING,
    121121    }
    122122
    123123    /**
     
    317317
    318318            protected ContainsFinder(Environment e) {
    319319                super(e);
    320                 CheckParameterUtil.ensureThat(!(e.osm instanceof INode), "Nodes not supported");
    321320            }
    322321
    323322            @Override
     
    336335                if (toCheck == null || toCheck.isEmpty())
    337336                    return;
    338337
    339                 if (e.osm instanceof IWay) {
     338                if (e.osm instanceof INode) {
     339                    for (IPrimitive p : toCheck) {
     340                        if (p instanceof INode && ((INode) p).getCoor().equals(((INode)e.osm).getCoor()))
     341                            addToChildren(e, p);
     342                    }
     343
     344                } else if (e.osm instanceof IWay) {
    340345                    for (IPrimitive p : Geometry.filterInsidePolygon(toCheck, (IWay<?>) e.osm)) {
    341346                        addToChildren(e, p);
    342347                    }
     
    348353            }
    349354        }
    350355
     356        private class InsideOrEqualFinder extends AbstractFinder {
     357
     358            protected InsideOrEqualFinder(Environment e) {
     359                super(e);
     360            }
     361
     362            @Override
     363            public void visit(INode n) {
     364                if (left.matches(new Environment(n).withParent(e.osm))) {
     365                    if (e.osm instanceof INode) {
     366                        if (n.getCoor().equals(((INode)e.osm).getCoor())) {
     367                            addToChildren(e, n);
     368                        }
     369                    } else {
     370                        if (e.osm instanceof IWay && Geometry.nodeInsidePolygon(n, ((IWay<?>) e.osm).getNodes())) {
     371                            addToChildren(e, n);
     372                        }
     373                    }
     374                }
     375            }
     376
     377            @Override
     378            public void visit(IWay<?> w) {
     379                if (left.matches(new Environment(w).withParent(e.osm))) {
     380                    if (e.osm instanceof INode) {
     381                     // not yet decided
     382                    } else {
     383                        if (!Geometry.filterInsidePolygon(Collections.singletonList(e.osm), w).isEmpty()) {
     384                            addToChildren(e, w);
     385                        }
     386                    }
     387                }
     388            }
     389
     390            @Override
     391            public void visit(IRelation<?> r) {
     392                if (r instanceof Relation && r.isMultipolygon() && left.matches(new Environment(r).withParent(e.osm))) {
     393                    if (e.osm instanceof INode) {
     394                        // not yet decided
     395                    } else {
     396                        if (!Geometry.filterInsideMultipolygon(Collections.singletonList(e.osm), (Relation) r).isEmpty()) {
     397                            addToChildren(e, r);
     398                        }
     399                    }
     400                }
     401            }
     402        }
     403
    351404        @Override
    352405        public boolean matches(Environment e) {
    353406
     
    354407            if (!right.matches(e))
    355408                return false;
    356409
    357             if (ChildOrParentSelectorType.ELEMENT_OF == type) {
     410            if (ChildOrParentSelectorType.ELEMENT_OF == type || ChildOrParentSelectorType.SUBSET_OR_EQUAL == type
     411                    || ChildOrParentSelectorType.NOT_SUBSET_OR_EQUAL == type) {
    358412
    359                 if (e.osm instanceof INode || e.osm.getDataSet() == null) {
    360                     // nodes cannot contain elements
     413                if ((ChildOrParentSelectorType.ELEMENT_OF == type  && e.osm instanceof INode) || e.osm.getDataSet() == null) {
     414                    // for ELEMENT_OF nodes cannot contain elements
    361415                    return false;
    362416                }
    363417
     
    379433                    containsFinder.visit(e.osm.getDataSet().allPrimitives());
    380434                }
    381435                containsFinder.execGeometryTests();
    382                 return e.children != null;
     436                if (ChildOrParentSelectorType.ELEMENT_OF == type || ChildOrParentSelectorType.SUBSET_OR_EQUAL == type)
     437                    return e.children != null;
     438                return e.children == null;
     439            } else if (ChildOrParentSelectorType.SUPERSET_OR_EQUAL == type || ChildOrParentSelectorType.NOT_SUPERSET_OR_EQUAL == type) {
     440                if (e.osm.getDataSet() == null || e.osm instanceof INode && ((INode)e.osm).getCoor() == null) {
     441                    return false;
     442                }
    383443
     444                InsideOrEqualFinder insideOrEqualFinder = new InsideOrEqualFinder(e);
     445                e.parent = e.osm;
     446
     447                if (left instanceof OptimizedGeneralSelector) {
     448                    if (((OptimizedGeneralSelector) left).matchesBase(OsmPrimitiveType.NODE)) {
     449                        insideOrEqualFinder.visit(e.osm.getDataSet().searchNodes(e.osm.getBBox()));
     450                    }
     451                    if (((OptimizedGeneralSelector) left).matchesBase(OsmPrimitiveType.WAY)) {
     452                        insideOrEqualFinder.visit(e.osm.getDataSet().searchWays(e.osm.getBBox()));
     453                    }
     454                    if (((OptimizedGeneralSelector) left).matchesBase(OsmPrimitiveType.RELATION)) {
     455                        insideOrEqualFinder.visit(e.osm.getDataSet().searchRelations(e.osm.getBBox()));
     456                    }
     457                } else {
     458                    // use slow test
     459                    insideOrEqualFinder.visit(e.osm.getDataSet().allPrimitives());
     460                }
     461                return ChildOrParentSelectorType.SUPERSET_OR_EQUAL == type ? e.children != null : e.children == null;
     462
    384463            } else if (ChildOrParentSelectorType.CROSSING == type && e.osm instanceof IWay) {
    385464                e.parent = e.osm;
    386465                if (right instanceof OptimizedGeneralSelector