¿Cómo puedo extrapolar más lejos por un camino?
Dado los datos de ubicación en tiempo real de un dispositivo en movimiento durante un corto período de tiempo, ¿cómo puedo obtener un par lat / long más a lo largo de este camino, por ejemplo, 2 millas, o incluso mejor, 5 minutos de conducción?
Veo que puedo usar la API de Roads de Google para encajar a un camino dado un par lat / long https://developers.google.com/maps/documentation/roads/snap , pero eso sólo me lleva a la parte.
- Límite API de Google Geocoding
- Error de Geocoder grpc
- Geocoder.getFromLocationName devuelve sólo null
- Android Geocoder obtener nombre corto del área de administración
- Obtener el contexto en una clase que implementa Runnable
Esto será en una aplicación de Android.
- ¿Cómo puedo encontrar la latitud y la longitud de la dirección?
- ¿Por qué Android Geocoder está lanzando una excepción "Servicio no disponible"?
- Cómo obtener sólo Ciudad, Estado, País de lat, largo en android
- El método isPresent () de Geocoder siempre devuelve false
- Servicio no disponible al llamar a geoCoder.getFromLocation ()
- Autocomplete la API del sitio para obtener las coordenadas GPS de la dirección ingresada
- Android geocoder ubicación inversa - forma fiable para obtener la ciudad?
- Servicio no disponible - Geocoder Android
Dada una ruta representada como una List<LatLng>
, esta función calcula el punto en la ruta que resulta de distance
desde el origin
en esa ruta (usando la Biblioteca de utilidades de la API de Google Maps para hacer algunos cálculos):
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; }
Aquí hay algunas pruebas:
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)