Download & Extend

Views: distance calculation should not be Euclidean

Project:Geo
Component:User interface
Category:bug report
Priority:minor
Assigned:Unassigned
Status:active

Issue Summary

I'm sure this is a known issue, but I didn't see an issue raised for it yet.

Suppose you create a view, listing users and their hometowns. Suppose you add a column showing the distance from everyone's hometown to a geo target that you enter in a filter field.
If you examine the SQL query, you see the distance calculation is a modified Euclidean distance calculation:

sqrt( power((a(x1-x2)),2) + power((b(y1-y2)),2))

a and b are constants that convert a degree of longitude and latitude into meters.
Let's assume a spherical earth.
Everywhere on earth, 1 degree of latitude is 111,206m. Hence, b = 111206
But the length of 1 degree of longitude depends on how close you are to the equator:

latitude length of 1 degree longitude
0 111206
30 96307
60 55603
89 1940

Hence, the value of constant a depends on the latitude of the target geo.
This solution works well for small distances, and also for large distances near the equator. But there are a few problems with global-scale distances:

Problem 1:
If your two points are separated by significant longitude AND latitudes, you get strange results:
Barrow, Alaska, USA to Miami, Florida, USA: 9,186km
Miami, Florida, USA to Barrow, Alaska, USA: 5,750km

Problem 2:
the euclidean calculation ignores that sometimes the shorter path is to fly over the north pole.
below shows the geo-calculated distance, compared with google earth in brackets:
Barrow, Alaska, USA to Porsanger, Finmark, Norway: 6710 km (4,310 km)
Barrow, Alaska, USA to Cairo, Egypt: 18,683 km (8,744 km)

Problem 3:
Crossing the place where East meets West
- If you want to travel from Hawaii to Japan, Geo will take you across Africa.
- Somewhere in Fiji, I'm sure there's two neighbouring houses that Geo would calculate as being 40,000 kms apart.

Solution:
The correct calculation can be found at:
http://en.wikipedia.org/wiki/Great-circle_distance

I'm not sure whether to call this a bug or a feature request... the current calculation is working as-designed, so I guess this is a feature request to remove a design bug. :-)

Great module, BTW.
Thanks to all involved.

Comments

#1

oops, above I meant:

latitude    length of 1 degree longitude, in meters
========    =======================================
0            111206
30            96307
60            55603
89            1940

#2

Component:Miscellaneous» User interface
Priority:normal» minor

Err, now I remember that there are two distance calculation options...
- distance
- distance (spherical)

After testing spherical, I see it works fine.

I guess when I first selected my choice for that field, I didn't know that the two calculation names meant.
I assumed "distance" was the normal calc, and maybe "distance (spherical)" meant that it would make a bee-line through the sphere or something.

I guess the old calculation remains purely for backwards-compatability?

I suggest that a friendly explanation be added to that field, explaining that you should always use spherical.

I'm changing this to a minor UI bug.

#3

You should not _always_ use spherical. Your data may be in a projected coordinate system, in which case spherical would make no sense.

#4

Why would anyone want to calculate distances using a projeted coordinate system?
Perhaps I'm not understanding something.

If your data values represent geographical coordinates, in (longitude, latitude), then "distance spherical" is clearly the best choice.

On the other hand, if your data is truly (x,y) (as in, 2 dimensional and flat), perhaps the coordinates of 2 people on a soccer field, or perhaps the coordinates of 2 different positions in a warehouse (I dunno), then neither distance calculation makes sense for you. You wouldn't want the relative lengths of an x and y unit skewed depending on how close they were to 90. And what if your warehouse is more than 90 units long? And why would you want your answer automatically multiplied by 111206, which happens to be the exact distance in meters between 2 lines of latitude?

No, both calculations are clearly designed to calculate distances between two positions on earth, where the position is stored as (longitude, latitude) not (x,y). One calculation is accurate, the other is not. If they both exist for legacy reasons, it should be documented as such.

Perhaps some databases don't support trigonometry? That's the only other reason I can think of.

It's a minor point, but I didn't expect controversy. :-)

Actually, it's not that minor a problem... I wasted hours debugging and debating something that could have been avoided with one line of documentation where that field is set. If I fell into that trap, I'm sure others will too.

But, like I said, on the whole, great module.