2016-04-02 24 views
2

Ich habe eine Array-Liste, ArrayList(), die verwendet wird, um lat und lng zu speichern. Und dann wird eine Linie gezeichnet, wenn es einen neuen Punkt gibt. Ich möchte das Element innerhalb dieses Arrays erhalten, um die Gesamtdistanz zu berechnen. Aber irgendwie benutze ich die calculateDistance Methode, um die Gesamtdistanz zu berechnen, das Ergebnis ist nicht korrekt. Also möchte ich wissen, ob ich etwas falsch gemacht habe.Wie berechnet man die gesamte zurückgelegte Strecke?

private void whereAmI(){ 

    Location location = manager.getLastKnownLocation(LocationManager.GPS_PROVIDER); 
    updateWithNewLocation(location); 

    //GPS Listener 
    manager.addGpsStatusListener(gpsListener); 

    //Location Listener 
    int minTime = 0;//ms 
    int minDist = 0;//meter 
    manager.requestLocationUpdates(LocationManager.GPS_PROVIDER, minTime, minDist, locationListener); 
} 

GpsStatus.Listener gpsListener = new GpsStatus.Listener() { 
    @Override 
    public void onGpsStatusChanged(int event) { 
     switch (event) { 
      case GpsStatus.GPS_EVENT_STARTED: 
       Log.d("x=", "GPS_EVENT_STARTED"); 
       Toast.makeText(MapsActivity.this, "GPS_EVENT_STARTED", Toast.LENGTH_SHORT).show(); 
       break; 
      case GpsStatus.GPS_EVENT_STOPPED: 
       Log.d("x=", "GPS_EVENT_STOPPED"); 
       Toast.makeText(MapsActivity.this, "GPS_EVENT_STOPPED", Toast.LENGTH_SHORT).show(); 
       break; 
      case GpsStatus.GPS_EVENT_FIRST_FIX: 
       Log.d("x=", "GPS_EVENT_FIRST_FIX"); 
       Toast.makeText(MapsActivity.this, "GPS_EVENT_FIRST_FIX", Toast.LENGTH_SHORT).show(); 
       break; 
      case GpsStatus.GPS_EVENT_SATELLITE_STATUS: 
       Log.d("x=", "GPS_EVENT_SATELLITE_STATUS"); 
       break; 
     } 
    } 
}; 

LocationListener locationListener = new LocationListener(){ 
    @Override 
    public void onLocationChanged(Location location) { 
     updateWithNewLocation(location); 
    } 

    @Override 
    public void onProviderDisabled(String provider) { 
     updateWithNewLocation(null); 
    } 

    @Override 
    public void onProviderEnabled(String provider) { 

    } 

    @Override 
    public void onStatusChanged(String provider, int status, Bundle extras) { 
     switch (status) { 
      case LocationProvider.OUT_OF_SERVICE: 
       Log.v("x=", "Status Changed: Out of Service"); 
       Toast.makeText(MapsActivity.this, "Status Changed: Out of Service", Toast.LENGTH_SHORT).show(); 
       break; 
      case LocationProvider.TEMPORARILY_UNAVAILABLE: 
       Log.v("x=", "Status Changed: Temporarily Unavailable"); 
       Toast.makeText(MapsActivity.this, "Status Changed: Temporarily Unavailable", Toast.LENGTH_SHORT).show(); 
       break; 
      case LocationProvider.AVAILABLE: 
       Log.v("x=", "Status Changed: Available"); 
       Toast.makeText(MapsActivity.this, "Status Changed: Available", Toast.LENGTH_SHORT).show(); 
       break; 
     } 
    } 

}; 

private void showMarkerMe(double lat, double lng){ 
    if (markerMe != null) { 
     markerMe.remove(); 
    } 

    MarkerOptions markerOpt = new MarkerOptions(); 
    markerOpt.position(new LatLng(lat, lng)); 
    markerOpt.title("I am here!"); 
    markerMe = mMap.addMarker(markerOpt); 

    //Toast.makeText(this, "lat:" + lat + ",lng:" + lng, Toast.LENGTH_SHORT).show(); 
} 

private void cameraFocusOnMe(double lat, double lng){ 
    CameraPosition camPosition = new CameraPosition.Builder() 
      .target(new LatLng(lat, lng)) 
      .zoom(16) 
      .build(); 

    mMap.animateCamera(CameraUpdateFactory.newCameraPosition(camPosition)); 
} 

private void trackToMe(double lat, double lng){ 
    if (traceOfMe == null) { 
     traceOfMe = new ArrayList<LatLng>(); 
    } 
    traceOfMe.add(new LatLng(lat, lng)); 

    calculateDistance(traceOfMe); 

    PolylineOptions polylineOpt = new PolylineOptions(); 
    for (LatLng latlng : traceOfMe) { 
     polylineOpt.add(latlng); 
    } 

    polylineOpt.color(Color.RED); 

    Polyline line = mMap.addPolyline(polylineOpt); 
    line.setWidth(10); 
} 

