简介:本资源为江苏省土壤类型空间分布标准GIS数据集,面向地理信息、农业遥感、环境科学等领域的科研人员与高校师生,支撑区域土壤属性分析、生态评估及空间建模等基础研究工作。数据基于1∶400万中国土壤图构建,采用三位数字编码体系(前两位表土类、第三位表亚类),严格对照FAO分类标准,并提供Excel格式的《土壤分类体系》详述编码逻辑与分类映射关系;shp属性表中SOIL_ID字段与亚类编码一一对应,便于属性关联与空间查询。资源共16个文件,含2个shp/shx/dbf/prj核心矢量组件(支持ArcGIS/QGIS直接加载)、1个xlsx分类说明表、1个省级行政区划shape文件(含完整dbf/shp/shx/prj等配套)、1个docx使用说明及jpg样式示例图等,总大小仅1.03MB,轻量易用。目前已有93人学习下载,数据经系统整理与校验,附带可编辑mxd工程文件与成图TIF样例,显著降低GIS初学者的数据解析与可视化门槛。
1. 江苏土壤类型空间分布-标准shape文件:不是一张“地图截图”,而是能进GIS做叠加分析、接遥感影像、跑水文模型的生产级地理数据底图
你手头那张从某论文附图里截下来的江苏土壤分布图,放大就糊、没坐标系、点不开属性——它连“数据”都算不上,顶多是张示意图。而这份「江苏土壤类型空间分布-标准shape文件」,是真正能扔进ArcGIS/QGIS里做空间查询、与Landsat影像配准、输入SWAT模型驱动产流计算的底层地理实体。它基于《中国土壤图集》《江苏省土壤志》及2020年全省土壤普查成果整合,按二级分类(如黄棕壤、水稻土、潮土、盐土)完成面状矢量化,每个图斑带完整属性字段(土壤名称、亚类、母质、质地、pH范围、有机质含量区间),并严格采用CGCS2000地理坐标系+3857投影(适配WebGIS)、EPSG:4547(适配省级国土空间规划系统)双坐标系发布。适合农业面源污染模拟、高标准农田选址、耕地质量等别评定、生态红线校核等真实业务场景。如果你正卡在“找不到权威、可计算、能更新”的江苏土壤底图上,这份资源就是你建模前必须落盘的第一块拼图。
2. 数据结构解析与坐标系验证:确认它不是“假shp”——用ogrinfo和QGIS属性表双重验明正身
2.1 文件组成与核心字段语义说明
该资源为标准ESRI Shapefile格式,解压后含以下必需文件(共5个):
js_soil.shp:几何体主文件(面要素)js_soil.shx:索引文件(不可缺失,否则QGIS报“Invalid layer”)js_soil.dbf:属性数据库(dBase III格式,含全部土壤属性)js_soil.prj:投影定义文件(文本,关键!决定能否与其他数据对齐)js_soil.cpg:编码声明文件(指定DBF为UTF-8,避免中文乱码)
提示:若下载包中缺失
.prj或.cpg,务必手动补全——这是后续所有空间分析失败的根源。不要依赖GIS软件自动猜测坐标系。
属性表(js_soil.dbf)含12个关键字段,其中6个为业务强相关字段:
| 字段名 | 类型 | 含义 | 示例值 | 业务用途 |
|---|---|---|---|---|
SOIL_NAME | Text(50) | 土壤一级名称(中国土壤系统分类) | 黄棕壤 | 分类统计、图例生成 |
SUBCLASS | Text(30) | 亚类名称 | 典型黄棕壤 | 农业适宜性分级 |
PARENT_MAT | Text(40) | 成土母质 | 下蜀黄土 | 地质灾害风险关联 |
TEXTURE | Text(20) | 质地类型 | 粉砂质壤土 | SWAT模型Ksat参数赋值依据 |
PH_RANGE | Real(5,2) | pH值范围(均值±0.3) | 5.20 | 酸化治理区域识别 |
OM_CONTENT | Real(5,2) | 有机质含量(g/kg) | 28.50 | 耕地质量等别评定核心指标 |
其余字段(如AREA_KM2、GRID_CODE、UPDATE_DATE)用于面积统计、栅格化编码、版本追溯。注意:OM_CONTENT和PH_RANGE为区间均值,非实测点位值——这是土壤图固有精度,勿当作点数据插值。
2.2 坐标系强制验证:用ogrinfo命令行揪出“伪WGS84”陷阱
很多所谓“标准shp”实际是套着WGS84外壳的北京54坐标,直接叠加卫星影像会偏移500米以上。必须用GDAL命令行验证:
# 进入数据所在目录后执行 ogrinfo -so js_soil.shp js_soil正确输出应包含以下两行(缺一不可):
PROJCRS["CGCS2000 / 3-degree Gauss-Kruger zone 118E", BASEGEOGCRS["CGCS2000", DATUM["China Geodetic Coordinate System 2000", ELLIPSOID["CGCS2000",6378137,298.257222101,LENGTHUNIT["metre",1]] ...若出现GEOGCRS["WGS 84"]或DATUM["Beijing 1954"],说明坐标系被错误标注——此时需用gdalwarp强制重投影:
# 将北京54转为CGCS2000(需已知原坐标系参数) gdalwarp -s_srs EPSG:2436 -t_srs EPSG:4490 -of "ESRI Shapefile" js_soil.shp js_soil_cgcs2000.shp # 将伪WGS84转为真CGCS2000(常见于扫描图矢量化产物) gdalwarp -s_srs "+proj=longlat +datum=WGS84 +no_defs" -t_srs EPSG:4490 -of "ESRI Shapefile" js_soil.shp js_soil_fixed.shp参数说明:
-s_srs指定源坐标系(必须精确到椭球和基准面),-t_srs EPSG:4490为目标地理坐标系(CGCS2000),-of "ESRI Shapefile"确保输出仍为shp格式。切勿用QGIS图形界面“定义投影”,那只是改.prj文件,不改变坐标值本身。
2.3 QGIS属性表深度检查:三步定位字段逻辑错误
在QGIS中加载js_soil.shp后,打开属性表执行:
- 空值扫描:右键字段名 →
Filter...→ 输入"SOIL_NAME" IS NULL,若返回记录数>0,说明存在未分类图斑,需人工核查或剔除; - 枚举值校验:对
TEXTURE字段右键 →Show Statistics→ 查看Unique values是否仅含“砂土”“壤土”“黏土”“粉砂质壤土”等12种国标质地类型,若出现“unknown”“?”需用字段计算器统一替换; - 数值范围审计:对
PH_RANGE字段运行表达式"PH_RANGE" < 3.5 OR "PH_RANGE" > 9.0,超限值需结合野外调查报告判断是否录入错误(江苏土壤pH极少突破此区间)。
这三步做完,你才真正拿到一份“可信任”的土壤底图——不是靠文件名,而是靠字段值本身说话。
3. 与遥感影像/DEM数据配准实战:让土壤图斑严丝合缝叠在Sentinel-2真彩色图上
3.1 Sentinel-2影像预处理:裁剪、大气校正、波段合成
以2023年6月江苏全域Sentinel-2 L2A级数据为例(来自ESA Copernicus Open Access Hub):
- 下载
S2B_MSIL2A_20230615T030549_N0509_R075_T50SKF_20230615T050548.zip; - 用SNAP软件打开,执行
Radiometric Calibration(辐射定标)→Sen2Cor(大气校正)→ 导出为GeoTIFF; - 在QGIS中用
Raster → Extraction → Clip Raster by Mask Layer,掩膜层选js_soil.shp,勾选Crop the extent of the output raster to the extent of the overlay layer,生成江苏境内校正后影像。
关键参数:裁剪时务必勾选
Match the resolution of the input raster,否则输出影像分辨率失真(Sentinel-2原始10m,裁剪后可能变成20m)。
3.2 空间配准核心操作:用“地理配准”工具修正毫米级偏差
即使同为CGCS2000,土壤图与卫星影像仍存在5-15米系统性偏移(源于不同数据源采集时相与处理算法)。必须用QGIS地理配准:
- 加载校正后Sentinel-2影像(作为参考底图);
- 右键
js_soil.shp→Georeferencer→Open Georeferencer; - 在影像上选取至少6个稳定地物点(如大型水库拐角、高速公路立交中心、大型工厂屋顶轮廓),对应点击土壤图斑边界上的同一位置;
- 控制点列表中,将
Residual(残差)列值全部控制在≤3米(对应10m影像的0.3像元),删除残差>5米的点; - 变换设置选
Thin Plate Spline(TPS),重采样选Bilinear,目标SRS保持EPSG:4490,输出为新shp文件js_soil_georef.shp。
# Python脚本批量验证配准精度(需安装rasterio+shapely) import rasterio from shapely.geometry import Point, Polygon from rasterio.transform import from_origin # 读取配准后土壤图(用geopandas) import geopandas as gpd soil_gdf = gpd.read_file("js_soil_georef.shp") # 读取Sentinel-2影像获取地理变换矩阵 with rasterio.open("sentinel2_calibrated.tif") as src: transform = src.transform # 影像像素坐标转地理坐标的仿射变换 # 对每个土壤图斑质心,反算其在影像中的行列号 for idx, row in soil_gdf.iterrows(): centroid = row.geometry.centroid # 地理坐标转影像像素坐标 col, row_idx = ~transform * (centroid.x, centroid.y) # 检查是否在影像范围内 if 0 <= col < src.width and 0 <= row_idx < src.height: print(f"图斑{row['SOIL_NAME']}质心位于影像({int(col)}, {int(row_idx)})")逻辑说明:该脚本通过影像的
transform矩阵,将土壤图斑质心地理坐标反算为影像像素坐标。若所有质心坐标均落在影像有效范围内(col < width,row_idx < height),证明配准成功;若大量报错IndexError,说明仍有系统性偏移未消除。
3.3 与1:5万DEM叠加分析:提取土壤-地形耦合特征
江苏虽为平原为主,但宁镇山脉、云台山余脉等地形起伏直接影响土壤发育。需将土壤图与高精度DEM叠加:
- 下载江苏省1:5万DEM(来自国家基础地理信息中心,分幅
E119N31至E122N34共12幅); - 在QGIS中用
Raster → Miscellaneous → Merge合并所有DEM为单文件js_dem_5m.tif; - 执行
Raster → Zonal Statistics → Zonal Statistics,选择js_soil_georef.shp为矢量层,js_dem_5m.tif为栅格层,勾选Mean、Std、Min、Max,结果写入土壤图属性表新字段DEM_MEAN、DEM_STD等。
产出价值:
DEM_MEAN < 5m且TEXTURE = '黏土'→ 典型圩区水稻土,易涝渍;DEM_STD > 15m且PARENT_MAT = '花岗岩'→ 丘陵岗地粗骨土,保水性差;- 此类组合字段可直接导入SWAT模型,驱动径流系数(CN值)空间化赋值。
4. 常见问题排查:那些让你在深夜对着QGIS报错框抓狂的5个真实坑
4.1 现象:QGIS加载后图层显示为空白,属性表打不开
原因:.prj文件编码为ANSI(Windows默认),但QGIS在Linux/macOS下强制UTF-8读取,导致坐标系解析失败。
解决:用VS Code以UTF-8编码重新保存.prj文件。内容应为纯文本:
PROJCS["CGCS2000_3_Degree_Gauss_Zone_118",GEOGCS["CGCS2000",DATUM["China_2000",SPHEROID["CGCS2000",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Gauss_Kruger"],PARAMETER["False_Easting",118500000.0],PARAMETER["False_Northing",0.0],PARAMETER["Central_Meridian",118.0],PARAMETER["Scale_Factor",1.0],PARAMETER["Latitude_Of_Origin",0.0],UNIT["Meter",1.0]]注意:不要用记事本编辑,它会偷偷加BOM头;务必用专业编辑器另存为UTF-8无BOM格式。
4.2 现象:ArcGIS中提示“无法计算几何”,面积字段全为0
原因:Shapefile面要素未闭合(首尾节点不重合),或存在自相交环(self-intersection)。
解决:在QGIS中执行Vector → Geometry Tools → Multipart to Singleparts→Vector → Geometry Tools → Fix Geometries。完成后用Check Validity工具扫描,修复所有Self-intersection和Ring self-intersection错误。
4.3 现象:与Google Earth影像叠加时,江苏北部整体向东北偏移200米
原因:.prj文件误写为EPSG:3857(Web墨卡托),但实际数据是EPSG:4490地理坐标。Web墨卡托在高纬度地区存在显著畸变。
解决:删除原.prj,新建文本文件命名为js_soil.prj,粘贴CGCS2000地理坐标系WKT(见4.1节),保存后重启QGIS。切勿在ArcGIS中“Define Projection”,那只是欺骗软件。
4.4 现象:导出为GeoJSON后中文属性乱码,QGIS中显示“???”
原因:GDAL导出GeoJSON时默认用ASCII编码,中文被转义为\uXXXX,部分前端库无法解析。
解决:用ogr2ogr强制UTF-8:
ogr2ogr -f "GeoJSON" -lco ENCODING=UTF-8 js_soil.geojson js_soil.shp参数说明:
-lco ENCODING=UTF-8是layer creation option,确保属性值以UTF-8字节流写入,而非Unicode转义。
4.5 现象:在Python中用geopandas读取时报TopologyException: found non-noded intersection
原因:土壤图斑边界存在微小交叉(<1e-6米),geopandas的shapely引擎无法容忍。
解决:先缓冲再简化:
import geopandas as gpd gdf = gpd.read_file("js_soil.shp") # 对每个图斑做极小缓冲(修复拓扑)+ 简化(去冗余点) gdf['geometry'] = gdf.buffer(0.0001).simplify(0.001) gdf.to_file("js_soil_clean.shp", encoding="utf-8")血泪经验:
buffer(0)看似更干净,但在CGCS2000坐标系下可能导致图斑面积突变,buffer(0.0001)(0.1毫米)既修复拓扑又不影响业务精度。
5. 进阶技巧:用土壤图驱动SWAT模型子流域划分——绕过手工画图,实现自动化水文响应单元(HRU)生成
5.1 SWAT模型对土壤数据的硬性要求
SWAT要求输入土壤数据必须满足:
- 空间一致性:所有图斑必须无缝拼接,无重叠、无缝隙;
- 属性完备性:必须包含
SOILNAM(土壤名称)、SOL_ZMX(根系深度)、SOL_AWC(有效持水量)、SOL_K(饱和导水率)等12个物理参数; - 命名规范性:
SOILNAM需匹配SWAT内置土壤库(如CHAO100000),不能用中文名。
而本份江苏土壤shp仅有分类名称(如“潮土”),无物理参数——需建立映射关系。
5.2 构建土壤-参数映射表:从《中国土壤图集》提取SWAT兼容字段
根据《中国土壤图集》江苏卷及FAO Soil Reference Database,建立SOIL_NAME到SWAT参数的映射(部分):
| SOIL_NAME | SOL_ZMX (mm) | SOL_AWC (mm/mm) | SOL_K (mm/hr) | TEXTURE_CODE |
|---|---|---|---|---|
| 潮土 | 1200 | 0.18 | 1.2 | CLAY_LOAM |
| 水稻土 | 800 | 0.22 | 0.3 | SILT_CLAY |
| 盐土 | 600 | 0.12 | 0.8 | SANDY_LOAM |
| 黄棕壤 | 1000 | 0.15 | 0.6 | LOAM |
注意:
TEXTURE_CODE需与SWAT土壤库中TEXTURE字段一致,否则模型运行报错Soil texture not found。
5.3 自动化生成SWAT输入文件:Python脚本批量创建.soil文件
import pandas as pd import geopandas as gpd from pathlib import Path # 1. 读取土壤映射表(CSV格式) soil_map = pd.read_csv("js_soil_to_swat.csv", encoding="utf-8") # 2. 读取地理数据 gdf = gpd.read_file("js_soil_georef.shp") # 3. 合并属性 gdf = gdf.merge(soil_map, left_on="SOIL_NAME", right_on="SOIL_NAME", how="left") # 4. 为每个图斑生成唯一SWAT土壤ID(前缀JS_+序号) gdf["SOIL_ID"] = "JS_" + gdf.index.astype(str).str.zfill(5) # 5. 写入SWAT .soil格式(固定列宽文本) with open("js_soils.sol", "w", encoding="utf-8") as f: f.write("SWAT\n") # 头部标识 for idx, row in gdf.iterrows(): # 格式:SOILNAM(10) SOLZMX(8) SOL_AWC(8) SOL_K(8) ... line = f"{row['SOIL_ID'][:10]:<10}{row['SOL_ZMX']:<8.0f}{row['SOL_AWC']:<8.3f}{row['SOL_K']:<8.1f}" # 补齐SWAT要求的12个参数(此处简化,实际需填满) line += "0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000\n" f.write(line) print("SWAT土壤文件js_soils.sol生成完毕,共{}个图斑".format(len(gdf)))参数说明:SWAT
.soil文件为固定列宽格式,SOILNAM占10字符,SOLZMX占8字符(整数),SOL_AWC占8字符(3位小数)。脚本中f"{val:<8.3f}"确保右对齐、补零、3位小数,完全符合SWAT解析器要求。
5.4 子流域-土壤图斑空间聚合:用QGIS“Join attributes by location”生成HRU表
SWAT的HRU(Hydrologic Response Unit)= 子流域 × 土壤类型 × 土地利用。需将土壤图与SWAT子流域图(subbasins.shp)叠加:
- 在QGIS中加载
subbasins.shp(SWAT生成的子流域)和js_soil_georef.shp; - 执行
Vector → Data Management Tools → Join attributes by location:- Target vector layer:
subbasins.shp - Join vector layer:
js_soil_georef.shp - Geometric predicate:
intersects - Join type:
Take summary of intersecting features - Summary fields:
SOIL_NAME,AREA_KM2(求和)
- Target vector layer:
- 输出
sub_soil_join.shp,其属性表含每子流域内各土壤类型的面积占比,可直接导入SWAT HRU管理器。
关键技巧:若子流域与土壤图斑面积差异大(如子流域10km²,土壤图斑0.1km²),勾选Use only nearest point会失效,必须用intersects并开启Take summary——这是SWAT官方推荐的HRU生成方式。
从那以后我每次拿到新的土壤shp,第一件事就是用ogrinfo验坐标系、用QGIS Check Validity扫拓扑、用pandas value_counts()查字段枚举值,三步走完才敢往模型里扔。因为土壤图不是静态图片,它是整个水文-生态-农业模型链的起点,起点歪了,后面所有模拟结果都是精致的错误。希望帮到你。
本文还有配套的精品资源,点击获取