ARTICLE DETAIL

资讯详情

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

城市路网shp数据处理实战:投影转换、清洗与修复(以武汉为例)

城市路网shp数据处理实战:投影转换、清洗与修复(以武汉为例) 简介一套武汉市路网矢量数据包面向地理信息系统、城市规划与交通分析方向的学习者及从业者用于获取武汉市域道路网络数据并进行地图制图、空间查询、缓冲区分析、连通性计算等常见任务。压缩包共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坐标系定义一小段 WKTWell-Known Text文本决定了坐标数字怎么解释.cpg编码声明说明 .dbf 里的属性是 UTF-8 还是 GBK很多人拷文件只拷 .shp结果加载报错或图层空白就是少了 .shx 或 .dbf。还有一部分数据包会额外带 .sbn/.sbx 空间索引、.qpjQGIS 读写的投影描述、.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_CLASSG 开头为国道S 开头省道X 县道Y 乡道车道数LANES / LANE_NUM数字路宽WIDTH / ROAD_WIDTH单位米单双向DIRECTION / ONE_WAY常见 1/0 或 FT/TF几何长度SHAPE_Leng / SHAPE_LengthArcGIS 自动计算注意老版本字段名会被截断成 8 位注意字段名SHAPE_Leng这种拼写不是错而是 ArcGIS 老版本字段名 8 字符截断的历史遗留。你在用ogr2ogr做筛选时字段名里带这种不规则的拼写写 SQL 之前最好先ogrinfo把字段列表打出来别凭印象写。对路网数据来说GB_CODE这类等级字段是最容易被加工成专题图的。比如清出“G 开头”的国道和高速作为路网分析的高等级道路子集。这个过程在下一章的筛选步骤里会用到。2.3 武汉路网的三套坐标系来源WGS84、CGCS2000 与当地投影坐标坐标系是 shp 数据里最像“黑匣子”的部分。武汉市路网 shp 的来源不同坐标系自然不同三套最常碰到的WGS84 经纬度EPSG:4326常见于从开放地图平台抓下来的路网坐标单位是度CGCS2000 经纬度EPSG:44902008 年之后测绘和国土口子的数据大多转到了这个基准CGCS2000 3 度带高斯-克吕格投影中央经线 114°E对应 EPSG 编号 4547 这个区间武汉本地规划测量成果常用坐标单位是米还有一个老古董要提防西安 80 坐标系。一些年龄较大的分区路网数据还在用椭球参数与 CGCS2000 有差异叠加到卫星影像上会偏几十米到上百米。判断方法很简单看 .prj 里的DATUM写的是什么。我看 .prj 的习惯是直接打开文本编辑器扫一眼关键词出现GCS_WGS_1984就是经纬度 WGS84出现CGCS2000就看后面接的是Degree还是Meter。解压后防翻车的第一步先备份 .prj再把 .prj 里的文字贴进记事本看一眼。如果这份路网完全没有 .prjArcGIS 加载时可能不报错但坐标系是 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 ENCODINGUTF-8 \ 武汉市路网_Project.shp 武汉市路网.shp参数含义-t_srs是目标坐标系EPSG 4547 对应中央经线 114°E 的 CGCS2000 投影带-lco ENCODINGUTF-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 ENCODINGUTF-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 21 | 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 ENCODINGGBK 或 -lco ENCODINGUTF-8 强制指定。属性字段如果是乱码用 Python 脚本按 errorsignore 读出来重写一遍是最彻底的方案但工作量大非必要不推荐。 ### 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整个过程十分钟但能挡掉后面一整天的排查。这个习惯也是从几次“数据看起来没问题管线跑起来全废”的翻车里学来的希望对你能有帮助少走我走过的弯路。本文还有配套的精品资源点击获取
返回列表