diff --git a/controller.py b/controller.py index 8b261fa..db13aad 100644 --- a/controller.py +++ b/controller.py @@ -9,7 +9,7 @@ from .settings import FILTER_COMMENT -class Controller(QObject): +class FilterController(QObject): currentFilter: Optional[FilterDefinition] filterChanged = pyqtSignal(FilterDefinition) @@ -25,7 +25,7 @@ def onToggled(self, checked: bool) -> None: return self.updateProjectLayers(checked) - def udpateConnectionProjectLayersAdded(self, checked): + def updateConnectionProjectLayersAdded(self, checked): self.disconnectProjectLayersAdded() if checked: QgsProject.instance().layersAdded.connect(self.onLayersAdded) @@ -40,7 +40,7 @@ def onLayersAdded(self, layers: Iterable[QgsMapLayer]): if not self.currentFilter.isValid: return for layer in getPostgisLayers(layers): - filterCondition = self.currentFilter.filterString(getLayerGeomName(layer)) + filterCondition = self.currentFilter.filterString(layer) filterString = f'{FILTER_COMMENT}{filterCondition}' layer.setSubsetString(filterString) @@ -53,7 +53,7 @@ def updateLayerFilters(self, checked: bool): refreshLayerTree() def updateProjectLayers(self, checked): - self.udpateConnectionProjectLayersAdded(checked) + self.updateConnectionProjectLayersAdded(checked) self.updateLayerFilters(checked) def refreshFilter(self): @@ -73,9 +73,7 @@ def setFilterFromSelection(self): iface.messageBar().pushInfo('', self.tr('No features selected')) return crs = iface.activeLayer().crs() - geom = QgsGeometry.fromWkt('GEOMETRYCOLLECTION()') - for feature in layer.selectedFeatures(): - geom = geom.combine(feature.geometry()) + geom = QgsGeometry().collectGeometry([feature.geometry() for feature in layer.selectedFeatures()]) self.currentFilter.srsid = crs.srsid() self.currentFilter.wkt = geom.asWkt() diff --git a/filters.py b/filters.py index 82f8bd6..aeef5d6 100644 --- a/filters.py +++ b/filters.py @@ -4,10 +4,10 @@ from PyQt5.QtCore import QObject from PyQt5.QtWidgets import QMessageBox -from qgis.core import QgsGeometry, QgsCoordinateReferenceSystem +from qgis.core import QgsVectorLayer, QgsGeometry, QgsCoordinateReferenceSystem from qgis.utils import iface -from .helpers import saveValue, readValue, allValues, removeValue +from .helpers import saveSettingsValue, readSettingsValue, allSettingsValues, removeSettingsValue, getLayerGeomName SPLIT_CHAR = '#' @@ -41,13 +41,15 @@ def crs(self) -> QgsCoordinateReferenceSystem: def geometry(self) -> QgsGeometry: return QgsGeometry.fromWkt(self.wkt) - def filterString(self, geom_name) -> str: - template = "ST_{predicate}(ST_TRANSFORM({geom_name}, {srid}), ST_GeomFromText('{wkt}', {srid}))" + def filterString(self, layer: QgsVectorLayer) -> str: + template = "ST_{predicate}({geom_name}, ST_TRANSFORM(ST_GeomFromText('{wkt}', {srid}), {layer_srid}))" + geom_name = getLayerGeomName(layer) return template.format( predicate=Predicate(self.predicate).name, geom_name=geom_name, wkt=self.wkt, - srid=self.crs.postgisSrid() + srid=self.crs.postgisSrid(), + layer_srid=layer.crs().postgisSrid() ) @property @@ -64,7 +66,7 @@ def isValid(self) -> bool: @property def isSaved(self) -> bool: - return self.storageString == readValue(self.name) + return self.storageString == readSettingsValue(self.name) class FilterManager(QObject): @@ -73,11 +75,11 @@ def __init__(self, parent: Optional[QObject] = None) -> None: @staticmethod def loadFilterDefinition(name: str) -> FilterDefinition: - return FilterDefinition.fromStorageString(readValue(name)) + return FilterDefinition.fromStorageString(readSettingsValue(name)) @staticmethod def loadAllFilterDefinitions() -> List[FilterDefinition]: - return [FilterDefinition.fromStorageString(value) for value in allValues()] + return [FilterDefinition.fromStorageString(value) for value in allSettingsValues()] def saveFilterDefinition(self, filterDef: FilterDefinition) -> None: if not filterDef.isValid: @@ -88,14 +90,14 @@ def saveFilterDefinition(self, filterDef: FilterDefinition) -> None: return if filterDef.isSaved: return - if readValue(filterDef.name): + if readSettingsValue(filterDef.name): if not self.askOverwrite(filterDef.name): return - saveValue(filterDef.name, filterDef.storageString) + saveSettingsValue(filterDef.name, filterDef.storageString) def deleteFilterDefinition(self, filterDef: FilterDefinition) -> None: if self.askDelete(filterDef.name): - removeValue(filterDef.name) + removeSettingsValue(filterDef.name) def askApply(self) -> bool: txt = self.tr('Current settings will be lost. Apply anyway?') diff --git a/helpers.py b/helpers.py index fb1f54f..70a1185 100644 --- a/helpers.py +++ b/helpers.py @@ -5,14 +5,14 @@ from .settings import GROUP, FILTER_COMMENT -def saveValue(key: str, value: Any): +def saveSettingsValue(key: str, value: Any): settings = QgsSettings() settings.beginGroup(GROUP) settings.setValue(key, value) settings.endGroup() -def readValue(key: str, defaultValue: Any = None) -> Any: +def readSettingsValue(key: str, defaultValue: Any = None) -> Any: settings = QgsSettings() settings.beginGroup(GROUP) value = settings.value(key, defaultValue) @@ -20,7 +20,7 @@ def readValue(key: str, defaultValue: Any = None) -> Any: return value -def allValues(defaultValue: Any = None) -> List[Any]: +def allSettingsValues(defaultValue: Any = None) -> List[Any]: settings = QgsSettings() settings.beginGroup(GROUP) values = [settings.value(key, defaultValue) for key in settings.allKeys()] @@ -28,7 +28,7 @@ def allValues(defaultValue: Any = None) -> List[Any]: return values -def removeValue(key: str) -> None: +def removeSettingsValue(key: str) -> None: settings = QgsSettings() settings.beginGroup(GROUP) settings.remove(key) @@ -63,7 +63,7 @@ def addFilterToLayer(layer: QgsVectorLayer, filterDef: 'FilterDefinition'): removeFilterFromLayer(layer) currentFilter = layer.subsetString() connect = " AND " if currentFilter else "" - newFilter = f'{currentFilter}{FILTER_COMMENT}{connect}{filterDef.filterString(getLayerGeomName(layer))}' + newFilter = f'{currentFilter}{FILTER_COMMENT}{connect}{filterDef.filterString(layer)}' layer.setSubsetString(newFilter) diff --git a/map_filter.py b/map_filter.py index 03fb8b6..8e88281 100644 --- a/map_filter.py +++ b/map_filter.py @@ -25,7 +25,7 @@ import os.path -from .controller import Controller +from .controller import FilterController from .widgets import FilterToolbar @@ -43,7 +43,7 @@ def __init__(self, iface): QCoreApplication.installTranslator(self.translator) def initGui(self): - self.toolbar = FilterToolbar(Controller(), self.iface.mainWindow()) + self.toolbar = FilterToolbar(FilterController(), self.iface.mainWindow()) self.iface.mainWindow().addToolBar(self.toolbar) def unload(self): diff --git a/widgets.py b/widgets.py index 8b753b8..66e960c 100644 --- a/widgets.py +++ b/widgets.py @@ -21,13 +21,13 @@ from qgis.core import QgsApplication, QgsGeometry, QgsProject from qgis.utils import iface -from .controller import Controller +from .controller import FilterController from .models import FilterModel, DataRole from .filters import Predicate, FilterManager, FilterDefinition class ExtentDialog(QDialog): - def __init__(self, controller: Controller, parent: Optional[QWidget] = None) -> None: + def __init__(self, controller: FilterController, parent: Optional[QWidget] = None) -> None: super().__init__(parent=parent) self.controller = controller self.setObjectName("mExtentDialog") @@ -172,7 +172,7 @@ def setCurrentAction(self, predicate: int): class FilterToolbar(QToolBar): - def __init__(self, controller: Controller, parent: Optional[QWidget] = None) -> None: + def __init__(self, controller: FilterController, parent: Optional[QWidget] = None) -> None: super().__init__(parent=parent) self.controller = controller self.setWindowTitle(self.tr('Filter Toolbar'))