Ticket #10391: 0005-new-selectors-v2.patch
File 0005-new-selectors-v2.patch, 10.6 KB (added by , 5 years ago) |
---|
-
src/org/openstreetmap/josm/data/validation/tests/MapCSSTagChecker.java
866 866 env.clearSelectorMatchingInformation(); 867 867 if (partialSelection && r.selector instanceof Selector.ChildOrParentSelector) { 868 868 ChildOrParentSelector sel = (Selector.ChildOrParentSelector) r.selector; 869 if (sel.type == ChildOrParentSelectorType.ELEMENT_OF && p.getDataSet() != null) { 869 boolean needEnclosing = sel.type == ChildOrParentSelectorType.ELEMENT_OF 870 || sel.type == ChildOrParentSelectorType.SUBSET_OR_EQUAL 871 || sel.type == ChildOrParentSelectorType.NOT_SUBSET_OR_EQUAL; 872 if (needEnclosing && p.getDataSet() != null) { 870 873 List<OsmPrimitive> toCheck = new ArrayList<>(); 871 874 toCheck.addAll(p.getDataSet().searchWays(p.getBBox())); 872 875 toCheck.addAll(p.getDataSet().searchRelations(p.getBBox())); -
src/org/openstreetmap/josm/gui/mappaint/mapcss/MapCSSParser.jj
217 217 | < FULLSTOP: "." > 218 218 | < DEG: "°" > 219 219 | < ELEMENT_OF: "∈" > 220 | < SUBSET_OR_EQUAL: "⊆" > 221 | < NOT_SUBSET_OR_EQUAL: "⊈" > 222 | < SUPERSET_OR_EQUAL: "⊇" > 223 | < NOT_SUPERSET_OR_EQUAL: "⊉" > 220 224 | < CROSSING: "⧉" > 221 225 | < PERCENT: "%" > 222 226 | < COMMENT_START: "/*" > : COMMENT … … 692 696 | 693 697 <ELEMENT_OF> { type = Selector.ChildOrParentSelectorType.ELEMENT_OF; } 694 698 | 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 | 695 707 <CROSSING> { type = Selector.ChildOrParentSelectorType.CROSSING; } 696 708 ) 697 709 w() -
src/org/openstreetmap/josm/gui/mappaint/mapcss/Selector.java
117 117 * @see ChildOrParentSelector 118 118 */ 119 119 enum ChildOrParentSelectorType { 120 CHILD, PARENT, ELEMENT_OF, CROSSING, SIBLING120 CHILD, PARENT, ELEMENT_OF, SUBSET_OR_EQUAL, NOT_SUBSET_OR_EQUAL, SUPERSET_OR_EQUAL, NOT_SUPERSET_OR_EQUAL, CROSSING, SIBLING, 121 121 } 122 122 123 123 /** … … 312 312 } 313 313 } 314 314 315 /** 316 * Finds elements which are inside the right element, collects those in {@code children} 317 * If e.osm is a node it finds nodes with with equal position. 318 */ 315 319 private class ContainsFinder extends AbstractFinder { 316 320 protected List<IPrimitive> toCheck; 317 321 318 322 protected ContainsFinder(Environment e) { 319 323 super(e); 320 CheckParameterUtil.ensureThat(!(e.osm instanceof INode), "Nodes not supported");321 324 } 322 325 323 326 @Override … … 336 339 if (toCheck == null || toCheck.isEmpty()) 337 340 return; 338 341 339 if (e.osm instanceof IWay) { 342 if (e.osm instanceof INode) { 343 for (IPrimitive p : toCheck) { 344 if (p instanceof INode && ((INode) p).getCoor().equals(((INode) e.osm).getCoor())) 345 addToChildren(e, p); 346 } 347 } else if (e.osm instanceof IWay) { 340 348 for (IPrimitive p : Geometry.filterInsidePolygon(toCheck, (IWay<?>) e.osm)) { 341 349 addToChildren(e, p); 342 350 } … … 348 356 } 349 357 } 350 358 359 /** 360 * Finds elements which are inside the left element, or in other words, it finds elements enclosing e.osm. 361 * The found enclosing elements are collected in {@code e.children}. 362 */ 363 private class InsideOrEqualFinder extends AbstractFinder { 364 365 protected InsideOrEqualFinder(Environment e) { 366 super(e); 367 } 368 369 @Override 370 public void visit(INode n) { 371 // rather special case: nodes with equal coordinates 372 if (e.osm instanceof INode && n.getCoor().equals(((INode) e.osm).getCoor()) 373 && left.matches(new Environment(n).withParent(e.osm))) { 374 addToChildren(e, n); 375 } 376 } 377 378 @Override 379 public void visit(IWay<?> w) { 380 if (left.matches(new Environment(w).withParent(e.osm)) 381 && w.getBBox().bounds(e.osm.getBBox()) 382 && !Geometry.filterInsidePolygon(Collections.singletonList(e.osm), w).isEmpty()) { 383 addToChildren(e, w); 384 } 385 } 386 387 @Override 388 public void visit(IRelation<?> r) { 389 if (r instanceof Relation && r.isMultipolygon() && r.getBBox().bounds(e.osm.getBBox()) 390 && left.matches(new Environment(r).withParent(e.osm)) 391 && !Geometry.filterInsideMultipolygon(Collections.singletonList(e.osm), (Relation) r).isEmpty()) { 392 addToChildren(e, r); 393 } 394 } 395 } 396 397 private void visitBBox(Environment e, AbstractFinder finder) { 398 boolean nodesOnly = finder instanceof ContainsFinder && e.osm instanceof INode; 399 if (left instanceof OptimizedGeneralSelector) { 400 if (((OptimizedGeneralSelector) left).matchesBase(OsmPrimitiveType.NODE)) { 401 finder.visit(e.osm.getDataSet().searchNodes(e.osm.getBBox())); 402 } 403 if (!nodesOnly) { 404 if (((OptimizedGeneralSelector) left).matchesBase(OsmPrimitiveType.WAY)) { 405 finder.visit(e.osm.getDataSet().searchWays(e.osm.getBBox())); 406 } 407 if (((OptimizedGeneralSelector) left).matchesBase(OsmPrimitiveType.RELATION)) { 408 finder.visit(e.osm.getDataSet().searchRelations(e.osm.getBBox())); 409 } 410 } 411 } else { 412 finder.visit(e.osm.getDataSet().searchNodes(e.osm.getBBox())); 413 if (!nodesOnly) { 414 finder.visit(e.osm.getDataSet().searchWays(e.osm.getBBox())); 415 finder.visit(e.osm.getDataSet().searchRelations(e.osm.getBBox())); 416 } 417 } 418 } 419 420 private static boolean isArea(IPrimitive p) { 421 return (p instanceof IWay && ((IWay<?>) p).isClosed() && ((IWay<?>) p).getNodesCount() >= 4) 422 || (p instanceof IRelation && p.isMultipolygon() && !p.isIncomplete()); 423 } 424 351 425 @Override 352 426 public boolean matches(Environment e) { 353 427 … … 354 428 if (!right.matches(e)) 355 429 return false; 356 430 357 if (ChildOrParentSelectorType.ELEMENT_OF == type) { 431 if (ChildOrParentSelectorType.ELEMENT_OF == type || ChildOrParentSelectorType.SUBSET_OR_EQUAL == type 432 || ChildOrParentSelectorType.NOT_SUBSET_OR_EQUAL == type) { 358 433 359 if (e.osm instanceof INode || e.osm.getDataSet() == null) {360 // nodes cannot contain elements434 if (e.osm.getDataSet() == null || (ChildOrParentSelectorType.ELEMENT_OF == type && e.osm instanceof INode)) { 435 // for ELEMENT_OF nodes cannot contain elements 361 436 return false; 362 437 } 363 438 if (!(e.osm instanceof INode) && !isArea(e.osm)) { 439 return false; 440 } 364 441 ContainsFinder containsFinder = new ContainsFinder(e); 365 442 e.parent = e.osm; 366 443 367 if (left instanceof OptimizedGeneralSelector) { 368 if (((OptimizedGeneralSelector) left).matchesBase(OsmPrimitiveType.NODE)) { 369 containsFinder.visit(e.osm.getDataSet().searchNodes(e.osm.getBBox())); 370 } 371 if (((OptimizedGeneralSelector) left).matchesBase(OsmPrimitiveType.WAY)) { 372 containsFinder.visit(e.osm.getDataSet().searchWays(e.osm.getBBox())); 373 } 374 if (((OptimizedGeneralSelector) left).matchesBase(OsmPrimitiveType.RELATION)) { 375 containsFinder.visit(e.osm.getDataSet().searchRelations(e.osm.getBBox())); 376 } 377 } else { 378 // use slow test 379 containsFinder.visit(e.osm.getDataSet().allPrimitives()); 444 visitBBox(e, containsFinder); 445 containsFinder.execGeometryTests(); 446 if (ChildOrParentSelectorType.ELEMENT_OF == type || ChildOrParentSelectorType.SUBSET_OR_EQUAL == type) 447 return e.children != null; 448 return e.children == null; 449 } else if (ChildOrParentSelectorType.SUPERSET_OR_EQUAL == type || ChildOrParentSelectorType.NOT_SUPERSET_OR_EQUAL == type) { 450 if (e.osm.getDataSet() == null || (e.osm instanceof INode && ((INode) e.osm).getCoor() == null)) { 451 return false; 380 452 } 381 containsFinder.execGeometryTests(); 382 return e.children != null; 453 if (!(e.osm instanceof INode) && !isArea(e.osm)) { 454 return false; 455 } 383 456 457 InsideOrEqualFinder insideOrEqualFinder = new InsideOrEqualFinder(e); 458 e.parent = e.osm; 459 460 visitBBox(e, insideOrEqualFinder); 461 return ChildOrParentSelectorType.SUPERSET_OR_EQUAL == type ? e.children != null : e.children == null; 462 384 463 } else if (ChildOrParentSelectorType.CROSSING == type && e.osm instanceof IWay) { 385 464 e.parent = e.osm; 386 465 if (right instanceof OptimizedGeneralSelector