Files
sunvpy-docs/docs/content/8-gong-zuo-kong-jian-yu-di-tu-gai-nian.md

319 lines
12 KiB
Markdown
Raw Normal View History

2026-04-10 13:47:53 +08:00
SunvStation 地理信息系统采用分层架构设计,其中工作空间与地图是理解整个系统的核心概念。本页将详细阐述这两个核心组件的职责、相互关系以及在 Python 脚本中的使用方式。掌握这些概念是高效使用 sunvpy 库进行二次开发的基础。
## 系统架构概览
SunvStation 系统采用单例模式的工作空间作为顶级容器,管理所有地图实例和系统资源。工作空间通过 `getInstance()` 方法获取全局唯一实例,确保整个应用程序共享同一资源上下文。地图对象则表示特定比例尺的地理数据视图,包含图层、地物、数据源等子组件。
```mermaid
graph TB
subgraph "应用程序级别"
WS[WorkSpace 工作空间<br/>单例实例]
end
subgraph "地图级别"
SM1[ScaleMap 地图1<br/>比例尺1:500]
SM2[ScaleMap 地图2<br/>比例尺1:1000]
end
subgraph "SM1 组件"
L1[图层1]
L2[图层2]
DS1[数据源EPS]
end
subgraph "SM2 组件"
L3[图层3]
L4[图层4]
DS2[数据源EPS]
end
subgraph "Python 脚本"
PSS[SSProcessManager<br/>SSProcess全局实例]
end
PSS --> |WorkSpace.getInstance| WS
PSS --> |getCurrentScaleMap| SM1
WS --> |管理多个| SM1
WS --> |管理多个| SM2
SM1 --> |包含| L1
SM1 --> |包含| L2
SM1 --> |引用| DS1
SM2 --> |包含| L3
SM2 --> |包含| L4
SM2 --> |引用| DS2
```
上图展示了系统的核心架构。工作空间作为顶级容器管理所有地图实例。每个地图对象包含一组图层和关联的数据源。Python 脚本通过 `SSProcess` 全局实例访问工作空间和当前地图,实现与系统资源的交互。
Sources: [PySSProcess.py](PySSProcess.py#L30-L60)
## 工作空间
工作空间是 SunvStation 系统的全局单例对象,负责管理整个应用程序的资源和上下文。它提供统一的入口点来访问当前活动的地图、配置信息和系统路径。
### 核心特性
工作空间采用单例设计模式,确保整个应用程序中只有一个工作空间实例。这种设计有以下优势:
- **资源统一管理**:所有地图实例和共享资源由工作空间统一分配和协调
- **全局状态一致性**:确保不同模块访问的系统状态保持一致
- **生命周期控制**:工作空间控制整个应用程序的生命周期,包括资源的创建和销毁
### 获取工作空间实例
在 Python 脚本中,通过 `WorkSpace.getInstance()` 方法获取工作空间实例。`SSProcessManager` 在初始化时会自动获取工作空间实例并存储为成员变量 `self.workspace`
Sources: [PySSProcess.py](PySSProcess.py#L42-L43)
### 主要职责
工作空间的核心职责包括:
- **地图管理**:维护所有打开的地图实例,提供获取当前活动地图的接口
- **资源协调**:协调地图之间的资源共享和互斥访问
- **全局配置**:存储和管理全局配置信息
- **系统路径**:提供系统级路径信息(配置路径、模板路径、脚本路径等)
### 便捷访问方法
`ProjectMixin` 提供了便捷方法 `getWorkspace()` 来获取工作空间实例:
Sources: [ssprocess_mixins/project_mixin.py](ssprocess_mixins/project_mixin.py#L36-L43)
## 地图
地图对象(`ScaleMap`)表示特定比例尺的地理数据视图,是工作空间中最核心的可视化和编辑单元。每个地图包含一组图层、地物对象和关联的数据源。
### 地图对象定义
`ScaleMap` 类定义在 `PySSMap` 模块中,通过 SWIG 从 C++ 封装而来。它是地图数据的主要容器和管理者。
Sources: [PySSMap.py](PySSMap.py#L303-L330)
### 地图组成结构
地图由以下核心组件构成:
| 组件类型 | 职责 | Python 类型 |
|---------|------|-----------|
| 图层 | 组织和管理地物对象,控制可见性和锁定状态 | Layer |
| 数据源 | 存储地物数据的底层存储EPS 数据库) | DataSource |
| 地物对象 | 点、线、面等地理要素 | GeoObject |
| 选择集 | 当前选中的地物集合 | GeoBaseList |
| 符号表 | 要素编码和符号样式定义 | FeatureList |
### 图层管理
图层是地图中组织地物的逻辑单元。每个图层对应特定的数据类型(点、线、面、注记),可以独立控制其可见性和编辑锁定状态。
#### 图层操作 API
| 方法 | 功能描述 |
|-----|---------|
| `getLayerSize()` | 获取图层数量 |
| `getLayerName(index)` | 获取指定索引的图层名称 |
| `setLayerVisible(layerName, status)` | 设置图层可见性 |
| `isLayerVisible(layerName)` | 检查图层是否可见 |
| `setLayerLock(layerName, status)` | 设置图层锁定状态 |
| `isLayerLock(layerName)` | 检查图层是否锁定 |
Sources: [PySSMap.py](PySSMap.py#L355-L430)
#### 便捷访问方法
`ProjectMixin` 提供了简化的图层访问接口:
Sources: [ssprocess_mixins/project_mixin.py](ssprocess_mixins/project_mixin.py#L180-L198)
### 数据源管理
数据源是存储地物数据的底层存储,通常是 EPS 格式的数据库。地图可以加载多个数据源,每个数据源包含多个数据集。
| 方法 | 功能描述 |
|-----|---------|
| `getCurrentDataSource()` | 获取当前激活的数据源 |
| `setCurrentDataSource(dataSource)` | 设置当前数据源 |
| `unloadDataSource(dataSource)` | 卸载指定的数据源 |
| `getDataSourceSet(dataSourceSet)` | 获取所有可见图层使用的数据源集合 |
Sources: [PySSMap.py](PySSMap.py#L445-L480)
### 地物搜索与检索
地图提供了强大的地物搜索功能,支持多种搜索条件:
| 方法 | 功能描述 |
|-----|---------|
| `searchObject(objList, ...)` | 根据编码、矩形范围、点位置等条件搜索地物 |
| `searchMarkNote(geoList, ...)` | 搜索注记对象 |
| `getNearObject(point, range, ...)` | 获取指定点附近的地物或注记 |
| `getObjectSize(objType)` | 获取指定类型的地物个数 |
Sources: [PySSMap.py](PySSMap.py#L650-L1000)
### 撤销与重做
地图内置了完整的撤销/重做机制,所有可撤销操作都会被记录在命令栈中。
| 方法 | 功能描述 |
|-----|---------|
| `pushUndoMark(action)` | 创建撤销标记,用于分组多个操作 |
| `undo(step=1)` | 执行撤销操作step 指定步数 |
| `redo(step=1)` | 执行重做操作 |
| `getUndoStackSize()` | 获取撤销栈的大小 |
| `getRedoStackSize()` | 获取重做栈的大小 |
Sources: [PySSMap.py](PySSMap.py#L1565-L1610)
## 工作空间与地图的关系
工作空间和地图之间的关系是整体与部分的关系。工作空间作为全局容器,可以管理多个地图实例,但通常只有一个当前活动的地图。
### 访问当前地图
通过工作空间的 `getCurrentScaleMap()` 方法获取当前活动的地图实例。在 `SSProcessManager` 初始化时,会自动获取当前地图并存储为成员变量 `self.map`
Sources: [PySSProcess.py](PySSProcess.py#L42-L43)
### 地图切换
当用户切换地图时例如从不同比例尺的地图视图切换工作空间会更新当前活动的地图引用。Python 脚本可以通过以下方式获取最新的当前地图:
```python
# 方法1直接使用 SSProcess 的 map 成员
current_map = SSProcess.map
# 方法2通过工作空间获取
current_map = SSProcess.workspace.getCurrentScaleMap()
# 方法3使用便捷方法
current_map = SSProcess.getCurrentMap()
```
Sources: [ssprocess_mixins/project_mixin.py](ssprocess_mixins/project_mixin.py#L45-L50)
## 系统路径管理
工作空间和相关组件提供了获取系统路径的接口,这些路径对于脚本操作文件和配置非常重要。
### 路径类型表
| 模式 | 路径类型 | 说明 |
|-----|---------|------|
| 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
# 获取脚本路径
script_path = SSProcess.getSysPathName(3)
# 获取当前工程文件所在目录
project_dir = SSProcess.getSysPathName(5)
# 获取配置路径
config_path = SSProcess.getSysPathName(0)
```
## 符号表管理
地图使用符号表来定义地物的显示样式和要素编码。符号表包括要素代码表、符号脚本表和注记模板表。
| 方法 | 功能描述 |
|-----|---------|
| `getFeatureCodeTB()` | 获取当前要素代码表名称 |
| `getSymbolScriptTB()` | 获取当前符号表名称 |
| `getNoteTemplateTB()` | 获取当前注记模板表名称 |
| `setFeatureCodeTB(codeTB, symbolTB)` | 设置要素代码表和符号表 |
| `setNoteTemplateTB(templateTB)` | 设置注记模板表 |
Sources: [ssprocess_mixins/project_mixin.py](ssprocess_mixins/project_mixin.py#L200-L267)
## 地图图幅管理
地图图幅是地图的一个逻辑划分单位,用于组织和管理地图的分幅显示。`ProjectMixin` 提供了图幅相关操作:
| 方法 | 功能描述 |
|-----|---------|
| `createMapFrame()` | 创建当前地图的图幅列表 |
| `getMapFrameCount()` | 获取图幅数量 |
| `getMapFrameCenterPoint(index)` | 获取指定图幅的中心点坐标 |
| `setCurMapFrame(x, y)` | 设置当前图幅 |
| `getCurMapFrame()` | 获取当前图幅的编号 |
| `getMapFrameNumber(x, y)` | 获取指定坐标所在的图幅号 |
| `freeMapFrame()` | 释放图幅资源 |
Sources: [ssprocess_mixins/project_mixin.py](ssprocess_mixins/project_mixin.py#L122-L178)
## 最佳实践
在使用工作空间和地图时,遵循以下最佳实践可以编写更健壮和高效的代码:
### 1. 始终检查空引用
访问地图或工作空间对象前,检查是否为 None
```python
current_map = SSProcess.getCurrentMap()
if current_map is None:
print("当前没有打开的地图")
return
```
### 2. 使用便捷方法优先
`ProjectMixin` 提供的便捷方法已经处理了常见的边界情况,优先使用这些方法而不是直接访问底层对象。
### 3. 批量操作使用撤销标记
执行批量修改操作前,先创建撤销标记:
```python
SSProcess.pushUndoMark("批量属性修改")
# 执行批量操作...
```
### 4. 及时释放资源
对于创建的临时资源(如图幅列表),使用完毕后及时释放:
```python
try:
SSProcess.createMapFrame()
# 处理图幅...
finally:
SSProcess.freeMapFrame()
```
### 5. 尊重图层锁定状态
修改地物前检查图层是否锁定:
```python
layer_name = "DLG"
if not SSProcess.map.isLayerLock(layer_name):
# 执行修改操作
pass
else:
print(f"图层 {layer_name} 已锁定,无法编辑")
```
## 与其他文档的关联
理解工作空间与地图概念后,可以继续深入学习以下主题:
- **选择集与查询**[清除与初始化选择集](11-qing-chu-yu-chu-shi-hua-xuan-ze-ji) 了解如何在地图中查询和选择地物
- **地理对象编辑**[创建默认地物对象](19-chuang-jian-mo-ren-di-wu-dui-xiang) 学习如何在工作空间和地图中创建地物
- **项目与工作流**[获取工作空间信息](34-huo-qu-gong-zuo-kong-jian-xin-xi) 探索更多工作空间信息获取方法
- **Mixin 设计模式**[Mixin 设计模式](9-mixin-she-ji-mo-shi) 理解 ProjectMixin 等模块的设计理念
通过掌握工作空间与地图的核心概念,您将能够更高效地使用 sunvpy 库进行二次开发,构建功能强大的地理信息处理脚本。