config_manager.py 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262
  1. import json
  2. import os
  3. from pathlib import Path
  4. from typing import Dict, Any, Optional, Union, List
  5. import yaml
  6. from core.optimized_processor import get_base_path
  7. # 全局配置字典
  8. _CONFIG: Dict[str, Any] = {}
  9. base_path = get_base_path()
  10. print("base_path is", base_path)
  11. # 默认配置
  12. DEFAULT_CONFIG = {
  13. # 数据处理配置
  14. "processing": {
  15. "use_parallel": True,
  16. "max_workers": None, # None表示使用CPU核心数
  17. "batch_size": 10000,
  18. "use_vectorized": True
  19. },
  20. # 数据库配置
  21. "database": {
  22. "batch_query_size": 10000,
  23. "use_parallel_query": True,
  24. "max_db_workers": None
  25. },
  26. # 插件配置
  27. "plugins": {
  28. "enabled": True,
  29. "auto_discover": True
  30. },
  31. # 日志配置
  32. "logging": {
  33. "level": "INFO",
  34. "log_to_file": True,
  35. "log_dir": "logs"
  36. },
  37. # 坐标系配置
  38. "coordinates": {
  39. "utm_zone": 51,
  40. "x_offset": 0.0,
  41. "y_offset": 0.0
  42. },
  43. # 文件路径配置
  44. "paths": {
  45. "resources_dir": "resources",
  46. "plugins_dir": "plugins",
  47. "output_dir": "output",
  48. "engine_path": f"{os.path.join(base_path, '_internal/engine')}",
  49. "map_path": f"{os.path.join(base_path, '_internal/data_map')}",
  50. "dbc_path": f"{os.path.join(base_path, '_internal/VBox.dbc')}"
  51. # "engine_path": '_internal/engine',
  52. # "map_path": '_internal/data_map',
  53. # "dbc_path": '_internal/VBox.dbc'
  54. }
  55. }
  56. def load_config(config_path: Optional[Union[str, Path]] = None) -> Dict[str, Any]:
  57. """加载配置文件
  58. Args:
  59. config_path: 配置文件路径,支持JSON和YAML格式
  60. Returns:
  61. 配置字典
  62. """
  63. global _CONFIG
  64. # 首先使用默认配置
  65. _CONFIG = DEFAULT_CONFIG.copy()
  66. if config_path is None:
  67. # 尝试查找默认配置文件
  68. default_paths = [
  69. Path("config.json"),
  70. Path("config.yaml"),
  71. Path("config.yml"),
  72. Path("config/config.json"),
  73. Path("config/config.yaml"),
  74. Path("config/config.yml")
  75. ]
  76. for path in default_paths:
  77. if path.exists():
  78. config_path = path
  79. break
  80. if config_path is None:
  81. print("未找到配置文件,使用默认配置")
  82. return _CONFIG
  83. # 确保config_path是Path对象
  84. if isinstance(config_path, str):
  85. config_path = Path(config_path)
  86. if not config_path.exists():
  87. print(f"配置文件不存在: {config_path},使用默认配置")
  88. return _CONFIG
  89. try:
  90. # 根据文件扩展名选择解析方法
  91. suffix = config_path.suffix.lower()
  92. if suffix in [".yaml", ".yml"]:
  93. with open(config_path, "r", encoding="utf-8") as f:
  94. user_config = yaml.safe_load(f)
  95. elif suffix == ".json":
  96. with open(config_path, "r", encoding="utf-8") as f:
  97. user_config = json.load(f)
  98. else:
  99. print(f"不支持的配置文件格式: {suffix},使用默认配置")
  100. return _CONFIG
  101. # 递归合并配置
  102. _CONFIG = _merge_configs(_CONFIG, user_config)
  103. print(f"成功加载配置文件: {config_path}")
  104. except Exception as e:
  105. print(f"加载配置文件失败: {e}")
  106. return _CONFIG
  107. def _merge_configs(base: Dict[str, Any], override: Dict[str, Any]) -> Dict[str, Any]:
  108. """递归合并配置字典
  109. Args:
  110. base: 基础配置
  111. override: 覆盖配置
  112. Returns:
  113. 合并后的配置
  114. """
  115. result = base.copy()
  116. for key, value in override.items():
  117. # 如果两个都是字典,递归合并
  118. if key in result and isinstance(result[key], dict) and isinstance(value, dict):
  119. result[key] = _merge_configs(result[key], value)
  120. else:
  121. # 否则直接覆盖
  122. result[key] = value
  123. return result
  124. def get_config(section: Optional[str] = None) -> Any:
  125. """获取配置
  126. Args:
  127. section: 配置节名称,如果为None则返回整个配置字典
  128. Returns:
  129. 配置值或配置字典
  130. """
  131. global _CONFIG
  132. # 如果配置为空,加载默认配置
  133. if not _CONFIG:
  134. _CONFIG = DEFAULT_CONFIG.copy()
  135. if section is None:
  136. return _CONFIG
  137. # 支持点号分隔的多级配置访问,如 "database.batch_query_size"
  138. if "." in section:
  139. parts = section.split(".")
  140. current = _CONFIG
  141. for part in parts:
  142. if part in current:
  143. current = current[part]
  144. else:
  145. print(f"配置节不存在: {section}")
  146. return None
  147. return current
  148. # 单级配置访问
  149. return _CONFIG.get(section)
  150. def set_config(section: str, value: Any) -> None:
  151. """设置配置
  152. Args:
  153. section: 配置节名称,支持点号分隔的多级配置
  154. value: 配置值
  155. """
  156. global _CONFIG
  157. # 如果配置为空,加载默认配置
  158. if not _CONFIG:
  159. _CONFIG = DEFAULT_CONFIG.copy()
  160. # 支持点号分隔的多级配置设置
  161. if "." in section:
  162. parts = section.split(".")
  163. current = _CONFIG
  164. # 遍历到倒数第二级
  165. for part in parts[:-1]:
  166. # 如果中间节点不存在或不是字典,创建新字典
  167. if part not in current or not isinstance(current[part], dict):
  168. current[part] = {}
  169. current = current[part]
  170. # 设置最后一级的值
  171. current[parts[-1]] = value
  172. else:
  173. # 单级配置设置
  174. _CONFIG[section] = value
  175. def save_config(config_path: Union[str, Path], format: str = "json") -> bool:
  176. """保存配置到文件
  177. Args:
  178. config_path: 配置文件路径
  179. format: 文件格式,支持 "json" 和 "yaml"
  180. Returns:
  181. 是否保存成功
  182. """
  183. global _CONFIG
  184. # 确保config_path是Path对象
  185. if isinstance(config_path, str):
  186. config_path = Path(config_path)
  187. # 确保目录存在
  188. config_path.parent.mkdir(parents=True, exist_ok=True)
  189. try:
  190. # 根据格式选择保存方法
  191. if format.lower() == "yaml":
  192. with open(config_path, "w", encoding="utf-8") as f:
  193. yaml.dump(_CONFIG, f, default_flow_style=False, sort_keys=False)
  194. else: # 默认使用JSON
  195. with open(config_path, "w", encoding="utf-8") as f:
  196. json.dump(_CONFIG, f, indent=2, ensure_ascii=False)
  197. print(f"配置已保存到: {config_path}")
  198. return True
  199. except Exception as e:
  200. print(f"保存配置失败: {e}")
  201. return False
  202. def update_config(new_config: Dict[str, Any]) -> None:
  203. """更新全局配置
  204. Args:
  205. new_config: 新的配置字典,将与现有配置合并
  206. """
  207. global _CONFIG
  208. _CONFIG = _merge_configs(_CONFIG, new_config)
  209. print("配置已更新")
  210. # 初始化时加载配置
  211. load_config()