十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

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

重庆各级公路Shapefile数据处理与应用:从文件结构到缓冲区分析

重庆各级公路Shapefile数据处理与应用:从文件结构到缓冲区分析 简介面向GIS分析与交通规划人员提供重庆全市各级公路网络与区县行政区划矢量数据。资源按一级公路、二级公路、三级公路及高速公路分类整理同时包含重庆各区县边界shp可用于路网可视化、区域连通性分析、交通可达性计算及城市空间研究等场景。包体共35个文件压缩包约1.15MB。除几何数据shp外还配齐dbf属性表、prj投影信息、shx索引及sbn/sbx空间索引并附带xml元数据适合在ArcGIS、QGIS等平台直接加载使用。结构简洁命名规范便于按公路等级或区县范围快速筛选调用。已有680人学习下载尤其适合需要基础路网底图开展教学实验、课题调研或业务制图的用户。结合人口、土地利用等数据后可进一步支撑交通规划、应急响应与城乡发展分析。1. 重庆各级公路shp文件到底是什么打开压缩包那一刻你会看到一整套完整的公路分级矢量数据重庆高速公路、一级公路、二级公路、三级公路再加上各区县行政区划面。这不是单张shp而是每个图层都标配了.shp、.dbf、.shx、.prj、.sbn、.sbx甚至还有.xml元数据文件。也就是说拿到手不需要修补坐标系直接拖进QGIS或ArcGIS就能用省去了最常见的“投影对不上”的麻烦。对于做区域交通分析、路网密度计算或者城市规划的人来说这套数据最值钱的不是“有没有路”而是“路分了几级”——高速公路、一二三级公路分别对应不同的通行能力、设计时速和规划口径这决定了你能不能准确算路网等级结构、做缓冲区分析、甚至为应急路径规划提供基础底图。适合的人群很明确GIS开发工程师、交通规划师、想做地图可视化的数据分析师以及需要行政边界和路网叠加做空间统计的研究人员。需要注意的是压缩包内容以重庆为范围名称里的“四川”只是历史行政区划沿革的残留实际使用以.shp边界范围为准。2. Shapefile组成与公路等级编码规则2.1 每个shp图层附带的那堆文件都是干什么的一套完整的shapefile不是单个文件而是一组配套文件的集合。你看到每个图层都有.shp、.dbf、.shx、.prj这是最核心的四件套缺一不可。.shp存几何坐标.dbf存属性表.shx是几何索引.prj存坐标系信息。除此之外还有.sbn和.sbx这是ArcGIS生成的空间索引文件只影响查询性能损坏了可以重建。.xml是元数据记录图层来源、字段说明和坐标系信息对数据校验很有用。以重庆二级公路.shp这一套为例常见的文件组合如下文件后缀作用缺失后果.shp几何数据点线面坐标无法显示地图.dbf属性数据道路等级、名称等无法查属性.shx几何位置索引部分软件打不开.prj坐标系定义坐标位置偏移.sbn / .sbx空间索引加载变慢可重建.xml元数据不影响使用但信息丢失这套数据里每个图层的文件是完整的.prj都在这是好事。很多网上下载的道路shp只有.shp和.dbf没有.prj结果在QGIS里默认跑到WGS84上跟其他数据一叠就跑到海里去了。拿到手第一步应该先看.prj内容确认坐标系统。2.2 公路等级在属性表里怎么编码打开重庆高速公路.dbf你会看到属性字段通常包括路名、编号、长度、等级等。不同数据源编码规则不一致有的用中文“高速公路”“一级公路”有的用代码“1”“2”“3”“4”。这份数据里从文件名能看出已经把等级拆成了单独图层但属性表里仍然可能有“class”或“grade”字段需要实际打开确认。我一般拿到shp会先用QGIS的属性表看一眼字段类型和值域再决定后续操作。常见做法是新建一个字段level_code把高速公路赋值为1一级公路为2二级公路为3三级公路为4。这样后面做样式分级、按等级做不同宽度渲染、或者导出成GeoJSON给前端地图用都比直接用中文字段名更省事。如果属性表里没有等级字段也完全不用慌。因为文件名已经分层直接在QGIS里按图层合并时手动指定等级即可。用Python的geopandas读取时也是同样道理import geopandas as gpd express gpd.read_file(重庆高速公路.shp) express[level_code] 1 primary gpd.read_file(重庆一级公路.shp) primary[level_code] 2 secondary gpd.read_file(重庆二级公路.shp) secondary[level_code] 3 tertiary gpd.read_file(重庆三级公路.shp) tertiary[level_code] 4 all_roads gpd.concat([express, primary, secondary, tertiary], ignore_indexTrue) print(all_roads.crs)这段代码把四个等级图层分别读取打上等级编码后纵向合并成一个完整路网。ignore_indexTrue是为了避免多个图层索引重复导致后续处理出错。合并前先打印crs确认坐标系一致四个图层的.prj如果都是从同一来源导出的坐标系应该相同但保险起见还是检查一下否则后续空间分析会出现“几何无效”或距离单位错误。2.3 坐标系判断prj里写的到底是什么打开重庆各区县.prj常见的坐标系有两种一种是GCS_WGS_1984经纬度单位另一种是CGCS2000_3_Degree_GK_Zone_35或类似投影坐标单位是米。如果是经纬度算距离时先转投影如果是投影坐标直接就能算长度。用文本编辑器打开.prj可以看到完整定义。QGIS里双击图层也能看到CRS信息。如果发现四个公路图层的坐标系跟区县图层不一致建议统一用重庆本地的投影坐标系比如EPSG:4547CGCS2000 / 3-degree Gauss-Kruger CM 108E因为重庆大致位于东经108度附近。这样后续做缓冲区、算路网密度单位都是米不用再换算。3. 加载、预览与基本检查3.1 用QGIS加载并查看路网拓扑把压缩包解压后QGIS里直接拖拽.shp到图层窗口即可。如果安装了QGIS推荐先打开重庆各区县.shp用半透明填充作为底图再叠加四个公路图层。这样能快速看出道路分布是否合理比如高速公路是不是跨区县连续有没有断头路。加载后按F6打开属性表重点检查几个字段道路名称是否完整、是否出现大量空值、几何类型是不是LineString。有一种常见坑某些shp文件内容本来是线但属性表里混入了点或多点导致后续网络分析报错。可以用QGIS的“检查几何有效性”工具跑一遍工具在“矢量”菜单下的“几何工具”里。如果出现“自相交”或“重复节点”问题先记下来后面用特定方法修复。3.2 命令行快速检查shp文件是否完整没有图形界面时用ogrinfo命令能快速看图层几何类型、字段列表和要素数量。这是GDAL自带的工具跨平台可用。打开终端执行ogrinfo -so 重庆高速公路.shp 重庆高速公路-so是只读汇总不遍历全部要素。输出里会显示Layer name、Geometry类型、Feature Count以及所有字段名和类型。这条命令最大的价值是快速确认shp有没有损坏、字段有没有丢失。如果ogrinfo报错“Failed to open shapefile”先检查.shx是否跟.shp在同目录且文件名一致这是最常见的打开失败原因。参数说明第一个参数是shp文件路径第二个参数是图层名。因为在shapefile格式里图层名默认就是文件名去掉后缀所以这两个参数通常一样。如果记不住也可以只写文件路径不写第二个参数ogrinfo会列出该文件所有图层。3.3 用Python做一次路网完整性校验如果想做更细的校验比如检查每条路是否有节点、有没有孤立路段写段Python脚本最方便。用geopandas读取后查看几何类型和边界import geopandas as gpd roads gpd.read_file(重庆一级公路.shp) print(roads.geom_type.unique()) # 应输出 LineString print(roads.is_valid.sum(), 条有效几何) print(roads.geometry.length.min()) # 最小长度单位为度或米geom_type.unique()能看出来有没有混入Point或Polygon。is_valid是shapely的几何有效性检查如果出现False后面做缓冲区、叠加分析时很可能会有异常结果。长度单位取决于坐标系如果是WGS84经纬度长度单位是度读数没有实际意义需要转换为投影坐标系再算。常见做法是用roads.to_crs(epsg4547)转换后再算长度。4. 按等级提取、缓冲区分析与shp转txt实战4.1 提取某一条高速公路的沿线缓冲区重庆高速公路.shp里包含多条高速线路。假设需要分析G5001重庆绕城高速两侧3公里范围内的用地类型第一步是按名称筛选出这条高速然后建缓冲区。在QGIS里用“按表达式选择要素”表达式写name LIKE %绕城%选中后右键图层导出保存为新文件。或者用Pythonimport geopandas as gpd highway gpd.read_file(重庆高速公路.shp) ring highway[highway[name].str.contains(绕城, naFalse)] ring ring.to_crs(epsg4547) # 投影到米制坐标 buffer_3km ring.geometry.buffer(3000) gpd.GeoDataFrame(geometrybuffer_3km, crsring.crs).to_file(绕城高速_3km缓冲区.shp)这里的关键是先把数据投影到EPSG:4547这样buffer(3000)的单位是米。如果跳过投影直接在经纬度上做缓冲区3000会被当成3000度结果完全错误。这是shp处理里最常见的灾难性失误我在很多项目里看到过坐标没转就直接做缓冲区的例子出来的范围能覆盖半个中国。4.2 把shp转成txt导出路网坐标热词里经常有人搜“shp转txt”实际场景是把路网坐标导出成文本给交通仿真的路网生成工具或者自研地图引擎用。每一条路的每个折点坐标写一行格式自定。用Python实现import geopandas as gpd import numpy as np roads gpd.read_file(重庆三级公路.shp) roads roads.to_crs(epsg4547) with open(roads.txt, w) as f: for geom in roads.geometry: if geom.geom_type LineString: for x, y in geom.coords: f.write(f{x:.3f},{y:.3f}\n) elif geom.geom_type MultiLineString: for line in geom.geoms: for x, y in line.coords: f.write(f{x:.3f},{y:.3f}\n)输出每行是一个点坐标x和y分别是投影后的横纵坐标:.3f保留到毫米级。如果后续要重建线段关系最好每条线之间留一行空行或者标记线ID。这个例子里只输出坐标适合做点集可视化不适合做路网重建。如果你是想输出带线段起止关系的拓扑txt建议同时把每条路在属性表里的唯一ID也写进去。4.3 渔网分割shp把大路网切成瓦片做web地图加载大路网时直接把整个shp转GeoJSON会很卡常见做法是把路网切分成网格然后分块处理。“渔网分割”就是生成一个规则网格用空间裁剪把原图层切割成多个小块。QGIS里有“创建渔网”工具参数包括网格范围、宽度、高度。也可以直接用Python批量炸开import geopandas as gpd from shapely.geometry import box roads gpd.read_file(重庆各级公路.shp) xmin, ymin, xmax, ymax roads.total_bounds grid_width 10000 # 10km见方 cols int((xmax - xmin) / grid_width) 1 rows int((ymax - ymin) / grid_width) 1 for i in range(rows): for j in range(cols): minx xmin j * grid_width maxx minx grid_width miny ymin i * grid_width maxy miny grid_width grid_cell box(minx, miny, maxx, maxy) clipped gpd.clip(roads, grid_cell) if not clipped.empty: clipped.to_file(ftile_{j}_{i}.shp)total_bounds返回整个路网的最小外接矩形然后按10公里边长切网格。gpd.clip做的是几何裁剪只保留落在网格内的线段并用not clipped.empty跳过空网格。这个方案适合把重庆全境路网切块并行处理切出来的每个tile都可以单独转成GeoJSON或者3D Tiles。注意这里的坐标系必须是投影坐标系否则10000会被当成经度差网格形状会变形。5. 修复shp问题、转GDB与只保留外边界线5.1 用shapechecker修复损坏的shp文件从网上下来的shp十有八九会有拓扑问题尤其是反复编辑过或者从CAD转换过来的。特征表现是QGIS打开后部分线段消失、属性表行数对不上、或者求长度时出现负数。这种情况下首选工具是ShapeChecker一个免费的小工具专门用来检查和修复shapefile的几何错误。打开软件后导入.shp它会列出所有如空几何、重复顶点、线段自相交等问题并一键修复。修复前后最好做一次备份。因为ShapeChecker有时会改动顶点顺序导致原本正确的方向字段反向。操作路径启动软件选择“File”里的“Open Shapefile”等扫描结束在问题列表里右键点击每一项选择“Repair”然后另存为新文件。修复后的shp再丢回QGIS里验证一遍看要素数量是否和原始dbf记录数一致。5.2 shp转gdb是不是同一个东西“shp转gdb”完全不是一个概念。shp是单文件集gdbFile Geodatabase是ArcGIS的文件夹式数据库可以装多个要素类支持拓扑规则、网络数据集和字段别名。如果项目要求把重庆各级公路全部塞进一个gdb里用gdal命令最快ogr2ogr -f FileGDB 重庆公路.gdb 重庆高速公路.shp ogr2ogr -f FileGDB 重庆公路.gdb 重庆一级公路.shp -nln 一级公路第一条命令把高速公路写入gdb第二条用-nln指定要素类名称不然还是沿用原名“重庆一级公路”。写入后gdb里就会多一个名叫“一级公路”的要素类。gdb的好处是属性字段长度、索引、空间参考都统一管理不需要维护一堆.sbn文件。但要注意gdb不能跨平台在QGIS里直接读除非把环境变量OGR_DRIVER_PATH配好或者用GeoPackage代替后者是跨平台的标准格式。5.3 只保留外边界线删除内部道路网有时候做地图背景只需要行政区边界不需要内部路网。shp有没有办法只保留外边界线如果是区县边界shp内部有很多子边界只保留外轮廓的方法是把面转线再删掉非外环线。QGIS里用“Polygons to lines”把面转成线后线属性表里有left和right字段表示这条线左右两侧的面。正常情况下外部边界线一侧是地块另一侧是空值。筛选条件left IS NULL OR right IS NULL这样就能滤出外边界线导出后就是只保留外轮廓的shp。如果数据没有左右字段用Python的shapely处理也可以import geopandas as gpd from shapely.geometry import LineString admin gpd.read_file(重庆各区县.shp) admin admin.to_crs(epsg4547) outer_lines [] for geom in admin.geometry: if geom.geom_type Polygon: outer_lines.append(LineString(geom.exterior)) elif geom.geom_type MultiPolygon: for part in geom.geoms: outer_lines.append(LineString(part.exterior)) outer_gdf gpd.GeoDataFrame(geometryouter_lines, crsadmin.crs) outer_gdf.to_file(重庆各区县_外边界线.shp)geom.exterior取Polygon的外环MultiPolygon则逐个取。生成的结果一定是线要素包含重庆市级外部边界内部区县之间的分界线全部排除。这个技巧在做城市群专题图、去掉内部行政区隔线时非常有用。配合公路shp叠加可以快速做出一张“只有边界路网”的交通底图。本文还有配套的精品资源点击获取
返回列表