Is there a convention for whether GIS points in MySQL should be stored as POINT($latitude $longitude)
or POINT($longitude $latitude)
?
Having longitude correspond to X on a cartesian map would visually make more sense with north pointing up, but common parlance is to say "latitude and longitude."
Latitude is the Y axis, longitude is the X axis. Since latitude can be positive and negative (north and south of the Equator), and longitude can be as well (negative west of Greenwich and positive eastward) when the -180 to +180 longitude system is use.
X = Longitude, Y = Latitude.
The first number is always the latitude and the second is the longitude. It easy to remember which is which if you think of the two coordinates in alphabetical terms: latitude comes before longitude in the dictionary. For example, the Empire State Building lies at 40.748440°, -73.984559°.
In MySQL you will probably use the GeomFromText()
function to insert data in a spatial field. This function uses the WKT (Well-Known Text) format to define the geometries, and in the POINT case, it is defined as:
POINT ($longitude $latitude)
The accepted answer is NOT CORRECT for working with GPS coordinates in MySQL 8+ and it will get into trouble (haven't tested it with previous version of MySQL).
TL;DR; Use 'POINT($lat $long)' as WKT string but POINT($long, $lat) with the POINT() function in MySQL 8+.
Full answer:
Using WKT notation as 'POINT($longitude $latitude)' while using SRID 4326 (the one you should use for GPS coordinates system) leads to incorrect distance calculations even if consistently used throughout the app. Read on for details.
For example, let's consider the direct distance between CN Tower in Toronto and One World Trade Center in NYC which is approx. 549,18km according to Google Maps.
GPS coordinates:
Expected distance: 549.18km
Following query yields the correct result:
SELECT
ST_DISTANCE(
ST_GEOMFROMTEXT('POINT(40.689321781458446 -74.04415571126154)', 4326),
ST_GEOMFROMTEXT('POINT(43.64386666880877 -79.38670551139633)', 4326),
'metre'
)
FROM DUAL;
-- results in 549902.432032006 meters which is around 549.9km (CORRECT)
However, if you provide longitude first in your WKT (as suggested in the accepted answer) you get a wrong distance calculated:
SELECT
ST_DISTANCE(
ST_GEOMFROMTEXT('POINT(-74.04415571126154 40.689321781458446)', 4326),
ST_GEOMFROMTEXT('POINT(-79.38670551139633 43.64386666880877)', 4326),
'metre'
)
FROM DUAL;
-- results in 601012.8595500318 which is around 601km (WRONG)
As you can see the POINT($long $lat) WKT string approach is incorrect and is off by approx. 51km compared to POINT($lat $long) approach which is almost 10% error. And it actually gets worse the farther you go.
Explanation:
It seems to happen because when MySQL considers a WKT string in the context of GPS coordinates it considers first argument as latitude and the second one as longitude. Try running the following query:
SELECT
ST_Latitude(ST_GEOMFROMTEXT('POINT(40.689321781458446 -74.04415571126154)',4326)) as latitude,
ST_Longitude(ST_GEOMFROMTEXT('POINT(40.689321781458446 -74.04415571126154)',4326)) as longitude
FROM dual;
-- results in
latitude, longitude
40.689321781458446,-74.04415571126154
Beware though, that the opposite is true when using the POINT(x, y) function instead of a WKT string!
Example:
SELECT
ST_DISTANCE(
ST_SRID(POINT(-74.04415571126154, 40.689321781458446), 4326),
ST_SRID(POINT(-79.38670551139633, 43.64386666880877), 4326),
'metre'
)
FROM DUAL;
-- results in 549902.432032006 meters which is around 549.9km (CORRECT)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With