EG/plugins/user/vegetation_ecosystem/terrain/terrain_influence.py
2025-12-12 16:16:15 +08:00

664 lines
23 KiB
Python

"""
地形影响系统
负责模拟地形特征对植被分布和生态系统的影响
"""
import time
from typing import Dict, Any, List, Optional, Tuple
import math
import random
class TerrainInfluence:
"""
地形影响系统
负责模拟地形特征(坡度、海拔、朝向等)对植被分布和生态系统的影响
"""
def __init__(self, plugin):
"""
初始化地形影响系统
Args:
plugin: 植被和生态系统插件实例
"""
self.plugin = plugin
self.enabled = False
self.initialized = False
# 地形因子定义
self.terrain_factors = {
'elevation': {
'name': '海拔',
'description': '海拔高度对植被的影响',
'optimal_range': (0, 2000), # 最佳海拔范围(米)
'stress_threshold': 3000, # 压力阈值(米)
'impact_weight': 0.3 # 影响权重
},
'slope': {
'name': '坡度',
'description': '坡度对植被的影响',
'optimal_range': (0, 30), # 最佳坡度范围(度)
'stress_threshold': 60, # 压力阈值(度)
'impact_weight': 0.2
},
'aspect': {
'name': '朝向',
'description': '坡面朝向对植被的影响',
'optimal_range': (135, 225), # 最佳朝向(东南-西南)
'stress_direction': (0, 180), # 不利朝向(北向)
'impact_weight': 0.15
},
'soil_depth': {
'name': '土壤深度',
'description': '土壤深度对植被根系的影响',
'optimal_range': (0.5, 2.0), # 最佳土壤深度(米)
'stress_threshold': 0.2, # 压力阈值(米)
'impact_weight': 0.25
},
'water_accumulation': {
'name': '积水',
'description': '地表积水对植被的影响',
'optimal_range': (0, 0.3), # 最佳积水深度(米)
'stress_threshold': 0.5, # 压力阈值(米)
'impact_weight': 0.1
}
}
# 地形影响模型
self.influence_models = {
'linear': {
'name': '线性模型',
'description': '线性影响关系'
},
'exponential': {
'name': '指数模型',
'description': '指数影响关系'
},
'threshold': {
'name': '阈值模型',
'description': '基于阈值的影响'
},
'combined': {
'name': '组合模型',
'description': '综合多种因子的影响'
}
}
# 地形数据缓存
self.terrain_cache = {}
self.cache_config = {
'max_size': 1000, # 最大缓存大小
'expiration_time': 300, # 过期时间(秒)
'update_interval': 60 # 更新间隔(秒)
}
# 地形微气候效应
self.microclimate_effects = {
'temperature_variation': 0.0, # 温度变化
'humidity_variation': 0.0, # 湿度变化
'wind_shelter': 0.0, # 风力遮蔽
'radiation_exposure': 0.0 # 辐射暴露
}
# 地形适应性参数
self.adaptation_params = {
'adaptation_rate': 0.01, # 适应速率
'genetic_diversity': 0.7, # 遗传多样性
'migration_capability': 0.3, # 迁移能力
'stress_tolerance': 0.5 # 压力耐受性
}
# 统计信息
self.terrain_stats = {
'influence_calculations': 0,
'cache_hits': 0,
'cache_misses': 0,
'microclimate_updates': 0
}
print("✓ 地形影响系统已创建")
def initialize(self) -> bool:
"""
初始化地形影响系统
Returns:
是否初始化成功
"""
try:
self.initialized = True
print("✓ 地形影响系统初始化完成")
return True
except Exception as e:
print(f"✗ 地形影响系统初始化失败: {e}")
import traceback
traceback.print_exc()
return False
def enable(self) -> bool:
"""
启用地形影响系统
Returns:
是否启用成功
"""
try:
if not self.initialized:
print("✗ 地形影响系统未初始化")
return False
self.enabled = True
print("✓ 地形影响系统已启用")
return True
except Exception as e:
print(f"✗ 地形影响系统启用失败: {e}")
import traceback
traceback.print_exc()
return False
def disable(self):
"""禁用地形影响系统"""
try:
self.enabled = False
print("✓ 地形影响系统已禁用")
except Exception as e:
print(f"✗ 地形影响系统禁用失败: {e}")
import traceback
traceback.print_exc()
def finalize(self):
"""清理地形影响系统资源"""
try:
self.disable()
self.terrain_cache.clear()
self.initialized = False
print("✓ 地形影响系统资源已清理")
except Exception as e:
print(f"✗ 地形影响系统资源清理失败: {e}")
import traceback
traceback.print_exc()
def update(self, dt: float):
"""
更新地形影响系统状态
Args:
dt: 时间增量
"""
try:
if not self.enabled:
return
# 更新地形缓存
self._update_terrain_cache()
# 更新微气候效应
self._update_microclimate_effects()
except Exception as e:
print(f"✗ 地形影响系统更新失败: {e}")
import traceback
traceback.print_exc()
def _update_terrain_cache(self):
"""更新地形数据缓存"""
try:
current_time = time.time()
# 清理过期缓存
expired_keys = []
for key, (timestamp, _) in self.terrain_cache.items():
if current_time - timestamp > self.cache_config['expiration_time']:
expired_keys.append(key)
for key in expired_keys:
del self.terrain_cache[key]
except Exception as e:
print(f"✗ 地形缓存更新失败: {e}")
def _update_microclimate_effects(self):
"""更新微气候效应"""
try:
# 在实际实现中,这里会根据地形特征更新微气候效应
self.terrain_stats['microclimate_updates'] += 1
except Exception as e:
print(f"✗ 微气候效应更新失败: {e}")
def calculate_terrain_influence(self, position: Tuple[float, float, float],
vegetation_type: str = None) -> Dict[str, float]:
"""
计算地形对植被的影响
Args:
position: 位置坐标 (x, y, z)
vegetation_type: 植被类型(可选)
Returns:
地形影响因子字典
"""
try:
# 检查缓存
cache_key = f"{position}_{vegetation_type or 'general'}"
current_time = time.time()
if cache_key in self.terrain_cache:
timestamp, cached_result = self.terrain_cache[cache_key]
if current_time - timestamp < self.cache_config['expiration_time']:
self.terrain_stats['cache_hits'] += 1
return cached_result
self.terrain_stats['cache_misses'] += 1
# 获取地形数据
terrain_data = self._get_terrain_data(position)
# 计算各因子影响
influence_factors = {}
total_weight = 0.0
weighted_sum = 0.0
for factor_name, factor_info in self.terrain_factors.items():
if factor_name in terrain_data:
factor_value = terrain_data[factor_name]
factor_influence = self._calculate_factor_influence(
factor_name, factor_value, factor_info
)
influence_factors[factor_name] = factor_influence
weight = factor_info['impact_weight']
weighted_sum += factor_influence * weight
total_weight += weight
# 计算综合影响
if total_weight > 0:
overall_influence = weighted_sum / total_weight
else:
overall_influence = 1.0
influence_factors['overall'] = overall_influence
# 缓存结果
self.terrain_cache[cache_key] = (current_time, influence_factors)
# 限制缓存大小
if len(self.terrain_cache) > self.cache_config['max_size']:
# 移除最旧的条目
oldest_key = min(self.terrain_cache.keys(),
key=lambda k: self.terrain_cache[k][0])
del self.terrain_cache[oldest_key]
self.terrain_stats['influence_calculations'] += 1
return influence_factors
except Exception as e:
print(f"✗ 地形影响计算失败: {e}")
return {'overall': 1.0}
def _get_terrain_data(self, position: Tuple[float, float, float]) -> Dict[str, float]:
"""
获取指定位置的地形数据
Args:
position: 位置坐标 (x, y, z)
Returns:
地形数据字典
"""
try:
x, y, z = position
# 简化的地形数据生成
# 在实际实现中,这里会从真实的地形数据源获取信息
terrain_data = {
'elevation': y, # 假设y坐标为海拔
'slope': random.uniform(0, 45), # 随机坡度
'aspect': random.uniform(0, 360), # 随机朝向
'soil_depth': random.uniform(0.1, 3.0), # 随机土壤深度
'water_accumulation': random.uniform(0, 0.8) # 随机积水深度
}
return terrain_data
except Exception as e:
print(f"✗ 地形数据获取失败: {e}")
return {}
def _calculate_factor_influence(self, factor_name: str, factor_value: float,
factor_info: Dict[str, Any]) -> float:
"""
计算单个地形因子的影响
Args:
factor_name: 因子名称
factor_value: 因子值
factor_info: 因子信息
Returns:
影响因子 (0.0-2.0)
"""
try:
optimal_range = factor_info['optimal_range']
impact_weight = factor_info['impact_weight']
min_optimal, max_optimal = optimal_range
# 计算在最优范围内的适宜性
if min_optimal <= factor_value <= max_optimal:
suitability = 1.0
else:
# 计算距离最优范围的距离
if factor_value < min_optimal:
distance = min_optimal - factor_value
else:
distance = factor_value - max_optimal
# 指数衰减函数
suitability = max(0.0, math.exp(-distance / (max_optimal - min_optimal)))
# 应用压力阈值
if 'stress_threshold' in factor_info:
stress_threshold = factor_info['stress_threshold']
if factor_name in ['elevation', 'slope', 'water_accumulation']:
if factor_value > stress_threshold:
# 超过压力阈值时进一步降低适宜性
excess = factor_value - stress_threshold
stress_factor = max(0.0, 1.0 - (excess / stress_threshold))
suitability *= stress_factor
return max(0.0, min(2.0, suitability))
except Exception as e:
print(f"✗ 因子影响计算失败: {e}")
return 1.0
def get_terrain_factors(self) -> Dict[str, Dict[str, Any]]:
"""
获取地形因子定义
Returns:
地形因子字典
"""
return self.terrain_factors.copy()
def get_terrain_factor_info(self, factor_name: str) -> Optional[Dict[str, Any]]:
"""
获取特定地形因子的信息
Args:
factor_name: 因子名称
Returns:
因子信息字典或None
"""
return self.terrain_factors.get(factor_name)
def set_terrain_factor_parameter(self, factor_name: str, parameter: str, value: Any):
"""
设置地形因子参数
Args:
factor_name: 因子名称
parameter: 参数名称
value: 参数值
"""
try:
if factor_name in self.terrain_factors and parameter in self.terrain_factors[factor_name]:
self.terrain_factors[factor_name][parameter] = value
print(f"✓ 地形因子参数已设置: {factor_name}.{parameter} = {value}")
else:
print(f"✗ 无效的地形因子参数: {factor_name}.{parameter}")
except Exception as e:
print(f"✗ 地形因子参数设置失败: {e}")
def get_influence_models(self) -> Dict[str, Dict[str, str]]:
"""
获取影响模型
Returns:
影响模型字典
"""
return self.influence_models.copy()
def set_influence_model(self, model_name: str):
"""
设置影响模型
Args:
model_name: 模型名称
"""
try:
if model_name in self.influence_models:
# 在实际实现中,这里会设置当前使用的模型
print(f"✓ 影响模型设置为: {self.influence_models[model_name]['name']}")
else:
print(f"✗ 无效的影响模型: {model_name}")
except Exception as e:
print(f"✗ 影响模型设置失败: {e}")
def set_cache_config(self, config: Dict[str, Any]):
"""
设置缓存配置
Args:
config: 缓存配置字典
"""
try:
self.cache_config.update(config)
print(f"✓ 缓存配置已更新: {self.cache_config}")
except Exception as e:
print(f"✗ 缓存配置更新失败: {e}")
def get_cache_config(self) -> Dict[str, Any]:
"""
获取缓存配置
Returns:
缓存配置字典
"""
return self.cache_config.copy()
def clear_terrain_cache(self):
"""清空地形缓存"""
try:
self.terrain_cache.clear()
print("✓ 地形缓存已清空")
except Exception as e:
print(f"✗ 地形缓存清空失败: {e}")
def get_terrain_cache_info(self) -> Dict[str, Any]:
"""
获取地形缓存信息
Returns:
缓存信息字典
"""
try:
return {
'cache_size': len(self.terrain_cache),
'max_size': self.cache_config['max_size'],
'hit_rate': (self.terrain_stats['cache_hits'] /
max(1, self.terrain_stats['cache_hits'] + self.terrain_stats['cache_misses']))
}
except Exception as e:
print(f"✗ 缓存信息获取失败: {e}")
return {}
def update_microclimate_effect(self, effect_name: str, value: float):
"""
更新微气候效应
Args:
effect_name: 效应名称
value: 效应值
"""
try:
if effect_name in self.microclimate_effects:
self.microclimate_effects[effect_name] = value
print(f"✓ 微气候效应已更新: {effect_name} = {value}")
else:
print(f"✗ 无效的微气候效应: {effect_name}")
except Exception as e:
print(f"✗ 微气候效应更新失败: {e}")
def get_microclimate_effects(self) -> Dict[str, float]:
"""
获取微气候效应
Returns:
微气候效应字典
"""
return self.microclimate_effects.copy()
def set_adaptation_parameter(self, parameter: str, value: float):
"""
设置适应性参数
Args:
parameter: 参数名称
value: 参数值
"""
try:
if parameter in self.adaptation_params:
self.adaptation_params[parameter] = max(0.0, min(1.0, value))
print(f"✓ 适应性参数已设置: {parameter} = {value}")
else:
print(f"✗ 无效的适应性参数: {parameter}")
except Exception as e:
print(f"✗ 适应性参数设置失败: {e}")
def get_adaptation_parameters(self) -> Dict[str, float]:
"""
获取适应性参数
Returns:
适应性参数字典
"""
return self.adaptation_params.copy()
def simulate_terrain_adaptation(self, vegetation_type: str,
terrain_conditions: Dict[str, float]) -> float:
"""
模拟植被对地形的适应过程
Args:
vegetation_type: 植被类型
terrain_conditions: 地形条件
Returns:
适应性评分 (0.0-1.0)
"""
try:
# 获取植被的地形偏好
if self.plugin.vegetation_manager:
veg_info = self.plugin.vegetation_manager.get_vegetation_info(vegetation_type)
if veg_info:
# 基于植被类型和地形条件计算适应性
adaptation_score = self._calculate_adaptation_score(vegetation_type, terrain_conditions)
return adaptation_score
# 默认适应性评分
return 0.5
except Exception as e:
print(f"✗ 地形适应模拟失败: {e}")
return 0.5
def _calculate_adaptation_score(self, vegetation_type: str,
terrain_conditions: Dict[str, float]) -> float:
"""
计算植被对地形的适应性评分
Args:
vegetation_type: 植被类型
terrain_conditions: 地形条件
Returns:
适应性评分 (0.0-1.0)
"""
try:
# 简化的适应性计算
scores = []
for factor_name, factor_value in terrain_conditions.items():
if factor_name in self.terrain_factors:
factor_info = self.terrain_factors[factor_name]
factor_influence = self._calculate_factor_influence(
factor_name, factor_value, factor_info
)
scores.append(factor_influence)
if scores:
return sum(scores) / len(scores)
return 0.5
except Exception as e:
print(f"✗ 适应性评分计算失败: {e}")
return 0.5
def get_terrain_stats(self) -> Dict[str, int]:
"""
获取地形统计信息
Returns:
统计信息字典
"""
return self.terrain_stats.copy()
def reset_terrain_stats(self):
"""重置地形统计信息"""
try:
self.terrain_stats = {
'influence_calculations': 0,
'cache_hits': 0,
'cache_misses': 0,
'microclimate_updates': 0
}
print("✓ 地形统计信息已重置")
except Exception as e:
print(f"✗ 地形统计信息重置失败: {e}")
def get_terrain_suitability_map(self, area: Tuple[Tuple[float, float], Tuple[float, float]],
resolution: float = 1.0) -> Dict[Tuple[float, float], float]:
"""
获取区域内地形适宜性地图
Args:
area: 区域范围 ((min_x, min_z), (max_x, max_z))
resolution: 分辨率
Returns:
适宜性地图字典 {(x, z): suitability}
"""
try:
(min_x, min_z), (max_x, max_z) = area
suitability_map = {}
x = min_x
while x <= max_x:
z = min_z
while z <= max_z:
# 计算位置的适宜性
position = (x, 0, z) # 假设y坐标为0
influence = self.calculate_terrain_influence(position)
suitability = influence.get('overall', 1.0)
suitability_map[(x, z)] = suitability
z += resolution
x += resolution
return suitability_map
except Exception as e:
print(f"✗ 适宜性地图生成失败: {e}")
return {}