use of com.graphhopper.util.details.PathDetail in project graphhopper by graphhopper.
the class GraphHopperWebIT method testPathDetails.
@Test
public void testPathDetails() {
GHRequest req = new GHRequest().addPoint(new GHPoint(49.6724, 11.3494)).addPoint(new GHPoint(49.6550, 11.4180));
req.getPathDetails().add("average_speed");
GHResponse res = gh.route(req);
assertFalse("errors:" + res.getErrors().toString(), res.hasErrors());
PathWrapper alt = res.getBest();
assertEquals(1, alt.getPathDetails().size());
List<PathDetail> details = alt.getPathDetails().get("average_speed");
assertFalse(details.isEmpty());
assertTrue((Double) details.get(0).getValue() > 20);
assertTrue((Double) details.get(0).getValue() < 70);
}
use of com.graphhopper.util.details.PathDetail in project graphhopper by graphhopper.
the class Path method calcDetails.
/**
* Calculates the PathDetails for this Path. This method will return fast, if there are no calculators.
*
* @param pathBuilderFactory Generates the relevant PathBuilders
* @return List of PathDetails for this Path
*/
public Map<String, List<PathDetail>> calcDetails(List<String> requestedPathDetails, PathDetailsBuilderFactory pathBuilderFactory, int previousIndex) {
if (!isFound() || requestedPathDetails.isEmpty())
return Collections.EMPTY_MAP;
List<PathDetailsBuilder> pathBuilders = pathBuilderFactory.createPathDetailsBuilders(requestedPathDetails, encoder, weighting);
if (pathBuilders.isEmpty())
return Collections.EMPTY_MAP;
forEveryEdge(new PathDetailsFromEdges(pathBuilders, previousIndex));
Map<String, List<PathDetail>> pathDetails = new HashMap<>(pathBuilders.size());
for (PathDetailsBuilder builder : pathBuilders) {
Map.Entry<String, List<PathDetail>> entry = builder.build();
List<PathDetail> existing = pathDetails.put(entry.getKey(), entry.getValue());
if (existing != null)
throw new IllegalStateException("Some PathDetailsBuilders use duplicate key: " + entry.getKey());
}
return pathDetails;
}
use of com.graphhopper.util.details.PathDetail in project graphhopper by graphhopper.
the class PathMerger method merge.
/**
* Merges <code>otherDetails</code> into the <code>pathDetails</code>.
* <p>
* This method makes sure that Entry list around via points are merged correctly.
* See #1091 and the misplaced PathDetail after waypoints.
*/
public static void merge(List<PathDetail> pathDetails, List<PathDetail> otherDetails) {
// Make sure that the PathDetail list is merged correctly at via points
if (!pathDetails.isEmpty() && !otherDetails.isEmpty()) {
PathDetail lastDetail = pathDetails.get(pathDetails.size() - 1);
if (lastDetail.getValue().equals(otherDetails.get(0).getValue())) {
lastDetail.setLast(otherDetails.get(0).getLast());
otherDetails.remove(0);
}
}
pathDetails.addAll(otherDetails);
}
use of com.graphhopper.util.details.PathDetail in project graphhopper by graphhopper.
the class PathSimplification method simplify.
public PointList simplify() {
if (pointList.size() <= 2) {
pointList.makeImmutable();
return pointList;
}
// no constraints
if (listsToSimplify.isEmpty()) {
douglasPeucker.simplify(pointList, 0, pointList.size() - 1);
pointList.makeImmutable();
return pointList;
}
// The offset of already included points
int[] offsets = new int[listsToSimplify.size()];
int[] endIntervals = new int[listsToSimplify.size()];
// All start at 0
int[] startIntervals = new int[listsToSimplify.size()];
while (true) {
boolean simplificationPossible = true;
int nonConflictingStart = 0;
int nonConflictingEnd = Integer.MAX_VALUE;
int listIndexToSimplify = -1;
int listIndexToShift = -1;
endIntervals = calculateEndIntervals(endIntervals, startIntervals, offsets, listsToSimplify);
// Find the intervals to run a simplification, if possible, and where to shift
for (int i = 0; i < listsToSimplify.size(); i++) {
if (startIntervals[i] >= nonConflictingEnd || endIntervals[i] <= nonConflictingStart) {
simplificationPossible = false;
}
if (startIntervals[i] > nonConflictingStart) {
listIndexToSimplify = -1;
nonConflictingStart = startIntervals[i];
}
if (endIntervals[i] < nonConflictingEnd) {
listIndexToSimplify = -1;
nonConflictingEnd = endIntervals[i];
// Remember the lowest endInterval
listIndexToShift = i;
}
if (startIntervals[i] >= nonConflictingStart && endIntervals[i] <= nonConflictingEnd) {
listIndexToSimplify = i;
}
}
if (listIndexToSimplify >= 0 && simplificationPossible) {
// Only simplify if there is more than one point
if (nonConflictingEnd - nonConflictingStart > 1) {
int removed = douglasPeucker.simplify(pointList, nonConflictingStart, nonConflictingEnd);
if (removed > 0) {
for (int i = 0; i < listsToSimplify.size(); i++) {
List pathDetails = listsToSimplify.get(i);
reduceLength(pathDetails, offsets[i], startIntervals[i], endIntervals[i] - removed);
// This is not needed for Instructions, as they don't contain references, but PointLists
if (pathDetails.get(0) instanceof PathDetail) {
for (int j = offsets[i] + 1; j < pathDetails.size(); j++) {
PathDetail pd = (PathDetail) pathDetails.get(j);
reduceLength(pathDetails, j, pd.getFirst() - removed, pd.getLast() - removed);
}
}
}
}
}
}
if (listIndexToShift < 0)
throw new IllegalStateException("toShiftIndex cannot be negative");
int length = getLength(listsToSimplify.get(listIndexToShift), offsets[listIndexToShift]);
startIntervals[listIndexToShift] += length;
offsets[listIndexToShift]++;
if (offsets[listIndexToShift] >= listsToSimplify.get(listIndexToShift).size())
break;
}
for (Map.Entry<String, List<PathDetail>> pdEntry : pathDetails.entrySet()) {
List<PathDetail> list = pdEntry.getValue();
if (list.isEmpty())
continue;
PathDetail prevPD = list.get(0);
for (int i = 1; i < list.size(); i++) {
if (prevPD.getLast() != list.get(i).getFirst())
throw new IllegalStateException("PathDetail list " + pdEntry.getKey() + " is inconsistent due to entries " + prevPD + " vs. " + list.get(i));
prevPD = list.get(i);
}
}
// Make sure that the instruction references are not broken
pointList.makeImmutable();
return pointList;
}
use of com.graphhopper.util.details.PathDetail in project graphhopper by graphhopper.
the class GraphHopperServletIT method testPathDetails.
@Test
public void testPathDetails() throws Exception {
GraphHopperAPI hopper = new com.graphhopper.api.GraphHopperWeb();
assertTrue(hopper.load(getTestRouteAPIUrl()));
GHRequest request = new GHRequest(42.554851, 1.536198, 42.510071, 1.548128);
request.setPathDetails(Arrays.asList("average_speed", "edge_id", "time"));
GHResponse rsp = hopper.route(request);
assertFalse(rsp.getErrors().toString(), rsp.hasErrors());
assertTrue(rsp.getErrors().toString(), rsp.getErrors().isEmpty());
Map<String, List<PathDetail>> pathDetails = rsp.getBest().getPathDetails();
assertFalse(pathDetails.isEmpty());
assertTrue(pathDetails.containsKey("average_speed"));
assertTrue(pathDetails.containsKey("edge_id"));
assertTrue(pathDetails.containsKey("time"));
List<PathDetail> averageSpeedList = pathDetails.get("average_speed");
assertEquals(9, averageSpeedList.size());
assertEquals(30.0, averageSpeedList.get(0).getValue());
assertEquals(14, averageSpeedList.get(0).getLength());
assertEquals(60.0, averageSpeedList.get(1).getValue());
assertEquals(5, averageSpeedList.get(1).getLength());
List<PathDetail> edgeIdDetails = pathDetails.get("edge_id");
assertEquals(77, edgeIdDetails.size());
assertEquals(3759L, edgeIdDetails.get(0).getValue());
assertEquals(2, edgeIdDetails.get(0).getLength());
assertEquals(881L, edgeIdDetails.get(1).getValue());
assertEquals(8, edgeIdDetails.get(1).getLength());
long expectedTime = rsp.getBest().getTime();
long actualTime = 0;
List<PathDetail> timeDetails = pathDetails.get("time");
for (PathDetail pd : timeDetails) {
actualTime += (Long) pd.getValue();
}
assertEquals(expectedTime, actualTime);
}
Aggregations