private void calculateDistance(ArrayList<LatLng> points) { 

    for (int i =0; i < points.size() -1; i++) { 
     LatLng pointA = points.get(i); 
     LatLng pointB = points.get(i + 1); 
     float[] results = new float[3]; 
     Location.distanceBetween (pointA.latitude, pointA.longitude, pointB.latitude, pointB.longitude, results); 
     totalD += results[0]; 
    } 
} 

private void updateWithNewLocation(Location location) { 

    String where = ""; 
    if (location != null) { 

     double lng = location.getLongitude(); 

     double lat = location.getLatitude(); 

     float speed = location.getSpeed(); 

     long time = location.getTime(); 
     String timeString = getTimeString(time); 

     speedList.add(""+ speed); 

     where = "Lng: " + lng + 
       " Lat: " + lat + 
       " Speed: " + speed + 
       "\nTime: " + timeString + 
       " Provider: " + "gps" + 
       " Distance: " + totalD ; 


     showMarkerMe(lat, lng); 
     cameraFocusOnMe(lat, lng); 
     trackToMe(lat, lng); 

    }else{ 
     where = "No location found."; 
    } 


    txt.setText(where); 
} 
+0

Sie sagen, die Ergebnisse sind falsch, wie falsch sie sind? Kannst du ein Beispiel geben –

+0

wenn ich auf einer 140m langen Route gelaufen bin, war die berechnete Entfernung 9950m, aber irgendwie ist der Weg richtig gezeichnet. Also ich will wissen, ob meine Logik der Verwendung des obigen Codes falsch ist –

+0

;) das ist zu viel, ich gebe es einen Blick, aber es könnte einige Zeit dauern und zurück –

Antwort

1

Ich bin mir nicht sicher, wo die totalD Variable deklariert ist, aber es scheint, wie es ist, Werte mit jedem Punkt Akkumulieren Sie zur Liste hinzufügen. Nehmen wir an, Sie gehen von Punkt A zu Punkt B mit einer Entfernung von 10 Metern, also enthält Ihre ursprüngliche ArrayList nur 2 Punkte und wenn Sie die Entfernung berechnen, wird sie korrekt als 10 Meter berechnet und der GesamtD-Variable zugewiesen. Jetzt gehst du weiter, von Punkt B zu Punkt C, sage noch 5 Meter, und deine ArrayList enthält nun 3 Punkte A, B und C mit einer Gesamtdistanz von 15 Metern (10 + 5). So wie Ihre Funktion geschrieben wurde, durchlaufen Sie die Liste der Punkte und fügen sie zu total hinzu, ohne sie jemals neu festzulegen. Also, Ihr totalD hatte bereits einen Wert von 10 aus der vorherigen Berechnung, und jetzt, indem Sie die ArrayList erneut durchgehen und insgesamt 15 erhalten, addieren Sie diese 15 zu den vorherigen 10, die Sie dort von der ersten Berechnung hatten. Ihr totalD ist jetzt 25 (10 + 15, die Ergebnisse aller vorherigen Berechnungen zusammen), anstatt nur 15 (das Ergebnis nur der letzten Berechnung). Also in Ihrer calculateDistance() Methode statt

totalD += results[0]; 

Sie eine lokale Variable haben sollten, sagen tempTotalDistance, und dann alle Abstände zwischen den Punkten in sie hinzufügen und dann seinen endgültigen Wert zu Ihrem globalen totalD zuweisen. Ihre neue calculateDistance() kann in etwa so aussehen:

private void calculateDistance(ArrayList<LatLng> points) { 

    float tempTotalDistance; 

    for (int i =0; i < points.size() -1; i++) { 
     LatLng pointA = points.get(i); 
     LatLng pointB = points.get(i + 1); 
     float[] results = new float[3]; 
     Location.distanceBetween (pointA.latitude, pointA.longitude, pointB.latitude, pointB.longitude, results); 
     tempTotalDistance += results[0]; 
    } 

    totalD = tempTotalDistance; 
} 
+0

ich deklariere das totalD als globale Variable float totalD = 0f; , muss ich zuerst den TempTotalDistance als 0 initialisieren? Können Sie sagen, was ist der Unterschied zwischen Ihrer Antwort und meinem Code, pls ?? Wie ich die Logik dahinter wissen will, thz viel –

+0

ok, ich weiß was du meinst, thz eine Menge !!!!!!!!!!!! –

+0

Ich aktualisierte die Antwort mit einer ausführlichen Erklärung. Sie können Ihren Floats 0f zuweisen, wenn Sie sie deklarieren. Wenn meine Antwort korrekt ist, markieren Sie sie bitte als akzeptiert. Vielen Dank! – Levon

Verwandte Themen