Changeset 15102 in josm
- Timestamp:
- 2019-05-21T10:04:36+02:00 (5 years ago)
- Location:
- trunk
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/data_nodist/amenity-in-amenity.osm
r11887 r15102 5 5 <node id='-3875' action='modify' visible='true' lat='-22.6907376271' lon='-48.56085907164' /> 6 6 <node id='-3871' action='modify' visible='true' lat='-22.69070289438' lon='-48.56081834975' /> 7 <node id='-3864' visible='true' lat='-22.69073023197' lon='-48.56082133585'>8 <tag k='amenity' v='hospital' />9 </node>10 7 <node id='-3863' visible='true' lat='-22.69071631095' lon='-48.56081028236' /> 11 8 <node id='-3862' visible='true' lat='-22.69074204865' lon='-48.56081115962' /> 12 9 <node id='-3861' visible='true' lat='-22.69071809155' lon='-48.56082765213' /> 13 10 <node id='-3860' visible='true' lat='-22.69074528609' lon='-48.56083782836' /> 11 <node id='123' version='3' lat='-22.69073023197' lon='-48.56082133585'> 12 <tag k='amenity' v='hospital' /> 13 </node> 14 14 <way id='-3880' action='modify' visible='true'> 15 15 <nd ref='-3877' /> -
trunk/src/org/openstreetmap/josm/data/validation/tests/MapCSSTagChecker.java
r15064 r15102 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.SUBSET_OR_EQUAL 870 || sel.type == ChildOrParentSelectorType.NOT_SUBSET_OR_EQUAL; 871 if (needEnclosing && p.getDataSet() != null) { 870 872 List<OsmPrimitive> toCheck = new ArrayList<>(); 871 873 toCheck.addAll(p.getDataSet().searchWays(p.getBBox())); -
trunk/src/org/openstreetmap/josm/gui/mappaint/mapcss/MapCSSParser.jj
r14746 r15102 217 217 | < FULLSTOP: "." > 218 218 | < DEG: "°" > 219 | < ELEMENT_OF: "∈" > 219 | < SUBSET_OR_EQUAL: ["∈","⊆"] > 220 | < NOT_SUBSET_OR_EQUAL: "⊈" > 221 | < SUPERSET_OR_EQUAL: "⊇" > 222 | < NOT_SUPERSET_OR_EQUAL: "⊉" > 220 223 | < CROSSING: "⧉" > 221 224 | < PERCENT: "%" > … … 691 694 ( ( c=condition(Context.LINK) | c=class_or_pseudoclass(Context.LINK) ) { conditions.add(c); } )* 692 695 | 693 <ELEMENT_OF> { type = Selector.ChildOrParentSelectorType.ELEMENT_OF; } 696 <SUBSET_OR_EQUAL> { type = Selector.ChildOrParentSelectorType.SUBSET_OR_EQUAL; } 697 | 698 <NOT_SUBSET_OR_EQUAL> { type = Selector.ChildOrParentSelectorType.NOT_SUBSET_OR_EQUAL; } 699 | 700 <SUPERSET_OR_EQUAL> { type = Selector.ChildOrParentSelectorType.SUPERSET_OR_EQUAL; } 701 | 702 <NOT_SUPERSET_OR_EQUAL> { type = Selector.ChildOrParentSelectorType.NOT_SUPERSET_OR_EQUAL; } 694 703 | 695 704 <CROSSING> { type = Selector.ChildOrParentSelectorType.CROSSING; } -
trunk/src/org/openstreetmap/josm/gui/mappaint/mapcss/Selector.java
r15083 r15102 118 118 */ 119 119 enum ChildOrParentSelectorType { 120 CHILD, PARENT, ELEMENT_OF, CROSSING, SIBLING120 CHILD, PARENT, SUBSET_OR_EQUAL, NOT_SUBSET_OR_EQUAL, SUPERSET_OR_EQUAL, NOT_SUPERSET_OR_EQUAL, CROSSING, SIBLING, 121 121 } 122 122 … … 313 313 } 314 314 315 /** 316 * Finds elements which are inside the right element, collects those in {@code children} 317 */ 315 318 private class ContainsFinder extends AbstractFinder { 316 319 protected List<IPrimitive> toCheck; … … 349 352 } 350 353 354 /** 355 * Finds elements which are inside the left element, or in other words, it finds elements enclosing e.osm. 356 * The found enclosing elements are collected in {@code e.children}. 357 */ 358 private class InsideOrEqualFinder extends AbstractFinder { 359 360 protected InsideOrEqualFinder(Environment e) { 361 super(e); 362 } 363 364 @Override 365 public void visit(IWay<?> w) { 366 if (left.matches(new Environment(w).withParent(e.osm)) 367 && w.getBBox().bounds(e.osm.getBBox()) 368 && !Geometry.filterInsidePolygon(Collections.singletonList(e.osm), w).isEmpty()) { 369 addToChildren(e, w); 370 } 371 } 372 373 @Override 374 public void visit(IRelation<?> r) { 375 if (r instanceof Relation && r.isMultipolygon() && r.getBBox().bounds(e.osm.getBBox()) 376 && left.matches(new Environment(r).withParent(e.osm)) 377 && !Geometry.filterInsideMultipolygon(Collections.singletonList(e.osm), (Relation) r).isEmpty()) { 378 addToChildren(e, r); 379 } 380 } 381 } 382 383 private void visitBBox(Environment e, AbstractFinder finder) { 384 boolean withNodes = finder instanceof ContainsFinder; 385 if (left instanceof OptimizedGeneralSelector) { 386 if (withNodes && ((OptimizedGeneralSelector) left).matchesBase(OsmPrimitiveType.NODE)) { 387 finder.visit(e.osm.getDataSet().searchNodes(e.osm.getBBox())); 388 } 389 if (((OptimizedGeneralSelector) left).matchesBase(OsmPrimitiveType.WAY)) { 390 finder.visit(e.osm.getDataSet().searchWays(e.osm.getBBox())); 391 } 392 if (((OptimizedGeneralSelector) left).matchesBase(OsmPrimitiveType.RELATION)) { 393 finder.visit(e.osm.getDataSet().searchRelations(e.osm.getBBox())); 394 } 395 } else { 396 if (withNodes) { 397 finder.visit(e.osm.getDataSet().searchNodes(e.osm.getBBox())); 398 } 399 finder.visit(e.osm.getDataSet().searchWays(e.osm.getBBox())); 400 finder.visit(e.osm.getDataSet().searchRelations(e.osm.getBBox())); 401 } 402 } 403 404 private static boolean isArea(IPrimitive p) { 405 return (p instanceof IWay && ((IWay<?>) p).isClosed() && ((IWay<?>) p).getNodesCount() >= 4) 406 || (p instanceof IRelation && p.isMultipolygon() && !p.isIncomplete()); 407 } 408 351 409 @Override 352 410 public boolean matches(Environment e) { … … 355 413 return false; 356 414 357 if (ChildOrParentSelectorType.ELEMENT_OF == type) { 358 359 if (e.osm instanceof INode || e.osm.getDataSet() == null) { 360 // nodes cannot contain elements 361 return false; 362 } 363 415 if (ChildOrParentSelectorType.SUBSET_OR_EQUAL == type || ChildOrParentSelectorType.NOT_SUBSET_OR_EQUAL == type) { 416 417 if (e.osm.getDataSet() == null || !isArea(e.osm)) { 418 // only areas can contain elements 419 return ChildOrParentSelectorType.NOT_SUBSET_OR_EQUAL == type; 420 } 364 421 ContainsFinder containsFinder = new ContainsFinder(e); 365 422 e.parent = e.osm; 366 423 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()); 380 } 424 visitBBox(e, containsFinder); 381 425 containsFinder.execGeometryTests(); 382 return e.children != null; 426 return ChildOrParentSelectorType.SUBSET_OR_EQUAL == type ? e.children != null : e.children == null; 427 428 } else if (ChildOrParentSelectorType.SUPERSET_OR_EQUAL == type || ChildOrParentSelectorType.NOT_SUPERSET_OR_EQUAL == type) { 429 430 if (e.osm.getDataSet() == null || (e.osm instanceof INode && ((INode) e.osm).getCoor() == null) 431 || (!(e.osm instanceof INode) && !isArea(e.osm))) { 432 return ChildOrParentSelectorType.NOT_SUPERSET_OR_EQUAL == type; 433 } 434 435 InsideOrEqualFinder insideOrEqualFinder = new InsideOrEqualFinder(e); 436 e.parent = e.osm; 437 438 visitBBox(e, insideOrEqualFinder); 439 return ChildOrParentSelectorType.SUPERSET_OR_EQUAL == type ? e.children != null : e.children == null; 383 440 384 441 } else if (ChildOrParentSelectorType.CROSSING == type && e.osm instanceof IWay) { -
trunk/test/unit/org/openstreetmap/josm/gui/mappaint/mapcss/ChildOrParentSelectorTest.java
r15034 r15102 187 187 } 188 188 189 /** 190 * Test inside/contains selectors (spatial test) 191 */ 189 192 @Test 190 193 public void testContains() throws Exception { 191 194 ds = OsmReader.parseDataSet(Files.newInputStream(Paths.get("data_nodist/amenity-in-amenity.osm")), null); 192 195 ChildOrParentSelector css = parse("node[tag(\"amenity\") = parent_tag(\"amenity\")] ∈ *[amenity] {}"); 196 assertFalse(css.matches(new Environment(ds.getPrimitiveById(123, OsmPrimitiveType.NODE)))); 193 197 assertTrue(css.matches(new Environment(ds.getPrimitiveById(123, OsmPrimitiveType.WAY)))); 194 198 assertTrue(css.matches(new Environment(ds.getPrimitiveById(123, OsmPrimitiveType.RELATION)))); 199 css = parse("node[tag(\"amenity\") = parent_tag(\"amenity\")] ⊆ *[amenity] {}"); 200 assertFalse(css.matches(new Environment(ds.getPrimitiveById(123, OsmPrimitiveType.NODE)))); 201 assertTrue(css.matches(new Environment(ds.getPrimitiveById(123, OsmPrimitiveType.WAY)))); 202 assertTrue(css.matches(new Environment(ds.getPrimitiveById(123, OsmPrimitiveType.RELATION)))); 203 css = parse("node[tag(\"amenity\") = parent_tag(\"amenity\")] ⊈ *[amenity] {}"); 204 assertTrue(css.matches(new Environment(ds.getPrimitiveById(123, OsmPrimitiveType.NODE)))); 205 assertFalse(css.matches(new Environment(ds.getPrimitiveById(123, OsmPrimitiveType.WAY)))); 206 assertFalse(css.matches(new Environment(ds.getPrimitiveById(123, OsmPrimitiveType.RELATION)))); 207 css = parse("*[tag(\"amenity\") = parent_tag(\"amenity\")] ⊇ *[amenity] {}"); 208 assertTrue(css.matches(new Environment(ds.getPrimitiveById(123, OsmPrimitiveType.NODE)))); 209 assertTrue(css.matches(new Environment(ds.getPrimitiveById(123, OsmPrimitiveType.WAY)))); 210 assertFalse(css.matches(new Environment(ds.getPrimitiveById(123, OsmPrimitiveType.RELATION)))); 211 css = parse("*[tag(\"amenity\") = parent_tag(\"amenity\")] ⊉ *[amenity] {}"); 212 assertFalse(css.matches(new Environment(ds.getPrimitiveById(123, OsmPrimitiveType.NODE)))); 213 assertFalse(css.matches(new Environment(ds.getPrimitiveById(123, OsmPrimitiveType.WAY)))); 214 assertTrue(css.matches(new Environment(ds.getPrimitiveById(123, OsmPrimitiveType.RELATION)))); 195 215 } 196 216 }
Note:
See TracChangeset
for help on using the changeset viewer.