南京矢量数据包全解析:SHP格式处理与坐标系转换实战
简介:这是一份覆盖南京市全域的GIS矢量数据资源包,内含市、区、县、镇、村多级行政边界,完整收录国道、省道、县道、高速、地铁轻轨、铁路及乡村道路等线状交通要素,同步整合水系、绿地、岛屿等自然地理底图,并集成公交站、地铁出入口、停车场、学校、医院、银行、餐饮、宾馆酒店等20余类POI兴趣点。资源面向GIS开发、城市规划、交通研究及地理教学人群,可直接用于空间分析、地图制图、城市研究与教学实训等场景。包体共184个文件,以shp、shx、dbf、prj等标准SHP配套格式为主,附带样式文档与工程文件,压缩包大小约11.17MB,组织规范,便于按图层快速检索与叠加分析。当前已有73人学习/下载。数据采用WGS84或CGCS2000坐标系,投影信息完整,属性表字段规范,可在ArcGIS、QGIS中直接读取使用,支持坐标转换与多种专题图制作,能有效节省基础地理数据的获取与预处理时间。 做GIS的应该都有这种体会:拿到的数据五花八门,网上找的矢量数据要么是GeoJSON,要么是带偏移的坐标,真正能直接进ArcGIS或QGIS用的SHP包反而难得。尤其是像南京这种城市,如果想做一张包含区县、乡镇街道、交通路网、水系和POI的综合底图,自己一点点去凑数据,光是坐标转换和字段整理就够折腾好几天。
我前段时间正好在整理一份南京市的矢量数据包,覆盖了区县界、乡镇街道边界、道路、水系、POI等核心图层,统一输出为SHP格式。这篇就来拆一拆这个数据包的具体内容,讲一讲拿到SHP之后要怎么处理、怎么转换、怎么避坑。适合刚接触GIS数据、或者正在做城市级项目但苦于数据整理的同学,已经有基础的朋友也能从里面的坐标系、字段陷阱这些细节里找到点有用的东西。
1. 数据包整体设计与内容拆解
1.1 图层清单与核心需求
先看这个数据包到底装了些什么。它的设计思路很明确:不追求大而全,而是围绕“城市空间分析”这个最常见的使用场景,把基础底图必备的几类要素拆成了独立图层。
| 图层名称 | 要素类型 | 主要内容 | 典型用途 |
|---|---|---|---|
| 区县界 | 面 | 南京市各区行政边界 | 行政区划统计、地图分级设色 |
| 乡镇街道界 | 面 | 街道、镇级边界 | 基层治理、网格化管理、选址分析 |
| 道路 | 线 | 高速、国道、省道、城市道路 | 路网分析、可达性计算、路径规划底图 |
| 水系 | 面/线 | 主要河流、湖泊、水库 | 水文分析、滨水空间规划、灾害评估 |
| POI | 点 | 餐饮、购物、医疗、教育、交通设施等 | 商业选址、生活圈分析、O2O场景 |
这个结构覆盖了从宏观区划到微观设施点的几个层级。做项目的时候,比如你在做门店选址,可以直接拿区县界和街道界做人口密度底图,拿道路做交通可达性,再拿POI做竞争分析,全部在同一个坐标体系下对齐,省掉了数据拼接的麻烦。
1.2 行政区划层级设计逻辑
很多人拿到SHP之后只顾着打开,很少去想边界图层是怎么组织起来的。实际上,这份数据包里区县界和乡镇街道界之间是有严格的层级关系的:每个乡镇街道的面要素都带有一个上级区县的行政代码,通过这个代码可以一键把乡镇面合并成区县面,也能反过来做属性的上卷统计。
这里有个实操心得:如果你在ArcGIS里做乡镇到区县的汇总,不要直接用“融合”工具去按名称合并,而是按行政代码字段融合。原因很简单,名称容易有重名和简称,代码是唯一的,只要代码对上,融合结果基本不会出错。在QGIS里对应的操作是Vector Geometry Tools的Dissolve,按字段选行政区代码就行。
涉及坐标系统一的问题也要提前确认。这个数据包默认是WGS84经纬度坐标,方便在Web地图和OpenStreetMap里直接叠加。但如果你要做高精度的面积计算或者距离分析,建议投影到高斯-克吕格投影(对应南京的中央经线基本是120度),否则算出来的面积误差会很明显。
2. 核心图层的属性结构与数据细节
2.1 道路图层:从画线到路网分析的跨越
道路图层是数据包里最常用也最容易出问题的图层。打开属性表你通常能看到这样几个字段:道路名称、道路等级、宽度、类型。其中道路等级直接决定了它在路网分析里的权重。
举一个我实际处理过的例子:做全市的急救服务可达性分析时,如果所有道路都按同样的速度计算,结果完全没有参考价值。正确做法是给不同等级道路设置不同的通行速度——高速公路取80到100km/h,国道60到80,省道50到60,城市次干道30到40。这些参数在QGIS的Network Analysis工具箱里都是可以预先设置好的。
道路数据里还有一个隐藏问题:拓扑关系。很多非专业来源的道路数据,在交叉口处并没有打断线条,也就是说两条路在交汇处虽然看起来相交,但在数据层面它们仍然是两条独立的线,没有节点。这样拿去做最短路径分析,车根本“开不上”另一条路。拿到数据后先做一次Planarize(在QGIS里是Split with lines,在ArcGIS里是Intersect或Feature To Line),把道路在交点处全部打断,再建拓扑关系,才能正确计算。
2.2 水系图层:面线分离和流向逻辑
水系图层一般分成面状水系和线状水系两个要素类。面状水系对应长江、玄武湖、秦淮河主干等大面积水体,线状水系则是对应的河流中心线。有些数据包里还会附带流向字段,这个字段在做水文分析时价值很高。
有个细节值得注意:处理水系数据时,如果做的是淹没模拟或洪水风险评估,千万不要直接拿面状水系的边界去分析,而要先根据DEM数据生成汇水区和河道缓冲区。因为面状水系本身的边界是静态的,代表的是常态水位,洪水时的淹没范围完全不是这个概念。如果你只是做一张普通地图,面状水系直接叠底图就行,但做专业分析时务必要明白这个区别。
还有一个实用小技巧:如果线状水系和面状水系同时存在,在地图上渲染时注意图层顺序,面状水系在下,线状水系在上,线的颜色调成比面更深的蓝色,这样可以避免河流看起来“断掉”或“双线”的问题。
2.3 POI数据:点位背后的分类体系与质量难题
POI是整个数据包里信息量最大、也最需要仔细清洗的图层。以南京为例,一份完整的POI数据会包含餐饮、购物、住宿、医疗、教育、交通设施、金融服务等大类,每个大类下面还有二级分类。比如餐饮下还会有中餐厅、西餐厅、咖啡厅等。
POI数据第一个常见问题就是分类标准不统一。不同来源的数据,分类字段的叫法五花八门,有的叫category,有的叫type,有的直接是中文大类。拿到手之后建议你做的第一件事就是统一分类字典。比如把“小吃快餐店”“面包甜点”“饮品店”归到“餐饮美食”大类,方便后续做统计出图。
第二个问题更麻烦——坐标偏移。如果你从某些互联网地图平台抓取POI,拿到的坐标是加密后的坐标系,直接叠加到WGS84底图上会偏移几百米。这就需要做坐标纠偏。转换原理不复杂,核心是已知加密前后坐标对应关系,通过采样点拟合出偏移模型。在实操中,我通常用公开的坐标转换库,把GCJ02转回WGS84,转换之后再抽查几十个点位,与高分辨率影像比对,确保误差在可接受范围内。
3. 实操:从GeoJSON到SHP的高效转换
3.1 转换工具怎么选
无论你从哪个渠道拿到GeoJSON,最后想进传统GIS软件,封装成SHP格式几乎是必经之路。转换工具我最推荐的还是GDAL里的ogr2ogr,功能稳定,命令行几秒钟就能搞定。
ogr2ogr -f "ESRI Shapefile" 南京市道路.shp 南京市道路.geojson -lco ENCODING=UTF-8这条命令做的事情,就是把GeoJSON转换成SHP,同时指定输出文件的编码为UTF-8。最后这个参数非常重要,不指定的话,默认输出是系统本地编码,中文属性值在别的电脑上打开经常乱码。
QGIS用户也可以用右键图层、导出、选择格式的方式,效果一样。但要注意,QGIS导出时如果遇到字段名超过10个字符,软件会自动截断,这一点和SHP格式本身的限制有关,后面细说。
3.2 Shapefile格式的先天限制
这个坑值得单独拿出来讲。SHP格式虽然普及,但它是上世纪80年代的设计,字段名最长只能10个字节。换句话说,如果你原来的GeoJSON里有“business_circle_name”这种字段名,转换时会被截断,可能变成“business_c”,数据损失就这么发生了。
另一个更常见的坑就是数字字段的“缩水”。GeoJSON里的数字型属性转进SHP的DBF文件后,如果字段宽度不够,小数位会被舍入,甚至大整数会变成科学计数法。网上经常有人问“POI导入文本后.0没有了”,其实就是这个原因:一个ID字段在JSON里是字符串“123456”,进到Excel或DBF后变成了数字123456,你再一列转文本,出来就变成123456.0,看起来像是多了个.0;反过来,如果你原本想保留的文本前导0也丢了,比如“025”变成“25”。
解决这个问题的办法,是在转换前就确定好字段类型。在QGIS里可以提前用Table Manager插件改字段定义,把ID字段设为字符串类型,宽度设成合适的值;在ogr2ogr里则可以用SQL语法选择字段并指定类型:
ogr2ogr -f "ESRI Shapefile" output.shp input.geojson -sql "SELECT CAST(id AS varchar(20)) AS id, name FROM input" -lco ENCODING=UTF-83.3 坐标系与投影的那些事
关于坐标系的处理,我见过太多人在这一步翻车。最简单来说,拿到数据先看PRJ文件,里面写了坐标系是什么。WGS84、GCJ02、BD09这三者之间的差别,可以这么理解:WGS84是GPS原始坐标,GCJ02是国测局加密坐标,BD09是在GCJ02基础上二次加密的百度坐标。它们之间的偏移量不是固定的,不能简单做加减。
如果你要做的项目是面向国内互联网地图展示,比如发布到百度地图或高德地图,那你得用GCJ02坐标,把SHP转成这个坐标系再出图。如果做的是学术研究或者和国际数据做叠加,WGS84就够用。QGIS里用Raster菜单下的Projections工具,或者右侧状态栏的EPSG选择器,都可以实时切换显示投影,不会改动数据本身。
特别要提醒的是,如果你做的是面积计算,务必使用投影坐标系。比如把南京市的区县边界投影到UTM 50N或CGCS2000 / 3-degree Gauss-Kruger zone 40(对应南京区域),再计算面积。用经纬度直接算面积,单位是度,结果没有任何实际意义。
4. 常见问题与排查技巧实录
4.1 POI抓取:关键词怎么定,范围怎么设
说到POI数据,很多人的第一反应是用八爪鱼这类可视化采集工具去抓百度地图或高德的POI。抓取本身不复杂,但有两个细节直接决定数据质量。
一个是关键词的选择。比如你想抓“南京餐饮POI”,不要只输一个“餐饮”关键词,这个关键词下返回的结果可能只有大型餐饮商圈,大量街边小店会被漏掉。更可靠的做法是按区域逐个网格抓取,同时把关键词拆细:中餐、火锅、烧烤、小吃、饮品分别抓一遍,再合并去重。范围也建议用矩形框或者按区县轮询,一次性请求过大的区域,平台很容易返回不全。
另一个是采集后的去重。同一个商家可能在多个关键词下重复出现,判断去重的标准不要只看名称,要“名称+坐标”联合判断。因为BD09坐标经过加密后是固定的,同一个POI即使名称略有变化,坐标基本是同一个点,相距几十米以内的同名点位应该视为重复。
4.2 数据清洗:编码乱码与字段丢失
SHP文件的中文乱码问题,我几乎每次处理数据都会碰上一两次。它的根源在于DBF文件的编码声明机制非常弱,就算你导出时写的是UTF-8,别人用ArcGIS打开时如果默认按GBK解析,一样乱码。解决的办法有两个方向:一是输出时统一用UTF-8编码,并附带说明;二是在QGIS里打开乱码数据后,右键图层、更改编码、选择GBK或UTF-8后重新加载。与其事后补救,不如一开始就用QGIS的“Save Features As”功能导出为GeoPackage格式——这个格式没有字段名长度限制,没有编码问题,唯一的门槛是老旧软件不支持读取。
字段丢失则是从Excel或CSV转SHP时的高发问题。如果你用Excel整理POI数据,记得把经纬度这两列设置成数值格式,保留足够多的小数位。而像ID这种不想被转成数字的字段,在Excel里提前设为文本格式。如果你已经导入了文本,发现ID后的.0一片,可以在Excel或WPS里通过分列功能,把该列强制转回文本,分列时可以指定每列格式,选择“文本”后整列就不会再自动加.0了。
4.3 Word/WPS表格里的POI属性小操作
顺带说一个和GIS无关但很多人问的场景:POI数据导入文本后,为什么表格里数字全变了,单元格宽度也乱七八糟。其实这是电子表格的锅,和SHP无关。在Word或WPS里粘贴POI属性表时,如果你只想要某个单元格变宽,不要整列拉,这样很容易破坏其他列排版。正确做法是选中目标单元格或整列,右键选择“表格属性”,在“列”页签里指定宽度值,单位可以直接填厘米。如果你想让某一行内容自动换行,右键选“单元格”页签,勾选“允许自动换行”就好。
5. 工具选型与工作流建议
5.1 我的默认工具链
最后分享一下我现在做这类矢量数据处理时的默认工作流。数据预览和简单编辑先用QGIS,免费、跨平台、对SHP和GeoJSON的支持都很好;批量转换统一用GDAL命令行,写个批处理脚本就能一次转几十个文件;需要做空间连接、缓冲区分析或者生成栅格时,用QGIS的Processing工具箱;做路网分析时才会切到ArcGIS Network Analyst里完成。
在这个流程里QGIS选版也有一点讲究,建议直接用长期支持版,插件兼容性和稳定性都更好,别追求尝鲜装最新版,遇到生产环境数据出问题的概率实在不值当。
5.2 数据版本管理与备份
处理这种全套的矢量数据包,版本管理同样重要。我习惯在项目目录下建立raw、process、output三个子目录。raw存放下载或抓取的原始数据,绝不修改;process目录存放清洗和转换过程中的中间文件;output目录存放最终成果。每一轮处理完,我会用压缩包打一个带有日期和项目批次标记的备份,一旦后面改坏了可以随时回退。这个习惯救过我很多次,数据量越大越能体现它的价值。
6. 一些可以继续扩展的方向
数据包拿到手之后,能做的分析其实远不止画几张图。如果你感兴趣,可以在道路和水系的基础上做一条“滨水慢行线路”的可达性评价,把水系边界提取出来做缓冲,再叠加POI里的公园、文体设施点,评价每个街道辖区的绿色空间覆盖水平。这些都是依托这个底图就能快速展开的方向。
就我个人这几年的经验来说,做GIS项目最花时间的往往不是分析本身,而是数据的前处理。一份干净、标准、坐标统一的矢量数据包,能让你在真正做分析时少走很多弯路。如果你正准备做南京区域的项目,不妨仔细看看这几个图层之间的空间关系,先把道路拓扑修好、把POI坐标纠偏,再开始后面的工作。毕竟数据底子打好了,分析结果才站得住脚。
本文还有配套的精品资源,点击获取
