PostGIS按经纬度顺序查询指定距离内数据无结果,交换顺序却正常的问题求助
兄弟,这个坑我刚入行的时候也踩过!核心原因就是你搞混了PostGIS里ST_MakePoint的参数顺序,和咱们日常说“经纬度”的习惯刚好匹配不上(或者说你插入数据的时候顺序就反了)。
先给你掰明白关键知识点:
PostGIS的ST_MakePoint函数遵循的是GIS领域的X/Y轴顺序——X在前,Y在后。而对应到咱们常用的WGS84坐标系(EPSG:4326),X轴对应经度,Y轴对应纬度,所以正常调用应该是ST_MakePoint(经度, 纬度)。
但你的情况是:用ST_MakePoint(经度, 纬度)查不到结果,换成ST_MakePoint(纬度, 经度)就有数据,这说明你插入数据的时候,把纬度当成了X参数,经度当成了Y参数——也就是存进去的点坐标是(纬度, 经度),和正确的(经度, 纬度)完全反过来了。
举个例子:你要存北京的坐标(东经116.4,北纬39.9),如果插入时写成ST_MakePoint(39.9, 116.4),那存进去的点其实是在南半球的某个位置,你查询时用ST_MakePoint(116.4, 39.9)找北京附近的数据,当然搜不到这个错位的点;但如果你查询时也写成ST_MakePoint(39.9, 116.4),就刚好匹配上存错的坐标,所以能查到。
给你两个靠谱的解决方案:
方案一:修正插入逻辑(推荐)
如果你的数据还没大规模插入,或者可以重新导入,直接把插入时的ST_MakePoint参数改成ST_MakePoint(经度, 纬度),之后查询时用同样的顺序就完全正常了。
比如插入语句改成:-- 假设你的经度字段叫lon,纬度字段叫lat INSERT INTO public.geospatial_data (geo_point, ...) VALUES (ST_SetSRID(ST_MakePoint(lon, lat), 4326), ...);方案二:适配已存的数据(如果不想重新导入)
要是已经存了大量数据不想动,有两个办法:- 查询时保持和插入一致的顺序(也就是用
ST_MakePoint(纬度, 经度)),但这样后期容易搞混,不推荐; - 把存储的坐标轴交换过来,执行一次更新语句:
执行完这个更新后,你的UPDATE public.geospatial_data SET geo_point = ST_SwapXY(geo_point);geo_point就变成正确的(经度, 纬度)顺序了,之后再用ST_MakePoint(经度, 纬度)查询就没问题了。
- 查询时保持和插入一致的顺序(也就是用
你可以先验证下自己的数据是不是存反了,执行这条SQL看一条数据的坐标:
SELECT ST_AsText(geo_point) FROM public.geospatial_data LIMIT 1;
如果结果是POINT(纬度值 经度值),那说明确实存反了,按上面的方案修正就行。
备注:内容来源于stack exchange,提问作者Olek




