""" geo_tools.config.settings ~~~~~~~~~~~~~~~~~~~~~~~~~ 全局配置,通过 Pydantic BaseSettings 从环境变量 / .env 文件加载。 使用方式 -------- >>> from geo_tools.config.settings import settings >>> print(settings.default_crs) 'EPSG:4326' """ from __future__ import annotations import multiprocessing from pathlib import Path from pydantic import field_validator, model_validator from pydantic_settings import BaseSettings, SettingsConfigDict class GeoToolsSettings(BaseSettings): """全局运行时配置。 所有字段均可通过前缀为 ``GEO_TOOLS_`` 的环境变量覆盖, 或在项目根目录创建 ``.env`` 文件(参考 ``.env.example``)。 """ model_config = SettingsConfigDict( env_prefix="GEO_TOOLS_", env_file=".env", env_file_encoding="utf-8", case_sensitive=False, extra="ignore", ) # ── 目录配置 ────────────────────────────────────────────── output_dir: Path = Path("output") """处理结果输出目录(相对路径相对于当前工作目录)。""" log_dir: Path = Path("logs") """日志文件目录。""" # ── 坐标系配置 ──────────────────────────────────────────── default_crs: str = "EPSG:4490" """默认地理坐标系,使用 EPSG 代码字符串。 常见值: - ``EPSG:4326`` — WGS84 经纬度 - ``EPSG:4490`` — CGCS2000 经纬度(中国国家标准) - ``EPSG:3857`` — Web Mercator """ # ── 日志配置 ────────────────────────────────────────────── log_level: str = "ERROR" """日志等级:DEBUG / INFO / WARNING / ERROR / CRITICAL。""" log_to_file: bool = True """是否同时将日志写出到文件。""" # ── 性能配置 ────────────────────────────────────────────── max_workers: int = 0 """并行处理最大 CPU 核数,0 表示自动检测(使用 CPU 核数 - 1)。""" # ── 校验器 ──────────────────────────────────────────────── @field_validator("log_level") @classmethod def validate_log_level(cls, v: str) -> str: allowed = {"DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL"} upper = v.upper() if upper not in allowed: raise ValueError(f"log_level 必须是 {allowed} 之一,收到:{v!r}") return upper @field_validator("default_crs") @classmethod def validate_crs(cls, v: str) -> str: # 简单前缀校验,完整校验在 validators.py 中通过 pyproj 完成 v = v.strip() if not v: raise ValueError("default_crs 不能为空") return v @model_validator(mode="after") def resolve_max_workers(self) -> "GeoToolsSettings": if self.max_workers <= 0: cpu_count = multiprocessing.cpu_count() self.max_workers = max(1, cpu_count - 1) return self def ensure_dirs(self) -> None: """创建输出和日志目录(幂等)。""" self.output_dir.mkdir(parents=True, exist_ok=True) self.log_dir.mkdir(parents=True, exist_ok=True) # 模块级单例,项目内统一引用 settings = GeoToolsSettings()