9

MySQL中的GIS点是否应存储为POINT($latitude $longitude)或是否有约定POINT($longitude $latitude)

将经度对应于笛卡尔地图上的 X 会在视觉上使北朝上更有意义,但常见的说法是“纬度和经度”。

4

2 回答 2

8

在 MySQL 中,您可能会使用该GeomFromText()函数在空间字段中插入数据。该函数使用 WKT ( Well-Known Text ) 格式来定义几何图形,在 POINT 的情况下,它被定义为:

POINT ($longitude $latitude)
于 2010-03-15T15:36:38.130 回答
3

接受的答案对于在 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)

但是,如果您首先在 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)

如您所见,POINT($long $lat) WKT 字符串方法不正确,大约偏离了。51 公里与POINT($lat $long)方法相比,误差几乎为 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

但请注意,当使用 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)
于 2021-11-21T21:40:20.547 回答