itinero / routing

The routing core of itinero.
Apache License 2.0
220 stars 70 forks source link

wrong DistanceEstimateInMeter if coords are close but different hemisphere #279

Open ironromeo opened 4 years ago

ironromeo commented 4 years ago

If (lon1 = 179, lat1 = 0) and (lon2=-179, lat2=0) you will get distance about 40000 km. but must be 222 km. My fix below:

var lat1Rad = (lat1 / 180d) System.Math.PI; var lon1Rad = (lon1 / 180d) System.Math.PI; var lat2Rad = (lat2 / 180d) System.Math.PI; var lon2Rad = (lon2 / 180d) System.Math.PI;

    **var lonRadDiff = Math.Abs(lon2Rad - lon1Rad);
    if (lonRadDiff > System.Math.PI) lonRadDiff -= 2 * System.Math.PI;
    var x = lonRadDiff * System.Math.Cos((lat1Rad + lat2Rad) / 2.0);**

var y = lat2Rad - lat1Rad;

        var m = System.Math.Sqrt(x * x + y * y) * EarthRadius;
juliusfriedman commented 4 years ago

Hey, thanks for pointing this out.

I made a quick unit test using your example code integrated and I still get what seems to be anomalous results:

 [Test]
        public void TestGeoCoordinateDistanceEstimateInMeter()
        {
            var coordinateStart = new Coordinate(179f, 0f);

            var coordinateEnd = new Coordinate(-179f, 0f);

            var distance = Coordinate.DistanceEstimateInMeter(coordinateStart, coordinateEnd);

            Assert.IsTrue(distance <= 223); //distance is 39807784

        }
juliusfriedman commented 4 years ago

@xivk , I tried an implementation from stack overflow and still I don't get 223 or less...

var d1 = latitude1 * (Math.PI / 180.0);
            var num1 = longitude1 * (Math.PI / 180.0);
            var d2 = latitude2 * (Math.PI / 180.0);
            var num2 = longitude2 * (Math.PI / 180.0) - num1;
            var d3 = Math.Pow(Math.Sin((d2 - d1) / 2.0), 2.0) + Math.Cos(d1) * Math.Cos(d2) * Math.Pow(Math.Sin(num2 / 2.0), 2.0);

            return (float)(6376500.0 * (2.0 * Math.Atan2(Math.Sqrt(d3), Math.Sqrt(1.0 - d3))));

But I do get 222581.844, not sure if that's exactly correct or not. Let me know what you think and I can also include this

juliusfriedman commented 4 years ago

Addressed in #302