Files
sunvpy-docs/docs/content/16-xiu-gai-di-wu-shu-xing-zhi.md
2026-04-10 13:47:53 +08:00

427 lines
14 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
修改地物属性值是 SunvStation Python API 中最核心的数据操作功能之一。本页将系统性地介绍如何通过脚本修改地物的基本属性、扩展属性以及几何属性,并确保修改内容正确保存到数据库。
## 属性修改架构概览
地物属性修改涉及三个核心层次:**新建对象属性设置**、**选择集对象属性修改**和**批量保存机制**。理解这个架构对于正确使用 API 至关重要。
```mermaid
flowchart TB
A[开始属性修改] --> B{修改场景}
B --> C[新建对象]
B --> D[选择集对象]
B --> E[批量修改]
C --> C1[createDefaultGeoBase<br/>创建对象]
C1 --> C2[setNewObjValue<br/>设置属性]
C2 --> C3[addNewObjToSaveObjList<br/>添加到保存列表]
D --> D1[遍历选择集对象]
D1 --> D2{属性类型}
D2 --> D3[SSObj_Code/LayerName<br/>特殊处理]
D2 --> D4[基本属性<br/>setGeoValue]
D2 --> D5[扩展属性<br/>setMemoData]
D3 --> D6[addSelGeoToSaveGeoList<br/>添加到保存列表]
D4 --> D6
D5 --> D6
E --> E1[setSelGeoValue -1<br/>批量设置]
E1 --> E2[addSelGeoToSaveGeoList -1<br/>批量添加]
C3 --> F[saveBufferObjToDatabase<br/>保存到数据库]
D6 --> F
E2 --> F
F --> G[updateRequest<br/>刷新地图显示]
G --> H[完成]
```
## 属性类型与命名规范
SunvStation 支持三种不同类型的属性,每种类型使用特定的命名前缀和语法规则。
| 属性类型 | 命名格式 | 示例 | 说明 |
|---------|---------|------|------|
| **基本属性** | `SSObj_` 开头 | `SSObj_Code`, `SSObj_Name`, `SSObj_Color` | 系统预定义的固有属性 |
| **扩展属性** | `[属性名]` 格式 | `[建筑类型]`, `[施工状态]` | 用户自定义的扩展字段 |
| **几何属性** | `<属性名>` 格式 | `<Area>`, `<Length>`, `<X(0)>` | 对象的几何特性和坐标信息 |
### 基本属性分类
**通用属性**:涵盖对象的标识、图层和图形表现。这包括对象 ID、编码、图层名称、颜色、线型和线宽等关键属性。
**几何属性**涉及对象的坐标、几何尺寸和拓扑特征。包括坐标点X, Y, Z、面积、长度、边界框等几何信息。
**注记属性**:专门针对文本标注的样式和格式。包括字体宽度、高度、名称、内容、对齐方式和角度等详细属性。
**时间与状态**:记录对象的创建和修改时间,以及对象的状态标记。
Sources: [ObjBaseAttr.py](ObjBaseAttr.py#L9-L79)
## 修改新建对象的属性
当通过 `createDefaultGeoBase()``createNewObjByCode()` 创建新地物对象后,可以使用 `setNewObjValue()` 方法设置其属性。这种方法适用于单次创建并立即设置属性的场景。
### 基本属性设置
```python
# 创建编码为 100 的线对象
obj, geo = ssp.createNewObjByCode(100)
# 设置基本属性
ssp.setNewObjValue("SSObj_Name", "主干道")
ssp.setNewObjValue("SSObj_Color", "16711680") # RGB 红色
ssp.setNewObjValue("SSObj_LineWidth", "2")
ssp.setNewObjValue("SSObj_Angle", "45.0")
```
### 扩展属性设置
扩展属性使用方括号 `[]` 包裹属性名,可以同时设置多个属性:
```python
# 设置单个扩展属性
ssp.setNewObjValue("[建筑类型]", "住宅楼")
ssp.setNewObjValue("[建成年份]", "2020")
# 同时设置多个扩展属性(用逗号分隔)
ssp.setNewObjValue("[建筑类型],[建成年份],[楼层数]", "商业楼,2021,18")
```
### 注记属性设置
对于注记对象,支持专门的字体属性:
```python
# 创建注记对象
obj, note = ssp.createNewObjByClass("1") # 分类号为1的注记
# 设置注记属性
ssp.setNewObjValue("SSObj_FontString", "示例文字")
ssp.setNewObjValue("SSObj_FontHeight", "300")
ssp.setNewObjValue("SSObj_FontWidth", "200")
ssp.setNewObjValue("SSObj_FontName", "SimSun")
ssp.setNewObjValue("SSObj_FontAlignment", "1") # 对齐方式
```
完成属性设置后,需要将新对象添加到保存列表并持久化:
```python
ssp.addNewObjToSaveObjList()
ssp.saveBufferObjToDatabase()
ssp.updateRequest()
```
Sources: [ssprocess_mixins/geo_edit_mixin.py](ssprocess_mixins/geo_edit_mixin.py#L106-L266)
## 修改选择集中对象的属性
对于已经存在于地图上的对象,需要先通过选择集过滤获取目标对象,然后使用 `setSelGeoValue()``setSelNoteValue()` 修改属性。
### 选择集对象属性修改流程
```mermaid
flowchart LR
A[设置选择条件] --> B[执行过滤查询]
B --> C[遍历选择集]
C --> D[修改对象属性]
D --> E[添加到保存列表]
E --> F[保存到数据库]
F --> G[刷新显示]
```
### 修改单个对象的属性
通过指定索引值修改选择集中特定对象的属性:
```python
# 清除并设置选择条件
ssp.clearSelection()
ssp.clearSelectCondition()
ssp.setSelectCondition("SSObj_Code", "==", "100")
ssp.selectFilter()
# 修改选择集中第0个对象的属性
ssp.setSelGeoValue(0, "SSObj_Name", "修改后的名称")
ssp.setSelGeoValue(0, "SSObj_Color", "255") # 设置颜色号
ssp.setSelGeoValue(0, "[施工状态]", "已完成")
# 将修改后的对象添加到保存列表
ssp.addSelGeoToSaveGeoList(0)
# 批量保存到数据库
ssp.saveBufferObjToDatabase()
ssp.updateRequest()
```
### 批量修改选择集对象的属性
将索引值设为 `-1` 可以一次性修改选择集中的所有对象:
```python
# 获取所有编码为 100 的对象
ssp.clearSelection()
ssp.setSelectCondition("SSObj_Code", "==", "100")
ssp.selectFilter()
print(f"当前选择集对象数量: {ssp.getSelGeoCount()}")
# 批量修改所有选择集对象的属性
ssp.setSelGeoValue(-1, "SSObj_Color", "255") # 统一颜色
ssp.setSelGeoValue(-1, "SSObj_LineWidth", "3") # 统一线宽
ssp.setSelGeoValue(-1, "[更新时间]", "2024-01-15")
# 批量添加到保存列表
for i in range(ssp.getSelGeoCount()):
ssp.addSelGeoToSaveGeoList(i)
# 保存并刷新
ssp.saveBufferObjToDatabase()
ssp.updateRequest()
```
### 修改注记对象的属性
对于注记对象,使用 `setSelNoteValue()` 方法:
```python
# 清除并设置注记选择条件
ssp.clearSelection()
ssp.setSelectCondition("SSObj_Type", "==", "NOTE")
ssp.setSelectCondition("[注记分类]", "==", "道路注记")
ssp.selectFilter()
# 批量修改注记属性
ssp.setSelNoteValue(-1, "SSObj_FontHeight", "250")
ssp.setSelNoteValue(-1, "SSObj_FontWeight", "700") # 粗体
ssp.setSelNoteValue(-1, "SSObj_FontColor", "16777215") # 白色
# 添加到保存列表
for i in range(ssp.getSelNoteCount()):
ssp.addSelNoteToSaveNoteList(i)
# 保存
ssp.saveBufferObjToDatabase()
ssp.updateRequest()
```
Sources: [ssprocess_mixins/selection_mixin.py](ssprocess_mixins/selection_mixin.py#L310-L411)
## 特殊属性处理
某些属性的修改涉及对象重建或特殊逻辑,需要特别注意。
### 编码属性SSObj_Code修改
修改对象编码会触发对象重新创建,需要通过数据源重新获取特性信息:
```python
# 修改单个对象的编码
ssp.setSelGeoValue(0, "SSObj_Code", "200")
# 注意:此操作会自动处理对象重建
# 无需手动管理新旧对象的替换
```
### 图层属性SSObj_LayerName修改
将对象移动到不同图层涉及完整的对象克隆和数据集切换:
```python
# 将选择集中的对象移动到"建筑"图层
ssp.setSelGeoValue(0, "SSObj_LayerName", "建筑")
# 系统会自动:
# 1. 克隆原始对象
# 2. 保留扩展属性
# 3. 删除旧对象
# 4. 在新图层创建新对象
```
### 点坐标修改SSObj_X, SSObj_Y, SSObj_Z
修改坐标点需要指定点的索引:
```python
# 修改第一个点的坐标
ssp.setSelGeoValue(0, "SSObj_X(0)", "123456.789")
ssp.setSelGeoValue(0, "SSObj_Y(0)", "3456789.123")
ssp.setSelGeoValue(0, "SSObj_Z(0)", "100.5")
# 修改第二个点的坐标
ssp.setSelGeoValue(0, "SSObj_X(1)", "123500.000")
ssp.setSelGeoValue(0, "SSObj_Y(1)", "3456800.000")
```
### 点名称与类型修改SSObj_PointName, SSObj_PointType
```python
# 修改点名称
ssp.setSelGeoValue(0, "SSObj_PointName(0)", "起点")
ssp.setSelGeoValue(0, "SSObj_PointName(1)", "终点")
# 修改点类型(需要指定点索引)
ssp.setSelGeoValue(0, "SSObj_PointType(0)", "1")
```
Sources: [ObjBaseAttr.py](ObjBaseAttr.py#L495-L550)
## 颜色属性设置详解
SunvStation 支持三种颜色表示方式,系统会自动识别并转换:
| 颜色表示方式 | 格式示例 | 说明 |
|------------|---------|------|
| **颜色号方式** | `COLORNO(1)` | 使用系统颜色索引,推荐方式 |
| **RGB方式** | `RGB(255,0,0)` | 直接指定红绿蓝分量 |
| **颜色值方式** | `16711680` | 24位RGB颜色值0x00FF0000 = 红) |
```python
# 三种等价的红色设置方式
ssp.setSelGeoValue(0, "SSObj_Color", "COLORNO(1)") # 颜色号方式
ssp.setSelGeoValue(0, "SSObj_Color", "RGB(255,0,0)") # RGB方式
ssp.setSelGeoValue(0, "SSObj_Color", "16711680") # 颜色值方式(红色)
```
Sources: [ObjBaseAttr.py](ObjBaseAttr.py#L413-L419)
## 完整示例:批量更新道路属性
下面的示例展示了完整的属性修改工作流程:选择所有道路对象,更新其颜色、线宽和扩展属性,然后保存到数据库。
```python
# 1. 清除并初始化选择集
ssp.clearSelection()
ssp.clearSelectCondition()
# 2. 设置选择条件:选择编码为 200 的道路对象
ssp.setSelectCondition("SSObj_Code", "==", "200")
ssp.selectFilter()
geo_count = ssp.getSelGeoCount()
print(f"选中对象数量: {geo_count}")
if geo_count > 0:
# 3. 批量修改基本属性
ssp.setSelGeoValue(-1, "SSObj_Color", "COLORNO(5)") # 统一颜色
ssp.setSelGeoValue(-1, "SSObj_LineWidth", "4") # 统一线宽
ssp.setSelGeoValue(-1, "SSObj_DataMark", "已更新") # 数据标记
# 4. 批量修改扩展属性
ssp.setSelGeoValue(-1, "[路面宽度]", "12.5")
ssp.setSelGeoValue(-1, "[铺装类型]", "沥青混凝土")
ssp.setSelGeoValue(-1, "[维护日期]", "2024-01-10")
# 5. 将所有修改后的对象添加到保存列表
for i in range(geo_count):
ssp.addSelGeoToSaveGeoList(i)
# 6. 保存到数据库并刷新显示
ssp.saveBufferObjToDatabase()
ssp.updateRequest()
print("属性更新完成!")
else:
print("未找到符合条件的对象")
```
Sources: [ssprocess_mixins/selection_mixin.py](ssprocess_mixins/selection_mixin.py#L50-L95)
## 完整示例:创建并设置新对象
```python
# 1. 创建编码为 101 的建筑物对象
obj, geo = ssp.createNewObjByCode(101)
# 2. 设置基本属性
ssp.setNewObjValue("SSObj_Name", "新建建筑A栋")
ssp.setNewObjValue("SSObj_Color", "COLORNO(3)")
ssp.setNewObjValue("SSObj_LayerName", "建筑物")
# 3. 添加坐标点
ssp.addNewObjPoint(123456.789, 3456789.123, 50.0, 0, "")
ssp.addNewObjPoint(123500.000, 3456800.000, 50.0, 0, "")
ssp.addNewObjPoint(123500.000, 3456700.000, 50.0, 0, "")
ssp.addNewObjPoint(123456.789, 3456789.123, 50.0, 0, "")
# 4. 设置扩展属性
ssp.setNewObjValue("[建筑高度]", "45.5")
ssp.setNewObjValue("[建筑面积]", "3200")
ssp.setNewObjValue("[建筑功能]", "办公")
# 5. 添加到保存列表并持久化
ssp.addNewObjToSaveObjList()
ssp.saveBufferObjToDatabase()
ssp.updateRequest()
print("新对象创建完成并已保存!")
```
Sources: [ssprocess_mixins/geo_edit_mixin.py](ssprocess_mixins/geo_edit_mixin.py#L106-L411)
## 注意事项与最佳实践
### 属性修改注意事项
1. **数据类型匹配**:确保属性值的数据类型与属性定义一致,数值属性使用数字字符串,文本属性使用字符串
2. **编码和图层**:修改 `SSObj_Code``SSObj_LayerName` 会触发对象重建,确保目标编码和图层存在
3. **批量操作**:修改大量对象时,使用 `-1` 索引进行批量操作可以提高性能
4. **扩展属性**:使用逗号分隔可以一次设置多个扩展属性,但确保属性数量和值数量匹配
### 保存机制
**重要**:属性修改后必须显式调用保存方法,否则修改仅在内存中生效,不会持久化到数据库:
```python
# 单个对象保存
ssp.addSelGeoToSaveGeoList(index) # index 为具体索引或 -1全部
ssp.saveBufferObjToDatabase()
# 新对象保存
ssp.addNewObjToSaveObjList()
ssp.saveBufferObjToDatabase()
```
### 错误处理
属性修改操作通常会静默失败,建议在关键操作后检查结果:
```python
# 修改属性前检查对象是否存在
if ssp.getSelGeoCount() > 0:
# 执行修改
ssp.setSelGeoValue(0, "SSObj_Color", "255")
ssp.addSelGeoToSaveGeoList(0)
else:
print("选择集为空,无法执行修改")
```
## 进阶操作通过对象ID直接修改属性
对于已知对象 ID 的情况,可以通过 `getObjectAttr()``setSelGeoValue()` 组合使用:
```python
# 通过对象 ID 直接获取属性
obj_id = 12345
attr_value = ssp.getObjectAttr(obj_id, "SSObj_Name")
print(f"当前名称: {attr_value}")
# 先选择该对象,再修改属性
ssp.clearSelection()
ssp.setSelectCondition("SSObj_ID", "==", str(obj_id))
ssp.selectFilter()
if ssp.getSelGeoCount() > 0:
ssp.setSelGeoValue(0, "SSObj_Name", "修改后的名称")
ssp.addSelGeoToSaveGeoList(0)
ssp.saveBufferObjToDatabase()
```
Sources: [ssprocess_mixins/geo_edit_mixin.py](ssprocess_mixins/geo_edit_mixin.py#L570-L600)
## 下一步学习
掌握属性修改后,建议继续学习以下相关主题:
- **[地物基本属性详解](17-di-wu-ji-ben-shu-xing-xiang-jie)** - 深入了解每种基本属性的含义和用途
- **[扩展属性与自定义属性](18-kuo-zhan-shu-xing-yu-zi-ding-yi-shu-xing)** - 学习如何创建和管理扩展属性系统
- **[批量保存到数据库](24-pi-liang-bao-cun-dao-shu-ju-ku)** - 了解批量保存的内部机制和性能优化
- **[撤销标记管理](25-che-xiao-biao-ji-guan-li)** - 学习如何实现属性修改的撤销功能