use of com.graphhopper.storage.index.Snap in project graphhopper by graphhopper.
the class RoundTripRouting method lookup.
public static List<Snap> lookup(List<GHPoint> points, EdgeFilter edgeFilter, LocationIndex locationIndex, Params params) {
// todo: no snap preventions for round trip so far
if (points.size() != 1)
throw new IllegalArgumentException("For round trip calculation exactly one point is required");
final GHPoint start = points.get(0);
TourStrategy strategy = new MultiPointTour(new Random(params.seed), params.distanceInMeter, params.roundTripPointCount, params.initialHeading);
List<Snap> snaps = new ArrayList<>(2 + strategy.getNumberOfGeneratedPoints());
Snap startSnap = locationIndex.findClosest(start.lat, start.lon, edgeFilter);
if (!startSnap.isValid())
throw new PointNotFoundException("Cannot find point 0: " + start, 0);
snaps.add(startSnap);
GHPoint last = start;
for (int i = 0; i < strategy.getNumberOfGeneratedPoints(); i++) {
double heading = strategy.getHeadingForIteration(i);
Snap result = generateValidPoint(last, strategy.getDistanceForIteration(i), heading, edgeFilter, locationIndex, params.maxRetries);
last = result.getSnappedPoint();
snaps.add(result);
}
snaps.add(startSnap);
return snaps;
}
use of com.graphhopper.storage.index.Snap in project graphhopper by graphhopper.
the class Router method routeVia.
protected GHResponse routeVia(GHRequest request, Solver solver) {
GHResponse ghRsp = new GHResponse();
StopWatch sw = new StopWatch().start();
DirectedEdgeFilter directedEdgeFilter = solver.createDirectedEdgeFilter();
List<Snap> snaps = ViaRouting.lookup(encodingManager, request.getPoints(), solver.createSnapFilter(), locationIndex, request.getSnapPreventions(), request.getPointHints(), directedEdgeFilter, request.getHeadings());
ghRsp.addDebugInfo("idLookup:" + sw.stop().getSeconds() + "s");
// (base) query graph used to resolve headings, curbsides etc. this is not necessarily the same thing as
// the (possibly implementation specific) query graph used by PathCalculator
QueryGraph queryGraph = QueryGraph.create(ghStorage, snaps);
PathCalculator pathCalculator = solver.createPathCalculator(queryGraph);
boolean passThrough = getPassThrough(request.getHints());
boolean forceCurbsides = getForceCurbsides(request.getHints());
ViaRouting.Result result = ViaRouting.calcPaths(request.getPoints(), queryGraph, snaps, directedEdgeFilter, pathCalculator, request.getCurbsides(), forceCurbsides, request.getHeadings(), passThrough);
if (request.getPoints().size() != result.paths.size() + 1)
throw new RuntimeException("There should be exactly one more point than paths. points:" + request.getPoints().size() + ", paths:" + result.paths.size());
// here each path represents one leg of the via-route and we merge them all together into one response path
ResponsePath responsePath = concatenatePaths(request, solver.weighting, queryGraph, result.paths, getWaypoints(snaps));
responsePath.addDebugInfo(result.debug);
ghRsp.add(responsePath);
ghRsp.getHints().putObject("visited_nodes.sum", result.visitedNodes);
ghRsp.getHints().putObject("visited_nodes.average", (float) result.visitedNodes / (snaps.size() - 1));
return ghRsp;
}
use of com.graphhopper.storage.index.Snap in project graphhopper by graphhopper.
the class ViaRouting method lookup.
/**
* @throws MultiplePointsNotFoundException in case one or more points could not be resolved
*/
public static List<Snap> lookup(EncodedValueLookup lookup, List<GHPoint> points, EdgeFilter snapFilter, LocationIndex locationIndex, List<String> snapPreventions, List<String> pointHints, DirectedEdgeFilter directedSnapFilter, List<Double> headings) {
if (points.size() < 2)
throw new IllegalArgumentException("At least 2 points have to be specified, but was:" + points.size());
final EnumEncodedValue<RoadClass> roadClassEnc = lookup.getEnumEncodedValue(RoadClass.KEY, RoadClass.class);
final EnumEncodedValue<RoadEnvironment> roadEnvEnc = lookup.getEnumEncodedValue(RoadEnvironment.KEY, RoadEnvironment.class);
EdgeFilter strictEdgeFilter = snapPreventions.isEmpty() ? snapFilter : new SnapPreventionEdgeFilter(snapFilter, roadClassEnc, roadEnvEnc, snapPreventions);
List<Snap> snaps = new ArrayList<>(points.size());
IntArrayList pointsNotFound = new IntArrayList();
for (int placeIndex = 0; placeIndex < points.size(); placeIndex++) {
GHPoint point = points.get(placeIndex);
Snap snap = null;
if (placeIndex < headings.size() && !Double.isNaN(headings.get(placeIndex))) {
if (!pointHints.isEmpty() && !Helper.isEmpty(pointHints.get(placeIndex)))
throw new IllegalArgumentException("Cannot specify heading and point_hint at the same time. " + "Make sure you specify either an empty point_hint (String) or a NaN heading (double) for point " + placeIndex);
snap = locationIndex.findClosest(point.lat, point.lon, new HeadingEdgeFilter(directedSnapFilter, headings.get(placeIndex), point));
} else if (!pointHints.isEmpty()) {
snap = locationIndex.findClosest(point.lat, point.lon, new NameSimilarityEdgeFilter(strictEdgeFilter, pointHints.get(placeIndex), point, 100));
} else if (!snapPreventions.isEmpty()) {
snap = locationIndex.findClosest(point.lat, point.lon, strictEdgeFilter);
}
if (snap == null || !snap.isValid())
snap = locationIndex.findClosest(point.lat, point.lon, snapFilter);
if (!snap.isValid())
pointsNotFound.add(placeIndex);
snaps.add(snap);
}
if (!pointsNotFound.isEmpty())
throw new MultiplePointsNotFoundException(pointsNotFound);
return snaps;
}
use of com.graphhopper.storage.index.Snap in project graphhopper by graphhopper.
the class ViaRouting method calcPaths.
public static Result calcPaths(List<GHPoint> points, QueryGraph queryGraph, List<Snap> snaps, DirectedEdgeFilter directedEdgeFilter, PathCalculator pathCalculator, List<String> curbsides, boolean forceCurbsides, List<Double> headings, boolean passThrough) {
if (!curbsides.isEmpty() && curbsides.size() != points.size())
throw new IllegalArgumentException("If you pass " + CURBSIDE + ", you need to pass exactly one curbside for every point, empty curbsides will be ignored");
if (!curbsides.isEmpty() && !headings.isEmpty())
throw new IllegalArgumentException("You cannot use curbsides and headings or pass_through at the same time");
final int legs = snaps.size() - 1;
Result result = new Result(legs);
for (int leg = 0; leg < legs; ++leg) {
Snap fromSnap = snaps.get(leg);
Snap toSnap = snaps.get(leg + 1);
// enforce headings
// at via-nodes and the target node the heading parameter is interpreted as the direction we want
// to enforce for arriving (not starting) at this node. the starting direction is not enforced at
// all for these points (unless using pass through). see this forum discussion:
// https://discuss.graphhopper.com/t/meaning-of-heading-parameter-for-via-routing/5643/6
double fromHeading = (leg == 0 && !headings.isEmpty()) ? headings.get(0) : Double.NaN;
double toHeading = (snaps.size() == headings.size() && !Double.isNaN(headings.get(leg + 1))) ? headings.get(leg + 1) : Double.NaN;
// enforce pass-through
int incomingEdge = NO_EDGE;
if (leg != 0) {
// enforce straight start after via stop
Path prevRoute = result.paths.get(leg - 1);
if (prevRoute.getEdgeCount() > 0)
incomingEdge = prevRoute.getFinalEdge().getEdge();
}
// enforce curbsides
final String fromCurbside = curbsides.isEmpty() ? CURBSIDE_ANY : curbsides.get(leg);
final String toCurbside = curbsides.isEmpty() ? CURBSIDE_ANY : curbsides.get(leg + 1);
EdgeRestrictions edgeRestrictions = buildEdgeRestrictions(queryGraph, fromSnap, toSnap, fromHeading, toHeading, incomingEdge, passThrough, fromCurbside, toCurbside, directedEdgeFilter);
edgeRestrictions.setSourceOutEdge(ignoreThrowOrAcceptImpossibleCurbsides(curbsides, edgeRestrictions.getSourceOutEdge(), leg, forceCurbsides));
edgeRestrictions.setTargetInEdge(ignoreThrowOrAcceptImpossibleCurbsides(curbsides, edgeRestrictions.getTargetInEdge(), leg + 1, forceCurbsides));
// calculate paths
List<Path> paths = pathCalculator.calcPaths(fromSnap.getClosestNode(), toSnap.getClosestNode(), edgeRestrictions);
result.debug += pathCalculator.getDebugString();
// a good method to decide how to combine the different legs
for (int i = 0; i < paths.size(); i++) {
Path path = paths.get(i);
if (path.getTime() < 0)
throw new RuntimeException("Time was negative " + path.getTime() + " for index " + i);
result.paths.add(path);
result.debug += ", " + path.getDebugInfo();
}
result.visitedNodes += pathCalculator.getVisitedNodes();
result.debug += "visited nodes sum: " + result.visitedNodes;
}
return result;
}
use of com.graphhopper.storage.index.Snap in project graphhopper by graphhopper.
the class LandmarkSuggestion method readLandmarks.
/**
* The expected format is lon,lat per line where lines starting with characters will be ignored. You can create
* such a file manually via geojson.io -> Save as CSV. Optionally add a second line with
* <pre>#BBOX:minLat,minLon,maxLat,maxLon</pre>
* <p>
* to specify an explicit bounding box. TODO: support GeoJSON instead.
*/
public static LandmarkSuggestion readLandmarks(String file, LocationIndex locationIndex) throws IOException {
// landmarks should be suited for all vehicles
EdgeFilter edgeFilter = EdgeFilter.ALL_EDGES;
List<String> lines = Helper.readFile(file);
List<Integer> landmarkNodeIds = new ArrayList<>();
BBox bbox = BBox.createInverse(false);
int lmSuggestionIdx = 0;
String errors = "";
for (String lmStr : lines) {
if (lmStr.startsWith("#BBOX:")) {
bbox = BBox.parseTwoPoints(lmStr.substring("#BBOX:".length()));
continue;
} else if (lmStr.isEmpty() || Character.isAlphabetic(lmStr.charAt(0))) {
continue;
}
GHPoint point = GHPoint.fromStringLonLat(lmStr);
if (point == null)
throw new RuntimeException("Invalid format " + lmStr + " for point " + lmSuggestionIdx);
lmSuggestionIdx++;
Snap result = locationIndex.findClosest(point.lat, point.lon, edgeFilter);
if (!result.isValid()) {
errors += "Cannot find close node found for landmark suggestion[" + lmSuggestionIdx + "]=" + point + ".\n";
continue;
}
bbox.update(point.lat, point.lon);
landmarkNodeIds.add(result.getClosestNode());
}
if (!errors.isEmpty())
throw new RuntimeException(errors);
return new LandmarkSuggestion(landmarkNodeIds, bbox);
}
Aggregations