geo icon indicating copy to clipboard operation
geo copied to clipboard

Haversine closest point is incorrect, at least at high lattitudes?

Open jodavaho opened this issue 10 months ago • 1 comments

Please correct me if my assumptions or test is incorrect.

use geo::prelude::*;
use geo::point;
use approx::assert_abs_diff_eq;
fn main() {
    // Make sure midpoint returned when at high latitudes
    use geo::Geodesic;
    let pt_a = point!(x: 0.0, y: 80.0);
    let pt_b = point!(x: 179.99, y: 80.0);
    let ln = geo::Line::new(pt_a, pt_b);
    let d = Geodesic::distance(pt_a, pt_b);
    let midpoint = Geodesic::point_at_ratio_between(pt_a, pt_b, 0.5);
    eprintln!("the midpoint is {:?}", midpoint);
    let closest_point = {
        let closest_res = ln.haversine_closest_point(&midpoint);
        use geo::Closest::*;
        match closest_res {
            Intersection(p) => p,
            SinglePoint(p) => p,
            Indeterminate => {
                panic!("Indeterminate");
            }
        }
    };
    assert_abs_diff_eq!(closest_point.y(), midpoint.y(), epsilon = 1e-6);
    assert_abs_diff_eq!(closest_point.x(), midpoint.x(), epsilon = 1e-6);
}

Image

The returned closest point is neither the input point or on the geodesic line.

again, please correct me if I've done something incorrect here.

jodavaho avatar Mar 11 '25 20:03 jodavaho

Thank you for reporting. I agree that looks highly suspicious.

To be clear (probably you realize this), I wouldn't expect the Haversine midpoint to be exactly the same as the Geodesic midpoint (which uses Karney ellipsoids). But they should be relatively close.

I don't have a very solid intuition for spherical trigonometry, but certainly the closest point on the haversine line (great circle) between those two points should be somewhere north of the euclidean line you're seeing.

michaelkirk avatar Mar 21 '25 17:03 michaelkirk