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

18 KiB
Raw Blame History

获取工作空间信息是 SunvStation 开发中的基础操作,它允许脚本访问当前活动的地图实例、系统路径、图层配置以及各种表管理信息。掌握这些信息获取方法对于构建功能完善的脚本至关重要。

架构概览

工作空间信息获取通过 ProjectMixin 提供的便捷方法实现,这些方法封装了底层的 WorkSpaceScaleMap 对象访问逻辑。以下展示了获取工作空间信息的调用层次结构:

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, ssprocess_mixins/project_mixin.py

获取工作空间实例

工作空间是 SunvStation 系统的全局单例对象,通过 getWorkspace() 方法可以获取当前工作空间的实例。这个实例提供了访问系统级资源和配置的入口。

基本用法

# 获取工作空间实例
workspace = SSProcess.getWorkspace()

# 获取当前活动的地图
current_map = workspace.getCurrentScaleMap()

Sources: ssprocess_mixins/project_mixin.py

使用场景

获取工作空间实例的主要使用场景包括:

  • 访问多个地图:当需要操作非当前活动的地图时
  • 系统级配置:获取全局配置选项和路径信息
  • 资源协调:在不同地图间协调资源访问

获取当前地图

getCurrentMap() 方法返回当前活动的地图实例(ScaleMap 类型),这是进行地图操作的主要入口。

获取方法

# 获取当前地图
current_map = SSProcess.getCurrentMap()

# 检查地图是否存在
if current_map is None:
    print("当前没有打开的地图")
    return

# 获取地图项目名称
project_name = current_map.getProjectName()

Sources: ssprocess_mixins/project_mixin.py

地图信息获取表

信息类型 获取方法 说明
项目名称 getProjectName() 返回当前工程文件路径
图层数量 getLayerSize() 返回地图中的图层数量
数据源 getCurrentDataSource() 返回当前活动的数据源

Sources: PySSMap.py

获取系统路径

系统路径信息对于脚本访问配置文件、模板、脚本目录等非常重要。getSysPathName(mode) 方法根据模式参数返回不同类型的系统路径。

路径模式对照表

模式 路径类型 说明 典型用途
0 配置路径 存放系统配置文件 读取系统配置
1 模板路径 存放模板文件 加载数据模板
2 Comm 路径 公共资源路径 访问共享资源
3 Script 路径 脚本文件路径 动态加载脚本
4 SSTemp 路径 临时文件路径 存储临时数据
5 工程文件路径 当前工程所在目录 相对路径计算
6 系统目录 Windows 系统目录或 Unix /usr 访问系统文件
7/8 工作台面目录 用户工作台面目录 输出文件保存

Sources: ssprocess_mixins/project_mixin.py

使用示例

# 获取各类系统路径
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"

路径获取流程

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

获取图层信息

图层信息获取包括图层数量查询和图层名称查询,这对于批量处理图层和检查图层状态非常有用。

图层操作方法

方法 功能描述 返回值
getLayerCount() 获取当前地图中的图层数量 int
getLayerName(index) 获取指定索引的图层名称 str
setLayerStatus(layerName, status, type) 设置图层状态 bool

Sources: ssprocess_mixins/project_mixin.py

使用示例

# 获取图层数量
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 图层

图层信息获取流程

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

获取符号表信息

符号表包括要素代码表、符号脚本表和注记模板表,这些表定义了地物的显示样式和属性结构。

符号表查询方法

方法 功能描述 返回值
getFeatureCodeTB() 获取当前要素代码表名称 str
getSymbolScriptTB() 获取当前符号脚本表名称 str
getNoteTemplateTB() 获取当前注记模板表名称 str

Sources: ssprocess_mixins/project_mixin.py

使用示例

# 获取当前符号表信息
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("警告: 当前未加载要素代码表")

符号表切换

当需要切换到不同的符号表时,可以使用设置方法:

# 设置新的要素代码表和符号表
success = SSProcess.setFeatureCodeTB("EPS2008", "EPS2008_Symbol")
if success:
    print("符号表切换成功")
else:
    print("符号表切换失败")

# 设置注记模板表
success = SSProcess.setNoteTemplateTB("Note_Template_Default")

Sources: ssprocess_mixins/project_mixin.py

获取地图图幅信息

地图图幅是地图的逻辑划分单位,用于组织地图的分幅显示。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

使用示例

# 创建图幅列表
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("创建图幅列表失败")

图幅处理流程

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

综合应用示例

以下是一个综合示例,展示如何在实际脚本中组合使用各种工作空间信息获取方法:

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. 始终检查空引用

在访问地图或其方法前,检查地图实例是否存在:

current_map = SSProcess.getCurrentMap()
if current_map is None:
    print("当前没有打开的地图,无法执行操作")
    return

Sources: ssprocess_mixins/project_mixin.py

2. 合理使用系统路径

优先使用系统路径而不是硬编码路径,这样可以确保脚本在不同环境下的兼容性:

# 好的做法
script_path = SSProcess.getSysPathName(3)
script_file = script_path + "my_script.py"

# 不好的做法(硬编码)
script_file = "C:\\SunvStation\\scripts\\my_script.py"

3. 及时释放资源

对于图幅等需要显式释放的资源,使用 try-finally 确保资源被正确释放:

try:
    SSProcess.createMapFrame()
    # 处理图幅...
finally:
    SSProcess.freeMapFrame()

Sources: ssprocess_mixins/project_mixin.py

4. 批量操作前检查图层状态

在进行批量操作前,检查目标图层是否存在且可编辑:

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. 使用日志记录关键信息

在获取关键工作空间信息时,使用日志记录以便调试和追踪:

# 配置日志记录器
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

错误处理与调试

在获取工作空间信息时可能会遇到各种错误情况,以下是一些常见的错误处理模式:

常见错误类型

错误类型 可能原因 处理方法
返回 None 当前没有打开地图 检查 getCurrentMap() 返回值
返回空字符串 路径不存在或项目未保存 检查返回值是否为空
索引越界 图层索引超出范围 使用 getLayerCount() 验证
图幅创建失败 地图中无地物对象 检查 createMapFrame() 返回值

错误处理示例

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

下一步学习

掌握了获取工作空间信息的方法后,您可以继续学习以下相关主题:

通过系统学习这些内容,您将能够构建功能完善的 SunvStation 二次开发脚本,充分发挥系统的强大功能。