}
final Collection<Relation> multipolygons = Utils.filteredCollection(Utils.filter(
e.osm.getReferrers(), Predicates.hasTag("type", "multipolygon")), Relation.class);
final Relation multipolygon = multipolygons.iterator().next();
if (multipolygon == null) throw new NoSuchElementException();
containsFinder = new ContainsFinder(new Environment().withPrimitive(multipolygon)) {
@Override
public boolean isPrimitiveUsable(OsmPrimitive p) {
return super.isPrimitiveUsable(p) && !multipolygon.getMemberPrimitives().contains(p);
}
};
} catch (NoSuchElementException ignore) {
containsFinder = new ContainsFinder(e);
}
e.parent = e.osm;
if (left instanceof OptimizedGeneralSelector) {
if (((OptimizedGeneralSelector) left).matchesBase(OsmPrimitiveType.NODE)) {
containsFinder.visit(e.osm.getDataSet().searchNodes(e.osm.getBBox()));
}
if (((OptimizedGeneralSelector) left).matchesBase(OsmPrimitiveType.WAY)) {
containsFinder.visit(e.osm.getDataSet().searchWays(e.osm.getBBox()));
}
} else {
// use slow test
containsFinder.visit(e.osm.getDataSet().allPrimitives());
}
return e.child != null;
} else if (ChildOrParentSelectorType.CROSSING.equals(type) && e.osm instanceof Way) {
e.parent = e.osm;
final CrossingFinder crossingFinder = new CrossingFinder(e);
if (right instanceof OptimizedGeneralSelector
&& ((OptimizedGeneralSelector) right).matchesBase(OsmPrimitiveType.WAY)) {
crossingFinder.visit(e.osm.getDataSet().searchWays(e.osm.getBBox()));
}
return e.child != null;
} else if (ChildOrParentSelectorType.SIBLING.equals(type)) {
if (e.osm instanceof Node) {
for (Way w : Utils.filteredCollection(e.osm.getReferrers(true), Way.class)) {
final int i = w.getNodes().indexOf(e.osm);
if (i - 1 >= 0) {
final Node n = w.getNode(i - 1);
final Environment e2 = e.withPrimitive(n).withParent(w).withChild(e.osm);
if (left.matches(e2) && link.matches(e2.withLinkContext())) {
e.child = n;
e.index = i;
e.parent = w;
return true;
}