protected void checkNumberOfLanesByKey(final OsmPrimitive p, String lanesKey, String message) { final Collection<String> keysForPattern = Utils.filter( p.keySet(), Predicates.stringContainsPattern(Pattern.compile(":" + lanesKey + "$"))); if (keysForPattern.size() < 1) { // nothing to check return; } final Set<Integer> lanesCount = new HashSet<Integer>( Utils.transform( keysForPattern, new Utils.Function<String, Integer>() { @Override public Integer apply(String key) { return getLanesCount(p.get(key)); } })); if (lanesCount.size() > 1) { // if not all numbers are the same errors.add(new TestError(this, Severity.WARNING, message, 3100, p)); } else if (lanesCount.size() == 1 && p.hasKey(lanesKey)) { // ensure that lanes <= *:lanes try { if (Integer.parseInt(p.get(lanesKey)) > lanesCount.iterator().next()) { errors.add( new TestError( this, Severity.WARNING, tr("Number of {0} greater than {1}", lanesKey, "*:" + lanesKey), 3100, p)); } } catch (NumberFormatException ignore) { Main.debug(ignore.getMessage()); } } }
@Override public boolean matches(Environment e) { if (!right.matches(e)) return false; if (ChildOrParentSelectorType.ELEMENT_OF.equals(type)) { if (e.osm instanceof Node || e.osm.getDataSet() == null) { // nodes cannot contain elements return false; } ContainsFinder containsFinder; try { // if right selector also matches relations and if matched primitive is a way which is // part of a multipolygon, // use the multipolygon for further analysis if (!(e.osm instanceof Way) || (right instanceof OptimizedGeneralSelector && !((OptimizedGeneralSelector) right).matchesBase(OsmPrimitiveType.RELATION))) { throw new NoSuchElementException(); } 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(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.count = w.getNodesCount(); e.parent = w; return true; } } } } } else if (ChildOrParentSelectorType.CHILD.equals(type) && link.conds != null && !link.conds.isEmpty() && link.conds.get(0) instanceof Condition.OpenEndPseudoClassCondition) { if (e.osm instanceof Node) { e.osm.visitReferrers(new MultipolygonOpenEndFinder(e)); return e.parent != null; } } else if (ChildOrParentSelectorType.CHILD.equals(type)) { MatchingReferrerFinder collector = new MatchingReferrerFinder(e); e.osm.visitReferrers(collector); if (e.parent != null) return true; } else if (ChildOrParentSelectorType.PARENT.equals(type)) { if (e.osm instanceof Way) { List<Node> wayNodes = ((Way) e.osm).getNodes(); for (int i = 0; i < wayNodes.size(); i++) { Node n = wayNodes.get(i); if (left.matches(e.withPrimitive(n))) { if (link.matches(e.withChildAndIndexAndLinkContext(n, i, wayNodes.size()))) { e.child = n; e.index = i; e.count = wayNodes.size(); return true; } } } } else if (e.osm instanceof Relation) { List<RelationMember> members = ((Relation) e.osm).getMembers(); for (int i = 0; i < members.size(); i++) { OsmPrimitive member = members.get(i).getMember(); if (left.matches(e.withPrimitive(member))) { if (link.matches(e.withChildAndIndexAndLinkContext(member, i, members.size()))) { e.child = member; e.index = i; e.count = members.size(); return true; } } } } } return false; }