818 lines
27 KiB
Markdown
818 lines
27 KiB
Markdown
本文档详细说明如何在 SunvStation Python 脚本中读取地物对象的属性值,涵盖基本属性、几何特性和扩展属性三种类型的属性访问方式。通过掌握这些方法,您可以高效地获取和分析地理对象的各类信息,为后续的数据处理、质量检查和统计分析奠定基础。
|
||
|
||
## 属性类型与命名规则
|
||
|
||
SunvStation 系统中,地物属性根据来源和用途分为三类,每类属性使用特定的前缀标识符进行区分。理解这些分类和命名规则是正确读取属性的前提。
|
||
|
||
```mermaid
|
||
flowchart TD
|
||
A[地物属性] --> B[基本属性 SSObj_]
|
||
A --> C[几何特性 #60; #62;]
|
||
A --> D[扩展属性 #91; #93;]
|
||
|
||
B --> B1[对象标识<br/>SSObj_ID, SSObj_Code]
|
||
B --> B2[外观属性<br/>SSObj_Color, SSObj_LineType, SSObj_LineWidth]
|
||
B --> B3[名称属性<br/>SSObj_Name, SSObj_Byname, SSObj_LayerName]
|
||
B --> B4[几何参量<br/>SSObj_Area, SSObj_Length, SSObj_PointCount]
|
||
B --> B5[时间属性<br/>SSObj_CreateTime, SSObj_ModifyTime]
|
||
B --> B6[坐标信息<br/>SSObj_X, SSObj_Y, SSObj_Z, SSObj_PointName]
|
||
B --> B7[注记属性<br/>SSObj_FontString, SSObj_FontHeight, SSObj_FontWidth]
|
||
|
||
C --> C1[拓扑判断<br/>#60;Overlap#62;, #60;Close#62;]
|
||
C --> C2[几何判断<br/>#60;Convex#62;, #60;SelfIntersect#62;]
|
||
|
||
D --> D1[业务属性<br/>#91;JG#93;, #91;CS#93;, #91;建筑结构#93;]
|
||
D --> D2[自定义属性<br/>#91;自定义字段1#93;, #91;自定义字段2#93;]
|
||
```
|
||
|
||
### 基本属性
|
||
|
||
以 `SSObj_` 开头,表示系统内置的地物基本属性,包括对象标识、外观、几何参量、时间戳等。这些属性直接存储在地理对象内部,访问效率最高。
|
||
|
||
| 属性名称 | 属性说明 | 数据类型 | 适用对象类型 |
|
||
|---------|---------|---------|------------|
|
||
| `SSObj_ID` | 对象唯一标识 | 整数 | 所有类型 |
|
||
| `SSObj_Code` | 地物编码 | 整数 | 所有类型 |
|
||
| `SSObj_LayerName` | 所在图层名 | 字符串 | 所有类型 |
|
||
| `SSObj_Type` | 对象类型 | 字符串(POINT/LINE/AREA/NOTE) | 所有类型 |
|
||
| `SSObj_Color` | 颜色值 | 整数 | 所有类型 |
|
||
| `SSObj_LineType` | 线型 | 整数 | LINE/AREA |
|
||
| `SSObj_LineWidth` | 线宽 | 整数 | LINE/AREA |
|
||
| `SSObj_Name` | 对象名称 | 字符串 | 所有类型 |
|
||
| `SSObj_Byname` | 对象别名 | 字符串 | 所有类型 |
|
||
| `SSObj_Angle` | 旋转角度 | 浮点数 | 所有类型 |
|
||
| `SSObj_ScaleX` | X 方向缩放 | 浮点数 | 所有类型 |
|
||
| `SSObj_ScaleY` | Y 方向缩放 | 浮点数 | 所有类型 |
|
||
| `SSObj_Area` | 面积 | 浮点数 | AREA |
|
||
| `SSObj_Length` | 周长/长度 | 浮点数 | LINE/AREA |
|
||
| `SSObj_3DLength` | 三维长度 | 浮点数 | LINE/AREA |
|
||
| `SSObj_PointCount` | 坐标点数量 | 整数 | POINT/LINE/AREA |
|
||
| `SSObj_X` | X 坐标 | 浮点数 | POINT/线对象指定点 |
|
||
| `SSObj_Y` | Y 坐标 | 浮点数 | POINT/线对象指定点 |
|
||
| `SSObj_Z` | Z 坐标 | 浮点数 | POINT/线对象指定点 |
|
||
| `SSObj_PointName` | 点名称 | 字符串 | POINT/线对象指定点 |
|
||
| `SSObj_PointType` | 点类型 | 整数 | POINT/线对象指定点 |
|
||
| `SSObj_CreateTime` | 创建时间 | 字符串(格式:YYYY-MM-DD HH:MM:SS) | 所有类型 |
|
||
| `SSObj_ModifyTime` | 修改时间 | 字符串(格式:YYYY-MM-DD HH:MM:SS) | 所有类型 |
|
||
| `SSObj_DataMark` | 数据标识 | 字符串 | 所有类型 |
|
||
|
||
**注记对象专用属性**:
|
||
|
||
| 属性名称 | 属性说明 | 数据类型 |
|
||
|---------|---------|---------|
|
||
| `SSObj_FontString` | 注记内容 | 字符串 |
|
||
| `SSObj_FontStringCount` | 注记字符数量 | 整数 |
|
||
| `SSObj_FontWidth` | 字宽 | 浮点数 |
|
||
| `SSObj_FontHeight` | 字高 | 浮点数 |
|
||
| `SSObj_FontName` | 字体名称 | 字符串 |
|
||
| `SSObj_FontClass` | 注记分类号 | 整数 |
|
||
| `SSObj_FontAlignment` | 对齐方式 | 整数 |
|
||
| `SSObj_FontPosType` | 位置类型 | 整数 |
|
||
| `SSObj_FontDirection` | 字方向 | 整数 |
|
||
| `SSObj_FontWordAngle` | 字角度 | 浮点数 |
|
||
| `SSObj_FontStringAngle` | 串角度 | 浮点数 |
|
||
| `SSObj_FontWeight` | 字重 | 整数 |
|
||
| `SSObj_FontItalicAngle` | 倾斜角度 | 浮点数 |
|
||
| `SSObj_FontDownAngle` | 下沉角度 | 浮点数 |
|
||
| `SSObj_FontUnderLine` | 下划线 | 整数(0/1) |
|
||
| `SSObj_FontInterval` | 字间隔 | 浮点数 |
|
||
| `SSObj_FontRealHeight` | 实际高度 | 浮点数 |
|
||
| `SSObj_FontRealLength` | 实际长度 | 浮点数 |
|
||
|
||
### 几何特性
|
||
|
||
用尖括号 `<>` 括住的属性,表示对象的几何拓扑特性,如是否重叠、是否封闭、是否凸多边形等。这些属性不是存储值,而是通过几何计算实时得到的判断结果。
|
||
|
||
| 属性名称 | 属性说明 | 返回值类型 |
|
||
|---------|---------|-----------|
|
||
| `<Overlap>` | 对象是否重叠 | 布尔值(True/False) |
|
||
| `<Close>` | 对象是否封闭 | 布尔值(True/False) |
|
||
| `<Convex>` | 对象是否为凸多边形 | 布尔值(True/False) |
|
||
| `<SelfIntersect>` | 对象是否自相交 | 布尔值(True/False) |
|
||
|
||
### 扩展属性
|
||
|
||
用方括号 `[]` 括住的属性,表示用户自定义的扩展属性,存储在对象的扩展属性表中。这些属性通常用于存储业务相关的自定义字段,如建筑结构、层数等。
|
||
|
||
| 属性名称 | 属性说明 | 数据类型 |
|
||
|---------|---------|---------|
|
||
| `[JG]` | 建筑结构 | 字符串 |
|
||
| `[CS]` | 建筑层数 | 字符串/整数 |
|
||
| `[自定义字段]` | 用户自定义字段 | 根据定义 |
|
||
|
||
Sources: [ObjBaseAttr.py](ObjBaseAttr.py#L7-L85)
|
||
|
||
## 核心 API 方法
|
||
|
||
获取地物属性值的核心方法是 `getSelGeoValue()` 和 `getSelNoteValue()`,这两个方法分别用于获取几何对象和注记对象的属性值。
|
||
|
||
### getSelGeoValue 方法
|
||
|
||
```python
|
||
def getSelGeoValue(self, index: int, fieldName: str) -> str
|
||
```
|
||
|
||
**参数说明**:
|
||
|
||
| 参数 | 类型 | 说明 |
|
||
|-----|------|------|
|
||
| index | int | 地物对象在选择集中的索引(从 0 开始) |
|
||
| fieldName | str | 属性名称,支持基本属性、几何特性和扩展属性 |
|
||
|
||
**返回值**:
|
||
- 类型:str
|
||
- 说明:指定地物对象的属性值,如果属性不存在或索引越界则返回空字符串
|
||
|
||
**使用示例**:
|
||
|
||
```python
|
||
from sunvpy import SSProcess
|
||
|
||
# 获取第 0 个对象的编码
|
||
code = SSProcess.getSelGeoValue(0, "SSObj_Code")
|
||
print(f"地物编码: {code}")
|
||
|
||
# 获取第 0 个对象的面积
|
||
area = SSProcess.getSelGeoValue(0, "SSObj_Area")
|
||
print(f"地物面积: {area}")
|
||
|
||
# 获取第 0 个对象的扩展属性 [JG]
|
||
structure = SSProcess.getSelGeoValue(0, "[JG]")
|
||
print(f"建筑结构: {structure}")
|
||
```
|
||
|
||
**内部实现逻辑**:
|
||
|
||
```mermaid
|
||
flowchart TD
|
||
A[getSelGeoValue 调用] --> B{索引越界?}
|
||
B -->|是| C[返回空字符串]
|
||
B -->|否| D{字段名以 [ 开头?}
|
||
D -->|是| E[扩展属性路径]
|
||
D -->|否| F[基本属性路径]
|
||
|
||
E --> E1[map.getExtentAttr<br/>获取扩展属性列表]
|
||
E1 --> E2{包含逗号?}
|
||
E2 -->|是| E3[分割多个字段名]
|
||
E2 -->|否| E4[查找单个字段]
|
||
E3 --> E5[查找并拼接多个值]
|
||
E4 --> E5
|
||
E5 --> E6[返回属性值]
|
||
|
||
F --> F1[objBaseAttr.getGeoValue<br/>处理基本属性]
|
||
F1 --> F2{对象类型判断}
|
||
F2 -->|注记对象| F3[读取注记专用属性]
|
||
F2 -->|其他对象| F4[读取通用属性]
|
||
F3 --> F5[返回属性值]
|
||
F4 --> F5
|
||
```
|
||
|
||
Sources: [ssprocess_mixins/selection_mixin.py](ssprocess_mixins/selection_mixin.py#L164-L202)
|
||
|
||
### getSelNoteValue 方法
|
||
|
||
```python
|
||
def getSelNoteValue(self, index: int, fieldName: str) -> str
|
||
```
|
||
|
||
**参数说明**:
|
||
|
||
| 参数 | 类型 | 说明 |
|
||
|-----|------|------|
|
||
| index | int | 注记对象在选择集中的索引(从 0 开始) |
|
||
| fieldName | str | 属性名称,支持基本属性、几何特性和扩展属性 |
|
||
|
||
**返回值**:
|
||
- 类型:str
|
||
- 说明:指定注记对象的属性值
|
||
|
||
**使用示例**:
|
||
|
||
```python
|
||
from sunvpy import SSProcess
|
||
|
||
# 获取第 0 个注记对象的字体内容
|
||
font_string = SSProcess.getSelNoteValue(0, "SSObj_FontString")
|
||
print(f"注记内容: {font_string}")
|
||
|
||
# 获取第 0 个注记对象的字体高度
|
||
font_height = SSProcess.getSelNoteValue(0, "SSObj_FontHeight")
|
||
print(f"字体高度: {font_height}")
|
||
|
||
# 获取第 0 个注记对象的字体分类号
|
||
font_class = SSProcess.getSelNoteValue(0, "SSObj_FontClass")
|
||
print(f"注记分类号: {font_class}")
|
||
```
|
||
|
||
Sources: [ssprocess_mixins/selection_mixin.py](ssprocess_mixins/selection_mixin.py#L204-L241)
|
||
|
||
## 属性获取流程
|
||
|
||
获取地物属性值的完整流程包括构建选择集、遍历对象、读取属性和输出结果四个阶段。下图展示了这个过程的完整数据流:
|
||
|
||
```mermaid
|
||
flowchart LR
|
||
A[初始化 SSProcess] --> B[清理选择集<br/>clearSelection]
|
||
B --> C[清理选择条件<br/>clearSelectCondition]
|
||
C --> D[设置选择条件<br/>setSelectCondition]
|
||
D --> E[执行过滤查询<br/>selectFilter]
|
||
E --> F[获取对象数量<br/>getSelGeoCount]
|
||
F --> G[遍历选择集]
|
||
G --> H[读取属性值<br/>getSelGeoValue]
|
||
H --> I{是否还有对象?}
|
||
I -->|是| G
|
||
I -->|否| J[处理完成]
|
||
```
|
||
|
||
## 基本属性读取示例
|
||
|
||
### 示例 1:读取单个对象的多个属性
|
||
|
||
```python
|
||
from sunvpy import SSProcess
|
||
|
||
# 假设选择集中已有对象
|
||
# 清理并设置选择条件
|
||
SSProcess.clearSelection()
|
||
SSProcess.clearSelectCondition()
|
||
SSProcess.setSelectCondition("SSObj_Code", "==", "3103013")
|
||
SSProcess.selectFilter()
|
||
|
||
# 定义要读取的属性列表
|
||
fields = [
|
||
"SSObj_ID", "SSObj_Code", "SSObj_LayerName", "SSObj_Type",
|
||
"SSObj_Color", "SSObj_LineType", "SSObj_LineWidth",
|
||
"SSObj_Name", "SSObj_Byname"
|
||
]
|
||
|
||
# 读取第 0 个对象的属性
|
||
print("=" * 50)
|
||
print("对象详细信息")
|
||
print("=" * 50)
|
||
for field in fields:
|
||
value = SSProcess.getSelGeoValue(0, field)
|
||
print(f"{field:20s}: {value}")
|
||
```
|
||
|
||
**输出示例**:
|
||
|
||
```
|
||
==================================================
|
||
对象详细信息
|
||
==================================================
|
||
SSObj_ID : 1001
|
||
SSObj_Code : 3103013
|
||
SSObj_LayerName : Default_A
|
||
SSObj_Type : LINE
|
||
SSObj_Color : 16777215
|
||
SSObj_LineType : 1
|
||
SSObj_LineWidth : 2
|
||
SSObj_Name : 道路1
|
||
SSObj_Byname : 主路
|
||
```
|
||
|
||
Sources: [PySSProcess.py](PySSProcess.py#L110-L138)
|
||
|
||
### 示例 2:批量读取所有对象的核心属性
|
||
|
||
```python
|
||
from sunvpy import SSProcess
|
||
|
||
# 清理并设置选择条件
|
||
SSProcess.clearSelection()
|
||
SSProcess.clearSelectCondition()
|
||
SSProcess.setSelectCondition("SSObj_Type", "==", "AREA")
|
||
SSProcess.selectFilter()
|
||
|
||
# 获取对象数量
|
||
count = SSProcess.getSelGeoCount()
|
||
print(f"选择集中有 {count} 个面对象\n")
|
||
|
||
# 定义要读取的核心属性
|
||
core_fields = ["SSObj_ID", "SSObj_Code", "SSObj_Area", "SSObj_Length"]
|
||
|
||
# 遍历所有对象并读取属性
|
||
for i in range(count):
|
||
print(f"对象 {i}:")
|
||
for field in core_fields:
|
||
value = SSProcess.getSelGeoValue(i, field)
|
||
print(f" {field}: {value}")
|
||
print("-" * 30)
|
||
```
|
||
|
||
Sources: [ssprocess_mixins/selection_mixin.py](ssprocess_mixins/selection_mixin.py#L152-L162)
|
||
|
||
## 坐标点属性读取
|
||
|
||
对于点、线、面对象,可以使用带参数的属性名来读取特定坐标点的信息。参数放在属性名后的括号中,如 `SSObj_X(0)` 表示第一个点的 X 坐标。
|
||
|
||
```python
|
||
from sunvpy import SSProcess
|
||
|
||
# 清理并设置选择条件
|
||
SSProcess.clearSelection()
|
||
SSProcess.clearSelectCondition()
|
||
SSProcess.setSelectCondition("SSObj_Type", "==", "LINE")
|
||
SSProcess.selectFilter()
|
||
|
||
# 获取第 0 个线对象
|
||
count = SSProcess.getSelGeoCount()
|
||
if count > 0:
|
||
# 获取点数
|
||
point_count = SSProcess.getSelGeoValue(0, "SSObj_PointCount")
|
||
print(f"该线对象包含 {point_count} 个坐标点\n")
|
||
|
||
# 遍历所有坐标点
|
||
for j in range(int(point_count)):
|
||
x = SSProcess.getSelGeoValue(0, f"SSObj_X({j})")
|
||
y = SSProcess.getSelGeoValue(0, f"SSObj_Y({j})")
|
||
z = SSProcess.getSelGeoValue(0, f"SSObj_Z({j})")
|
||
point_name = SSProcess.getSelGeoValue(0, f"SSObj_PointName({j})")
|
||
point_type = SSProcess.getSelGeoValue(0, f"SSObj_PointType({j})")
|
||
|
||
print(f"点 {j}: X={x}, Y={y}, Z={z}, 名称={point_name}, 类型={point_type}")
|
||
```
|
||
|
||
**输出示例**:
|
||
|
||
```
|
||
该线对象包含 5 个坐标点
|
||
|
||
点 0: X=12345.67, Y=54321.09, Z=0.00, 名称=起点, 类型=1
|
||
点 1: X=12400.00, Y=54380.00, Z=0.00, 名称=, 类型=0
|
||
点 2: X=12450.50, Y=54420.30, Z=0.00, 名称=, 类型=0
|
||
点 3: X=12500.00, Y=54480.00, Z=0.00, 名称=, 类型=0
|
||
点 4: X=12550.75, Y=54530.60, Z=0.00, 名称=终点, 类型=2
|
||
```
|
||
|
||
Sources: [ObjBaseAttr.py](ObjBaseAttr.py#L329-L363)
|
||
|
||
## 几何特性读取示例
|
||
|
||
几何特性属性用于判断对象的拓扑状态,通常用于数据质量检查。
|
||
|
||
```python
|
||
from sunvpy import SSProcess
|
||
|
||
# 清理并设置选择条件
|
||
SSProcess.clearSelection()
|
||
SSProcess.clearSelectCondition()
|
||
SSProcess.setSelectCondition("SSObj_Type", "==", "AREA")
|
||
SSProcess.selectFilter()
|
||
|
||
# 获取对象数量
|
||
count = SSProcess.getSelGeoCount()
|
||
print(f"面对象几何特性检查\n")
|
||
|
||
# 遍历所有面对象
|
||
for i in range(count):
|
||
obj_id = SSProcess.getSelGeoValue(i, "SSObj_ID")
|
||
obj_code = SSProcess.getSelGeoValue(i, "SSObj_Code")
|
||
|
||
# 读取几何特性
|
||
is_closed = SSProcess.getSelGeoValue(i, "<Close>")
|
||
is_overlap = SSProcess.getSelGeoValue(i, "<Overlap>")
|
||
is_convex = SSProcess.getSelGeoValue(i, "<Convex>")
|
||
is_self_intersect = SSProcess.getSelGeoValue(i, "<SelfIntersect>")
|
||
|
||
print(f"对象 ID={obj_id}, Code={obj_code}:")
|
||
print(f" 是否封闭: {is_closed}")
|
||
print(f" 是否重叠: {is_overlap}")
|
||
print(f" 是否凸多边形: {is_convex}")
|
||
print(f" 是否自相交: {is_self_intersect}")
|
||
|
||
# 检查是否有问题
|
||
issues = []
|
||
if is_closed == "False":
|
||
issues.append("未封闭")
|
||
if is_overlap == "True":
|
||
issues.append("存在重叠")
|
||
if is_self_intersect == "True":
|
||
issues.append("存在自相交")
|
||
|
||
if issues:
|
||
print(f" ⚠️ 发现问题: {', '.join(issues)}")
|
||
print("-" * 40)
|
||
```
|
||
|
||
Sources: [ssprocess_mixins/selection_mixin.py](ssprocess_mixins/selection_mixin.py#L52-L110)
|
||
|
||
## 扩展属性读取示例
|
||
|
||
扩展属性使用方括号 `[]` 括住属性名,支持读取单个属性或多个属性。
|
||
|
||
### 读取单个扩展属性
|
||
|
||
```python
|
||
from sunvpy import SSProcess
|
||
|
||
# 清理并设置选择条件
|
||
SSProcess.clearSelection()
|
||
SSProcess.clearSelectCondition()
|
||
SSProcess.setSelectCondition("SSObj_Type", "==", "AREA")
|
||
SSProcess.selectFilter()
|
||
|
||
# 读取第一个对象的扩展属性
|
||
building_structure = SSProcess.getSelGeoValue(0, "[JG]")
|
||
building_floors = SSProcess.getSelGeoValue(0, "[CS]")
|
||
custom_field = SSProcess.getSelGeoValue(0, "[建筑用途]")
|
||
|
||
print(f"建筑结构: {building_structure}")
|
||
print(f"建筑层数: {building_floors}")
|
||
print(f"建筑用途: {custom_field}")
|
||
```
|
||
|
||
### 读取多个扩展属性
|
||
|
||
使用逗号分隔多个属性名,可以一次性读取多个扩展属性,返回值会用逗号拼接。
|
||
|
||
```python
|
||
from sunvpy import SSProcess
|
||
|
||
# 清理并设置选择条件
|
||
SSProcess.clearSelection()
|
||
SSProcess.clearSelectCondition()
|
||
SSProcess.setSelectCondition("SSObj_Type", "==", "AREA")
|
||
SSProcess.selectFilter()
|
||
|
||
# 一次性读取多个扩展属性
|
||
combined_value = SSProcess.getSelGeoValue(0, "[JG],[CS]")
|
||
values = combined_value.split(',')
|
||
|
||
print(f"建筑结构: {values[0] if len(values) > 0 else ''}")
|
||
print(f"建筑层数: {values[1] if len(values) > 1 else ''}")
|
||
```
|
||
|
||
### 获取对象的完整扩展属性列表
|
||
|
||
如果不确定对象有哪些扩展属性,可以先获取完整的扩展属性列表:
|
||
|
||
```python
|
||
from sunvpy import SSProcess
|
||
|
||
# 清理并设置选择条件
|
||
SSProcess.clearSelection()
|
||
SSProcess.clearSelectCondition()
|
||
SSProcess.selectFilter()
|
||
|
||
# 获取第一个对象的扩展属性字段和值
|
||
SSProcess.curSelGeoFields.clear()
|
||
SSProcess.curSelGeoValues.clear()
|
||
|
||
# 直接访问地物对象获取扩展属性
|
||
geo = SSProcess.selGeoList[0]
|
||
SSProcess.map.getExtentAttr(geo, SSProcess.curSelGeoFields, SSProcess.curSelGeoValues)
|
||
|
||
# 打印所有扩展属性
|
||
print("对象的扩展属性列表:")
|
||
for i in range(SSProcess.curSelGeoFields.size()):
|
||
field = SSProcess.curSelGeoFields[i]
|
||
value = SSProcess.curSelGeoValues[i]
|
||
print(f" [{field}]: {value}")
|
||
```
|
||
|
||
**输出示例**:
|
||
|
||
```
|
||
对象的扩展属性列表:
|
||
[JG]: 砖混结构
|
||
[CS]: 6
|
||
[建筑用途]: 住宅
|
||
[竣工年份]: 2020
|
||
[建设单位]: XX公司
|
||
```
|
||
|
||
Sources: [ssprocess_mixins/selection_mixin.py](ssprocess_mixins/selection_mixin.py#L164-L186)
|
||
|
||
## 注记对象属性读取
|
||
|
||
注记对象(NOTE 类型)除了通用属性外,还有许多专用的字体和排版属性。
|
||
|
||
```python
|
||
from sunvpy import SSProcess
|
||
|
||
# 清理并设置选择条件
|
||
SSProcess.clearSelection()
|
||
SSProcess.clearSelectCondition()
|
||
SSProcess.setSelectCondition("SSObj_Type", "==", "NOTE")
|
||
SSProcess.selectFilter()
|
||
|
||
# 获取注记对象数量
|
||
count = SSProcess.getSelNoteCount()
|
||
print(f"选择集中有 {count} 个注记对象\n")
|
||
|
||
# 定义注记专用属性列表
|
||
note_fields = [
|
||
"SSObj_FontString", "SSObj_FontStringCount",
|
||
"SSObj_FontWidth", "SSObj_FontHeight", "SSObj_FontName",
|
||
"SSObj_FontClass", "SSObj_FontAlignment", "SSObj_FontPosType",
|
||
"SSObj_FontWordAngle", "SSObj_FontStringAngle",
|
||
"SSObj_FontWeight", "SSObj_FontUnderLine", "SSObj_FontInterval"
|
||
]
|
||
|
||
# 遍历所有注记对象
|
||
for i in range(min(count, 5)): # 最多显示前 5 个
|
||
print(f"注记对象 {i}:")
|
||
for field in note_fields:
|
||
value = SSProcess.getSelNoteValue(i, field)
|
||
print(f" {field:20s}: {value}")
|
||
print("-" * 50)
|
||
```
|
||
|
||
**输出示例**:
|
||
|
||
```
|
||
选择集中有 3 个注记对象
|
||
|
||
注记对象 0:
|
||
SSObj_FontString : 测区边界
|
||
SSObj_FontStringCount : 4
|
||
SSObj_FontWidth : 15.00
|
||
SSObj_FontHeight : 20.00
|
||
SSObj_FontName : 宋体
|
||
SSObj_FontClass : 1
|
||
SSObj_FontAlignment : 0
|
||
SSObj_FontPosType : 0
|
||
SSObj_FontWordAngle : 0.00
|
||
SSObj_FontStringAngle : 0.00
|
||
SSObj_FontWeight : 400
|
||
SSObj_FontUnderLine : 0
|
||
SSObj_FontInterval : 1.00
|
||
--------------------------------------------------
|
||
```
|
||
|
||
Sources: [ObjBaseAttr.py](ObjBaseAttr.py#L147-L207)
|
||
|
||
## 综合应用示例
|
||
|
||
下面的示例展示了如何结合基本属性、几何特性和扩展属性,实现一个完整的属性查询和分析功能。
|
||
|
||
```python
|
||
from sunvpy import SSProcess
|
||
|
||
def analyze_geospatial_objects():
|
||
"""分析地物对象的综合属性"""
|
||
|
||
# 步骤 1: 清理并设置选择条件
|
||
SSProcess.clearSelection()
|
||
SSProcess.clearSelectCondition()
|
||
SSProcess.setSelectCondition("SSObj_Type", "==", "AREA")
|
||
SSProcess.selectFilter()
|
||
|
||
# 步骤 2: 获取对象数量
|
||
count = SSProcess.getSelGeoCount()
|
||
print(f"分析 {count} 个面对象的综合属性\n")
|
||
|
||
# 步骤 3: 统计信息
|
||
total_area = 0.0
|
||
total_length = 0.0
|
||
problem_count = 0
|
||
|
||
# 步骤 4: 遍历所有对象
|
||
for i in range(count):
|
||
# 读取基本属性
|
||
obj_id = SSProcess.getSelGeoValue(i, "SSObj_ID")
|
||
obj_code = SSProcess.getSelGeoValue(i, "SSObj_Code")
|
||
obj_layer = SSProcess.getSelGeoValue(i, "SSObj_LayerName")
|
||
obj_area = float(SSProcess.getSelGeoValue(i, "SSObj_Area"))
|
||
obj_length = float(SSProcess.getSelGeoValue(i, "SSObj_Length"))
|
||
obj_create_time = SSProcess.getSelGeoValue(i, "SSObj_CreateTime")
|
||
obj_modify_time = SSProcess.getSelGeoValue(i, "SSObj_ModifyTime")
|
||
|
||
# 累计面积和长度
|
||
total_area += obj_area
|
||
total_length += obj_length
|
||
|
||
# 读取几何特性
|
||
is_closed = SSProcess.getSelGeoValue(i, "<Close>")
|
||
is_overlap = SSProcess.getSelGeoValue(i, "<Overlap>")
|
||
|
||
# 读取扩展属性
|
||
building_structure = SSProcess.getSelGeoValue(i, "[JG]")
|
||
building_floors = SSProcess.getSelGeoValue(i, "[CS]")
|
||
|
||
# 检查几何问题
|
||
has_problem = False
|
||
problems = []
|
||
|
||
if is_closed == "False":
|
||
problems.append("未封闭")
|
||
has_problem = True
|
||
|
||
if is_overlap == "True":
|
||
problems.append("存在重叠")
|
||
has_problem = True
|
||
|
||
if has_problem:
|
||
problem_count += 1
|
||
print(f"⚠️ 对象 {obj_id} (Code={obj_code}) 发现问题: {', '.join(problems)}")
|
||
|
||
# 输出对象详细信息
|
||
print(f"对象 ID={obj_id}:")
|
||
print(f" 图层: {obj_layer}")
|
||
print(f" 面积: {obj_area:.2f} 平方米")
|
||
print(f" 周长: {obj_length:.2f} 米")
|
||
print(f" 建筑结构: {building_structure if building_structure else '未知'}")
|
||
print(f" 建筑层数: {building_floors if building_floors else '未知'}")
|
||
print(f" 创建时间: {obj_create_time}")
|
||
print(f" 修改时间: {obj_modify_time}")
|
||
print(f" 几何状态: {'封闭' if is_closed == 'True' else '未封闭'}, {'重叠' if is_overlap == 'True' else '无重叠'}")
|
||
print("-" * 60)
|
||
|
||
# 步骤 5: 输出统计摘要
|
||
print("\n" + "=" * 60)
|
||
print("统计摘要")
|
||
print("=" * 60)
|
||
print(f"对象总数: {count}")
|
||
print(f"总面积: {total_area:.2f} 平方米")
|
||
print(f"平均面积: {total_area/count if count > 0 else 0:.2f} 平方米")
|
||
print(f"总周长: {total_length:.2f} 米")
|
||
print(f"平均周长: {total_length/count if count > 0 else 0:.2f} 米")
|
||
print(f"问题对象数: {problem_count} ({problem_count/count*100 if count > 0 else 0:.1f}%)")
|
||
print("=" * 60)
|
||
|
||
# 执行分析
|
||
analyze_geospatial_objects()
|
||
```
|
||
|
||
Sources: [PySSProcess.py](PySSProcess.py#L110-L138)
|
||
|
||
## 常见问题与解决方案
|
||
|
||
### 问题 1:属性值返回空字符串
|
||
|
||
**现象**:调用 `getSelGeoValue()` 后返回空字符串
|
||
|
||
**可能原因**:
|
||
1. 索引越界:指定的索引超出了选择集范围
|
||
2. 属性名不存在:属性名拼写错误或该对象不支持此属性
|
||
3. 属性不适用:尝试读取不适用的属性(如点对象的面积)
|
||
|
||
**解决方案**:
|
||
|
||
```python
|
||
from sunvpy import SSProcess
|
||
|
||
# 检查索引是否有效
|
||
count = SSProcess.getSelGeoCount()
|
||
index = 0
|
||
|
||
if index >= 0 and index < count:
|
||
value = SSProcess.getSelGeoValue(index, "SSObj_Code")
|
||
if value:
|
||
print(f"属性值: {value}")
|
||
else:
|
||
print("属性值为空,可能属性不存在")
|
||
else:
|
||
print(f"索引 {index} 越界,选择集中只有 {count} 个对象")
|
||
```
|
||
|
||
### 问题 2:扩展属性无法读取
|
||
|
||
**现象**:使用 `[扩展属性名]` 格式读取时返回空值
|
||
|
||
**可能原因**:
|
||
1. 扩展属性名称拼写错误
|
||
2. 当前对象没有该扩展属性
|
||
3. 扩展属性未在数据源中定义
|
||
|
||
**解决方案**:
|
||
|
||
```python
|
||
from sunvpy import SSProcess
|
||
|
||
# 方法 1: 先查询对象有哪些扩展属性
|
||
SSProcess.curSelGeoFields.clear()
|
||
SSProcess.curSelGeoValues.clear()
|
||
geo = SSProcess.selGeoList[0] if SSProcess.getSelGeoCount() > 0 else None
|
||
|
||
if geo:
|
||
SSProcess.map.getExtentAttr(geo, SSProcess.curSelGeoFields, SSProcess.curSelGeoValues)
|
||
print("可用的扩展属性:")
|
||
for i in range(SSProcess.curSelGeoFields.size()):
|
||
print(f" {SSProcess.curSelGeoFields[i]}")
|
||
|
||
# 方法 2: 使用正确的属性名读取
|
||
structure = SSProcess.getSelGeoValue(0, "[JG]") # 确保方括号和名称正确
|
||
```
|
||
|
||
### 问题 3:坐标点属性读取失败
|
||
|
||
**现象**:使用 `SSObj_X(0)` 等格式读取坐标点时返回空值
|
||
|
||
**可能原因**:
|
||
1. 对象点数不足:指定的点索引超出了对象的实际点数
|
||
2. 对象类型不支持:注记对象不支持坐标点属性
|
||
|
||
**解决方案**:
|
||
|
||
```python
|
||
from sunvpy import SSProcess
|
||
|
||
# 先获取对象的点数
|
||
point_count = SSProcess.getSelGeoValue(0, "SSObj_PointCount")
|
||
obj_type = SSProcess.getSelGeoValue(0, "SSObj_Type")
|
||
|
||
if obj_type in ["POINT", "LINE", "AREA"]:
|
||
if point_count:
|
||
for j in range(int(point_count)):
|
||
x = SSProcess.getSelGeoValue(0, f"SSObj_X({j})")
|
||
y = SSProcess.getSelGeoValue(0, f"SSObj_Y({j})")
|
||
print(f"点 {j}: ({x}, {y})")
|
||
else:
|
||
print("对象没有坐标点")
|
||
else:
|
||
print("注记对象不支持坐标点属性")
|
||
```
|
||
|
||
### 问题 4:几何特性返回值不是预期的布尔值
|
||
|
||
**现象**:读取 `<Close>` 等几何特性时,返回值不是 "True" 或 "False"
|
||
|
||
**可能原因**:几何特性的返回值格式可能与预期不同
|
||
|
||
**解决方案**:
|
||
|
||
```python
|
||
from sunvpy import SSProcess
|
||
|
||
# 读取几何特性并处理不同格式
|
||
is_closed = SSProcess.getSelGeoValue(0, "<Close>")
|
||
|
||
# 处理不同的返回值格式
|
||
if is_closed in ["True", "true", "1", "是"]:
|
||
print("对象是封闭的")
|
||
elif is_closed in ["False", "false", "0", "否", ""]:
|
||
print("对象未封闭")
|
||
else:
|
||
print(f"未知的状态值: {is_closed}")
|
||
```
|
||
|
||
Sources: [ssprocess_mixins/selection_mixin.py](ssprocess_mixins/selection_mixin.py#L164-L241)
|
||
|
||
## 属性读取性能优化建议
|
||
|
||
在处理大量地物对象时,合理的代码组织可以显著提高属性读取效率。
|
||
|
||
### 建议 1:批量读取多个属性
|
||
|
||
```python
|
||
# 不推荐:多次调用 getSelGeoValue
|
||
code = SSProcess.getSelGeoValue(i, "SSObj_Code")
|
||
name = SSProcess.getSelGeoValue(i, "SSObj_Name")
|
||
layer = SSProcess.getSelGeoValue(i, "SSObj_LayerName")
|
||
|
||
# 推荐:使用列表批量定义属性,然后循环读取
|
||
fields = ["SSObj_Code", "SSObj_Name", "SSObj_LayerName"]
|
||
for field in fields:
|
||
value = SSProcess.getSelGeoValue(i, field)
|
||
print(f"{field}: {value}")
|
||
```
|
||
|
||
### 建议 2:避免重复读取
|
||
|
||
```python
|
||
# 不推荐:在循环中重复读取相同的属性
|
||
for i in range(count):
|
||
obj_type = SSProcess.getSelGeoValue(i, "SSObj_Type")
|
||
if obj_type == "AREA":
|
||
area = SSProcess.getSelGeoValue(i, "SSObj_Area") # 第一次读取
|
||
length = SSProcess.getSelGeoValue(i, "SSObj_Length")
|
||
# ... 其他处理
|
||
print(f"面积: {SSProcess.getSelGeoValue(i, 'SSObj_Area')}") # 重复读取
|
||
|
||
# 推荐:缓存已读取的属性值
|
||
for i in range(count):
|
||
obj_type = SSProcess.getSelGeoValue(i, "SSObj_Type")
|
||
if obj_type == "AREA":
|
||
area = SSProcess.getSelGeoValue(i, "SSObj_Area")
|
||
length = SSProcess.getSelGeoValue(i, "SSObj_Length")
|
||
# ... 其他处理
|
||
print(f"面积: {area}") # 使用缓存的值
|
||
```
|
||
|
||
### 建议 3:使用字典存储对象属性
|
||
|
||
```python
|
||
# 推荐:使用字典存储每个对象的属性
|
||
for i in range(count):
|
||
obj_attrs = {}
|
||
fields = ["SSObj_ID", "SSObj_Code", "SSObj_Name", "SSObj_Area"]
|
||
|
||
for field in fields:
|
||
obj_attrs[field] = SSProcess.getSelGeoValue(i, field)
|
||
|
||
# 使用字典中的值进行处理
|
||
print(f"对象 {obj_attrs['SSObj_ID']}: {obj_attrs['SSObj_Name']}, 面积={obj_attrs['SSObj_Area']}")
|
||
```
|
||
|
||
## 下一步学习
|
||
|
||
掌握了属性读取方法后,您可能对以下主题感兴趣:
|
||
|
||
- **修改地物属性值**:学习如何使用 `setSelGeoValue()` 和 `setSelNoteValue()` 方法修改地物属性,参见 [修改地物属性值](16-xiu-gai-di-wu-shu-xing-zhi)
|
||
- **地物基本属性详解**:深入了解各个基本属性的含义和取值范围,参见 [地物基本属性详解](17-di-wu-ji-ben-shu-xing-xiang-jie)
|
||
- **扩展属性与自定义属性**:学习如何定义和使用扩展属性,参见 [扩展属性与自定义属性](18-kuo-zhan-shu-xing-yu-zi-ding-yi-shu-xing)
|
||
- **遍历选择集对象**:了解更多关于选择集遍历的高级技巧和最佳实践,参见 [遍历选择集对象](14-bian-li-xuan-ze-ji-dui-xiang)
|
||
|
||
通过这些文档的结合学习,您将能够全面掌握 SunvStation 地物属性的管理技巧,构建更强大和高效的地理数据处理脚本。 |