""" 地形影响系统 负责模拟地形特征对植被分布和生态系统的影响 """ 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 {}