Пример #1
0
    /**
     * 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>();
      }
    }
Пример #2
0
  public static Route load(Relation left, Relation right, Way w) {
    left = left == null ? right : left;
    right = right == null ? left : right;

    if (left == null) {
      throw new IllegalArgumentException("At least one relation must not be null.");
    }

    final Route leftRoute = load(left);
    final Route rightRoute = load(right);

    int iLeft = 0;
    while (!w.equals(leftRoute.getSegments().get(iLeft++).getWay())) ;

    int iRight = 0;
    while (!w.equals(rightRoute.getSegments().get(iRight++).getWay())) ;

    final int min = Math.min(iLeft, iRight);

    final List<Segment> leftSegments = leftRoute.getSegments().subList(iLeft - min, iLeft);
    final List<Segment> rightSegments = rightRoute.getSegments().subList(iRight - min, iRight);

    if (!leftSegments.equals(rightSegments)) {
      throw new IllegalArgumentException("Routes are split across different ways.");
    }

    return new Route(iLeft == min ? rightSegments : leftSegments);
  }
Пример #3
0
 @Override
 protected void parseWays(List<Osmformat.Way> osmWays) {
   if (exception == null) {
     try {
       for (Osmformat.Way w : osmWays) {
         final Info info = w.getInfo();
         if (!info.hasVersion()) discourageUpload = true;
         final Way way = new Way(w.getId(), info.hasVersion() ? info.getVersion() : 1);
         setMetadata(way, info);
         Map<String, String> keys = new HashMap<>();
         for (int i = 0; i < w.getKeysCount(); i++) {
           keys.put(getStringById(w.getKeys(i)), getStringById(w.getVals(i)));
         }
         way.setKeys(keys);
         long previousId = 0; // Node ids are delta coded
         Collection<Long> nodeIds = new ArrayList<>();
         for (Long id : w.getRefsList()) {
           nodeIds.add(previousId += id);
         }
         ways.put(way.getUniqueId(), nodeIds);
         externalIdMap.put(way.getPrimitiveId(), way);
       }
     } catch (IllegalDataException e) {
       exception = e;
     }
   }
 }
Пример #4
0
 /**
  * Remove all tags from the way
  *
  * @param x The Way to remove all tags from
  */
 private void stripTags(Way x) {
   Way y = new Way(x);
   for (String key : x.keySet()) {
     y.remove(key);
   }
   cmds.add(new ChangeCommand(x, y));
 }
Пример #5
0
  @Override
  public boolean isFixable(TestError testError) {
    if (!(testError.getTester() instanceof DuplicateWay)) return false;

    // Do not automatically fix same ways with different tags
    if (testError.getCode() != DUPLICATE_WAY) return false;

    // We fix it only if there is no more than one way that is relation member.
    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 false;

    int waysWithRelations = 0;
    for (Way w : ways) {
      List<Relation> rel = OsmPrimitive.getFilteredList(w.getReferrers(), Relation.class);
      if (!rel.isEmpty()) {
        ++waysWithRelations;
      }
    }
    return (waysWithRelations <= 1);
  }
  @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());
  }
Пример #7
0
  protected Way parseWay() throws XMLStreamException {
    WayData wd = new WayData();
    readCommon(wd);
    Way w = new Way(wd.getId(), wd.getVersion());
    w.setVisible(wd.isVisible());
    w.load(wd);
    externalIdMap.put(wd.getPrimitiveId(), w);

    Collection<Long> nodeIds = new ArrayList<Long>();
    while (true) {
      int event = parser.next();
      if (event == XMLStreamConstants.START_ELEMENT) {
        if (parser.getLocalName().equals("nd")) {
          nodeIds.add(parseWayNode(w));
        } else if (parser.getLocalName().equals("tag")) {
          parseTag(w);
        } else {
          parseUnknown();
        }
      } else if (event == XMLStreamConstants.END_ELEMENT) {
        break;
      }
    }
    if (w.isDeleted() && nodeIds.size() > 0) {
      System.out.println(tr("Deleted way {0} contains nodes", w.getUniqueId()));
      nodeIds = new ArrayList<Long>();
    }
    ways.put(wd.getUniqueId(), nodeIds);
    return w;
  }
 void addWayNodes(Way w) {
   add(tr("{0} Nodes: ", w.getNodesCount()));
   for (Node n : w.getNodes()) {
     s.append(INDENT).append(INDENT);
     addNameAndId(n);
     s.append(NL);
   }
 }
