112 lines
4.4 KiB
Python
112 lines
4.4 KiB
Python
import geopandas as gpd
|
||
import pandas as pd
|
||
import rasterio
|
||
from rasterio.features import rasterize
|
||
import numpy as np
|
||
from shapely.geometry import mapping
|
||
|
||
|
||
def merge_and_rasterize_vectors_three_categories(file_paths, output_vector_path, output_raster_path,
|
||
raster_resolution=30):
|
||
"""
|
||
合并3个矢量图层(bareland, grass, shrub),转为栅格并显示3个类别,保留0值作为背景
|
||
|
||
参数:
|
||
file_paths: 包含3个矢量文件路径的列表 (按顺序: bareland, grass, shrub)
|
||
output_vector_path: 输出合并后的矢量文件路径
|
||
output_raster_path: 输出栅格文件路径
|
||
raster_resolution: 输出栅格的分辨率(默认30米)
|
||
"""
|
||
try:
|
||
# 检查输入文件数量
|
||
if len(file_paths) != 3:
|
||
raise ValueError("请提供正好3个矢量文件路径")
|
||
|
||
# 定义类别映射,按照指定顺序
|
||
categories = ['bareland', 'grass', 'shrub']
|
||
category_values = {'bareland': 1, 'grass': 2, 'shrub': 3} # bareland=1, grass=2, shrub=3
|
||
|
||
# 读取所有矢量文件并添加分类
|
||
gdfs = []
|
||
for i, (path, category) in enumerate(zip(file_paths, categories), 1):
|
||
print(f"正在读取第{i}个矢量文件: {path}")
|
||
gdf = gpd.read_file(path)
|
||
gdf['category'] = category # 添加类别字段
|
||
gdf['value'] = category_values[category] # 添加数值字段用于栅格化
|
||
gdfs.append(gdf)
|
||
|
||
# 检查和统一坐标系(以第一个图层为基准)
|
||
base_crs = gdfs[0].crs
|
||
for i, gdf in enumerate(gdfs[1:], 2):
|
||
if gdf.crs != base_crs:
|
||
print(f"第{i}个图层坐标系不同,正在转换为第一个图层的坐标系...")
|
||
gdfs[i - 1] = gdf.to_crs(base_crs)
|
||
|
||
# 合并所有GeoDataFrame
|
||
print("正在合并图层...")
|
||
merged_gdf = gpd.GeoDataFrame(pd.concat(gdfs, ignore_index=True))
|
||
merged_gdf = merged_gdf.set_geometry('geometry')
|
||
|
||
# 保存合并后的矢量文件
|
||
print(f"正在保存合并矢量结果到: {output_vector_path}")
|
||
merged_gdf.to_file(output_vector_path)
|
||
|
||
# 计算栅格化的范围
|
||
bounds = merged_gdf.total_bounds # [minx, miny, maxx, maxy]
|
||
width = int((bounds[2] - bounds[0]) / raster_resolution)
|
||
height = int((bounds[3] - bounds[1]) / raster_resolution)
|
||
|
||
# 创建栅格化变换
|
||
transform = rasterio.transform.from_bounds(
|
||
bounds[0], bounds[1], bounds[2], bounds[3], width, height
|
||
)
|
||
|
||
# 栅格化:将几何对象转为栅格,使用'value'字段作为像素值
|
||
print("正在将矢量转为栅格...")
|
||
shapes = ((mapping(geom), value) for geom, value in zip(merged_gdf.geometry, merged_gdf['value']))
|
||
raster = rasterize(
|
||
shapes=shapes,
|
||
out_shape=(height, width),
|
||
transform=transform,
|
||
fill=0, # 背景值为0
|
||
dtype=rasterio.uint8
|
||
)
|
||
|
||
# 保存栅格文件
|
||
with rasterio.open(
|
||
output_raster_path,
|
||
'w',
|
||
driver='GTiff',
|
||
height=height,
|
||
width=width,
|
||
count=1,
|
||
dtype=rasterio.uint8,
|
||
crs=base_crs,
|
||
transform=transform,
|
||
nodata=0 # 设置nodata值为0,表示背景
|
||
) as dst:
|
||
dst.write(raster, 1)
|
||
|
||
print("处理完成!")
|
||
print(f"合并矢量保存为: {output_vector_path}")
|
||
print(f"栅格保存为: {output_raster_path}")
|
||
print(f"栅格中类别值: 0=背景, 1=bareland, 2=grass, 3=shrub")
|
||
|
||
except Exception as e:
|
||
print(f"发生错误: {str(e)}")
|
||
|
||
|
||
# 使用示例
|
||
if __name__ == "__main__":
|
||
# 输入3个矢量文件路径(按顺序: bareland, grass, shrub)
|
||
input_files = [
|
||
r"E:\njds\shenyang\shengyangshp\bareland\bareland.shp",
|
||
r"E:\njds\shenyang\shengyangshp\grass\grass2.shp",
|
||
r"E:\njds\shenyang\shengyangshp\shrub\shrub.shp"
|
||
]
|
||
output_vector_file = r"E:\njds\shenyang\shengyangshp\kejianshe\merged_vector_three.shp"
|
||
output_raster_file = r"E:\njds\shenyang\shengyangshp\kejianshe\merged_raster_three.tif"
|
||
|
||
# 执行合并和栅格化
|
||
merge_and_rasterize_vectors_three_categories(input_files, output_vector_file, output_raster_file,
|
||
raster_resolution=30) |