Search code examples
androidgoogle-mapsgoogle-maps-android-api-2android-maps-v2

Check if current point is on route (path) and get those points from list where it matches


Next function com.google.maps.android.PolyUtil.isLocationOnPath only returns boolean value to tell if checked point (location) is on path

PolyUtil.isLocationOnPath(latLng, mPointsOfRoute, true, 10);

(https://github.com/googlemaps/android-maps-utils/blob/master/library/src/com/google/maps/android/PolyUtil.java#L158)

But I also would like to find out where this point was matched, between which points from my point list (mPointsOfRoute)

Because I need to short this route (path), remove points which were passed and make shorter route from new current position to the same destination


Solution

  • Suppose p is the Polyline and you found out that:

    PolyUtil.isLocationOnPath(latLng, mPointsOfRoute, true, 10);

    returns true, where:

    List<LatLng> mPointsOfRoute = p.getPoints();

    So, the latLng is somewhere on p.

    You can use the findIntersectingPoint() method to find the LatLong of the intersecting location.

    Just pass the List of LatLngs to this method, like this:

    LatLng intersectingLocationOnPath = findIntersectingPoint(latLng, mPointsOfRoute.get(0), mPointsOfRoute.get(mPointsOfRoute.size() - 1));

    private LatLng findIntersectingPoint(final LatLng p, final LatLng start, final LatLng end) {
        if (start.equals(end)) {
            return start;
        }
    
        final double s0lat = Math.toRadians(p.latitude);
        final double s0lng = Math.toRadians(p.longitude);
        final double s1lat = Math.toRadians(start.latitude);
        final double s1lng = Math.toRadians(start.longitude);
        final double s2lat = Math.toRadians(end.latitude);
        final double s2lng = Math.toRadians(end.longitude);
    
        double s2s1lat = s2lat - s1lat;
        double s2s1lng = s2lng - s1lng;
        final double u = ((s0lat - s1lat) * s2s1lat + (s0lng - s1lng) * s2s1lng)
                / (s2s1lat * s2s1lat + s2s1lng * s2s1lng);
        if (u <= 0) {
            return start;
        }
        if (u >= 1) {
            return end;
        }
    
        return new LatLng(start.latitude + (u * (end.latitude - start.latitude)),
                start.longitude + (u * (end.longitude - start.longitude)));
    }