
简介这份全国矢量数据图大全面向GIS从业者、城市规划与交通分析人员以及需要历史地理数据的研究者重点提供2005年全国铁路与路网矢量数据可用于空间查询、地图制作与区域对比分析。资源包共161个文件约11.25MB以shp、shx、dbf、prj、sbn、sbx等Shapefile配套文件为主分别承载几何图形、属性表、投影信息与空间索引另含少量adf、dat、nit等栅格与辅助文件及mxd工程文件便于在ArcGIS中直接加载与制图。已有2567人学习下载说明其在同类数据中具备一定参考价值。数据涵盖铁路线位置、类型与车站分布以及高速、国道、省道、乡道等道路等级与几何属性配合Lambert投影参数可减少空间位置误差。读者可据此开展交通连通性评估、物流路径分析或结合人口数据规划设施也能为历史铁路演变研究提供基础底图。1. 全国矢量数据图大全从路网到水系一套 shp 能省掉多少折腾做 GIS 的人大概都有过这种经历项目要底图手头只有一份全国行政区划道路、铁路、河流全得自己找。找来的数据要么坐标系对不上要么属性表缺字段要么干脆是图片描出来的假矢量。我前阵子整理了一份全国矢量数据图大全覆盖道路、铁路、河流等基础地理要素格式是标准的 shp可以直接拖进 ArcGIS 或 QGIS 用。它解决的不是什么高深问题就是「底图从哪来」这个最烦人的前置环节。适合做区域规划、交通分析、水文研究或者单纯需要一个能看的全国底图的人。2005 年的全国铁路数据和路网矢量数据也在里面做历史对比或变化监测的可以直接拿去用。2. 先搞清楚手里这套 shp 到底装了什么图层结构与属性字段拆解2.1 道路、铁路、河流三类要素的组织方式拿到一套矢量数据第一件事不是急着加载而是先看目录结构。这套数据按要素类型分文件夹常见做法是 roads、railways、rivers 三个主目录每个目录下是一组同名文件.shp、.shx、.dbf、.prj。少一个都打不开尤其是 .prj 丢了坐标系就成黑匣子后面投影转换全是玄学。道路图层通常按等级再分比如高速、国道、省道、县道各一个 shp或者合在一个图层里用字段区分。铁路图层一般不分等级但会区分已建和规划。河流图层按水系级别分一级河流、二级河流分开存方便按比例尺控制显示。我一般会先打开属性表看字段确认有没有 name、type、length 这类关键列。没有 name 字段的河流图层做标注时就得自己补很麻烦。属性字段的完整性直接决定后续能不能做分析。比如道路图层如果有 type 字段就能按等级设不同线宽和颜色如果没有只能统一符号出图效果差很多。铁路图层如果有 electrific 字段能区分电气化与否做专题图时有用。拿到数据先花十分钟翻属性表比后面返工强。2.2 坐标系与投影为什么你的数据叠不上这套数据大概率是地理坐标系常见的是 GCS_WGS_1984 或 GCS_China_Geodetic_Coordinate_System_2000。地理坐标系下线要素的长度和面积算出来是度不是米直接量算会得到离谱结果。要做长度统计或缓冲区分析必须先投影到合适的投影坐标系。全国范围常用 Albers 等面积投影参数一般是中央经线 105°E双标准纬线 25°N 和 47°N。在 ArcGIS 里用 Project 工具在 QGIS 里用「矢量 → 数据管理工具 → 重投影图层」。投影之后再去算道路长度单位才是米。我见过有人直接在地理坐标系下算全国公路总里程结果出来是「度」还纳闷为什么数字这么小。提示投影转换前先确认源数据的 .prj 文件内容用记事本打开看一眼确认是 GCS 还是 PCS。如果 .prj 缺失用 Define Projection 工具先补上再做 Project。2.3 用 ArcGIS 快速检查数据完整性的三个动作加载数据后别急着出图先做三个检查。第一打开属性表看记录数是否合理全国道路图层几十万条正常几百条就有问题。第二用「识别」工具点几个要素看几何是否正常有没有自相交或空几何。第三缩放至全图看范围是否覆盖全国有没有跑到境外或缺失省份。这三个动作花不了五分钟但能提前发现大部分坑。比如有些数据把台湾省漏了或者南海诸岛没包含出图时才发现就晚了。属性表里如果有大量空值也要留意可能是字段映射时丢了。# 用 arcpy 快速检查 shp 的坐标系和要素数量 import arcpy shp_path rD:\data\roads\national_roads.shp # 读取坐标系信息 desc arcpy.Describe(shp_path) print(坐标系:, desc.spatialReference.name) print(要素类型:, desc.shapeType) # 统计要素数量 count int(arcpy.GetCount_management(shp_path).getOutput(0)) print(要素总数:, count) # 检查是否有空几何 with arcpy.da.SearchCursor(shp_path, [OID, SHAPE]) as cursor: null_count 0 for oid, shape in cursor: if shape is None: null_count 1 print(空几何数量:, null_count)这段代码做了三件事读坐标系、数要素、查空几何。desc.spatialReference.name返回的是坐标系名称如果是 Unknown 就说明 .prj 有问题。GetCount_management比遍历游标快适合大图层。空几何检查用 SearchCursor 遍历几十万条会慢可以抽样或只在怀疑有问题时跑。参数上shp_path换成你自己的路径就行注意用原始字符串避免转义。3. 把 shp 用起来从加载、裁剪到导出的完整操作链3.1 在 ArcGIS 中按区域裁剪路网并导出全国数据动辄几百 MB做市级或流域分析时没必要全加载。用「裁剪」工具按行政区或流域边界切出目标范围既加快渲染也减小文件体积。ArcGIS 里在 Analysis Tools → Extract → Clip输入要素选路网裁剪要素选边界输出就是目标区域的路网。裁剪时注意一点裁剪要素的坐标系要和被裁剪的一致或者工具会自动投影但结果坐标系以输入要素为准。如果边界是地理坐标系路网是投影坐标系裁出来可能位置偏移。我一般先把两者统一到同一坐标系再裁。# 按行政区边界裁剪全国路网 import arcpy arcpy.env.workspace rD:\data arcpy.env.overwriteOutput True input_roads rD:\data\roads\national_roads.shp clip_boundary rD:\data\boundary\city_boundary.shp output_roads rD:\data\output\city_roads.shp # 执行裁剪 arcpy.Clip_analysis(input_roads, clip_boundary, output_roads) # 统计裁剪后要素数 count int(arcpy.GetCount_management(output_roads).getOutput(0)) print(裁剪后道路要素数:, count)Clip_analysis三个参数分别是输入、裁剪边界、输出。overwriteOutput True避免重复运行时因文件存在报错。裁剪后要素数应该明显小于全国数据如果没变可能是边界范围覆盖了全国或者坐标系不匹配导致裁剪失败。裁剪不会修改原始数据输出是新文件这点可以放心。3.2 属性筛选只保留高速和国道做交通可达性分析时往往只关心高等级道路。属性筛选比裁剪更轻量不改变几何只过滤记录。在 ArcGIS 里用 Select by AttributesSQL 表达式类似type 高速 OR type 国道然后导出选中要素。字段值的中文编码要注意有些 shp 的 dbf 是 GBK有些是 UTF-8ArcGIS 有时会乱码。如果筛选不出结果先看属性表里字段值显示是否正常。乱码的话在 ArcGIS 里设置注册表或用 QGIS 转一下编码。# 按道路等级筛选并导出 import arcpy input_roads rD:\data\roads\national_roads.shp output_highway rD:\data\output\highway_only.shp # 用 MakeFeatureLayer 加 SQL 筛选 arcpy.MakeFeatureLayer_management(input_roads, roads_lyr) arcpy.SelectLayerByAttribute_management( roads_lyr, NEW_SELECTION, \type\ 高速 OR \type\ 国道 ) # 导出选中要素 arcpy.CopyFeatures_management(roads_lyr, output_highway) print(导出完成)MakeFeatureLayer创建临时图层SelectLayerByAttribute_management执行 SQL 选择CopyFeatures_management把选中要素写成新 shp。SQL 里字段名用双引号包裹字符串值用单引号。如果字段名是中文可能需要加引号或改用字段索引。导出后记得检查要素数确认筛选生效。3.3 导出为 GeoJSON 或 WKT 供 Web 端使用shp 是桌面端格式Web 地图或数据库导入时常用 GeoJSON 或 WKT。QGIS 里右键图层 → 导出 → 保存要素为格式选 GeoJSON。ArcGIS 里用 Features To JSON 工具勾选 GeoJSON 选项。WKT 更适合数据库比如 PostGIS 的 ST_GeomFromText。# 用 geopandas 把 shp 转成 GeoJSON 并输出 WKT import geopandas as gpd gdf gpd.read_file(rD:\data\roads\national_roads.shp) # 转 GeoJSON gdf.to_file(rD:\data\output\roads.geojson, driverGeoJSON) # 输出前 5 条要素的 WKT for idx, row in gdf.head(5).iterrows(): print(row.geometry.wkt[:100], ...)geopandas 读 shp 会自动带上坐标系to_file写 GeoJSON 时 driver 指定 GeoJSON。WKT 输出用geometry.wkt截前 100 字符看格式。注意 GeoJSON 默认用 WGS84如果原数据是投影坐标系geopandas 会保留原坐标Web 端可能显示偏移需要先to_crs(epsg4326)转一下。4. 避坑与排查坐标系、编码、大文件处理里的血泪经验4.1 现象数据加载后位置偏移到境外原因.prj 文件缺失或坐标系定义错误ArcGIS 按默认坐标系解释导致位置漂移。常见于从非正规渠道拿到的 shp或者解压时 .prj 被杀毒软件误删。解决用 Define Projection 工具补上正确坐标系。如果不确定原始坐标系看数据范围全国数据经度 73°E 到 135°E纬度 3°N 到 54°N对应 WGS84 或 CGCS2000。补完后用 Project 转到目标坐标系。4.2 现象属性表中文显示为乱码原因dbf 文件的编码和 ArcGIS 默认编码不一致。ArcGIS 默认用系统编码中文 Windows 是 GBK但有些数据是 UTF-8。解决在 ArcGIS 里改注册表HKEY_CURRENT_USER\Software\ESRI\Desktop10.x\Common\CodePage把 dbfDefault 改成 UTF-8 或 GBK。或者用 QGIS 打开QGIS 编码识别更灵活导出时选正确编码再给 ArcGIS 用。4.3 现象裁剪或相交操作跑到一半崩溃原因全国路网数据量大几何复杂内存不够或几何无效。常见于节点数过多的线要素或者有自相交的几何。解决先用 Repair Geometry 修复几何再用 Dissolve 合并相邻线段减少节点。如果还崩分省裁剪别一次处理全国。ArcGIS 的 64 位后台处理可以打开QGIS 里调大内存缓存。4.4 现象导出的 GeoJSON 在 Web 端不显示原因坐标系不是 WGS84或者 GeoJSON 文件太大浏览器加载超时。解决导出前用to_crs(epsg4326)转 WGS84。文件太大就按区域切分或者用 TopoJSON 压缩。Web 端加载 GeoJSON 建议单文件不超过 10MB全国路网肯定超必须切。4.5 现象铁路和道路图层叠在一起分不清原因两个图层符号系统默认都是单色细线没有区分。解决在 ArcGIS 里按属性设符号道路用灰色系按等级分线宽铁路用黑白相间或虚线。QGIS 里用「分类」渲染按 type 字段分颜色。出图时铁路放在道路上层避免被盖住。5. 进阶用法用全国路网做可达性分析与历史对比5.1 基于路网的距离计算与缓冲区分析拿到路网后除了出图还能做分析。比如算某个城市到全国主要城市的公路距离用 Network Analyst 建网络数据集或者用 QGIS 的 Road Graph 插件。更简单的做法是算路网密度每个行政区内的道路总长度除以面积反映交通发达程度。# 计算各行政区路网密度 import geopandas as gpd import pandas as pd roads gpd.read_file(rD:\data\output\city_roads.shp) boundary gpd.read_file(rD:\data\boundary\city_boundary.shp) # 确保同一坐标系 roads roads.to_crs(boundary.crs) # 按行政区统计道路长度 joined gpd.sjoin(roads, boundary, howinner, predicateintersects) length_by_city joined.groupby(city_name)[geometry].apply( lambda x: x.length.sum() ) # 计算密度 boundary[area] boundary.geometry.area density boundary.set_index(city_name).join( length_by_city.rename(road_length) ) density[density] density[road_length] / density[area] print(density[[road_length, area, density]].head())这段代码先做空间连接把道路按行政区归类再按城市分组求长度和最后除以面积得密度。sjoin的 predicate 用 intersects跨边界的道路会被两个城市都算严格来说应该用 within 或先裁剪。密度单位是米/平方米通常换算成 km/km² 更直观。5.2 2005 年与现状数据的对比方法这套数据里有 2005 年的全国铁路和路网做变化监测时可以和更新的数据对比。方法很简单把两个年份的路网叠在一起用 Symmetrical Difference 找出新增或消失的线段。或者按行政区统计两个年份的路网长度算增长率。对比时注意坐标系要统一属性字段要对齐。2005 年的数据字段可能和现在不一样比如道路等级分类标准变了直接按 type 对比会失真。我一般先做字段映射把旧数据的等级归到新标准里再对比。注意历史数据的精度和现势性有限2005 年的路网可能不含后来新建的高速做变化分析时要说明数据来源和局限别把「数据里没有」当成「当时不存在」。5.3 一个我常用的检查习惯每次拿到新 shp不管多急我都会先做三件事看 .prj、翻属性表、缩放至全图。这三步花不了几分钟但能避开后面百分之八十的返工。有一次赶项目直接拿数据出图结果坐标系是错的整张图偏移了几百公里重新做花了半天。从那以后我每次加载数据都强制走一遍这个检查流程。希望帮到你。本文还有配套的精品资源点击获取