数据编辑与数字化

第十二章 数据编辑与数字化

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操作

  1. 选择图层,开启编辑
  2. 点击"添加点要素"工具
  3. 在地图上点击位置
  4. 填写属性
  5. 确认

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操作

  1. 选择"添加线要素"工具
  2. 依次点击节点位置
  3. 右键结束绘制
  4. 填写属性

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 在属性表中编辑

  1. 开启图层编辑
  2. 打开属性表 (F6)
  3. 直接点击单元格编辑
  4. 保存更改

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 栅格地理配准

栅格 > 地理配准

步骤

  1. 加载待配准影像
  2. 添加控制点(GCP)
  3. 选择转换类型
  4. 设置目标CRS
  5. 运行配准

转换类型

  • 线性
  • 亥姆霍兹
  • 多项式(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中的数据编辑与数字化功能:

关键要点

  1. 掌握基本的编辑操作流程
  2. 熟练使用各种数字化工具
  3. 了解捕捉和拓扑编辑设置
  4. 能够进行属性编辑和批量更新
  5. 掌握地理配准和GPS数据处理
  6. 了解编辑验证和自动化方法

数据编辑是GIS数据生产的核心技能。


上一章第11章 地图布局与打印

下一章第13章 Processing工具箱

posted @ 2026-01-08 14:04  我才是银古  阅读(23)  评论(0)    收藏  举报