Open moiatto opened 1 year ago
Your code does not look correct. You will need a lot more data in the RouteLeg, you need to build Steps, Maneuvers, Instructions, etc.
I would recommend to check the content that Mapbox or OSRM provide and go from there.
If you have a working solution for OSMDroid, a PR would be welcome so we can add support for different routing providers (it needs to integrate well with the current code though :)).
Sure...if I can make it!
I need to understand the minimum data needed to make navigation work and then add the extras.
Your code does not look correct. You will need a lot more data in the RouteLeg, you need to build Steps, Maneuvers, Instructions, etc.
I would recommend to check the content that Mapbox or OSRM provide and go from there.
If you have a working solution for OSMDroid, a PR would be welcome so we can add support for different routing providers (it needs to integrate well with the current code though :)).
the information received by OSMDroid is much less than that received by MapBox. I managed to get it to work, but a lot of information is missing
If this is something you would like to contribute, I think a PR would be welcome 👍
Add these dependencies in build.gradle:
// OSMdroid (for Geocoding & Routing features)
implementation 'org.osmdroid:osmdroid-android:6.1.14' // OSMdroid https://github.com/osmdroid/osmdroid
implementation 'com.github.MKergall:osmbonuspack:6.9.0' // OSMBonusPack https://github.com/MKergall/osmbonuspack
declare as global:
private DirectionsRoute route; // MapLibre
private Road[] roads = null; // OSMBonusPack
then:
org.osmdroid.util.GeoPoint sPoint;
org.osmdroid.util.GeoPoint ePoint;
ArrayList<org.osmdroid.util.GeoPoint> vPoints = new ArrayList<>();
ArrayList<org.osmdroid.util.GeoPoint> wayPoints = new ArrayList<>();
sPoint = new org.osmdroid.util.GeoPoint(locationGps.getLatitude(), locationGps.getLongitude());
ePoint = new org.osmdroid.util.GeoPoint(destinationPoint.getLatitude(), destinationPoint.getLongitude());
// ....fill array vPoints with ViaPoints (if there are)
wayPoints.add(sPoint);
//add intermediate via points:
wayPoints.addAll(vPoints);
//add destination point:
wayPoints.add(ePoint);
ExecutorService executor = Executors.newSingleThreadExecutor();
Handler handler = new Handler(Looper.getMainLooper());
executor.execute(() -> {
//Background work here
// OSMR route provider
RoadManager roadManager = new OSRMRoadManager(requireContext(), userAgent);
roads = roadManager.getRoads(wayPoints);
if (roads[0].mStatus == STATUS_OK) route = convertOsrmRoadToMapLibreRoute(roads[0]);
handler.post(() -> {
//UI Thread work here
if (roads[0].mStatus == STATUS_OK)
{
startNavigation(route);
}
// STATUS_INVALID
// STATUS_TECHNICAL_ISSUE
else {
// MANAGE EXCEPTIONS
}
});
});
private DirectionsRoute convertOsrmRoadToMapLibreRoute(Road road)
{
List<Point> routePoints = new ArrayList<>();
ArrayList<org.osmdroid.util.GeoPoint> OsrmPoints;
// Convert list of Points
OsrmPoints = road.mRouteHigh;
for (org.osmdroid.util.GeoPoint point : OsrmPoints) {
routePoints.add(Point.fromLngLat(point.getLongitude(), point.getLatitude()));
}
// BUILD RouteOptions
RouteOptions routeOptions = RouteOptions.builder()
.geometries(DirectionsCriteria.GEOMETRY_POLYLINE6)
.profile(DirectionsCriteria.PROFILE_DRIVING)
.accessToken("pk.0") // fake AccessToken
.user(userAgent)
.requestUuid("c945b0b4-9764-11ed-a8fc-0242ac120002") // fake UUID ver.1
.baseUrl("www.fakeUrl.com") // fake url
.coordinates(routePoints)
.voiceInstructions(true)
.bannerInstructions(true)
.build();
// BUILD RouteLegs
List<RouteLeg> routeLegs = new ArrayList<>();
for (RoadLeg leg: road.mLegs)
{
// BUILD LegSteps
int indexEndNode;
List<org.osmdroid.util.GeoPoint> roadPoints = new ArrayList<>(road.mRouteHigh);
List<LegStep> legSteps = new ArrayList<>();
for (RoadNode roadNode: road.mNodes)
{
// GEOMETRY of LegStep
indexEndNode = 0;
for (int i = 0; i < roadPoints.size(); i++) {
if (CompareIfTwoGeoPointsAreEquals(roadPoints.get(i), roadNode.mLocation)) {
indexEndNode = I;
break;
}
}
ArrayList<org.osmdroid.util.GeoPoint> legPoints = new ArrayList<>();
for (int i = 0; i <= indexEndNode ; I++)
legPoints.add(roadPoints.get(i));
roadPoints.subList(0, indexEndNode + 1).clear();
// End GEOMETRY of LegStep
double[] rawLocation = {roadNode.mLocation.getLongitude(), roadNode.mLocation.getLatitude()};
List<StepIntersection> stepIntersections = new ArrayList<>();
StepIntersection stepIntersection = StepIntersection.builder() // No other OSM data for this
.rawLocation(rawLocation)
.build();
stepIntersections.add(stepIntersection);
LegStep legStep = LegStep.builder()
.distance(roadNode.mLength * 1000)
.duration(roadNode.mDuration)
.weight(1.0)
.mode("auto")
.intersections(stepIntersections)
.geometry(PolylineEncoder.encode(legPoints,1))
.maneuver(StepManeuver.builder() // No all OSM data for this
.instruction(roadNode.mInstructions)
.rawLocation(rawLocation)
.bearingBefore(0.0) // No OSM data for this
.bearingAfter(0.0) // No OSM data for this
.build())
.build();
legSteps.add(legStep);
}
RouteLeg routeLeg = RouteLeg.builder()
.distance(leg.mLength)
.duration(leg.mDuration)
.steps(legSteps)
.build();
routeLegs.add(routeLeg);
}
// Build DirectionsRoute
return DirectionsRoute.builder()
.legs(routeLegs)
.geometry(PolylineEncoder.encode(road.mRouteHigh,1))
.weightName("auto")
.weight(1.0)
.distance(road.mLength * 1000)
.duration(road.mDuration)
.routeOptions(routeOptions)
.build();
}
Try and let me know
I'm using OSMDroid server to get routes.
Then, I convert the obtained OSMDroid route class in DirectionRoute class with the DirectionsRoute.builder():
Road road; // Route obtained from OSMDroid server
points = road.mRouteHigh; for (org.osmdroid.util.GeoPoint point : points) pointsFromResponse.add(Point.fromLngLat(point.getLongitude(), point.getLatitude()));
RouteOptions routeOptions = RouteOptions.builder() .geometries(DirectionsCriteria.GEOMETRY_POLYLINE6) .profile(DirectionsCriteria.PROFILE_DRIVING) .accessToken(accessToken) .user(userAgent) .requestUuid("c945b0b4-9764-11ed-a8fc-0242ac120002") // fake UUID ver.1 .baseUrl("www.fakeurl.com") // fake url .coordinates(pointsFromResponse) .voiceInstructions(true) .bannerInstructions(true) .build();
List routeLegs = new ArrayList<>();
for (RoadLeg leg: road.mLegs)
{
RouteLeg routeLeg = RouteLeg.builder()
.distance(leg.mLength)
.duration(leg.mDuration)
.build();
route = DirectionsRoute.builder() .legs(routeLegs) .geometry(PolylineEncoder.encode(roads.mRouteHigh, 1)). // from OSMDroid class .weightName("auto") .weight(1.0) // I didn't understand what it is, so I assign this value. Can you help me? .distance(roads[0].mLength * 1000) .duration(roads[0].mDuration) .routeOptions(routeOptions) .build();
FATAL EXCEPTION: mapbox_navigation_thread Process: com.speedox.myride, PID: 2528 java.lang.NullPointerException: Attempt to invoke interface method 'int java.util.List.size()' on a null object reference at com.mapbox.services.android.navigation.v5.navigation.NavigationRouteProcessor.processNewIndex(NavigationRouteProcessor.java:198) at com.mapbox.services.android.navigation.v5.navigation.NavigationRouteProcessor.createFirstIndices(NavigationRouteProcessor.java:182) at com.mapbox.services.android.navigation.v5.navigation.NavigationRouteProcessor.checkNewRoute(NavigationRouteProcessor.java:125) at com.mapbox.services.android.navigation.v5.navigation.NavigationRouteProcessor.buildNewRouteProgress(NavigationRouteProcessor.java:87) at com.mapbox.services.android.navigation.v5.navigation.RouteProcessorHandlerCallback.handleRequest(RouteProcessorHandlerCallback.java:49) at com.mapbox.services.android.navigation.v5.navigation.RouteProcessorHandlerCallback.handleMessage(RouteProcessorHandlerCallback.java:33) at android.os.Handler.dispatchMessage(Handler.java:102) at android.os.Looper.loop(Looper.java:246) at android.os.HandlerThread.run(HandlerThread.java:67)