locationtech / spatial4j

LocationTech Spatial4j: A Geospatial Library for Java

Home Page:https://projects.eclipse.org/projects/locationtech.spatial4j

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

How to correctly calculate distances

MoeweX opened this issue · comments

Hi,

I am currently testing spatial4j and struggle with correctly calculating distances. For example, I tried to calculate the distance between Berlin and Hamburg with this:

SpatialContext ctx = SpatialContext.GEO;
Point berlin = ctx.getShapeFactory().pointXY(52.5200, 13.4050);
Point hamburg = ctx.getShapeFactory().pointXY(53.511, 9.9937);
logger.info(ctx.getDistCalc().distance(berlin, hamburg) * DEG_TO_KM);

Unfortunately, this results in ~394km when the real value is 253.4km.

As I could not find out what I was doing wrong, I looked into your test cases to see whether I can reproduce the results of the "testSomeDistances" test. So I tried this code snippet:

Point ctr = ctx.getShapeFactory().pointXY(0, 100);
logger.info(ctx.getDistCalc().distance(ctr, GEO.getShapeFactory().pointXY(10, 0)));

Unfortunately, this throws an InvalidShapeException (Bad Y value 100.0 is not in boundary Rect(minX=-180.0,maxX=180.0,minY=-90.0,maxY=90.0)), so I wonder: why is the test working?

I think you are flipping your "X" and "Y" (longitude & latitude). It's a common mistake in geo apps.... I deliberately had those methods end in "XY" to help users know the order.

Thanks for your swift response, and you are right. Now it works :), 253.4km. Maybe you should add a pointLatLong()/coordinate() method, as coordinates are normally the other way around. If you like the idea, I could create a pull request.

Nevertheless, should the test case not also throw an exception, as (0, 100) is not in boundary?

Maybe you should add a pointLatLong()

Given how common it is to have inputs latitude, longitude, that'd be a fine idea indeed. Though I prefer "pointLatLon" ("Lon" not "Long") for an abbreviated name. "Long" nomenclature interferes with 64-bit integers in common programming languages like Java.

Nevertheless, should the test case not also throw an exception, as (0, 100) is not in boundary?

Do you refer to line 45? If so, notice it's pLL(0,100); (which is not pointXY). The "LL" signifies LatLon.