2013-04-05 23 views
5

Nella mia app "nativa" Android sto provando a calcolare la distanza in piedi e/o metri (in linea d'aria) tra due posizioni su una mappa. Idealmente ci sarebbe un metodo che prenderebbe due valori LatLng (come quello che ho prontamente disponibile) come input e restituirò la distanza in metri e/o yard. Come notato sopra sto usando Android Maps v2 API.Android Maps v2 API ... Come calcolare la distanza tra due posizioni (Lat, lunga)

Ho guardato molti messaggi (20-30) relativi al calcolo delle distanze e non ho trovato nessuno che mi abbia aiutato a risolvere il mio problema. Anche in questo caso si tratta di un'applicazione Android nativa e sto utilizzando Maps v2 API.

Non sono sicuro se questo è l'approccio migliore, ma sto attualmente cercando di utilizzare il metodo Location:

distanceBetween(double startLatitude, double startLongitude, double endLatitude, double endLongitude, float[] results) 

Ma purtroppo l'applicazione va in crash ogni volta perché ho un valore nullo per i risultati. Ho verificato tramite il debugger che i valori dummy di latitudine e longitudine in cui sto passando sono validi e che il valore di results è nullo (da qui il problema). Ecco l'LogCat:

04-04 23:48:04.770: D/onMapClick(17970): lat/lng: (32.90843038503306,-117.22537234425546) 
04-04 23:48:08.710: D/dalvikvm(17970): threadid=1: still suspended after undo (sc=1 dc=1 s=Y) 
04-04 23:48:08.710: D/dalvikvm(17970): GC_FOR_MALLOC freed 7010 objects/641712 bytes in 121ms 
04-04 23:48:24.980: D/AndroidRuntime(17970): Shutting down VM 
04-04 23:48:24.980: W/dalvikvm(17970): threadid=1: thread exiting with uncaught exception (group=0x40020950) 
04-04 23:48:25.100: E/AndroidRuntime(17970): FATAL EXCEPTION: main 
04-04 23:48:25.100: E/AndroidRuntime(17970): java.lang.IllegalArgumentException: results is null or has length < 1 
04-04 23:48:25.100: E/AndroidRuntime(17970): at android.location.Location.distanceBetween(Location.java:394) 
04-04 23:48:25.100: E/AndroidRuntime(17970): at com.example.googleplacesandmaps.PlacesMapActivity$1.onMapClick(PlacesMapActivity.java:259) 
04-04 23:48:25.100: E/AndroidRuntime(17970): at com.google.android.gms.maps.GoogleMap$6.onMapClick(Unknown Source) 
04-04 23:48:25.100: E/AndroidRuntime(17970): at com.google.android.gms.internal.t$a.onTransact(Unknown Source) 
04-04 23:48:25.100: E/AndroidRuntime(17970): at android.os.Binder.transact(Binder.java:249) 
04-04 23:48:25.100: E/AndroidRuntime(17970): at com.google.android.gms.maps.internal.IOnMapClickListener$Stub$Proxy.onMapClick(IOnMapClickListener.java:93) 
04-04 23:48:25.100: E/AndroidRuntime(17970): at maps.i.s.b(Unknown Source) 
04-04 23:48:25.100: E/AndroidRuntime(17970): at maps.y.v.c(Unknown Source) 
04-04 23:48:25.100: E/AndroidRuntime(17970): at maps.y.bf.onSingleTapConfirmed(Unknown Source) 
04-04 23:48:25.100: E/AndroidRuntime(17970): at maps.d.v.onSingleTapConfirmed(Unknown Source) 
04-04 23:48:25.100: E/AndroidRuntime(17970): at maps.d.j.handleMessage(Unknown Source) 
04-04 23:48:25.100: E/AndroidRuntime(17970): at android.os.Handler.dispatchMessage(Handler.java:99) 
04-04 23:48:25.100: E/AndroidRuntime(17970): at android.os.Looper.loop(Looper.java:123) 
04-04 23:48:25.100: E/AndroidRuntime(17970): at android.app.ActivityThread.main(ActivityThread.java:4627) 
04-04 23:48:25.100: E/AndroidRuntime(17970): at java.lang.reflect.Method.invokeNative(Native Method) 
04-04 23:48:25.100: E/AndroidRuntime(17970): at java.lang.reflect.Method.invoke(Method.java:521) 
04-04 23:48:25.100: E/AndroidRuntime(17970): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:893) 
04-04 23:48:25.100: E/AndroidRuntime(17970): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:651) 
04-04 23:48:25.100: E/AndroidRuntime(17970): at dalvik.system.NativeStart.main(Native Method) 

