数据编辑与数字化
第十二章 数据编辑与数字化
12.1 编辑基础
12.1.1 开启编辑模式
GUI方式:
- 工具栏:点击编辑按钮
- 右键图层 > 切换编辑
- 快捷键:Ctrl+E
PyQGIS:
layer = iface.activeLayer()
layer.startEditing()
12.1.2 保存和取消编辑
# 保存编辑
layer.commitChanges()
# 取消编辑(不保存)
layer.rollBack()
# 保存但继续编辑
layer.commitChanges()
layer.startEditing()
12.1.3 编辑能力检查
provider = layer.dataProvider()
caps = provider.capabilities()
# 检查能力
can_add = caps & QgsVectorDataProvider.AddFeatures
can_delete = caps & QgsVectorDataProvider.DeleteFeatures
can_modify_attrs = caps & QgsVectorDataProvider.ChangeAttributeValues
can_modify_geom = caps & QgsVectorDataProvider.ChangeGeometries
12.2 数字化工具
12.2.1 添加点要素
GUI操作:
- 选择图层,开启编辑
- 点击"添加点要素"工具
- 在地图上点击位置
- 填写属性
- 确认
PyQGIS:
from qgis.core import QgsFeature, QgsGeometry, QgsPointXY
layer.startEditing()
feature = QgsFeature()
feature.setGeometry(QgsGeometry.fromPointXY(QgsPointXY(116.4, 39.9)))
feature.setAttributes([1, "北京", 21540000])
layer.addFeature(feature)
layer.commitChanges()
12.2.2 添加线要素
GUI操作:
- 选择"添加线要素"工具
- 依次点击节点位置
- 右键结束绘制
- 填写属性
PyQGIS:
from qgis.core import QgsGeometry, QgsPoint
points = [
QgsPoint(116.0, 39.0),
QgsPoint(117.0, 39.5),
QgsPoint(118.0, 40.0)
]
feature = QgsFeature()
feature.setGeometry(QgsGeometry.fromPolyline(points))
layer.addFeature(feature)
12.2.3 添加面要素
PyQGIS:
# 简单多边形
points = [
QgsPointXY(116.0, 39.0),
QgsPointXY(117.0, 39.0),
QgsPointXY(117.0, 40.0),
QgsPointXY(116.0, 40.0),
QgsPointXY(116.0, 39.0) # 闭合
]
feature = QgsFeature()
feature.setGeometry(QgsGeometry.fromPolygonXY([points]))
layer.addFeature(feature)
# 带洞的多边形
outer = [...] # 外环
inner = [...] # 内环(洞)
feature.setGeometry(QgsGeometry.fromPolygonXY([outer, inner]))
12.2.4 编辑快捷键
| 快捷键 | 功能 |
|---|---|
| Ctrl+E | 切换编辑模式 |
| Ctrl+S | 保存图层编辑 |
| Ctrl+Z | 撤销 |
| Ctrl+Shift+Z | 重做 |
| Del | 删除选中要素 |
| 空格 | 添加节点时完成 |
| Backspace | 删除最后添加的节点 |
| Esc | 取消当前操作 |
12.3 节点编辑
12.3.1 节点工具
功能:
- 选择节点
- 移动节点
- 添加节点
- 删除节点
- 修改线段
12.3.2 PyQGIS节点操作
# 获取几何节点
geom = feature.geometry()
# 对于多边形
for part in geom.parts():
for ring in part:
for point in ring:
print(point.x(), point.y())
# 移动节点
geom.moveVertex(new_x, new_y, vertex_index)
# 删除节点
geom.deleteVertex(vertex_index)
# 插入节点
geom.insertVertex(x, y, vertex_index)
# 更新要素几何
layer.changeGeometry(feature.id(), geom)
12.3.3 高级编辑工具
| 工具 | 功能 |
|---|---|
| 移动要素 | 整体移动选中要素 |
| 旋转要素 | 旋转选中要素 |
| 缩放要素 | 缩放选中要素 |
| 简化要素 | 减少节点数量 |
| 添加环 | 在多边形中添加洞 |
| 添加部件 | 创建多部件几何 |
| 删除环 | 删除多边形中的洞 |
| 删除部件 | 删除多部件中的部件 |
| 重塑要素 | 重新绘制部分边界 |
| 分割要素 | 将要素分割为多个 |
| 合并要素 | 合并多个要素 |
12.4 捕捉设置
12.4.1 启用捕捉
项目 > 捕捉选项 (Ctrl+U)
或点击状态栏捕捉按钮
12.4.2 捕捉设置
from qgis.core import QgsSnappingConfig, QgsTolerance
# 获取捕捉配置
config = QgsProject.instance().snappingConfig()
# 启用捕捉
config.setEnabled(True)
# 设置捕捉类型
config.setTypeFlag(QgsSnappingConfig.VertexFlag) # 节点
# QgsSnappingConfig.SegmentFlag # 线段
# QgsSnappingConfig.VertexAndSegment # 两者
# 设置容差
config.setTolerance(10)
config.setUnits(QgsTolerance.Pixels)
# 设置图层捕捉
config.setMode(QgsSnappingConfig.AllLayers) # 所有图层
# QgsSnappingConfig.ActiveLayer # 仅当前图层
# QgsSnappingConfig.AdvancedConfiguration # 高级配置
QgsProject.instance().setSnappingConfig(config)
12.4.3 高级捕捉
# 启用拓扑编辑
config.setIntersectionSnapping(True)
# 启用追踪
# 通过GUI: 启用追踪工具按钮
12.5 拓扑编辑
12.5.1 共享边界编辑
启用拓扑编辑后,移动共享节点会同时更新相邻要素:
项目 > 捕捉选项 > 启用拓扑编辑
12.5.2 避免重叠/空隙
# 设置避免重叠的图层
config.setIndividualLayerSettings(
layer,
QgsSnappingConfig.IndividualLayerSettings(
True, # 启用
QgsSnappingConfig.VertexAndSegment,
10, # 容差
QgsTolerance.Pixels,
True # 避免重叠
)
)
12.5.3 拓扑检查
import processing
# 检查重叠
result = processing.run("qgis:checkoverlap", {
'INPUT': layer,
'OUTPUT': 'memory:'
})
# 检查空隙
result = processing.run("qgis:checkgaps", {
'INPUT': layer,
'OUTPUT': 'memory:'
})
12.6 属性编辑
12.6.1 在属性表中编辑
- 开启图层编辑
- 打开属性表 (F6)
- 直接点击单元格编辑
- 保存更改
12.6.2 批量修改
layer.startEditing()
# 使用字段计算器表达式
expression = QgsExpression('$area / 1000000')
context = QgsExpressionContext()
context.appendScopes(QgsExpressionContextUtils.globalProjectLayerScopes(layer))
field_index = layer.fields().indexOf('area_km2')
for feature in layer.getFeatures():
context.setFeature(feature)
value = expression.evaluate(context)
layer.changeAttributeValue(feature.id(), field_index, value)
layer.commitChanges()
12.6.3 字段计算器
# 使用Processing的字段计算器
result = processing.run("native:fieldcalculator", {
'INPUT': layer,
'FIELD_NAME': 'area_km2',
'FIELD_TYPE': 0, # 0=Float
'FIELD_LENGTH': 10,
'FIELD_PRECISION': 2,
'FORMULA': '$area / 1000000',
'OUTPUT': 'memory:'
})
12.7 地理配准
12.7.1 栅格地理配准
栅格 > 地理配准
步骤:
- 加载待配准影像
- 添加控制点(GCP)
- 选择转换类型
- 设置目标CRS
- 运行配准
转换类型:
- 线性
- 亥姆霍兹
- 多项式(1-3阶)
- 薄板样条
- 投影变换
12.7.2 矢量地理配准
使用矢量配准插件或Processing工具:
result = processing.run("gdal:translate", {
'INPUT': raster_layer,
'EXTRA': '-gcp 100 200 116.0 39.0 -gcp 300 200 117.0 39.0',
'OUTPUT': '/path/to/output.tif'
})
12.8 GPS数据
12.8.1 连接GPS
视图 > 面板 > GPS信息面板
12.8.2 实时追踪
GPS面板 > 连接
选择设备类型和端口
12.8.3 记录轨迹
GPS面板 > 数字化模式
选择目标图层
开始记录
12.8.4 导入GPX
# 加载GPX文件
tracks = QgsVectorLayer("/path/to/data.gpx|layername=tracks", "Tracks", "ogr")
waypoints = QgsVectorLayer("/path/to/data.gpx|layername=waypoints", "Waypoints", "ogr")
12.9 CAD工具
12.9.1 高级数字化工具栏
| 工具 | 功能 |
|---|---|
| CAD构造模式 | 启用精确输入 |
| 平行/垂直 | 限制绘制方向 |
| 锁定角度/距离 | 精确控制 |
| 坐标输入 | 直接输入坐标 |
12.9.2 精确输入
启用CAD工具后:
- Tab:切换输入框
- 输入距离和角度
- Enter:确认
12.9.3 构造辅助
# 启用CAD工具
视图 > 工具栏 > 高级数字化工具栏
# 使用:
1. 点击CAD构造模式按钮
2. 输入精确坐标/距离/角度
3. 完成绘制
12.10 编辑验证
12.10.1 几何验证
# 检查所有要素的几何有效性
for feature in layer.getFeatures():
geom = feature.geometry()
if not geom.isGeosValid():
print(f"要素 {feature.id()} 几何无效")
errors = geom.validateGeometry()
for error in errors:
print(f" 错误: {error.what()}")
12.10.2 修复无效几何
result = processing.run("native:fixgeometries", {
'INPUT': layer,
'OUTPUT': 'memory:'
})
12.10.3 拓扑规则检查
# 检查拓扑规则
from qgis.analysis import QgsGeometrySnapper, QgsInternalGeometrySnapper
# 常见检查:
# - 自相交
# - 重复节点
# - 重叠多边形
# - 空隙
12.11 撤销与历史
12.11.1 撤销堆栈
# 获取撤销堆栈
undo_stack = layer.undoStack()
# 撤销
undo_stack.undo()
# 重做
undo_stack.redo()
# 检查是否可撤销
can_undo = undo_stack.canUndo()
can_redo = undo_stack.canRedo()
12.11.2 编辑缓冲区
# 获取编辑缓冲区
buffer = layer.editBuffer()
if buffer:
# 获取已更改的要素
changed = buffer.changedGeometries()
added = buffer.addedFeatures()
deleted = buffer.deletedFeatureIds()
12.12 自动化编辑
12.12.1 批量操作
# 批量添加要素
layer.startEditing()
features = []
for i in range(100):
feature = QgsFeature()
feature.setGeometry(QgsGeometry.fromPointXY(QgsPointXY(i, i)))
feature.setAttributes([i, f"Point {i}"])
features.append(feature)
layer.addFeatures(features)
layer.commitChanges()
12.12.2 条件更新
# 根据条件更新
layer.startEditing()
request = QgsFeatureRequest().setFilterExpression('"status" = \'old\'')
for feature in layer.getFeatures(request):
layer.changeAttributeValue(feature.id(),
layer.fields().indexOf('status'),
'updated')
layer.commitChanges()
12.13 小结
本章详细介绍了QGIS中的数据编辑与数字化功能:
关键要点:
- 掌握基本的编辑操作流程
- 熟练使用各种数字化工具
- 了解捕捉和拓扑编辑设置
- 能够进行属性编辑和批量更新
- 掌握地理配准和GPS数据处理
- 了解编辑验证和自动化方法
数据编辑是GIS数据生产的核心技能。
上一章:第11章 地图布局与打印

浙公网安备 33010602011771号