上周被甲方催得头秃,手里攥着一堆散落的形状文件(shp),还有几个巨大的 GeoPackage,得往公司的 PostGIS 数据库里塞。说实话,第一次搞这块的时候,我盯着 QGIS 里的 "Database" 面板发呆了整整两小时,脑子里全是问号。今天就把这套土法炼钢的过程捋一捋,特别是那个坑死人“坐标系统一”的问题,真不是吓唬人,我在这上面浪费了一整下午。
很多新手朋友问 geo数据库如何上传数据图 最稳的办法,我的答案很直接:别迷信那些一键脚本,先用 QGIS 手动导一遍,把底层逻辑摸透了,后面用 Shapefile 批量加载工具才不容易崩。记得我上个月做那个城市路网项目的时候,直接拿命令行跑 shp2pgsql,结果导进去的点全是散装的,连不上线。后来才发现,是源数据的 EPSG 编码没转过来。
操作起来其实不复杂,但细节魔鬼。打开 QGIS,左侧图层面板右键新建图层,选“导入矢量图层”。这里有个很隐蔽的坑,就是那个“目标字段类型”。如果你源数据里有个字段叫 id,而数据库里已经有个自增主键也叫 id,恭喜,冲突了。我建议上传前先在 Excel 里把源数据的 id 字段重命名为 source_id 之类的,省得后面排查报错排查到怀疑人生。
说到排查报错,我必须吹爆一个思路:看日志。别在那瞎猜,直接看 PostGIS 的服务器日志,红字写得很清楚。我遇到过最搞心态的一次,提示 "Invalid geometry"。当时心态崩了,拿 ST_IsValid 查了半天都没问题。最后绝望中用 QGIS 的“修复损坏几何图形”工具跑了一遍,竟然好了两个点。原来是有自相交的小毛刺,肉眼根本看不出来。这种时候,工具的容错性真的比人工检查靠谱。
再聊聊性能。数据量超过 100w 个面或者点的时候,一定要记得创建空间索引(Spatial Index)。很多人传完数据就不管了,查询的时候慢得跟牛车一样。记得执行 CREATE INDEX idx_geometries ON your_table USING GIST(geom);。别嫌麻烦,这一步能救你的命。另外,如果是批量上传,建议分块,别一口气塞 5 个 GB 的文件进去,服务器内存爆掉的时候,重启那几分钟真的让人想摔键盘。
还有一个经常被忽略的点:属性表的空值处理。GIS 数据和关系型数据库最大的区别就是,地理信息允许空值,但很多统计需求不允许。我在导入前通常会加一步清洗,把关键属性列的 Null 值替换成 -1 或者特定标识符。不然后期做 SQL 分析的时候,WHERE value > 0 这类语句会把空值也过滤掉或者报错,到时候再回头改数据,那就是一场灾难。
说到这,不得不提一下坐标系的坑。我那个路网项目,源数据是 WGS84 (4326),目标库是 CGCS2000 (4490)。虽然看起来只差 2 号,但直接导进去是绝对不行的。必须在 QGIS 里先投影转换,或者在导入配置里勾选“转换坐标参考系”。我有一回偷懒没转,结果所有路网都漂移了个几公里,跟城市边界完全对不上,那天真的想抽自己。
最后总结一下 gis数据导入 的核心心法:先小后大,先单后多。先导 100 条数据进去验证坐标系、字段映射、索引是否生效。没问题了,再上全量数据。千万别觉得“反正都是数据,应该都一样”,这种想法是GIS人最大的敌人。
其实 空间数据库批量加载 并没有想象中那么高大上,它就是一项体力活加细心活。工具只是辅助,你对数据结构的理解才是关键。多备份,多检查日志,遇到报错先别急,90% 的问题都是坐标系或者主键冲突引起的。
对了,还有个冷知识,如果你的 shp 文件后缀是 .shp、.shx、.dbf 三个文件,别删掉 .shx 和 .dbf,它们是索引和属性文件,少了任何一个,导入都是不完整的。我以前犯过这种低级错误,导进去全是空的点,查了半天代码,最后发现是文件缺胳膊少腿。
希望这些踩坑经验能帮大家省点时间。技术这东西,都是在报错堆里滚出来的。下次遇到 geo数据库如何上传数据图 的难题,记得回头看看这篇,说不定能帮你避开那几个深坑。