简介这份资源面向地理信息、城乡规划、交通与水文领域的研究者及GIS初学者提供江苏省河流、湖泊、县域、高速公路等核心地理要素的Shapefile矢量数据可用于地图制作、空间分析与区域研究。压缩包共83个文件约974KB以shp几何数据、dbf属性表、shx索引、prj投影及sbn、sbx空间索引为主另含少量xml元数据与atx文件覆盖河流、湖泊、县域、地级市、国道、铁路、湿地、丘陵、经纬网等多个图层各图层均配套完整属性信息。目前已有2381人学习下载说明该数据在同类资源中具备一定参考价值。读者可直接在ArcGIS、QGIS等软件中导入进行数据叠加、洪水风险与交通网络分析或提取河流长度、湖泊面积等指标为区域规划与科学决策提供基础支撑。1. 江苏省河流湖泊县域高速等 shp 数据一套底图怎么撑起整条分析链路做空间分析的人多半遇到过这种局面手头有一份业务点位表想按行政区汇总发现没有县域边界想算某个点到最近河流的距离发现没有水系图层想统计高速沿线缓冲区内的设施数量发现路网数据是别处拷来的、坐标系还对不上。江苏省河流、湖泊、县域、高速等 shp 数据这类基础地理底图解决的正是这个「万事俱备只差底图」的问题。它面向的是做区域规划、选址评估、环境统计、物流路径分析、数据可视化大屏的从业者也适合刚接触 GIS、需要一套完整练手数据的新手。这类数据的价值不在单个文件而在于水系、行政区、交通三类图层能叠在同一套坐标基准上互相运算——底图不统一后面所有分析都是玄学。2. 先搞清楚这几类 shp 图层各自能干什么拿到一套 shp 数据最忌讳的就是不看清属性表直接往地图上一丢。河流、湖泊、县域、高速这四类图层的几何类型、属性字段、精度层级完全不同用错了轻则统计口径对不上重则空间关系判断全错。这一章先把每类图层的用途和判断标准讲透再谈怎么组织。2.1 河流与湖泊线要素和面要素不能混用河流通常是线要素Polyline湖泊是面要素Polygon这是最基本的区分。但实际数据里经常出现「双线河」——宽度较大的河流被画成两条平行线加中间一个面或者干脆用面表示整条河。判断方法很简单打开属性表看有没有长度字段和面积字段线要素一般带 Length面要素带 Area。用途上线状河流适合做最近距离计算、路径连通性分析、沿线缓冲区。面状湖泊适合做水域面积统计、淹没范围分析、与行政区做相交运算。如果你要做「某县水域面积占比」必须用面要素如果要做「某工厂距最近河流多远」用线要素更直接。一个常见坑是河流图层里混着渠道、沟渠、甚至排水管属性表里往往有个类似 Type 或 Class 的字段区分。不筛选直接统计水域面积会虚高。我一般会先按该字段做一次频数统计把明显不属于自然水系的类别剔掉再往下走。2.2 县域边界行政代码是关联一切的主键县域图层是整套数据里最重要的关联表。它的核心价值不是画个轮廓而是提供一个稳定的行政代码字段常见命名如 adcode、code、PAC让你能把业务数据按区县聚合。拿到县域图层后第一件事是检查三样东西行政代码是否唯一、是否有层级字段省/市/县、边界是否闭合。代码不唯一说明可能混入了乡镇级或重复记录没有层级字段做市级汇总时就得自己拼边界不闭合会导致相交运算出现缝隙或重叠。提示县域边界在不同年份会有调整如果业务数据是历史年份的边界版本对不上会导致归属错误。做时间序列分析前先确认边界年份。2.3 高速路网注意匝道和服务区的干扰高速图层一般是线要素属性里可能包含道路名称、等级、编号。做缓冲区分析时匝道、连接线、服务区内部道路如果没剔除缓冲区会变得支离破碎统计结果偏高。判断是否需要剔除看你的分析目标。如果是「高速沿线 5 公里内有多少个物流园」匝道影响不大如果是「高速主线两侧 500 米噪声影响范围」匝道必须去掉否则城区段会算出一大片本不存在的范围。筛选依据通常是属性表里的等级字段或道路类型字段。2.4 图层组织与坐标系统一四类图层放一起之前必须统一坐标系。国内常用的是 CGCS2000 或各地方坐标系统有些数据还带着 WGS84 经纬度。坐标系不统一叠加时会出现几百米甚至几公里的偏移这种错误在图上不一定看得出来但一算面积和距离就露馅。统一坐标系的判断方法在 GIS 软件里加载两个图层看它们是否严丝合缝重叠。如果县域边界和高速路网明显错位八成是坐标系不一致。处理方式是用投影转换工具统一到同一个投影坐标系不要用地理坐标系直接做距离计算。3. 用 Python 把四类 shp 读进来并做基础校验这一章给一套可以直接抄的代码流程从读取、校验到统一坐标系每一步都说明参数含义和失败时看什么。环境用 geopandas它是目前处理 shp 最顺手的库。3.1 环境准备与依赖安装# 建议用 conda 建独立环境避免和系统 GDAL 冲突 conda create -n gis_base python3.10 conda activate gis_base # geopandas 依赖 GDAL、fiona、pyproj用 conda 装最省心 conda install -c conda-forge geopandas shapely pyproj matplotlib逻辑说明geopandas 底层依赖 GDAL 读取 shp用 pip 装经常因为 GDAL 版本不匹配报错conda-forge 渠道的预编译包能避开大部分坑。参数上 python 版本选 3.10 是因为部分地理库对 3.11 以上支持还不稳求稳不追新。3.2 批量读取四类图层并打印基本信息import geopandas as gpd import os # 数据目录按实际路径改 data_dir ./jiangsu_shp # 四类图层的文件名关键词按实际命名调整 layers { river: river, # 河流线 lake: lake, # 湖泊面 county: county, # 县域边界 highway: highway # 高速路网 } gdfs {} for key, kw in layers.items(): # 遍历目录找匹配的 shp for f in os.listdir(data_dir): if f.endswith(.shp) and kw in f.lower(): path os.path.join(data_dir, f) gdf gpd.read_file(path) gdfs[key] gdf # 打印几何类型、要素数、坐标系 print(f[{key}] 文件: {f}) print(f 几何类型: {gdf.geom_type.unique()}) print(f 要素数量: {len(gdf)}) print(f 坐标系: {gdf.crs}) print(f 字段: {list(gdf.columns)}) print(- * 40)逻辑说明这段代码做的是「先看清再动手」。geom_type 打印出来能立刻发现河流图层里是不是混了面要素crs 打印出来能发现坐标系是否为空或与预期不符字段列表让你知道后面按哪个字段筛选。参数上kw in f.lower()是模糊匹配因为实际文件名可能带年份或版本后缀写死文件名容易翻车。3.3 坐标系检查与统一转换# 目标坐标系CGCS2000 高斯投影按江苏所在带号选 # 江苏跨 3 度带 39 和 40 带这里以 40 带为例 target_crs EPSG:4547 # CGCS2000 / 3-degree Gauss-Kruger CM 120E for key, gdf in gdfs.items(): if gdf.crs is None: print(f[警告] {key} 坐标系为空需要手动指定原始坐标系) continue if gdf.crs.to_epsg() ! 4547: # 转换到目标坐标系 gdfs[key] gdf.to_crs(target_crs) print(f[{key}] 已转换: {gdf.crs} - {target_crs}) else: print(f[{key}] 坐标系已匹配无需转换)逻辑说明to_crs 做的是投影转换不是简单改标签。如果原始坐标系为空不能直接 to_crs必须先 set_crs 指定原始坐标系再转换否则结果会偏。参数 EPSG:4547 对应 CGCS2000 三度带 120E 中央经线江苏东部用这个西部可能要用 39 带EPSG:4546。选错带号会导致东西向偏移做距离计算时误差随距离累积。3.4 县域边界闭合性与代码唯一性校验county gdfs[county] # 检查行政代码字段是否唯一字段名按实际改 code_field adcode # 常见命名还有 code、PAC if code_field in county.columns: dup county[county.duplicated(subsetcode_field, keepFalse)] if len(dup) 0: print(f[警告] 行政代码重复 {len(dup)} 条需排查) else: print([通过] 行政代码唯一) else: print(f[警告] 未找到字段 {code_field}请确认实际字段名) # 检查几何有效性 invalid county[~county.is_valid] if len(invalid) 0: print(f[警告] 存在无效几何 {len(invalid)} 条尝试修复) county[geometry] county.buffer(0) # buffer(0) 是常用的几何修复手段 else: print([通过] 几何全部有效)逻辑说明duplicated 找出重复代码重复往往意味着数据混入了不同层级。is_valid 检查几何是否自相交或未闭合buffer(0) 是修复无效几何的常用手段能把自相交的多边形修正为有效几何。参数 keepFalse 让所有重复项都显示出来方便定位。4. 避坑与排查这几类 shp 数据最容易翻车的地方基础地理数据看着简单实际用起来坑不少。这一章列五条我踩过的每条按现象、原因、解决写清楚。4.1 叠加后图层错位几百米现象县域边界和高速路网加载到同一张图上明显对不齐路网整体偏移。原因两个图层坐标系不一致一个是地理坐标系经纬度一个是投影坐标系米或者投影带号不同。解决用 to_crs 统一到同一投影坐标系。如果其中一个 crs 为空先确认它的真实坐标系再 set_crs不要盲目转换。判断方法是对比两个图层里同一个明显地物的坐标值差一个数量级就是坐标系类型不同。4.2 水域面积统计结果虚高现象按县域统计水域面积结果比实际大很多。原因河流图层里混入了渠道、沟渠、甚至面状河流和线状河流重复计算或者湖泊图层包含了水库、池塘等非自然水域。解决先看属性表里的类型字段做频数统计把不属于目标类别的记录筛掉。如果河流同时有线和面明确用哪个不要两个都算。4.3 缓冲区分析结果破碎现象对高速做缓冲区得到的范围断断续续城区段尤其明显。原因高速图层包含匝道、连接线、服务区道路这些短线段各自生成缓冲区后不连续。解决按道路等级或类型字段筛选出主线再做缓冲区。如果属性表没有区分字段可以按线段长度过滤匝道通常很短。4.4 行政代码关联不上业务数据现象用行政代码把业务数据关联到县域边界大量记录匹配失败。原因代码字段类型不一致一边是字符串一边是整数或者代码位数不同一边带前导零一边不带。解决关联前统一转成字符串并补齐位数。用 astype(str).str.zfill(6) 把代码统一成 6 位字符串再关联。4.5 几何无效导致相交运算报错现象做空间相交或叠加分析时程序报错提示几何无效。原因多边形自相交、边界未闭合、重复节点等。解决用 buffer(0) 或 make_valid 修复。修复后重新检查 is_valid确认全部通过再往下做。修复前先备份原始数据buffer(0) 在极端情况下会改变几何形状。5. 从底图到分析结果一个县域水域占比的完整算例前面讲了读取、校验、避坑这一章把流程串起来做一个具体算例统计每个县的水域面积占比。这个算例覆盖了面要素相交、面积计算、分组汇总三个核心操作跑通它其他类似分析都能照搬。5.1 水域图层合并与县域相交# 合并河流面和湖泊面作为水域假设河流已筛选为面要素 water gdfs[lake].copy() # 如果有面状河流用 pd.concat 合并 # import pandas as pd # water pd.concat([water, river_polygon], ignore_indexTrue) county gdfs[county].copy() # 确保两者坐标系一致 water water.to_crs(county.crs) # 空间相交水域与县域求交 intersect gpd.overlay(water, county, howintersection) # 计算相交后的面积单位取决于投影坐标系EPSG:4547 下是平方米 intersect[water_area] intersect.geometry.area # 按行政代码汇总水域面积 water_stat intersect.groupby(adcode)[water_area].sum().reset_index() # 计算县域总面积 county[total_area] county.geometry.area county_stat county[[adcode, total_area]].merge(water_stat, onadcode, howleft) # 计算水域占比缺失值填 0 county_stat[water_area] county_stat[water_area].fillna(0) county_stat[water_ratio] county_stat[water_area] / county_stat[total_area] print(county_stat[[adcode, water_ratio]].head())逻辑说明overlay 的 howintersection 保留两个图层的重叠部分这是水域归属到县的关键步骤。面积计算依赖投影坐标系EPSG:4547 单位是米算出来是平方米。groupby 按行政代码汇总merge 时用 howleft 保证没有水域的县也保留fillna(0) 把缺失水域面积补零否则占比会变成 NaN。参数上 water_ratio 是小数需要百分比的话乘 100。5.2 结果校验与异常值排查算完之后不能直接出图先做两件事检查占比是否超过 1检查是否有县的水域面积为 0。占比超过 1 说明水域图层有重叠或县域边界有重叠需要回去查几何。水域面积为 0 可能是该县确实没有水域也可能是行政代码没匹配上需要对比原始数据确认。我一般会把占比排序看头尾几个是否符合常识明显异常的单独拎出来查。5.3 导出结果与可视化# 导出为 shp 或 csv county_stat.to_file(./output/county_water_ratio.shp, encodingutf-8) county_stat.drop(columnsgeometry).to_csv(./output/county_water_ratio.csv, indexFalse) # 简单可视化 import matplotlib.pyplot as plt fig, ax plt.subplots(figsize(10, 8)) county_stat.plot(columnwater_ratio, cmapBlues, legendTrue, axax) ax.set_title(Water Ratio by County) plt.savefig(./output/water_ratio_map.png, dpi150)逻辑说明to_file 导出 shp 时指定 encodingutf-8 避免中文乱码这是血泪经验默认编码在部分环境下会把中文字段名写坏。drop(columnsgeometry) 导出 csv 时去掉几何列否则 csv 里会多一列无法阅读的 WKB。可视化用 plot 的 column 参数按占比着色cmap 选 Blues 是因为水域用蓝色系直观。5.4 参数调整与复用这套流程换其他分析目标时只需要改三处水域图层的筛选条件、相交的目标图层、汇总的字段。比如改成统计高速缓冲区内的设施数量就把水域换成高速缓冲区县域换成设施点位overlay 换成空间连接sjoin面积汇总换成计数。注意sjoin 和 overlay 的区别在于sjoin 只判断空间关系并附加属性不切割几何overlay 会实际切割几何。做计数用 sjoin 更快做面积统计必须用 overlay。6. 进阶技巧让这套底图数据真正好用起来基础流程跑通之后有几个习惯能让这套数据用起来更顺。第一个是建一个统一的字段映射表把不同来源图层的行政代码字段名、类型、位数记下来每次关联前先查表避免重复踩坑。第二个是把坐标系转换和几何修复封装成函数每次读数据先过一遍不要等到分析报错才回头处理。第三个技巧是关于精度取舍。基础地理数据精度越高文件越大处理越慢。做省级尺度的分析县域边界用 1:100 万精度足够做县级尺度的选址可能需要 1:10 万甚至更高。不要盲目追求高精度先明确分析尺度再选数据精度否则会在数据加载和运算上浪费大量时间。第四个是版本管理。行政边界和路网数据会更新每次更新后重新跑一遍校验流程对比新旧版本的差异确认没有引入新的几何问题。我一般会把每次校验的结果存成日志出问题时能快速定位是哪次更新引入的。最后一个习惯是永远保留原始数据不动所有处理都在副本上做。buffer(0) 修复几何、to_crs 转换坐标系这些操作都会改变数据一旦在原始文件上操作出了问题没有后悔药。这个习惯看着简单但真到数据出错的时候能省下大量返工时间。希望帮到你。本文还有配套的精品资源点击获取