Files
sunvpy-docs/docs/content/34-huo-qu-gong-zuo-kong-jian-xin-xi.md
2026-04-10 13:47:53 +08:00

566 lines
18 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
获取工作空间信息是 SunvStation 开发中的基础操作,它允许脚本访问当前活动的地图实例、系统路径、图层配置以及各种表管理信息。掌握这些信息获取方法对于构建功能完善的脚本至关重要。
## 架构概览
工作空间信息获取通过 `ProjectMixin` 提供的便捷方法实现,这些方法封装了底层的 `WorkSpace``ScaleMap` 对象访问逻辑。以下展示了获取工作空间信息的调用层次结构:
```mermaid
graph TD
A[Python 脚本] -->|调用| B[SSProcess 实例]
B -->|继承| C[ProjectMixin]
C -->|提供方法| D[getWorkspace]
C -->|提供方法| E[getCurrentMap]
C -->|提供方法| F[getSysPathName]
C -->|提供方法| G[getLayerCount/Name]
C -->|提供方法| H[getFeatureCodeTB]
D -->|访问| WS[WorkSpace 单例]
E -->|调用| WS
WS -->|返回| SM[ScaleMap 当前地图]
F -->|使用| GO[GlobalOptions 单例]
G -->|访问| SM
H -->|访问| SM
style B fill:#e1f5ff
style C fill:#fff4e1
style WS fill:#f0f0f0
style SM fill:#f0f0f0
```
Sources: [PySSProcess.py](PySSProcess.py#L30-L60), [ssprocess_mixins/project_mixin.py](ssprocess_mixins/project_mixin.py#L1-L267)
## 获取工作空间实例
工作空间是 SunvStation 系统的全局单例对象,通过 `getWorkspace()` 方法可以获取当前工作空间的实例。这个实例提供了访问系统级资源和配置的入口。
### 基本用法
```python
# 获取工作空间实例
workspace = SSProcess.getWorkspace()
# 获取当前活动的地图
current_map = workspace.getCurrentScaleMap()
```
Sources: [ssprocess_mixins/project_mixin.py](ssprocess_mixins/project_mixin.py#L36-L43)
### 使用场景
获取工作空间实例的主要使用场景包括:
- **访问多个地图**:当需要操作非当前活动的地图时
- **系统级配置**:获取全局配置选项和路径信息
- **资源协调**:在不同地图间协调资源访问
## 获取当前地图
`getCurrentMap()` 方法返回当前活动的地图实例(`ScaleMap` 类型),这是进行地图操作的主要入口。
### 获取方法
```python
# 获取当前地图
current_map = SSProcess.getCurrentMap()
# 检查地图是否存在
if current_map is None:
print("当前没有打开的地图")
return
# 获取地图项目名称
project_name = current_map.getProjectName()
```
Sources: [ssprocess_mixins/project_mixin.py](ssprocess_mixins/project_mixin.py#L45-L50)
### 地图信息获取表
| 信息类型 | 获取方法 | 说明 |
|---------|---------|------|
| 项目名称 | `getProjectName()` | 返回当前工程文件路径 |
| 图层数量 | `getLayerSize()` | 返回地图中的图层数量 |
| 数据源 | `getCurrentDataSource()` | 返回当前活动的数据源 |
Sources: [PySSMap.py](PySSMap.py#L355-L430)
## 获取系统路径
系统路径信息对于脚本访问配置文件、模板、脚本目录等非常重要。`getSysPathName(mode)` 方法根据模式参数返回不同类型的系统路径。
### 路径模式对照表
| 模式 | 路径类型 | 说明 | 典型用途 |
|-----|---------|------|---------|
| 0 | 配置路径 | 存放系统配置文件 | 读取系统配置 |
| 1 | 模板路径 | 存放模板文件 | 加载数据模板 |
| 2 | Comm 路径 | 公共资源路径 | 访问共享资源 |
| 3 | Script 路径 | 脚本文件路径 | 动态加载脚本 |
| 4 | SSTemp 路径 | 临时文件路径 | 存储临时数据 |
| 5 | 工程文件路径 | 当前工程所在目录 | 相对路径计算 |
| 6 | 系统目录 | Windows 系统目录或 Unix /usr | 访问系统文件 |
| 7/8 | 工作台面目录 | 用户工作台面目录 | 输出文件保存 |
Sources: [ssprocess_mixins/project_mixin.py](ssprocess_mixins/project_mixin.py#L52-L80)
### 使用示例
```python
# 获取各类系统路径
config_path = SSProcess.getSysPathName(0) # 配置路径
template_path = SSProcess.getSysPathName(1) # 模板路径
script_path = SSProcess.getSysPathName(3) # 脚本路径
temp_path = SSProcess.getSysPathName(4) # 临时路径
project_dir = SSProcess.getSysPathName(5) # 工程目录
print(f"配置路径: {config_path}")
print(f"脚本路径: {script_path}")
print(f"工程目录: {project_dir}")
# 使用系统路径构造文件路径
config_file = config_path + "system_config.ini"
```
### 路径获取流程
```mermaid
flowchart LR
A[调用 getSysPathName] --> B{判断 mode 参数}
B -->|mode 0| C[返回配置路径]
B -->|mode 1| D[返回模板路径]
B -->|mode 2| E[返回 Comm 路径]
B -->|mode 3| F[返回 Script 路径]
B -->|mode 4| G[返回 SSTemp 路径]
B -->|mode 5| H{获取当前地图项目名}
H -->|成功| I[返回工程目录]
H -->|失败| J[返回空字符串]
B -->|mode 6| K{判断操作系统}
K -->|Windows| L[返回 WINDIR 路径]
K -->|Unix| M[返回 /usr 路径]
B -->|mode 7/8| N[返回工作台面目录]
B -->|其他| O[返回空字符串]
style A fill:#e1f5ff
style H fill:#fff4e1
style K fill:#fff4e1
```
Sources: [ssprocess_mixins/project_mixin.py](ssprocess_mixins/project_mixin.py#L52-L80)
## 获取图层信息
图层信息获取包括图层数量查询和图层名称查询,这对于批量处理图层和检查图层状态非常有用。
### 图层操作方法
| 方法 | 功能描述 | 返回值 |
|-----|---------|--------|
| `getLayerCount()` | 获取当前地图中的图层数量 | int |
| `getLayerName(index)` | 获取指定索引的图层名称 | str |
| `setLayerStatus(layerName, status, type)` | 设置图层状态 | bool |
Sources: [ssprocess_mixins/project_mixin.py](ssprocess_mixins/project_mixin.py#L180-L198)
### 使用示例
```python
# 获取图层数量
layer_count = SSProcess.getLayerCount()
print(f"当前地图共有 {layer_count} 个图层")
# 遍历所有图层并输出名称
for i in range(layer_count):
layer_name = SSProcess.getLayerName(i)
print(f" 图层 {i}: {layer_name}")
# 设置图层状态
# type=1: 控制可见性, type=2: 控制编辑锁定
SSProcess.setLayerStatus("DLG", True, 1) # 显示 DLG 图层
SSProcess.setLayerStatus("DLG", False, 2) # 解锁 DLG 图层
```
### 图层信息获取流程
```mermaid
sequenceDiagram
participant Script as Python 脚本
participant P as ProjectMixin
participant M as ScaleMap
participant L as Layer
Script->>P: getLayerCount()
P->>M: getLayerSize()
M->>Script: 返回图层数量
Script->>P: getLayerName(index)
P->>M: getLayerName(index)
M->>L: 查询图层名称
L->>M: 返回名称
M->>Script: 返回图层名称
Script->>P: setLayerStatus(name, status, type)
alt type=1
P->>M: setLayerVisible(name, status)
else type=2
P->>M: setLayerLock(name, status)
end
M->>Script: 返回操作结果
```
Sources: [ssprocess_mixins/project_mixin.py](ssprocess_mixins/project_mixin.py#L180-L198)
## 获取符号表信息
符号表包括要素代码表、符号脚本表和注记模板表,这些表定义了地物的显示样式和属性结构。
### 符号表查询方法
| 方法 | 功能描述 | 返回值 |
|-----|---------|--------|
| `getFeatureCodeTB()` | 获取当前要素代码表名称 | str |
| `getSymbolScriptTB()` | 获取当前符号脚本表名称 | str |
| `getNoteTemplateTB()` | 获取当前注记模板表名称 | str |
Sources: [ssprocess_mixins/project_mixin.py](ssprocess_mixins/project_mixin.py#L200-L213)
### 使用示例
```python
# 获取当前符号表信息
feature_code_tb = SSProcess.getFeatureCodeTB()
symbol_script_tb = SSProcess.getSymbolScriptTB()
note_template_tb = SSProcess.getNoteTemplateTB()
print(f"要素代码表: {feature_code_tb}")
print(f"符号脚本表: {symbol_script_tb}")
print(f"注记模板表: {note_template_tb}")
# 检查符号表是否加载
if not feature_code_tb:
print("警告: 当前未加载要素代码表")
```
### 符号表切换
当需要切换到不同的符号表时,可以使用设置方法:
```python
# 设置新的要素代码表和符号表
success = SSProcess.setFeatureCodeTB("EPS2008", "EPS2008_Symbol")
if success:
print("符号表切换成功")
else:
print("符号表切换失败")
# 设置注记模板表
success = SSProcess.setNoteTemplateTB("Note_Template_Default")
```
Sources: [ssprocess_mixins/project_mixin.py](ssprocess_mixins/project_mixin.py#L215-L267)
## 获取地图图幅信息
地图图幅是地图的逻辑划分单位,用于组织地图的分幅显示。`ProjectMixin` 提供了完整的图幅管理接口。
### 图幅操作方法
| 方法 | 功能描述 | 返回值 |
|-----|---------|--------|
| `createMapFrame()` | 创建当前地图的图幅列表 | bool |
| `getMapFrameCount()` | 获取图幅数量 | int |
| `getMapFrameCenterPoint(index)` | 获取指定图幅的中心点坐标 | tuple (x, y) |
| `setCurMapFrame(x, y)` | 设置当前图幅 | GeoBase |
| `getCurMapFrame()` | 获取当前图幅的编号 | int |
| `getMapFrameNumber(x, y)` | 获取指定坐标所在的图幅号 | int |
| `freeMapFrame()` | 释放图幅资源 | void |
Sources: [ssprocess_mixins/project_mixin.py](ssprocess_mixins/project_mixin.py#L122-L178)
### 使用示例
```python
# 创建图幅列表
if SSProcess.createMapFrame():
# 获取图幅数量
frame_count = SSProcess.getMapFrameCount()
print(f"地图共有 {frame_count} 个图幅")
# 遍历所有图幅并输出中心点
for i in range(frame_count):
x, y = SSProcess.getMapFrameCenterPoint(i)
print(f" 图幅 {i} 中心点: ({x}, {y})")
# 设置当前图幅
frame_x, frame_y = SSProcess.getMapFrameCenterPoint(0)
SSProcess.setCurMapFrame(frame_x, frame_y)
# 获取当前图幅编号
current_frame = SSProcess.getCurMapFrame()
print(f"当前图幅编号: {current_frame}")
# 查询指定坐标所在的图幅
test_x, test_y = 1000, 2000
frame_num = SSProcess.getMapFrameNumber(test_x, test_y)
print(f"坐标 ({test_x}, {test_y}) 位于图幅 {frame_num}")
# 释放图幅资源
SSProcess.freeMapFrame()
else:
print("创建图幅列表失败")
```
### 图幅处理流程
```mermaid
flowchart TD
A[开始] --> B[createMapFrame]
B --> C{创建成功?}
C -->|否| D[报错退出]
C -->|是| E[getMapFrameCount]
E --> F{有图幅?}
F -->|否| G[freeMapFrame]
F -->|是| H[遍历图幅]
H --> I[getMapFrameCenterPoint]
I --> J{还有图幅?}
J -->|是| H
J -->|否| K[setCurMapFrame]
K --> L[getMapFrameNumber]
L --> M[freeMapFrame]
M --> N[结束]
G --> N
style B fill:#e1f5ff
style E fill:#fff4e1
style I fill:#fff4e1
```
Sources: [ssprocess_mixins/project_mixin.py](ssprocess_mixins/project_mixin.py#L122-L178)
## 综合应用示例
以下是一个综合示例,展示如何在实际脚本中组合使用各种工作空间信息获取方法:
```python
from sunvpy import SSProcess
def analyze_workspace_info():
"""分析并输出当前工作空间的综合信息"""
# 获取工作空间和地图
workspace = SSProcess.getWorkspace()
current_map = SSProcess.getCurrentMap()
if current_map is None:
print("错误: 当前没有打开的地图")
return
print("=" * 60)
print("工作空间信息分析")
print("=" * 60)
# 输出项目信息
print("\n【项目信息】")
project_name = current_map.getProjectName()
print(f"项目名称: {project_name}")
# 输出系统路径
print("\n【系统路径】")
print(f"配置路径: {SSProcess.getSysPathName(0)}")
print(f"模板路径: {SSProcess.getSysPathName(1)}")
print(f"脚本路径: {SSProcess.getSysPathName(3)}")
print(f"工程目录: {SSProcess.getSysPathName(5)}")
# 输出图层信息
print("\n【图层信息】")
layer_count = SSProcess.getLayerCount()
print(f"图层数量: {layer_count}")
for i in range(min(5, layer_count)): # 最多显示前5个图层
layer_name = SSProcess.getLayerName(i)
print(f" - {layer_name}")
if layer_count > 5:
print(f" ... (还有 {layer_count - 5} 个图层)")
# 输出符号表信息
print("\n【符号表信息】")
print(f"要素代码表: {SSProcess.getFeatureCodeTB()}")
print(f"符号脚本表: {SSProcess.getSymbolScriptTB()}")
print(f"注记模板表: {SSProcess.getNoteTemplateTB()}")
# 输出图幅信息
print("\n【图幅信息】")
if SSProcess.createMapFrame():
frame_count = SSProcess.getMapFrameCount()
print(f"图幅数量: {frame_count}")
if frame_count > 0:
x, y = SSProcess.getMapFrameCenterPoint(0)
print(f"首个图幅中心点: ({x:.2f}, {y:.2f})")
SSProcess.freeMapFrame()
else:
print("未创建图幅列表")
print("\n" + "=" * 60)
print("分析完成")
print("=" * 60)
# 执行分析
analyze_workspace_info()
```
## 最佳实践
在使用工作空间信息获取功能时,遵循以下最佳实践可以提高脚本的健壮性和可维护性:
### 1. 始终检查空引用
在访问地图或其方法前,检查地图实例是否存在:
```python
current_map = SSProcess.getCurrentMap()
if current_map is None:
print("当前没有打开的地图,无法执行操作")
return
```
Sources: [ssprocess_mixins/project_mixin.py](ssprocess_mixins/project_mixin.py#L45-L50)
### 2. 合理使用系统路径
优先使用系统路径而不是硬编码路径,这样可以确保脚本在不同环境下的兼容性:
```python
# 好的做法
script_path = SSProcess.getSysPathName(3)
script_file = script_path + "my_script.py"
# 不好的做法(硬编码)
script_file = "C:\\SunvStation\\scripts\\my_script.py"
```
### 3. 及时释放资源
对于图幅等需要显式释放的资源,使用 try-finally 确保资源被正确释放:
```python
try:
SSProcess.createMapFrame()
# 处理图幅...
finally:
SSProcess.freeMapFrame()
```
Sources: [ssprocess_mixins/project_mixin.py](ssprocess_mixins/project_mixin.py#L122-L178)
### 4. 批量操作前检查图层状态
在进行批量操作前,检查目标图层是否存在且可编辑:
```python
layer_name = "DLG"
layer_count = SSProcess.getLayerCount()
layer_exists = any(SSProcess.getLayerName(i) == layer_name
for i in range(layer_count))
if not layer_exists:
print(f"错误: 图层 {layer_name} 不存在")
return
# 进一步检查图层状态...
```
### 5. 使用日志记录关键信息
在获取关键工作空间信息时,使用日志记录以便调试和追踪:
```python
# 配置日志记录器
SSProcess.configure_logger("workspace_script.log", level="INFO")
logger = SSProcess.logger
logger.info(f"当前项目: {current_map.getProjectName()}")
logger.info(f"图层数量: {SSProcess.getLayerCount()}")
```
Sources: [ssprocess_mixins/log_mixin.py](ssprocess_mixins/log_mixin.py#L1-L50)
## 错误处理与调试
在获取工作空间信息时可能会遇到各种错误情况,以下是一些常见的错误处理模式:
### 常见错误类型
| 错误类型 | 可能原因 | 处理方法 |
|---------|---------|---------|
| 返回 None | 当前没有打开地图 | 检查 getCurrentMap() 返回值 |
| 返回空字符串 | 路径不存在或项目未保存 | 检查返回值是否为空 |
| 索引越界 | 图层索引超出范围 | 使用 getLayerCount() 验证 |
| 图幅创建失败 | 地图中无地物对象 | 检查 createMapFrame() 返回值 |
### 错误处理示例
```python
def safe_get_layer_info(index):
"""安全地获取图层信息"""
try:
# 检查地图是否存在
if SSProcess.getCurrentMap() is None:
raise RuntimeError("当前没有打开的地图")
# 检查索引是否有效
layer_count = SSProcess.getLayerCount()
if index < 0 or index >= layer_count:
raise IndexError(f"图层索引 {index} 超出范围 [0, {layer_count-1}]")
# 获取图层名称
layer_name = SSProcess.getLayerName(index)
if not layer_name:
raise ValueError(f"图层 {index} 的名称为空")
return layer_name
except Exception as e:
print(f"获取图层信息失败: {e}")
return None
# 使用示例
layer_name = safe_get_layer_info(0)
if layer_name:
print(f"成功获取图层: {layer_name}")
```
## API 快速参考
以下是工作空间信息获取相关方法的快速参考表:
| 方法 | 参数 | 返回值 | 说明 |
|-----|------|--------|------|
| `getWorkspace()` | 无 | WorkSpace | 获取工作空间实例 |
| `getCurrentMap()` | 无 | ScaleMap | 获取当前地图实例 |
| `getSysPathName(mode)` | mode: int | str | 获取系统路径 |
| `getLayerCount()` | 无 | int | 获取图层数量 |
| `getLayerName(index)` | index: int | str | 获取图层名称 |
| `setLayerStatus(name, status, type)` | name: str, status: bool, type: int | bool | 设置图层状态 |
| `getFeatureCodeTB()` | 无 | str | 获取要素代码表名称 |
| `getSymbolScriptTB()` | 无 | str | 获取符号表名称 |
| `getNoteTemplateTB()` | 无 | str | 获取注记模板表名称 |
| `setFeatureCodeTB(codeTB, symbolTB)` | codeTB: str, symbolTB: str | bool | 设置要素代码表 |
| `setNoteTemplateTB(templateTB)` | templateTB: str | bool | 设置注记模板表 |
| `createMapFrame()` | 无 | bool | 创建图幅列表 |
| `getMapFrameCount()` | 无 | int | 获取图幅数量 |
| `getMapFrameCenterPoint(index)` | index: int | tuple | 获取图幅中心点 |
| `setCurMapFrame(x, y)` | x: float, y: float | GeoBase | 设置当前图幅 |
| `getCurMapFrame()` | 无 | int | 获取当前图幅编号 |
| `getMapFrameNumber(x, y)` | x: float, y: float | int | 获取坐标所在图幅号 |
| `freeMapFrame()` | 无 | void | 释放图幅资源 |
Sources: [ssprocess_mixins/project_mixin.py](ssprocess_mixins/project_mixin.py#L36-L267)
## 下一步学习
掌握了获取工作空间信息的方法后,您可以继续学习以下相关主题:
- **系统路径管理**[系统路径管理](35-xi-tong-lu-jing-guan-li) 深入了解更高级的路径操作技巧
- **地图缩放控制**[地图缩放控制](36-di-tu-suo-fang-kong-zhi) 学习如何控制地图视图的缩放和平移
- **选择集与查询**[清除与初始化选择集](11-qing-chu-yu-chu-shi-hua-xuan-ze-ji) 探索如何在地图中查询和选择地物
- **工作空间与地图概念**[工作空间与地图概念](8-gong-zuo-kong-jian-yu-di-tu-gai-nian) 理解工作空间和地图的底层架构
通过系统学习这些内容,您将能够构建功能完善的 SunvStation 二次开发脚本,充分发挥系统的强大功能。