增加坡度计算

This commit is contained in:
2026-04-22 09:27:59 +08:00
parent 4fd1b0a203
commit d563a56358
20 changed files with 4891 additions and 344 deletions

83
slope/slope_aspect.py Normal file
View File

@ -0,0 +1,83 @@
import xdem
import rasterio
import numpy as np
def calc_cosine_i(solar_zn, solar_az, aspect, slope):
"""Generate cosine i image. The cosine of the incidence angle (i) is
defined as the angle between the normal to the pixel surface
and the solar zenith direction.
All input geometry units must be in radians.
Args:
solar_az (numpy.ndarray): Solar azimuth angle.
solar_zn (numpy.ndarray): Solar zenith angle.
aspect (numpy.ndarray): Ground aspect.
slope (numpy.ndarray): Ground slope.
Returns:
numpy.ndarray: Cosine i image.
"""
relative_az = aspect - solar_az
cosine_i = (np.cos(solar_zn) * np.cos(slope) +
np.sin(solar_zn) * np.sin(slope) * np.cos(relative_az))
return cosine_i
# ========== 1. 读取 DEM ==========
dem = xdem.DEM("E:/is2/yaopu/DEM/dsm.tif")
# ========== 2. 计算坡度、坡向 ==========
slope = xdem.terrain.slope(dem, method='ZevenbergThorne')
aspect = xdem.terrain.aspect(dem)
# ========== 3. 获取空间参考信息 ==========
transform = dem.transform
crs = dem.crs
# ========== 4. 转换为 numpy 数组 ==========
slope_data = slope.data
aspect_data = aspect.data
# ========== 5. 太阳角度(单位:度,根据实际飞行时间和地理位置设置) ==========
solar_zn_deg = 30.0 # 太阳天顶角(从天顶到太阳的夹角),例如 30°
solar_az_deg = 180.0 # 太阳方位角(从北顺时针),例如 180°正南
# 转换为弧度(因为三角函数需要弧度)
solar_zn_rad = np.deg2rad(solar_zn_deg)
solar_az_rad = np.deg2rad(solar_az_deg)
# 坡度和坡向也转换为弧度
slope_rad = np.deg2rad(slope_data)
aspect_rad = np.deg2rad(aspect_data)
# ========== 6. 计算 cosine_i ==========
cosine_i = calc_cosine_i(solar_zn_rad, solar_az_rad, aspect_rad, slope_rad)
# ========== 7. 处理无效值NaN ==========
# 注意:将 NaN 替换为 0 可能会与真实值为 0 的像元混淆如水平面坡度为0阴影边缘cosine_i=0
# 如需严格区分,建议使用特殊值(如 -9999作为 NoData。
slope_data = np.nan_to_num(slope_data, nan=0.0)
aspect_data = np.nan_to_num(aspect_data, nan=0.0)
cosine_i = np.nan_to_num(cosine_i, nan=0.0)
# ========== 8. 堆叠为多波段数组坡度、坡向、cosine_i ==========
stacked = np.stack([slope_data, aspect_data, cosine_i], axis=0)
# ========== 9. 输出 ENVI 格式文件 ==========
output_path = "E:/is2/yaopu/DEM/slope_aspect_cosine.dat"
with rasterio.open(
output_path,
'w',
driver='ENVI',
height=stacked.shape[1],
width=stacked.shape[2],
count=stacked.shape[0],
dtype=stacked.dtype,
crs=crs,
transform=transform,
nodata=0.0, # 与上面替换的 NaN 值一致
) as dst:
dst.write(stacked)
print(f"已保存多波段 ENVI 文件:{output_path}")
print(f"波段顺序1-坡度(°), 2-坡向(°), 3-cosine_i")