获取工作空间信息是 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 二次开发脚本，充分发挥系统的强大功能。