ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

QGIS中CGCS2000与西安80/北京54坐标转换全流程实践

QGIS中CGCS2000与西安80/北京54坐标转换全流程实践 刚帮一个做水利规划的朋友处理完一批历史数据几十个西安80坐标的Shapefile加上几张老式地形图扫描件都要统一到CGCS2000坐标系里。QGIS在这个场景下比商业GIS软件更有优势转换参数完全透明、能自定义七参数、还能批量重投影关键是免费开源无需授权。折腾了两天把CGCS2000和西安80/北京54互转的流程彻底捋顺畅了把踩过的坑和验证方法一并写出来给遇到同样坐标转换需求的朋友做个参考。1. 认识三种坐标系统为什么不能一套参数打天下很多刚入门QGIS的朋友以为坐标转换就是换个投影方式结果直接把西安80投影坐标换成CGCS2000投影坐标跑到原数据的位置一看图层跑偏了几百米。要搞明白为什么先得把三种坐标系统的底子看清楚。1.1 椭球、基准面和参心/地心地球是个不规则的椭球体测量上我们用旋转椭球来近似它。但椭球有很多种有的偏胖、有的偏瘦只有椭球还不够还得定义这个椭球怎么摆在地球上——这就叫基准面。北京54用的是克拉索夫斯基椭球西安80用的是IAG-1975椭球CGCS2000用的是CGCS2000椭球。椭球形状不同地面上同一个点的经纬度自然不一样。更重要的是北京54和西安80都是参心坐标系什么意思简单说它们的椭球中心并不是地球质量中心而是为了照顾某一区域大地水准面人为把椭球中心挪了个位置。CGCS2000则是地心坐标系原点在地球质心。一个是“偏心模板”一个是“同心模板”两者之间必然存在一个系统性的空间偏移这个偏移要靠基准面变换来消除。1.2 三种坐标系的差异把三种坐标系的关键差异汇总成一张表做转换前最好对着表确认一下坐标系椭球原点性质常见投影精度特点北京54克拉索夫斯基参心偏心高斯-克吕格整体精度偏低局部控制点密集区尚可西安80IAG-1975参心偏心高斯-克吕格较北京54整体改善但区域差异明显CGCS2000CGCS2000椭球地心原点在地心高斯-克吕格 / 纬度-经度与WGS84接近现代测绘基准注意北京54和西安80的历史数据往往存在分区平差问题不同省份、不同测区可能套用了不同精度的控制网。这种情况下用一个全国统一的七参数做全范围转换精度很难保证通常只能保证米级甚至更差。如果你的项目要求厘米级转换最好只针对测区范围布设控制点求取局部转换参数。1.3 转换的本质两步走坐标转换不是简单把X/Y加一个固定数。从西安80投影坐标到CGCS2000投影坐标中间其实要经过三段路先把源投影坐标按源椭球和投影参数反算成大地坐标经纬度再做基准面变换把源椭球下的经纬度换算到CGCS2000椭球下的经纬度最后按CGCS2000椭球和目标投影参数正算成CGCS2000投影坐标。很多人只在第3步上动手以为换个EPSG代码就行了实际上第2步基准面变换才是关键。基准面变换最常用的是布尔莎七参数模型包含三个平移参数(dx、dy、dz)、三个旋转参数(rx、ry、rz)和一个尺度参数(ds)。有这台“模板摆正机”才能把偏心椭球的数据挪到地心椭球上。2. QGIS坐标转换的四种常用路径QGIS里做坐标转换的路子很多但要根据数据类型和工作量选。矢量图层、栅格图层的处理方式不一样单文件还是批量处理也不一样。下面这四条路径基本覆盖了日常90%的需求。2.1 矢量图层重投影处理工具箱里有个“重投影图层”Reproject Layer算法专门用来把矢量要素转到一个新CRS。它会先读取输入图层的源CRS再通过目标CRS自动计算转换路径。调用方式很简单菜单处理 - 工具箱搜索“重投影图层”设置“输入图层”为待转换的数据“目标CRS”选你要转到的CGCS2000投影坐标系统运行生成一个内存图层再右键导出另存为。需要注意QGIS的自动重投影依赖底层的PROJ库。如果源CRS和目标CRS之间没有内置的转换关系或者PROJ数据库里查不到可用的转换方法它就会弹窗问你“是否允许使用无基准面转换的近似方法”。这时候必须小心一旦选了允许近似转换基准面变换就被跳过了结果必然跑偏。2.2 另存要素时指定CRS如果只处理一两个图层直接在图层列表右键点“导出 - 要素另存为”对话框里有CRS选项。选择目标坐标系后QGIS在写文件时会执行同样的重投影逻辑。这个方法的优点是可以同时把dbf编码、格式GeoPackage、Shapefile一并处理了缺点是工作量大时不方便批处理。实际操作中我建议如果只是临时查看坐标转换后的效果优先用“重投影图层”生成临时图层确认精度没问题后再用“要素另存为”保存正式成果。2.3 栅格数据使用Warp栅格数据不能用重投影图层直接转因为栅格需要重采样。QGIS的栅格变形Warp工具封装了GDAL的warp接口可以指定源CRS、目标CRS、重采样方法还能控制输出分辨率。具体入口栅格 - 投影 - 变形Warp。在对话框里选“输入文件”设置“源CRS”如果栅格没有附带坐标参考信息需要先给栅格分配CRS设置“目标CRS”重采样方法可以用“双线性”或“三次卷积”输出分辨率如果留空会按源分辨率和转换比例自动计算实际不如手动指定一个合理值避免最后生成的栅格被拉伸得奇形怪状。栅格转换的坑主要在“源CRS又快又准”这个前提上。很多老地形图扫描件本身没有空间参考甚至只是经过简单的地理配准。这时直接Warp会失败必须先通过“栅格 - 投影 - 分配投影”把CRS钉到栅格上再执行变形。2.4 自定义CRS与Python批处理国内使用西安80/北京54的投影数据经常在QGIS的CRS选择器里找不到对应的带号或者找到了但名称显示为“未知”。这时候绝对不要硬选一个看起来像的坐标系统而是要自己定义CRS。自定义CRS在“设置 - 自定义坐标参考系统”里操作。用PROJ字符串或WKT定义定义好之后它会出现在CRS选择器的用户定义分类下。最实用的场景是当你手里有当地测绘部门提供的七参数就把这个带七参数的CRS定义进去之后所有重投影、Warp、导出操作都会优先使用你定义好的精确转换不再依赖PROJ内置的弱鸡默认。如果需要批量转换很多图层Python处理框架是最高效的。配合QgsCoordinateTransform类遍历目录下的所有矢量文件逐个转换并保存。后面实操部分我会贴一个可以直接改的脚本。3. 实操将西安80数据转换到CGCS2000的全流程下面以一个真实的项目场景走一遍流程手头有一批西安80高斯-克吕格投影的Shapefile中央经线是117°E需要转到CGCS2000的3度带高斯-克吕格投影。为了演示完整我保留了定义自定义CRS的过程。3.1 判断原数据CRS拿到一个老数据第一步不是急着转而是先搞清楚它的原始坐标系到底是什么。看三种信息.prj文件里有没有完整WKT描述图层属性里“源”选项卡有没有显示CRS从坐标值本身推断投影参数。没有.prj文件的情况很常见QGIS会显示“未知CRS”。这时可以打开属性表看坐标字段的位数和大小。比如X坐标通常是6位含500000的东偏移Y坐标可能是3位或7位说明是高斯-克吕格投影加了带号的结果。如果Y坐标前两位是“39”或“40”那大概率是3度带带号中央经线可以通过带号换算3度带中央经线带号*3。比如39带对应117°E。如果坐标是8位、6位也可能是6度带需要结合区域判断。这一步非常关键源CRS判断错了后面转换再精确也是白搭数据会飞到地球另一边。3.2 定义西安80自定义CRS含七参数没有七参数就做不了精确的基准面变换。参数怎么来最靠谱的是找当地测绘主管部门要测区的转换参数。如果实在拿不到可以在测区内找至少3个已知北京54/西安80坐标和CGCS2000坐标的控制点用坐标转换软件拟合七参数。这里必须强调七参数有区域局限性网上随便抄一套“全国通用”的参数往往不适用千万要用至少一个已知点做交叉验证。假设我已经有了测区的七参数以米、角秒、ppm为单位dx23.45, dy-112.32, dz56.78rx-0.018, ry0.024, rz-0.027ds3.8在QGIS里“设置 - 自定义坐标参考系统”名称填“Xian80 / GK CM 117E myparam”格式选PROJ字符串填入下面这段projtmerc lat_00 lon_0117 k1 x_0500000 y_00 ellpskrass unitsm no_defs towgs8423.45,-112.32,56.78,-0.018,0.024,-0.027,3.8注意这里lon_0必须与数据带的中央经线一致x_0500000是高斯克吕格投影的东偏值ellpskrass对应克拉索夫斯基椭球北京54如果处理的是西安80需要把ellps改成对应IAG-1975椭球参数通常写作a6378140 b6356755.288或者直接用ellpsIAU76然后叠加基准面参数。不同写法都行关键是椭球不能错。点“验证”如果返回“CRS有效”就可以在CRS选择器里按“USER:100001”这类ID找到它了。我在这一步曾经把旋转参数的符号搞反结果所有点都偏移了一百多米。所以强烈建议好记性不如烂笔头在自定义CRS名称里把参数来源日期写上比如Xian80_CM117_2024survey避免以后用的时候记不清是哪套参数。3.3 矢量数据转换步骤现在开始转换。把原始Shapefile拖进QGIS在图层上右键 - 图层属性 - 源如果CRS显示为“未知”就在底部点击“指定CRS”从用户定义列表里选刚才做好的Xian80_CM117_myparam菜单处理 - 工具箱搜索并打开“重投影图层”输入图层选择原始Shapefile目标CRS选择CGCS2000下对应的3度带投影比如“CGCS2000 / 3-degree Gauss-Kruger CM 117E”这里的中央经线必须也是117°E否则坐标还会错位运行得到临时图层与天地图或已有的CGCS2000参考数据叠在一起看如果偏差只有几厘米到几分米说明参数没问题确认无误后右键临时图层 - 导出 - 要素另存为选择GeoPackage格式CRS仍选CGCS2000界面保存正式成果。这里有几个细节容易踩坑QGIS里如果找不到“CGCS2000 / 3-degree Gauss-Kruger CM 117E”CRS搜索栏直接输入117一般能找到选择目标CRS时注意区分“CM 117E”和“zone 39”虽然中央经线相同但有些版本会同时列出两种命名带号版本对X坐标的处理可能不同选之前看一眼坐标系描述的公式如果勾选了“在保存时跳过几何修复”转换后可能产生无效几何建议不勾选除非数据本身有严重拓扑错误。3.4 栅格数据转换步骤处理栅格时假设我手里是一张已经地理配准过的西安80扫描地形图TIFF格式坐标系为西安80高斯投影CM 117E。第一步先给栅格分配CRS菜单“栅格 - 投影 - 分配投影”输入源栅格在CRS列表里选自定义的西安80CRS。第二步打开“栅格 - 投影 - 变形Warp”。第三步输入文件选源TIFF源CRS会自动读取刚才分配的自定义CRS目标CRS选CGCS2000对应的3度带投影。第四步重采样方法建议选“双线性”或“三次卷积”不要选“最近邻”否则地形图的等值线会出现明显锯齿。第五步输出分辨率不要留空。比如源栅格是0.5米分辨率那就填0.5如果填0GDAL可能基于边界范围计算出离谱的分辨率成图发虚或者文件超大。第六步设置输出路径运行。转换完成后在QGIS里加载与矢量成果叠加验证。栅格转换有个比较现实的问题老的扫描地形图色带丰富Warp默认的压缩算法有时会让文件体积变得巨大。可以在变形对话框的高级参数里设置创建选项compressDEFLATE和predictor2能明显减小输出文件体积。3.5 结果验证坐标转换到底准不准不能只看图形叠在一起顺眼要用数据说话。验证方法分三个层级第一层目视叠加把转换后的图层加载到已有CGCS2000成果或天地图影像底图上看道路、地块是否明显偏移第二层控制点检查在测区内找几个没参与参数拟合的已知点对比转换后坐标与其CGCS2000实测坐标之间的差值通常应不超过参数拟合精度第三层属性坐标数字化新建临时字段在属性表里用$x和$y提取转换后坐标与已知值逐一核对。我自己的习惯是转换后第一件事先量几个关键点比如地块角点、桥梁中心点记录坐标差。如果发现差值是个固定常数可能是中央经线或带号选错如果差值随位置变化通常是旋转参数问题如果差值整体呈梯度变化需要检查尺度参数。4. 常见转换错误与排查手册坐标转换的报错和异常现象通常来得很突然但只要抓住几类典型问题排查起来很快。我这两年用QGIS处理坐标系问题翻来覆去最多遇到的就是下面这五个场景。4.1 图形跑偏几百米以上这是最经典的症状。转换后所有要素整体偏移了一个固定的量比如东方向差了三四百米北方向差了几十米。原因几乎可以断定是基准面变换没生效或被跳过。排查思路先看QGIS在重投影时有没有提示“已应用近似无基准面转换”如果有肯定是跳过基准面变换了。解决方法是给源CRS配上towgs84参数或者使用PROJ数据库里定义好的转换方法。另外还要检查目标坐标系选的是不是带GK投影的CGCS2000如果选成了CGCS2000的经纬度坐标系坐标值会从七八位数直接变成一百多那是另一种跑偏。如果加七参数后跑偏问题消失说明源CRS定义基本正确。如果加完七参数还是跑偏先用处理 - 工具箱 - 重投影图层输出到临时图层在临时图层上用“测量”工具量一个已知点与目标成果控制点对比判断差值大小再回头调七参数。4.2 坐标轴顺序导致翻转QGIS 3.x对CRS轴顺序比较敏感CGCS2000的经纬度坐标系(CRS)默认是“纬度、经度”轴序但很多用户拿到的数据是“经度、纬度”如果源CRS定义成EPSG:4490这种而数据实际按先经度后纬度存储转换后图形会出现类似镜像翻转的现象点都跑到奇怪的位置。遇到这种问题先在“设置 - 选项 - 坐标系”里把“使用投影时使用默认轴顺序”关掉或者自定义CRS时在PROJ字符串末尾加axisneu强制按北-东-高顺序。更简单的做法是把源CRS改成EPSG:4490的“传统经纬度”变体比如EPSG:4463之类实测能绕开大多数轴顺序烦恼。4.3 七参数单位填错towgs84参数按顺序是三个平移(米)、三个旋转(角秒)、一个尺度(ppm)。这个“角秒”和“度”的区别我栽过一次。写参数时把0.018度填进了旋转位结果整个测区坐标像被揉搓过一样到处乱飞。排查方法很直接如果转换后坐标错乱得毫无规律先看看旋转参数是不是数量级不对。角秒对应的弧度值大约是4.848e-6度0.018角秒等于约1.0e-7度是很小的数。如果填进几十甚至几千的旋转值明显是单位错。另外尺度参数单位ppm1.5 ppm约等于每公里1.5毫米的尺度变化而不是1.5%填成1.5就会造成每公里1.5米的系统拉伸。如果不确定参数单位可以用控制点反试先只填三个平移参数旋转和尺度全填0平移参数可以有效消除大部分位置偏差再逐渐加入旋转、尺度看是否收敛。这个分段试参法比一次填全七参数更安全。4.4 自定义CRS保存后变成未知在QGIS里自定义了CRS点击“验证”提示有效但重新打开项目后图层CRS又变成“未知”或者CRS选择器里找不到刚才定义的那条。这类问题多见于使用了较新的WKT2格式语法而当前QGIS安装的PROJ库版本偏旧。解决方法自定义CRS界面里优先使用PROJ字符串而不是WKT格式。WKT虽然原生但不同PROJ版本对WKT2的支持度有差异。如果一定要用WKT可以用typecrs开头的老式WKT1兼容性更好。另外自定义CRS保存在用户配置里换了电脑或重装系统会丢失重要项目的自定义CRS建议导出为.qgis.ini或直接在Python控制台保存成.QgsCoordinateReferenceSystem代码片段下次一键重建。4.5 栅格转换后出现黑色空白Warp运行完输出的栅格一大半是黑色或透明或者边缘出现奇怪的空白。这通常是目标CRS选错、源栅格范围超出投影有效区域导致的。比如源数据中央经线是105°E目标CRS却选了117°E的投影带边缘地区的点被投影到很远的坐标生成的范围巨大且大部分没有数据。解决办法是回头检查中央经线。更稳妥的方法是设置Warp的“裁剪到目标范围”选项或者先给目标CRS指定一个合理的输出范围比如原来数据的外接矩形在目标坐标系下的合理范围。另外检查重采样扩展位数有时目标CRS的X方向坐标需要500000带号如果带了带号数据会分成两半此时需要先“去除带号”统一到不带带号的投影下再处理。最后再分享一点实战经验要我说坐标转换最大的坑不是软件不会用而是对数据的地域性和参数来源太轻信。QGIS只是执行工具它不会告诉你手上这套七参数是1980年代的老参数、还是基于最新CGCS2000网平差得到的参数。不同年代、不同区域拟合出来的参数结果能差出好几米。所以我现在的流程永远是先拿已知控制点验证参数再批量转换并且转换后立即抽查。宁可前期多花半小时做控制点核对也不要转换完全部图层再返工。另外QGIS的CRS列表里内置了很多看起来很像的坐标系统比如“Xian80 / GK CM 117E”和“Xian80 / 3-degree Gauss-Kruger CM 117E”就不是一回事前者是6度带还是3度带命名要看版本建议直接看坐标值里Y方向有没有带号来确认。这批数据最后用了三天全部转完成果叠加到CGCS2000影像底图上几乎严丝合缝。把流程写下来希望给同行省点时间。
返回列表