Skip to content

Commit

Permalink
Merge branch 'maptool_filter_geometry' into 'main'
Browse files Browse the repository at this point in the history
maptool_filter_geometry

Closes #4

See merge request qgis/hvbg-filterplugin!9
  • Loading branch information
pgipper committed Nov 14, 2022
2 parents 2fdf704 + 1f7ffaa commit fd6a243
Show file tree
Hide file tree
Showing 4 changed files with 94 additions and 13 deletions.
4 changes: 2 additions & 2 deletions controller.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from typing import Iterable, Optional
from typing import Iterable, Optional, List

from PyQt5.QtCore import pyqtSignal, QObject
from qgis.core import QgsProject, QgsMapLayer, QgsMapLayerType, QgsWkbTypes, QgsGeometry, QgsCoordinateReferenceSystem
Expand All @@ -12,7 +12,7 @@

class FilterController(QObject):
currentFilter: Optional[FilterDefinition]
rubberBands: Optional[Iterable[QgsRubberBand]]
rubberBands: Optional[List[QgsRubberBand]]

filterChanged = pyqtSignal(FilterDefinition)

Expand Down
59 changes: 59 additions & 0 deletions maptool.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
from qgis.gui import QgsMapTool, QgsRubberBand
from qgis.core import QgsGeometry, QgsWkbTypes
from qgis.utils import iface

from PyQt5.QtCore import Qt, QPoint, pyqtSignal


class PolygonTool(QgsMapTool):
sketchFinished = pyqtSignal(QgsGeometry)

def __init__(self):
self.rubberBand = None
self.canvas = iface.mapCanvas()
super().__init__(self.canvas)

def reset(self):
if self.rubberBand:
self.rubberBand.reset()
self.canvas.scene().removeItem(self.rubberBand)
self.rubberBand = None

def canvasPressEvent(self, event):
pass

def canvasReleaseEvent(self, event):
x = event.pos().x()
y = event.pos().y()
thisPoint = QPoint(x, y)

mapToPixel = self.canvas.getCoordinateTransform() # QgsMapToPixel instance

if event.button() == Qt.LeftButton:
if not self.rubberBand:
self.rubberBand = QgsRubberBand(self.canvas, geometryType=QgsWkbTypes.PolygonGeometry)
self.rubberBand.setLineStyle(Qt.DashLine)
self.rubberBand.setWidth(2)
self.rubberBand.addPoint(mapToPixel.toMapCoordinates(thisPoint))

elif event.button() == Qt.RightButton:
if self.rubberBand and self.rubberBand.numberOfVertices() > 3:
# Finish rubberband sketch
self.rubberBand.removeLastPoint()
geometry = self.rubberBand.asGeometry()
self.sketchFinished.emit(geometry)
self.reset()
self.canvas.refresh()

def canvasMoveEvent(self, event):
if not self.rubberBand:
return
x = event.pos().x()
y = event.pos().y()
thisPoint = QPoint(x, y)
mapToPixel = self.canvas.getCoordinateTransform()
self.rubberBand.movePoint(self.rubberBand.numberOfVertices() - 1, mapToPixel.toMapCoordinates(thisPoint))

def deactivate(self):
self.reset()
QgsMapTool.deactivate(self)
2 changes: 1 addition & 1 deletion pb_tool.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ plugin_path:

[files]
# Python files that should be deployed with the plugin
python_files: __init__.py map_filter.py widgets.py models.py controller.py filters.py helpers.py settings.py
python_files: __init__.py map_filter.py widgets.py models.py controller.py filters.py helpers.py settings.py maptool.py

# The main dialog file that is loaded (not compiled)
main_dialog:
Expand Down
42 changes: 32 additions & 10 deletions widgets.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@
)
from qgis.gui import QgsExtentWidget, QgsRubberBand
from qgis.core import (
QgsMessageLog,
Qgis,
QgsApplication,
QgsGeometry,
QgsProject,
Expand All @@ -29,6 +31,7 @@
)
from qgis.utils import iface

from .maptool import PolygonTool
from .helpers import removeFilterFromLayer, setLayerException, hasLayerException, addFilterToLayer
from .controller import FilterController
from .models import FilterModel, LayerModel, DataRole
Expand Down Expand Up @@ -249,8 +252,8 @@ def setupUi(self):

