/**
   * 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());
    }
  }
示例#4
0
    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();
     }
   }
 }
示例#6
0
  /** 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());
  }
示例#10
0
  /**
   * 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;
  }