17 KiB
本页面将引导您编写第一个 SunvStation Python 脚本,从最基础的地物属性查询开始。通过实际案例,您将学习如何使用选择集过滤地物对象,并读取它们的属性信息。这是所有数据处理和编辑操作的基础起点。
脚本功能概览
我们的第一个脚本将实现以下完整流程:在当前地图中按照编码条件筛选地物对象,然后遍历选择集中的每个对象,读取并显示其核心属性信息。这个示例涵盖了脚本开发的四个核心环节——准备工作、筛选对象、遍历结果、输出信息。
Sources: PySSProcess.py
完整工作流程
让我们先通过一个流程图理解整个脚本的数据流转过程,这有助于把握各步骤之间的逻辑关系:
flowchart LR
A[初始化 SSProcess<br>获取工作空间与地图] --> B[清除旧选择集<br>clearSelection]
B --> C[清除旧选择条件<br>clearSelectCondition]
C --> D[设置筛选条件<br>setSelectCondition]
D --> E[执行过滤查询<br>selectFilter]
E --> F{选择集非空?}
F -->|是| G[获取对象数量<br>getSelGeoCount]
F -->|否| H[脚本结束]
G --> I[循环遍历对象]
I --> J[获取对象属性<br>getSelGeoValue]
J --> K[输出属性信息]
K --> L{还有对象?}
L -->|是| I
L -->|否| H
这个流程图展示了脚本的核心执行路径,其中每个节点对应一个关键的 API 调用。接下来的详细教程将逐步解析每个节点的具体实现。
Sources: PySSProcess.py
步骤一:准备环境与初始化
在编写任何脚本之前,首先需要导入 sunvpy 模块中的核心类 SSProcess。这是一个全局单例对象,封装了工作空间、地图、选择集以及所有地物操作的核心功能。初始化完成后,SSProcess 会自动获取当前 SunvStation 系统的工作空间和活动地图实例,为后续操作做好准备。
from sunvpy import SSProcess
这个简单的导入语句就完成了所有必要的准备工作。SSProcess 内部维护了 WorkSpace(工作空间)和 ScaleMap(比例尺地图)两个核心对象,以及 GeoBaseList(地物列表)、SSearchHelper(搜索助手)等辅助对象,共同构成了脚本运行的基础环境。
Sources: PySSProcess.py
步骤二:清理选择集与条件
在开始新的查询之前,良好的习惯是清理之前可能残留的选择集和选择条件。这确保了脚本的执行结果不受上一次操作的影响,提高了脚本的可重复性和可靠性。
SSProcess.clearSelection() # 清除脚本选择集中的所有对象
SSProcess.clearSelectCondition() # 清除之前设置的选择条件
clearSelection() 会清空 selGeoList(点线面地物列表)和 selNoteList(注记对象列表),而 clearSelectCondition() 则会清空 searchHelper 中存储的过滤条件。这两个方法都是无参数的简单调用,为后续操作提供一个干净的开始状态。
Sources: ssprocess_mixins/selection_mixin.py
步骤三:设置选择条件
选择条件定义了我们要筛选地物的规则。SunvStation 支持三种类型的属性:基本属性、几何特性和扩展属性,它们通过不同的前缀标识符来区分。
条件类型说明
| 属性类型 | 前缀标识 | 示例 | 说明 |
|---|---|---|---|
| 基本属性 | SSObj_ |
SSObj_Code |
以 SSObj_ 开头的系统内置属性 |
| 几何特性 | < > |
<Overlap> |
用尖括号括住的几何判断条件 |
| 扩展属性 | [ ] |
[JG] |
用方括号括住的自定义扩展属性 |
操作符支持
系统提供了丰富的比较操作符,满足各种查询需求:
| 操作符 | 含义 | 示例 |
|---|---|---|
== |
等于 | SSObj_Code == "3103013" |
> |
大于 | SSObj_Length > "100" |
< |
小于 | SSObj_Area < "500" |
<> |
不等于 | SSObj_Type <> "NOTE" |
LIKE |
模糊匹配 | SSObj_Name LIKE "%道路%" |
NOT LIKE |
不匹配 | SSObj_Name NOT LIKE "%临时%" |
CompareNoCase |
忽略大小写比较 | SSObj_Name CompareNoCase "MAIN" |
Dec |
小数位比较 | SSObj_Area Dec 2 |
设置选择条件代码
在我们的第一个脚本中,我们将按照地物编码进行筛选:
SSProcess.setSelectCondition("SSObj_Code", "==", "3103013")
这行代码会调用 searchHelper.addCondition() 方法,将条件添加到过滤条件列表中。地物编码 3103013 是一个具体的编码值,表示我们要筛选出编码为 3103013 的所有地物对象。
Sources: ssprocess_mixins/selection_mixin.py
步骤四:执行过滤查询
设置好选择条件后,需要调用 selectFilter() 方法来实际执行查询。这个方法会在当前数据源中查找符合所有设置条件的对象,并将它们添加到脚本选择集中。
SSProcess.selectFilter()
selectFilter() 方法执行以下操作流程:
- 调用
searchHelper.getFilterObj()获取初步过滤的对象列表 - 调用
searchHelper.filterObj()进行精确过滤 - 将过滤结果根据对象类型分别添加到
selGeoList或selNoteList - 在整个过程中显示进度条,提升用户体验
执行完成后,所有符合条件的对象都存储在 SSProcess 的内部选择集列表中,可以通过索引访问它们。
Sources: ssprocess_mixins/selection_mixin.py
步骤五:获取选择集对象数量
在遍历选择集之前,通常需要先了解查询到了多少对象,这有助于后续的逻辑判断和循环控制。
geo_count = SSProcess.getSelGeoCount()
print(f"选择集中的点线面对象数量: {geo_count}")
getSelGeoCount() 方法返回 selGeoList 的长度,即当前选择集中的点、线、面对象总数。如果还有注记对象,可以使用 getSelNoteCount() 方法获取注记对象的数量。了解对象数量可以帮助我们判断查询结果是否符合预期,或者避免在空选择集上执行不必要的操作。
Sources: ssprocess_mixins/selection_mixin.py
步骤六:遍历选择集并读取属性
现在我们进入了脚本的核心部分——遍历选择集中的每个对象,并读取它们的属性值。这需要使用 getSelGeoValue() 方法,它接受两个参数:对象在选择集中的索引和属性名称。
常用地物属性速查表
| 属性名称 | 属性说明 | 数据类型 | 示例值 |
|---|---|---|---|
SSObj_ID |
对象唯一标识 | 整数 | 1001 |
SSObj_Code |
地物编码 | 整数 | 3103013 |
SSObj_LayerName |
所在图层名 | 字符串 | "Default_A" |
SSObj_Type |
对象类型 | 字符串 | "POINT", "LINE", "AREA", "NOTE" |
SSObj_Color |
颜色值 | 整数 | 16777215 (白色) |
SSObj_LineType |
线型 | 整数 | 1 |
SSObj_LineWidth |
线宽 | 整数 | 2 |
SSObj_Name |
对象名称 | 字符串 | "道路1" |
SSObj_Byname |
对象别名 | 字符串 | "主路" |
SSObj_Area |
面积 | 浮点数 | 1234.56 |
SSObj_Length |
长度 | 浮点数 | 567.89 |
SSObj_PointCount |
坐标点数量 | 整数 | 5 |
SSObj_X |
X坐标 | 浮点数 | 12345.67 |
SSObj_Y |
Y坐标 | 浮点数 | 54321.09 |
遍历代码示例
以下代码展示了如何遍历选择集的前10个对象,并读取它们的多个属性:
# 定义要读取的属性列表
fields = [
"SSObj_ID", "SSObj_Code", "SSObj_LayerName", "SSObj_Type", "SSObj_Color",
"SSObj_LineType", "SSObj_LineWidth", "SSObj_Name", "SSObj_Byname",
"SSObj_Area", "SSObj_Length", "SSObj_X", "SSObj_Y"
]
# 遍历选择集(最多显示前10个对象)
for i in range(min(10, geo_count)):
print(f"第 {i} 个对象属性:")
for field in fields:
value = SSProcess.getSelGeoValue(i, field)
print(f" {field}: {value}")
print("-" * 40)
getSelGeoValue() 方法内部会根据属性名的前缀判断属性类型:
- 如果属性名以
[开头,则调用map.getExtentAttr()获取扩展属性 - 否则,调用
objBaseAttr.getGeoValue()获取基本属性
这种设计使得属性读取接口对用户保持统一,而内部实现则根据属性类型自动适配。
Sources: ssprocess_mixins/selection_mixin.py
完整示例脚本
将上述所有步骤组合起来,我们就得到了一个完整可运行的第一个脚本:
from sunvpy import SSProcess
# 1. 清理选择集和条件
SSProcess.clearSelection()
SSProcess.clearSelectCondition()
# 2. 设置筛选条件:按编码筛选
SSProcess.setSelectCondition("SSObj_Code", "==", "3103013")
# 3. 执行过滤查询
SSProcess.selectFilter()
# 4. 获取选择集对象数量
geo_count = SSProcess.getSelGeoCount()
print(f"选择集中的点线面对象数量: {geo_count}")
# 5. 定义要读取的属性列表
fields = [
"SSObj_ID", "SSObj_Code", "SSObj_LayerName", "SSObj_Type", "SSObj_Color",
"SSObj_LineType", "SSObj_LineWidth", "SSObj_Name", "SSObj_Byname",
"SSObj_Area", "SSObj_Length", "SSObj_PointCount", "SSObj_X", "SSObj_Y"
]
# 6. 遍历选择集并读取属性
for i in range(min(10, geo_count)):
print(f"第 {i} 个对象属性:")
for field in fields:
value = SSProcess.getSelGeoValue(i, field)
print(f" {field}: {value}")
print("-" * 40)
运行这个脚本后,您将在控制台看到每个选中对象的详细属性信息,格式化输出为清晰的键值对形式,便于查看和调试。
Sources: PySSProcess.py
脚本执行结果示例
假设我们的地图中有3个编码为3103013的地物对象,脚本执行后的输出可能如下:
选择集中的点线面对象数量: 3
第 0 个对象属性:
SSObj_ID: 1001
SSObj_Code: 3103013
SSObj_LayerName: Default_A
SSObj_Type: LINE
SSObj_Color: 16777215
SSObj_LineType: 1
SSObj_LineWidth: 1
SSObj_Name: 道路1
SSObj_Byname: 主路
SSObj_Area: 0.0
SSObj_Length: 567.89
SSObj_PointCount: 5
SSObj_X: 12345.67
SSObj_Y: 54321.09
----------------------------------------
第 1 个对象属性:
SSObj_ID: 1002
SSObj_Code: 3103013
SSObj_LayerName: Default_A
SSObj_Type: LINE
SSObj_Color: 16777215
SSObj_LineType: 1
SSObj_LineWidth: 1
SSObj_Name: 道路2
SSObj_Byname: 支路
SSObj_Area: 0.0
SSObj_Length: 234.56
SSObj_PointCount: 3
SSObj_X: 13000.00
SSObj_Y: 55000.00
----------------------------------------
第 2 个对象属性:
SSObj_ID: 1003
SSObj_Code: 3103013
SSObj_LayerName: Default_A
SSObj_Type: AREA
SSObj_Color: 16711680
SSObj_LineType: 2
SSObj_LineWidth: 2
SSObj_Name: 区域1
SSObj_Byname: 核心区
SSObj_Area: 1234.56
SSObj_Length: 150.00
SSObj_PointCount: 6
SSObj_X: 12500.00
SSObj_Y: 54500.00
----------------------------------------
从输出结果可以看出,我们成功查询到了3个符合条件的对象,包括2个线型对象和1个面对象,每个对象的属性都清晰地显示出来。
常见问题与解决方案
问题1:选择集为空
现象:运行脚本后显示"选择集中的点线面对象数量: 0"
可能原因:
- 指定的编码在当前地图中不存在
- 当前数据源中没有符合条件的对象
- 选择条件设置不正确
解决方案:尝试使用更宽泛的条件,例如按图层筛选:
SSProcess.setSelectCondition("SSObj_LayerName", "==", "Default_A")
或者不设置任何条件,查询所有对象:
# 不调用 setSelectCondition,直接执行 selectFilter
SSProcess.selectFilter()
问题2:属性值为空
现象:某些属性显示为空字符串
可能原因:
- 该属性对于当前对象类型不适用(例如,点对象的
SSObj_Area总是为 0) - 扩展属性
[ ]在当前对象上不存在
解决方案:根据对象类型选择合适的属性。例如,对于线对象,查询 SSObj_Length;对于面对象,查询 SSObj_Area。
问题3:扩展属性无法读取
现象:使用 [扩展属性名] 格式读取时返回空值
可能原因:
- 扩展属性名称拼写错误
- 当前对象没有该扩展属性
解决方案:先查询对象的扩展属性列表:
# 获取对象的扩展属性字段名
SSProcess.curSelGeoFields.clear()
SSProcess.curSelGeoValues.clear()
SSProcess.map.getExtentAttr(geo, SSProcess.curSelGeoFields, SSProcess.curSelGeoValues)
# 打印所有扩展属性
for i in range(SSProcess.curSelGeoFields.size()):
print(f"{SSProcess.curSelGeoFields[i]}: {SSProcess.curSelGeoValues[i]}")
Sources: ssprocess_mixins/selection_mixin.py
架构原理补充说明
SSProcess 的内部结构
SSProcessManager 类采用了Mixin 设计模式,将不同功能模块分离到独立的 Mixin 类中,然后通过多重继承组合成一个功能完整的管理器:
classDiagram
class SSProcessManager {
-workspace: WorkSpace
-map: ScaleMap
-selGeoList: GeoBaseList
-selNoteList: GeoBaseList
-searchHelper: SSearchHelper
+clearSelection()
+clearSelectCondition()
+setSelectCondition()
+selectFilter()
+getSelGeoCount()
+getSelGeoValue()
}
class SelectionMixin {
+clearSelection()
+clearSelectCondition()
+setSelectCondition()
+selectFilter()
+getSelGeoCount()
+getSelGeoValue()
}
class GeoEditMixin {
+createGeo()
+deleteGeo()
+updateGeo()
}
class ProjectMixin {
+getWorkspace()
+getMap()
}
class LogMixin {
+log()
+logger
}
class ProgressMixin {
+startProgress()
+stepProgress()
+closeProgress()
}
SSProcessManager --|> SelectionMixin
SSProcessManager --|> GeoEditMixin
SSProcessManager --|> ProjectMixin
SSProcessManager --|> LogMixin
SSProcessManager --|> ProgressMixin
这种架构设计的优势在于:
- 关注点分离:每个 Mixin 只负责一个特定的功能领域
- 代码复用:不同功能的代码可以独立维护和测试
- 扩展性强:新增功能只需添加新的 Mixin 类
- 清晰的职责边界:便于理解和使用
Sources: PySSProcess.py
属性读取机制
SunvStation 支持三种属性类型,它们在底层有不同的存储和访问机制:
flowchart LR
A[getSelGeoValue 调用] --> B{属性名前缀判断}
B -->|基本属性| C[调用 objBaseAttr.getGeoValue]
B -->|几何特性| D[调用 searchHelper 几何判断]
B -->|扩展属性| E[调用 map.getExtentAttr]
C --> F[返回基本属性值]
D --> G[返回几何特性结果]
E --> H[返回扩展属性值]
F --> I[统一返回字符串]
G --> I
H --> I
基本属性存储在 C++ 对象的内部结构中,通过 ObjBaseAttr 类的索引机制快速访问;扩展属性存储在数据库或附加结构中,通过地图接口动态获取;几何特性则是实时计算的判断结果。
Sources: ObjBaseAttr.py
下一步学习建议
掌握了第一个脚本的基本流程后,您可以根据自己的学习需求选择接下来的学习路径:
继续深入选择集与查询
如果您想了解更多选择集操作和高级查询技巧,建议阅读:
- 使用 SSProcess 管理选择集 - 学习更复杂的选择集管理方法
- 设置选择条件 - 深入了解多条件组合查询
- 遍历选择集对象 - 掌握高效的遍历技巧
学习地物属性操作
如果您想学习如何修改地物属性,建议阅读:
探索高级功能
如果您已经掌握了基础知识,可以尝试更高级的功能:
- 运行内置示例脚本 - 查看更多实际应用案例
- SunvStation 系统架构 - 理解系统的整体设计原理
无论选择哪条路径,都建议您在实际项目中多练习,通过编写不同的脚本加深对 SunvStation Python API 的理解。每个页面都提供了详细的示例代码和源文件引用,可以作为您学习的参考手册。