JavadocMD / simplelatlng

A simple, lightweight library for common latitude and longitude calculation needs in Java.
90 stars 20 forks source link

Loss of precision when using naively as lat/long representation #11

Closed fwielstra closed 8 years ago

fwielstra commented 9 years ago
double latitude = 52.3788871765137;
double longitude = 4.90027761459351;
LatLng latLng = new LatLng(latitude, longitude);
System.out.println("Before: " + latitude + "\nAfter: " + latLng.getLatitude());

Output:

Before: 52.3788871765137
After: 52.378887
JavadocMD commented 9 years ago

Thanks for getting in touch! This is actually designed behavior: lat/lng data is represented internally as a fixed-point number with 6 decimal places. If I recall correctly, many of the more compelling reasons for this choice stem from the Geohashing feature of SimpleLatLng.

In any case, you're of course wondering if this library is suitable to your needs. I would argue that either you don't need anything below the sixth decimal place, or if you do need it, you need a different library.

0.000001 degree of latitude and longitude represents a "box" no bigger than a few centimeters on a side. So that's the resolution: in the neighborhood of a centimeter. How accurate are the distance calculations provided? The Haversine formula, which approximates the Earth as a sphere, is only accurate to around +/- 0.3%. So if you're trying to calculate distances more than a few meters apart, the margin for error is much larger than a centimeter.

In essence: I didn't want the library to lie to you about how accurate it is. When using SimpleLatLng to do calculations, everything under the sixth decimal place is essentially trash data. (You could argue for more than that, of course, but six seemed like a decent cutoff.)

fwielstra commented 8 years ago

Thanks for your clear explanation, :). In my case, the input of the lat / long is from Apple's location services, which does seem to offer that kind of accuracy. In our use case, it was more about just storing and passing around the lat/long than doing any calculations with it though. We can make our own simple container object for that, and use your library if we ever need to do calculations - taking your explanation into consideration.

JavadocMD commented 8 years ago

I would be quite surprised if an iPhone could pin-point you within a few centimeters. They just give you whichever pair of floats comes out of the calculations and, I noticed, some accuracy info (measured in meters). Floats are common and easy to work with, so I'm not saying they should do it differently.

So this is just to say I'm still confident that using SimpleLatLng in your use-case (even just for distances) it's unlikely you'd lose useful information. Thanks for the feedback!

fwielstra commented 8 years ago

Nah, not right now; the minimum accuracy you can set is in meters, which I guess is possible when combining GPS with wifi and cellular data. I do think sub-meter accuracy is possible though, when combined with beacons and, perhaps in the (near) future, other indoor location systems. I heard of a research involving LED lights in the ceiling, each emitting an individual ID (which can be linked to a location) which could be received by a smartphone camera and used to determine an accurate location (based on the angles of the lights). Probably still very experimental and not likely to become mainstream, but still - my futuristic prediction here is that future sub-meter accurate locations will become possible.