Files
sunvpy-docs/docs/content/34-huo-qu-gong-zuo-kong-jian-xin-xi.md

566 lines
18 KiB
Markdown
Raw Normal View History

2026-04-10 13:47:53 +08:00
获取工作空间信息是 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 二次开发脚本,充分发挥系统的强大功能。