Ecco il metodo Attualmente sto usando per cercare di calcolare la distanza:

  Location.distanceBetween(Double.parseDouble(user_latitude), Double.parseDouble(user_longitude), 
       fxdLatitude, fxdLongitude, results); 

Il results è stata definita come una variabile di classe: private float[] results = null;

Non certo cosa sto facendo di sbagliato qui.

Ancora una volta preferisco un metodo che prenda due LatLng come parametri di input perché sono entrambi prontamente disponibili ... ma forse più importante ho solo una delle posizioni disponibili come valori separati di Longitudine, Latitudine ... la seconda posizione è disponibile solo come valore LatLng perché la ottengo tramite onMapClick (quando l'utente tocca la schermata). Quindi, per utilizzare il metodo distanceBetween, avrei bisogno di un po 'di tempo per convertire questo valore LatLng in una coppia Latitude/Longitude per poterlo usare. Qualcuno sa come farlo?

Speriamo che ci sia un modo semplice per calcolare le distanze e un modo semplice per "estrarre" la latitudine/longitudine da un valore LatLng.

risposta

1

private float[] results = null; è errato.

È necessario utilizzare private float[] results = new float[1]; e leggere la distanza con results[0].

3

È possibile utilizzare la seguente funzione che accetta due LatLng per calcolare la distanza tra di loro. Ma prima di usare questo assicurati che le tue variabili LatLng non siano nulle.

public static double distance(LatLng StartP, LatLng EndP) { 
    double lat1 = StartP.latitude; 
    double lat2 = EndP.latitude; 
    double lon1 = StartP.longitude; 
    double lon2 = EndP.longitude; 
    double dLat = Math.toRadians(lat2-lat1); 
    double dLon = Math.toRadians(lon2-lon1); 
    double a = Math.sin(dLat/2) * Math.sin(dLat/2) + 
    Math.cos(Math.toRadians(lat1)) * Math.cos(Math.toRadians(lat2)) * 
    Math.sin(dLon/2) * Math.sin(dLon/2); 
    double c = 2 * Math.asin(Math.sqrt(a)); 
    return 6366000 * c; 
} 
+0

Come arrivare raggio con centro LatLong nella Mappa di Google v2? –

+0

@KetanMehta Se si intende il raggio dell'area visibile, è possibile ottenere la vista tramite LatLngBounds bbox = GoogleMap.getProjection(). GetVisibleRegion(). LatLngBounds. Successivamente basta usare il metodo di calcolo della distanza Sharj per ottenere la distanza tra bbox.southwest e bbox.northeast (quale sarebbe il diametro del viewport). – Marco

0

Sì, penso MaciejGórski è giusto.

La distanza calcolata viene memorizzata nei risultati [0]. Se i risultati hanno lunghezza 2 o maggiore, il rilevamento iniziale viene memorizzato nei risultati [1]. Se i risultati hanno lunghezza 3 o maggiore, il rilevamento finale viene memorizzato nei risultati [2].

11

Che ne pensi di rendere oggetto Location dai due?

private float distanceBetween(LatLng latLng1, LatLng latLng2) { 

     Location loc1 = new Location(LocationManager.GPS_PROVIDER); 
     Location loc2 = new Location(LocationManager.GPS_PROVIDER); 

     loc1.setLatitude(latLng1.latitude); 
     loc1.setLongitude(latLng1.longitude); 

     loc2.setLatitude(latLng2.latitude); 
     loc2.setLongitude(latLng2.longitude); 


     return loc1.distanceTo(loc2); 
    } 
+0

Non è necessario convertire la latitudine e la longitudine poiché sono in micro gradi? – Snake

+0

se non sono in formato float (come 27.132235), devono essere convertiti. – MSaudi

+0

Interessante .. Grazie – Snake

0

In Kotlin, è possibile:

Definire un metodo per convertire LatLng a Location:

fun LatLng.toLocation() = Location(LocationManager.GPS_PROVIDER).also { 
    it.latitude = latitude 
    it.longitude = longitude 
} 

chiamarlo su ogni LatLng e utilizzare Location#distanceTo(...) metodo:

val distance = coords1.toLocation().distanceTo(coords2.toLocation()) 

Definire un metodo di estensione per LatLngBounds:

fun LatLngBounds.computeDistance(): Float { 
    return northeast.toLocation().distanceTo(southwest.toLocation()) 
} 
Problemi correlati