5 votes

Comment puis-je extrapoler plus loin sur une route ?

Compte tenu des données de localisation en temps réel d'un appareil mobile sur une courte période, comment puis-je obtenir un couple lat/long plus loin sur cette route, disons à 3 km, ou mieux encore, en 5 minutes de conduite ?

Je vois que je peux utiliser l'API des routes de Google pour trouver une route à partir d'un couple lat/long. https://developers.google.com/maps/documentation/roads/snap mais cela ne m'amène qu'à une partie du chemin.

Ce sera dans une application Android.

5voto

antonio Points 14882

Étant donné un itinéraire représenté sous la forme d'un List<LatLng> cette fonction calcule le point de l'itinéraire qui résulte du déplacement de distance mètres de origin sur cette route (en utilisant le Bibliothèque utilitaire de l'API Google Maps pour effectuer certains calculs) :

private LatLng extrapolate(List<LatLng> path, LatLng origin, float distance) {
    LatLng extrapolated = null;

    if (!PolyUtil.isLocationOnPath(origin, path, false, 1)) { // If the location is not on path non geodesic, 1 meter tolerance
        return null;
    }

    float accDistance = 0f;
    boolean foundStart = false;
    List<LatLng> segment = new ArrayList<>();

    for (int i = 0; i < path.size() - 1; i++) {
        LatLng segmentStart = path.get(i);
        LatLng segmentEnd = path.get(i + 1);

        segment.clear();
        segment.add(segmentStart);
        segment.add(segmentEnd);

        double currentDistance = 0d;

        if (!foundStart) {
            if (PolyUtil.isLocationOnPath(origin, segment, false, 1)) {
                foundStart = true;

                currentDistance = SphericalUtil.computeDistanceBetween(origin, segmentEnd);

                if (currentDistance > distance) {
                    double heading = SphericalUtil.computeHeading(origin, segmentEnd);
                    extrapolated = SphericalUtil.computeOffset(origin, distance - accDistance, heading);
                    break;
                }
            }
        } else {
            currentDistance = SphericalUtil.computeDistanceBetween(segmentStart, segmentEnd);

            if (currentDistance + accDistance > distance) {
                double heading = SphericalUtil.computeHeading(segmentStart, segmentEnd);
                extrapolated = SphericalUtil.computeOffset(segmentStart, distance - accDistance, heading);
                break;
            }
        }

        accDistance += currentDistance;
    }

    return extrapolated;
}

Voici quelques tests :

List<LatLng> route = new ArrayList<>();
route.add(new LatLng(40, 4));
route.add(new LatLng(40.1, 4));
route.add(new LatLng(40.1, 4.1));
route.add(new LatLng(40.2, 4.1));
route.add(new LatLng(40.2, 4.2));
route.add(new LatLng(40.3, 4.2));
route.add(new LatLng(40.3, 4.3));

LatLng origin;
LatLng extrapolated;

origin = new LatLng(40.1, 4.05);
extrapolated = extrapolate(route, origin, 30000);
Log.e("Extrapolated1", "" + extrapolated); //  lat/lng: (40.25517043951189,4.2)

origin = new LatLng(40.05, 4);
extrapolated = extrapolate(route, origin, 100);
Log.e("Extrapolated2", "" + extrapolated); //  lat/lng: (40.05089932033549,4.0)

origin = new LatLng(40.05, 4);
extrapolated = extrapolate(route, origin, 50000);
Log.e("Extrapolated3", "" + extrapolated); //  lat/lng: (40.300010207449226,4.261348349980259)

origin = new LatLng(40.05, 4);
extrapolated = extrapolate(route, origin, 100000);
Log.e("Extrapolated4", "" + extrapolated); //  null (result out of the route)

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X