public void addNode(OSMNode node) {
      if (!_nodesWithNeighbors.contains(node.getId())) return;

      if (_nodes.containsKey(node.getId())) return;

      _nodes.put(node.getId(), node);

      if (_nodes.size() % 100000 == 0) _log.debug("nodes=" + _nodes.size());
    }
 /**
  * Record the level of the way for this node, e.g. if the way is at level 5, mark that this node
  * is active at level 5.
  *
  * @param the way that has the level
  * @param the node to record for
  * @author mattwigway
  */
 private IntersectionVertex recordLevel(OSMNode node, OSMWay way) {
   HashMap<Integer, IntersectionVertex> levels;
   long nid = node.getId();
   int level = Integer.parseInt(way.getTag("otp:numeric_level"));
   if (multiLevelNodes.containsKey(nid)) {
     levels = multiLevelNodes.get(nid);
   } else {
     levels = new HashMap<Integer, IntersectionVertex>();
     multiLevelNodes.put(nid, levels);
   }
   if (!levels.containsKey(level)) {
     Coordinate coordinate = getCoordinate(node);
     String label = "osm node " + nid;
     IntersectionVertex iv =
         new IntersectionVertex(graph, label, coordinate.x, coordinate.y, label);
     levels.put(level, iv);
     return iv;
   }
   return levels.get(level);
 }
 /**
  * Make or get a shared vertex for flat intersections, or one vertex per level for multilevel
  * nodes like elevators. When there is an elevator or other Z-dimension discontinuity, a single
  * node can appear in several ways at different levels.
  *
  * @param node The node to fetch a label for.
  * @param way The way it is connected to (for fetching level information).
  * @return vertex The graph vertex.
  */
 private IntersectionVertex getVertexForOsmNode(OSMNode node, OSMWay way) {
   // If the node should be decomposed to multiple levels,
   // use the numeric level because it is unique, the human level may not be (although
   // it will likely lead to some head-scratching if it is not).
   IntersectionVertex iv = null;
   if (isMultiLevelNode(node)) {
     // make a separate node for every level
     return recordLevel(node, way);
   }
   // single-level case
   long nid = node.getId();
   iv = intersectionNodes.get(nid);
   if (iv == null) {
     Coordinate coordinate = getCoordinate(node);
     String label = "osm node " + nid;
     iv = new IntersectionVertex(graph, label, coordinate.x, coordinate.y, label);
     intersectionNodes.put(nid, iv);
     endpoints.add(iv);
     // endpoints and intersectionNodes.values are the same thing now right?
   }
   return iv;
 }