在MySQL和MariaDB中使用地理空间列类型(如POINT
(时,对于指定纬度和经度(1,2,3(的顺序有很多混乱,不同的应用程序使用不同的约定。然而,当使用某些函数(如ST_DISTANCE_SPHERE
(时,lat和long的顺序很重要。
在MySQL和MariaDB中创建POINT时,指定纬度和经度的顺序是什么
我忽略了MariaDB文档中的一个例子,并在MariaDB 10.6.7和MySQL 8.0.28上进行了测试。两个数据库返回数值相同的结果:
set @zenica = ST_GeomFromText('POINT(17.907743 44.203438)');
set @sarajevo = ST_GeomFromText('POINT(18.413076 43.856258)');
set @zenica2 = ST_GeomFromText('POINT(44.203438 17.907743)');
set @sarajevo2 = ST_GeomFromText('POINT(43.856258 18.413076)');
SELECT ST_Distance_Sphere(@zenica, @sarajevo), ST_Distance_Sphere(@zenica2, @sarajevo2);
-- Result: 55878.59337591705 67103.51207765185
所以在MySQL和MariaDB中,我们在创建POINTS时都应该使用长lat格式,即经度优先
MySQL和MariaDB返回GIS坐标的顺序是什么
当选择一个点时,MySQL和MariaDB会返回该点的二进制格式。然而,根据我使用的数据库,我会得到不同的响应:
$testCase = DB::select("SELECT ST_PointFromText('POINT(24.00 12.00)', 4326) AS samplePoint")[0];
$testUnpacked = unpack("lSRID/CByteOrder/lTypeInfo/dFirst/dSecond", $testCase->samplePoint);
var_dump($testUnpacked['First'])
# double(12) -- MySQL output
# double(24) -- MariaDB output
在MySQL中,解释取决于您在数据中使用的SRID,并遵循SRID定义的顺序,因此SRID 4326的纬度-经度。如果没有SRID(与SRID=0相同(,则使用经纬度顺序。例如,通过极点的位置,90:100可以很容易地进行检查——按照lat:lon的顺序,它是北极,按照lon:lat的顺序,这是不正确的数据,因为纬度应该在-90和90之间。
在MySQL中,您也可以使用常规的ST_Distance
来计算SRID=4326中的点之间的距离(以米为单位(,因为它正确地实现了这个地理SRID:
-- MySQL 8.0
select
-- ST_Distance_Sphere without SRID => lon lat order.
st_distance_sphere(
st_geomfromtext('point(1 90)'),
st_geomfromtext('point(100 90)')) AS dist_sphere_0,
-- ST_Distance with SRID => lat lon order.
st_distance(
st_geomfromtext('point(90 1)', 4326),
st_geomfromtext('point(90 100)', 4326)) AS dist,
-- ST_Distance_Sphere with SRID => lat lon order.
st_distance_sphere(
st_geomfromtext('point(90 1)', 4326),
st_geomfromtext('point(90 100)', 4326)) AS dist_sphere_4326;
所有这些点都返回0或非常接近0的值,因为所有这些点的纬度都是90,并描述了北极。
MariaDB不实现地理SRID AFAIK,因此它允许任何x/y值,即使SRID=4326,ST_Distance仍然返回不正确的(平面(距离,并且ST_Distance_Sphere
的顺序似乎总是经度-纬度。