372 lines
13 KiB
Python
372 lines
13 KiB
Python
#根据日期计算当年天数
|
||
import numpy as np
|
||
import pandas as pd
|
||
from matplotlib import pyplot as plt
|
||
|
||
|
||
def is_leap_year(year):
|
||
return (year % 4 == 0 and year % 100 != 0) or (year % 400 == 0)
|
||
|
||
def day_of_year(date_str):
|
||
date_part = date_str.split()[0]
|
||
year = int(date_str[:4]) # 取前4位 → 2025
|
||
month = int(date_str[5:7]) # 取第5-6位 → 06 → 6
|
||
day = int(date_str[8:10]) # 取第8-9位 → 30
|
||
month_days = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
|
||
if is_leap_year(year):
|
||
month_days[1] = 29 # 闰年2月29天
|
||
total = sum(month_days[:month-1]) + day
|
||
return total
|
||
#计算每天有效日照时长
|
||
def count_above_threshold(data, threshold,date):
|
||
filtered = filter(lambda x: float(x['value_cal']) >= threshold and x['datetime'].split(" ")[0] == date, data)
|
||
return len(list(filtered))
|
||
# 示例计算函数:Lux转W/m²
|
||
def lux_to_wm2(lux_value):
|
||
"""将Lux值转换为W/m²(使用标准系数0.0081)"""
|
||
return lux_value * 0.0081
|
||
def convert_lux_to_Radiant_Flux(data_dict):
|
||
"""
|
||
递归地将字典中的所有'timestamp'字段转换为可读的日期时间格式
|
||
保留原始时间戳的同时添加新的'datetime'字段
|
||
"""
|
||
if 'value' in data_dict:
|
||
radiant_Flux=data_dict["value"]*0.001496
|
||
data_dict["value_radiant"] =radiant_Flux
|
||
return data_dict
|
||
def lux_to_solar_rad(lux,h):
|
||
|
||
return lux * 0.001496*h * 3.6 / 1000
|
||
def plot(soil_data,name):
|
||
import matplotlib.dates as mdates
|
||
# 创建画布
|
||
plt.figure(figsize=(14, 8))
|
||
|
||
# 处理并绘制地表湿度数据
|
||
surface_df = pd.DataFrame(soil_data["SOIL_MOISTURE_SURFACE"])
|
||
surface_df['datetime'] = pd.to_datetime(surface_df['datetime'])
|
||
surface_df['value'] = surface_df['value'].astype(float)
|
||
plt.plot(surface_df['datetime'], surface_df['value'],
|
||
label='Surface Moisture (0-5cm)', color='#FF6B6B', linewidth=2, marker='o', markersize=5)
|
||
|
||
# 处理并绘制中层湿度数据
|
||
middle_df = pd.DataFrame(soil_data["SOIL_MOISTURE_MIDDLE"])
|
||
middle_df['datetime'] = pd.to_datetime(middle_df['datetime'])
|
||
middle_df['value'] = middle_df['value'].astype(float)
|
||
plt.plot(middle_df['datetime'], middle_df['value'],
|
||
label='Middle Layer Moisture', color='#4ECDC4', linewidth=2, marker='s', markersize=5)
|
||
# 处理并绘制中层湿度数据
|
||
middle_df = pd.DataFrame(soil_data["SOIL_MOISTURE_BOTTOM"])
|
||
middle_df['datetime'] = pd.to_datetime(middle_df['datetime'])
|
||
middle_df['value'] = middle_df['value'].astype(float)
|
||
plt.plot(middle_df['datetime'], middle_df['value'],
|
||
label='BOTTOM Layer Moisture', color='blue', linewidth=2, marker='s', markersize=5)
|
||
|
||
# 设置图表格式
|
||
plt.title('Soil Moisture Variation (Jun 18 - Jul 3, 2025)', fontsize=16, pad=20)
|
||
plt.xlabel('Date', fontsize=12)
|
||
plt.ylabel('Soil Moisture (%)', fontsize=12)
|
||
plt.grid(True, linestyle='--', alpha=0.7)
|
||
|
||
# 设置x轴日期格式
|
||
ax = plt.gca()
|
||
ax.xaxis.set_major_locator(mdates.DayLocator(interval=2))
|
||
ax.xaxis.set_major_formatter(mdates.DateFormatter('%m/%d'))
|
||
plt.xticks(rotation=45)
|
||
|
||
# 添加图例和注释
|
||
plt.legend(loc='upper right', fontsize=10)
|
||
plt.tight_layout()
|
||
# 保存图片到本地
|
||
output_path = 'D:\悦柠\遥感\甘草\ceshi/'+name+".png"
|
||
plt.savefig(output_path, dpi=300, bbox_inches='tight')
|
||
# 显示图表
|
||
# plt.show()
|
||
|
||
|
||
def rh_to_theta_vg(rh, soil_params, temperature=25):
|
||
"""使用Van Genuchten模型将相对湿度转换为体积含水量"""
|
||
# 计算土壤水势(kPa)
|
||
psi = -145 * np.log(rh / 100)
|
||
|
||
# 提取土壤参数
|
||
theta_s = soil_params["theta_s"] # 饱和含水量
|
||
theta_r = soil_params["theta_r"] # 残余含水量
|
||
alpha = soil_params["alpha"] # Van Genuchten参数
|
||
n = soil_params["n"] # Van Genuchten参数
|
||
m = 1 - 1 / n
|
||
|
||
# 计算体积含水量
|
||
theta = theta_r + (theta_s - theta_r) / ((1 + (alpha * abs(psi)) ** n) ** m)
|
||
print(theta)
|
||
return theta
|
||
|
||
|
||
def calculate_soil_moisture_after_irrigation(
|
||
initial_moisture: float,
|
||
field_capacity: float,
|
||
irrigation_volume: float,
|
||
soil_volume: float,
|
||
area: float = None,
|
||
verbose: bool = False
|
||
) -> float:
|
||
"""
|
||
不考虑降雨量和蒸散量时,计算灌溉后的土壤相对湿度
|
||
|
||
参数:
|
||
initial_moisture: 初始土壤相对湿度 (%)
|
||
field_capacity: 田间持水量 (%)
|
||
irrigation_volume: 灌溉量 (m³)
|
||
soil_volume: 土壤体积 (m³)
|
||
area: 灌溉面积 (㎡,可选,仅用于打印提示)
|
||
verbose: 是否打印详细计算过程
|
||
|
||
返回:
|
||
float: 灌溉后土壤相对湿度 (%)
|
||
"""
|
||
# 参数验证
|
||
if not (0 <= initial_moisture <= 100):
|
||
raise ValueError("初始湿度必须在0-100%之间")
|
||
if not (0 < field_capacity <= 100):
|
||
raise ValueError("田间持水量必须在0-100%之间且大于0")
|
||
if irrigation_volume < 0:
|
||
raise ValueError("灌溉量不能为负数")
|
||
if soil_volume <= 0:
|
||
raise ValueError("土壤体积必须大于0")
|
||
|
||
# 计算初始土壤含水量(m³)
|
||
initial_water = (initial_moisture / 100) * (field_capacity / 100) * soil_volume
|
||
|
||
# 灌溉后总含水量(m³)
|
||
total_water = initial_water + irrigation_volume
|
||
|
||
# 计算田间持水总量(m³)
|
||
max_water = (field_capacity / 100) * soil_volume
|
||
|
||
# 计算灌溉后湿度(超过田间持水量时取100%)
|
||
final_moisture = min((total_water / max_water) * 100, 100.0)
|
||
|
||
# if verbose:
|
||
# area_info = f"(面积: {area}㎡)" if area else ""
|
||
# print(f"===== 不考虑降雨与蒸散的灌溉计算 {area_info} =====")
|
||
# print(f"初始湿度: {initial_moisture}%")
|
||
# print(f"田间持水量: {field_capacity}%")
|
||
# print(f"土壤体积: {soil_volume}m³")
|
||
# print(f"灌溉量: {irrigation_volume}m³")
|
||
# print(f"初始含水量: {initial_water:.2f}m³")
|
||
# print(f"灌溉后含水量: {total_water:.2f}m³")
|
||
# print(f"田间最大持水量: {max_water:.2f}m³")
|
||
# print(f"灌溉后土壤湿度: {final_moisture:.2f}%")
|
||
|
||
return final_moisture
|
||
def calculate_irrigation_volume(
|
||
initial_moisture: float,
|
||
target_moisture: float,
|
||
field_capacity: float,
|
||
soil_volume: float
|
||
) -> float:
|
||
"""
|
||
计算为达到目标土壤相对湿度所需的灌溉量
|
||
|
||
参数:
|
||
initial_moisture: 初始土壤相对湿度 (%)
|
||
target_moisture: 目标土壤相对湿度 (%)
|
||
field_capacity: 田间持水量 (%)
|
||
soil_volume: 土壤体积 (m³)
|
||
area: 灌溉面积 (㎡,可选,仅用于打印提示)
|
||
verbose: 是否打印详细计算过程
|
||
|
||
返回:
|
||
float: 需要的灌溉量 (m³)
|
||
"""
|
||
# 参数验证
|
||
if not (0 <= initial_moisture <= 100):
|
||
raise ValueError("初始湿度必须在0-100%之间")
|
||
if not (0 <= target_moisture <= 100):
|
||
raise ValueError("目标湿度必须在0-100%之间")
|
||
if not (0 < field_capacity <= 100):
|
||
raise ValueError("田间持水量必须在0-100%之间且大于0")
|
||
if soil_volume <= 0:
|
||
raise ValueError("土壤体积必须大于0")
|
||
if target_moisture <= initial_moisture:
|
||
raise ValueError("目标湿度必须大于初始湿度")
|
||
|
||
# 计算初始土壤含水量(m³)
|
||
initial_water = (initial_moisture / 100) * (field_capacity / 100) * soil_volume
|
||
|
||
# 计算目标含水量(m³)
|
||
target_water = (target_moisture / 100) * (field_capacity / 100) * soil_volume
|
||
|
||
# 需要的灌溉量
|
||
irrigation_volume = target_water - initial_water
|
||
|
||
return irrigation_volume
|
||
def irriDepth_irrvolume(area,irrDepth):
|
||
volume=area*667*(irrDepth/1000)
|
||
return volume
|
||
|
||
|
||
def calculate_irrigation(dry_soil_weight, current_humidity, target_humidity,
|
||
irrigation_efficiency=0.8, water_density=1000):
|
||
"""
|
||
计算达到目标湿度所需的灌溉量
|
||
|
||
Args:
|
||
dry_soil_weight (float): 土壤干重(kg)
|
||
current_humidity (float): 当前相对湿度(%)
|
||
target_humidity (float): 目标相对湿度(%)
|
||
irrigation_efficiency (float): 灌溉效率(0~1)
|
||
water_density (float): 水密度(kg/m³)
|
||
|
||
Returns:
|
||
float: 灌溉量(立方米)
|
||
"""
|
||
if current_humidity >= target_humidity:
|
||
return 0.0
|
||
|
||
delta_humidity = (target_humidity - current_humidity) / 100
|
||
water_weight = dry_soil_weight * delta_humidity
|
||
water_volume = water_weight / water_density
|
||
return water_volume / irrigation_efficiency
|
||
def calculate_rh_target(
|
||
initial_moisture: float,
|
||
root: float,
|
||
field_capacity: float,
|
||
irrigation:float
|
||
) -> float:
|
||
initial_moisture=(initial_moisture / 100) * field_capacity
|
||
iir_volume=irrigation/(10*root)
|
||
target_moisture = initial_moisture + (iir_volume/field_capacity)
|
||
return target_moisture
|
||
|
||
|
||
def calculate_rh_target(
|
||
initial_moisture: float, # 初始土壤相对湿度(%)
|
||
root: float, # 根系深度(cm)
|
||
field_capacity: float, # 田间持水量(体积含水量 cm³/cm³)
|
||
irrigation: float # 灌溉量(mm)
|
||
) -> float:
|
||
"""
|
||
计算灌溉后的目标土壤相对湿度(%)
|
||
|
||
参数:
|
||
initial_moisture: 初始土壤相对湿度(%)
|
||
root: 根系深度(cm)
|
||
field_capacity: 田间持水量(体积含水量 cm³/cm³)
|
||
irrigation: 灌溉量(mm)
|
||
|
||
返回:
|
||
float: 灌溉后的目标土壤相对湿度(%)
|
||
"""
|
||
# 参数验证
|
||
if initial_moisture < 0 or initial_moisture > 100:
|
||
raise ValueError("初始湿度必须在0-100%之间")
|
||
if root <= 0:
|
||
raise ValueError("根系深度必须大于0")
|
||
if field_capacity <= 0 or field_capacity > 1:
|
||
raise ValueError("田间持水量必须在0-1 cm³/cm³之间")
|
||
if irrigation < 0:
|
||
raise ValueError("灌溉量不能为负值")
|
||
|
||
# 将相对湿度转为体积含水量
|
||
initial_volume_moisture = (initial_moisture / 100) * field_capacity
|
||
|
||
# 计算灌溉增加的体积含水量
|
||
# 将mm转为cm,并除以根系深度得到体积含水量增量
|
||
moisture_increase = (irrigation / 10) / root
|
||
|
||
# 计算灌溉后的体积含水量
|
||
target_volume_moisture = initial_volume_moisture + moisture_increase
|
||
# 转换回相对湿度(%)
|
||
target_rh = (target_volume_moisture / field_capacity) * 100
|
||
|
||
# 确保不超过100%
|
||
target_rh = min(target_rh, 100.0)
|
||
|
||
# # 3. 计算目标体积含水量 (不超过田间持水量)
|
||
# target_volume = min(initial_volume + moisture_increase, field_capacity)
|
||
#
|
||
# # 4. 转换回相对湿度 (%)
|
||
# target_rh = (target_volume / field_capacity) * 100
|
||
|
||
return target_rh
|
||
|
||
|
||
def calculate_rh_target_rz(
|
||
initial_moisture: float, # 初始土壤相对湿度(%)
|
||
soil_root: float, # 根系深度(cm)
|
||
area: float, # 灌溉面积(亩)
|
||
irrigation: float, # 灌溉量(mm)
|
||
field_capacity: float = 28.84, # 田间持水量(%),默认35%
|
||
soil_bulk_density: float = 1.5 # 土壤容重(g/cm³),默认1.5
|
||
) -> float:
|
||
"""
|
||
计算灌溉后的目标根区土壤相对湿度
|
||
|
||
参数:
|
||
initial_moisture: 初始土壤相对湿度(%)
|
||
soil_root: 根系深度(cm)
|
||
area: 灌溉面积(亩)
|
||
irrigation: 灌溉量(mm)
|
||
field_capacity: 田间持水量(%),默认35%
|
||
soil_bulk_density: 土壤容重(g/cm³),默认1.5
|
||
|
||
返回:
|
||
float: 灌溉后的目标土壤相对湿度(%)
|
||
"""
|
||
# 参数验证
|
||
if initial_moisture < 0 or initial_moisture > 100:
|
||
raise ValueError("初始湿度必须在0-100%之间")
|
||
if soil_root <= 0:
|
||
raise ValueError("根系深度必须大于0")
|
||
if area <= 0:
|
||
raise ValueError("面积必须大于0")
|
||
if irrigation < 0:
|
||
raise ValueError("灌溉量不能为负值")
|
||
|
||
# 计算根区体积
|
||
root_volume = area * 667 * (soil_root / 100) # m³,将cm转为m
|
||
|
||
# 计算灌溉水体积
|
||
water_volume = (irrigation / 1000) * area * 667 # m³,将mm转为m
|
||
|
||
# 计算灌溉增加的土壤湿度(%)
|
||
moisture_increase = (water_volume / (root_volume * soil_bulk_density)) * 100
|
||
|
||
# 计算目标湿度
|
||
target_moisture = initial_moisture + moisture_increase
|
||
|
||
# 确保不超过田间持水量
|
||
target_moisture = min(target_moisture, field_capacity)
|
||
|
||
return target_moisture
|
||
if __name__ == '__main__':
|
||
# volume=irriDepth_irrvolume(10.95,11.123)
|
||
# soil_volume_dk1 = 10.95 * 667 * 0.15
|
||
# soil_volume_dk2 = 8.92 * 667 * 0.15
|
||
# result1 = calculate_soil_moisture_after_irrigation(
|
||
# initial_moisture=15.2,
|
||
# field_capacity=28.84,
|
||
# irrigation_volume=168,
|
||
# soil_volume=soil_volume_dk1,
|
||
# verbose=True
|
||
# )
|
||
# print(f"\n示例1结果: 灌溉后湿度 = {result1:.2f}%\n")
|
||
# print(soil_volume_dk1)
|
||
# result2=calculate_irrigation_volume(initial_moisture=15.44,
|
||
# field_capacity=28.84,
|
||
# target_moisture=70,
|
||
# soil_volume=soil_volume_dk1)
|
||
# print(f"\n达到目标湿度所需灌溉量 = {result2:.2f}\n")
|
||
# # 调用示例
|
||
# dry_soil_weight=10.95*667*0.1*1200
|
||
# volume = calculate_irrigation(
|
||
# dry_soil_weight=dry_soil_weight,
|
||
# current_humidity=15.4,
|
||
# target_humidity=70
|
||
# )
|
||
# print(f"灌溉量: {volume:.2f} m³") # 输出: 0.09 m³
|
||
rh=calculate_rh_target(67.96,6,0.2884,33.14)
|
||
rh1 = rh*0.7
|
||
print(rh,rh1)
|