527 lines
18 KiB
Markdown
527 lines
18 KiB
Markdown
系统路径管理是 SunvStation 二次开发中的核心功能之一,它允许脚本动态访问系统配置文件、模板、脚本目录、临时文件目录等关键资源路径。通过统一的接口获取路径信息,可以确保脚本在不同安装环境和操作系统上的兼容性和可移植性。
|
||
|
||
## 架构概览
|
||
|
||
系统路径管理通过 `ProjectMixin` 提供的 `getSysPathName(mode)` 方法实现,该方法封装了底层的 `GlobalOptions` 单例对象访问逻辑,根据模式参数返回不同类型的系统路径。以下展示了系统路径管理的调用层次结构:
|
||
|
||
```mermaid
|
||
graph TD
|
||
A[Python 脚本] -->|调用| B[SSProcess 实例]
|
||
B -->|继承| C[ProjectMixin]
|
||
C -->|提供方法| D[getSysPathName]
|
||
D -->|使用| E[GlobalOptions 单例]
|
||
|
||
D -->|mode=0| F[getConfigurePath]
|
||
D -->|mode=1| G[getTemplatePath]
|
||
D -->|mode=2| H[getCommonPath]
|
||
D -->|mode=3| I[getSchemeFilePath]
|
||
D -->|mode=4| J[getEpsTempPath]
|
||
D -->|mode=5| K[getCurrentMap]
|
||
D -->|mode=6| L[os.environ]
|
||
D -->|mode=7/8| M[getSchemeFilePath]
|
||
|
||
K -->|获取| N[getProjectName]
|
||
N -->|Path.parent| O[工程目录]
|
||
|
||
style B fill:#e1f5ff
|
||
style C fill:#fff4e1
|
||
style E fill:#f0f0f0
|
||
```
|
||
|
||
Sources: [PySSProcess.py](PySSProcess.py#L25-L50), [ssprocess_mixins/project_mixin.py](ssprocess_mixins/project_mixin.py#L71-L116)
|
||
|
||
## 路径模式详解
|
||
|
||
`getSysPathName(mode)` 方法支持 9 种路径模式(0-8),每种模式对应不同类型的系统路径。理解这些路径模式的用途对于构建健壮的脚本至关重要。
|
||
|
||
### 路径模式对照表
|
||
|
||
| 模式 | 路径类型 | 底层方法 | 说明 | 典型用途 |
|
||
|-----|---------|---------|------|---------|
|
||
| 0 | 配置路径 | `getConfigurePath()` | 存放系统配置文件(Windows 下为应用程序路径) | 读取 SSGlobal.xml 等配置文件 |
|
||
| 1 | 模板路径 | `getTemplatePath()` | 存放地物模板文件 | 加载 .egdb 模板创建新工程 |
|
||
| 2 | Comm 路径 | `getCommonPath()` | 公共资源目录 | 访问共享的数据符号库 |
|
||
| 3 | Script 路径 | `getSchemeFilePath("scripts")` | 脚本文件目录 | 动态加载或引用其他脚本 |
|
||
| 4 | SSTemp 路径 | `getEpsTempPath()` | 临时文件目录 | 存储中间处理结果 |
|
||
| 5 | 工程文件路径 | `getCurrentMap().getProjectName()` | 当前工程文件所在目录 | 计算相对路径、保存输出 |
|
||
| 6 | 系统目录 | `WINDIR` 或 `/usr` | 操作系统目录 | 访问系统级文件 |
|
||
| 7 | 工作台面目录 | `getSchemeFilePath("")` | 用户工作台面根目录 | 访问用户自定义配置 |
|
||
| 8 | 工作台面目录 | `getSchemeFilePath("")` | 用户工作台面根目录 | 同模式 7,保留兼容性 |
|
||
|
||
Sources: [ssprocess_mixins/project_mixin.py](ssprocess_mixins/project_mixin.py#L71-L116), [PySSWidget.py](PySSWidget.py#L1019-L1049), [PySSWidget.py](PySSWidget.py#L1059-L1065), [PySSWidget.py](PySSWidget.py#L1172-L1180)
|
||
|
||
### 路径特点说明
|
||
|
||
**配置路径(mode 0)**:在 Windows 系统中通常为应用程序安装目录,在 Unix 系统中可能为 `/etc` 或 `/opt` 等系统配置目录。此路径用于存放全局配置文件,如 `SSGlobal.xml`。
|
||
|
||
**模板路径(mode 1)**:存放预定义的地物模板文件(.egdb 格式)。当需要创建新的工程文件时,通常基于这些模板进行初始化。
|
||
|
||
**Comm 路径(mode 2)**:公共资源目录,包含符号库、样式表等跨工程共享的资源文件。
|
||
|
||
**Script 路径(mode 3)**:存放 Python 脚本文件的目录。此路径对于脚本间的相互引用(import)和动态加载(exec)非常重要。
|
||
|
||
**SSTemp 路径(mode 4)**:临时文件目录,用于存储处理过程中的临时数据。脚本完成后应清理此目录中的临时文件。
|
||
|
||
**工程文件路径(mode 5)**:返回当前打开的工程文件(.egdb)所在的父目录。如果当前没有工程或工程未保存,则返回空字符串。此路径对于保存输出文件、创建相对路径非常有用。
|
||
|
||
**系统目录(mode 6)**:根据操作系统类型返回不同的目录。Windows 下为 `%WINDIR%` 环境变量指向的目录(通常为 `C:\Windows`),Unix/Linux 下为 `/usr` 目录。
|
||
|
||
**工作台面目录(mode 7/8)**:返回当前激活的工作台面目录。工作台面是 SunvStation 的用户配置组织单位,不同的工作台面可以有独立的配置、脚本和模板。
|
||
|
||
Sources: [ssprocess_mixins/project_mixin.py](ssprocess_mixins/project_mixin.py#L104-L116)
|
||
|
||
## 基本用法
|
||
|
||
### 获取各类系统路径
|
||
|
||
最简单的用法是直接调用 `getSysPathName(mode)` 获取所需路径:
|
||
|
||
```python
|
||
from sunvpy import SSProcess
|
||
|
||
# 获取配置路径
|
||
config_path = SSProcess.getSysPathName(0)
|
||
print(f"配置路径: {config_path}")
|
||
|
||
# 获取模板路径
|
||
template_path = SSProcess.getSysPathName(1)
|
||
print(f"模板路径: {template_path}")
|
||
|
||
# 获取公共资源路径
|
||
common_path = SSProcess.getSysPathName(2)
|
||
print(f"公共资源路径: {common_path}")
|
||
|
||
# 获取脚本路径
|
||
script_path = SSProcess.getSysPathName(3)
|
||
print(f"脚本路径: {script_path}")
|
||
|
||
# 获取临时文件路径
|
||
temp_path = SSProcess.getSysPathName(4)
|
||
print(f"临时文件路径: {temp_path}")
|
||
```
|
||
|
||
Sources: [ssprocess_mixins/project_mixin.py](ssprocess_mixins/project_mixin.py#L71-L116)
|
||
|
||
### 构造完整文件路径
|
||
|
||
获取路径后,可以使用路径构造功能完整的文件路径:
|
||
|
||
```python
|
||
# 构造配置文件的完整路径
|
||
config_file = config_path + "system_config.xml"
|
||
|
||
# 构造模板文件的完整路径
|
||
template_file = template_path + "standard_template.egdb"
|
||
|
||
# 构造脚本文件的完整路径
|
||
script_file = script_path + "utility_functions.py"
|
||
|
||
# 使用 pathlib 进行更安全的路径操作(推荐)
|
||
from pathlib import Path
|
||
|
||
config_file_safe = Path(config_path) / "system_config.xml"
|
||
template_file_safe = Path(template_path) / "standard_template.egdb"
|
||
script_file_safe = Path(script_path) / "utility_functions.py"
|
||
```
|
||
|
||
Sources: [ssprocess_mixins/project_mixin.py](ssprocess_mixins/project_mixin.py#L85-L98)
|
||
|
||
## 高级用法
|
||
|
||
### 获取工程文件路径
|
||
|
||
工程文件路径(mode 5)需要当前地图已打开并保存才能获取。在实际使用中需要检查返回值:
|
||
|
||
```python
|
||
# 获取工程文件所在目录
|
||
project_dir = SSProcess.getSysPathName(5)
|
||
|
||
if not project_dir:
|
||
print("警告: 当前没有打开的工程或工程未保存")
|
||
print("无法使用相对路径保存输出文件")
|
||
else:
|
||
print(f"工程目录: {project_dir}")
|
||
|
||
# 在工程目录下创建输出文件
|
||
output_dir = project_dir + "output/"
|
||
output_file = output_dir + "result.json"
|
||
|
||
print(f"输出文件将保存到: {output_file}")
|
||
```
|
||
|
||
Sources: [ssprocess_mixins/project_mixin.py](ssprocess_mixins/project_mixin.py#L99-L103)
|
||
|
||
### 跨平台系统目录访问
|
||
|
||
系统目录(mode 6)会根据操作系统类型自动选择正确的路径:
|
||
|
||
```python
|
||
import os
|
||
|
||
# 获取系统目录(跨平台兼容)
|
||
system_dir = SSProcess.getSysPathName(6)
|
||
|
||
if os.name == "nt":
|
||
print(f"Windows 系统目录: {system_dir}")
|
||
# 示例:访问 Windows 字体目录
|
||
font_dir = system_dir + "\\Fonts\\"
|
||
else:
|
||
print(f"Unix/Linux 系统目录: {system_dir}")
|
||
# 示例:访问系统共享目录
|
||
font_dir = system_dir + "/share/fonts/"
|
||
```
|
||
|
||
Sources: [ssprocess_mixins/project_mixin.py](ssprocess_mixins/project_mixin.py#L104-L111)
|
||
|
||
### 工作台面目录操作
|
||
|
||
工作台面目录(mode 7/8)允许访问用户特定的配置和资源:
|
||
|
||
```python
|
||
# 获取工作台面目录
|
||
workspace_dir = SSProcess.getSysPathName(7)
|
||
|
||
print(f"当前工作台面目录: {workspace_dir}")
|
||
|
||
# 工作台面目录的典型子目录
|
||
scripts_dir = workspace_dir + "scripts/"
|
||
templates_dir = workspace_dir + "templates/"
|
||
config_dir = workspace_dir + "config/"
|
||
|
||
print(f"工作台面脚本目录: {scripts_dir}")
|
||
print(f"工作台面模板目录: {templates_dir}")
|
||
print(f"工作台面配置目录: {config_dir}")
|
||
```
|
||
|
||
Sources: [ssprocess_mixins/project_mixin.py](ssprocess_mixins/project_mixin.py#L112-L113)
|
||
|
||
## 路径获取流程
|
||
|
||
`getSysPathName` 方法的执行逻辑如下:
|
||
|
||
```mermaid
|
||
flowchart TD
|
||
A[调用 getSysPathName] --> B{判断 mode 参数}
|
||
|
||
B -->|mode 0| C[调用 global_options.getConfigurePath]
|
||
C --> C1[添加斜杠并返回]
|
||
|
||
B -->|mode 1| D[调用 global_options.getTemplatePath]
|
||
D --> D1[添加斜杠并返回]
|
||
|
||
B -->|mode 2| E[调用 global_options.getCommonPath]
|
||
E --> E1[添加斜杠并返回]
|
||
|
||
B -->|mode 3| F[调用 global_options.getSchemeFilePath]
|
||
F --> F1[参数为 scripts]
|
||
F1 --> F2[添加斜杠并返回]
|
||
|
||
B -->|mode 4| G[调用 global_options.getEpsTempPath]
|
||
G --> G1[添加斜杠并返回]
|
||
|
||
B -->|mode 5| H[获取当前地图项目名]
|
||
H --> H1{项目名有效?}
|
||
H1 -->|否| H2[返回空字符串]
|
||
H1 -->|是| H3[使用 Path.parent 提取父目录]
|
||
H3 --> H4[返回目录路径]
|
||
|
||
B -->|mode 6| I{判断操作系统}
|
||
I -->|Windows| J[获取 WINDIR 环境变量]
|
||
I -->|Unix| K[返回 /usr]
|
||
J --> L[转换为 Path 对象]
|
||
K --> L
|
||
L --> L1[返回路径字符串]
|
||
|
||
B -->|mode 7/8| M[调用 global_options.getSchemeFilePath]
|
||
M --> M1[参数为空字符串]
|
||
M1 --> M2[添加斜杠并返回]
|
||
|
||
B -->|其他| N[返回空字符串]
|
||
|
||
style A fill:#e1f5ff
|
||
style H fill:#fff4e1
|
||
style I fill:#fff4e1
|
||
```
|
||
|
||
Sources: [ssprocess_mixins/project_mixin.py](ssprocess_mixins/project_mixin.py#L85-L116)
|
||
|
||
## 综合应用示例
|
||
|
||
以下是一个综合示例,展示如何在实际脚本中系统性地使用各种路径功能:
|
||
|
||
```python
|
||
from sunvpy import SSProcess
|
||
from pathlib import Path
|
||
import json
|
||
|
||
def setup_script_environment():
|
||
"""设置脚本运行环境并输出路径信息"""
|
||
|
||
print("=" * 70)
|
||
print("SunvStation 系统路径信息")
|
||
print("=" * 70)
|
||
|
||
# 获取各类系统路径
|
||
paths = {
|
||
"配置路径": SSProcess.getSysPathName(0),
|
||
"模板路径": SSProcess.getSysPathName(1),
|
||
"公共资源路径": SSProcess.getSysPathName(2),
|
||
"脚本路径": SSProcess.getSysPathName(3),
|
||
"临时文件路径": SSProcess.getSysPathName(4),
|
||
"工程文件路径": SSProcess.getSysPathName(5),
|
||
"系统目录": SSProcess.getSysPathName(6),
|
||
"工作台面目录": SSProcess.getSysPathName(7)
|
||
}
|
||
|
||
# 输出路径信息
|
||
for name, path in paths.items():
|
||
if path:
|
||
print(f"✓ {name:15s}: {path}")
|
||
else:
|
||
print(f"✗ {name:15s}: (未设置或不可用)")
|
||
|
||
print("=" * 70)
|
||
|
||
# 检查关键路径的可用性
|
||
if not paths["工程文件路径"]:
|
||
print("\n警告: 当前没有打开的工程")
|
||
print("某些功能可能无法正常工作")
|
||
|
||
# 返回路径字典供后续使用
|
||
return paths
|
||
|
||
def create_output_file(filename):
|
||
"""在合适的位置创建输出文件"""
|
||
|
||
# 优先使用工程目录
|
||
project_dir = SSProcess.getSysPathName(5)
|
||
|
||
if project_dir:
|
||
output_dir = Path(project_dir) / "output"
|
||
else:
|
||
# 降级使用临时目录
|
||
temp_dir = SSProcess.getSysPathName(4)
|
||
output_dir = Path(temp_dir)
|
||
|
||
# 创建输出目录
|
||
output_dir.mkdir(parents=True, exist_ok=True)
|
||
|
||
# 构造完整文件路径
|
||
output_file = output_dir / filename
|
||
|
||
return str(output_file)
|
||
|
||
def load_custom_config(config_name):
|
||
"""从工作台面目录加载自定义配置"""
|
||
|
||
workspace_dir = SSProcess.getSysPathName(7)
|
||
|
||
if not workspace_dir:
|
||
print("错误: 无法获取工作台面目录")
|
||
return None
|
||
|
||
config_dir = Path(workspace_dir) / "config"
|
||
config_file = config_dir / config_name
|
||
|
||
if not config_file.exists():
|
||
print(f"警告: 配置文件不存在: {config_file}")
|
||
return None
|
||
|
||
try:
|
||
with open(config_file, 'r', encoding='utf-8') as f:
|
||
config = json.load(f)
|
||
print(f"成功加载配置: {config_file}")
|
||
return config
|
||
except Exception as e:
|
||
print(f"加载配置失败: {e}")
|
||
return None
|
||
|
||
# 主程序
|
||
if __name__ == "__main__":
|
||
# 设置环境并获取路径信息
|
||
paths = setup_script_environment()
|
||
|
||
# 创建输出文件
|
||
output_file = create_output_file("script_output.json")
|
||
print(f"\n输出文件将保存到: {output_file}")
|
||
|
||
# 加载自定义配置
|
||
custom_config = load_custom_config("my_config.json")
|
||
if custom_config:
|
||
print(f"自定义配置: {custom_config}")
|
||
```
|
||
|
||
Sources: [ssprocess_mixins/project_mixin.py](ssprocess_mixins/project_mixin.py#L71-L116), [PySSProcess.py](PySSProcess.py#L53-L86)
|
||
|
||
## 最佳实践
|
||
|
||
在使用系统路径管理功能时,遵循以下最佳实践可以提高脚本的健壮性和可移植性:
|
||
|
||
### 1. 优先使用系统路径而非硬编码
|
||
|
||
```python
|
||
# 好的做法:使用系统路径
|
||
template_path = SSProcess.getSysPathName(1)
|
||
template_file = template_path + "standard.egdb"
|
||
|
||
# 不好的做法:硬编码路径
|
||
template_file = "C:\\Program Files\\SunvStation\\templates\\standard.egdb"
|
||
```
|
||
|
||
Sources: [ssprocess_mixins/project_mixin.py](ssprocess_mixins/project_mixin.py#L71-L116)
|
||
|
||
### 2. 始终检查路径有效性
|
||
|
||
```python
|
||
project_dir = SSProcess.getSysPathName(5)
|
||
if not project_dir:
|
||
print("警告: 工程目录不可用,使用临时目录")
|
||
output_dir = SSProcess.getSysPathName(4)
|
||
else:
|
||
output_dir = project_dir
|
||
```
|
||
|
||
Sources: [ssprocess_mixins/project_mixin.py](ssprocess_mixins/project_mixin.py#L99-L103)
|
||
|
||
### 3. 使用 pathlib 进行路径操作
|
||
|
||
```python
|
||
from pathlib import Path
|
||
|
||
# 推荐做法:使用 pathlib
|
||
script_path = SSProcess.getSysPathName(3)
|
||
script_file = Path(script_path) / "utils.py"
|
||
|
||
# 可以方便地检查文件是否存在
|
||
if script_file.exists():
|
||
print(f"脚本文件存在: {script_file}")
|
||
```
|
||
|
||
Sources: [ssprocess_mixins/project_mixin.py](ssprocess_mixins/project_mixin.py#L103-L103)
|
||
|
||
### 4. 临时文件及时清理
|
||
|
||
```python
|
||
import os
|
||
|
||
# 在临时目录创建临时文件
|
||
temp_dir = SSProcess.getSysPathName(4)
|
||
temp_file = temp_dir + "temp_data.tmp"
|
||
|
||
# 使用后及时清理
|
||
try:
|
||
# 处理临时文件...
|
||
pass
|
||
finally:
|
||
if os.path.exists(temp_file):
|
||
os.remove(temp_file)
|
||
print(f"已删除临时文件: {temp_file}")
|
||
```
|
||
|
||
Sources: [ssprocess_mixins/project_mixin.py](ssprocess_mixins/project_mixin.py#L97-L98)
|
||
|
||
### 5. 处理路径中的斜杠
|
||
|
||
`getSysPathName` 返回的路径都以斜杠结尾(`/`),这简化了路径拼接操作:
|
||
|
||
```python
|
||
config_path = SSProcess.getSysPathName(0)
|
||
# config_path 已包含结尾斜杠,无需额外添加
|
||
config_file = config_path + "system.xml" # 正确拼接
|
||
```
|
||
|
||
Sources: [ssprocess_mixins/project_mixin.py](ssprocess_mixins/project_mixin.py#L90-L98)
|
||
|
||
## 错误处理与调试
|
||
|
||
在使用系统路径功能时可能会遇到各种错误情况,以下是一些常见的错误处理模式:
|
||
|
||
### 常见错误类型
|
||
|
||
| 错误类型 | 可能原因 | 处理方法 |
|
||
|---------|---------|---------|
|
||
| 返回空字符串 | 路径不可用或未配置 | 检查返回值,提供降级方案 |
|
||
| 路径不存在 | 目录被删除或未创建 | 使用 `os.makedirs()` 创建目录 |
|
||
| 权限错误 | 无访问权限 | 使用 try-except 捕获异常 |
|
||
| 跨平台路径问题 | 使用了平台特定的路径分隔符 | 使用 `os.path.join()` 或 `pathlib.Path` |
|
||
|
||
### 错误处理示例
|
||
|
||
```python
|
||
import os
|
||
from pathlib import Path
|
||
|
||
def safe_get_path(mode):
|
||
"""安全地获取路径并进行验证"""
|
||
|
||
# 获取路径
|
||
path = SSProcess.getSysPathName(mode)
|
||
|
||
# 检查路径是否有效
|
||
if not path:
|
||
raise ValueError(f"模式 {mode} 对应的路径不可用")
|
||
|
||
# 转换为 Path 对象
|
||
path_obj = Path(path)
|
||
|
||
# 检查路径是否存在(对于需要创建的路径可跳过此检查)
|
||
if not path_obj.exists():
|
||
print(f"警告: 路径不存在 - {path}")
|
||
print("尝试创建路径...")
|
||
try:
|
||
path_obj.mkdir(parents=True, exist_ok=True)
|
||
print(f"成功创建路径: {path}")
|
||
except PermissionError:
|
||
raise PermissionError(f"无权限创建路径: {path}")
|
||
except Exception as e:
|
||
raise RuntimeError(f"创建路径失败: {e}")
|
||
|
||
# 检查是否为目录
|
||
if not path_obj.is_dir():
|
||
raise RuntimeError(f"路径不是目录: {path}")
|
||
|
||
return str(path_obj)
|
||
|
||
# 使用示例
|
||
try:
|
||
config_dir = safe_get_path(0)
|
||
print(f"配置目录: {config_dir}")
|
||
except Exception as e:
|
||
print(f"获取配置目录失败: {e}")
|
||
print("使用默认配置目录...")
|
||
config_dir = "./default_config/"
|
||
```
|
||
|
||
Sources: [ssprocess_mixins/project_mixin.py](ssprocess_mixins/project_mixin.py#L71-L116)
|
||
|
||
## API 快速参考
|
||
|
||
以下是系统路径管理相关方法的快速参考表:
|
||
|
||
| 方法 | 参数 | 返回值 | 说明 |
|
||
|-----|------|--------|------|
|
||
| `getSysPathName(mode)` | mode: int (0-8) | str | 获取指定模式的系统路径 |
|
||
|
||
**GlobalOptions 底层方法**(供高级用户参考):
|
||
|
||
| 方法 | 返回值 | 说明 |
|
||
|-----|--------|------|
|
||
| `getConfigurePath()` | std::filesystem::path | 获取配置路径 |
|
||
| `getTemplatePath()` | std::filesystem::path | 获取模板路径 |
|
||
| `getCommonPath()` | std::filesystem::path | 获取公共资源路径 |
|
||
| `getEpsTempPath()` | std::filesystem::path | 获取临时文件路径 |
|
||
| `getSchemeFilePath(fileName)` | std::filesystem::path | 获取工作台面下的文件路径 |
|
||
| `getScriptsPath()` | std::filesystem::path | 获取当前台面下的 scripts 文件夹路径 |
|
||
|
||
Sources: [PySSWidget.py](PySSWidget.py#L989-L1390), [ssprocess_mixins/project_mixin.py](ssprocess_mixins/project_mixin.py#L71-L116)
|
||
|
||
## 下一步学习
|
||
|
||
掌握了系统路径管理的方法后,您可以继续学习以下相关主题:
|
||
|
||
- **获取工作空间信息**:[获取工作空间信息](34-huo-qu-gong-zuo-kong-jian-xin-xi) 了解如何获取工作空间、地图、图层等系统信息
|
||
- **地图缩放控制**:[地图缩放控制](36-di-tu-suo-fang-kong-zhi) 学习如何控制地图视图的缩放和平移
|
||
- **数据交换与导入导出**:[数据交换参数配置](26-shu-ju-jiao-huan-can-shu-pei-zhi) 探索如何配置和管理数据交换流程
|
||
- **工作空间与地图概念**:[工作空间与地图概念](8-gong-zuo-kong-jian-yu-di-tu-gai-nian) 深入理解工作空间和地图的底层架构
|
||
|
||
通过系统学习这些内容,您将能够构建功能完善、路径规范的 SunvStation 二次开发脚本,充分发挥系统的强大功能。 |