/** * 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); }
/** * 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")); }
@Test public void testBackrefrenceForNode() throws OsmTransferException { Node n = lookupNode(ds, 0); assertNotNull(n); Way w = lookupWay(ds, 0); assertNotNull(w); OsmServerBackreferenceReader reader = new OsmServerBackreferenceReader(n); reader.setReadFull(false); DataSet referers = reader.parseOsm(NullProgressMonitor.INSTANCE); assertEquals(10, referers.getNodes().size()); assertEquals(1, referers.getWays().size()); assertEquals(0, referers.getRelations().size()); for (Way way : referers.getWays()) { assertEquals(w.getId(), way.getId()); assertEquals(false, way.isIncomplete()); } }
SegmentToKeepSelectionDialog( Way selectedWay, List<Way> newWays, Way wayToKeep, List<OsmPrimitive> selection) { super( Main.parent, tr("Which way segment should reuse the history of {0}?", selectedWay.getId()), new String[] {tr("Ok"), tr("Cancel")}, true); this.selectedWay = selectedWay; this.newWays = newWays; this.selection = selection; this.list = new JList<>(newWays.toArray(new Way[newWays.size()])); buildList(); this.list.setSelectedValue(wayToKeep, true); setButtonIcons(new String[] {"ok", "cancel"}); final JPanel pane = new JPanel(new GridLayout(2, 1)); pane.add(new JLabel(getTitle())); pane.add(list); setContent(pane); }
protected void loadIncompleteNodes() throws OsmTransferException { // a way loaded with MultiFetch may have incomplete nodes because at least one of its // nodes isn't present in the local data set. We therefore fully load all ways with incomplete // nodes. for (Way w : ds.getWays()) { if (canceled) return; if (w.hasIncompleteNodes()) { synchronized (this) { if (canceled) return; objectReader = new OsmServerObjectReader(w.getId(), OsmPrimitiveType.WAY, true /* full */); } DataSet theirDataSet = objectReader.parseOsm( progressMonitor.createSubTaskMonitor(ProgressMonitor.ALL_TICKS, false)); synchronized (this) { objectReader = null; } new DataSetMerger(ds, theirDataSet).merge(); } } }
/** Fix the error by removing all but one instance of duplicate ways */ @Override public Command fixError(TestError testError) { Collection<? extends OsmPrimitive> sel = testError.getPrimitives(); HashSet<Way> ways = new HashSet<Way>(); for (OsmPrimitive osm : sel) { if (osm instanceof Way) { ways.add((Way) osm); } } if (ways.size() < 2) return null; long idToKeep = 0; Way wayToKeep = ways.iterator().next(); // Only one way will be kept - the one with lowest positive ID, if such exist // or one "at random" if no such exists. Rest of the ways will be deleted for (Way w : ways) { if (!w.isNew()) { if (idToKeep == 0 || w.getId() < idToKeep) { idToKeep = w.getId(); wayToKeep = w; } } } // Find the way that is member of one or more relations. (If any) Way wayWithRelations = null; List<Relation> relations = null; for (Way w : ways) { List<Relation> rel = OsmPrimitive.getFilteredList(w.getReferrers(), Relation.class); if (!rel.isEmpty()) { if (wayWithRelations != null) throw new AssertionError( "Cannot fix duplicate Ways: More than one way is relation member."); wayWithRelations = w; relations = rel; } } Collection<Command> commands = new LinkedList<Command>(); // Fix relations. if (wayWithRelations != null && wayToKeep != wayWithRelations) { for (Relation rel : relations) { Relation newRel = new Relation(rel); for (int i = 0; i < newRel.getMembers().size(); ++i) { RelationMember m = newRel.getMember(i); if (wayWithRelations.equals(m.getMember())) { newRel.setMember(i, new RelationMember(m.getRole(), wayToKeep)); } } commands.add(new ChangeCommand(rel, newRel)); } } // Delete all ways in the list // Note: nodes are not deleted, these can be detected and deleted at next pass ways.remove(wayToKeep); commands.add(new DeleteCommand(ways)); return new SequenceCommand(tr("Delete duplicate ways"), commands); }
@Test public void testBackrefrenceForRelation() throws OsmTransferException { Relation r = lookupRelation(ds, 1); assertNotNull(r); // way with name "relation-1" is referred to by four relations: // relation-6, relation-7, relation-8, relation-9 // OsmServerBackreferenceReader reader = new OsmServerBackreferenceReader(r); reader.setReadFull(false); DataSet referers = reader.parseOsm(NullProgressMonitor.INSTANCE); Set<Long> referringRelationsIds = new HashSet<Long>(); r = lookupRelation(referers, 6); assertNotNull(r); assertEquals(false, r.isIncomplete()); referringRelationsIds.add(r.getId()); r = lookupRelation(referers, 7); assertNotNull(r); assertEquals(false, r.isIncomplete()); referringRelationsIds.add(r.getId()); r = lookupRelation(referers, 8); assertNotNull(r); assertEquals(false, r.isIncomplete()); referringRelationsIds.add(r.getId()); r = lookupRelation(referers, 9); assertNotNull(r); assertEquals(false, r.isIncomplete()); referringRelationsIds.add(r.getId()); for (Relation r1 : referers.getRelations()) { if (!referringRelationsIds.contains(r1.getId())) { assertEquals(true, r1.isIncomplete()); } } // make sure we read all ways referred to by parent relations. These // ways are incomplete after reading. // Set<Long> expectedWayIds = new HashSet<Long>(); for (RelationMember m : lookupRelation(ds, 6).getMembers()) { if (m.isWay()) { expectedWayIds.add(m.getMember().getId()); } } for (RelationMember m : lookupRelation(ds, 7).getMembers()) { if (m.isWay()) { expectedWayIds.add(m.getMember().getId()); } } for (RelationMember m : lookupRelation(ds, 8).getMembers()) { if (m.isWay()) { expectedWayIds.add(m.getMember().getId()); } } for (RelationMember m : lookupRelation(ds, 9).getMembers()) { if (m.isWay()) { expectedWayIds.add(m.getMember().getId()); } } assertEquals(expectedWayIds.size(), referers.getWays().size()); for (Way w1 : referers.getWays()) { assertEquals(true, expectedWayIds.contains(w1.getId())); assertEquals(true, w1.isIncomplete()); } // make sure we didn't read any nodes // assertEquals(0, referers.getNodes().size()); }
/** * their way has a higher version and different tags. And it has more nodes. Two of the existing * nodes are modified. * * <p>=> merge it onto my way, no conflict */ @Test public void waySimple_AdditionalNodesAndChangedNodes() { // -- my data set 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); my.addPrimitive(myWay); // --- their data set 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, 2); 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(); // -- tests Way merged = (Way) my.getPrimitiveById(3, OsmPrimitiveType.WAY); assertEquals(0, visitor.getConflicts().size()); assertEquals(3, merged.getId()); assertEquals(2, merged.getVersion()); assertEquals(3, merged.getNodesCount()); assertEquals(1, merged.getNode(0).getId()); assertEquals(4, merged.getNode(1).getId()); assertEquals(2, merged.getNode(2).getId()); assertEquals("value1", merged.getNode(2).get("key1")); assertSame(merged.getNode(0), n1); assertNotSame(merged.getNode(1), n5); // must be clone of the original node in their assertSame(merged.getNode(2), n2); assertFalse( merged .isModified()); // the target wasn't modified before merging, it mustn't be after // merging }
/** * 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; }