MySQL GIS Lat/Lon到X/Y:哪个是哪个?

erj*_*ang 8 mysql gis gps coordinate

是否存在关于MySQL中的GIS点应该存储为POINT($latitude $longitude)或者POINT($longitude $latitude)?的约定?

如果经度与笛卡尔地图上的X相对应,那么从北向上看会更有意义,但常见的说法是说"纬度和经度".

ame*_*der 6

在MySQL中,您可能会使用该GeomFromText()函数在空间字段中插入数据.此函数使用WKT(已知文本)格式来定义几何,在POINT情况下,它定义为:

POINT ($longitude $latitude)
Run Code Online (Sandbox Code Playgroud)


小智 5

对于在 MySQL 8+ 中使用 GPS 坐标,接受的答案是不正确的,并且它会遇到麻烦(尚未使用以前版本的 MySQL 进行测试)。

TL;博士; 在 MySQL 8+ 中,使用“POINT($lat $long)”作为 WKT 字符串,但使用 POINT($long, $lat) 与 POINT() 函数。

完整答案:

在使用 SRID 4326(您应该用于 GPS 坐标系的)时使用 WKT 表示法作为“POINT($longitude $latitude)”会导致不正确的距离计算,即使在整个应用程序中一致使用也是如此。请继续阅读以了解详细信息。

例如,让我们考虑一下多伦多的加拿大国家电视塔和纽约的世界贸易中心一号大楼之间的直接距离约为。根据谷歌地图549,18公里。

GPS坐标:

  • 加拿大国家电视塔: 43.64386666880877, -79.38670551139633
  • 世界贸易中心一号大楼:40.689321781458446、-74.04415571126154

预计距离:549.18km

以下查询产生正确的结果:

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)
Run Code Online (Sandbox Code Playgroud)

但是,如果您首先在 WKT 中提供经度(按照已接受的答案中的建议),您会计算出错误的距离:

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)
Run Code Online (Sandbox Code Playgroud)

正如您所看到的,POINT($long $lat) WKT 字符串方法是不正确的,并且偏离了大约。与POINT($lat $long)方法相比,距离为 51 公里,误差几乎为 10%。事实上,你走得越远,情况就会变得更糟。

解释:

之所以会发生这种情况,是因为当 MySQL 在 GPS 坐标上下文中考虑 WKT 字符串时,它会将第一个参数视为纬度,将第二个参数视为经度。尝试运行以下查询:

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
Run Code Online (Sandbox Code Playgroud)

但请注意,当使用 POINT(x, y) 函数而不是 WKT 字符串时,情况正好相反!

例子:

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)
Run Code Online (Sandbox Code Playgroud)