简介:内蒙古路网矢量数据是一份以Shapefile(SHP)格式存储的线型GIS数据集,面向地理信息、交通规划、地图制图与城乡规划相关从业者及学习者,可用于道路网络结构的精确表达、空间分析与可视化。压缩包共7个文件,包含几何数据(.shp)、属性数据(.dbf)、索引文件(.shx、.sbn、.sbx)、坐标系定义(.prj)及元数据(.xml),齐全的文件组成保证了数据可被主流GIS软件直接读取和运算,压缩后整体约34.32MB。目前已有764人学习下载。借助ArcGIS或QGIS等平台,用户可以加载路网数据,提取高速公路、国道、省道、县道等各级道路的几何特征与属性信息,完成路网密度计算、交通流量预估、环境影响评价、应急救灾路线规划等多场景任务。同时,路网数据可与人口分布、土地利用、气候等图层叠加开展综合分析,尤其适合作为区域交通研究与教学演示的基础数据源,具有较高的实用价值。
1. 内蒙古路网矢量数据:一份shp格式的路网,能省掉多少地面工作
内蒙古地域跨度大,路网密度差异明显,做交通可达性、物流配送半径或者自然灾害应急救援路径分析时,最基础也是最重要的就是一套可用的路网数据。这份内蒙古路网矢量数据以shp格式整理,省的正是从纸质地图扫描、地理配准、逐条画线那一整套重复劳动。打开属性表就能看到道路等级、编号、名称这些常规字段,直接挂到ArcGIS或QGIS里能跑缓冲区和网络分析。适合做路网规划的工程师、GIS数据处理的一线人员,以及给ArcSWAT小流域分析准备基础数据的科研用户。不过到手先别急着拖进软件,前十分钟检查坐标系和字段编码,能避开后面绝大部分错位和乱码问题。
2. 先看懂shp里的家底:坐标系、字段、路网拓扑三件事
2.1 坐标系:CGCS2000还是WGS84
shp文件本身不强制带坐标系信息,它只是把坐标数值存在dbf表里。加载到ArcGIS或QGIS时,软件会根据一个同名的.prj文件来判断投影方式。内蒙古路网数据常见的有两种坐标基准:CGCS2000(2000国家大地坐标系)和WGS84。很多新手打开后看到经纬度显示正常,就直接开始画缓冲区和做面积统计,结果在计算道路长度时全部出错,原因就是把地理坐标系当投影坐标系用了。
拿到shp文件第一件事就是在图层属性里查看“源”或“坐标参考系统”。如果.prj不存在,软件会默认给一个未知坐标系,这时候不要瞎猜,先看看属性表里的坐标数值范围:经度105度左右、纬度40度左右的,是地理坐标;坐标数值在五六位数量级、比如x坐标是4字开头或6字开头的,大概率是高斯克吕格投影或UTM投影。
内蒙古东西跨度大,跨越多个分带,处理全蒙路网时建议使用Albers等积圆锥投影(Krasovsky或CGCS2000椭球体),这样面积和长度测量误差比较均衡。如果你只做呼和浩特周边的小范围分析,可以用CGCS2000 / 3-degree Gauss-Kruger zone 26,对应的EPSG代码是4528。双击加载后先缩放至图层,看路网是否与在线影像叠加吻合,这一步比任何投影参数检查都直观。
下面是常见坐标系对应EPSG代码对照表,保存到项目的元数据说明里会方便很多:
| 坐标系描述 | EPSG代码 | 适合场景 |
|---|---|---|
| CGCS2000 地理坐标系 | 4490 | 全蒙范围粗略定位、可视化 |
| WGS84 地理坐标系 | 4326 | 与GPS原始数据直接互转 |
| CGCS2000 3度带CM 117E | 4527 | 巴彦淖尔、鄂尔多斯等西侧 |
| CGCS2000 3度带CM 123E | 4530 | 通辽、赤峰等东侧 |
| WGS84 / UTM 49N | 32649 | 与国外数据集衔接的辅助投影 |
2.2 要素类型和属性字段:线要素的公路等级怎么定义
shp格式有三种基本要素类型:点(Point)、线(Polyline)、面(Polygon)。内蒙古路网数据应该是线要素,但在某些局部版本里,隧道口和收费站会单独做成点要素层。打开属性表后,重点关注几个常规字段:
ROAD_CODE:道路编号,比如G110、S203、X401ROAD_NAME:路线名称ROAD_TYPE或CLASS:公路等级,通常用数字或字母表示,例如1表示高速公路、2表示国道、3表示省道、4表示县道WIDTH或LANES:路面宽度或车道数,用于网络分析时估算通行能力
常见问题在于不同来源的数据字段名不统一。有的用ROADCLASS,有的用TYPE,还有的直接在备注里写“高速/国道”。拿到数据后先做一次字段映射,统一到自己的项目标准里。用ArcGIS的字段计算器或Python脚本都能快速重命名和填充,这个后面细说。
线要素的方向也需要检查。shp的线方向记录的是数字化方向,不一定代表实际行驶方向。做道路网络分析时,如果路网有单行道属性字段,必须确认线的起点到终点是否与允许通行方向一致。内蒙古路网大部分是省级和国家级道路,双向通行问题不大,但在城区匝道和连接线数据里就容易踩坑。
2.3 拓扑关系:路网能不能直接做网络分析
拿到路网线要素,很多人想直接跑最短路径,结果发现网络分析结果极其离谱,比如车在两条路之间“飞”过去,根本不受道路连接约束。原因是原始路网数据没有建立拓扑关系,道路在交叉口处只是视觉上相交,实际上线段的端点没有打断成公共节点。
ArcGIS的Network Analyst要求路网要素必须有正确的连通性。简单做法是先用“打断相交线”工具,把交叉处的线在交点处切开,然后用“构建网络数据集”工具生成网络。QGIS可用v.split(GRASS)或Split lines at intersections插件。操作顺序别反了:先打断,再检查悬挂点,最后构建网络。
很多路基数据为了压缩体积,会把整条G110国道做成一条连续的线要素,跨越多个盟市。这种情况下即使打断相交线,也不能处理自身相交或自重叠。建议先用“修复几何”工具,再进行多边形重建和打断处理。拓扑检查的完整流程是:添加拓扑规则到要素数据集,选择“不能自重叠”“不能自相交”“端点必须被其他要素覆盖”,然后验证拓扑并导出错误点,逐条修。
3. 在ArcGIS与QGIS中把路网用起来:加载、投影和按属性抽路网
3.1 加载shp前的必查三项
不管是ArcGIS Pro还是QGIS,加载shp前我习惯按顺序做三件事:查.prj、查字段编码、查几何错误。.prj缺失或错误会导致图层叠加错位,字段编码错误会让中文路名全变成乱码,几何错误会导致后续统计长度时出现负数或零值。
QGIS里加载shp后,在图层右键“属性-源”可以看到坐标系,在“图层-要素计数”里查看要素数量是否与文件资源里的说明一致。ArcGIS可以在目录面板中直接右键shp,选“属性”,看到“坐标系”和“字段”两页。如果发现没有.prj,可以用“定义投影”工具手动指定,注意这里的操作是先定义,而不是直接“投影”,后者会把坐标数值重新计算,对原本就有正确坐标的数据来说是二次转换。
一个实用的加载前检查脚本如下,在QGIS的Python控制台里跑,可以一次性输出这个shp的坐标系、要素类型和字段列表:
layer = iface.activeLayer() if layer: crs = layer.crs() print("坐标系:", crs.authid(), crs.description()) print("要素类型:", layer.geometryType()) for field in layer.fields(): print(field.name(), field.typeName(), field.length())这段代码先获取当前图层,再分别打印坐标系标识、要素几何类型和每个字段的名称、类型、长度。刚接触QGIS的人可以把这段代码放进控制台,选中路网图层运行,输出的字段清单就是你后面做属性筛选和字段计算的基础。
3.2 按等级和编号筛选:用arcpy把国道从全路网里拎出来
内蒙古路网shp里往往同时包含高速、国道、省道、县道和乡村道路。做路网密度分析时常需要单独抽出某一等级道路,不建议直接在图层上右键“导出数据”反复操作,更规范的做法是用arcpy写一个筛选脚本,处理结果可重复,也不容易把原始数据改乱。
以ArcGIS Pro为例,用arcpy的Select_analysis工具完成筛选,脚本示例如下:
import arcpy input_fc = r"D:\GeoData\InnerMongoliaRoads\roads.shp" output_fc = r"D:\GeoData\InnerMongoliaRoads\national_roads.shp" where_clause = "ROAD_TYPE = 2 OR ROAD_CODE LIKE 'G%'" arcpy.analysis.Select(input_fc, output_fc, where_clause) print("筛选完成,要素数:", arcpy.GetCount_management(output_fc)[0])ROAD_TYPE = 2是假设字段里用2代表国道,ROAD_CODE LIKE 'G%'则是把编号以G开头的路线全部选出来,两条条件用OR连接,保证字段缺失时不漏选。这类方式同样适合用ROAD_NAME LIKE '%高速%'提取高速公路。筛选结果放同一个地理数据库里,比输出为新的shp更利于后续构建网络数据集。
如果没有ArcGIS环境,在QGIS里用“按表达式提取要素”即可,原因是地图代数表达式"ROAD_TYPE" = 2,导出后命名规范一点,别叫“roads_copy”,直接叫“national_roads”。
3.3 发布到GeoServer:矢量数据发布服务前的图层检查
用GeoServer发布内蒙古路网矢量数据时,容易遇到一个尴尬情况:图层预览正常,但前端加载速度极慢,或者缩放后道路形状走样。这通常不是GeoServer的锅,而是shp的空间索引缺失或坐标系未正确声明。
发布流程中,在“新建数据源”选择Shapefile类型,直接填shp所在目录,数据源名称建议用全小写字母加下划线。发布图层前,必须到“Tile Caching”页签勾选“为每个缩放级别生成切片”,并设置合适的切片格式,这样前端瓦片请求才会走缓存,而不是每次都读取整个shp文件。
在“发布”页签的“坐标参考系统”部分,如果shp没有.prj文件,GeoServer默认用EPSG:4326瓦片矩阵,但路网坐标可能是投影坐标系。这个矛盾会导致图层显示在错误位置。解决方法是先在QGIS中定义好坐标系再另存一份完整shp,或是在GeoServer的“覆盖设置”中手工指定Native SRS为EPSG:4546,然后声明Declared SRS为EPSG:4326,让GeoServer自动转换。
发布之后一定要在“Layer Preview”里选择OpenLayers预览模式,拖动地图到呼和浩特附近,检查道路是否与大底图贴合。如果偏差超过几十米,多半是坐标系声明错误,不要急着调前端代码。
4. shp与kml、dwg、mapgis互转:坐标系和字段的二次加工
4.1 shp转kml:给外业人员看路线的标准操作
外业踏勘和领导汇报经常需要把路网转成kml,放到奥维或Google Earth里看现场。ArcGIS中自带的“图层转KML”工具能直接完成,但中间有个坑:kml默认要求WGS84地理坐标系,如果你的shp是CGCS2000投影坐标系,直接转换会得到错位结果,必须先把shp投影成WGS84。
QGIS的操作更快,右键图层“导出-另存为”,格式选Keyhole Markup Language [KML],坐标系选择EPSG:4326,文件名后缀kml即可。在ArcGIS里可以用工具箱中的“Project”先把线要素转成GCS_WGS_1984,然后运行“Layer To KML”。
一个典型的转换命令序列如下,用QGIS的Processing算法生成:
# 先做投影转换,再转kml ogr2ogr -f KML -t_srs EPSG:4326 roads.kml roads.shpogr2ogr是GDAL带的工具,改输出路径和文件名之后在命令行直接用。-t_srs EPSG:4326指定目标坐标系,这样kml拿到任何手机地图软件里都能落在正确位置。如果转换后kml的文件很大,超过20MB,可以参考GDAL的-segmentize参数来减少点数,代价是几何精度稍微下降。
转出的kml建议再用QGIS加载验证一遍,重点看道路要素数量是否与原始shp一致。经常发生的情况是shp里的MultiLineString被转成kml后变成了多条LineString,要素数变多,不影响使用,但在做属性关联时会找不到对应关系。
4.2 shp转dwg和mapgis:线型映射与字段剥离
工程设计单位一般用CAD或mapgis,所以经常遇到把内蒙古路网shp转成dwg或mapgis线文件的请求。ArcGIS的“Export to CAD”工具可以直接转dwg,但转换结果里没有图层隔离,所有道路都躺在同一个实体层上,线型也全是连续的,不适合后续审图。
更可控的方法是先在GIS软件里按道路等级字段拆分要素,然后分别导出dwg。在QGIS中可以用“按属性拆分”工具,把ROAD_TYPE作为拆分字段,一次生成多个要素层,再用“导出-另存为DXF”导出。DXF比DWG的兼容性更好,很多CAD软件的后续操作可以自动转换。导出前要把要素的线宽、线型映射到CAD图层,常见做法是在导出对话框里设置CAD扇区为“Architecture”,这样生成结果更干净。
转mapgis线文件需要注意,mapgis对shp的属性字段支持有限,中文字段名很容易变成乱码。建议先另存一份只保留必要字段的shp,字段名改成英文,避免转过去后属性表没法看。另外一种方式是直接用FME转换,构建读模块读取shp,写模块输出mapgis格式,但在没有FME的环境下,我的做法是先用ArcGIS把线要素转成DXF,再用mapgis的“文件转换-DXF转线文件”导入,这样至少能保住图形,属性字段再手工挂接。
4.3 用QGIS批量合并shp:ArcGIS Pro的合并套路
内蒙古路网数据有时按盟市切分,每个shp只包含一个盟市的路网,做全蒙分析需要先合并。用“矢量通用-合并矢量图层”工具,把多个shp一次性合并成新图层,这是最简单的方式,不需要任何脚本。
如果处理的是十几个甚至几十个shp文件,QGIS的批量处理面板更好用:“处理-历史日志”旁边的“批量处理”入口,选“合并矢量图层”,用目录选择器一次把整个文件夹的shp文件装入列表,统一输出。ArcGIS Pro里对应的工具是“合并”,前提是所有输入图层的字段结构一致,否则合并后属性表会出现大量空值。
合并之前先检查所有输入shp的坐标系,ArcGIS Pro在合并工具里有一个环境设置,可以强制输出坐标系,推荐设置成阿拉斯加等积圆锥投影(CGCS2000版本),这样全蒙范围的长度和面积统计误差最小。合并后务必运行“修复几何”和“检查几何”工具,原因是各盟市数据的生产标准不同,常出现微小缝隙和拓扑错误,这些错误在单个图层内看不出来,合并后会在边界处暴露。
5. 避坑与常见问题:路网数据翻车的五个典型现场
5.1 现象:路网加载后飞到非洲海岸
原因:shp文件缺少.prj,或者ArcGIS/QGIS把没有坐标系信息的文件自动识别为WGS84/WGS84 Web Mercator,然后显示位置跑偏。
解决:不要手动移动图层去对齐,那样只会让数据更乱。右键图层打开属性,在“源-坐标系”中点击“定义”,选择正确的坐标系。如果不知道正确坐标系,查看原始坐标数值范围:凡是x约在110到125、y约在38到46的,用EPSG:4490;凡是x约在四五十万到百万级、y在几百万级的,基本是高斯克吕格。定义后如果还是没有.prj,记得用“数据-导出要素”另存一份,把定义结果固化到新shp里。
5.2 现象:属性表里中文路名全是乱码
原因:shapefile的dbf字段编码为GBK或GB2312,而ArcGIS新版默认用UTF-8读取,QGIS默认也可能读错,导致中文字段显示为一堆问号或乱码。
解决:在QGIS中重新加载shp时选择“数据源-编码”,手动选择GBK或System,中文就能正常显示。ArcGIS Pro中可以在dbf同目录放一个.cpg文件来指定编码,常见做法是用记事本创建一个roads.cpg,内容写GBK或UTF-8,保存后在ArcCatalog里刷新属性表。如果已经是乱码且无法恢复,用QGIS重新加载正确编码,然后导出成新的shp,导出时在“编码”下拉框选择UTF-8,一劳永逸。
5.3 现象:两条路明明相交却建立不了拓扑
原因:线要素在交叉口没有公共节点,一条线被另一条线跨越,实际坐标值相差极小,视觉上连在一起,但端点没有捕捉。
解决:在ArcGIS中先用“集成”工具,容差设为0.001米或按数据精度设置,让重合节点合并;然后“打断相交线”,将相交线在交点处切开。QGIS里先用v.clean的break选项,再用v.build检查线拓扑。打断后,用“列出悬挂点”工具找出没有与其他线连接的端点,人工判断哪些是真实断头路,哪些是应该被连接的缺口。不要全自动修复,否则会把不该连的道路连一起。
5.4 现象:裁剪或合并后图形严重变形
原因:投影坐标系设置错误。比如数据本身是高斯克吕格投影,裁剪时界面环境里被强制改成Web墨卡托,结果图形被拉长。更常见的是做缓冲区时,直接在WGS84经纬度坐标系下用“距离”参数,得到的是一个近似于矩形的怪异形状。
解决:做任何距离和面积运算前,把路网图层复制一遍到投影坐标系,工程地理数据库的投影尽量使用CGCS2000等积圆锥投影或UIM投影。在ArcGIS的“环境-输出坐标系”里手动指定,比依赖图层自动投影更靠谱。QGIS用户可以在“图层-属性-数据源”里设置临时投影,但最终导出一定要选“导出-另存为”,在CRS字段明确选择投影EPSG,不要默认使用当前投影。
5.5 现象:ArcSWAT小流域分析里加载路网后软件崩溃或提示无效数据
原因:ArcSWAT要求所有空间数据具有一致的投影坐标系,并且要素类型严格区分。路网如果使用地理坐标系或要素类型混乱,会导致子流域参数化阶段失败。路网数据在小流域分析里不是必需输入,它只辅助计算道路密度和径流路径,所以格式错误时要果断换用更简单的线图层。
解决:在进入ArcSWAT之前,先把路网shp批量投影到与DEM相同的坐标系,推荐使用UTM投影或Albers等积投影。然后在ArcCatalog中检查要素类型,确认是Polyline而不是MultiPatch或者带Z值的3D线。如果还报错,到ArcSWAT的“Delete Previous Data”里清空重来,这一步能排除团队常见的ArcSWAT自带暂存数据残留问题。网上搜索“arcswat做小流域分析要用什么矢量数据”时,注意分辨官方文档和培训PPT,官方文档里列的资源是DEM、河网、土地利用、土壤,路网是属于可选辅助层,别把它当作核心输入去对格式。
6. 最后一道工序:用Python脚本给路网shp做体检
路网数据拿到手,第一份成果应该是体检报告,而不是直接开始分析。我用下面这段脚本检查坐标范围、要素数和几何有效性,每次做新数据集时都会先跑一遍。
import shapefile from shapely.geometry import shape sf = shapefile.Reader(r"D:\GeoData\InnerMongoliaRoads\roads.shp") shapes = sf.shapes() records = sf.records() total = len(shapes) print("要素总数:", total) all_geom_valid = True line_length_sum = 0.0 for s in shapes: geom = shape(s) if not geom.is_valid: all_geom_valid = False print("发现无效几何:", s.shapeType) line_length_sum += geom.length print("所有要素几何有效:", all_geom_valid) print("线要素总长度(基于原始坐标系):", line_length_sum)脚本使用pyshp读取shp,再结合shapely判断几何有效性。shape(s)把原始记录转成shapely的几何对象,is_valid能发现自相交和退化线。总长度这里只是一个相对值,要得到真实公里数,需要先把图层投影到合适坐标系,再乘以单位转换系数。这段脚本同样可以统计最长一条线段的长度,用来判断是否存在异常地跨州长线,方便决定是否需要打断。
做完几何体检,再检查字段和坐标系:
from osgeo import ogr ds = ogr.Open(r"D:\GeoData\InnerMongoliaRoads\roads.shp") layer = ds.GetLayer() spatial_ref = layer.GetSpatialRef() print("EPSG:", spatial_ref.GetAuthorityCode(None)) for field in layer.schema: print("字段:", field.name, field.type) feat_count = layer.GetFeatureCount() print("要素数:", feat_count)这里用GDAL的OGR接口直接读取shp的坐标系和字段定义。打印出的EPSG代码要和前面提到的规划值比对,字段列表要和你的分析需求做映射。如果一个都对应不上,就要回到源数据确认是不是“内蒙古路网”的完整版,还是只含省道以上等级的简化版。
从那以后,我每次从外部拿到shp数据,都强制走一遍这个流程:先看PRJ,再看字段编码,跑一遍自检脚本,最后才灌进ArcGIS做正事。这套习惯帮我在内蒙古路网、塔里木河流域矢量数据等好几个项目里省下了重新配准和返工的体力活。自检脚本不复杂,但能让你对这份资源的边界很清楚:哪些字段可以信任,哪些需要实测,哪些必须在文档里留个备注。希望帮到你。
本文还有配套的精品资源,点击获取