Пример #9
0
  /**
   * This method removes duplicate points (if any) from the input way.
   *
   * @param ways the ways to process
   * @return {@code true} if any changes where made
   */
  private boolean removeDuplicateNodes(List<Way> ways) {
    // TODO: maybe join nodes with JoinNodesAction, rather than reconnect the ways.

    Map<Node, Node> nodeMap = new TreeMap<Node, Node>(new NodePositionComparator());
    int totalNodesRemoved = 0;

    for (Way way : ways) {
      if (way.getNodes().size() < 2) {
        continue;
      }

      int nodesRemoved = 0;
      List<Node> newNodes = new ArrayList<Node>();
      Node prevNode = null;

      for (Node node : way.getNodes()) {
        if (!nodeMap.containsKey(node)) {
          // new node
          nodeMap.put(node, node);

          // avoid duplicate nodes
          if (prevNode != node) {
            newNodes.add(node);
          } else {
            nodesRemoved++;
          }
        } else {
          // node with same coordinates already exists, substitute with existing node
          Node representator = nodeMap.get(node);

          if (representator != node) {
            nodesRemoved++;
          }

          // avoid duplicate node
          if (prevNode != representator) {
            newNodes.add(representator);
          }
        }
        prevNode = node;
      }

      if (nodesRemoved > 0) {

        if (newNodes.size()
            == 1) { // all nodes in the same coordinate - add one more node, to have closed way.
          newNodes.add(newNodes.get(0));
        }

        Way newWay = new Way(way);
        newWay.setNodes(newNodes);
        cmds.add(new ChangeCommand(way, newWay));
        totalNodesRemoved += nodesRemoved;
      }
    }

    return totalNodesRemoved > 0;
  }
Пример #10
0
 /**
  * Determines which way chunk should reuse the old id and its history. Selects the one with the
  * highest node count.
  *
  * @param wayChunks the way chunks
  * @return the way to keep
  */
 protected static Way determineWayToKeep(Iterable<Way> wayChunks) {
   Way wayToKeep = null;
   for (Way i : wayChunks) {
     if (wayToKeep == null || i.getNodesCount() > wayToKeep.getNodesCount()) {
       wayToKeep = i;
     }
   }
   return wayToKeep;
 }
Пример #11
0
  /**
   * 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;
  }
 protected static void populateTestDataSetWithWays(DataSet ds) {
   for (int i = 0; i < 20; i++) {
     Way w = new Way();
     for (int j = 0; j < 10; j++) {
       w.addNode(lookupNode(ds, i + j));
     }
     w.put("name", "way-" + i);
     ds.addPrimitive(w);
   }
 }
Пример #13
0
 /**
  * Creates new way objects for the way chunks and transfers the keys from the original way.
  *
  * @param way the original way whose keys are transferred
  * @param wayChunks the way chunks
  * @return the new way objects
  */
 protected static List<Way> createNewWaysFromChunks(Way way, Iterable<List<Node>> wayChunks) {
   final List<Way> newWays = new ArrayList<>();
   for (List<Node> wayChunk : wayChunks) {
     Way wayToAdd = new Way();
     wayToAdd.setKeys(way.getKeys());
     wayToAdd.setNodes(wayChunk);
     newWays.add(wayToAdd);
   }
   return newWays;
 }
Пример #14
0
  /**
   * 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;
    }
  }
Пример #15
0
 /**
  * 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;
 }
Пример #16
0
 @Override
 public boolean hasEqualSemanticAttributes(OsmPrimitive other) {
   if (!(other instanceof Way)) return false;
   if (!super.hasEqualSemanticAttributes(other)) return false;
   Way w = (Way) other;
   if (getNodesCount() != w.getNodesCount()) return false;
   for (int i = 0; i < getNodesCount(); i++) {
     if (!getNode(i).hasEqualSemanticAttributes(w.getNode(i))) return false;
   }
   return true;
 }
Пример #17
0
 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);
     }
   }
 }
Пример #18
0
 @Override
 public void cloneFrom(OsmPrimitive osm) {
   boolean locked = writeLock();
   try {
     super.cloneFrom(osm);
     Way otherWay = (Way) osm;
     setNodes(otherWay.getNodes());
   } finally {
     writeUnlock(locked);
   }
 }
Пример #19
0
  protected void populate() {
    Way w1 = new Way(1);
    w1.addNode(new Node(10));
    w1.addNode(new Node(11));

    Way w2 = new Way(1);
    w2.addNode(new Node(10));
    w2.addNode(new Node(11));

    dialog.getConflictResolver().populate(new Conflict<OsmPrimitive>(w1, w2));
  }
Пример #20
0
  /**
   * Return a list of all objects in the selection, respecting the different modifier.
   *
   * @param alt Whether the alt key was pressed, which means select all objects that are touched,
   *     instead those which are completely covered.
   * @return The collection of selected objects.
   */
  public Collection<OsmPrimitive> getSelectedObjects(boolean alt) {

    Collection<OsmPrimitive> selection = new LinkedList<>();

    // whether user only clicked, not dragged.
    boolean clicked = false;
    Rectangle bounding = lasso.getBounds();
    if (bounding.height <= 2 && bounding.width <= 2) {
      clicked = true;
    }

    if (clicked) {
      Point center = new Point(lasso.xpoints[0], lasso.ypoints[0]);
      OsmPrimitive osm = nc.getNearestNodeOrWay(center, OsmPrimitive.isSelectablePredicate, false);
      if (osm != null) {
        selection.add(osm);
      }
    } else {
      // nodes
      for (Node n : nc.getCurrentDataSet().getNodes()) {
        if (n.isSelectable() && lasso.contains(nc.getPoint2D(n))) {
          selection.add(n);
        }
      }

      // ways
      for (Way w : nc.getCurrentDataSet().getWays()) {
        if (!w.isSelectable() || w.getNodesCount() == 0) {
          continue;
        }
        if (alt) {
          for (Node n : w.getNodes()) {
            if (!n.isIncomplete() && lasso.contains(nc.getPoint2D(n))) {
              selection.add(w);
              break;
            }
          }
        } else {
          boolean allIn = true;
          for (Node n : w.getNodes()) {
            if (!n.isIncomplete() && !lasso.contains(nc.getPoint(n))) {
              allIn = false;
              break;
            }
          }
          if (allIn) {
            selection.add(w);
          }
        }
      }
    }
    return selection;
  }
