private Seq<PolygonwithHoles> buildMultipolygons( Hashtable<Long, Point2D> nodes, Hashtable<Long, List<Long>> multipolygonWays, List<List<Tuple2<WayRole, Long>>> multipolygonWayRefs) { return Seq.seq(multipolygonWayRefs) .map( waysOfPoly -> { try { // I know this not how should assemble them, but parsing OSM wasn't our objective. List<Polygon> holes = new ArrayList<>(); Polygon outer = null; for (Tuple2<WayRole, Long> way : waysOfPoly) { WayRole role = way.v1; long wayRef = way.v2; List<Long> nodeRefs = multipolygonWays.get(wayRef); Polygon p = buildPolygonFromWayRefs(nodeRefs, nodes); if (role == WayRole.OUTER && outer == null && p.GetPointsNumber() > 0) { outer = p; } else if (role == WayRole.INNER && p.GetPointsNumber() > 0) { holes.add(p); } else { LOG.warn("Could not process a way"); } } return new PolygonwithHoles(outer, holes); } catch (Exception ex) { // System.out.println("Failed to build a certain multipolygon"); } return null; }) .filter(p -> p != null); }
/** * Requires vn to point to a way element. From there it iterates over all matches of the ap. Puts * a dummy point into nodes for every node it finds. */ private List<Long> extractNodeRefs(VTDNav vn, Hashtable<Long, Point2D> nodes) throws NavException, XPathEvalException { vn.push(); List<Long> refs = new ArrayList<>(); for (int j = NODE_REF_PATH.evalXPath(); j != -1; j = NODE_REF_PATH.evalXPath()) { long ref = Long.parseLong(vn.toString(j + 1)); refs.add(ref); nodes.put(ref, new Point2D(0, 0)); } NODE_REF_PATH.resetXPath(); vn.pop(); return refs; }