如何计算总行驶距离?
How to calculate the total distance traveled?
我有一个数组列表,ArrayList(),用来保存纬度和经度。然后当有一个新点时会画一条线。我想获取此数组中的元素,以计算总距离。但是不知何故我使用 calculateDistance 方法来计算总距离,结果不正确。所以我想知道我是不是做错了什么。
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);
}
我不确定 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;
}
我有一个数组列表,ArrayList(),用来保存纬度和经度。然后当有一个新点时会画一条线。我想获取此数组中的元素,以计算总距离。但是不知何故我使用 calculateDistance 方法来计算总距离,结果不正确。所以我想知道我是不是做错了什么。
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);
}
我不确定 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;
}