mysqldistancehaversinespatial-query

MySQL function ST_Distance_Sphere isn't using Haversine formula?


I'm trying to calculate distances between two geographic points using MySQL, but I think ST_Distance_Sphere function is incorrect or is not using Haversine formula.

To describe this problem, I'll use these two points and this Earth radius:

Point A: 41.8902142, 12.4900422
Point B: 48.8583736, 2.2922926
Earth radius: 6378000

I've made this script in JavaScript that uses Haversine formula:

Number.prototype.toRad = function() {
    return this * Math.PI / 180;
}

const sin2 = (x) => {
    return Math.pow( Math.sin(x), 2 );
}

 function computeDistanceBetween(x1, y1, x2, y2, rad = 6378000) {
            
    const x_diff = x2 - x1;
    const y_diff = y2 - y1;

    let a = sin2(x_diff.toRad() / 2) + Math.cos(x1.toRad()) * Math.cos(x2.toRad()) * sin2(y_diff.toRad() / 2);

    a = 2 * rad * Math.asin(Math.sqrt(a))

    return a;

}

console.log(

    computeDistanceBetween(
        41.8902142, 12.4900422,
        48.8583736, 2.2922926
    ) / 1000 // Convert to Km
    
);

This script gives me this result: 1110.6415064d524447, if I check this in Google Maps, the result is approximately the same (1,109.43 km)

Now, MySQL is the problem, I'm trying to do the same with exactly that two points, but the result is very different:

SELECT 
ST_Distance_Sphere(
    POINT(41.8902142, 12.4900422), POINT(48.8583736, 2.2922926), 6378000
) / 1000 as distances

It gives me 1370.65792958018 as result, there are 260 Km of difference, so the result is very wrong, note that I'm using exactly the same points and the same radius in both cases, so MySQL is wrong or something? How can I get the same result as in JavaScript, but using spatial functions in MySQL? Thanks a lot for your help


Solution

  • Ok, this was very tricky, the function POINT receives first the longitude parameter and after receives the latitude parameter, so, the correct query should be this:

    SELECT ST_Distance_Sphere(POINT(12.4900422, 41.8902142), 
                              POINT( 2.2922926, 48.8583736), 
                              6378000                       ) /1000 as distances
    

    So this returns me 1110.641506452445 which is correct result.