private void visitAllStartSegments(
      final RoutingContext ctx,
      RouteSegment start,
      PriorityQueue<RouteSegment> graphDirectSegments,
      TLongObjectHashMap<RouteSegment> visitedSegments,
      int startX,
      int startY)
      throws IOException {
    // mark as visited code seems to be duplicated
    long nt = (start.road.getId() << 8l) + start.segmentStart;
    visitedSegments.put(nt, start);
    graphDirectSegments.add(start);

    loadRoutes(
        ctx,
        (startX >> (31 - ctx.getZoomToLoadTileWithRoads())),
        (startY >> (31 - ctx.getZoomToLoadTileWithRoads())));
    long ls = (((long) startX) << 31) + (long) startY;
    RouteSegment startNbs = ctx.routes.get(ls);
    while (startNbs != null) { // startNbs.road.id >> 1, start.road.id >> 1
      if (startNbs.road.getId() != start.road.getId()) {
        startNbs.parentRoute = start;
        startNbs.parentSegmentEnd = start.segmentStart;
        startNbs.distanceToEnd = start.distanceToEnd;

        // duplicated to be sure start is added
        nt = (startNbs.road.getId() << 8l) + startNbs.segmentStart;
        visitedSegments.put(nt, startNbs);
        graphDirectSegments.add(startNbs);
      }
      startNbs = startNbs.next;
    }
  }
 private void loadAllObjects(
     final List<RouteDataObject> toFillIn,
     RoutingContext ctx,
     TLongObjectHashMap<RouteDataObject> excludeDuplications) {
   if (routes != null) {
     Iterator<RouteSegment> it = routes.valueCollection().iterator();
     while (it.hasNext()) {
       RouteSegment rs = it.next();
       while (rs != null) {
         RouteDataObject ro = rs.road;
         if (!excludeDuplications.contains(ro.id)) {
           excludeDuplications.put(ro.id, ro);
           toFillIn.add(ro);
         }
         rs = rs.next;
       }
     }
   } else if (searchResult != null) {
     RouteDataObject[] objects = searchResult.objects;
     if (objects != null) {
       for (RouteDataObject ro : objects) {
         if (ro != null && !excludeDuplications.contains(ro.id)) {
           excludeDuplications.put(ro.id, ro);
           toFillIn.add(ro);
         }
       }
     }
   }
 }
    private RouteSegment loadRouteSegment(
        int x31,
        int y31,
        RoutingContext ctx,
        TLongObjectHashMap<RouteDataObject> excludeDuplications,
        RouteSegment original) {
      if (searchResult == null && routes == null) {
        return original;
      }
      access++;
      if (searchResult == null) {
        long l = (((long) x31) << 31) + (long) y31;
        RouteSegment segment = routes.get(l);
        while (segment != null) {
          RouteDataObject ro = segment.road;
          RouteDataObject toCmp =
              excludeDuplications.get(calcRouteId(ro, segment.getSegmentStart()));
          if (toCmp == null || toCmp.getPointsLength() < ro.getPointsLength()) {
            excludeDuplications.put(calcRouteId(ro, segment.getSegmentStart()), ro);
            RouteSegment s = new RouteSegment(ro, segment.getSegmentStart());
            s.next = original;
            original = s;
          }
          segment = segment.next;
        }
        return original;
      }
      // Native use case
      long nanoTime = System.nanoTime();
      RouteDataObject[] res = ctx.nativeLib.getDataObjects(searchResult, x31, y31);
      ctx.timeToLoad += (System.nanoTime() - nanoTime);
      if (res != null) {
        for (RouteDataObject ro : res) {

          boolean accept = ro != null;
          if (ctx != null) {
            accept = ctx.getRouter().acceptLine(ro);
          }
          if (accept) {
            for (int i = 0; i < ro.pointsX.length; i++) {
              if (ro.getPoint31XTile(i) == x31 && ro.getPoint31YTile(i) == y31) {
                RouteDataObject toCmp = excludeDuplications.get(calcRouteId(ro, i));
                if (toCmp == null || toCmp.getPointsLength() < ro.getPointsLength()) {
                  RouteSegment segment = new RouteSegment(ro, i);
                  segment.next = original;
                  original = segment;
                  excludeDuplications.put(calcRouteId(ro, i), ro);
                }
              }
            }
          }
        }
      }
      return original;
    }
  @Override
  public void addWordVector(String word, Vector vector) {
    long l = md5Encode(word);

    if (vectors.containsKey(l)) {
      logger.error(
          "Warning: collision while reading matrix. The word "
              + word
              + " collides with "
              + String.valueOf(words.get(l)));
    }

    vectors.put(l, vector);
    words.put(l, word.toCharArray());
  }
 public RouteSegment loadRouteSegment(int x31, int y31, int memoryLimit) {
   long tileId = getRoutingTile(x31, y31, memoryLimit, OPTION_SMART_LOAD);
   TLongObjectHashMap<RouteDataObject> excludeDuplications =
       new TLongObjectHashMap<RouteDataObject>();
   RouteSegment original = null;
   if (tileRoutes.containsKey(tileId)) {
     List<RouteDataObject> routes = tileRoutes.get(tileId);
     if (routes != null) {
       for (RouteDataObject ro : routes) {
         for (int i = 0; i < ro.pointsX.length; i++) {
           if (ro.getPoint31XTile(i) == x31 && ro.getPoint31YTile(i) == y31) {
             excludeDuplications.put(calcRouteId(ro, i), ro);
             RouteSegment segment = new RouteSegment(ro, i);
             segment.next = original;
             original = segment;
           }
         }
       }
     }
   }
   List<RoutingSubregionTile> subregions = indexedSubregions.get(tileId);
   if (subregions != null) {
     for (RoutingSubregionTile rs : subregions) {
       original = rs.loadRouteSegment(x31, y31, this, excludeDuplications, original);
     }
   }
   return original;
 }
 private void getAllObjects(long tileId, final List<RouteDataObject> toFillIn) {
   TLongObjectHashMap<RouteDataObject> excludeDuplications =
       new TLongObjectHashMap<RouteDataObject>();
   if (tileRoutes.containsKey(tileId)) {
     List<RouteDataObject> routes = tileRoutes.get(tileId);
     if (routes != null) {
       for (RouteDataObject ro : routes) {
         if (!excludeDuplications.contains(ro.id)) {
           excludeDuplications.put(ro.id, ro);
           toFillIn.add(ro);
         }
       }
     }
   }
   List<RoutingSubregionTile> subregions = indexedSubregions.get(tileId);
   if (subregions != null) {
     for (RoutingSubregionTile rs : subregions) {
       rs.loadAllObjects(toFillIn, this, excludeDuplications);
     }
   }
 }
  private RoutePair processRouteSegment(
      final RoutingContext ctx,
      RouteSegment end,
      boolean reverseWaySearch,
      PriorityQueue<RouteSegment> graphSegments,
      TLongObjectHashMap<RouteSegment> visitedSegments,
      int targetEndX,
      int targetEndY,
      RouteSegment segment,
      TLongObjectHashMap<RouteSegment> oppositeSegments)
      throws IOException {
    // Always start from segmentStart (!), not from segmentEnd
    // It makes difference only for the first start segment
    // Middle point will always be skipped from observation considering already visited
    final BinaryMapDataObject road = segment.road;
    final int middle = segment.segmentStart;
    int middlex = road.getPoint31XTile(middle);
    int middley = road.getPoint31YTile(middle);

    // 0. mark route segment as visited
    long nt = (road.getId() << 8l) + middle;
    // avoid empty segments to connect but mark the point as visited
    visitedSegments.put(nt, null);
    if (oppositeSegments.contains(nt) && oppositeSegments.get(nt) != null) {
      segment.segmentEnd = middle;
      RouteSegment opposite = oppositeSegments.get(nt);
      opposite.segmentEnd = middle;
      return new RoutePair(segment, opposite);
    }

    boolean oneway = ctx.getRouter().isOneWay(road);
    boolean minusAllowed = !oneway || reverseWaySearch;
    boolean plusAllowed = !oneway || !reverseWaySearch;

    // +/- diff from middle point
    int d = plusAllowed ? 1 : -1;
    // Go through all point of the way and find ways to continue
    // ! Actually there is small bug when there is restriction to move forward on way (it doesn't
    // take into account)
    while (minusAllowed || plusAllowed) {
      // 1. calculate point not equal to middle
      // (algorithm should visit all point on way if it is not oneway)
      int segmentEnd = middle + d;
      if (!minusAllowed && d > 0) {
        d++;
      } else if (!plusAllowed && d < 0) {
        d--;
      } else {
        if (d <= 0) {
          d = -d + 1;
        } else {
          d = -d;
        }
      }
      if (segmentEnd < 0) {
        minusAllowed = false;
        continue;
      }
      if (segmentEnd >= road.getPointsLength()) {
        plusAllowed = false;
        continue;
      }

      // if we found end point break cycle
      long nts = (road.getId() << 8l) + segmentEnd;
      if (oppositeSegments.contains(nts) && oppositeSegments.get(nt) != null) {
        segment.segmentEnd = segmentEnd;
        RouteSegment opposite = oppositeSegments.get(nts);
        opposite.segmentEnd = segmentEnd;
        return new RoutePair(segment, opposite);
      }
      visitedSegments.put(nts, segment);

      // 2. calculate point and try to load neighbor ways if they are not loaded
      int x = road.getPoint31XTile(segmentEnd);
      int y = road.getPoint31YTile(segmentEnd);
      loadRoutes(
          ctx,
          (x >> (31 - ctx.getZoomToLoadTileWithRoads())),
          (y >> (31 - ctx.getZoomToLoadTileWithRoads())));
      long l = (((long) x) << 31) + (long) y;
      RouteSegment next = ctx.routes.get(l);

      // 3. get intersected ways
      if (next != null) {
        double distOnRoadToPass = squareRootDist(x, y, middlex, middley);
        double distToFinalPoint = squareRootDist(x, y, targetEndX, targetEndY);
        RouteSegment foundIntersection =
            processIntersectionsWithWays(
                ctx,
                graphSegments,
                visitedSegments,
                oppositeSegments,
                distOnRoadToPass,
                distToFinalPoint,
                segment,
                road,
                d == 0,
                segmentEnd,
                next,
                reverseWaySearch);
        if (foundIntersection != null) {
          segment.segmentEnd = segmentEnd;
          return new RoutePair(segment, foundIntersection);
        }
      }
    }
    return null;
  }
 private void readRouteTreeData(
     RouteSubregion routeTree,
     TLongArrayList idTables,
     TLongObjectHashMap<TLongArrayList> restrictions)
     throws IOException {
   routeTree.dataObjects = new ArrayList<RouteDataObject>();
   idTables.clear();
   restrictions.clear();
   List<String> stringTable = null;
   while (true) {
     int t = codedIS.readTag();
     int tag = WireFormat.getTagFieldNumber(t);
     switch (tag) {
       case 0:
         TLongObjectIterator<TLongArrayList> it = restrictions.iterator();
         while (it.hasNext()) {
           it.advance();
           int from = (int) it.key();
           RouteDataObject fromr = routeTree.dataObjects.get(from);
           fromr.restrictions = new long[it.value().size()];
           for (int k = 0; k < fromr.restrictions.length; k++) {
             int to = (int) (it.value().get(k) >> RouteDataObject.RESTRICTION_SHIFT);
             long valto =
                 (idTables.get(to) << RouteDataObject.RESTRICTION_SHIFT)
                     | ((long) it.value().get(k) & RouteDataObject.RESTRICTION_MASK);
             fromr.restrictions[k] = valto;
           }
         }
         for (RouteDataObject o : routeTree.dataObjects) {
           if (o != null) {
             if (o.id < idTables.size()) {
               o.id = idTables.get((int) o.id);
             }
             if (o.names != null && stringTable != null) {
               int[] keys = o.names.keys();
               for (int j = 0; j < keys.length; j++) {
                 o.names.put(keys[j], stringTable.get(o.names.get(keys[j]).charAt(0)));
               }
             }
           }
         }
         return;
       case RouteDataBlock.DATAOBJECTS_FIELD_NUMBER:
         int length = codedIS.readRawVarint32();
         int oldLimit = codedIS.pushLimit(length);
         RouteDataObject obj =
             readRouteDataObject(routeTree.routeReg, routeTree.left, routeTree.top);
         while (obj.id >= routeTree.dataObjects.size()) {
           routeTree.dataObjects.add(null);
         }
         routeTree.dataObjects.set((int) obj.id, obj);
         codedIS.popLimit(oldLimit);
         break;
       case RouteDataBlock.IDTABLE_FIELD_NUMBER:
         long routeId = 0;
         length = codedIS.readRawVarint32();
         oldLimit = codedIS.pushLimit(length);
         idLoop:
         while (true) {
           int ts = codedIS.readTag();
           int tags = WireFormat.getTagFieldNumber(ts);
           switch (tags) {
             case 0:
               break idLoop;
             case IdTable.ROUTEID_FIELD_NUMBER:
               routeId += codedIS.readSInt64();
               idTables.add(routeId);
               break;
             default:
               skipUnknownField(ts);
               break;
           }
         }
         codedIS.popLimit(oldLimit);
         break;
       case RouteDataBlock.RESTRICTIONS_FIELD_NUMBER:
         length = codedIS.readRawVarint32();
         oldLimit = codedIS.pushLimit(length);
         long from = 0;
         long to = 0;
         long type = 0;
         idLoop:
         while (true) {
           int ts = codedIS.readTag();
           int tags = WireFormat.getTagFieldNumber(ts);
           switch (tags) {
             case 0:
               break idLoop;
             case RestrictionData.FROM_FIELD_NUMBER:
               from = codedIS.readInt32();
               break;
             case RestrictionData.TO_FIELD_NUMBER:
               to = codedIS.readInt32();
               break;
             case RestrictionData.TYPE_FIELD_NUMBER:
               type = codedIS.readInt32();
               break;
             default:
               skipUnknownField(ts);
               break;
           }
         }
         if (!restrictions.containsKey(from)) {
           restrictions.put(from, new TLongArrayList());
         }
         restrictions.get(from).add((to << RouteDataObject.RESTRICTION_SHIFT) + type);
         codedIS.popLimit(oldLimit);
         break;
       case RouteDataBlock.STRINGTABLE_FIELD_NUMBER:
         length = codedIS.readRawVarint32();
         oldLimit = codedIS.pushLimit(length);
         stringTable = map.readStringTable();
         //				codedIS.skipRawBytes(codedIS.getBytesUntilLimit());
         codedIS.popLimit(oldLimit);
         break;
       default:
         skipUnknownField(t);
         break;
     }
   }
 }
 public K put(int key1, int key2, K value) {
   long key = (((long) key1) << 32) | (((long) key2) & 0xFFFFFFFFL);
   return map.put(key, value);
 }