319 lines
12 KiB
Markdown
319 lines
12 KiB
Markdown
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 库进行二次开发,构建功能强大的地理信息处理脚本。 |