简介:这份全国矢量数据图大全面向GIS从业者、城市规划与交通分析人员,以及需要历史地理数据支撑研究的高校师生。资源以2005年全国铁路与路网矢量数据为核心,涵盖铁路线位置、长度、类型及车站分布,以及高速、国道、省道、乡道等多等级道路的几何形状与属性信息,可用于交通规划、导航开发、物流分析和区域经济研究。压缩包共161个文件,约11.25MB,以shp、shx、dbf、prj、sbn、sbx等Shapefile配套文件为主,另有mxd工程文件、xml元数据及adf栅格数据,便于在ArcGIS中直接加载、查询与制图。资源还包含Lambert投影相关文件,有助于避免投影差异导致的空间位置误差。目前已有2567人学习下载,适合需要快速获取全国路网底图、开展空间分析与历史对比的读者参考使用。
1. 全国矢量数据图大全:从2005年铁路与路网数据说起
手上拿到一份2005年的全国铁路与路网矢量数据,第一反应往往不是兴奋,而是犯嘀咕——这份数据到底能不能用、坐标系对不对、属性字段全不全。全国矢量数据图大全这类资源,核心价值在于把道路、河流、铁路这些线状要素按统一的空间参考整理成可被 GIS 软件直接读取的格式,省去从零采集的功夫。2005全国铁路数据和2005年全国路网矢量数据属于典型的 historical baseline 数据,适合做长时序变化分析、路网可达性建模、历史地图底图。它面向的是做交通规划、城市研究、GIS 二次开发的人,不是拿来当导航用的。这一章先把这份数据是什么、能解决什么讲清楚,后面再拆怎么用、参数怎么调、坑在哪。
2. 2005全国铁路与路网矢量数据的格式与字段拆解
2.1 常见交付格式与坐标系判断
拿到一份全国路网矢量数据,先别急着往 QGIS 里拖。第一步是确认它是什么格式。常见的交付形态有 Shapefile(.shp/.shx/.dbf/.prj)、GeoJSON、File Geodatabase(.gdb)、KML 几种。2005 年前后的数据,Shapefile 占绝大多数,因为那个年代 GIS 工具链基本围绕 Esri 生态转。Shapefile 有个硬限制:单个文件不能超过 2GB,字段名不能超过 10 个字符,中文属性容易乱码。如果你拿到的是一堆 .shp 散落在文件夹里,先看有没有 .prj 文件——没有 .prj 就意味着坐标系未知,这是最常见的翻车点。
坐标系判断有个实操办法:把数据加载进 QGIS,看右下角坐标显示。如果数值在 73~135 和 3~53 之间,大概率是 WGS84 地理坐标系(EPSG:4326);如果数值是几十万到几百万量级,那是投影坐标系,常见的有 CGCS2000 高斯克吕格投影或西安80。2005 年的数据,很多用的是北京54或西安80,这两个坐标系和现在的 CGCS2000 有几十到上百米的偏移。做全国尺度分析时这个偏移可以忍,做城市级路网匹配就必须做坐标转换。
# 用 ogrinfo 快速查看 Shapefile 的坐标系和字段信息 ogrinfo -so -al china_railway_2005.shp # 输出里重点看两行: # Layer SRS WKT: 显示坐标系定义 # 字段列表: 看有没有 NAME、TYPE、LENGTH 等属性ogrinfo -so只输出摘要不输出几何,-al表示所有图层。如果 SRS 显示为(unknown),说明 .prj 缺失,需要手动指定。字段列表里如果只有FID和Shape,那这份数据就是纯几何没有属性,铁路和道路混在一起没法区分,得靠几何特征或外部资料补属性。
2.2 铁路与道路的属性字段差异
2005 年全国路网矢量数据里,铁路和道路通常分图层存放,也可能合在一个图层用 TYPE 字段区分。铁路的属性一般包含线路名称、等级(高铁/普铁/支线)、轨距、电气化状态。2005 年这个时间点比较特殊——高铁还没大规模铺开,主要干线路网已经成型,但很多现在的高铁线路在当时还是规划线或既有线。道路数据则按技术等级分:高速、国道、省道、县道、乡道,字段里常见ROAD_CODE(路线编号)、ROAD_NAME、ROAD_LEVEL、PAVE_TYPE(路面类型)。
import geopandas as gpd # 读取铁路和道路图层 rail = gpd.read_file("china_railway_2005.shp", encoding="utf-8") road = gpd.read_file("china_road_2005.shp", encoding="utf-8") # 查看字段和数据类型 print("铁路字段:", rail.columns.tolist()) print("道路字段:", road.columns.tolist()) print("铁路坐标系:", rail.crs) print("道路坐标系:", road.crs) # 按等级统计道路长度(需先投影到等面积坐标系) road_proj = road.to_crs("EPSG:4527") # CGCS2000 3度带 road_proj["length_km"] = road_proj.geometry.length / 1000 print(road_proj.groupby("ROAD_LEVEL")["length_km"].sum())encoding="utf-8"是关键参数,2005 年的 Shapefile 很多用 GBK 编码,读出来乱码就换成encoding="gbk"。to_crs("EPSG:4527")把地理坐标转成投影坐标,这样geometry.length算出来的才是米而不是度。直接对 EPSG:4326 算长度会得到度数,数值没有物理意义。groupby("ROAD_LEVEL")按道路等级汇总长度,能快速判断数据完整性——如果县道长度占比异常低,说明数据可能只收录了高等级道路。
2.3 数据完整性检查的四个维度
全国尺度的矢量数据,完整性检查不能只看文件能不能打开。我一般从四个维度过一遍:空间覆盖范围、属性缺失率、几何有效性、拓扑一致性。空间覆盖看数据是否覆盖全国所有省份,2005 年的数据有时会缺西藏、新疆部分区域。属性缺失率用isnull().sum()快速统计,关键字段缺失超过 30% 就要考虑是否值得用。几何有效性用is_valid检查,自相交、悬挂节点、重复点都会导致后续空间分析报错。拓扑一致性主要看铁路和道路在交叉处有没有打断——如果铁路穿过道路但两者没有共享节点,做网络分析时就会断路。
# 几何有效性检查与修复 invalid = road[~road.geometry.is_valid] print(f"无效几何数量: {len(invalid)}") # 尝试修复 from shapely.validation import make_valid road["geometry"] = road.geometry.apply( lambda g: make_valid(g) if not g.is_valid else g ) # 属性缺失率 missing_rate = road.isnull().sum() / len(road) * 100 print(missing_rate[missing_rate > 0].sort_values(ascending=False))make_valid是 Shapely 2.0 之后的标准修复方法,比老的buffer(0)更可靠。buffer(0)对某些自相交多边形有效,但对线状要素的悬挂节点无能为力。属性缺失率排序后,优先关注ROAD_NAME和ROAD_LEVEL这两个字段——名字缺失影响可读性,等级缺失直接影响分类统计的准确性。
3. 把2005路网数据用起来的三个实操场景
3.1 用 QGIS 做全国路网密度制图
路网密度是交通地理里最基础的指标,算法是单位面积内的道路长度。全国尺度做这个图,核心是选对投影和格网大小。我一般用 50km×50km 的渔网,投影选 Albers 等面积投影(中国常用EPSG:4527或自定义 Albers),这样每个格网的面积才一致。QGIS 里的操作链路是:导入路网 → 投影转换 → 创建渔网 → 相交 → 汇总长度 → 分级渲染。
import geopandas as gpd import numpy as np # 投影到 Albers 等面积投影 road_albers = road.to_crs("+proj=aea +lat_1=25 +lat_2=47 +lat_0=0 +lon_0=105 +datum=WGS84 +units=m") # 生成 50km 渔网 from shapely.geometry import box bounds = road_albers.total_bounds cell_size = 50000 # 50km cols = np.arange(bounds[0], bounds[2], cell_size) rows = np.arange(bounds[1], bounds[3], cell_size) cells = [box(x, y, x + cell_size, y + cell_size) for x in cols for y in rows] grid = gpd.GeoDataFrame(geometry=cells, crs=road_albers.crs) # 空间相交并汇总 intersect = gpd.overlay(road_albers, grid, how="intersection") intersect["seg_len"] = intersect.geometry.length density = intersect.groupby(intersect.index_right)["seg_len"].sum().reset_index() grid["road_km"] = grid.index.map(density.set_index("index_right")["seg_len"]).fillna(0) grid["density"] = grid["road_km"] / (cell_size / 1000) ** 2 # km/km²Albers 投影的参数lat_1=25和lat_2=47是中国标准纬线,lon_0=105是中央经线。gpd.overlay做相交时会把每条道路按格网边界打断,index_right记录原始格网索引。fillna(0)处理没有道路穿过的格网。密度单位是 km/km²,全国平均大概在 0.2~0.5 之间,东部沿海能到 1.5 以上,西部荒漠区接近 0。
3.2 基于铁路数据的可达性分析
2005 年铁路数据做可达性,经典方法是基于列车时刻表的 OD 矩阵,但纯矢量数据没有班次信息。退而求其次的做法是用铁路网络做最短路径距离,再换算成时间。铁路速度按等级赋值:普铁干线 80km/h,支线 40km/h,这个参数在 2005 年比较合理。用 NetworkX 建图,节点是铁路站点或交叉点,边是路段,权重是长度除以速度。
import networkx as nx from shapely.ops import unary_union # 铁路网络转图结构(简化版:用端点作为节点) G = nx.Graph() for idx, row in rail.iterrows(): coords = list(row.geometry.coords) start, end = coords[0], coords[-1] length_km = row.geometry.length * 111 # 粗略换算,精确需投影 speed = 80 if row.get("LEVEL") == "干线" else 40 G.add_edge(start, end, weight=length_km / speed, length=length_km) # 计算北京到主要城市的铁路最短时间 beijing = (116.4, 39.9) # 找最近节点 nearest = min(G.nodes, key=lambda n: (n[0]-beijing[0])**2 + (n[1]-beijing[1])**2) times = nx.single_source_dijkstra_path_length(G, nearest, weight="weight")row.geometry.length * 111是度到公里的粗略换算,纬度方向 1 度约 111km,经度方向随纬度变化。精确做法是先投影再算长度。nx.single_source_dijkstra_path_length返回从源点到所有可达节点的最短时间。这个简化模型忽略了换乘和停站时间,实际可达性会差 20%~30%,但用于宏观对比足够。
3.3 路网数据与人口栅格的叠加分析
把路网密度和人口分布叠加,能看出交通供给与需求的匹配程度。2005 年的人口栅格可以用 GPW v4 或中国 1km 格网人口数据。操作上把人口栅格重采样到和路网密度格网一致的分辨率,然后做相关分析或分级配色。QGIS 里用栅格计算器或 Python 的 rasterio 都行。
import rasterio from rasterio.warp import reproject, Resampling # 读取人口栅格并重采样到 50km 格网 with rasterio.open("population_2005.tif") as src: pop = src.read(1) pop_crs = src.crs pop_transform = src.transform # 重采样到路网格网 # 需先将 grid 转为栅格或统一到相同 transform # 此处省略栅格化步骤,核心是 Resampling.bilinear重采样用双线性插值(Resampling.bilinear)比最近邻更适合连续型人口数据。叠加后计算每个格网的「路网密度/人口密度」比值,高值区说明交通供给相对充足,低值区可能是需求缺口。这个分析在 2005 年数据上做,能反映西部大开发前后的交通格局差异。
4. 全国矢量数据处理的避坑与排查清单
4.1 坐标系缺失导致的面积计算错误
现象:算出来的道路总长度是几百,单位不知道是什么。原因:数据是 EPSG:4326 地理坐标系,geometry.length返回的是度数不是米。解决:先to_crs转到投影坐标系再算长度,全国尺度用 Albers,省级用高斯克吕格。
4.2 Shapefile 中文属性乱码
现象:ROAD_NAME字段显示成??????或锟斤拷。原因:Shapefile 的 .dbf 文件编码和读取时指定的编码不一致,2005 年数据多为 GBK。解决:gpd.read_file(..., encoding="gbk"),如果还乱就试encoding="gb18030"。QGIS 里在图层属性中手动改编码。
4.3 铁路与道路图层叠加后节点不匹配
现象:做网络分析时铁路和道路交叉处不连通,最短路径绕远。原因:两个图层的交叉点没有共享节点,拓扑上断开。解决:用shapely.ops.split在交叉处打断,或统一用unary_union合并后重新提取节点。QGIS 的「线段相交」工具可以批量处理。
4.4 数据覆盖范围与行政区划不匹配
现象:按省统计道路长度时,某些省的数据明显偏少。原因:2005 年数据可能按当时行政区划采集,与现在的省份边界有差异,或部分区域数据缺失。解决:用gpd.clip按最新行政区划裁剪,缺失区域标注出来,分析时说明数据覆盖限制。
4.5 大文件内存溢出
现象:读取全国路网 Shapefile 时 Python 进程被 kill。原因:全国尺度的线状要素可能有几十万条,一次性加载占内存过大。解决:用pyogrio引擎分块读取,或先按省拆分再合并。gpd.read_file(..., rows=slice(0, 10000))可以只读前一万行测试。
5. 从2005数据到多时相分析的进阶路径
2005 年的全国铁路和路网数据,单独用价值有限,真正的价值在于放进时间序列里对比。我一般会把它和 2015、2020 的同类型数据叠在一起,看路网扩张的方向和速度。具体做法是:先把各年份数据统一到同一坐标系和属性结构,然后用gpd.overlay做差分,新增路段和消失路段一目了然。铁路方面,2005 到 2020 年最大的变化是高铁网络从无到有,用差分能直接量化这个过程的时空特征。
验证数据质量有个笨办法但很管用:挑几条你熟悉的线路,比如京广铁路、京沪高速,看它们的几何走向和实际是否吻合。如果一条直线穿过山区没有弯曲,那大概率是简化过的示意线,不能用于精确分析。属性方面,随机抽 50 条记录,对照维基百科或公开资料核对名称和等级,准确率低于 80% 就要谨慎使用。
我自己的习惯是,拿到任何一份历史矢量数据,先建一个data_qc的 Jupyter Notebook,把坐标系、字段、缺失率、几何有效性、抽样核对这五步跑一遍,结果存成 HTML 报告。这样后面每次用这份数据,翻报告就知道能不能直接用,不用重复踩坑。2005 年的数据尤其需要这一步,因为时间久远,元数据往往丢失,只能靠数据本身反推。希望帮到你。
本文还有配套的精品资源,点击获取