2016-04-02 3 views
2

У меня есть список массивов ArrayList(), который используется для сохранения lat и lng. И тогда линия будет нарисована, когда появится новая точка. Я хочу получить элемент внутри этого массива, чтобы рассчитать общее расстояние. Но каким-то образом я использую метод вычисления расчета для вычисления общего расстояния, результат неправильный. Поэтому я хочу знать, что я сделал что-то неправильно.Как рассчитать общее пройденное расстояние?

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

Вы говорите, что результаты неверны, насколько они неправильны? можете ли вы привести пример –

+0

, когда я шел по 140-метровому маршруту, рассчитанное расстояние составляло 9950 м, но каким-то образом правильный путь. Поэтому я хочу знать, не ошибается ли моя логика использования вышеуказанного кода –

+0

;) Это слишком много, я смотрю на него, но может потребоваться некоторое время и вернуться обратно –

ответ

1

Я не уверен, где объявляется переменная totalD, но кажется, что он накапливает значения с каждой точкой вы добавляете в список. Скажем, вы идете от точки A до точки B на расстоянии 10 метров, поэтому ваш исходный ArrayList содержит только 2 точки, а когда вы вычисляете расстояние, оно правильно рассчитано как 10 метров и присваивается переменной totalD. Теперь вы идете дальше, от точки B до точки C, скажем еще 5 метров, и ваш ArrayList теперь содержит 3 балла A, B и C с общим расстоянием, которое должно быть 15 метров (10 + 5). Как ваша функция была написана, вы просматриваете список пунктов и добавляете все это в totalD, не переустанавливая ее. Таким образом, ваш totalD уже имел значение 10 из предыдущего расчета, и теперь, снова перейдя через ArrayList и получив в общей сложности 15, вы добавите 15 к предыдущим 10, которые были там из первого вычисления. Ваш totalD теперь 25 (10 + 15, результаты всех предыдущих вычислений объединены), а не просто 15 (результат только последнего вычисления). Таким образом, в методе calculateDistance() вместо

totalD += results[0]; 

вы должны иметь локальную переменную, скажем tempTotalDistance, а затем добавить все расстояния между точками в ней, а затем присвоить его конечное значение к глобальной totalD. Ваш новый calculateDistance() может выглядеть примерно так:

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

i объявить totalD как глобальную переменную float totalD = 0f; , мне нужно сначала инициализировать tempTotalDistance как 0? Можете ли вы рассказать, что отличает ваш ответ от моего кода, PLS? Как я хочу знать логику, я много знаю –

+0

нормально, я знаю, что вы имеете в виду, много! !!!!!!!!!!!! –

+0

Я обновил ответ с подробным объяснением. Вы можете назначить 0f своим поплавкам при их объявлении. Если мой ответ правильный, отметьте его как принятый. Благодаря! – Levon

Смежные вопросы