I am developing an app which is more of a time-shift racing between your friends.
I need to calculate speed of a moving vehicle, and I don\'t want to use Locat
Omg.....
Location
Check this method - it allows you to calculate distance between 2 geo points, just divide it by your time. It should be much more accurate than yours as it calculates distances with much better approximation (WGS83 instead of using sin, cos and rest of this stuff).
Good, general idea is to keep all your data in plain units like m, s, kg etc. and make changes only for showing data to user.
I agree with Pierre, also you are rounding the results. If the points are not far enough apart, you're rounding may just provide 0. I don't see how the rounding tolerance is defined. I always calculate in meters - it makes things much easier. I'd suggest following the SI standard units in your code. Your output also shows that the timeDelta is zero, so no distance was actually calculated.
If the algorithm is correct?
The distance calculation looks like the haversine formula which is correct. (There are much faster formulas for small distances (and you only use small distances), but haversine will work)
Should I calculate in Centimeters instead of meters?
Never use centimeter, stay with SI units, the unit of speed is meter/s. just use meter as floating point (double).
Ios, where I am developping a tracking App, seems to be more friendly related to the getSpeed() nethod from Location class.
But I (again?) warn you to use speeds at slow speed. If you get an invalid speed, then just stop calculation or mark it as invalid in your app. If the GPS chip cannot deliver a valid speed, it has good reason to do so, and it's an interesting question whether you will do it better. At low speed GPS tends to randomly jump around the true position, giving 5-30m jumps. It's very likely that your self calculated speed shows much more speed that the device is (not) moving. Try to fix your app, that it does not need speeds at low speeds.
I develop MyTrails, an Android mapping and tracking app, and like you I struggled at first with the very crude location APIs Google has seen fit to include in Android.
hasSpeed() is false when the GPS chip doesn't have a good enough fix to compute speed based on dopler effect. Even when it does, I usually don't trust the speed if it's less than 5km/h or thereabouts.
The way I handle speed calculations is by using a crude low-pass filter: I record a trackpoint every second (and a minimum of 5m apart, based on LocationManager.requestLocationUpdates()
, and to calculate the recent speed, I go back a few samples to get one that is a sufficient distance apart (but no more than 30s prior), and perform the averaging you're doing.
I'm using Location.distanceBetween() for the actual distance calculation. Beware that it fails on a very small (but unfortunate) number of devices, so the haversine method you have may be a better bet. You may want to check it though, what I have is
/**
* Gets distance in meters, coordinates in RADIAN
*/
private static double getDistance(double lat1, double lon1, double lat2, double lon2) {
double R = 6371000; // for haversine use R = 6372.8 km instead of 6371 km
double dLat = lat2 - lat1;
double dLon = lon2 - lon1;
double a = Math.sin(dLat / 2) * Math.sin(dLat / 2) +
Math.cos(lat1) * Math.cos(lat2) *
Math.sin(dLon / 2) * Math.sin(dLon / 2);
//double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
return 2 * R * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
// simplify haversine:
//return 2 * R * 1000 * Math.asin(Math.sqrt(a));
}
(note the 1000 factor)