use of net.osmand.binary.RouteDataObject in project Osmand by osmandapp.
the class BinaryRoutePlannerOld method processRouteSegment.
private boolean processRouteSegment(final RoutingContext ctx, 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 RouteDataObject road = segment.road;
final int middle = segment.getSegmentStart();
float obstaclePlusTime = 0;
float obstacleMinusTime = 0;
// This is correct way of checking but it has problem with relaxing strategy
// long ntf = (segment.road.getId() << ROUTE_POINTS) + segment.segmentStart;
// visitedSegments.put(ntf, segment);
// if (oppositeSegments.contains(ntf) && oppositeSegments.get(ntf) != null) {
// RouteSegment opposite = oppositeSegments.get(ntf);
// if (opposite.segmentStart == segment.segmentStart) {
// if (reverseWaySearch) {
// reverse : segment.parentSegmentEnd - segment.parentRoute
// } else {
// reverse : opposite.parentSegmentEnd - oppositie.parentRoute
// }
// return true;
// }
// }
// 0. mark route segment as visited
long nt = (road.getId() << ROUTE_POINTS) + middle;
// avoid empty segments to connect but mark the point as visited
visitedSegments.put(nt, null);
int oneway = ctx.getRouter().isOneWay(road);
boolean minusAllowed;
boolean plusAllowed;
if (ctx.firstRoadId == nt) {
if (ctx.firstRoadDirection < 0) {
obstaclePlusTime += 500;
} else if (ctx.firstRoadDirection > 0) {
obstacleMinusTime += 500;
}
}
if (!reverseWaySearch) {
minusAllowed = oneway <= 0;
plusAllowed = oneway >= 0;
} else {
minusAllowed = oneway >= 0;
plusAllowed = oneway <= 0;
}
// +/- diff from middle point
int d = plusAllowed ? 1 : -1;
if (segment.parentRoute != null) {
if (plusAllowed && middle < segment.getRoad().getPointsLength() - 1) {
obstaclePlusTime = (float) ctx.getRouter().calculateTurnTime(segment, segment.getRoad().getPointsLength() - 1, segment.parentRoute, segment.parentSegmentEnd);
}
if (minusAllowed && middle > 0) {
obstacleMinusTime = (float) ctx.getRouter().calculateTurnTime(segment, 0, segment.parentRoute, segment.parentSegmentEnd);
}
}
// 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)
float posSegmentDist = 0;
float negSegmentDist = 0;
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;
boolean positive = d > 0;
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() << ROUTE_POINTS) + segmentEnd;
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);
if (positive) {
posSegmentDist += squareRootDist(x, y, road.getPoint31XTile(segmentEnd - 1), road.getPoint31YTile(segmentEnd - 1));
} else {
negSegmentDist += squareRootDist(x, y, road.getPoint31XTile(segmentEnd + 1), road.getPoint31YTile(segmentEnd + 1));
}
// 2.1 calculate possible obstacle plus time
if (positive) {
double obstacle = ctx.getRouter().defineRoutingObstacle(road, segmentEnd);
if (obstacle < 0) {
plusAllowed = false;
continue;
}
obstaclePlusTime += obstacle;
} else {
double obstacle = ctx.getRouter().defineRoutingObstacle(road, segmentEnd);
if (obstacle < 0) {
minusAllowed = false;
continue;
}
obstacleMinusTime += obstacle;
}
// int overhead = 0;
// could be expensive calculation
int overhead = (ctx.visitedSegments - ctx.relaxedSegments) * STANDARD_ROAD_IN_QUEUE_OVERHEAD;
if (overhead > ctx.config.memoryLimitation * 0.95) {
throw new OutOfMemoryError("There is no enough memory " + ctx.config.memoryLimitation / (1 << 20) + " Mb");
}
RouteSegment next = ctx.loadRouteSegment(x, y, ctx.config.memoryLimitation - overhead);
// 3. get intersected ways
if (next != null) {
// TO-DO U-Turn
if ((next == segment || next.road.id == road.id) && next.next == null) {
// simplification if there is no real intersection
continue;
}
// Using A* routing algorithm
// g(x) - calculate distance to that point and calculate time
float priority = ctx.getRouter().defineSpeedPriority(road);
float speed = ctx.getRouter().defineRoutingSpeed(road) * priority;
if (speed == 0) {
speed = ctx.getRouter().getMinDefaultSpeed() * priority;
}
float distOnRoadToPass = positive ? posSegmentDist : negSegmentDist;
float distStartObstacles = segment.distanceFromStart + (positive ? obstaclePlusTime : obstacleMinusTime) + distOnRoadToPass / speed;
float distToFinalPoint = (float) squareRootDist(x, y, targetEndX, targetEndY);
boolean routeFound = processIntersections(ctx, graphSegments, visitedSegments, oppositeSegments, distStartObstacles, distToFinalPoint, segment, segmentEnd, next, reverseWaySearch);
if (routeFound) {
return routeFound;
}
}
}
return false;
}
use of net.osmand.binary.RouteDataObject in project Osmand by osmandapp.
the class PrecalculatedRouteDirection method init.
private void init(List<RouteSegmentResult> ls) {
TIntArrayList px = new TIntArrayList();
TIntArrayList py = new TIntArrayList();
List<Float> speedSegments = new ArrayList<Float>();
for (RouteSegmentResult s : ls) {
boolean plus = s.getStartPointIndex() < s.getEndPointIndex();
int i = s.getStartPointIndex();
RouteDataObject obj = s.getObject();
float routeSpd = (s.getRoutingTime() == 0 || s.getDistance() == 0) ? maxSpeed : (s.getDistance() / s.getRoutingTime());
while (true) {
i = plus ? i + 1 : i - 1;
px.add(obj.getPoint31XTile(i));
py.add(obj.getPoint31YTile(i));
speedSegments.add(routeSpd);
if (i == s.getEndPointIndex()) {
break;
}
}
}
init(px, py, speedSegments);
}
use of net.osmand.binary.RouteDataObject in project Osmand by osmandapp.
the class RoutingContext method loadSubregionTile.
public void loadSubregionTile(final RoutingSubregionTile ts, boolean loadObjectsInMemory, List<RouteDataObject> toLoad, TLongHashSet excludeNotAllowed) {
boolean wasUnloaded = ts.isUnloaded();
int ucount = ts.getUnloadCont();
if (nativeLib == null) {
long now = System.nanoTime();
try {
BinaryMapIndexReader reader = reverseMap.get(ts.subregion.routeReg);
ts.setLoadedNonNative();
List<RouteDataObject> res = reader.loadRouteIndexData(ts.subregion);
// System.out.println(ts.subregion.shiftToData + " " + res);
if (toLoad != null) {
toLoad.addAll(res);
} else {
for (RouteDataObject ro : res) {
if (ro != null) {
if (config.router.acceptLine(ro)) {
if (excludeNotAllowed != null && !excludeNotAllowed.contains(ro.getId())) {
ts.add(ro);
}
} else if (excludeNotAllowed != null && ro.getId() > 0) {
excludeNotAllowed.add(ro.getId());
if (ts.excludedIds == null) {
ts.excludedIds = new TLongHashSet();
}
ts.excludedIds.add(ro.getId());
}
}
}
}
} catch (IOException e) {
throw new RuntimeException("Loading data exception", e);
}
timeToLoad += (System.nanoTime() - now);
} else {
long now = System.nanoTime();
NativeRouteSearchResult ns = nativeLib.loadRouteRegion(ts.subregion, loadObjectsInMemory);
// System.out.println(ts.subregion.shiftToData + " " + Arrays.toString(ns.objects));
ts.setLoadedNative(ns, this);
timeToLoad += (System.nanoTime() - now);
}
loadedTiles++;
if (wasUnloaded) {
if (ucount == 1) {
loadedPrevUnloadedTiles++;
}
} else {
if (global != null) {
global.allRoutes += ts.tileStatistics.allRoutes;
global.coordinates += ts.tileStatistics.coordinates;
}
distinctLoadedTiles++;
}
global.size += ts.tileStatistics.size;
}
use of net.osmand.binary.RouteDataObject in project Osmand by osmandapp.
the class RoutingContext method getAllObjects.
private void getAllObjects(long tileId, final List<RouteDataObject> toFillIn, TLongObjectHashMap<RouteDataObject> excludeDuplications) {
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);
}
}
}
use of net.osmand.binary.RouteDataObject in project Osmand by osmandapp.
the class RoutingContext method loadTileHeaders.
public List<RoutingSubregionTile> loadTileHeaders(final int zoomToLoadM31, int tileX, int tileY) {
SearchRequest<RouteDataObject> request = BinaryMapIndexReader.buildSearchRouteRequest(tileX << zoomToLoadM31, (tileX + 1) << zoomToLoadM31, tileY << zoomToLoadM31, (tileY + 1) << zoomToLoadM31, null);
List<RoutingSubregionTile> collection = null;
for (Entry<BinaryMapIndexReader, List<RouteSubregion>> r : map.entrySet()) {
// NOTE: load headers same as we do in non-native (it is not native optimized)
try {
if (r.getValue().size() > 0) {
long now = System.nanoTime();
// int rg = r.getValue().get(0).routeReg.regionsRead;
List<RouteSubregion> subregs = r.getKey().searchRouteIndexTree(request, r.getValue());
if (subregs.size() > 0) {
checkOldRoutingFiles(r.getKey());
}
for (RouteSubregion sr : subregs) {
int ind = searchSubregionTile(sr);
RoutingSubregionTile found;
if (ind < 0) {
found = new RoutingSubregionTile(sr);
subregionTiles.add(-(ind + 1), found);
} else {
found = subregionTiles.get(ind);
}
if (collection == null) {
collection = new ArrayList<RoutingContext.RoutingSubregionTile>(4);
}
collection.add(found);
}
timeToLoadHeaders += (System.nanoTime() - now);
}
} catch (IOException e) {
throw new RuntimeException("Loading data exception", e);
}
}
return collection;
}
Aggregations