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()); }
private void remove(long id, int index, TLongObjectHashMap<TIntArrayList> map) { TIntArrayList list = map.get(id); if (list == null) return; list.remove(index); if (list.size() == 0) map.remove(id); }
private RouteSegment processIntersectionsWithWays( RoutingContext ctx, PriorityQueue<RouteSegment> graphSegments, TLongObjectHashMap<RouteSegment> visitedSegments, TLongObjectHashMap<RouteSegment> oppositeSegments, double distOnRoadToPass, double distToFinalPoint, RouteSegment segment, BinaryMapDataObject road, boolean firstOfSegment, int segmentEnd, RouteSegment inputNext, boolean reverseWay) { // This variables can be in routing context // initialize temporary lists to calculate not forbidden ways at way intersections ArrayList<RouteSegment> segmentsToVisitPrescripted = new ArrayList<RouteSegment>(5); ArrayList<RouteSegment> segmentsToVisitNotForbidden = new ArrayList<RouteSegment>(5); // collect time for obstacles double obstaclesTime = 0; boolean exclusiveRestriction = false; // 3.1 calculate time for obstacles (bumps, traffic_signals, level_crossing) if (firstOfSegment) { RouteSegment possibleObstacle = inputNext; while (possibleObstacle != null) { obstaclesTime += ctx.getRouter().defineObstacle(possibleObstacle.road, possibleObstacle.segmentStart); possibleObstacle = possibleObstacle.next; } } // 3.2 calculate possible ways to put into priority queue // for debug next.road.getId() >> 1 == 33911427 && road.getId() >> 1 == 33911442 RouteSegment next = inputNext; while (next != null) { long nts = (next.road.getId() << 8l) + next.segmentStart; boolean oppositeConnectionFound = oppositeSegments.containsKey(nts) && oppositeSegments.get(nts) != null; boolean processRoad = true; if (ctx.isUseStrategyOfIncreasingRoadPriorities()) { double roadPriority = ctx.getRouter().getRoadPriorityHeuristicToIncrease(segment.road); double nextRoadPriority = ctx.getRouter().getRoadPriorityHeuristicToIncrease(segment.road); if (nextRoadPriority < roadPriority) { processRoad = false; } } /* next.road.getId() >> 1 (3) != road.getId() >> 1 (3) - used that line for debug with osm map */ // road.id could be equal on roundabout, but we should accept them if ((!visitedSegments.contains(nts) && processRoad) || oppositeConnectionFound) { int type = -1; if (!reverseWay) { for (int i = 0; i < road.getRestrictionCount(); i++) { if (road.getRestriction(i) == next.road.getId()) { type = road.getRestrictionType(i); break; } } } else { for (int i = 0; i < next.road.getRestrictionCount(); i++) { if (next.road.getRestriction(i) == road.getId()) { type = next.road.getRestrictionType(i); break; } // Check if there is restriction only to the current road if (next.road.getRestrictionType(i) == MapRenderingTypes.RESTRICTION_ONLY_RIGHT_TURN || next.road.getRestrictionType(i) == MapRenderingTypes.RESTRICTION_ONLY_LEFT_TURN || next.road.getRestrictionType(i) == MapRenderingTypes.RESTRICTION_ONLY_STRAIGHT_ON) { // check if that restriction applies to considered junk RouteSegment foundNext = inputNext; while (foundNext != null && foundNext.getRoad().getId() != next.road.getRestriction(i)) { foundNext = foundNext.next; } if (foundNext != null) { type = REVERSE_WAY_RESTRICTION_ONLY; // special constant } } } } if (type == REVERSE_WAY_RESTRICTION_ONLY) { // next = next.next; continue; } else if (type == -1 && exclusiveRestriction) { // next = next.next; continue; } else if (type == MapRenderingTypes.RESTRICTION_NO_LEFT_TURN || type == MapRenderingTypes.RESTRICTION_NO_RIGHT_TURN || type == MapRenderingTypes.RESTRICTION_NO_STRAIGHT_ON || type == MapRenderingTypes.RESTRICTION_NO_U_TURN) { // next = next.next; continue; } else { // no restriction can go out if (oppositeConnectionFound) { RouteSegment oppSegment = oppositeSegments.get(nts); oppSegment.segmentEnd = next.segmentStart; return oppSegment; } double distanceToEnd = distToFinalPoint / ctx.getRouter().getMaxDefaultSpeed(); if (ctx.isUseDynamicRoadPrioritising()) { double priority = ctx.getRouter().getRoadPriorityToCalculateRoute(next.road); distanceToEnd /= priority; } // Using A* routing algorithm // g(x) - calculate distance to that point and calculate time double speed = ctx.getRouter().defineSpeed(road); if (speed == 0) { speed = ctx.getRouter().getMinDefaultSpeed(); } double distanceFromStart = segment.distanceFromStart + distOnRoadToPass / speed; // calculate turn time distanceFromStart += ctx.getRouter().calculateTurnTime(segment, next, segmentEnd); // add obstacles time distanceFromStart += obstaclesTime; // segment.getRoad().getId() >> 1 if (next.parentRoute == null || ctx.roadPriorityComparator( next.distanceFromStart, next.distanceToEnd, distanceFromStart, distanceToEnd) > 0) { next.distanceFromStart = distanceFromStart; next.distanceToEnd = distanceToEnd; if (next.parentRoute != null) { // already in queue remove it graphSegments.remove(next); } // put additional information to recover whole route after next.parentRoute = segment; next.parentSegmentEnd = segmentEnd; if (type == -1) { // case no restriction segmentsToVisitNotForbidden.add(next); } else { // case exclusive restriction (only_right, only_straight, ...) // 1. in case we are going backward we should not consider only_restriction // as exclusive because we have main "in" roads and one "out" // 2. in case we are going forward we have one "in" and many "out" if (!reverseWay) { exclusiveRestriction = true; segmentsToVisitNotForbidden.clear(); segmentsToVisitPrescripted.add(next); } else { segmentsToVisitNotForbidden.add(next); } } } } } next = next.next; } // add all allowed route segments to priority queue for (RouteSegment s : segmentsToVisitNotForbidden) { graphSegments.add(s); } for (RouteSegment s : segmentsToVisitPrescripted) { graphSegments.add(s); } return null; }
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; }
@Override public Vector getVector(String word) { long l = md5Encode(word); if (!vectors.contains(l)) return null; return vectors.get(l); }
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 get(int key1, int key2) { long key = (((long) key1) << 32) | (((long) key2) & 0xFFFFFFFFL); return map.get(key); }