Files
sunvpy-docs/docs/content/15-huo-qu-di-wu-shu-xing-zhi.md
2026-04-10 13:47:53 +08:00

818 lines
27 KiB
Markdown
Raw Permalink 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 脚本中读取地物对象的属性值,涵盖基本属性、几何特性和扩展属性三种类型的属性访问方式。通过掌握这些方法,您可以高效地获取和分析地理对象的各类信息,为后续的数据处理、质量检查和统计分析奠定基础。
## 属性类型与命名规则
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{字段名以 &#91 开头?}
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 地物属性的管理技巧,构建更强大和高效的地理数据处理脚本。