简介:台湾省道路数据最新分级精确到乡道矢量数据包,面向地理信息系统开发、交通规划与地图制图等专业人员,适合需要道路路网底图进行空间分析、可视化或研究台湾地区道路分级体系的场景。数据分为三个维度:城市一级至四级道路线要素,覆盖城区内部不同等级路网;高速、国道、省道、县道、乡道等行政等级道路,体现区域骨架与连接关系;另有来源于OpenStreetMap的铁路与道路图层,包含轻轨、窄轨、地铁、有轨电车及主干道、次干道、支道、人行道、住宅街道、自行车道等多种类型。16种道路数据既有重复也有互补,可相互校验与修正,便于按不同精度与用途选用,也可用于不同来源路网对比和台湾地区道路现状研究。压缩包整体约43.63MB,已被463人浏览学习,适合作为GIS底图、制图输出与路网分析的补充资料。
1. 用之前先看懂分级:从高速到乡道的道路矢量能做什么
做 GIS 的人都知道,一份「分级精确到乡道」的道路矢量数据有多难得。日常接触的免费路网要么只有主干道,要么是某个平台导出的切片,想按国道、省道、县道、乡道分级出图,要么靠人工描,要么靠关系找测绘院的朋友。这份压缩包解压之后就是一套完整的台湾地区道路 shp 数据,从高速公路一路分到乡道,导入 QGIS 或 ArcGIS 就能直接筛、直接切、直接出图,不依赖在线服务,离线环境里也能跑。对搞规划、做制图、写 WebGIS 地图服务的人,以及需要把本地路网接进自己系统的开发者,这份数据都能省掉一大半预处理时间。
这套数据真正值钱的地方是「分级」两个字。很多公开路网数据只有几何,没有道路等级字段,你想把高速和乡道分开渲染都做不到。这里的 shp 属性表里带着等级标识,按字段筛一下,就能把不同层级的路拆到独立图层。第 2 章先把 shp 的内部结构和投影坐标系讲清楚,因为后面所有筛选、导出、验证的坑,几乎都出在坐标系和编码上。
2. 数据组织与坐标系:打开 shp 前先搞清三件事
拿到 rar 压缩包,先别急着拖进 GIS 软件。shp 不是单文件,它是一组同名文件的集合,缺了任何一个都可能出问题。这一步花五分钟检查清楚,后面能省两小时排错。
2.1 shp 文件族:.shp、.dbf、.prj 各管什么
一个完整的 shapefile 至少要有 .shp(几何)、.shx(索引)、.dbf(属性)三个文件,带投影信息的还会有 .prj,带编码说明的经常有 .cpg。解压后我先按文件后缀过一遍,下面这张表是判断依据。
| 后缀 | 作用 | 缺失后果 |
|---|---|---|
| .shp | 存储点线面几何坐标 | 无法显示图形 |
| .shx | 几何位置索引 | 部分软件打不开 |
| .dbf | 属性数据,道路分级字段就在这里 | 只有图形没有属性 |
| .prj | 坐标系与投影定义 | 软件按默认坐标系猜测,容易套错 |
| .cpg | 属性编码声明 | 中文属性乱码 |
我一般习惯先把这些文件复制到一个纯英文路径的目录里,比如D:\gis\tw_road\,顺手把 dbf 用文本编辑器打开看一眼开头几行。要是 dbf 里出现「鍦嬮亾」这种乱码,说明编码没识别对,别急着改,后面第 5 章有具体解法。这里要说的重点是:字段里通常有一个列叫ROAD_CLASS、Class或RANK,存的就是高速、省道、县道、乡道这类分级代码,数字还是拼音缩写,每套数据不一样,先看字典再动手。
2.2 坐标系判断:WGS84 和 TWD97 的区别决定了你叠不叠得准
台湾地区的道路数据,常见坐标系有两种。第一种是 WGS84,经纬度坐标,单位和全球 GPS 一致,QGIS 里默认就是它,打开直接能叠在线底图上。第二种是 TWD97,这是台湾本地的地心坐标基准,常配合 TM 二度分带投影,坐标单位是米,数值看起来是几十万到三十万左右的样子。还有更老的 TWD67,和 TWD97 之间差几百米,叠图时一眼就能看出来偏了。
判断方法是打开 .prj 文件看文字描述:带GCS_WGS_1984的是经纬度,带TWD_1997_TM_2_NGA_121或类似字样的就是投影坐标。如果连 .prj 都没有,打开图层后看坐标范围——经度在 120 左右、纬度在 22 到 25 之间的,是 WGS84 没跑了;数值落在十几万到三十几万、最大不超过五十万的,是按米计的投影坐标。
QGIS 里右键图层选「图层属性 → 源」,下面有个「强制图层 CRS」按钮,可以手动指定坐标系,不用重新投影文件。注意:用「强制」只是把错的标注改掉,不改几何;真要换坐标系,得用工具箱里的「重投影图层」。这一步是后期导出 WKT 时最容易翻车的地方,第 4 章会专门讲。
3. 在 QGIS 里按分级拆层:筛选、分离和出底图
数据能正常显示了,下一步就是把不同等级的路拆出来。拆层的目的不只是好看,更是给后续每条路单独做样式、做分析打基础。你可以用「按属性选择」临时看效果,也可以用「按表达式提取要素」,一劳永逸拆出独立图层。
3.1 先用表达式摸清字段内容
打开属性表,点左上角「选择使用表达式」,先跑一句看看分级字段里到底存了什么值。假设分级字段叫Class,先统计一下有哪些取值:
-- 统计 Class 字段的去重值,确认道路分级代码 "Class" IS NOT NULL这一步在「按属性选择」里执行,选中后看底部状态栏的选中数量,再配合字段筛选逐个查看。用 QGIS 的「按字段值分组统计」更方便:菜单「处理 → 工具箱」搜「统计」,选Class作为分组字段,直接出汇总表。
实际数据里Class可能是数字(1 代表高速、2 代表省道),也可能是拼音(G、S、X、Y,分别对应国道、省道、县道、乡道),还可能直接是中文。先跑出这一张去重表,后面所有提取表达式都以它为准,这是最稳的做法。
3.2 用提取表达式拆出乡道图层
摸清取值后,用「按表达式提取要素」拆层,输出 shp 到本地目录。假设验证下来Class字段里Y代表乡道,提取表达式如下:
"Class" = 'Y'参数说明:这是精确匹配。如果字段是数字类型就别加引号,写成"Class" = 4。如果发现同一个等级在数据里有两种写法,比如Y和Y1同时存在,用 LIKE 匹配更保险:
"Class" LIKE 'Y%'逻辑说明:LIKE是按前缀模糊匹配,这样Y1、Y2都会被抓出来,适合分道编号和等级混在一个字段里的情况。提取工具会生成一个新的矢量图层,右键导出就能存成独立 shp。拆层时顺手做三件事:给每个等级分别存一个文件、文件命名带等级名、全部放在同一坐标系目录里,不然第 4 章会自食其果。
3.3 分级配色的出图小技巧
拆完层,出图就很轻松了。我一般用「图层样式 → 分类」按字段自动配五档:高速用红色宽线、国道用橙色、省道用黄色、县道用浅蓝、乡道用灰色细线。乡道数量大,显示级别调到最小,避免盖住高层级。出图前确认一下项目的 CRS 是 WGS84(EPSG:4326),因为后续如果接在线底图,CRS 不一致,图面直接错位。
4. shp 导出 WKT:把矢量数据喂给离线地图和 WebGIS
很多做前端地图和离线瓦片的人会卡在这一步:手里有 shp,但项目要的是 WKT 或 GeoJSON,没法直接读 shp。WKT 是文本格式的几何描述,PostGIS、OpenLayers、Leaflet 里都能直接吃,导出后相当于把数据做了一次格式解耦,不再依赖 GIS 软件。
4.1 先用 ogr2ogr 做批量转换
GDAL 里的ogr2ogr是最快的转换工具,一条命令就能把整个 shp 转成 WKT 文本:
ogr2ogr -f "CSV" tw_road_wkt.csv tw_road.shp -lco GEOMETRY=AS_WKT参数说明:-f "CSV"指定输出格式为 CSV,-lco GEOMETRY=AS_WKT是让几何列以 WKT 形式写入。生成的文件里每个要素一行,WKT列里就是LINESTRING (… )或MULTILINESTRING (…)这样的文本。
注意一点:CSV 输出默认不保留 CRS 信息,所以转之前要在 QGIS 里先把图层重投影到 WGS84。命令改成:
ogr2ogr -f "CSV" tw_road_wkt.csv tw_road.shp -lco GEOMETRY=AS_WKT -t_srs EPSG:4326-t_srs EPSG:4326是目标坐标系参数,加了它,转换过程会自动把 TWD97 米制坐标转成经纬度,坐标准确性由这一步保证。转完用文本编辑器打开看一眼,确认LINESTRING里的坐标是 120.x、24.x 这种格式,说明坐标系对了。
4.2 用 Python ogr 跑字段级导出
如果只想导出某个等级,或者想把道路等级一起写进 WKT,ogr2ogr 不够灵活。我一般直接用 Python 的osgeo.ogr,把 WKT 和属性一起落表:
from osgeo import ogr # 打开 shp,第二个参数 0 表示只读 ds = ogr.Open(r"D:\gis\tw_road\tw_road.shp", 0) layer = ds.GetLayer() with open(r"D:\gis\tw_road\tw_road_wkt.csv", "w", encoding="utf-8") as f: f.write("class,wkt\n") # 表头:等级与几何 for feat in layer: cls = feat.GetField("Class") geom = feat.geometry() if geom is None: continue # 空几何直接跳过,避免写坏行 wkt = geom.ExportToWkt() f.write(f"{cls},{wkt}\n") ds = None # 手动释放数据源,Windows 上不释放会锁文件逻辑说明:feat.GetField("Class")按字段名取值,geom.ExportToWkt()把几何对象序列化成 WKT 字符串。字段名对不上会直接抛异常,跑之前先打印layer.schema确认字段写法。
这段脚本默认用 shp 自带的坐标系输出 WKT。要强制转 WGS84,需要额外调用osr做坐标变换,处理思路是:源坐标系读取 shp 的 .prj,目标坐标系设 EPSG:4326,再用geom.Transform(transform)转换。导出后抽样对比几段路的经纬度数值,就能确认没偏。
4.3 导出后怎么验证数据没丢
导出完不是直接扔进项目里完事。我有个习惯:先数行数,再抽查拐点。ogr2ogr转换后,用如下命令统计 CSV 行数:
wc -l tw_road_wkt.csv行数应该和原 shp 的属性表行数一致,偏差超过 1 说明有要素因为几何为空被跳过了。再选一条熟悉的道路,比如从台北到桃园的某段高速,在 QGIS 里对比原始几何和 WKT 画出的是否一致,比如拐点数量和形状有没有收敛,偏差不超过 2 个点,说明转换无损。
5. 避坑清单:坐标系、乱码、字段截断与无图层的真凶
这套数据我踩过的坑不少,挑五个典型记录下来,照着排查能省很多时间。
坑一:整层偏移 300 米,叠在线底图上是歪的。现象:图层单独看没问题,叠加到在线卫星图后,道路和建筑明显不重合,整体平移了几百米。 原因:数据实际是 TWD97 投影坐标系,但打开时 QGIS 自动按 WGS84 识别,坐标系一错,几何数值被当成经纬度显示。 解决:右键图层选「图层属性 → 源 → 强制图层 CRS」,手动指定为 TWD97 对应的 EPSG 代码,坐标值和图面立即归位。注意是「强制」,不是「重投影」。
坑二:属性表里中文全是乱码。现象:dbf 字段里的中文路名显示成「鍙板」「閬撹」这种。 原因:dbf 的编码声明文件缺失或写的是 BIG5,QGIS 默认按 UTF-8 读,必然乱码。台湾早期数据很多是 BIG5 编码。 解决:在「图层属性 → 源 → 数据源编码」里手动改成 System(BIG5),或者改成 UTF-8,切换后立即重载属性表,再重新导出成 UTF-8 的 shp 或 CSV。
坑三:属性字段名被截断成 10 个字符。现象:本应是ROAD_CLASS_CODE,打开后变成ROAD_CLASS_,字段名不全。 原因:shapefile 的 dbf 格式规定字段名最长 10 字符,超出部分被截断。这不是数据损坏,是格式硬限制。 解决:直接用截断后的字段名写表达式,或先在 QGIS 里用「重命名字段」把名改短。写脚本时用layer.schema打印实际字段名,别凭记忆写。
坑四:乡道图层提取后要素数量骤减。现象:用"Class" = 'Y'提取乡道,结果只剩几百条,而属性表里明明有好几千。 原因:Class字段里乡道可能混着Y、Y1、Y2多种代码,精确匹配只抓到了纯Y的。 解决:改用"Class" LIKE 'Y%'模糊匹配,或先去重统计出所有取值再写表达式。这也印证了第 3 章先统计数据再动手的做法是对的。
坑五:Python 跑导出时报「Permission Denied」。现象:代码运行到一半报错,提示文件被占用,第二次跑也一样。 原因:上一次运行没有释放数据源,Windows 把 shp 文件锁住了。QGIS 开着这个图层时,脚本也是打不开的。 解决:脚本末尾必须写ds = None,运行前关闭 QGIS 里打开的同名图层。我自己后来养成的习惯是导出脚本第一行先尝试删掉旧的输出文件,代码里加一句清理逻辑,一劳永逸。
6. 最后一公里:把 WKT 数据接进路径分析和离线底图
数据转成 WKT 之后,用途一下就打开了。我最近一次是把这套路网接进一个离线物流路径分析的实验里,用 PostGIS 的pgRouting插件直接加载 WKT 文本建拓扑,跑最短路径。关键步骤是用ST_GeometryFromText把 WKT 列转成空间字段,再走pgr_createTopology建拓扑。这一步对数据质量要求很高,尤其是乡道和县道的接点必须严格共点,否则建出来的拓扑是断的,路径经常绕远路。这套数据在接点上的处理算规整,比我之前处理过某些开源路网好很多。
想快速验证数据能不能用,有个零成本的土办法:直接把 WKT 粘到在线坐标预览工具里,比如 geojson.io 的代码面板,选择 WKT 模式贴上,能正确渲染成线段就说明几何没坏。我每次处理新数据都会拿一段最复杂的乡道交叉口做测试,交叉口都没问题,整条路大概率没问题。这样验证一次,比后面跑路径规划才发现错误,效率高得多。
往后我每拿到一套矢量数据,都强制走一遍这个流程:先查字段字典,再确认坐标系,再转 WKT 抽样验几何,然后才敢接进项目。这套流程看起来很基础,但每次能挡掉不少事后返工的活。希望帮到你。
本文还有配套的精品资源,点击获取