/** * Check if a Way is correct. * * @param way The way. * @return <code>true</code> is valid. <code>false</code> is not valid. */ public boolean isvalidWay(Way way) { // if (!way.isTagged()) <---not needed me thinks // return false; String highway = way.get("highway"); return (highway != null && !excludedHighwayValues.contains(highway)) || way.get("junction") != null || way.get("service") != null; }
public static GpxData toGpxData(DataSet data, File file) { GpxData gpxData = new GpxData(); gpxData.storageFile = file; HashSet<Node> doneNodes = new HashSet<Node>(); for (Way w : data.ways) { if (w.incomplete || w.deleted) continue; ImmutableGpxTrack trk = new ImmutableGpxTrack( new LinkedList<Collection<WayPoint>>(), new HashMap<String, Object>()); gpxData.tracks.add(trk); if (w.get("name") != null) trk.attr.put("name", w.get("name")); ArrayList<WayPoint> trkseg = null; for (Node n : w.nodes) { if (n.incomplete || n.deleted) { trkseg = null; continue; } if (trkseg == null) { trkseg = new ArrayList<WayPoint>(); trk.trackSegs.add(trkseg); } if (!n.isTagged()) { doneNodes.add(n); } WayPoint wpt = new WayPoint(n.getCoor()); if (!n.isTimestampEmpty()) { wpt.attr.put("time", DateUtils.fromDate(n.getTimestamp())); wpt.setTime(); } trkseg.add(wpt); } } // what is this loop meant to do? it creates waypoints but never // records them? for (Node n : data.nodes) { if (n.incomplete || n.deleted || doneNodes.contains(n)) continue; WayPoint wpt = new WayPoint(n.getCoor()); if (!n.isTimestampEmpty()) { wpt.attr.put("time", DateUtils.fromDate(n.getTimestamp())); wpt.setTime(); } if (n.keys != null && n.keys.containsKey("name")) { wpt.attr.put("name", n.keys.get("name")); } } return gpxData; }
@Test public void testMultiGet10Ways() throws OsmTransferException { MultiFetchServerObjectReader reader = new MultiFetchServerObjectReader(); ArrayList<Way> ways = new ArrayList<>(ds.getWays()); for (int i = 0; i < 10; i++) { reader.append(ways.get(i)); } DataSet out = reader.parseOsm(NullProgressMonitor.INSTANCE); assertEquals(10, out.getWays().size()); for (Way w1 : out.getWays()) { Way w2 = (Way) ds.getPrimitiveById(w1); assertNotNull(w2); assertEquals(w2.getNodesCount(), w1.getNodesCount()); assertEquals(w2.get("name"), w1.get("name")); } assertTrue(reader.getMissingPrimitives().isEmpty()); }
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; }
/** * their way has a higher version and different nodes. My way is modified. * * <p>=> merge onto my way not possible, create a conflict */ @Test public void waySimple_DifferentNodesAndMyIsModified() { // -- the target dataset Node n1 = new Node(new LatLon(0, 0)); n1.setOsmId(1, 1); my.addPrimitive(n1); Node n2 = new Node(new LatLon(1, 1)); n2.setOsmId(2, 1); my.addPrimitive(n2); Way myWay = new Way(); myWay.setOsmId(3, 1); myWay.addNode(n1); myWay.addNode(n2); myWay.setModified(true); myWay.put("key1", "value1"); my.addPrimitive(myWay); // -- the source dataset Node n3 = new Node(new LatLon(0, 0)); n3.setOsmId(1, 1); their.addPrimitive(n3); Node n5 = new Node(new LatLon(1, 1)); n5.setOsmId(4, 1); their.addPrimitive(n5); Node n4 = new Node(new LatLon(2, 2)); n4.setOsmId(2, 1); n4.put("key1", "value1"); their.addPrimitive(n4); Way theirWay = new Way(); theirWay.setOsmId(3, 2); theirWay.addNode(n3); theirWay.addNode(n5); // insert a node theirWay.addNode(n4); // this one is updated their.addPrimitive(theirWay); DataSetMerger visitor = new DataSetMerger(my, their); visitor.merge(); Way merged = (Way) my.getPrimitiveById(3, OsmPrimitiveType.WAY); assertEquals(1, visitor.getConflicts().size()); assertEquals(3, merged.getId()); assertEquals(1, merged.getVersion()); assertEquals(2, merged.getNodesCount()); assertEquals(1, merged.getNode(0).getId()); assertEquals(2, merged.getNode(1).getId()); assertEquals("value1", merged.get("key1")); }
private static int getCount(Way w) { final String countStr = w.get("lanes"); if (countStr != null) { return Integer.parseInt(countStr); } // TODO default lane counts based on "highway" tag return 2; }
/** * Returns the weight for the given segment depending on the highway type and the length of the * segment. The higher the value, the less it is used in routing. * * @param way the way. * @return */ private double getWeight(Way way, double length) { // Default speed if no setting is found double speed = 1; switch (routeType) { case SHORTEST: // Same speed for all types of ways if (this.waySpeeds.containsKey("residential")) speed = this.waySpeeds.get("residential"); break; case FASTEST: // Each type of way may have a different speed if (this.waySpeeds.containsKey(way.get("highway"))) speed = this.waySpeeds.get(way.get("highway")); logger.debug("Speed=" + speed); break; default: break; } // Return the time spent to traverse the way return length / speed; }
@Override public void visit(Way w) { if (!w.isUsable() || !w.isClosed()) return; String natural = w.get("natural"); if (natural == null) return; else if ("coastline".equals(natural) && Geometry.isClockwise(w)) { reportError(w, tr("Reversed coastline: land not on left side"), WRONGLY_ORDERED_COAST); } else if ("land".equals(natural) && Geometry.isClockwise(w)) { reportError(w, tr("Reversed land: land not on left side"), WRONGLY_ORDERED_LAND); } else return; }
@Override public void visit(Way w) { assert aNode != null; if (w.hasKey(tag)) { double dist = OsmUtils.getMinimumDistanceToWay(aNode.getCoor(), w); if (dist < minDist && dist < maxDist) { minDist = dist; currentValue = w.get(tag); srcNode = w; } } }
@Override public void visit(Way w) { if (!w.isUsable()) return; Map<String, String> tags = w.getKeys(); if (!tags.isEmpty()) { String highway = tags.get("highway"); if (highway != null && NAMED_WAYS.contains(highway)) { if (!tags.containsKey("name") && !tags.containsKey("ref")) { boolean isRoundabout = false; boolean hasName = false; for (String key : w.keySet()) { hasName = key.startsWith("name:") || key.endsWith("_name") || key.endsWith("_ref"); if (hasName) { break; } if (key.equals("junction")) { isRoundabout = w.get("junction").equals("roundabout"); break; } } if (!hasName && !isRoundabout) { errors.add(new TestError(this, Severity.WARNING, tr("Unnamed ways"), UNNAMED_WAY, w)); } else if (isRoundabout) { errors.add( new TestError(this, Severity.WARNING, tr("Unnamed junction"), UNNAMED_JUNCTION, w)); } } } } if (!w.isTagged() && !multipolygonways.contains(w)) { if (w.hasKeys()) { errors.add( new TestError( this, Severity.WARNING, tr("Untagged ways (commented)"), COMMENTED_WAY, w)); } else { errors.add(new TestError(this, Severity.WARNING, tr("Untagged ways"), UNTAGGED_WAY, w)); } } if (w.getNodesCount() == 0) { errors.add(new TestError(this, Severity.ERROR, tr("Empty ways"), EMPTY_WAY, w)); } else if (w.getNodesCount() == 1) { errors.add(new TestError(this, Severity.ERROR, tr("One node ways"), ONE_NODE_WAY, w)); } }
/** * Extracts the address information from the given primitive into a newly created {@link Node}. * The new node is added into the JOSM database. * * <p>If the extraction in not applicable, nothing happens. * * @param primitive the {@link Way} from which the address will be extracted */ @Override public void apply(OsmPrimitive primitive) { if (!isApplicable(primitive)) return; Way way = (Way) primitive; BoundingXYVisitor visitor = new BoundingXYVisitor(); way.accept(visitor); Node addrNode = new Node(visitor.getBounds().getCenter()); for (String key : way.keySet()) if (key.startsWith("addr")) addrNode.put(key, way.get(key)); for (String key : addrNode.keySet()) way.remove(key); Main.main.getCurrentDataSet().addPrimitive(addrNode); }
/** * Create OSM graph for routing * * @return */ public void createGraph() { logger.debug("Creating Graph..."); graph = new DirectedWeightedMultigraph<>(OsmEdge.class); rgDelegator = new RoutingGraphDelegator(graph); rgDelegator.setRouteType(this.routeType); // iterate all ways and segments for all nodes: for (Way way : data.getWays()) { // skip way if not suitable for routing. if (way == null || way.isDeleted() || !this.isvalidWay(way) || way.getNodes().size() < 1) continue; // INIT Node from = null; Node to = null; List<Node> nodes = way.getNodes(); int nodes_count = nodes.size(); /* * Assume node is A B C D E. The procedure should be * * case 1 - bidirectional ways: * 1) Add vertex A B C D E * 2) Link A<->B, B<->C, C<->D, D<->E as Edges * * case 2 - oneway reverse: * 1) Add vertex A B C D E * 2) Link B->A,C->B,D->C,E->D as Edges. result: A<-B<-C<-D<-E * * case 3 - oneway normal: * 1) Add vertex A B C D E * 2) Link A->B, B->C, C->D, D->E as Edges. result: A->B->C->D->E * * */ String oneway_val = way.get("oneway"); /* get (oneway=?) tag for this way. */ String junction_val = way.get("junction"); /* get (junction=?) tag for this way. */ from = nodes.get(0); /* 1st node A */ graph.addVertex(from); /* add vertex A */ for (int i = 1; i < nodes_count; i++) { /* loop from B until E */ to = nodes.get(i); /* 2nd node B */ if (to != null && !to.isDeleted()) { graph.addVertex(to); /* add vertex B */ // this is where we link the vertices if (!routingProfile.isOnewayUsed()) { // "Ignore oneways" is selected addEdgeBidirectional(way, from, to); } else if (oneway_val == null && junction_val == "roundabout") { // Case (roundabout): oneway=implicit yes addEdgeNormalOneway(way, from, to); } else if (oneway_val == null || oneway_val == "false" || oneway_val == "no" || oneway_val == "0") { // Case (bi-way): oneway=false OR oneway=unset OR oneway=0 OR oneway=no addEdgeBidirectional(way, from, to); } else if (oneway_val == "-1") { // Case (oneway reverse): oneway=-1 addEdgeReverseOneway(way, from, to); } else if (oneway_val == "1" || oneway_val == "yes" || oneway_val == "true") { // Case (oneway normal): oneway=yes OR 1 OR true addEdgeNormalOneway(way, from, to); } from = to; /* we did A<->B, next loop we will do B<->C, so from=B,to=C for next loop. */ } } // end of looping thru nodes } // end of looping thru ways logger.debug("End Create Graph"); logger.debug("Vertex: " + graph.vertexSet().size()); logger.debug("Edges: " + graph.edgeSet().size()); }
protected static Way lookupWay(DataSet ds, int i) { for (Way w : ds.getWays()) { if (("way-" + i).equals(w.get("name"))) return w; } return null; }
/** * their way has a higher version and different tags. the nodes are the same. My way is not * modified. Merge is possible. No conflict. * * <p>=> merge it onto my way. */ @Test public void waySimple_IdenicalNodesDifferentTags() { // -- the target dataset Node n1 = new Node(); n1.setCoor(new LatLon(0, 0)); n1.setOsmId(1, 1); my.addPrimitive(n1); Node n2 = new Node(); n2.setCoor(new LatLon(0, 0)); n2.setOsmId(2, 1); my.addPrimitive(n2); Way myWay = new Way(); myWay.setOsmId(3, 1); myWay.put("key1", "value1"); myWay.addNode(n1); myWay.addNode(n2); my.addPrimitive(myWay); // -- the source data set Node n3 = new Node(new LatLon(0, 0)); n3.setOsmId(1, 1); their.addPrimitive(n3); Node n4 = new Node(new LatLon(1, 1)); n4.setOsmId(2, 1); their.addPrimitive(n4); Way theirWay = new Way(); theirWay.setOsmId(3, 2); theirWay.put("key1", "value1"); theirWay.put("key2", "value2"); theirWay.addNode(n3); theirWay.addNode(n4); their.addPrimitive(theirWay); DataSetMerger visitor = new DataSetMerger(my, their); visitor.merge(); // -- tests Way merged = (Way) my.getPrimitiveById(3, OsmPrimitiveType.WAY); assertEquals(0, visitor.getConflicts().size()); assertEquals("value1", merged.get("key1")); assertEquals("value2", merged.get("key2")); assertEquals(3, merged.getId()); assertEquals(2, merged.getVersion()); assertEquals(2, merged.getNodesCount()); assertEquals(1, merged.getNode(0).getId()); assertEquals(2, merged.getNode(1).getId()); assertSame(merged, myWay); assertSame(merged.getDataSet(), my); Node mergedNode = (Node) my.getPrimitiveById(1, OsmPrimitiveType.NODE); assertSame(mergedNode, n1); mergedNode = (Node) my.getPrimitiveById(2, OsmPrimitiveType.NODE); assertSame(mergedNode, n2); assertFalse(merged.isModified()); }
/** * Formats a name for a way * * @param way the way * @return the name */ @Override public String format(Way way) { StringBuilder name = new StringBuilder(); if (way.isIncomplete()) { name.append(tr("incomplete")); } else { TaggingPreset preset = TaggingPresetNameTemplateList.getInstance().findPresetTemplate(way); if (preset == null) { String n; if (Main.pref.getBoolean("osm-primitives.localize-name", true)) { n = way.getLocalName(); } else { n = way.getName(); } if (n == null) { n = way.get("ref"); } if (n == null) { n = (way.get("highway") != null) ? tr("highway") : (way.get("railway") != null) ? tr("railway") : (way.get("waterway") != null) ? tr("waterway") : (way.get("landuse") != null) ? tr("landuse") : null; } if (n == null) { String s; if ((s = way.get("addr:housename")) != null) { /* I18n: name of house as parameter */ n = tr("House {0}", s); } if (n == null && (s = way.get("addr:housenumber")) != null) { String t = way.get("addr:street"); if (t != null) { /* I18n: house number, street as parameter, number should remain before street for better visibility */ n = tr("House number {0} at {1}", s, t); } else { /* I18n: house number as parameter */ n = tr("House number {0}", s); } } } if (n == null && way.get("building") != null) n = tr("building"); if (n == null || n.length() == 0) { n = String.valueOf(way.getId()); } name.append(n); } else { preset.nameTemplate.appendText(name, way); } int nodesNo = way.getRealNodesCount(); /* note: length == 0 should no longer happen, but leave the bracket code nevertheless, who knows what future brings */ /* I18n: count of nodes as parameter */ String nodes = trn("{0} node", "{0} nodes", nodesNo, nodesNo); name.append(" (").append(nodes).append(")"); } decorateNameWithId(name, way); String result = name.toString(); for (NameFormatterHook hook : formatHooks) { String hookResult = hook.checkFormat(way, result); if (hookResult != null) return hookResult; } return result; }