简介:一套武汉市路网矢量数据包,面向地理信息系统、城市规划与交通分析方向的学习者及从业者,用于获取武汉市域道路网络数据并进行地图制图、空间查询、缓冲区分析、连通性计算等常见任务。压缩包共21个文件,以shp矢量主文件为核心,配以dbf属性表、prj投影参数、shx几何索引,以及sbn/sbx空间索引和xml元数据,构成可跨平台使用的完整Shapefile数据集,能在ArcGIS、QGIS中流畅加载与编辑。内容包括武汉市整体边界、区级行政边界和道路路网三个图层,既可单独提取某类要素,也支持叠加开展路网密度、行政区域衔接等分析;配合属性信息,还可按不同要素进行符号化渲染与筛选。包体约3.45MB,轻量易用,已有101人学习下载,适合GIS课程练习、毕业设计以及交通类项目预研,便于快速上手和二次开发。
1. 拿到“武汉市路网矢量数据shp文件.zip”,别急着双击拖进ArcGIS
“武汉市路网矢量数据shp文件.zip”这个压缩包,解压后往往是一堆同名不同后缀的文件,很多人第一步就做错:直接把 .shp 拖进地图文档,看到线出来就以为完工。实际上,路网矢量化数据最容易翻车的点不在“线有没有显示”,而在坐标系、字段语义和几何完整性——这三样没确认,后续做路径分析、缓冲区、转 KML、切 3DTiles 全都会被带偏。
这个数据包的典型用途有三类:做城市路网分析的底图、给 POI 或小区做道路匹配、拿来当制图要素配图。使用人群也基本是 GIS 工程师、规划分析人员和测绘相关方向的学生。你要做的第一件事,不是加载,而是打开文件组仔细看一遍,尤其是一般人忽略的 .prj 和 .cpg。下面按一条完整可复现的流程讲清楚,每一步停在哪个位置、为什么停,都会给到具体判断依据。
2. 解压后的shp文件组:五个文件各有分工,坐标系写在.prj里
2.1 .shp/.shx/.dbf/.prj/.cpg:路网数据为什么不是“一个文件”
ESRI Shapefile 表面上叫“shp 文件”,实际上是一个文件组。武汉路网这份数据解压后,你能看到的典型成员是下面这几类:
- .shp:几何本体,存储线段、节点的坐标,车道的形状全在这里
- .shx:形状索引,让软件能按要素编号快速定位
- .dbf:属性表,道路名、道路等级、宽度、方向等信息全在这个 dBASE 表里
- .prj:坐标系定义,一小段 WKT(Well-Known Text)文本,决定了坐标数字怎么解释
- .cpg:编码声明,说明 .dbf 里的属性是 UTF-8 还是 GBK
很多人拷文件只拷 .shp,结果加载报错或图层空白,就是少了 .shx 或 .dbf。还有一部分数据包会额外带 .sbn/.sbx 空间索引、.qpj(QGIS 读写的投影描述)、.xml 元数据,这些属于可选附件,删掉不影响主数据。
判断一份路网能不能用,先看文件组是否完整。我一般会在命令行里用 GDAL 自带的工具一次性确认几何类型、要素个数和坐标系,而不是靠眼睛盯 ArcGIS 的图层属性。
ogrinfo -so -al 武汉市路网.shp-so表示只输出概要,不遍历每个要素;-al表示列出全部图层。这个命令的输出大致长这样:
Layer name: 武汉市路网 Geometry: Line String Feature Count: 18642 Extent: (113.842123, 29.975674) - (114.614324, 31.210354) Layer SRS WKT: GEOGCRS["WGS 84", ENSEMBLE["World Geodetic System 1984 ensemble", MEMBER["World Geodetic System 1984 (Transit)"]], ...]输出里的Geometry是 Line String,说明这份数据按路网处理没问题;Feature Count是要素总量;Extent是经纬度包围盒。对武汉来说,坐标范围如果不在这附近,比如跑到 (117, 33) 去了,基本可以判断坐标系定义与实际坐标不一致,这时候坐标系是第一个需要人工介入的点。
2.2 看懂字段设计再做清洗:道路等级、名称、方向的常见约定
路网数据的价值一半在几何,一半在属性。武汉市路网 shp 的 .dbf 里,字段命名常见有以下几种风格,具体字段名以你手上这份为准,但语义基本一致:
| 字段含义 | 常见字段名 | 典型取值 |
|---|---|---|
| 道路名称 | NAME / ROAD_NAME | 如“解放大道” |
| 道路等级 | CLASS / GB_CODE / ROAD_CLASS | G 开头为国道,S 开头省道,X 县道,Y 乡道 |
| 车道数 | LANES / LANE_NUM | 数字 |
| 路宽 | WIDTH / ROAD_WIDTH | 单位米 |
| 单双向 | DIRECTION / ONE_WAY | 常见 1/0 或 FT/TF |
| 几何长度 | SHAPE_Leng / SHAPE_Length | ArcGIS 自动计算,注意老版本字段名会被截断成 8 位 |
注意字段名SHAPE_Leng这种拼写不是错,而是 ArcGIS 老版本字段名 8 字符截断的历史遗留。你在用ogr2ogr做筛选时,字段名里带这种不规则的拼写,写 SQL 之前最好先ogrinfo把字段列表打出来,别凭印象写。
对路网数据来说,GB_CODE这类等级字段是最容易被加工成专题图的。比如清出“G 开头”的国道和高速,作为路网分析的高等级道路子集。这个过程在下一章的筛选步骤里会用到。
2.3 武汉路网的三套坐标系来源:WGS84、CGCS2000 与当地投影坐标
坐标系是 shp 数据里最像“黑匣子”的部分。武汉市路网 shp 的来源不同,坐标系自然不同,三套最常碰到的:
- WGS84 经纬度(EPSG:4326),常见于从开放地图平台抓下来的路网,坐标单位是度
- CGCS2000 经纬度(EPSG:4490),2008 年之后测绘和国土口子的数据大多转到了这个基准
- CGCS2000 3 度带高斯-克吕格投影(中央经线 114°E,对应 EPSG 编号 4547 这个区间),武汉本地规划测量成果常用,坐标单位是米
还有一个老古董要提防:西安 80 坐标系。一些年龄较大的分区路网数据还在用,椭球参数与 CGCS2000 有差异,叠加到卫星影像上会偏几十米到上百米。判断方法很简单,看 .prj 里的DATUM写的是什么。我看 .prj 的习惯是直接打开文本编辑器扫一眼关键词:出现GCS_WGS_1984就是经纬度 WGS84,出现CGCS2000就看后面接的是Degree还是Meter。
解压后防翻车的第一步,先备份 .prj,再把 .prj 里的文字贴进记事本看一眼。如果这份路网完全没有 .prj,ArcGIS 加载时可能不报错,但坐标系是 Unknown,后续所有量算和叠加都有风险。这种情况的处理在第三章。 ## 3. 用ArcGIS/QGIS把武汉市路网加载进项目并完成投影统一 ### 3.1 加载前先做五项体检:坐标系、范围、编码、几何、字段 拿到一份路网 shp,我建议按下面的顺序做体检,而不是直接往地图里拖: 1. 用 `ogrinfo -so -al` 看坐标系和范围的墙角 2. 检查 .dbf 能不能正常读,乱码不放心的话看 .cpg 或缺 .cpg 3. 打开属性表扫一下 NAME 和等级字段的空值率 4. 把几何要素数与你预期的路网规模对比,比如武汉路网线要素上万条合理,几百条就值得怀疑 5. 检查要素有没有重叠或零长度线段,这个可用 `ogrinfo` 配合 SQL 语句快速查 这套流程的权重不是平均的。我踩过的坑里,坐标系问题占四成,编码问题占三成,几何问题占两成,剩下是一些玄学问题,比如同一份数据两个人打开表现不同。 如果想用 SQL 直接查字段空值数量,`ogrinfo` 也能干: ```bash ogrinfo -dialect sqlite -sql "SELECT COUNT(*) AS cnt FROM 武汉市路网 WHERE NAME IS NULL OR NAME = ''" 武汉市路网.shp-dialect sqlite是让 GDAL 用 SQLite 的方言来解析属性查询,支持IS NULL和字符串函数,比默认的-where更灵活。返回值里cnt不为 0,说明属性表中存在无名道路,这会影响后续按名称合并或匹配 POI。
坐标系不一致,直接改 .prj 文本是治标不治本,正确做法是重投影,这一点下面细说。 ### 3.2 投影转换两条路:图形界面单步操作与命令行批量重投影 统一投影是路网数据进入分析前的标准动作。武汉地区最常用的投影坐标系是 CGCS2000 3 度带高斯-克吕格投影,中央经线 114°E。投影转换的核心目的是把经纬度坐标换算成平面米坐标,这样缓冲区分析、长度计算才有真实意义。 在 ArcGIS 里用“投影”工具,输入要素选路网,输出坐标系选 CGCS2000 3-degree Gauss-Kruger zone 38(或者直接在搜索框输入 EPSG 4547),地理变换如果要求填,一般选默认的“无变换”,因为 WGS84 和 CGCS2000 在大部分城市尺度下差异在几十厘米到一米内,路网分析可忽略。 命令行方式适合处理几十个分幅文件的情况,用 ogr2ogr 一次转完: ```bash ogr2ogr -f "ESRI Shapefile" \ -t_srs EPSG:4547 \ -lco ENCODING=UTF-8 \ 武汉市路网_Project.shp 武汉市路网.shp参数含义:-t_srs是目标坐标系,EPSG 4547 对应中央经线 114°E 的 CGCS2000 投影带;-lco ENCODING=UTF-8是让输出 .dbf 用 UTF-8 编码,避免中文字段名和中文属性在高版本软件里显示乱码;输出文件名放在输入文件之前,这个顺序和 cp 命令相反,容易搞混。
如果输出的结果在 ArcGIS 打开后道路错位几十米,多半是源数据不是 WGS84 而是西安 80,而你没做地理变换。可以在命令行加-s_srs EPSG:4610显式声明源坐标系,再配合+towgs84参数做布尔莎七参数转换。但这个参数需要知道转换系数,不知道的情况下别乱填,先用-s_srs声明源坐标系再转,偏差通常能控制在可接受范围。
关于 EPSG 4547 的使用前提:它属于 CGCS2000 3 度带投影,如果你这份路网的字段和范围分布超出 114°E 带覆盖,比如横跨到湖南、江西边界,可以考虑用 Albers 等积投影做省级分析。武汉本市范围正好落在这个 3 度带内,EPSG 4547 是首选。 ### 3.3 按道路等级筛选出可用子集:公路代码与属性查询 武汉市路网全量数据往往要素量很大,做分析时我不建议直接用全量。更常见的是按等级字段筛出一个“高等级路网子集”,这样路网简化、连通性计算更快,也能规避细碎支路带来的拓扑噪声。 假设属性表中等级字段是 `GB_CODE`,国道和省道分别以 G 和 S 开头,用 ogr2ogr 做筛选: ```bash ogr2ogr -f "ESRI Shapefile" \ -where "GB_CODE LIKE 'G%' OR GB_CODE LIKE 'S%'" \ -lco ENCODING=UTF-8 \ 武汉高等级路网.shp 武汉市路网_Project.shp-where里的字符串用 SQL 语法,LIKE模式匹配与通用 SQL 行为一致。注意:这个操作会保留原属性表的所有字段,不会只保留被筛选出来的列。对字段进行剪裁可以用-sql配合SELECT语句,但如果只是想快速产出子集,-where已经够用。
在 ArcGIS 里对应操作是“按属性选择”,表达式写法相同。这里有个小坑:如果等级字段不是字符型而是数值型,比如 1 代表高速,2 代表国道,那么LIKE就不适用,得改成GB_CODE IN (1,2)。所以筛选前先用ogrinfo确认字段类型,数值字段用IN,字符字段用LIKE,这属于经验性的小规则。
筛选出的子集别忘了再跑一遍 `ogrinfo`,确认 Feature Count 和范围没有异常。如果筛出来的要素数只占原来的百分之几,说明字段语义和你想的不一样,先回去看属性表分布再做判断,别硬往下游送。 ## 4. 数据质量体检:几何错误、字段空值、重叠道路的修复流程 ### 4.1 路网shp最常见几何问题:自相交、悬空、重复要素 路网矢量数据与地块多边形的典型差异在于它是线要素,线要素的几何错误比面要素更隐蔽。自相交是指一条折线内部自己穿过自己,这在制图时看不出来,但做网络分析时常被算法拒绝;悬空是指在路口端点没有与另一条道路的节点完全贴合,形成一条“断头路”;重复要素则是两条道路几何完全重合,通常来自多源数据拼接。 这些几何问题的来源基本可以归到三类:第一,数据是从 DWG 图纸转换来的,设计院图纸里线条本就没有严格捕捉,转成 shp 后交点差几厘米是常态;第二,按行政边界裁剪时,切割线把道路拦腰截断,产生大量端点悬空和极短线;第三,多个区县数据拼接时,接边处重复采集。 QGIS 里查几何错误最直白的操作是“矢量菜单—几何工具—检查几何有效性”,ArcGIS 里则是“修复几何”工具。跑完之后先看错误列表定位到具体位置,再判断是删还是修。判断标准就一条:这段路在真实路网里是否物理存在,存在就修,不存在就删。 ### 4.2 用shapechk修损坏shp,用GDAL脚本批量查几何 `shapechk` 是针对 Shapefile 损坏的修复工具,处理场景是 .shp 文件头部损坏、要素读取到一半报错、打开提示“文件被锁定或已损坏”。日常工作中我一般是先用 GDAL 的命令行判断损坏范围,再决定要不要上 shapechk: ```bash ogrinfo -ro -al 武汉市路网.shp 2>&1 | tail -20-ro是只读模式,tail -20看最后 20 行输出。如果输出里大量出现ERROR和读取中断的提示,说明文件本体有问题,不是坐标系和编码的事。shapechk 的常见用法是把待修复的 shp 路径作为参数传给工具,修复后会在同目录生成修复版本,原文件可以保留作为备份。这个工具的界面和具体参数在不同版本里略有差别,你拿到手先看帮助信息,别默认所有版本都带一样的开关。
形状文件损坏时,最能救命的操作顺序是这样的:先把 .dbf 单独拷贝出来备份,再用 shapechk 修复几何文件,最后把备份的 .dbf 覆盖回去。因为shapechk的修复重点是 .shp 和 .shx,属性表如果一并重建会丢掉你之前的字段修改。 批量查几何错误,我常用一小段 Python 脚本,配合 GDAL 的 Python 绑定: ```python #!/usr/bin/env python # -*- coding: utf-8 -*- from osgeo import ogr src = ogr.Open("武汉市路网.shp", 0) # 0 表示只读 lyr = src.GetLayer(0) bad = [] for feat in lyr: geom = feat.GetGeometryRef() if geom is None: bad.append((feat.GetFID(), "空几何")) elif not geom.IsValid(): bad.append((feat.GetFID(), "无效几何")) print("问题要素数量:", len(bad)) for fid, reason in bad[:20]: print(fid, reason)IsValid()是 OGR 对 OGC 简单要素规范的实现,它会把自相交、环反转这类结构性问题判定为 False。这里注意:对于线图层,OGC 的 IsValid 判定标准和 ArcGIS 不完全一致,ArcGIS 里“线自相交”会被标记,但 OGR 的线有效性检查相对宽松。所以这个脚本定位的是比较严重的错误,细节问题还得靠 QGIS 的拓扑检查。
4.3 字段清洗:空道路名补全与等级归一化
几何修完,下来进入属性清洗。路网字段的常见毛病是同一个等级在数据里有多套写法,比如“高速”“高速公路”“G42 沪蓉高速”同时出现在 NAME 字段,而等级字段 CLASS 又全是空值。这种情况做不了统计,只能清洗。
清洗分两步走。第一步,利用 NAME 里的文本关键词推断等级。第二步,把推断结果写回等级字段。用 GDAL 的 Python 绑定做批量处理最顺手:
#!/usr/bin/env python # -*- coding: utf-8 -*- from osgeo import ogr src = ogr.Open("武汉市路网.shp", 1) # 1 表示可写 lyr = src.GetLayer(0) for feat in lyr: name = feat.GetField("NAME") or "" cls = feat.GetField("CLASS") or "" if cls == "": if name.startswith("G"): feat.SetField("CLASS", "国道") elif name.startswith("S"): feat.SetField("CLASS", "省道") else: feat.SetField("CLASS", "城市道路") lyr.SetFeature(feat) src = None print("清洗完成")GetField 返回的可能是 None,所以用or ""兜底,这是处理 shp 属性最常踩的坑之一——直接拿 None 去做 startswith 会抛异常。SetFeature之后改的是内存中的要素,必须通过lyr.SetFeature(feat)写回到图层,最后把src置为 None 触发生成新文件。
不要把字段清洗放在几何修复之前。原因很直接:如果某条路几何是坏的,你花力气给它补了属性,修复几何时这条要素一旦被重建,属性修改可能丢。属性清洗永远放在几何确认无误之后。 ## 5. 武汉路网shp处理中的5个高频问题:现象、原因、解决一条条过 ### 5.1 坐标系与编码:最容易翻车的前置问题 **问题一:加载后道路整体偏移几百米,甚至跑到海里。** 现象:ArcGIS 里叠加影像底图,路网与影像整体错位,偏移方向一致。 原因:源数据坐标是西安 80 或北京 54,.prj 里却标成 WGS84;或者实际是 CGCS2000,被默认当成 WGS84 用了。两者椭球差异在武汉地区可以造成几十米到百余米的平移。 解决:先看 .prj 文本落实源坐标系,再用 `ogr2ogr -s_srs` 显式指定源坐标系重投影。拿不准源坐标系的时候,可以采集几个明显的路口坐标,与在线地图比对,估算出偏移量后反推坐标系。 **问题二:属性表打开,道路名全是问号或乱码。** 现象:ArcGIS/QGIS 打开 .dbf,中文名称字段显示成 `???` 或 `鍖哄潡` 这类乱码。 原因:shp 的 .dbf 编码与软件读取编码不一致。常见组合是数据本是 GBK,软件按 UTF-8 读取,或者反过来。.cpg 文件缺失会加剧判断难度。 解决:用 QGIS 加载时在“数据源管理”里手动指定编码,GBK 和 UTF-8 都试一遍;命令行用 `ogr2ogr` 转存时加 `-lco ENCODING=GBK` 或 `-lco ENCODING=UTF-8` 强制指定。属性字段如果是乱码,用 Python 脚本按 `errors='ignore'` 读出来重写一遍是最彻底的方案,但工作量大,非必要不推荐。 ### 5.2 几何与数据边界:隐藏最深的两类问题 **问题三:武汉边界处道路整齐断开,出现大量极短线。** 现象:路网沿武汉市界裁切,跨界道路在边界处戛然而止,且附近存在大量长度不足几米的碎线。 原因:数据来自省级路网按市界裁剪,ArcGIS 的交集/裁剪操作会在线与边界相交处生成截断端点,碎线是裁剪工具产生的边界伪影。 解决:碎线按长度阈值删除,比如长度小于 5 米的要素批量移除。断头路如果在下游要用来做连通性分析,不能只删,要用“捕捉工具”把端点吸附到主干路节点上。QGIS 的 Snapping 工具目标图层设为主干路,容差设 5~10 米,效果可控。这条路属于常规裁切伴生问题,数据本身不坏,处理时也要同步更新几何长度字段,否则长度统计失真。 **问题四:ArcGIS 里打开正常的图层,放进 QGIS 或转成 GeoJSON 发布后,位置偏了几米到十几米。** 现象:桌面软件显示正常,Web 端偏离明显。 原因:桌面软件(尤其是 ArcGIS Pro)支持动态投影,加载后会自动按项目坐标系实时纠偏,但 shp 文件本身的坐标系并没有改动。发布到 Web 或转出 GeoJSON 时,如果目标平台不支持动态投影,就会按原坐标原样显示。 解决:出外业或发布之前,统一用 `ogr2ogr -t_srs EPSG:4326` 转成 WGS84 经纬度,或者直接转成 EPSG:3857 的 Web 墨卡托,避免在目标平台上二次投影。这个步骤别看小,省掉它你会花一下午排查偏移是哪里来的。 **问题五:数据包里有多个同名 shp 分幅文件,如 road_1、road_2,合并不了。** 现象:武汉全市路网分了多个区县文件,字段结构相同但合并后出现重复要素和属性丢失。 原因:分幅数据相互之间存在重叠带,部分道路在相邻两幅里各画了一次;字段类型在合并时被隐式转换也容易丢东西。 解决:先用 `ogr2ogr` 逐幅导入一个空的 PostgreSQL/PostGIS 表,用 `UNION ALL` 合并,再按几何去重,或者直接用 FME 的 FeatureMerger。单纯在 ArcGIS 里用“合并”工具会保留所有重叠要素,还得二次处理。以上五条覆盖了我处理城市级路网 shp 时遇到的七成问题。你手上这份武汉路网具体踩到哪一条,取决于数据生产方和流向。建议处理前先把原始压缩包复制一份留底,所有操作在副本上进行,处理错了还有后悔药。
6. 拿到的路网shp先跑一遍验证:从坐标范围到拓扑连通性
6.1 坐标边界与统计信息一次拿全
数据修整完成,最后别直接进入分析,先跑一轮验证。验证的目的是回答三个问题:坐标范围对不对、要素数量合理吗、几何有没有明显残留错误。
ogrinfo -so -al 武汉市路网_Project.shp | grep -E "Extent|Feature Count|Geometry"对武汉市全域路网来说,要素量上万是常态;范围在 (113.8, 29.9) 到 (114.6, 31.2) 附近,属于正常。如果范围经度跑到 115 度开外,大概率混入了周边城市数据。
6.2 拓扑连通性检查:悬挂点看一遍再决定动不动
路网拓扑验证用 QGIS 的 Topology Checker 插件就够了,不需要上 ArcGIS 的 Network Analyst。规则选择“必须被覆盖”或“不能有悬挂点”,容差设 0.001 度或对应米值。跑完后会列出所有悬挂点位置。
关键判断:不是所有悬挂点都要修。城市路网的尽端路、断头路是真实存在的,比如停车场入口、施工封闭路段,这类悬挂点是合法状态。需要处理的是主干路和次干路上的悬挂点,那些往往是被裁切打断的。按道路等级字段过滤后再修,效率高得多。
6.3 数据出口前的最后检查:shp转kml、shp转3dtiles前的坐标系确认
路网数据最常被转出去的两种格式是 KML 和 3DTiles。转 KML 时有个硬约束——KML 只接受 WGS84 经纬度坐标。你手上如果还是 CGCS2000 投影坐标的 shp,直接转会得到一张整体错位的网,正确做法是先用ogr2ogr -t_srs EPSG:4326转地理坐标,再导出 KML。
转 3DTiles 则反过来,需要明确投影坐标。如果你用 shp 转 3dtiles 的工具链处理武汉路网,最怕的是几何里混入异常 Z 值,生成结果会出现棱柱乱飞。转之前运行一次属性表统计,确认 Z 值范围在合理区间,或直接用“均为 0”的二维 shp 去转,能省掉大量返工。
我现在的固定习惯是:任何一份路网 shp 到手,先跑ogrinfo打印三行信息,再开属性表看一列 NAME,整个过程十分钟,但能挡掉后面一整天的排查。这个习惯也是从几次“数据看起来没问题,管线跑起来全废”的翻车里学来的,希望对你能有帮助,少走我走过的弯路。
本文还有配套的精品资源,点击获取