use of com.graphhopper.storage.index.Snap in project graphhopper by graphhopper.
the class MapMatching method createTimeSteps.
/**
* Creates TimeSteps with candidates for the GPX entries but does not create emission or
* transition probabilities. Creates directed candidates for virtual nodes and undirected
* candidates for real nodes.
*/
private List<ObservationWithCandidateStates> createTimeSteps(List<Observation> filteredObservations, List<Collection<Snap>> splitsPerObservation) {
if (splitsPerObservation.size() != filteredObservations.size()) {
throw new IllegalArgumentException("filteredGPXEntries and queriesPerEntry must have same size.");
}
final List<ObservationWithCandidateStates> timeSteps = new ArrayList<>();
for (int i = 0; i < filteredObservations.size(); i++) {
Observation observation = filteredObservations.get(i);
Collection<Snap> splits = splitsPerObservation.get(i);
List<State> candidates = new ArrayList<>();
for (Snap split : splits) {
if (queryGraph.isVirtualNode(split.getClosestNode())) {
List<VirtualEdgeIteratorState> virtualEdges = new ArrayList<>();
EdgeIterator iter = queryGraph.createEdgeExplorer().setBaseNode(split.getClosestNode());
while (iter.next()) {
if (!queryGraph.isVirtualEdge(iter.getEdge())) {
throw new RuntimeException("Virtual nodes must only have virtual edges " + "to adjacent nodes.");
}
virtualEdges.add((VirtualEdgeIteratorState) queryGraph.getEdgeIteratorState(iter.getEdge(), iter.getAdjNode()));
}
if (virtualEdges.size() != 2) {
throw new RuntimeException("Each virtual node must have exactly 2 " + "virtual edges (reverse virtual edges are not returned by the " + "EdgeIterator");
}
// Create a directed candidate for each of the two possible directions through
// the virtual node. We need to add candidates for both directions because
// we don't know yet which is the correct one. This will be figured
// out by the Viterbi algorithm.
candidates.add(new State(observation, split, virtualEdges.get(0), virtualEdges.get(1)));
candidates.add(new State(observation, split, virtualEdges.get(1), virtualEdges.get(0)));
} else {
// Create an undirected candidate for the real node.
candidates.add(new State(observation, split));
}
}
timeSteps.add(new ObservationWithCandidateStates(observation, candidates));
}
return timeSteps;
}
use of com.graphhopper.storage.index.Snap in project graphhopper by graphhopper.
the class RoundTripRouting method calcPaths.
public static Result calcPaths(List<Snap> snaps, FlexiblePathCalculator pathCalculator) {
RoundTripCalculator roundTripCalculator = new RoundTripCalculator(pathCalculator);
Result result = new Result(snaps.size() - 1);
Snap start = snaps.get(0);
for (int snapIndex = 1; snapIndex < snaps.size(); snapIndex++) {
// instead getClosestNode (which might be a virtual one and introducing unnecessary tails of the route)
// use next tower node -> getBaseNode or getAdjNode
// Later: remove potential route tail, maybe we can just enforce the heading at the start and when coming
// back, and for tower nodes it does not matter anyway
Snap startSnap = snaps.get(snapIndex - 1);
int startNode = (startSnap == start) ? startSnap.getClosestNode() : startSnap.getClosestEdge().getBaseNode();
Snap endSnap = snaps.get(snapIndex);
int endNode = (endSnap == start) ? endSnap.getClosestNode() : endSnap.getClosestEdge().getBaseNode();
Path path = roundTripCalculator.calcPath(startNode, endNode);
result.visitedNodes += pathCalculator.getVisitedNodes();
result.paths.add(path);
}
return result;
}
use of com.graphhopper.storage.index.Snap in project graphhopper by graphhopper.
the class Router method routeRoundTrip.
protected GHResponse routeRoundTrip(GHRequest request, FlexSolver solver) {
GHResponse ghRsp = new GHResponse();
StopWatch sw = new StopWatch().start();
double startHeading = request.getHeadings().isEmpty() ? Double.NaN : request.getHeadings().get(0);
RoundTripRouting.Params params = new RoundTripRouting.Params(request.getHints(), startHeading, routerConfig.getMaxRoundTripRetries());
List<Snap> snaps = RoundTripRouting.lookup(request.getPoints(), solver.createSnapFilter(), locationIndex, params);
ghRsp.addDebugInfo("idLookup:" + sw.stop().getSeconds() + "s");
QueryGraph queryGraph = QueryGraph.create(ghStorage, snaps);
FlexiblePathCalculator pathCalculator = solver.createPathCalculator(queryGraph);
RoundTripRouting.Result result = RoundTripRouting.calcPaths(snaps, pathCalculator);
// we merge the different legs of the roundtrip into one response path
ResponsePath responsePath = concatenatePaths(request, solver.weighting, queryGraph, result.paths, getWaypoints(snaps));
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 Router method routeAlt.
protected GHResponse routeAlt(GHRequest request, Solver solver) {
if (request.getPoints().size() > 2)
throw new IllegalArgumentException("Currently alternative routes work only with start and end point. You tried to use: " + request.getPoints().size() + " points");
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");
QueryGraph queryGraph = QueryGraph.create(ghStorage, snaps);
PathCalculator pathCalculator = solver.createPathCalculator(queryGraph);
boolean passThrough = getPassThrough(request.getHints());
boolean forceCurbsides = getForceCurbsides(request.getHints());
if (passThrough)
throw new IllegalArgumentException("Alternative paths and " + PASS_THROUGH + " at the same time is currently not supported");
if (!request.getCurbsides().isEmpty())
throw new IllegalArgumentException("Alternative paths do not support the " + CURBSIDE + " parameter yet");
ViaRouting.Result result = ViaRouting.calcPaths(request.getPoints(), queryGraph, snaps, directedEdgeFilter, pathCalculator, request.getCurbsides(), forceCurbsides, request.getHeadings(), passThrough);
if (result.paths.isEmpty())
throw new RuntimeException("Empty paths for alternative route calculation not expected");
// each path represents a different alternative and we do the path merging for each of them
PathMerger pathMerger = createPathMerger(request, solver.weighting, queryGraph);
for (Path path : result.paths) {
PointList waypoints = getWaypoints(snaps);
ResponsePath responsePath = pathMerger.doWork(waypoints, Collections.singletonList(path), encodingManager, translationMap.getWithFallBack(request.getLocale()));
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 GraphHopperTest method issue2306_1.
@Test
public void issue2306_1() {
final String profile = "profile";
final String vehicle = "car";
GraphHopper hopper = new GraphHopper().setGraphHopperLocation(GH_LOCATION).setOSMFile("../map-matching/files/leipzig_germany.osm.pbf").setProfiles(new Profile("profile").setVehicle(vehicle).setWeighting("fastest")).setMinNetworkSize(200);
hopper.importOrLoad();
Weighting weighting = hopper.createWeighting(hopper.getProfile(profile), new PMap());
EdgeFilter edgeFilter = new DefaultSnapFilter(weighting, hopper.getEncodingManager().getBooleanEncodedValue(Subnetwork.key(profile)));
LocationIndexTree locationIndex = ((LocationIndexTree) hopper.getLocationIndex());
// have to increase the default search radius to find our snap
locationIndex.setMaxRegionSearch(6);
Snap snap = locationIndex.findClosest(51.229248, 12.328892, edgeFilter);
assertTrue(snap.isValid());
assertTrue(snap.getQueryDistance() < 3_000);
}
Aggregations