山不就我,我来就山。
0.写在前面
参与一个室内定位的项目,有场景需要实现局部平面坐标和地理经纬度实现转换。虽然网上有C、C++、python以及java版本的代码实现,但是一方面经过测试准确性有待商榷,另一方面实现逻辑较为复杂,由于本人不是专业的Gis开发工程师,所以希望借助postgis插件本身提供的函数实现这一功能,稳定可靠。下文会围绕postgis提供的ST_Transform函数以WGS84和UTM说明不同投影、坐标系的转换。
postgresql:14.6 (linux)
postgis:3.1.3
1.准备环境
安装pg以及postgis:可以参考CentOS7 安装PostgreSQL及PostGIS扩展 - 简书
2.ST_Transform
官方文档 ST_Transform
这里使用的是geometry ST_Transform(geometry g1, integer srid);
2.1什么是SRID
空间参考标识符 (SRID) 是与特定坐标系、容差和分辨率关联的唯一标识符。
这个是ArcGIS对于srid的标准定义,理解起来就是空间坐标系的标准标识符,不同坐标系有其对应的srid,比如EPSG:4326,也就是WGS64,是很常见的一种投影坐标系,当然按照gis中严格来说,这俩是有差异,在本文的应用场景中姑且认为一致。
2.2UTM
推荐看这一篇 什么是UTM坐标系
简单理解就是将地球划分60个区,以平面直角坐标的方式描述位置的一种坐标系,看下图即可。
3.数据准备
3.1 geometry
WGS84 geometry: ST_PointFromText('POINT(116.557393208 39.785114571)',4326)
116.557393208 39.785114571分别为地理经、纬度。
3.2 srid
UTM的srid,以我现在所在区域为例:32650,后面的50即代表是东经114-120,所以不同经度的区域转换时,采用的srid是不一样的,否则很影响转换精准度。
4.验证
4.1 WGS84转UTM
select ST_Transform(
ST_PointFromText('POINT(116.557393208 39.785114571)',4326),
32650
)
结果:
POINT (462100.98723251454 4404001.154837837)
4.2 UTM转WGS84
select ST_Transform(
ST_PointFromText('POINT(462100.98723251454 4404001.154837837)',32650),
4326
)
结果:
POINT (116.55739320800001 39.78511457100001)
4.3 说明
通过带入经纬度的WGS84坐标和UTM的相互转换结果可见,误差还是极小的,可用于生产环境。
5.总结
本文是基于Postgis,对于不同空间坐标系之间转换实现,应用场景有限制,如果希望完全通过代码而非数据库插件,则可能需要更多Gis相关的专业知识以及数学公式转换的能力,我是数学苦手,实在做不来,所以采用这种取巧的方案。里面涉及Gis相关概念理解有所偏差,欢迎指正。