
简介这份资源面向GIS从业者、地理研究人员及交通规划相关专业学生提供新疆维吾尔自治区各级公路与地级市行政区划的Shapefile矢量数据可用于空间分析、地图制图与交通网络研究。压缩包共35个文件约1.9MB包含shp主文件、shx索引、dbf属性表、prj坐标系统及sbn、sbx空间索引、xml元数据等配套类型覆盖一级、二级、三级公路、高速公路以及各地级市行政边界五类要素属性与坐标信息完整可直接导入ArcGIS、QGIS等平台使用。已有1248人学习下载数据经过整理省去自行采集与清洗的环节。借助这套数据读者能够快速完成新疆路网密度统计、等级结构对比、行政区划叠加分析及专题图输出为交通规划、城市研究和地理数据分析提供可靠的基础底图支撑。1. 新疆各级公路shp文件从一份路网数据到能跑通的空间分析做交通可达性、物流路径规划或者区域经济研究的人多半都遇到过同一个卡点底图上的路网要么太粗要么缺属性要么干脆找不到覆盖全疆的矢量数据。新疆各级公路shp文件这个关键词之所以被反复搜索背后是一类非常具体的诉求——需要一份带行政等级、能直接拖进GIS软件、还能参与空间计算的公路矢量数据。它解决的不是看一眼地图的问题而是拿来做分析的问题。适合谁做国土空间规划、物流选址、应急调度、路网密度统计的从业者以及需要把公路作为分析底图的研究生和工程师。这一章先把这份数据到底是什么、字段长什么样、能支撑哪些分析讲清楚后面几章再落到获取、清洗、拼接和实际跑通一个可达性计算的完整路径。2. 新疆公路shp文件的图层结构与字段含义2.1 一份合格的公路shp应该包含哪些字段shp本身只是几何容器真正决定它能不能用的是属性表。新疆地域辽阔公路等级跨度大从高速、国道、省道一直到县道、乡道如果属性里没有等级字段后续做缓冲区分析或者按等级筛选就无从下手。常见做法是至少保留以下几类字段道路名称、行政等级、技术等级、路面类型、车道数、设计速度、里程。不同来源的数据字段命名差异很大有的用拼音首字母有的用英文缩写拿到手第一件事就是打开属性表核对字段含义而不是急着画图。字段名示例含义典型取值NAME道路名称G30、S101、X208GRADE行政等级高速、国道、省道、县道、乡道TECH_LEVEL技术等级一级、二级、三级、四级SURFACE路面类型沥青、水泥、砂石LANES车道数2、4、6、8LENGTH路段里程公里数值型字段核对完之后还要看几何类型。公路shp通常是线图层Polyline但有些数据会把互通立交单独做成点图层或者把服务区做成面图层。如果拿到的是多个分幅文件拼接前必须确认坐标系一致否则会出现路网错位几十公里的经典翻车现场。2.2 坐标系与投影为什么直接量算长度会出错新疆跨越多个UTM带常见的地理坐标系是WGS84或CGCS2000投影坐标系则可能是UTM 44N到46N。如果shp用的是地理坐标系单位是度直接算长度得到的是度而不是米数值毫无意义。正确做法是先确认坐标系再投影到合适的投影坐标系下做量算。下面这段Python用geopandas演示如何检查并转换坐标系。import geopandas as gpd # 读取公路shp gdf gpd.read_file(xinjiang_roads.shp) # 查看当前坐标系 print(原始CRS:, gdf.crs) # 如果长度字段是度先投影到UTM 45N新疆中部常用带 if gdf.crs and gdf.crs.is_geographic: gdf_proj gdf.to_crs(epsg32645) # WGS84 / UTM zone 45N else: gdf_proj gdf.copy() # 重新计算长度单位米 gdf_proj[length_m] gdf_proj.geometry.length print(投影后总里程(km):, gdf_proj[length_m].sum() / 1000)逻辑说明先判断当前CRS是否为地理坐标系如果是就转换到UTM 45N。参数epsg32645对应WGS84的45N带如果数据覆盖新疆西部可能需要换成32644。转换后geometry.length返回的是投影单位米除以1000得到公里。这一步不做后面所有基于长度的统计都是错的。2.3 按行政等级拆分图层的最小操作拿到全疆路网后往往需要按等级拆成高速、国道、省道等独立图层方便分别做缓冲区和密度分析。下面这段代码按GRADE字段拆分并导出。import geopandas as gpd gdf gpd.read_file(xinjiang_roads.shp) # 按行政等级分组导出 for grade, sub in gdf.groupby(GRADE): out_name froads_{grade}.shp sub.to_file(out_name, encodingutf-8) print(f{grade}: {len(sub)} 条路段 - {out_name})逻辑说明groupby按GRADE字段分组每组导出为独立shp。参数encodingutf-8是为了避免中文属性乱码尤其在Windows环境下必须加。导出后建议逐个打开检查确认没有空几何或异常短路段。如果GRADE字段里有空值会生成一个名为roads_nan.shp的文件需要单独处理。3. 获取与拼接把分幅数据合成一份可用的全疆路网3.1 分幅数据的常见来源与拼接前的检查清单新疆公路数据常见的获取方式有几种一是从公开的地理信息平台下载分省或分地州数据二是从OSM提取并做等级映射三是通过行业渠道获取。不管哪种来源分幅拼接前必须做三件事统一坐标系、统一字段结构、检查接边处是否有重复路段。我一般会先写一个检查脚本把每个分幅文件的字段名、几何类型、要素数量打印出来确认一致后再合并。import geopandas as gpd import os files [f for f in os.listdir(.) if f.endswith(.shp)] for f in files: gdf gpd.read_file(f) print(f, | 要素数:, len(gdf), | CRS:, gdf.crs, | 字段:, list(gdf.columns))逻辑说明遍历当前目录所有shp打印要素数、坐标系和字段列表。这一步能快速发现某个分幅坐标系不一致或字段缺失的问题。如果发现字段名不同但含义相同需要在合并前重命名统一。3.2 用geopandas合并分幅并去重确认字段一致后用concat合并再用drop_duplicates去重。注意去重不能只按几何因为接边处可能有属性不同但几何相同的重复段。import geopandas as gpd import pandas as pd gdfs [gpd.read_file(f) for f in files] merged gpd.GeoDataFrame(pd.concat(gdfs, ignore_indexTrue), crsgdfs[0].crs) # 按几何和名称去重 merged[geom_wkt] merged.geometry.to_wkt() merged merged.drop_duplicates(subset[geom_wkt, NAME]) merged merged.drop(columns[geom_wkt]) merged.to_file(xinjiang_roads_merged.shp, encodingutf-8) print(合并后要素数:, len(merged))逻辑说明concat合并所有分幅ignore_index重置索引。去重时把几何转成WKT字符串作为辅助列结合NAME字段判断重复。参数subset指定去重依据如果数据没有NAME字段可以只用geom_wkt。合并后要素数应该小于等于各分幅之和如果反而变多说明concat时索引处理有问题。3.3 拓扑检查悬挂点与自相交的处理合并后的路网常见问题是悬挂点断头路和自相交。悬挂点不一定是错误可能是数据分幅导致的断口但自相交几乎肯定是错误。用shapely检查自相交并修复。from shapely.validation import explain_validity invalid merged[~merged.geometry.is_valid] print(无效几何数:, len(invalid)) for idx, row in invalid.iterrows(): print(idx, explain_validity(row.geometry))逻辑说明is_valid返回布尔序列取反得到无效几何。explain_validity给出具体原因常见的是Self-intersection。修复可以用buffer(0)但会改变几何形状建议先定位再手动处理。参数上没有需要调的重点是看输出结果决定下一步。4. 避坑与排查新疆公路shp处理中的5个血泪教训4.1 现象长度统计结果比实际里程大好几倍原因坐标系是地理坐标系单位是度直接算length得到的是度数。解决先to_crs投影到UTM带再算length。新疆跨44N、45N、46N三个带选错带会导致边缘区域变形偏大一般选45N覆盖中部西部数据选44N。4.2 现象合并后属性表出现乱码原因shp的dbf文件默认编码可能是GBK而读取时用了UTF-8。解决读取时指定encodinggbk导出时统一用encodingutf-8。如果已经乱码用geopandas重新读取并指定正确编码再导出。4.3 现象按等级筛选后某些等级为空原因GRADE字段的值不统一比如高速公路和高速混用或者有空格。解决先做值统计用value_counts()看分布再用str.strip()和replace统一。这一步不做后面按等级做的分析会漏掉大量路段。4.4 现象缓冲区分析结果出现大量碎片原因路网在接边处有重复路段缓冲后重叠区域被反复计算。解决合并后必须去重去重依据用几何WKT加名称。如果去重后仍有碎片检查是否有极短路段长度小于1米这类路段通常是数字化误差可以按长度阈值过滤。4.5 现象导出shp后中文属性变成问号原因dbf字段名或字段值编码不兼容。解决导出时加encodingutf-8如果目标软件不支持UTF-8可以导出为GeoJSON或GPKG格式这两种格式对中文支持更好。参数上to_file的driver参数可以指定GPKG。5. 用新疆公路shp跑通一个可达性计算从数据到结论5.1 构建路网数据集并计算节点间最短路径拿到清洗后的路网下一步是把它变成可计算的路网图。常见做法是用networkx或igraph把路段作为边交叉点作为节点。下面这段代码演示如何从shp构建图并计算两个节点间的最短路径。import geopandas as gpd import networkx as nx from shapely.geometry import Point gdf gpd.read_file(xinjiang_roads_merged.shp).to_crs(epsg32645) G nx.Graph() for idx, row in gdf.iterrows(): line row.geometry start line.coords[0] end line.coords[-1] G.add_edge(start, end, weightline.length, namerow.get(NAME, )) # 示例计算两个坐标点之间的最短路径 # 实际使用时需要先把起终点吸附到最近的路网节点 source min(G.nodes, keylambda n: Point(n).distance(Point(500000, 4800000))) target min(G.nodes, keylambda n: Point(n).distance(Point(800000, 4700000))) path nx.shortest_path(G, source, target, weightweight) print(路径节点数:, len(path))逻辑说明遍历每条路段取首尾坐标作为节点路段长度为权重。参数weightweight指定用长度作为权重。实际项目中起终点不会正好落在路网节点上需要先做最近节点吸附这一步可以用geopandas的sjoin_nearest实现。这段代码的价值在于验证路网连通性——如果shortest_path抛异常说明起终点之间不连通需要检查数据是否有断头路。5.2 用等时圈验证路网数据的完整性等时圈是检验路网数据质量的好方法。以某个城市为中心按一定速度计算30分钟、60分钟可达范围如果结果出现明显缺口说明路网有缺失。下面用buffer模拟一个简化版等时圈。import geopandas as gpd gdf gpd.read_file(xinjiang_roads_merged.shp).to_crs(epsg32645) # 以乌鲁木齐附近某点为中心按60km/h计算30分钟可达 center gpd.GeoSeries([gpd.points_from_xy([500000], [4800000])[0]], crsEPSG:32645) reach center.buffer(30000) # 30分钟 * 60km/h 30km # 裁剪路网 roads_in gpd.clip(gdf, reach) print(可达范围内路段数:, len(roads_in))逻辑说明buffer半径按速度和时间计算30分钟60km/h等于30公里投影坐标系下单位是米所以用30000。clip裁剪出路网范围内的路段。如果结果里某些方向完全没有路段说明数据在该方向缺失。这个方法比单纯看地图更能量化数据完整性。5.3 一个我常用的检查习惯每次拿到新的公路shp我不会直接开始做分析而是先花十分钟做三件事打开属性表看字段和值分布、用explain_validity检查几何有效性、按等级画一张全疆分布图。这三步能挡掉八成以上的后续问题。新疆路网数据尤其要注意边境区域和沙漠路段的完整性这些地方往往是数据盲区。希望帮到你。本文还有配套的精品资源点击获取