#根据日期计算当年天数 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)