You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

MySQL 8.0 ST_Contains查询坐标顺序报错问题咨询

MySQL 5.6升级至8.0后ST_Contains查询的坐标顺序问题

我们正从MySQL 5.6升级至8.0,原有ST_Contains查询在5.6中正常运行,但在8.0及Workbench测试时返回错误:

Error Code: 3617. Latitude 127.000000 is out of range in function st_geomfromtext. It must be within [-90.000000, 90.000000].

我们在POLYGON和POINT中一直采用**x=经度(lon)、y=纬度(lat)**的格式,示例坐标均位于东南半球且所有经纬度值均在合法范围内。但从错误信息来看,系统似乎把f.lon当作纬度值进行范围校验,将坐标顺序改为x=纬度、y=经度后能得到正确结果。

疑问:WKT规范中是否应为x=经度、y=纬度?恳请相关技术解释与帮助。


复现代码

创建测试表

CREATE DATABASE  IF NOT EXISTS `tempdata`;
USE `tempdata`;
DROP TABLE IF EXISTS `sample`;
CREATE TABLE `sample` (
  `Place` char(10) NOT NULL,
  `Lat` decimal(10,8) DEFAULT NULL,
  `Lon` decimal(11,8) DEFAULT NULL,
  PRIMARY KEY (`Place`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
INSERT INTO `sample` VALUES ('IN_SE',-29.10000000,26.30000000),
('OUT_NE',29.00000000,127.00000000),
('OUT_NW',30.00000000,-120.00000000),
('OUT_SE',-45.00000000,130.00000000),
('OUT_SW',-40.00000000,-45.00000000);

查询语句

SELECT f.Place, f.Lat, f.Lon FROM tempdata.sample f
WHERE ST_Contains(ST_GeomFromText('POLYGON((
20.92061458693626 -42.957921556353014, 
8.551680010173861 -30.52917617616417, 
21.9325174415095 -19.051246698460766, 
28.12566921079717 -16.967667823403218, 
38.428497878482574 -27.255151898241817, 
35.35015222665547 -32.90654636609105, 
20.92061458693626 -42.957921556353014))', 4326), 
ST_GeomFromText(CONCAT('POINT(', f.lon, ' ', f.lat, ')'), 4326));

技术解释与解决方案

WKT规范与坐标顺序

WKT(Well-Known Text)规范中的坐标顺序并非固定为"经度在前、纬度在后",而是由空间参考系统(SRS)的定义决定。

对于常用的EPSG:4326(WGS84地理坐标系),MySQL 8.0开始严格遵循OGC(开放地理空间联盟)规范:在地理坐标系中,坐标顺序为纬度(y轴,南北方向)在前,经度(x轴,东西方向)在后。这和很多人直觉中的顺序相反,但符合OGC对地理坐标系轴顺序的定义。

MySQL 5.6对坐标顺序的校验较为宽松,即使传入"经度在前"的坐标也不会报错(但可能存在隐性计算错误);而MySQL 8.0新增了严格的坐标范围校验,当你把超过纬度范围(-90~90)的经度值放在第一个位置时,系统会将其识别为纬度,从而触发3617错误——比如测试数据中OUT_NE的经度127,就被当作纬度校验,自然超出范围。

可行解决方案

方案1:调整坐标顺序(遵循OGC规范)

将POINT和POLYGON的WKT坐标改为纬度在前、经度在后的格式:

  • 查询中的POINT构造语句改为:CONCAT('POINT(', f.lat, ' ', f.lon, ')')
  • POLYGON中的坐标也对应调整为纬度 经度的顺序,例如原坐标20.92061458693626 -42.957921556353014改为-42.957921556353014 20.92061458693626

方案2:显式指定轴顺序(兼容原有习惯)

MySQL 8.0的ST_GeomFromText支持第三个参数axis-order,可以直接指定坐标顺序为longitude-first(经度在前),无需修改坐标字符串:

SELECT f.Place, f.Lat, f.Lon FROM tempdata.sample f
WHERE ST_Contains(
  ST_GeomFromText('POLYGON((
20.92061458693626 -42.957921556353014, 
8.551680010173861 -30.52917617616417, 
21.9325174415095 -19.051246698460766, 
28.12566921079717 -16.967667823403218, 
38.428497878482574 -27.255151898241817, 
35.35015222665547 -32.90654636609105, 
20.92061458693626 -42.957921556353014))', 4326, 'longitude-first'), 
  ST_GeomFromText(CONCAT('POINT(', f.lon, ' ', f.lat, ')'), 4326, 'longitude-first')
);

注意事项

  • 若选择调整坐标顺序,需确保所有空间数据(表中存储、查询构造的)统一使用纬度在前的格式,避免后续空间计算出错。
  • 从长远兼容性考虑,建议遵循OGC规范和MySQL 8.0的默认行为,采用纬度在前的坐标顺序,减少跨系统、跨版本的适配成本。

内容的提问来源于stack exchange,提问作者Lefty

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 04:08:15