Пример #21
0
    Segment(Node start, Way way, Node end) {
      this.start = start;
      this.way = way;
      this.end = end;

      final List<Node> ns = way.getNodes();
      if (way.lastNode().equals(start)) {
        Collections.reverse(ns);
      }

      this.nodes = Collections.unmodifiableList(ns);
    }
Пример #22
0
 @Override
 public void visit(Way w) {
   if (e.child == null && left.matches(new Environment(w))) {
     if (e.osm instanceof Way
             && Geometry.PolygonIntersection.FIRST_INSIDE_SECOND.equals(
                 Geometry.polygonIntersection(w.getNodes(), ((Way) e.osm).getNodes()))
         || e.osm instanceof Relation
             && ((Relation) e.osm).isMultipolygon()
             && Geometry.isPolygonInsideMultiPolygon(w.getNodes(), (Relation) e.osm, null)) {
       e.child = w;
     }
   }
 }
  @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;
      }
    }
  }
Пример #24
0
  @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;
  }
Пример #25
0
 @Override
 public void mouseMoved(MouseEvent e) {
   Way nearestWay = Main.map.mapView.getNearestWay(e.getPoint(), OsmPrimitive.isUsablePredicate);
   if (nearestWay != highlightedWay) {
     if (highlightedWay != null) {
       highlightedWay.setHighlighted(false);
     }
     if (nearestWay != null) {
       nearestWay.setHighlighted(true);
     }
     highlightedWay = nearestWay;
     Main.map.mapView.repaint();
   }
 }
Пример #26
0
  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;
  }
Пример #27
0
 /**
  * Search by closed status.
  *
  * @throws ParseError if an error has been encountered while compiling
  */
 @Test
 public void testClosed() throws ParseError {
   SearchContext sc = new SearchContext("closed");
   // Closed
   sc.w1.addNode(sc.n1);
   for (Way w : new Way[] {sc.w1}) {
     assertTrue(w.toString(), w.isClosed());
     sc.match(w, true);
   }
   // Unclosed
   for (OsmPrimitive p : new OsmPrimitive[] {sc.n1, sc.n2, sc.w2, sc.r1, sc.r2}) {
     sc.match(p, false);
   }
 }
Пример #28
0
 @Override
 public ControllerState onMouseUp(MouseUpEvent evt, OsmPrimitive osm) {
   //        if (evt.isShiftKeyDown()) { FIXME
   //
   //        } else
   if (osm instanceof Node && osm.getReferrers().contains(parentWay)) {
     // select node within way
     boolean isFirst = parentWay.firstNode().equals(node);
     boolean isLast = parentWay.lastNode().equals(node);
     if (isFirst == isLast) return new SelectedWayNode(parentWay, node);
     else return new DrawWay(parentWay, isLast);
   }
   ControllerState cs = sharedOnMouseUp(evt, osm);
   return cs != null ? cs : this;
 }
Пример #29
0
  public static Route create(List<Way> ws, Node end) {
    final List<Segment> segments = new ArrayList<Segment>(ws.size());

    for (Way w : ws) {
      if (!w.isFirstLastNode(end)) {
        throw new IllegalArgumentException("Ways must be ordered.");
      }

      final Node start = Utils.getOppositeEnd(w, end);
      segments.add(0, new Segment(start, w, end));
      end = start;
    }

    return new Route(segments);
  }
Пример #30
0
 @Override
 public void visit(Way w) {
   if (!w.isUsable()) return;
   List<Node> wNodes = w.getNodes();
   List<LatLon> wLat = new ArrayList<LatLon>(wNodes.size());
   for (int i = 0; i < wNodes.size(); i++) {
     wLat.add(wNodes.get(i).getCoor());
   }
   Map<String, String> wkeys = w.getKeys();
   removeUninterestingKeys(wkeys);
   WayPair wKey = new WayPair(wLat, wkeys);
   ways.put(wKey, w);
   WayPairNoTags wKeyN = new WayPairNoTags(wLat);
   waysNoTags.put(wKeyN, w);
 }