Files
sunvpy-docs/docs/content/19-chuang-jian-mo-ren-di-wu-dui-xiang.md
2026-04-10 13:47:53 +08:00

384 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 系统中创建默认地物对象。地物对象是地理信息系统中的核心数据单元,包括点、线、面和注记四种基本类型。创建默认地物对象是进行地理数据编辑和管理的第一步,为后续的属性设置、坐标添加和数据持久化奠定基础。
建议在学习本页面之前,先了解 [SSProcess 基础概念](4-shi-yong-ssprocess-guan-li-xuan-ze-ji) 和 [地物基本属性](17-di-wu-ji-ben-shu-xing-xiang-jie)。完成本页面学习后,可以继续学习 [通过编码创建对象](20-tong-guo-bian-ma-chuang-jian-dui-xiang) 和 [添加对象坐标点](21-tian-jia-dui-xiang-zuo-biao-dian)。
Sources: [ssprocess_mixins/geo_edit_mixin.py](ssprocess_mixins/geo_edit_mixin.py#L1-L60)
## 地物对象类型概述
SunvStation 系统支持四种基本的地物对象类型,每种类型对应不同的几何形态和应用场景。理解这些类型的差异是正确使用创建方法的前提。
| 对象类型 | 类型标识 | 几何类 | 典型应用场景 |
|---------|---------|--------|------------|
| 点对象 | 0 | PointObject | 控制点、界碑、建筑物中心点 |
| 线对象 | 1 | LineObject | 道路、管线、河流中心线 |
| 面对象 | 2 | AreaObject | 建筑物轮廓、湖泊、行政区划 |
| 注记对象 | 3 | MarkNote | 文字标注、地名说明 |
地物对象由两个核心组件构成:`GeoObject` 容器对象和具体的几何对象(`PointObject``LineObject``AreaObject``MarkNote`)。`GeoObject` 负责管理对象的数据集关联和唯一标识,而几何对象负责存储具体的几何数据和图形属性。
Sources: [ssprocess_mixins/geo_edit_mixin.py](ssprocess_mixins/geo_edit_mixin.py#L93-L120)
## createDefaultGeoBase 方法详解
`createDefaultGeoBase` 是创建默认地物对象的核心方法,属于 `GeoEditMixin` 混入类。该方法接受对象类型和数据集两个参数,返回包含 `GeoObject` 和几何对象的元组。
### 方法签名
```python
def createDefaultGeoBase(self, obj_type: int, dataset) -> tuple:
```
### 参数说明
| 参数名 | 类型 | 必需 | 说明 |
|--------|------|------|------|
| obj_type | int | 是 | 地物对象类型0-点1-线2-面3-注记) |
| dataset | Dataset | 是 | 目标数据集实例,用于存储对象 |
### 返回值
返回一个包含两个元素的元组:
- 第一个元素:`GeoObject` 实例,作为地物对象的容器
- 第二个元素:具体的几何对象实例(`PointObject`/`LineObject`/`AreaObject`/`MarkNote`
Sources: [ssprocess_mixins/geo_edit_mixin.py](ssprocess_mixins/geo_edit_mixin.py#L93-L120)
## 创建地物对象的工作流程
创建默认地物对象涉及多个步骤,从获取数据集到最终保存到数据库。理解完整的流程有助于正确地组织代码和处理异常情况。
```mermaid
flowchart TD
A[开始] --> B[获取当前数据源EPS]
B --> C{EPS是否有效?}
C -->|否| D[记录错误并返回]
C -->|是| E[获取目标数据集]
E --> F{数据集是否有效?}
F -->|否| G[记录错误并返回]
F -->|是| H[调用createDefaultGeoBase]
H --> I[创建GeoObject容器]
I --> J{对象类型?}
J -->|0| K[创建PointObject]
J -->|1| L[创建LineObject]
J -->|2| M[创建AreaObject]
J -->|3| N[创建MarkNote]
K --> O[设置几何对象]
L --> O
M --> O
N --> O
O --> P[返回对象元组]
P --> Q[设置对象属性]
Q --> R[添加坐标点]
R --> S[添加到保存列表]
S --> T[保存到数据库]
T --> U[结束]
```
Sources: [ssprocess_mixins/geo_edit_mixin.py](ssprocess_mixins/geo_edit_mixin.py#L140-L250)
## 基础创建示例
以下示例展示了如何使用 `createDefaultGeoBase` 方法创建不同类型的默认地物对象。
### 创建点对象
```python
# 获取当前地图的数据源
ds_eps = SSProcess.map.getCurrentDataSourceEPS()
if ds_eps is None:
print("无法获取数据源")
exit()
# 获取点图层对应的数据集假设代码为100
fea = ds_eps.getFeature(100)
dataset = getDatasetByFeaCode(ds_eps, fea)
# 创建默认点对象
obj, geo = SSProcess.createDefaultGeoBase(0, dataset)
if obj is not None and geo is not None:
print(f"成功创建点对象ID: {geo.getId()}")
print(f"对象类型: {geo.getObjectType()}") # 输出: 0
```
### 创建线对象
```python
# 创建默认线对象
obj, geo = SSProcess.createDefaultGeoBase(1, dataset)
if geo is not None and geo.getObjectType() == 1:
print("成功创建线对象")
# 设置线对象的基本属性
geo.setLineColor(0xFF0000) # 红色
geo.setLineWidth(2)
geo.setLineType(1) # 实线
```
### 创建面对象
```python
# 创建默认面对象
obj, geo = SSProcess.createDefaultGeoBase(2, dataset)
if geo is not None and geo.getObjectType() == 2:
print("成功创建面对象")
# 设置面对象的基本属性
geo.setColor(0x00FF00) # 绿色
geo.setLineWidth(1)
geo.setFillColor(0x00FF00) # 填充色
```
### 创建注记对象
```python
# 创建默认注记对象
obj, geo = SSProcess.createDefaultGeoBase(3, dataset)
if geo is not None and geo.getObjectType() == 3:
print("成功创建注记对象")
note = castToMarkNote(geo)
if note is not None:
note.setNote("示例注记")
note.setFontHeight(100) # 字体高度
note.setAlignment(1) # 居中对齐
```
Sources: [ssprocess_mixins/geo_edit_mixin.py](ssprocess_mixins/geo_edit_mixin.py#L93-L120)
## 完整创建流程示例
以下示例展示了从对象创建到保存到数据库的完整流程,包括属性设置、坐标点添加和数据持久化。
### 创建并保存点对象
```python
# 1. 创建点对象
ds_eps = SSProcess.map.getCurrentDataSourceEPS()
fea = ds_eps.getFeature(100) # 获取点地物编码
dataset = getDatasetByFeaCode(ds_eps, fea)
obj, geo = SSProcess.createDefaultGeoBase(0, dataset)
# 2. 设置点对象属性
geo.setCode(100)
geo.setColor(0xFF0000)
geo.setObjName("控制点A")
# 3. 添加坐标点(点对象至少需要一个点)
SSProcess.addNewObjPoint(100.0, 200.0, 0.0, 0, "PT1")
# 4. 添加到保存列表
SSProcess.addNewObjToSaveObjList()
# 5. 保存到数据库
SSProcess.saveBufferObjToDatabase()
print("点对象已成功保存到数据库")
```
### 创建并保存线对象
```python
# 1. 创建线对象
ds_eps = SSProcess.map.getCurrentDataSourceEPS()
fea = ds_eps.getFeature(200) # 获取线地物编码
dataset = getDatasetByFeaCode(ds_eps, fea)
obj, geo = SSProcess.createDefaultGeoBase(1, dataset)
# 2. 设置线对象属性
geo.setCode(200)
geo.setColor(0x0000FF)
geo.setLineWidth(3)
geo.setLineType(1)
# 3. 添加多个坐标点构成线段
SSProcess.addNewObjPoint(100.0, 100.0, 0.0, 0, "起点")
SSProcess.addNewObjPoint(200.0, 150.0, 0.0, 0, "中间点1")
SSProcess.addNewObjPoint(300.0, 200.0, 0.0, 0, "终点")
# 4. 添加到保存列表并保存
SSProcess.addNewObjToSaveObjList()
SSProcess.saveBufferObjToDatabase()
print("线对象已成功保存到数据库")
```
Sources: [ssprocess_mixins/geo_edit_mixin.py](ssprocess_mixins/geo_edit_mixin.py#L450-L520)
## 错误处理与验证
在创建地物对象时,需要进行适当的错误处理以确保程序的健壮性。
### 常见错误及处理方式
| 错误场景 | 错误表现 | 处理方式 |
|---------|---------|---------|
| 数据源为空 | `ds_eps is None` | 检查数据源是否正确加载 |
| 数据集无效 | `dataset is None` | 验证地物编码是否存在 |
| 对象类型错误 | `geo is None` | 确保类型参数在 0-3 范围内 |
| 属性设置失败 | 返回值 `False` | 检查属性值格式是否正确 |
### 错误处理示例
```python
def createPointSafely(code: int, x: float, y: float, z: float):
"""安全创建点对象,包含完整错误处理"""
try:
# 1. 验证数据源
ds_eps = SSProcess.map.getCurrentDataSourceEPS()
if ds_eps is None:
SSProcess.log_error_msg("无法获取当前数据源")
return False
# 2. 验证地物编码
fea = ds_eps.getFeature(code)
if fea is None:
SSProcess.log_error_msg(f"地物编码 {code} 不存在")
return False
# 3. 获取数据集
dataset = getDatasetByFeaCode(ds_eps, fea)
if dataset is None:
SSProcess.log_error_msg(f"无法获取编码 {code} 对应的数据集")
return False
# 4. 创建对象
obj, geo = SSProcess.createDefaultGeoBase(fea.nObjectType, dataset)
if obj is None or geo is None:
SSProcess.log_error_msg("创建地物对象失败")
return False
# 5. 设置属性和坐标
geo.setCode(code)
geo.setColor(fea.uLineColor)
if not SSProcess.addNewObjPoint(x, y, z, 0, "PT"):
SSProcess.log_error_msg("添加坐标点失败")
return False
# 6. 保存对象
SSProcess.addNewObjToSaveObjList()
SSProcess.saveBufferObjToDatabase()
return True
except Exception as e:
SSProcess.log_error_msg(f"创建点对象时发生异常: {str(e)}")
return False
```
Sources: [ssprocess_mixins/geo_edit_mixin.py](ssprocess_mixins/geo_edit_mixin.py#L140-L250)
## 与其他创建方法的对比
`createDefaultGeoBase` 是创建地物对象的基础方法,系统还提供了其他便捷方法用于特定场景。
| 方法 | 适用场景 | 特点 | 相比createDefaultGeoBase的优势 |
|------|---------|------|---------------------------|
| createDefaultGeoBase | 需要精确控制类型和属性 | 最底层,最灵活 | 无,是其他方法的基础 |
| createNewObjByCode | 已知地物编码 | 自动从编码获取属性和类型 | 自动设置编码、颜色、线型等 |
| createNewObjByClass | 创建注记对象 | 基于注记类模板创建 | 自动加载注记模板属性 |
### 使用场景对比示例
```python
# 方式1使用 createDefaultGeoBase需要手动设置所有属性
obj, geo = SSProcess.createDefaultGeoBase(0, dataset)
geo.setCode(100)
geo.setColor(0xFF0000)
geo.setLineWidth(2)
# 方式2使用 createNewObjByCode自动从编码获取属性
obj, geo = SSProcess.createNewObjByCode(100) # 自动设置颜色、线型等
# 内部调用 createDefaultGeoBase但额外设置了从编码获取的属性
# 方式3使用 createNewObjByClass专用于注记
obj, geo = SSProcess.createNewObjByClass("注记类A") # 自动加载注记模板
# 内部调用 createDefaultGeoBase(3, dataset),并应用模板属性
```
Sources: [ssprocess_mixins/geo_edit_mixin.py](ssprocess_mixins/geo_edit_mixin.py#L200-L280)
## 属性设置与扩展
创建地物对象后,需要设置各种属性以满足业务需求。属性分为基本属性和扩展属性两类。
### 基本属性设置
基本属性是系统预定义的标准属性,直接通过几何对象的 setter 方法设置。
```python
# 设置基本属性示例
geo.setCode(100) # 设置地物编码
geo.setColor(0xFF0000) # 设置颜色(红色)
geo.setLineWidth(2) # 设置线宽
geo.setLineType(1) # 设置线型(实线)
geo.setFillColor(0x00FF00) # 设置填充色
geo.setObjName("示例对象") # 设置对象名称
geo.setGroupId(1) # 设置分组ID
geo.setObjStatus(1) # 设置对象状态
```
### 扩展属性设置
扩展属性是自定义的属性字段,存储在对象的备忘数据中。
```python
# 设置单个扩展属性
SSProcess.setNewObjValue("[自定义属性A]", "属性值")
# 设置多个扩展属性(逗号分隔)
SSProcess.setNewObjValue("[属性1],[属性2],[属性3]", "值1,值2,值3")
# 基本属性使用 SSObj_ 前缀
SSProcess.setNewObjValue("SSObj_Code", "100")
SSProcess.setNewObjValue("SSObj_Color", "0xFF0000")
```
Sources: [ssprocess_mixins/geo_edit_mixin.py](ssprocess_mixins/geo_edit_mixin.py#L280-L380)
## 批量创建与性能优化
当需要创建大量地物对象时,合理的批量处理策略可以显著提高性能。
### 批量创建流程
```python
def批量创建点对象(点坐标列表: list, 代码: int):
"""批量创建点对象并一次性保存"""
ds_eps = SSProcess.map.getCurrentDataSourceEPS()
fea = ds_eps.getFeature(代码)
dataset = getDatasetByFeaCode(ds_eps, fea)
for i, (x, y, z) in enumerate(点坐标列表):
# 1. 创建对象
obj, geo = SSProcess.createDefaultGeoBase(0, dataset)
# 2. 设置属性
geo.setCode(代码)
geo.setColor(fea.uLineColor)
geo.setObjName(f"{i+1}")
# 3. 添加坐标
SSProcess.addNewObjPoint(x, y, z, 0, f"PT{i+1}")
# 4. 添加到保存列表(不立即保存)
SSProcess.addNewObjToSaveObjList()
# 5. 批量保存到数据库(一次性提交)
SSProcess.saveBufferObjToDatabase()
print(f"成功保存 {len(点坐标列表)} 个点对象")
```
### 性能优化建议
| 优化措施 | 说明 | 预期效果 |
|---------|------|---------|
| 批量保存 | 累积对象后一次性保存 | 减少数据库事务次数 |
| 延迟属性设置 | 在创建后统一设置属性 | 避免重复的对象遍历 |
| 使用缓存 | 利用对象缓存机制 | 减少内存分配开销 |
| 进度显示 | 对大批量操作显示进度 | 提升用户体验 |
Sources: [ssprocess_mixins/geo_edit_mixin.py](ssprocess_mixins/geo_edit_mixin.py#L520-L580)
## 下一步学习
完成默认地物对象的创建后,建议继续学习以下内容:
1. **[通过编码创建对象](20-tong-guo-bian-ma-chuang-jian-dui-xiang)**:学习如何根据地物编码自动创建对象并应用编码预设的属性
2. **[添加对象坐标点](21-tian-jia-dui-xiang-zuo-biao-dian)**:深入了解如何为不同类型的对象添加坐标点
3. **[对象缓存机制](23-dui-xiang-huan-cun-ji-zhi)**:理解系统如何通过缓存机制提升创建和保存效率
4. **[批量保存到数据库](24-pi-liang-bao-cun-dao-shu-ju-ku)**:掌握高效的数据持久化策略