0.项目调研
由于项目需要开发一个结合深度学习模型进行智能解译,并且能够对解译完的矢量进行编辑,因此大致制定了三个可行方案:1、基于python现有的gis二次开发库进行实现。2、基于c#的AE二次开发实现。3、基于Webgis中可用的GIS平台API实现。
考虑到c#实现涉及到跨平台的问题,并且AE里面也没有合适的矢量编辑组件,需要从基础逻辑开始实现鼠标编辑功能,而WebGIS的实现会涉及到前后端的问题,一般遥感影像数据量较大,部署到后端可能会不方便,因此最后考虑利用基于python的pyqgis库进行项目开发。
1.参考资料
知乎里面有位博主针对pyqgis的二次开发写了详细的基础教程,初学者参考价值非常大:
此外,pyqgis的官方教程也非常具有参考价值:Map Rendering and Printing — QGIS Documentation documentation
2.矢量编辑功能
class VertexDragTool22(QgsMapTool):
def __init__(self, canvas, layer):
super().__init__(canvas)
self.canvas = canvas
self.layer = layer
self.dragging = False
self.feature_s = None
self.start_point = None
def activate(self):
self.canvas.setCursor(Qt.CrossCursor)
def deactivate(self):
self.canvas.setCursor(Qt.ArrowCursor)
def canvasPressEvent(self, e):
if e.button() == Qt.LeftButton:
point = self.toMapCoordinates(e.pos())
features = self.layer.selectedFeatures()
for feature in features:
if feature:
self.feature_s = feature
self.start_point = point
self.dragging = True
e.accept()
feature = self.feature_s
geometry = feature.geometry()
if geometry.type():
parts = geometry.asMultiPolygon()
# 创建一个空列表,用于存储单独的Polygon
polygons = []
# 遍历各个部分并将其转换为Polygon
for part in parts:
polygon = QgsGeometry.fromPolygonXY(part)
polygons.append(polygon)
polygon = polygons[0].asPolygon()
self.closest_vertex_index = self.getClosestVertexIndex(polygon, point)
def canvasReleaseEvent(self, e):
if self.dragging:
self.dragging = False
e.accept()
def canvasMoveEvent(self, e):
if self.dragging:
current_point = self.toMapCoordinates(e.pos())
delta = current_point - self.start_point
self.layer.startEditing()
feature = self.feature_s
geometry = feature.geometry()
if geometry.type():
parts = geometry.asMultiPolygon()
if geometry.type()==2:
parts = geometry.asMultiPolygon()
# 创建一个空列表,用于存储单独的Polygon
polygons = []
# 遍历各个部分并将其转换为Polygon
for part in parts:
polygon = QgsGeometry.fromPolygonXY(part)
polygons.append(polygon)
polygon = polygons[0].asPolygon()
else:
polygon=geometry.asPolygon()
closest_vertex_index = self.closest_vertex_index
polygon[0][closest_vertex_index] = QgsPointXY(current_point)
new_geometry = QgsGeometry.fromPolygonXY(polygon)
self.layer.changeGeometry(feature.id(), new_geometry)
self.start_point = current_point
self.layer.commitChanges()
def getClosestFeature(self, point):
for feature in self.layer.getFeatures():
if feature.geometry().nearestPoint(point) == point:
return feature
return None
def getClosestVertexIndex(self, vertices, point):
closest_vertex_index = None
min_distance = float('inf')
for verticess in vertices:
for i, vertex in enumerate(verticess):
distance = point.distance(vertex)
if distance < min_distance:
min_distance = distance
closest_vertex_index = i
return closest_vertex_index
主要定义了一个工具类,利用工具类中的鼠标点击和移动函数,对需要编辑的矢量进行捕获和移动。
3.踩坑
需要注意,在QT中选中的图标文件路径是基于当前路径(qt文件所在路径的相对位置),而主函数中工作路径可能为上一级路径。
进度条需要将主窗体传入函数中实现。