PostgreSQL 13:如何计算一组geography点的总球面距离?
PostGIS计算Geography点序列的总球面距离(Postgres v13)
问题根源
你当前查询的偏差来自于将geography类型转为geometry后计算长度——虽然ST_Length的第二个参数TRUE会启用球面计算,但geometry的球面计算是基于球体近似,而geography类型本身基于WGS84椭球,长距离下椭球计算的精度远高于球体近似,这就是偏差的核心原因。
核心结论
ST_MakeLine完全支持geography类型的点,不需要转成geometry。直接基于geography类型构建线并计算长度,就能得到精确的椭球面总距离(单位为米)。
正确查询语句
SELECT ST_Length(ST_MakeLine(lh.position ORDER BY report_time)) AS total_distance_meters FROM location_history AS lh WHERE lh.device_id = 1 AND lh.report_time BETWEEN '2022-10-10T13:25:00.000Z' AND '2022-10-11T13:25:00.000Z' GROUP BY lh.device_id;
ST_MakeLine(lh.position ORDER BY report_time):直接用geography(Point)类型的点按时间排序,生成geography(LineString)对象ST_Length对geography线计算时,默认采用WGS84椭球算法,结果单位为米,精度适配长距离场景
备选方案:逐段距离累加
如果需要查看相邻点的分段距离,可结合LAG窗口函数实现:
SELECT SUM(ST_Distance(lh.position, LAG(lh.position) OVER (PARTITION BY lh.device_id ORDER BY report_time))) AS total_distance_meters FROM location_history AS lh WHERE lh.device_id = 1 AND lh.report_time BETWEEN '2022-10-10T13:25:00.000Z' AND '2022-10-11T13:25:00.000Z' GROUP BY lh.device_id;
LAG(lh.position):获取当前点的上一个时间点位置ST_Distance对两个geography点计算时,默认返回椭球面距离(单位米)SUM累加所有相邻点距离,最终结果和ST_MakeLine+ST_Length完全一致
内容的提问来源于stack exchange,提问作者demian85
相关产品推荐
相关产品推荐

