MySQL使用st_distance_sphere过滤行时纬度越界报错问题咨询
问题根因
报错和距离计算函数本身无关,核心是存量几何数据的坐标写入顺序和MySQL地理坐标系要求的轴顺序不匹配:
- MySQL默认的WGS84地理坐标系(SRS 4326)确实遵循EPSG标准,要求坐标顺序为「纬度在前、经度在后」,其中纬度合法范围为[-90,90],经度合法范围为[-180,180],官方文档关于轴顺序的描述没有错误,不需要修改全局轴顺序配置。
- 你查询时手动构造的点
Point(35.0872464,-106.6975887)本身参数顺序是符合要求的(35.08为北纬值、-106.69为西经值),但表中spatialdata字段存储的Polygon数据,写入时所有坐标点都按「经度在前、纬度在后」的顺序传参,导致存储的几何对象第一个维度全是-106左右的经度值。 - 调用
ST_Centroid计算面的质心时,返回的质心点第一个坐标为-106.646665(本质是经度平均值),被st_distance_sphere识别为纬度值,超出合法范围直接触发报错。
解决方案
根据你是否能修改存量数据,二选一即可:
方案1:修正存量数据(长期推荐)
使用MySQL自带的ST_SwapXY函数批量交换表中所有几何对象的坐标维度,把顺序统一调整为「纬度在前、经度在后」,后续新增数据也严格按这个顺序构造,即可直接复用原有查询逻辑。
操作前务必备份表数据,更新语句如下:
UPDATE geo SET spatialdata = ST_SwapXY(spatialdata);
数据修正后,原查询语句可正常执行:
SELECT * FROM geo WHERE st_distance_sphere(Point(35.0872464,-106.6975887), ST_Centroid(`spatialdata`)) <= 1609*10;
方案2:查询时临时转换顺序(适合无法修改存量数据的场景)
如果不能改动表中已存数据,可以在计算距离前,临时交换质心结果的坐标维度,匹配轴顺序要求,示例语句:
SELECT * FROM geo WHERE st_distance_sphere( Point(35.0872464,-106.6975887), ST_SwapXY(ST_Centroid(`spatialdata`)) -- 交换质心的XY坐标,对齐lat-long顺序 ) <= 1609*10;
注意:如果几何字段未绑定地理SRS,MySQL会按平面几何规则处理,默认坐标顺序为X(经度)在前、Y(纬度)在后,只有绑定地理SRS时才会强制校验纬度-经度顺序。
内容的提问来源于stack exchange,提问作者kms
相关产品推荐
相关产品推荐

