GreenTransPowerCalculate/deeplabv3sdRenewable/tools/山东省地貌识别tools/潜力评估阶段/合并矢量转栅格但保存分类(可建设3)-分布式风机.py

112 lines
4.4 KiB
Python
Raw Normal View History

2025-04-27 09:58:17 +08:00
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_two_categories(file_paths, output_vector_path, output_raster_path,
raster_resolution=30):
"""
合并2个矢量图层forest, water转为栅格并显示2个类别保留0值作为背景
参数:
file_paths: 包含2个矢量文件路径的列表 (按顺序: forest, water)
output_vector_path: 输出合并后的矢量文件路径
output_raster_path: 输出栅格文件路径
raster_resolution: 输出栅格的分辨率默认30米
"""
try:
# 检查输入文件数量
if len(file_paths) != 2:
raise ValueError("请提供正好2个矢量文件路径")
# 定义类别映射,按照指定顺序
categories = ['forest', 'water']
category_values = {'forest': 1, 'water': 2} # forest=1, water=2
# 读取所有矢量文件并添加分类
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=forest, 2=water")
except Exception as e:
print(f"发生错误: {str(e)}")
# 使用示例
if __name__ == "__main__":
# 输入2个矢量文件路径按顺序: forest, water
input_files = [
r"E:\Data\z18\sd\Total_sd\shandonghebingshp\sdshp\forest\sdforest.shp",
r"E:\Data\z18\sd\Total_sd\shandonghebingshp\sdshp\water\true\shandongsuiyu3.shp"
]
output_vector_file = r"E:\njds\shenyang\shengyangshp\kejianshe\merged_vector_forest_water.shp"
output_raster_file = r"E:\njds\shenyang\shengyangshp\kejianshe\merged_raster_forest_water.tif"
# 执行合并和栅格化
merge_and_rasterize_vectors_two_categories(input_files, output_vector_file, output_raster_file,
raster_resolution=10)