@Test public void testBackrefrenceForWay_Full() throws OsmTransferException { Way w = lookupWay(ds, 1); assertNotNull(w); // way with name "way-1" is referred to by two relations // OsmServerBackreferenceReader reader = new OsmServerBackreferenceReader(w); reader.setReadFull(true); DataSet referers = reader.parseOsm(NullProgressMonitor.INSTANCE); assertEquals(6, referers.getWays().size()); // 6 ways referred by two relations for (Way w1 : referers.getWays()) { assertEquals(false, w1.isIncomplete()); } assertEquals(2, referers.getRelations().size()); // two relations referring to Set<Long> expectedNodeIds = new HashSet<Long>(); for (Way way : referers.getWays()) { Way orig = (Way) ds.getPrimitiveById(way); for (Node n : orig.getNodes()) { expectedNodeIds.add(n.getId()); } } assertEquals(expectedNodeIds.size(), referers.getNodes().size()); for (Node n : referers.getNodes()) { assertEquals(true, expectedNodeIds.contains(n.getId())); } Relation r = lookupRelation(referers, 0); assertNotNull(r); assertEquals(false, r.isIncomplete()); r = lookupRelation(referers, 1); assertEquals(false, r.isIncomplete()); }
/** * Compute weight and add edge to the graph * * @param way * @param from * @param to */ private void addEdge(Way way, Node from, Node to) { LatLon fromLL = from.getCoor(); LatLon toLL = from.getCoor(); if (fromLL == null || toLL == null) { return; } double length = fromLL.greatCircleDistance(toLL); OsmEdge edge = new OsmEdge(way, from, to); edge.setSpeed(12.1); graph.addEdge(from, to, edge); // weight = getWeight(way); double weight = getWeight(way, length); setWeight(edge, length); logger.debug( "edge for way " + way.getId() + "(from node " + from.getId() + " to node " + to.getId() + ") has weight: " + weight); ((DirectedWeightedMultigraph<Node, OsmEdge>) graph).setEdgeWeight(edge, weight); }
/** * Extract and store relation information based on the relation member * * @param src The relation member to store information about */ public RelMember(RelationMember src) { role = src.getRole(); type = src.getType(); rel_id = 0; coor = new ArrayList<LatLon>(); if (src.isNode()) { Node r = src.getNode(); tags = r.getKeys(); coor = new ArrayList<LatLon>(1); coor.add(r.getCoor()); } if (src.isWay()) { Way r = src.getWay(); tags = r.getKeys(); List<Node> wNodes = r.getNodes(); coor = new ArrayList<LatLon>(wNodes.size()); for (Node wNode : wNodes) { coor.add(wNode.getCoor()); } } if (src.isRelation()) { Relation r = src.getRelation(); tags = r.getKeys(); rel_id = r.getId(); coor = new ArrayList<LatLon>(); } }
private Node createPlatform(StopPointType stop) { Node n = createNode(createLatLon(stop)); n.put(OSM_PUBLIC_TRANSPORT, OSM_PLATFORM); linkTridentObjectToOsmPrimitive(stop, n); n.put("name", stop.getName()); return n; }
protected Set<Long> getNodeIdsInWay(Way way) { HashSet<Long> ret = new HashSet<Long>(); if (way == null) return ret; for (Node n : way.getNodes()) { ret.add(n.getId()); } return ret; }
private static BBox getNodesBounds(ArrayList<Node> nodes) { BBox bounds = new BBox(nodes.get(0)); for (Node n : nodes) { bounds.add(n.getCoor()); } return bounds; }
protected static void populateTestDataSetWithNodes(DataSet ds) { for (int i = 0; i < 100; i++) { Node n = new Node(); n.setCoor(new LatLon(-36.6, 47.6)); n.put("name", "node-" + i); ds.addPrimitive(n); } }
@Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((end == null) ? 0 : end.hashCode()); result = prime * result + ((start == null) ? 0 : start.hashCode()); result = prime * result + ((way == null) ? 0 : way.hashCode()); return result; }
@Override public void updateDataSet(DataSet ds) { for (Node n : ds.getNodes()) { n.remove("name"); n.put("amenity", "recycling"); n.put("recycling:glass", "no"); n.put("recycling:glass_bottles", "yes"); } }
/** * Determine which ways to split. * * @param selectedWays List of user selected ways. * @param selectedNodes List of user selected nodes. * @return List of ways to split */ private List<Way> getApplicableWays(List<Way> selectedWays, List<Node> selectedNodes) { if (selectedNodes.isEmpty()) return null; // Special case - one of the selected ways touches (not cross) way that we // want to split if (selectedNodes.size() == 1) { Node n = selectedNodes.get(0); List<Way> referedWays = OsmPrimitive.getFilteredList(n.getReferrers(), Way.class); Way inTheMiddle = null; for (Way w : referedWays) { // Need to look at all nodes see #11184 for a case where node n is // firstNode, lastNode and also in the middle if (selectedWays.contains(w) && w.isInnerNode(n)) { if (inTheMiddle == null) { inTheMiddle = w; } else { inTheMiddle = null; break; } } } if (inTheMiddle != null) return Collections.singletonList(inTheMiddle); } // List of ways shared by all nodes List<Way> result = new ArrayList<>( OsmPrimitive.getFilteredList(selectedNodes.get(0).getReferrers(), Way.class)); for (int i = 1; i < selectedNodes.size(); i++) { List<OsmPrimitive> ref = selectedNodes.get(i).getReferrers(); for (Iterator<Way> it = result.iterator(); it.hasNext(); ) { if (!ref.contains(it.next())) { it.remove(); } } } // Remove broken ways for (Iterator<Way> it = result.iterator(); it.hasNext(); ) { if (it.next().getNodesCount() <= 2) { it.remove(); } } if (selectedWays.isEmpty()) return result; else { // Return only selected ways for (Iterator<Way> it = result.iterator(); it.hasNext(); ) { if (!selectedWays.contains(it.next())) { it.remove(); } } return result; } }
public Collection<Node> nearbyNodes(double dist) { // If you're looking for nodes that are farther away that we looked for last time, // the cached result is no good if (dist > nearbyNodeCacheDist) { nearbyNodeCache = null; } if (nearbyNodeCache != null) { // If we've cached an area greater than the // one now being asked for... if (nearbyNodeCacheDist > dist) { // Used the cached result and trim out // the nodes that are not in the smaller // area, but keep the old larger cache. Set<Node> trimmed = new HashSet<>(nearbyNodeCache); Set<Node> initial = new HashSet<>(nearbyNodeCache); for (Node n : initial) { if (!nearby(n, dist)) { trimmed.remove(n); } } return trimmed; } return nearbyNodeCache; } /* * We know that any point near the line must be at * least as close as the other end of the line, plus * a little fudge for the distance away ('dist'). */ // This needs to be a hash set because the searches // overlap a bit and can return duplicate nodes. nearbyNodeCache = null; List<LatLon> bounds = this.getBounds(dist * (360.0d / (Ellipsoid.WGS84.a * 2 * Math.PI))); List<Node> foundNodes = endnodesHighway.search(new BBox(bounds.get(0), bounds.get(1))); foundNodes.addAll(endnodes.search(new BBox(bounds.get(0), bounds.get(1)))); for (Node n : foundNodes) { if (!nearby(n, dist) || !n.getCoor().isIn(dsArea)) { continue; } // It is actually very rare for us to find a node // so defer as much of the work as possible, like // allocating the hash set if (nearbyNodeCache == null) { nearbyNodeCache = new HashSet<>(); } nearbyNodeCache.add(n); } nearbyNodeCacheDist = dist; if (nearbyNodeCache == null) { nearbyNodeCache = Collections.emptySet(); } return nearbyNodeCache; }
public void visit(Way w) { if (w.isNewOrUndeleted() || w.isModified() || w.isDeleted()) { // upload new ways as well as modified and deleted ones hull.add(w); for (Node n : w.getNodes()) { // we upload modified nodes even if they aren't in the current // selection. n.visit(this); } } }
/** * Collect all nodes with more than one referrer. * * @param ways Ways from witch nodes are selected * @return List of nodes with more than one referrer */ private static List<Node> collectNodesWithExternReferers(List<Way> ways) { List<Node> withReferrers = new ArrayList<>(); for (Way w : ways) { for (Node n : w.getNodes()) { if (n.getReferrers().size() > 1) { withReferrers.add(n); } } } return withReferrers; }
public double getLength() { double length = 0; Node last = nodes.get(0); for (Node n : nodes.subList(1, nodes.size())) { length += last.getCoor().greatCircleDistance(n.getCoor()); last = n; } return length; }
static { MultiCascade mc = new MultiCascade(); Cascade c = mc.getOrCreateCascade("default"); c.put(TEXT, Keyword.AUTO); Node n = new Node(); n.put("name", "dummy"); SIMPLE_NODE_TEXT_ELEMSTYLE = create( new Environment(n, mc, "default", null), NodeElemStyle.SIMPLE_NODE_ELEMSTYLE.getBoxProvider()); if (SIMPLE_NODE_TEXT_ELEMSTYLE == null) throw new AssertionError(); }
private WayInPolygon advanceNextWay(boolean rightmost) { Node headNode = !lastWayReverse ? lastWay.way.lastNode() : lastWay.way.firstNode(); Node prevNode = !lastWayReverse ? lastWay.way.getNode(lastWay.way.getNodesCount() - 2) : lastWay.way.getNode(1); // find best next way WayInPolygon bestWay = null; Node bestWayNextNode = null; boolean bestWayReverse = false; for (WayInPolygon way : availableWays) { if (way.way.firstNode().equals(headNode)) { // start adjacent to headNode Node nextNode = way.way.getNode(1); if (nextNode.equals(prevNode)) { // this is the path we came from - ignore it. } else if (bestWay == null || (Geometry.isToTheRightSideOfLine(prevNode, headNode, bestWayNextNode, nextNode) == rightmost)) { // the new way is better bestWay = way; bestWayReverse = false; bestWayNextNode = nextNode; } } if (way.way.lastNode().equals(headNode)) { // end adjacent to headNode Node nextNode = way.way.getNode(way.way.getNodesCount() - 2); if (nextNode.equals(prevNode)) { // this is the path we came from - ignore it. } else if (bestWay == null || (Geometry.isToTheRightSideOfLine(prevNode, headNode, bestWayNextNode, nextNode) == rightmost)) { // the new way is better bestWay = way; bestWayReverse = true; bestWayNextNode = nextNode; } } } lastWay = bestWay; lastWayReverse = bestWayReverse; return lastWay; }
/** * Apply selected routing algorithm to the graph. * * @param nodes Nodes used to calculate path. * @param algorithm Algorithm used to compute the path, * RoutingGraph.Algorithm.ROUTING_ALG_DIJKSTRA or * RoutingGraph.Algorithm.ROUTING_ALG_BELLMANFORD * @return new path. */ public List<OsmEdge> applyAlgorithm(List<Node> nodes, Algorithm algorithm) { List<OsmEdge> path = new ArrayList<>(); Graph<Node, OsmEdge> g; double totalWeight = 0; RoutingLayer layer = (RoutingLayer) Main.map.mapView.getActiveLayer(); RoutingModel routingModel = layer.getRoutingModel(); if (graph == null || routingModel.getOnewayChanged()) this.createGraph(); logger.debug("apply algorithm between nodes "); for (Node node : nodes) { logger.debug(node.getId()); } logger.debug("-----------------------------------"); // Assign the graph to g g = graph; switch (algorithm) { case ROUTING_ALG_DIJKSTRA: logger.debug("Using Dijkstra algorithm"); DijkstraShortestPath<Node, OsmEdge> routingk = null; for (int index = 1; index < nodes.size(); ++index) { routingk = new DijkstraShortestPath<>(g, nodes.get(index - 1), nodes.get(index)); if (routingk.getPathEdgeList() == null) { logger.debug("no path found!"); break; } path.addAll(routingk.getPathEdgeList()); totalWeight += routingk.getPathLength(); } break; case ROUTING_ALG_BELLMANFORD: logger.debug("Using Bellman Ford algorithm"); for (int index = 1; index < nodes.size(); ++index) { path = BellmanFordShortestPath.findPathBetween( rgDelegator, nodes.get(index - 1), nodes.get(index)); if (path == null) { logger.debug("no path found!"); return null; } } break; default: logger.debug("Wrong algorithm"); break; } logger.debug("shortest path found: " + path + "\nweight: " + totalWeight); return path; }
@Override public void visit(Node n) { assert aNode != null; if (n.hasKey(tag)) { double dist = n.getCoor().greatCircleDistance(aNode.getCoor()); if (dist < minDist && dist < maxDist) { minDist = dist; currentValue = n.get(tag); srcNode = n; } } }
/** Rotate nodes. */ @Override protected void transformNodes() { for (Node n : nodes) { double cosPhi = Math.cos(rotationAngle); double sinPhi = Math.sin(rotationAngle); EastNorth oldEastNorth = oldStates.get(n).getEastNorth(); double x = oldEastNorth.east() - pivot.east(); double y = oldEastNorth.north() - pivot.north(); double nx = cosPhi * x + sinPhi * y + pivot.east(); double ny = -sinPhi * x + cosPhi * y + pivot.north(); n.setEastNorth(new EastNorth(nx, ny)); } }
public void visit(List<Node> nodes) { Node lastN = null; for (Node n : nodes) { if (lastN == null) { lastN = n; continue; } if (n.isDrawable() && isSegmentVisible(lastN, n)) { drawSegment(lastN, n, severity.getColor()); } lastN = n; } }
private void appendNode(double x, double y) throws IOException { if (currentway == null) { throw new IOException("Shape is started incorectly"); } Node nd = new Node(projection.eastNorth2latlon(center.add(x * scale, -y * scale))); if (nd.getCoor().isOutSideWorld()) { throw new IOException("Shape goes outside the world"); } currentway.addNode(nd); nodes.add(nd); lastX = x; lastY = y; }
void addCoordinates(Node n) { if (n.getCoor() != null) { add( tr("Coordinates: "), Double.toString(n.getCoor().lat()), ", ", Double.toString(n.getCoor().lon())); add( tr("Coordinates (projected): "), Double.toString(n.getEastNorth().east()), ", ", Double.toString(n.getEastNorth().north())); } }
public boolean nearby(Node n, double dist) { if (w == null) { Main.debug("way null"); return false; } if (w.containsNode(n)) return false; if (n.isKeyTrue("noexit")) return false; EastNorth coord = n.getEastNorth(); if (coord == null) return false; Point2D p = new Point2D.Double(coord.east(), coord.north()); if (line.getP1().distance(p) > len + dist) return false; if (line.getP2().distance(p) > len + dist) return false; return line.ptSegDist(p) < dist; }
protected Map<Node, Way> getWayEndNodesNearOtherHighway() { Map<Node, Way> map = new HashMap<>(); for (int iter = 0; iter < 1; iter++) { for (MyWaySegment s : ways) { if (isCanceled()) { map.clear(); return map; } for (Node en : s.nearbyNodes(mindist)) { if (en == null || !s.highway || !endnodesHighway.contains(en)) { continue; } if (en.hasTag("highway", "turning_circle", "bus_stop") || en.hasTag("amenity", "parking_entrance") || en.hasTag("railway", "buffer_stop") || en.isKeyTrue("noexit") || en.hasKey("entrance") || en.hasKey("barrier")) { continue; } // to handle intersections of 't' shapes and similar if (en.isConnectedTo(s.w.getNodes(), 3 /* hops */, null)) { continue; } map.put(en, s.w); } } } return map; }
/** * Check if one or more nodes are outside of download area * * @param nodes Nodes to check * @return true if action can be done */ private boolean actionAllowed(Collection<Node> nodes) { boolean outside = false; for (Node n : nodes) if (n.isOutsideDownloadArea()) { outside = true; break; } if (outside) new Notification( tr("One or more nodes involved in this action is outside of the downloaded area.")) .setIcon(JOptionPane.WARNING_MESSAGE) .setDuration(Notification.TIME_SHORT) .show(); return true; }
/** * Returns area of a closed way in square meters. (approximate(?), but should be OK for small * areas) * * <p>Relies on the current projection: Works correctly, when one unit in projected coordinates * corresponds to one meter. This is true for most projections, but not for WGS84 and Mercator * (EPSG:3857). * * @param way Way to measure, should be closed (first node is the same as last node) * @return area of the closed way. */ public static double closedWayArea(Way way) { // http://local.wasp.uwa.edu.au/~pbourke/geometry/polyarea/ double area = 0; Node lastN = null; for (Node n : way.getNodes()) { if (lastN != null) { n.getEastNorth().getX(); area += (calcX(n) * calcY(lastN)) - (calcY(n) * calcX(lastN)); } lastN = n; } return Math.abs(area / 2); }
@Test public void testMultiGet800Nodes() throws OsmTransferException { MultiFetchServerObjectReader reader = new MultiFetchServerObjectReader(); ArrayList<Node> nodes = new ArrayList<>(ds.getNodes()); for (int i = 0; i < 812; i++) { reader.append(nodes.get(i)); } DataSet out = reader.parseOsm(NullProgressMonitor.INSTANCE); assertEquals(812, out.getNodes().size()); for (Node n1 : out.getNodes()) { Node n2 = (Node) ds.getPrimitiveById(n1); assertNotNull(n2); assertEquals(n2.get("name"), n2.get("name")); } assertTrue(reader.getMissingPrimitives().isEmpty()); }
private static Area getArea(List<Node> polygon) { Path2D path = new Path2D.Double(); boolean begin = true; for (Node n : polygon) { if (begin) { path.moveTo(n.getEastNorth().getX(), n.getEastNorth().getY()); begin = false; } else { path.lineTo(n.getEastNorth().getX(), n.getEastNorth().getY()); } } path.closePath(); return new Area(path); }
@Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; Segment other = (Segment) obj; if (end == null) { if (other.end != null) return false; } else if (!end.equals(other.end)) return false; if (start == null) { if (other.start != null) return false; } else if (!start.equals(other.start)) return false; if (way == null) { if (other.way != null) return false; } else if (!way.equals(other.way)) return false; return true; }
MyWaySegment(Way w, Node n1, Node n2) { this.w = w; String railway = w.get("railway"); String highway = w.get("highway"); this.isAbandoned = "abandoned".equals(railway) || w.isKeyTrue("disused"); this.highway = (highway != null || railway != null) && !isAbandoned; this.isBoundary = !this.highway && "administrative".equals(w.get("boundary")); line = new Line2D.Double( n1.getEastNorth().east(), n1.getEastNorth().north(), n2.getEastNorth().east(), n2.getEastNorth().north()); len = line.getP1().distance(line.getP2()); this.n1 = n1; this.n2 = n2; }