Skip to content

Commit

Permalink
fix: Mapbox Arrival and Destinations assumptions (graphhopper#3062)
Browse files Browse the repository at this point in the history
  • Loading branch information
OlafFlebbeBosch authored Oct 15, 2024
1 parent 97fd564 commit 136309c
Show file tree
Hide file tree
Showing 2 changed files with 72 additions and 26 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@ private static void putRouteInformation(ObjectNode pathJson, ResponsePath path,

Map<String, List<PathDetail>> pathDetails = path.getPathDetails();
List<PathDetail> intersectionDetails = pathDetails.getOrDefault(INTERSECTION, Collections.emptyList());
fixFirstIntersectionDetail(intersectionDetails);

for (int i = 0; i < instructions.size(); i++) {
ObjectNode instructionJson = steps.addObject();
Expand Down Expand Up @@ -158,6 +159,38 @@ private static void putLegInformation(ObjectNode legJson, ResponsePath path, int
legJson.put("distance", Helper.round(distance, 1));
}

/**
* fix the first IntersectionDetail.
*
* The first Intersection of the first step should only have one "bearings" and one
* "out" entry
*
*/
private static void fixFirstIntersectionDetail(List<PathDetail> intersectionDetails) {

if (intersectionDetails.size() < 2) {
// Can happen if start and stop are at the same spot and other edge cases
return;
}

final Map<String, Object> firstItersectionMap = (Map<String, Object>) intersectionDetails.get(0).getValue();

int out = (int) firstItersectionMap.get("out");
firstItersectionMap.put("out", 0);

// bearings
List<Integer> oldBearings = (List<Integer>) firstItersectionMap.get("bearings");
List<Integer> newBearings = new ArrayList<>();
newBearings.add(oldBearings.get(out));
firstItersectionMap.put("bearings", newBearings);

// entries
final List<Boolean> oldEntries = (List<Boolean>) firstItersectionMap.get("entries");
List<Boolean> newEntries = new ArrayList<>();
newEntries.add(oldEntries.get(out));
firstItersectionMap.put("entries", newEntries);
}

/**
* filter the IntersectionDetails.
*
Expand Down Expand Up @@ -244,7 +277,7 @@ private static List<PathDetail> filterIntersectionDetails(PointList points, List
// and replace the intersection with the merged one
list.set(i, mergedPathDetail);
} catch (ClassCastException e) {
LOGGER.warn( "Exception :" + e);
LOGGER.warn("Exception :" + e);
continue;
}
}
Expand All @@ -260,6 +293,34 @@ private static ObjectNode putInstruction(PointList points, InstructionList instr
Instruction instruction = instructions.get(instructionIndex);
ArrayNode intersections = instructionJson.putArray("intersections");

// make pointList writeable
PointList pointList = instruction.getPoints().clone(false);

if (instructionIndex < instructions.size() - 1) {
// modify pointlist to include the first point of the next instruction
// for all instructions but the arrival
PointList nextPoints = instructions.get(instructionIndex + 1).getPoints();
pointList.add(nextPoints.getLat(0), nextPoints.getLon(0), nextPoints.getEle(0));
} else {
// we are at the arrival (or via point arrival instruction)
// Duplicate the last point in the arrival instruction, which does has only one
// point
pointList.add(pointList.getLat(0), pointList.getLon(0), pointList.getEle(0));

// Add an arrival intersection with only one enty
ObjectNode intersection = intersections.addObject();
ArrayNode entryArray = intersection.putArray("entry");
entryArray.add(true);

// copy the bearing from the previous instruction
ArrayNode bearingsrray = intersection.putArray("bearings");
bearingsrray.add(0);

// add the in tag
intersection.put("in", 0);
putLocation(pointList.getLat(0), pointList.getLon(0), intersection);
}

// preprocess intersectionDetails
List<PathDetail> filteredIntersectionDetails = filterIntersectionDetails(points, intersectionDetails,
pointIndexFrom, pointIndexTo);
Expand Down Expand Up @@ -294,28 +355,6 @@ private static ObjectNode putInstruction(PointList points, InstructionList instr
}
}

// Make pointList mutable
PointList pointList = instruction.getPoints().clone(false);

if (instructionIndex + 1 < instructions.size()) {
// Add the first point of the next instruction
PointList nextPoints = instructions.get(instructionIndex + 1).getPoints();
pointList.add(nextPoints.getLat(0), nextPoints.getLon(0), nextPoints.getEle(0));
} else if (pointList.size() == 1) {
// Duplicate the last point in the arrive instruction, if the size is 1
pointList.add(pointList.getLat(0), pointList.getLon(0), pointList.getEle(0));
}

if (intersections.size() == 0) {
// this is the fallback if we don't have any intersections.
// this can happen for via points or finish instructions or when no intersection
// details have been requested
ObjectNode intersection = intersections.addObject();
intersection.putArray("entry");
intersection.putArray("bearings");
putLocation(pointList.getLat(0), pointList.getLon(0), intersection);
}

instructionJson.put("driving_side", "right");

// Does not include elevation
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ public static void afterClass() {
@Test
public void basicTest() {

GHResponse rsp = hopper.route(new GHRequest(42.554851, 1.536198, 42.510071, 1.548128).setProfile(profile));
GHResponse rsp = hopper.route(new GHRequest(42.554851, 1.536198, 42.510071, 1.548128).setProfile(profile).setPathDetails(Collections.singletonList("intersection")));

ObjectNode json = NavigateResponseConverter.convertFromGHResponse(rsp, trMap, Locale.ENGLISH, distanceConfig);

Expand Down Expand Up @@ -286,8 +286,8 @@ public void intersectionTest() {
JsonNode intersection = step.get("intersections").get(0);

assertFalse(intersection.has("in"));
assertEquals(1, intersection.get("out").asInt());

assertEquals(0, intersection.get("out").asInt());
assertEquals(1, intersection.get("bearings").size());
JsonNode location = intersection.get("location");
// The first intersection to be equal to the first snapped waypoint
assertEquals(rsp.getBest().getWaypoints().get(0).lon, location.get(0).asDouble(), .000001);
Expand All @@ -300,6 +300,13 @@ public void intersectionTest() {
location = intersection.get("location");
assertEquals(1.534679, location.get(0).asDouble(), .000001);
assertEquals(42.556444, location.get(1).asDouble(), .000001);

int nrSteps=steps.size();
JsonNode lastStep = steps.get(nrSteps-1);
intersection= lastStep.get("intersections").get(0);
assertFalse(intersection.has("out"));
assertEquals(0, intersection.get("in").asInt());
assertEquals(1, intersection.get("bearings").size());
}

@Test
Expand Down

0 comments on commit 136309c

Please sign in to comment.