use of com.graphhopper.routing.ev.EncodedValueLookup in project graphhopper by graphhopper.
the class GraphHopperTest method testSRTMWithTunnelInterpolation.
@ParameterizedTest
@ValueSource(booleans = { true, false })
public void testSRTMWithTunnelInterpolation(boolean withTunnelInterpolation) {
final String profile = "profile";
final String vehicle = "foot";
final String weighting = "shortest";
GraphHopper hopper = new GraphHopper().setGraphHopperLocation(GH_LOCATION).setOSMFile(MONACO).setProfiles(new Profile(profile).setVehicle(vehicle).setWeighting(weighting)).setStoreOnFlush(true);
if (!withTunnelInterpolation) {
hopper.setTagParserFactory(new DefaultTagParserFactory() {
@Override
public TagParser create(EncodedValueLookup lookup, String name) {
TagParser parser = super.create(lookup, name);
if (name.equals("road_environment"))
parser = new OSMRoadEnvironmentParser(lookup.getEnumEncodedValue(RoadEnvironment.KEY, RoadEnvironment.class)) {
@Override
public IntsRef handleWayTags(IntsRef edgeFlags, ReaderWay readerWay, IntsRef relationFlags) {
// do not change RoadEnvironment to avoid triggering tunnel interpolation
return edgeFlags;
}
};
return parser;
}
});
hopper.setEncodedValuesString("road_environment");
}
hopper.setElevationProvider(new SRTMProvider(DIR));
hopper.importOrLoad();
GHPoint from = new GHPoint(43.7405647, 7.4299266);
GHPoint to = new GHPoint(43.7378990, 7.4279780);
// make sure we hit tower nodes, because all we really want is test the elevation interpolation
assertEquals(Snap.Position.TOWER, hopper.getLocationIndex().findClosest(from.lat, from.lon, EdgeFilter.ALL_EDGES).getSnappedPosition());
assertEquals(Snap.Position.TOWER, hopper.getLocationIndex().findClosest(to.lat, to.lon, EdgeFilter.ALL_EDGES).getSnappedPosition());
GHResponse rsp = hopper.route(new GHRequest(from, to).setProfile(profile));
ResponsePath res = rsp.getBest();
PointList pointList = res.getPoints();
assertEquals(6, pointList.size());
assertTrue(pointList.is3D());
if (withTunnelInterpolation) {
assertEquals(351.8, res.getDistance(), .1);
assertEquals(17, pointList.getEle(0), .1);
assertEquals(19.04, pointList.getEle(1), .1);
assertEquals(21.67, pointList.getEle(2), .1);
assertEquals(25.03, pointList.getEle(3), .1);
assertEquals(28.65, pointList.getEle(4), .1);
assertEquals(34.00, pointList.getEle(5), .1);
} else {
assertEquals(358.3, res.getDistance(), .1);
assertEquals(17.0, pointList.getEle(0), .1);
assertEquals(23.0, pointList.getEle(1), .1);
assertEquals(23.0, pointList.getEle(2), .1);
assertEquals(41.0, pointList.getEle(3), .1);
assertEquals(19.0, pointList.getEle(4), .1);
assertEquals(34.0, pointList.getEle(5), .1);
}
}
use of com.graphhopper.routing.ev.EncodedValueLookup in project graphhopper by graphhopper.
the class TripFromLabel method createResponsePath.
ResponsePath createResponsePath(Translation tr, PointList waypoints, Graph queryGraph, Weighting accessWeighting, Weighting egressWeighting, List<Label.Transition> solution, List<String> requestedPathDetails) {
final List<List<Label.Transition>> partitions = parsePathToPartitions(solution);
final List<Trip.Leg> legs = new ArrayList<>();
for (int i = 0; i < partitions.size(); i++) {
legs.addAll(parsePartitionToLegs(partitions.get(i), queryGraph, encodedValueLookup, i == partitions.size() - 1 ? egressWeighting : accessWeighting, tr, requestedPathDetails));
}
if (legs.size() > 1 && legs.get(0) instanceof Trip.WalkLeg) {
final Trip.WalkLeg accessLeg = (Trip.WalkLeg) legs.get(0);
legs.set(0, new Trip.WalkLeg(accessLeg.departureLocation, new Date(legs.get(1).getDepartureTime().getTime() - (accessLeg.getArrivalTime().getTime() - accessLeg.getDepartureTime().getTime())), accessLeg.geometry, accessLeg.distance, accessLeg.instructions, accessLeg.details, legs.get(1).getDepartureTime()));
}
if (legs.size() > 1 && legs.get(legs.size() - 1) instanceof Trip.WalkLeg) {
final Trip.WalkLeg egressLeg = (Trip.WalkLeg) legs.get(legs.size() - 1);
legs.set(legs.size() - 1, new Trip.WalkLeg(egressLeg.departureLocation, legs.get(legs.size() - 2).getArrivalTime(), egressLeg.geometry, egressLeg.distance, egressLeg.instructions, egressLeg.details, new Date(legs.get(legs.size() - 2).getArrivalTime().getTime() + (egressLeg.getArrivalTime().getTime() - egressLeg.getDepartureTime().getTime()))));
}
ResponsePath path = new ResponsePath();
path.setWaypoints(waypoints);
path.getLegs().addAll(legs);
final InstructionList instructions = new InstructionList(tr);
final PointList pointsList = new PointList();
Map<String, List<PathDetail>> pathDetails = new HashMap<>();
for (int i = 0; i < path.getLegs().size(); ++i) {
Trip.Leg leg = path.getLegs().get(i);
if (leg instanceof Trip.WalkLeg) {
final Trip.WalkLeg walkLeg = ((Trip.WalkLeg) leg);
List<Instruction> theseInstructions = walkLeg.instructions.subList(0, i < path.getLegs().size() - 1 ? walkLeg.instructions.size() - 1 : walkLeg.instructions.size());
int previousPointsCount = pointsList.size();
for (Instruction instruction : theseInstructions) {
pointsList.add(instruction.getPoints());
}
instructions.addAll(theseInstructions);
Map<String, List<PathDetail>> shiftedLegPathDetails = shift(((Trip.WalkLeg) leg).details, previousPointsCount);
shiftedLegPathDetails.forEach((k, v) -> pathDetails.merge(k, shiftedLegPathDetails.get(k), (a, b) -> Lists.newArrayList(Iterables.concat(a, b))));
} else if (leg instanceof Trip.PtLeg) {
final Trip.PtLeg ptLeg = ((Trip.PtLeg) leg);
final PointList pl;
if (!ptLeg.isInSameVehicleAsPrevious) {
pl = new PointList();
final Instruction departureInstruction = new Instruction(Instruction.PT_START_TRIP, ptLeg.trip_headsign, pl);
departureInstruction.setDistance(leg.getDistance());
departureInstruction.setTime(ptLeg.travelTime);
instructions.add(departureInstruction);
} else {
pl = instructions.get(instructions.size() - 2).getPoints();
}
pl.add(ptLeg.stops.get(0).geometry.getY(), ptLeg.stops.get(0).geometry.getX());
pointsList.add(ptLeg.stops.get(0).geometry.getY(), ptLeg.stops.get(0).geometry.getX());
for (Trip.Stop stop : ptLeg.stops.subList(0, ptLeg.stops.size() - 1)) {
pl.add(stop.geometry.getY(), stop.geometry.getX());
pointsList.add(stop.geometry.getY(), stop.geometry.getX());
}
final PointList arrivalPointList = new PointList();
final Trip.Stop arrivalStop = ptLeg.stops.get(ptLeg.stops.size() - 1);
arrivalPointList.add(arrivalStop.geometry.getY(), arrivalStop.geometry.getX());
pointsList.add(arrivalStop.geometry.getY(), arrivalStop.geometry.getX());
Instruction arrivalInstruction = new Instruction(Instruction.PT_END_TRIP, arrivalStop.stop_name, arrivalPointList);
if (ptLeg.isInSameVehicleAsPrevious) {
instructions.set(instructions.size() - 1, arrivalInstruction);
} else {
instructions.add(arrivalInstruction);
}
}
}
path.setInstructions(instructions);
path.setPoints(pointsList);
path.addPathDetails(pathDetails);
path.setDistance(path.getLegs().stream().mapToDouble(Trip.Leg::getDistance).sum());
path.setTime((legs.get(legs.size() - 1).getArrivalTime().toInstant().toEpochMilli() - legs.get(0).getDepartureTime().toInstant().toEpochMilli()));
path.setNumChanges((int) path.getLegs().stream().filter(l -> l instanceof Trip.PtLeg).filter(l -> !((Trip.PtLeg) l).isInSameVehicleAsPrevious).count() - 1);
com.graphhopper.gtfs.fare.Trip faresTrip = new com.graphhopper.gtfs.fare.Trip();
path.getLegs().stream().filter(leg -> leg instanceof Trip.PtLeg).map(leg -> (Trip.PtLeg) leg).findFirst().ifPresent(firstPtLeg -> {
LocalDateTime firstPtDepartureTime = GtfsHelper.localDateTimeFromDate(firstPtLeg.getDepartureTime());
path.getLegs().stream().filter(leg -> leg instanceof Trip.PtLeg).map(leg -> (Trip.PtLeg) leg).map(ptLeg -> {
final GTFSFeed gtfsFeed = gtfsStorage.getGtfsFeeds().get(ptLeg.feed_id);
return new com.graphhopper.gtfs.fare.Trip.Segment(ptLeg.feed_id, ptLeg.route_id, Duration.between(firstPtDepartureTime, GtfsHelper.localDateTimeFromDate(ptLeg.getDepartureTime())).getSeconds(), gtfsFeed.stops.get(ptLeg.stops.get(0).stop_id).zone_id, gtfsFeed.stops.get(ptLeg.stops.get(ptLeg.stops.size() - 1).stop_id).zone_id, ptLeg.stops.stream().map(s -> gtfsFeed.stops.get(s.stop_id).zone_id).collect(Collectors.toSet()));
}).forEach(faresTrip.segments::add);
Fares.cheapestFare(gtfsStorage.getFares(), faresTrip).ifPresent(amount -> path.setFare(amount.getAmount()));
});
return path;
}
use of com.graphhopper.routing.ev.EncodedValueLookup in project graphhopper by graphhopper.
the class TripFromLabel method parsePartitionToLegs.
// We are parsing a string of edges into a hierarchical trip.
// One could argue that one should never write a parser
// by hand, because it is always ugly, but use a parser library.
// The code would then read like a specification of what paths through the graph mean.
private List<Trip.Leg> parsePartitionToLegs(List<Label.Transition> path, Graph graph, EncodedValueLookup encodedValueLookup, Weighting weighting, Translation tr, List<String> requestedPathDetails) {
if (path.size() <= 1) {
return Collections.emptyList();
}
if (GtfsStorage.EdgeType.ENTER_PT == path.get(1).edge.getType()) {
String feedId = path.get(1).edge.getPlatformDescriptor().feed_id;
List<Trip.Leg> result = new ArrayList<>();
long boardTime = -1;
List<Label.Transition> partition = null;
for (int i = 1; i < path.size(); i++) {
Label.Transition transition = path.get(i);
GraphExplorer.MultiModalEdge edge = path.get(i).edge;
if (edge.getType() == GtfsStorage.EdgeType.BOARD) {
boardTime = transition.label.currentTime;
partition = new ArrayList<>();
}
if (partition != null) {
partition.add(path.get(i));
}
if (EnumSet.of(GtfsStorage.EdgeType.TRANSFER, GtfsStorage.EdgeType.LEAVE_TIME_EXPANDED_NETWORK).contains(edge.getType())) {
GtfsRealtime.TripDescriptor tripDescriptor = partition.get(0).edge.getTripDescriptor();
final StopsFromBoardHopDwellEdges stopsFromBoardHopDwellEdges = new StopsFromBoardHopDwellEdges(feedId, tripDescriptor);
partition.stream().filter(e -> EnumSet.of(GtfsStorage.EdgeType.HOP, GtfsStorage.EdgeType.BOARD, GtfsStorage.EdgeType.DWELL).contains(e.edge.getType())).forEach(stopsFromBoardHopDwellEdges::next);
stopsFromBoardHopDwellEdges.finish();
List<Trip.Stop> stops = stopsFromBoardHopDwellEdges.stops;
result.add(new Trip.PtLeg(feedId, partition.get(0).edge.getTransfers() == 0, tripDescriptor.getTripId(), tripDescriptor.getRouteId(), Optional.ofNullable(gtfsStorage.getGtfsFeeds().get(feedId).trips.get(tripDescriptor.getTripId())).map(t -> t.trip_headsign).orElse("extra"), stops, partition.stream().mapToDouble(t -> t.edge.getDistance()).sum(), path.get(i - 1).label.currentTime - boardTime, geometryFactory.createLineString(stops.stream().map(s -> s.geometry.getCoordinate()).toArray(Coordinate[]::new))));
partition = null;
if (edge.getType() == GtfsStorage.EdgeType.TRANSFER) {
feedId = edge.getPlatformDescriptor().feed_id;
int[] skippedEdgesForTransfer = gtfsStorage.getSkippedEdgesForTransfer().get(edge.getId());
if (skippedEdgesForTransfer != null) {
List<Trip.Leg> legs = parsePartitionToLegs(transferPath(skippedEdgesForTransfer, weighting, path.get(i - 1).label.currentTime), graph, encodedValueLookup, weighting, tr, requestedPathDetails);
result.add(legs.get(0));
}
}
}
}
return result;
} else {
InstructionList instructions = new InstructionList(tr);
InstructionsFromEdges instructionsFromEdges = new InstructionsFromEdges(graph, weighting, encodedValueLookup, instructions);
int prevEdgeId = -1;
for (int i = 1; i < path.size(); i++) {
if (path.get(i).edge.getType() != GtfsStorage.EdgeType.HIGHWAY) {
throw new IllegalStateException("Got a transit edge where I think I must be on a road.");
}
EdgeIteratorState edge = graph.getEdgeIteratorState(path.get(i).edge.getId(), path.get(i).label.node.streetNode);
instructionsFromEdges.next(edge, i, prevEdgeId);
prevEdgeId = edge.getEdge();
}
instructionsFromEdges.finish();
Path pathh = new Path(graph);
for (Label.Transition transition : path) {
if (transition.edge != null)
pathh.addEdge(transition.edge.getId());
}
pathh.setFromNode(path.get(0).label.node.streetNode);
pathh.setEndNode(path.get(path.size() - 1).label.node.streetNode);
pathh.setFound(true);
Map<String, List<PathDetail>> pathDetails = PathDetailsFromEdges.calcDetails(pathh, encodedValueLookup, weighting, requestedPathDetails, pathDetailsBuilderFactory, 0);
final Instant departureTime = Instant.ofEpochMilli(path.get(0).label.currentTime);
final Instant arrivalTime = Instant.ofEpochMilli(path.get(path.size() - 1).label.currentTime);
return Collections.singletonList(new Trip.WalkLeg("Walk", Date.from(departureTime), lineStringFromInstructions(instructions), edges(path).mapToDouble(edgeLabel -> edgeLabel.getDistance()).sum(), instructions, pathDetails, Date.from(arrivalTime)));
}
}
Aggregations