PostGIS中有两种常用的空间类型geometry和geography。对于GIS来说,坐标系有两种:一种是球面坐标(地理坐标),另一种是平面坐标(投影坐标)。球坐标通常用于计算,平面坐标通常用于展示(也可以计算)。
投影坐标是从球坐标投影后展开得来(用一个圆柱将地球包起来,把地球当成会发光的光源,投影后,将圆柱展开得到),投影的范围越大,精度就越低。范围越小,精度就越高。除了投影扇形的大小有区别,在不同的行业,也有不同的坐标系,例如用于测绘的坐标系。
目前用得最多的有SRID=4326球坐标,SRID为EPSG:3785的墨卡托投影坐标。
geometry支持平面对象也支持空间对象,而geography则仅支持空间对象。geometry支持更多的函数,一些几何计算的代价更低。
2 使用球坐标,通过st_distancespheroid计算两个geometry类型的球面距离。对于geometry类型,可以使用st_distancespheroid直接用球坐标计算,在计算时会自动设置这个椭球特性(SPHEROID["Krasovsky_1940",6378245.000000,298.299997264589] )。
SELECT st_distancespheroid(ST_GeomFromText('POINT(120.08 30.96)', 4326),ST_GeomFromText('POINT(120.08 30.92)', 4326), 'SPHEROID["WGS84",6378137,298.257223563]');
3 使用平面坐标,通过st_distance计算两个geometry类型的平面投影后的距离
采用精准的投影坐标(小面积投影坐标系)(但是必须要覆盖到要计算的两个点)
ST_Transform(ST_GeomFromText('POINT(120.08 30.96)', 4326), 2163 )
如果geometry值的SRID不是(高精度)目标坐标系,可以使用ST_Transform函数进行转换,转换为目标投影坐标系,再计算距离。
4 使用球坐标,通过ST_Distance计算两个geography类型的球面距离
float ST_Distance(geography gg1, geography gg2, boolean use_spheroid); -- 适用椭球体(WGS84) use_spheroid设置为ture表示使用: -- WGS84 椭球体参数定义 vspheroid := 'SPHEROID["WGS84",6378137,298.257223563]' ;
这里的XXXX就是你要选择的球坐标系SRID。在spatial_ref_sys表里可以查看各种坐标系。
5 指定SPHEROID内容,通过st_distancesphereoid计算geometry的球面距离
这种方法最为精确,但是要求了解计算距离当地的地形属性:
6 小结
计算距离时,应该考虑到需要计算的两点所在处的地球特性(spheroid)。这样计算得到的距离才是最精确的。关于geometry和geography类型的选择,建议使用geometry,既可以支持球坐标系,又可以支持平面坐标系。
欢迎关注笔者,每天分享架构干货。
,