self.toggleVisibilityAction = QAction(self)
visibilityIcon = QIcon()
pixmapOn = QgsApplication.getThemeIcon("/mActionHideAllLayers.svg").pixmap(self.iconSize())
pixmapOff = QgsApplication.getThemeIcon("/mActionShowAllLayers.svg").pixmap(self.iconSize())
pixmapOn = QgsApplication.getThemeIcon("/mActionShowAllLayers.svg").pixmap(self.iconSize())
pixmapOff = QgsApplication.getThemeIcon("/mActionHideAllLayers.svg").pixmap(self.iconSize())
visibilityIcon.addPixmap(pixmapOn, QIcon.Normal, QIcon.On)
visibilityIcon.addPixmap(pixmapOff, QIcon.Normal, QIcon.Off)
self.toggleVisibilityAction.setIcon(visibilityIcon)
Expand All @@ -264,10 +267,15 @@ def setupUi(self):
self.addAction(self.filterFromExtentAction)

self.filterFromSelectionAction = QAction(self)
self.filterFromSelectionAction.setIcon(QgsApplication.getThemeIcon('/mActionAddPolygon.svg'))
self.filterFromSelectionAction.setIcon(QgsApplication.getThemeIcon('/mActionSelectFreehand.svg'))
self.filterFromSelectionAction.setToolTip(self.tr('Filter from selected features'))
self.addAction(self.filterFromSelectionAction)

self.sketchingToolAction = QAction(self)
self.sketchingToolAction.setIcon(QgsApplication.getThemeIcon('/mActionAddPolygon.svg'))
self.sketchingToolAction.setToolTip(self.tr('Draw a filter polygon on the canvas'))
self.addAction(self.sketchingToolAction)

self.predicateButton = PredicateButton(self)
self.predicateButton.setIconSize(self.iconSize())
self.addWidget(self.predicateButton)
Expand Down Expand Up @@ -297,6 +305,7 @@ def setupConnections(self):
self.filterFromSelectionAction.triggered.connect(self.controller.setFilterFromSelection)
self.controller.filterChanged.connect(self.onFilterChanged)
self.toggleVisibilityAction.toggled.connect(self.onShowGeom)
self.sketchingToolAction.triggered.connect(self.startSketchingTool)

def onToggled(self, checked: bool):
self.controller.onToggled(checked)
Expand Down Expand Up @@ -337,22 +346,17 @@ def startManageFiltersDialog(self):
dlg.exec()

def onShowGeom(self, checked: bool):

self.showGeomStatus = checked

if checked:
tooltip = self.tr('Hide filter geometry')
self.removeFilterGeom()
self.drawFilterGeom()

self.showFilterGeom()
else:
tooltip = self.tr('Show filter geometry')
self.removeFilterGeom()

self.toggleVisibilityAction.setToolTip(tooltip)


def drawFilterGeom(self):
def showFilterGeom(self):
# Get filterRubberBand geometry, transform it and show it on canvas
filterRubberBand = QgsRubberBand(iface.mapCanvas(), QgsWkbTypes.PolygonGeometry)
filterWkt = self.controller.currentFilter.wkt
Expand All @@ -373,3 +377,21 @@ def removeFilterGeom(self):
while self.controller.rubberBands:
rubberBand = self.controller.rubberBands.pop()
iface.mapCanvas().scene().removeItem(rubberBand)

def startSketchingTool(self):
self.mapTool = PolygonTool()
self.mapTool.sketchFinished.connect(self.onSketchFinished)
iface.mapCanvas().setMapTool(self.mapTool)

def stopSketchingTool(self):
iface.mapCanvas().unsetMapTool(self.mapTool)
self.mapTool.deactivate()

def onSketchFinished(self, geometry: QgsGeometry):
self.stopSketchingTool()
if not geometry.isGeosValid():
QgsMessageLog.logMessage(self.tr("Geometry is not valid"), "FilterPlugin", level=Qgis.Warning)
return
self.controller.currentFilter.wkt = geometry.asWkt()
self.controller.currentFilter.crs = QgsProject.instance().crs()
self.controller.refreshFilter()

0 comments on commit fd6a243

Please sign in to comment.