Postgres使用PostGIS计算两点距离并返回公里单位问题求助
报错根因
你当前使用的coordenate是PostgreSQL原生point类型,并非PostGIS定义的GEOMETRY类型;ST_GeomFromText()要求入参为WKT格式的字符串,直接传入原生point类型会触发类型不匹配错误。同时如果你的坐标是常规GPS经纬度(WGS84坐标系),直接调用平面ST_Distance()返回的单位是度,无法直接得到公里结果。
正确实现方案
假设你存储的坐标为WGS84坐标系(SRID=4326,经度在前、纬度在后),用户提交的坐标替换为实际值即可,可直接用以下SQL实现按距离排序、返回公里单位结果:
SELECT -- 计算距离后除以1000转为公里,保留2位小数 ROUND( ST_DistanceSphere( -- 将原生point转为PostGIS几何类型并指定坐标系 ST_SetSRID(ST_MakePoint(coordenate[0], coordenate[1]), 4326), -- 传入用户提交的坐标点,示例为北京坐标 ST_SetSRID(ST_MakePoint(116.40, 39.90), 4326) ) / 1000, 2 ) AS distance_km FROM app.location -- 按距离由近到远排序 ORDER BY distance_km ASC;
精度/性能选择说明
- 普通业务场景用上面的
ST_DistanceSphere即可,性能更高,误差控制在0.3%以内 - 如果你需要更高精度的距离计算,可以改用椭球计算方案,替换为如下写法:
SELECT ROUND( ST_Distance( ST_SetSRID(ST_MakePoint(coordenate[0], coordenate[1]), 4326)::geography, ST_SetSRID(ST_MakePoint(116.40, 39.90), 4326)::geography ) / 1000, 2 ) AS distance_km FROM app.location ORDER BY distance_km ASC;
可选优化建议
如果数据量较大查询性能不足,可以新增一个GEOMETRY类型的预计算字段,提前存储带SRID的坐标值并建立GIST索引,可大幅提升排序查询效率。
内容的提问来源于stack exchange,提问作者Alexander Álvarez
相关产品推荐
相关产品推荐

