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 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; }
public void add(RouteDataObject ro) { tileStatistics.addObject(ro); for (int i = 0; i < ro.pointsX.length; i++) { int x31 = ro.getPoint31XTile(i); int y31 = ro.getPoint31YTile(i); long l = (((long) x31) << 31) + (long) y31; RouteSegment segment = new RouteSegment(ro, i); if (!routes.containsKey(l)) { routes.put(l, segment); } else { RouteSegment orig = routes.get(l); while (orig.next != null) { orig = orig.next; } orig.next = segment; } } }
public RoutingContext(RoutingContext cp) { this.config = cp.config; this.map.putAll(cp.map); this.useBaseMap = cp.useBaseMap; this.reverseMap.putAll(cp.reverseMap); this.nativeLib = cp.nativeLib; // copy local data and clear caches for (RoutingSubregionTile tl : subregionTiles) { if (tl.isLoaded()) { subregionTiles.add(tl); for (RouteSegment rs : tl.routes.valueCollection()) { RouteSegment s = rs; while (s != null) { s.parentRoute = null; s.parentSegmentEnd = 0; s.distanceFromStart = 0; s.distanceToEnd = 0; s = s.next; } } } } }
private List<RouteSegmentResult> convertFinalSegmentToResults( RoutingContext ctx, FinalRouteSegment finalSegment) { List<RouteSegmentResult> result = new ArrayList<RouteSegmentResult>(); if (finalSegment != null) { ctx.routingTime = finalSegment.distanceFromStart; println("Routing calculated time distance " + finalSegment.distanceFromStart); // Get results from opposite direction roads RouteSegment segment = finalSegment.reverseWaySearch ? finalSegment : finalSegment.opposite.getParentRoute(); int parentSegmentStart = finalSegment.reverseWaySearch ? finalSegment.opposite.getSegmentStart() : finalSegment.opposite.getParentSegmentEnd(); while (segment != null) { RouteSegmentResult res = new RouteSegmentResult(segment.road, parentSegmentStart, segment.getSegmentStart()); parentSegmentStart = segment.getParentSegmentEnd(); segment = segment.getParentRoute(); addRouteSegmentToResult(result, res, false); } // reverse it just to attach good direction roads Collections.reverse(result); segment = finalSegment.reverseWaySearch ? finalSegment.opposite.getParentRoute() : finalSegment; int parentSegmentEnd = finalSegment.reverseWaySearch ? finalSegment.opposite.getParentSegmentEnd() : finalSegment.opposite.getSegmentStart(); while (segment != null) { RouteSegmentResult res = new RouteSegmentResult(segment.road, segment.getSegmentStart(), parentSegmentEnd); parentSegmentEnd = segment.getParentSegmentEnd(); segment = segment.getParentRoute(); // happens in smart recalculation addRouteSegmentToResult(result, res, true); } Collections.reverse(result); } return result; }
private void attachRoadSegments( RoutingContext ctx, List<RouteSegmentResult> result, int routeInd, int pointInd, boolean plus) throws IOException { RouteSegmentResult rr = result.get(routeInd); RouteDataObject road = rr.getObject(); long nextL = pointInd < road.getPointsLength() - 1 ? getPoint(road, pointInd + 1) : 0; long prevL = pointInd > 0 ? getPoint(road, pointInd - 1) : 0; // attach additional roads to represent more information about the route RouteSegmentResult previousResult = null; // by default make same as this road id long previousRoadId = road.getId(); if (pointInd == rr.getStartPointIndex() && routeInd > 0) { previousResult = result.get(routeInd - 1); previousRoadId = previousResult.getObject().getId(); if (previousRoadId != road.getId()) { if (previousResult.getStartPointIndex() < previousResult.getEndPointIndex() && previousResult.getEndPointIndex() < previousResult.getObject().getPointsLength() - 1) { rr.attachRoute( pointInd, new RouteSegmentResult( previousResult.getObject(), previousResult.getEndPointIndex(), previousResult.getObject().getPointsLength() - 1)); } else if (previousResult.getStartPointIndex() > previousResult.getEndPointIndex() && previousResult.getEndPointIndex() > 0) { rr.attachRoute( pointInd, new RouteSegmentResult( previousResult.getObject(), previousResult.getEndPointIndex(), 0)); } } } Iterator<RouteSegment> it; if (rr.getPreAttachedRoutes(pointInd) != null) { final RouteSegmentResult[] list = rr.getPreAttachedRoutes(pointInd); it = new Iterator<BinaryRoutePlanner.RouteSegment>() { int i = 0; @Override public boolean hasNext() { return i < list.length; } @Override public RouteSegment next() { RouteSegmentResult r = list[i++]; return new RouteSegment(r.getObject(), r.getStartPointIndex()); } @Override public void remove() {} }; } else { RouteSegment rt = ctx.loadRouteSegment( road.getPoint31XTile(pointInd), road.getPoint31YTile(pointInd), ctx.config.memoryLimitation); it = rt.getIterator(); } // try to attach all segments except with current id while (it.hasNext()) { RouteSegment routeSegment = it.next(); if (routeSegment.road.getId() != road.getId() && routeSegment.road.getId() != previousRoadId) { RouteDataObject addRoad = routeSegment.road; checkAndInitRouteRegion(ctx, addRoad); // TODO restrictions can be considered as well int oneWay = ctx.getRouter().isOneWay(addRoad); if (oneWay >= 0 && routeSegment.getSegmentStart() < addRoad.getPointsLength() - 1) { long pointL = getPoint(addRoad, routeSegment.getSegmentStart() + 1); if (pointL != nextL && pointL != prevL) { // if way contains same segment (nodes) as different way (do not attach it) rr.attachRoute( pointInd, new RouteSegmentResult( addRoad, routeSegment.getSegmentStart(), addRoad.getPointsLength() - 1)); } } if (oneWay <= 0 && routeSegment.getSegmentStart() > 0) { long pointL = getPoint(addRoad, routeSegment.getSegmentStart() - 1); // if way contains same segment (nodes) as different way (do not attach it) if (pointL != nextL && pointL != prevL) { rr.attachRoute( pointInd, new RouteSegmentResult(addRoad, routeSegment.getSegmentStart(), 0)); } } } } }