diff --git a/.dev/setup_dev_linux.sh b/.dev/setup_dev_linux.sh index 0fb74bda5..7e4ae43ac 100755 --- a/.dev/setup_dev_linux.sh +++ b/.dev/setup_dev_linux.sh @@ -1,3 +1,3 @@ #!/usr/bin/env bash -ln -s ${PWD}/../DsgTools ~/.local/share/QGIS/QGIS3/profiles/default/python/plugins/DsgTools \ No newline at end of file +ln -s ${PWD}/../DsgTools ~/.local/share/QGIS/QGIS3/profiles/default/python/plugins/DsgTools diff --git a/.dev/setup_dev_macos.sh b/.dev/setup_dev_macos.sh index 437403264..055a16155 100755 --- a/.dev/setup_dev_macos.sh +++ b/.dev/setup_dev_macos.sh @@ -1,3 +1,3 @@ #!/usr/bin/env bash -ln -s ${PWD}/../DsgTools ~/Library/Application\ Support/QGIS/QGIS3/profiles/default/python/plugins/DsgTools \ No newline at end of file +ln -s ${PWD}/../DsgTools ~/Library/Application\ Support/QGIS/QGIS3/profiles/default/python/plugins/DsgTools diff --git a/.dev/setup_dev_windows.bat b/.dev/setup_dev_windows.bat index 03c500a2a..b1f46da1c 100644 --- a/.dev/setup_dev_windows.bat +++ b/.dev/setup_dev_windows.bat @@ -1,4 +1,4 @@ @echo off set "_updir=%~dp0" for %%a in ("%_updir:~0,-1%") do set "_dir=%%~dpa" -mklink /D %HOMEDRIVE%%HOMEPATH%\AppData\Roaming\QGIS\QGIS3\profiles\default\python\plugins\DsgTools %_dir%DsgTools \ No newline at end of file +mklink /D %HOMEDRIVE%%HOMEPATH%\AppData\Roaming\QGIS\QGIS3\profiles\default\python\plugins\DsgTools %_dir%DsgTools diff --git a/.docker/docker-compose.yml b/.docker/docker-compose.yml index d7fcaf7dd..1f3899a8f 100644 --- a/.docker/docker-compose.yml +++ b/.docker/docker-compose.yml @@ -10,4 +10,4 @@ services: - ../tests:/tests_directory/tests environment: # - DISPLAY=unix$DISPLAY - - DISPLAY=:99 \ No newline at end of file + - DISPLAY=:99 diff --git a/.docker/exec.sh b/.docker/exec.sh index 29138085f..7670e4f55 100755 --- a/.docker/exec.sh +++ b/.docker/exec.sh @@ -4,4 +4,4 @@ docker exec -t dsgtools-testing-env sh -c "cd /tests_directory && qgis_testrunne docker exec -t dsgtools-testing-env sh -c "cd /tests_directory && qgis_testrunner.sh tests.test_EnvironmentSetterAlgorithms" docker exec -t dsgtools-testing-env sh -c "cd /tests_directory && qgis_testrunner.sh tests.test_CustomButtonSetup" docker exec -t dsgtools-testing-env sh -c "cd /tests_directory && qgis_testrunner.sh tests.test_DsgToolsProcessingModel" -docker exec -t dsgtools-testing-env sh -c "cd /tests_directory && qgis_testrunner.sh tests.test_OtherAlgorithms" \ No newline at end of file +docker exec -t dsgtools-testing-env sh -c "cd /tests_directory && qgis_testrunner.sh tests.test_OtherAlgorithms" diff --git a/.docker/start.sh b/.docker/start.sh index 328a7a836..8ebbbd7c7 100755 --- a/.docker/start.sh +++ b/.docker/start.sh @@ -8,4 +8,4 @@ docker exec -t dsgtools-testing-env sh -c "qgis_setup.sh DsgTools" docker exec -t dsgtools-testing-env sh -c "rm -f /root/.local/share/QGIS/QGIS3/profiles/default/python/plugins/DsgTools" docker exec -t dsgtools-testing-env sh -c "ln -s /tests_directory/ /root/.local/share/QGIS/QGIS3/profiles/default/python/plugins/DsgTools" docker exec -t dsgtools-testing-env sh -c "apt update && apt install -y libqt5sql5-psql libqt5sql5-sqlite" -echo 'Containers are running' \ No newline at end of file +echo 'Containers are running' diff --git a/.docker/stop.sh b/.docker/stop.sh index 0262b8338..3ca70187c 100755 --- a/.docker/stop.sh +++ b/.docker/stop.sh @@ -2,4 +2,4 @@ echo 'Stopping/killing containers' docker-compose kill -docker-compose rm -f \ No newline at end of file +docker-compose rm -f diff --git a/.github/workflows/test_plugin_on_qgis.yml b/.github/workflows/test_plugin_on_qgis.yml index caaa2e053..df92f107a 100644 --- a/.github/workflows/test_plugin_on_qgis.yml +++ b/.github/workflows/test_plugin_on_qgis.yml @@ -24,4 +24,4 @@ jobs: - name: Tests run: ./exec.sh - name: Stop the environment - run: docker-compose down + run: docker-compose down diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 000000000..9f7d40ccf --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,11 @@ +repos: +- repo: https://github.com/pre-commit/pre-commit-hooks + rev: v4.3.0 + hooks: + - id: check-yaml + - id: end-of-file-fixer + - id: trailing-whitespace +- repo: https://github.com/psf/black + rev: 22.6.0 + hooks: + - id: black diff --git a/.qgis-plugin-ci b/.qgis-plugin-ci index 4ed8d54b2..a7106095c 100644 --- a/.qgis-plugin-ci +++ b/.qgis-plugin-ci @@ -1,4 +1,4 @@ plugin_path: DsgTools github_organization_slug: dsgoficial project_slug: DsgTools -changelog_include: True \ No newline at end of file +changelog_include: True diff --git a/CHANGELOG.md b/CHANGELOG.md index 486b108f2..88ef56a71 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,41 @@ # CHANGELOG +## 4.7.0 + +Novas funcionalidades: +- Novo processo de selecionar feições no canvas de camadas selecionadas; +- Novo processo de filtrar lista de camadas no processing por tipo geométrico; +- Novo processo de remover holes pequenos de camadas de cobertura; +- Novo processo de dissolver polígonos para vizinhos (heurística pelo maior comprimento da intersecção); +- Novo processo de construir grid de pontos dentro de polígonos; +- Novo processo de dividir polígonos; +- Novo processo de dividir polígonos por grid; +- Novo processo de selecionar por DE9IM; +- Novo processo de extrair feições por DE9IM; +- Processo de converter linha para multilinha portado do ferramentas experimentais; + +Melhorias: +- Adicionada a opção de dar pan na barra de ferramentas de revisão; +- Adicionada mudanca de ferramenta atual nos icones das ferramentas de filtro; +- Processing de construção do diagrama de elevação portado para o Ferramentas de Edição; +- Adicionado o comportamento no seletor genérico de selecionar somente na camada ativa quando a tecla Alt estiver selecionada; +- Adicionada a opção de rodar a construção de polígonos por polígono de área geográfica (por MI); +- Melhoria de desempenho na construção de polígonos (adicionado paralelismo em thread); +- Melhoria de desempenho na verificação de delimitadores não utilizados no processo de construção de polígonos; +- Adicionada a opção de verificar ou não delimitadores não utilizados no processo de construção de polígonos; +- Melhoria de desempenho na identificação de erros de construção do terreno (roda em thread por área geográfica); +- A ferramenta de verificação de erros de relacionamentos espaciais agora permite regras com de9im e relacionamentos espaciais simultaneamente; +- Adicionada a opção de desligar todas as imagens ativas na ferramenta de seleção de raster; +- Adicionado o id da geometria na flag do identificar geometrias inválidas; +- O menu de aquisição agora permite reclassificação de polígono para ponto (particularmente útil quando se está corrigindo flags de áreas sem centroide na construção de polígonos utilizando linha e centroide); + + +Correção de bug: +- Corrigido o bug de sempre apontar flags quando a geometria tem buraco do processo de identificar geometrias com densidade incorreta de vértices; +- Correção de bug no processo de adicionar vértice em segmento compartilhado; +- Correção de bug no processo de dissolver polígonos com mesmo conjunto de atributos quando é passada uma área mínima para o dissolve; +- Correção de bug no acesso ao BDGEx (a url do serviço mudou e o código teve de ser atualizado, mudando a url do serviço de https para http); + ## 4.6.0 Novas funcionalidades: diff --git a/Dockerfile b/Dockerfile index ab5cf2502..fd3a7d9a3 100644 --- a/Dockerfile +++ b/Dockerfile @@ -7,4 +7,4 @@ RUN mkdir /tests_directory && \ ln -s /tests_directory/DsgTools/ /root/.local/share/QGIS/QGIS3/profiles/default/python/plugins/DsgTools ENV PYTHONPATH=/usr/share/qgis/python/:/usr/lib/python2.7/dist-packages/qgis:/usr/lib/python3/dist-packages/qgis:/usr/share/qgis/python/qgis:/usr/share/qgis/python/qgis/python/:/usr/share/qgis/python/qgis/python/plugins/:/root/.local/share/QGIS/QGIS3/profiles/default/:/root/.local/share/QGIS/QGIS3/profiles/default/python/:/root/.local/share/QGIS/QGIS3/profiles/default/python/plugins/:/root/.local/share/QGIS/QGIS3/profiles/default/python/plugins/DsgTools -CMD ["/usr/bin/supervisord", "-c", "/etc/supervisor/supervisord.conf"] \ No newline at end of file +CMD ["/usr/bin/supervisord", "-c", "/etc/supervisor/supervisord.conf"] diff --git a/DsgTools/Modules/acquisitionMenu/controllers/acquisitionMenuCtrl.py b/DsgTools/Modules/acquisitionMenu/controllers/acquisitionMenuCtrl.py index ec4acdeec..9d404b8be 100644 --- a/DsgTools/Modules/acquisitionMenu/controllers/acquisitionMenuCtrl.py +++ b/DsgTools/Modules/acquisitionMenu/controllers/acquisitionMenuCtrl.py @@ -2,21 +2,18 @@ from PyQt5 import QtCore, uic, QtWidgets, QtGui from DsgTools.Modules.qgis.controllers.qgisCtrl import QgisCtrl import json +from qgis.core import QgsWkbTypes + class AcquisitionMenuCtrl: - - def __init__( - self, - qgis=QgisCtrl(), - widgetFactory=WidgetFactory() - ): + def __init__(self, qgis=QgisCtrl(), widgetFactory=WidgetFactory()): self.qgis = qgis self.widgetFactory = widgetFactory self.menuDock = None self.menuEditor = None self.addMenuTab = None self.addMenuButton = None - self.reclassifyDialog = None + self.reclassifyDialog = None self.ignoreSignal = False self.connectQgisSignals() @@ -24,59 +21,59 @@ def unloadPlugin(self): self.disconnectQgisSignals() def connectQgisSignals(self): - self.qgis.connectSignal( 'StartAddFeature', self.deactiveMenu ) - self.qgis.connectSignal( 'ClickLayerTreeView', self.deactiveMenu ) - self.qgis.connectSignal( 'AddLayerTreeView', self.deactiveMenu ) - self.qgis.connectSignal( 'StartEditing', self.deactiveMenu ) + self.qgis.connectSignal("StartAddFeature", self.deactiveMenu) + self.qgis.connectSignal("ClickLayerTreeView", self.deactiveMenu) + self.qgis.connectSignal("AddLayerTreeView", self.deactiveMenu) + self.qgis.connectSignal("StartEditing", self.deactiveMenu) def disconnectQgisSignals(self): - self.qgis.disconnectSignal( 'StartAddFeature', self.deactiveMenu ) - self.qgis.disconnectSignal( 'ClickLayerTreeView', self.deactiveMenu ) - self.qgis.disconnectSignal( 'AddLayerTreeView', self.deactiveMenu ) - self.qgis.disconnectSignal( 'StartEditing', self.deactiveMenu ) + self.qgis.disconnectSignal("StartAddFeature", self.deactiveMenu) + self.qgis.disconnectSignal("ClickLayerTreeView", self.deactiveMenu) + self.qgis.disconnectSignal("AddLayerTreeView", self.deactiveMenu) + self.qgis.disconnectSignal("StartEditing", self.deactiveMenu) def openMenuEditor(self): if not self.menuEditor: - self.menuEditor = self.widgetFactory.createWidget( 'MenuEditorDialog', self ) - self.menuEditor.setMenuWidget( self.getMenuWidget() ) - self.menuEditor.setTabEditorWidget( self.getTabEditorWidget() ) - self.menuEditor.setButtonEditorWidget( self.getButtonEditorWidget() ) + self.menuEditor = self.widgetFactory.createWidget("MenuEditorDialog", self) + self.menuEditor.setMenuWidget(self.getMenuWidget()) + self.menuEditor.setTabEditorWidget(self.getTabEditorWidget()) + self.menuEditor.setButtonEditorWidget(self.getButtonEditorWidget()) self.menuEditor.showTopLevel() def getMenuWidget(self): - return self.widgetFactory.createWidget( 'MenuWidget', self ) + return self.widgetFactory.createWidget("MenuWidget", self) def getTabEditorWidget(self): - return self.widgetFactory.createWidget( 'TabEditorWidget', self ) + return self.widgetFactory.createWidget("TabEditorWidget", self) def getButtonEditorWidget(self): - return self.widgetFactory.createWidget( 'ButtonEditorWidget', self ) + return self.widgetFactory.createWidget("ButtonEditorWidget", self) def getAttributeTableWidget(self): - return self.widgetFactory.createWidget( 'AttributeTableWidget', self ) + return self.widgetFactory.createWidget("AttributeTableWidget", self) def getFilterComboBoxWidget(self): - return self.widgetFactory.createWidget( 'FilterComboBox', self ) - + return self.widgetFactory.createWidget("FilterComboBox", self) + def openAddTabDialog(self, callback): - self.addMenuTab = self.widgetFactory.createWidget( 'AddTabDialog', self ) + self.addMenuTab = self.widgetFactory.createWidget("AddTabDialog", self) self.addMenuTab.showTopLevel() - self.addMenuTab.setCallback( callback ) + self.addMenuTab.setCallback(callback) def openEditTabDialog(self, tabData, callback): - self.addMenuTab = self.widgetFactory.createWidget( 'AddTabDialog', self ) - self.addMenuTab.setData( tabData ) + self.addMenuTab = self.widgetFactory.createWidget("AddTabDialog", self) + self.addMenuTab.setData(tabData) self.addMenuTab.showTopLevel() - self.addMenuTab.setCallback( callback ) + self.addMenuTab.setCallback(callback) def addTabMenuEditor(self, tabId, tabName): - self.menuEditor.addPreviewTab( tabId, tabName ) + self.menuEditor.addPreviewTab(tabId, tabName) def updateTabMenuEditor(self, tabId, tabName): - self.menuEditor.updatePreviewTab( tabId, tabName ) - + self.menuEditor.updatePreviewTab(tabId, tabName) + def deleteTabMenuEditor(self, tabId): - self.menuEditor.deletePreviewTab( tabId ) + self.menuEditor.deletePreviewTab(tabId) def getTabNamesMenuEditor(self): return self.menuEditor.getPreviewTabNames() @@ -85,160 +82,174 @@ def openAddButtonDialog(self, callback): tabNames = self.getTabNamesMenuEditor() layerNames = self.getLoadedVectorLayerNames() if not tabNames: - raise Exception( 'Adicione uma aba primeiro!' ) + raise Exception("Adicione uma aba primeiro!") if not layerNames: - raise Exception( 'Adicione uma camada primeiro!' ) - self.addMenuButton = self.widgetFactory.createWidget( 'AddButtonDialog', self ) - self.addMenuButton.setAttributeTableWidget( self.getAttributeTableWidget() ) - self.addMenuButton.setTabComboWidget( self.getFilterComboBoxWidget() ) - self.addMenuButton.setToolComboWidget( self.getFilterComboBoxWidget() ) - self.addMenuButton.setLayerComboWidget( self.getFilterComboBoxWidget() ) - self.addMenuButton.setTabNames( tabNames ) - self.addMenuButton.setLayerNames( layerNames ) - self.addMenuButton.setToolNames( self.qgis.getAcquisitionToolNames() ) + raise Exception("Adicione uma camada primeiro!") + self.addMenuButton = self.widgetFactory.createWidget("AddButtonDialog", self) + self.addMenuButton.setAttributeTableWidget(self.getAttributeTableWidget()) + self.addMenuButton.setTabComboWidget(self.getFilterComboBoxWidget()) + self.addMenuButton.setToolComboWidget(self.getFilterComboBoxWidget()) + self.addMenuButton.setLayerComboWidget(self.getFilterComboBoxWidget()) + self.addMenuButton.setTabNames(tabNames) + self.addMenuButton.setLayerNames(layerNames) + self.addMenuButton.setToolNames(self.qgis.getAcquisitionToolNames()) self.addMenuButton.showTopLevel() - self.addMenuButton.setCallback( callback ) + self.addMenuButton.setCallback(callback) def openEditButtonDialog(self, buttonConfig, callback): tabNames = self.getTabNamesMenuEditor() layerNames = self.getLoadedVectorLayerNames() if not tabNames: - raise Exception( 'Adicione uma aba primeiro!' ) + raise Exception("Adicione uma aba primeiro!") if not layerNames: - raise Exception( 'Adicione uma camada primeiro!' ) - self.addMenuButton = self.widgetFactory.createWidget( 'AddButtonDialog', self ) - self.addMenuButton.setAttributeTableWidget( self.getAttributeTableWidget() ) - self.addMenuButton.setTabComboWidget( self.getFilterComboBoxWidget() ) - self.addMenuButton.setToolComboWidget( self.getFilterComboBoxWidget() ) - self.addMenuButton.setLayerComboWidget( self.getFilterComboBoxWidget() ) - self.addMenuButton.setTabNames( tabNames ) - self.addMenuButton.setLayerNames( layerNames ) - self.addMenuButton.setToolNames( self.qgis.getAcquisitionToolNames() ) - self.addMenuButton.setData( buttonConfig ) + raise Exception("Adicione uma camada primeiro!") + self.addMenuButton = self.widgetFactory.createWidget("AddButtonDialog", self) + self.addMenuButton.setAttributeTableWidget(self.getAttributeTableWidget()) + self.addMenuButton.setTabComboWidget(self.getFilterComboBoxWidget()) + self.addMenuButton.setToolComboWidget(self.getFilterComboBoxWidget()) + self.addMenuButton.setLayerComboWidget(self.getFilterComboBoxWidget()) + self.addMenuButton.setTabNames(tabNames) + self.addMenuButton.setLayerNames(layerNames) + self.addMenuButton.setToolNames(self.qgis.getAcquisitionToolNames()) + self.addMenuButton.setData(buttonConfig) self.addMenuButton.showTopLevel() - self.addMenuButton.setCallback( callback ) + self.addMenuButton.setCallback(callback) def openCloneButtonDialog(self, buttonConfig, callback): tabNames = self.getTabNamesMenuEditor() layerNames = self.getLoadedVectorLayerNames() if not tabNames: - raise Exception( 'Adicione uma aba primeiro!' ) + raise Exception("Adicione uma aba primeiro!") if not layerNames: - raise Exception( 'Adicione uma camada primeiro!' ) - self.addMenuButton = self.widgetFactory.createWidget( 'AddButtonDialog', self ) - self.addMenuButton.setAttributeTableWidget( self.getAttributeTableWidget() ) - self.addMenuButton.setTabComboWidget( self.getFilterComboBoxWidget() ) - self.addMenuButton.setToolComboWidget( self.getFilterComboBoxWidget() ) - self.addMenuButton.setLayerComboWidget( self.getFilterComboBoxWidget() ) - self.addMenuButton.setTabNames( tabNames ) - self.addMenuButton.setLayerNames( layerNames ) - self.addMenuButton.setToolNames( self.qgis.getAcquisitionToolNames() ) - buttonConfig['buttonId'] = None - buttonConfig['buttonName'] = '' - self.addMenuButton.setData( buttonConfig ) + raise Exception("Adicione uma camada primeiro!") + self.addMenuButton = self.widgetFactory.createWidget("AddButtonDialog", self) + self.addMenuButton.setAttributeTableWidget(self.getAttributeTableWidget()) + self.addMenuButton.setTabComboWidget(self.getFilterComboBoxWidget()) + self.addMenuButton.setToolComboWidget(self.getFilterComboBoxWidget()) + self.addMenuButton.setLayerComboWidget(self.getFilterComboBoxWidget()) + self.addMenuButton.setTabNames(tabNames) + self.addMenuButton.setLayerNames(layerNames) + self.addMenuButton.setToolNames(self.qgis.getAcquisitionToolNames()) + buttonConfig["buttonId"] = None + buttonConfig["buttonName"] = "" + self.addMenuButton.setData(buttonConfig) self.addMenuButton.showTopLevel() - self.addMenuButton.setCallback( callback ) + self.addMenuButton.setCallback(callback) def addButtonMenuEditor(self, buttonConfig, callback): - self.menuEditor.addButtonPreviewMenu( buttonConfig, callback ) + self.menuEditor.addButtonPreviewMenu(buttonConfig, callback) def updateButtonMenuEditor(self, newButtonConfig, oldButtonConfig, callback): - self.menuEditor.updateButtonPreviewMenu( newButtonConfig, oldButtonConfig, callback) + self.menuEditor.updateButtonPreviewMenu( + newButtonConfig, oldButtonConfig, callback + ) def deleteButtonMenuEditor(self, buttonConfig): - self.menuEditor.deleteButtonPreviewMenu( buttonConfig ) + self.menuEditor.deleteButtonPreviewMenu(buttonConfig) def getLoadedVectorLayerNames(self): return self.qgis.getLoadedVectorLayerNames() def getAttributesConfigByLayerName(self, layerName): - return self.qgis.getAttributesConfigByLayerName( layerName ) + return self.qgis.getAttributesConfigByLayerName(layerName) def createMenuDock(self, menuConfigs): self.removeMenuDock() - self.menuDock = self.widgetFactory.createWidget( 'MenuDock', self ) - self.menuDock.setMenuWidget( self.getMenuWidget() ) - self.menuDock.loadMenus( menuConfigs ) - self.qgis.addDockWidget( self.menuDock ) + self.menuDock = self.widgetFactory.createWidget("MenuDock", self) + self.menuDock.setMenuWidget(self.getMenuWidget()) + self.menuDock.loadMenus(menuConfigs) + self.qgis.addDockWidget(self.menuDock) def removeMenuDock(self): - self.qgis.removeDockWidget( self.menuDock ) if self.menuDock else '' + self.qgis.removeDockWidget(self.menuDock) if self.menuDock else "" def openReclassifyDialog(self, buttonConfig, callback): - layers = self.qgis.getVectorLayersByName( buttonConfig['buttonLayer'] ) + layers = self.qgis.getVectorLayersByName(buttonConfig["buttonLayer"]) if not layers: - raise Exception('Camada não encontrada!') - if len( layers ) > 1: - raise Exception('Há camadas repetidas!') + raise Exception("Camada não encontrada!") + if len(layers) > 1: + raise Exception("Há camadas repetidas!") layer = layers[0] - layerName = layer.dataProvider().uri().table() - layersToReclassification = self.getLayersForReclassification( - layerName, - layer.geometryType() + layerName = layer.dataProvider().uri().table() if layer.providerType() == "postgres" else layer.name() + layersToReclassification = self.getLayersForReclassification( + layerName, layer.geometryType() ) if not layersToReclassification: return if self.reclassifyDialog: self.reclassifyDialog.close() - self.reclassifyDialog = self.widgetFactory.createWidget( 'ReclassifyDialog', self ) - self.reclassifyDialog.setAttributeTableWidget( self.getAttributeTableWidget() ) - self.reclassifyDialog.loadAttributes( self.getAttributesConfigByLayerName( buttonConfig['buttonLayer'] ) ) - self.reclassifyDialog.setAttributesValues( buttonConfig['buttonAttributes'] ) - self.reclassifyDialog.loadLayersStatus( layersToReclassification ) - self.reclassifyDialog.success.connect( callback ) + self.reclassifyDialog = self.widgetFactory.createWidget( + "ReclassifyDialog", self + ) + self.reclassifyDialog.setAttributeTableWidget(self.getAttributeTableWidget()) + self.reclassifyDialog.loadAttributes( + self.getAttributesConfigByLayerName(buttonConfig["buttonLayer"]) + ) + self.reclassifyDialog.setAttributesValues(buttonConfig["buttonAttributes"]) + self.reclassifyDialog.loadLayersStatus(layersToReclassification) + self.reclassifyDialog.success.connect(callback) self.reclassifyDialog.showTopLevel() def reclassify(self, buttonConfig, reclassifyData): - destinatonLayerName = buttonConfig['buttonLayer'] - destinatonLayer = self.qgis.getVectorLayerByName( destinatonLayerName ) - selectedLayers = reclassifyData['layers'] - attributes = reclassifyData['attributes'] - layerNames = self.qgis.getVectorLayerNames( selectedLayers ) + destinatonLayerName = buttonConfig["buttonLayer"] + destinatonLayer = self.qgis.getVectorLayerByName(destinatonLayerName) + selectedLayers = reclassifyData["layers"] + attributes = reclassifyData["attributes"] + layerNames = self.qgis.getVectorLayerNames(selectedLayers) for layerName, layer in zip(layerNames, selectedLayers): if destinatonLayerName == layerName: - self.qgis.attributeSelectedFeatures( layer, attributes ) + self.qgis.attributeSelectedFeatures(layer, attributes) else: - self.qgis.cutAndPasteSelectedFeatures( layer, destinatonLayer, attributes ) - + self.qgis.cutAndPasteSelectedFeatures( + layer, destinatonLayer, attributes + ) + def getLayersForReclassification(self, layerName, geometryType): layers = self.qgis.getLoadedVectorLayers() + geometryFilterDict = { + QgsWkbTypes.PointGeometry: (QgsWkbTypes.PointGeometry), + QgsWkbTypes.LineGeometry: (QgsWkbTypes.LineGeometry), + QgsWkbTypes.PolygonGeometry: (QgsWkbTypes.PointGeometry, QgsWkbTypes.PolygonGeometry) + } return [ l for l in layers - if l.geometryType() == geometryType and l.selectedFeatureCount() > 0 + if l.selectedFeatureCount() > 0 and l.geometryType() in geometryFilterDict[l.geometryType()] ] def activeMenuButton(self, buttonConfig): self.disconnectQgisSignals() - layers = self.qgis.getVectorLayersByName( buttonConfig['buttonLayer'] ) + layers = self.qgis.getVectorLayersByName(buttonConfig["buttonLayer"]) if not layers: - raise Exception('Camada não encontrada!') - if len( layers ) > 1: - raise Exception('Há camadas repetidas!') + raise Exception("Camada não encontrada!") + if len(layers) > 1: + raise Exception("Há camadas repetidas!") layer = layers[0] self.ignoreSignal = True - self.qgis.setActiveLayer( layer ) + self.qgis.setActiveLayer(layer) self.ignoreSignal = False - attributesBackup = self.qgis.getLayerVariable( layer, 'attributesBackupV1' ) + attributesBackup = self.qgis.getLayerVariable(layer, "attributesBackupV1") if attributesBackup: - attributesBackup = json.loads( attributesBackup ) + attributesBackup = json.loads(attributesBackup) else: - attributesBackup = self.qgis.getDefaultFields( layer ) - self.qgis.suppressLayerForm( layer, buttonConfig['buttonSuppressForm'] ) - self.qgis.setDefaultFields( layer, buttonConfig['buttonAttributes'] ) - self.qgis.setLayerVariable( layer, 'attributesBackupV1', json.dumps( attributesBackup ) ) - toolName = buttonConfig['buttonAcquisitionTool'] - self.startToolByName( buttonConfig['buttonAcquisitionTool'] ) if toolName else '' + attributesBackup = self.qgis.getDefaultFields(layer) + self.qgis.suppressLayerForm(layer, buttonConfig["buttonSuppressForm"]) + self.qgis.setDefaultFields(layer, buttonConfig["buttonAttributes"]) + self.qgis.setLayerVariable( + layer, "attributesBackupV1", json.dumps(attributesBackup) + ) + toolName = buttonConfig["buttonAcquisitionTool"] + self.startToolByName(buttonConfig["buttonAcquisitionTool"]) if toolName else "" self.connectQgisSignals() def deactiveMenuButton(self, buttonConfig): - layers = self.qgis.getVectorLayersByName( buttonConfig['buttonLayer'] ) + layers = self.qgis.getVectorLayersByName(buttonConfig["buttonLayer"]) for layer in layers: - self.qgis.suppressLayerForm( layer, False ) - attributesBackup = self.qgis.getLayerVariable( layer, 'attributesBackupV1' ) + self.qgis.suppressLayerForm(layer, False) + attributesBackup = self.qgis.getLayerVariable(layer, "attributesBackupV1") if not attributesBackup: continue - self.qgis.setDefaultFields( layer, json.loads( attributesBackup ), reset=True ) + self.qgis.setDefaultFields(layer, json.loads(attributesBackup), reset=True) def deactiveMenu(self): if not self.menuDock: @@ -248,9 +259,7 @@ def deactiveMenu(self): buttonConfig = self.menuDock.getCurrentButtonConfig() if not buttonConfig: return - self.deactiveMenuButton( buttonConfig ) + self.deactiveMenuButton(buttonConfig) def startToolByName(self, name): - self.qgis.startToolByName( name ) - - + self.qgis.startToolByName(name) diff --git a/DsgTools/Modules/acquisitionMenu/factories/menuEditorDialogSingleton.py b/DsgTools/Modules/acquisitionMenu/factories/menuEditorDialogSingleton.py index 349aca55f..8b5236aa2 100644 --- a/DsgTools/Modules/acquisitionMenu/factories/menuEditorDialogSingleton.py +++ b/DsgTools/Modules/acquisitionMenu/factories/menuEditorDialogSingleton.py @@ -1,4 +1,5 @@ -from DsgTools.Modules.acquisitionMenu.widgets.menuEditorDialog import MenuEditorDialog +from DsgTools.Modules.acquisitionMenu.widgets.menuEditorDialog import MenuEditorDialog + class MenuEditorDialogSingleton: @@ -7,5 +8,5 @@ class MenuEditorDialogSingleton: @staticmethod def getInstance(controller): if not MenuEditorDialogSingleton.instance: - MenuEditorDialogSingleton.instance = MenuEditorDialog( controller ) - return MenuEditorDialogSingleton.instance \ No newline at end of file + MenuEditorDialogSingleton.instance = MenuEditorDialog(controller) + return MenuEditorDialogSingleton.instance diff --git a/DsgTools/Modules/acquisitionMenu/factories/widgetFactory.py b/DsgTools/Modules/acquisitionMenu/factories/widgetFactory.py index 3203c0d92..e9126d93e 100644 --- a/DsgTools/Modules/acquisitionMenu/factories/widgetFactory.py +++ b/DsgTools/Modules/acquisitionMenu/factories/widgetFactory.py @@ -1,27 +1,45 @@ from DsgTools.Modules.acquisitionMenu.widgets.menuWidget import MenuWidget from DsgTools.Modules.acquisitionMenu.widgets.tabEditorWidget import TabEditorWidget -from DsgTools.Modules.acquisitionMenu.widgets.buttonEditorWidget import ButtonEditorWidget -from DsgTools.Modules.acquisitionMenu.factories.menuEditorDialogSingleton import MenuEditorDialogSingleton +from DsgTools.Modules.acquisitionMenu.widgets.buttonEditorWidget import ( + ButtonEditorWidget, +) +from DsgTools.Modules.acquisitionMenu.factories.menuEditorDialogSingleton import ( + MenuEditorDialogSingleton, +) from DsgTools.Modules.acquisitionMenu.widgets.addTabDialog import AddTabDialog from DsgTools.Modules.acquisitionMenu.widgets.addButtonDialog import AddButtonDialog from DsgTools.Modules.acquisitionMenu.widgets.customComboBox import CustomComboBox -from DsgTools.Modules.acquisitionMenu.widgets.attributeTableWidget import AttributeTableWidget +from DsgTools.Modules.acquisitionMenu.widgets.attributeTableWidget import ( + AttributeTableWidget, +) from DsgTools.Modules.acquisitionMenu.widgets.menuDock import MenuDock from DsgTools.Modules.acquisitionMenu.widgets.reclassifyDialog import ReclassifyDialog -class WidgetFactory: +class WidgetFactory: def createWidget(self, widgetName, controller): widgetNames = { - 'MenuEditorDialog': lambda controller: MenuEditorDialogSingleton.getInstance( controller ), - 'MenuWidget': lambda controller: MenuWidget(controller=controller), - 'TabEditorWidget': lambda controller: TabEditorWidget(controller=controller), - 'ButtonEditorWidget': lambda controller: ButtonEditorWidget(controller=controller), - 'AddTabDialog': lambda controller: AddTabDialog(controller=controller), - 'AddButtonDialog': lambda controller: AddButtonDialog(controller=controller), - 'FilterComboBox': lambda controller: CustomComboBox(), - 'AttributeTableWidget': lambda controller: AttributeTableWidget(controller=controller), - 'MenuDock': lambda controller: MenuDock(controller=controller), - 'ReclassifyDialog': lambda controller: ReclassifyDialog(controller=controller) + "MenuEditorDialog": lambda controller: MenuEditorDialogSingleton.getInstance( + controller + ), + "MenuWidget": lambda controller: MenuWidget(controller=controller), + "TabEditorWidget": lambda controller: TabEditorWidget( + controller=controller + ), + "ButtonEditorWidget": lambda controller: ButtonEditorWidget( + controller=controller + ), + "AddTabDialog": lambda controller: AddTabDialog(controller=controller), + "AddButtonDialog": lambda controller: AddButtonDialog( + controller=controller + ), + "FilterComboBox": lambda controller: CustomComboBox(), + "AttributeTableWidget": lambda controller: AttributeTableWidget( + controller=controller + ), + "MenuDock": lambda controller: MenuDock(controller=controller), + "ReclassifyDialog": lambda controller: ReclassifyDialog( + controller=controller + ), } - return widgetNames[ widgetName ]( controller ) \ No newline at end of file + return widgetNames[widgetName](controller) diff --git a/DsgTools/Modules/acquisitionMenu/widgets/addButtonDialog.py b/DsgTools/Modules/acquisitionMenu/widgets/addButtonDialog.py index ea4e4d2ff..df161121c 100644 --- a/DsgTools/Modules/acquisitionMenu/widgets/addButtonDialog.py +++ b/DsgTools/Modules/acquisitionMenu/widgets/addButtonDialog.py @@ -3,15 +3,13 @@ from DsgTools.Modules.utils.factories.utilsFactory import UtilsFactory import uuid -class AddButtonDialog( QtWidgets.QDialog ): +class AddButtonDialog(QtWidgets.QDialog): def __init__( - self, - controller, - messageFactory=UtilsFactory().createMessageFactory() - ): + self, controller, messageFactory=UtilsFactory().createMessageFactory() + ): super(AddButtonDialog, self).__init__() - uic.loadUi( self.getUiPath(), self ) + uic.loadUi(self.getUiPath(), self) self.controller = controller self.messageFactory = messageFactory self.uuid = None @@ -23,17 +21,17 @@ def __init__( self.tabNames = [] self.toolNames = [] self.layerNames = [] - self.selectedBackgroundColor = '' - self.selectedTextColor = '' - self.previewBtn.setText('') - self.nameLe.textEdited.connect( self.previewBtn.setText ) + self.selectedBackgroundColor = "" + self.selectedTextColor = "" + self.previewBtn.setText("") + self.nameLe.textEdited.connect(self.previewBtn.setText) def showError(self, title, message): - errorMessageBox = self.messageFactory.createMessage('ErrorMessageBox') + errorMessageBox = self.messageFactory.createMessage("ErrorMessageBox") errorMessageBox.show(self, title, message) def showInfo(self, title, message): - infoMessageBox = self.messageFactory.createMessage('InfoMessageBox') + infoMessageBox = self.messageFactory.createMessage("InfoMessageBox") infoMessageBox.show(self, title, message) def getController(self): @@ -53,40 +51,40 @@ def getSelectedTextColor(self): def setAttributeTableWidget(self, attributeTableWidget): self.attributeTable = attributeTableWidget - self.attributeLayout.addWidget( attributeTableWidget ) - + self.attributeLayout.addWidget(attributeTableWidget) + def setTabComboWidget(self, tabComboWidget): self.tabCombo = tabComboWidget - self.tabListLayout.addWidget( tabComboWidget ) + self.tabListLayout.addWidget(tabComboWidget) def setTabNames(self, tabNames): self.tabNames = tabNames - self.tabCombo.loadItems( [ i['name'] for i in self.tabNames ] ) + self.tabCombo.loadItems([i["name"] for i in self.tabNames]) def setToolComboWidget(self, toolComboWidget): self.toolCombo = toolComboWidget - self.toolListLayout.addWidget( toolComboWidget ) + self.toolListLayout.addWidget(toolComboWidget) def setToolNames(self, toolNames): self.toolNames = toolNames self.toolCombo.clear() for toolName in self.toolNames: - self.toolCombo.addItem( toolName, self.toolNames[ toolName ] ) + self.toolCombo.addItem(toolName, self.toolNames[toolName]) def setLayerComboWidget(self, layerComboWidget): self.layerCombo = layerComboWidget - self.layerCombo.currentIndexChanged.connect( self.loadLayerAttribures ) - self.layerListLayout.addWidget( layerComboWidget ) + self.layerCombo.currentIndexChanged.connect(self.loadLayerAttribures) + self.layerListLayout.addWidget(layerComboWidget) def setLayerNames(self, layerNames): self.layerNames = layerNames - self.layerCombo.loadItems( layerNames ) + self.layerCombo.loadItems(layerNames) def setUUID(self, uuid): self.uuid = uuid def getUUID(self): - return self.uuid if self.uuid else str( uuid.uuid4() ) + return self.uuid if self.uuid else str(uuid.uuid4()) def showTopLevel(self): self.show() @@ -96,96 +94,128 @@ def showTopLevel(self): def getUiPath(self): return os.path.join( os.path.abspath(os.path.dirname(__file__)), - '..', - 'uis', - "addButtonDialog.ui" + "..", + "uis", + "addButtonDialog.ui", ) def setData(self, buttonConfig): - self.setUUID( buttonConfig['buttonId'] ) - self.nameLe.setText( buttonConfig['buttonName'] ) - self.tabCombo.setCurrentIndex( self.tabCombo.findText( buttonConfig['buttonTabName'] ) ) - self.toolCombo.setCurrentIndex( self.toolCombo.findData( buttonConfig['buttonAcquisitionTool'] ) ) - self.layerCombo.setCurrentIndex( self.layerCombo.findText( buttonConfig['buttonLayer'] ) ) - self.setSelectedBackgroundColor( buttonConfig['buttonBackgroundColor'] ) - self.backgroundColorBtn.setStyleSheet("QPushButton {background-color: rgb("+self.getSelectedBackgroundColor()+")}") - self.setSelectedTextColor( buttonConfig['buttonTextColor'] ) - self.textColorBtn.setStyleSheet("QPushButton {background-color: rgb("+self.getSelectedTextColor()+")}") - self.attributeTable.setAttributesValues( buttonConfig['buttonAttributes'] ) - self.keyWordsLe.setText( buttonConfig['buttonKeyWords'] ) - self.tooltipLe.setText( buttonConfig['buttonTooltip'] ) - self.suppressFormCkb.setChecked( buttonConfig['buttonSuppressForm'] ) - - self.previewBtn.setText( buttonConfig['buttonName'] ) - self.setColorPreviewButton( self.getSelectedTextColor(), self.getSelectedBackgroundColor() ) + self.setUUID(buttonConfig["buttonId"]) + self.nameLe.setText(buttonConfig["buttonName"]) + self.tabCombo.setCurrentIndex( + self.tabCombo.findText(buttonConfig["buttonTabName"]) + ) + self.toolCombo.setCurrentIndex( + self.toolCombo.findData(buttonConfig["buttonAcquisitionTool"]) + ) + self.layerCombo.setCurrentIndex( + self.layerCombo.findText(buttonConfig["buttonLayer"]) + ) + self.setSelectedBackgroundColor(buttonConfig["buttonBackgroundColor"]) + self.backgroundColorBtn.setStyleSheet( + "QPushButton {background-color: rgb(" + + self.getSelectedBackgroundColor() + + ")}" + ) + self.setSelectedTextColor(buttonConfig["buttonTextColor"]) + self.textColorBtn.setStyleSheet( + "QPushButton {background-color: rgb(" + self.getSelectedTextColor() + ")}" + ) + self.attributeTable.setAttributesValues(buttonConfig["buttonAttributes"]) + self.keyWordsLe.setText(buttonConfig["buttonKeyWords"]) + self.tooltipLe.setText(buttonConfig["buttonTooltip"]) + self.suppressFormCkb.setChecked(buttonConfig["buttonSuppressForm"]) + + self.previewBtn.setText(buttonConfig["buttonName"]) + self.setColorPreviewButton( + self.getSelectedTextColor(), self.getSelectedBackgroundColor() + ) def setColorPreviewButton(self, textColor, backgroundColor): - self.previewBtn.setStyleSheet( - '''background-color: rgb({0}); color: rgb({1});'''.format( - backgroundColor, - textColor - ) + self.previewBtn.setStyleSheet( + """background-color: rgb({0}); color: rgb({1});""".format( + backgroundColor, textColor + ) ) def getData(self): if not self.validData(): - raise Exception('Dados inválidos!') + raise Exception("Dados inválidos!") return { - 'buttonId': self.getUUID(), - 'buttonName': self.nameLe.text(), - 'buttonBackgroundColor': self.getSelectedBackgroundColor(), - 'buttonTextColor': self.getSelectedTextColor(), - 'buttonTabName': self.tabCombo.itemText( self.tabCombo.currentIndex() ), - 'buttonTabId': [ i['id'] for i in self.tabNames if i['name'] == self.tabCombo.itemText( self.tabCombo.currentIndex() ) ][0], - 'buttonAcquisitionTool': self.toolCombo.itemData( self.toolCombo.currentIndex() ), - 'buttonLayer': self.layerCombo.itemText( self.layerCombo.currentIndex() ), - 'buttonAttributes': self.attributeTable.getAttributes(), - 'buttonKeyWords': self.keyWordsLe.text(), - 'buttonTooltip': self.tooltipLe.text(), - 'buttonSuppressForm': self.suppressFormCkb.isChecked() + "buttonId": self.getUUID(), + "buttonName": self.nameLe.text(), + "buttonBackgroundColor": self.getSelectedBackgroundColor(), + "buttonTextColor": self.getSelectedTextColor(), + "buttonTabName": self.tabCombo.itemText(self.tabCombo.currentIndex()), + "buttonTabId": [ + i["id"] + for i in self.tabNames + if i["name"] == self.tabCombo.itemText(self.tabCombo.currentIndex()) + ][0], + "buttonAcquisitionTool": self.toolCombo.itemData( + self.toolCombo.currentIndex() + ), + "buttonLayer": self.layerCombo.itemText(self.layerCombo.currentIndex()), + "buttonAttributes": self.attributeTable.getAttributes(), + "buttonKeyWords": self.keyWordsLe.text(), + "buttonTooltip": self.tooltipLe.text(), + "buttonSuppressForm": self.suppressFormCkb.isChecked(), } def validData(self): - self.tabCombo.setStyleSheet( "" ) - self.toolCombo.setStyleSheet( "" ) - self.layerCombo.setStyleSheet( "" ) - self.nameLe.setStyleSheet( "" ) + self.tabCombo.setStyleSheet("") + self.toolCombo.setStyleSheet("") + self.layerCombo.setStyleSheet("") + self.nameLe.setStyleSheet("") if not self.nameLe.text(): - self.nameLe.setStyleSheet( "QLineEdit { border: 1px solid red; }" ) + self.nameLe.setStyleSheet("QLineEdit { border: 1px solid red; }") return False - if not( self.tabCombo.currentText() in [ i['name'] for i in self.tabNames ] ): - self.tabCombo.setStyleSheet( "QComboBox { border: 1px solid red; }" ) + if not (self.tabCombo.currentText() in [i["name"] for i in self.tabNames]): + self.tabCombo.setStyleSheet("QComboBox { border: 1px solid red; }") return False - if not( self.toolCombo.currentText() in self.toolNames ): - self.toolCombo.setStyleSheet( "QComboBox { border: 1px solid red; }" ) + if not (self.toolCombo.currentText() in self.toolNames): + self.toolCombo.setStyleSheet("QComboBox { border: 1px solid red; }") return False - if not( self.layerCombo.currentText() in self.layerNames ): - self.layerCombo.setStyleSheet( "QComboBox { border: 1px solid red; }" ) + if not (self.layerCombo.currentText() in self.layerNames): + self.layerCombo.setStyleSheet("QComboBox { border: 1px solid red; }") return False return True def loadLayerAttribures(self, index): - attrConfig = self.getController().getAttributesConfigByLayerName( self.layerCombo.itemText( index ) ) - self.attributeTable.loadAttributes( attrConfig ) + attrConfig = self.getController().getAttributesConfigByLayerName( + self.layerCombo.itemText(index) + ) + self.attributeTable.loadAttributes(attrConfig) @QtCore.pyqtSlot(bool) def on_backgroundColorBtn_clicked(self): - colorRgb = self.openColorDialog( self.getSelectedBackgroundColor() ) - self.setSelectedBackgroundColor( colorRgb ) - self.backgroundColorBtn.setStyleSheet("QPushButton {background-color: rgb("+colorRgb+")}") - self.setColorPreviewButton( self.getSelectedTextColor(), self.getSelectedBackgroundColor() ) + colorRgb = self.openColorDialog(self.getSelectedBackgroundColor()) + self.setSelectedBackgroundColor(colorRgb) + self.backgroundColorBtn.setStyleSheet( + "QPushButton {background-color: rgb(" + colorRgb + ")}" + ) + self.setColorPreviewButton( + self.getSelectedTextColor(), self.getSelectedBackgroundColor() + ) @QtCore.pyqtSlot(bool) def on_textColorBtn_clicked(self): - colorRgb = self.openColorDialog( self.getSelectedTextColor() ) - self.setSelectedTextColor( colorRgb ) - self.textColorBtn.setStyleSheet("QPushButton {background-color: rgb("+colorRgb+")}") - self.setColorPreviewButton( self.getSelectedTextColor(), self.getSelectedBackgroundColor() ) + colorRgb = self.openColorDialog(self.getSelectedTextColor()) + self.setSelectedTextColor(colorRgb) + self.textColorBtn.setStyleSheet( + "QPushButton {background-color: rgb(" + colorRgb + ")}" + ) + self.setColorPreviewButton( + self.getSelectedTextColor(), self.getSelectedBackgroundColor() + ) - def openColorDialog(self, colorRgb, ): + def openColorDialog( + self, + colorRgb, + ): colorDlg = QtWidgets.QColorDialog() if colorRgb: - r, g, b = colorRgb.split(',') + r, g, b = colorRgb.split(",") colorDlg.setCurrentColor(QtGui.QColor(int(r), int(g), int(b))) if not colorDlg.exec(): return @@ -201,11 +231,11 @@ def getCallback(self): @QtCore.pyqtSlot(bool) def on_saveBtn_clicked(self): if not self.validData(): - self.showError('Aviso', 'Dados inválidos') + self.showError("Aviso", "Dados inválidos") return self.accept() - self.getCallback()( self.getData() ) + self.getCallback()(self.getData()) @QtCore.pyqtSlot(bool) def on_cancelBtn_clicked(self): - self.reject() \ No newline at end of file + self.reject() diff --git a/DsgTools/Modules/acquisitionMenu/widgets/addTabDialog.py b/DsgTools/Modules/acquisitionMenu/widgets/addTabDialog.py index c462d8050..3fae76fb6 100644 --- a/DsgTools/Modules/acquisitionMenu/widgets/addTabDialog.py +++ b/DsgTools/Modules/acquisitionMenu/widgets/addTabDialog.py @@ -2,11 +2,11 @@ from PyQt5 import QtCore, uic, QtWidgets, QtGui import uuid -class AddTabDialog( QtWidgets.QDialog ): +class AddTabDialog(QtWidgets.QDialog): def __init__(self, controller): super(AddTabDialog, self).__init__() - uic.loadUi( self.getUiPath(), self ) + uic.loadUi(self.getUiPath(), self) self.controller = controller self.uuid = None self.callback = None @@ -18,7 +18,7 @@ def setUUID(self, uuid): self.uuid = uuid def getUUID(self): - return self.uuid if self.uuid else str( uuid.uuid4() ) + return self.uuid if self.uuid else str(uuid.uuid4()) def showTopLevel(self): self.show() @@ -27,21 +27,15 @@ def showTopLevel(self): def getUiPath(self): return os.path.join( - os.path.abspath(os.path.dirname(__file__)), - '..', - 'uis', - "addTabDialog.ui" + os.path.abspath(os.path.dirname(__file__)), "..", "uis", "addTabDialog.ui" ) def setData(self, tab): - self.setUUID( tab['id'] ) - self.tabNameLe.setText( tab['name'] ) + self.setUUID(tab["id"]) + self.tabNameLe.setText(tab["name"]) def getData(self): - return { - 'id': self.getUUID(), - 'name': self.tabNameLe.text() - } + return {"id": self.getUUID(), "name": self.tabNameLe.text()} def setCallback(self, callback): self.callback = callback @@ -52,8 +46,8 @@ def getCallback(self): @QtCore.pyqtSlot(bool) def on_saveBtn_clicked(self): self.accept() - self.getCallback()( self.getData() ) + self.getCallback()(self.getData()) @QtCore.pyqtSlot(bool) def on_cancelBtn_clicked(self): - self.reject() \ No newline at end of file + self.reject() diff --git a/DsgTools/Modules/acquisitionMenu/widgets/attributeTableWidget.py b/DsgTools/Modules/acquisitionMenu/widgets/attributeTableWidget.py index a536ed75c..9b3b0d498 100644 --- a/DsgTools/Modules/acquisitionMenu/widgets/attributeTableWidget.py +++ b/DsgTools/Modules/acquisitionMenu/widgets/attributeTableWidget.py @@ -2,48 +2,46 @@ from PyQt5 import QtCore, uic, QtWidgets, QtGui from DsgTools.Modules.utils.factories.utilsFactory import UtilsFactory -class AttributeTableWidget( QtWidgets.QWidget ): +class AttributeTableWidget(QtWidgets.QWidget): def __init__( - self, - controller, - messageFactory=UtilsFactory().createMessageFactory() - ): - super( AttributeTableWidget, self).__init__() - uic.loadUi( self.getUiPath(), self ) + self, controller, messageFactory=UtilsFactory().createMessageFactory() + ): + super(AttributeTableWidget, self).__init__() + uic.loadUi(self.getUiPath(), self) self.controller = controller self.messageFactory = messageFactory self.tableWidget.horizontalHeader().sortIndicatorOrder() self.tableWidget.setSortingEnabled(True) self.tableWidget.setColumnHidden(0, True) - + def getController(self): return self.controller def getUiPath(self): return os.path.join( os.path.abspath(os.path.dirname(__file__)), - '..', - 'uis', - "attributeTableWidget.ui" + "..", + "uis", + "attributeTableWidget.ui", ) def getSelectedRowData(self): rowsData = [] for item in self.tableWidget.selectionModel().selectedRows(): - rowsData.append( self.getRowData(item.row()) ) + rowsData.append(self.getRowData(item.row())) return rowsData def validateValue(self, value): if value is None: - return '' + return "" return str(value) def createNotEditableItem(self, value): item = QtWidgets.QTableWidgetItem(self.validateValue(value)) item.setFlags(QtCore.Qt.ItemIsEnabled | QtCore.Qt.ItemIsSelectable) return item - + def createEditableItem(self, value): item = QtWidgets.QTableWidgetItem(self.validateValue(value)) return item @@ -53,19 +51,19 @@ def searchRows(self, text): if text and not self.hasTextOnRow(idx, text): self.tableWidget.setRowHidden(idx, True) else: - self.tableWidget.setRowHidden(idx, False) + self.tableWidget.setRowHidden(idx, False) def showError(self, title, message): - errorMessageBox = self.messageFactory.createMessage('ErrorMessageBox') + errorMessageBox = self.messageFactory.createMessage("ErrorMessageBox") errorMessageBox.show(self, title, message) def showInfo(self, title, message): - infoMessageBox = self.messageFactory.createMessage('InfoMessageBox') + infoMessageBox = self.messageFactory.createMessage("InfoMessageBox") infoMessageBox.show(self, title, message) def clearAllItems(self): self.tableWidget.setRowCount(0) - + def adjustColumns(self): self.tableWidget.resizeColumnsToContents() @@ -73,8 +71,10 @@ def adjustRows(self): self.tableWidget.resizeRowsToContents() def removeSelected(self): - while self.tableWidget.selectionModel().selectedRows() : - self.tableWidget.removeRow(self.tableWidget.selectionModel().selectedRows()[0].row()) + while self.tableWidget.selectionModel().selectedRows(): + self.tableWidget.removeRow( + self.tableWidget.selectionModel().selectedRows()[0].row() + ) def hasTextOnRow(self, rowIdx, text): for colIdx in self.getColumnsIndexToSearch(): @@ -88,19 +88,19 @@ def getColumnsIndexToSearch(self): def createLineEdit(self): wd = QtWidgets.QWidget() - layout = QtWidgets.QHBoxLayout( wd ) - lineEdit = QtWidgets.QLineEdit( self.tableWidget ) - layout.addWidget( lineEdit ) + layout = QtWidgets.QHBoxLayout(wd) + lineEdit = QtWidgets.QLineEdit(self.tableWidget) + layout.addWidget(lineEdit) return wd def createComboBox(self, values): - data = { 'IGNORAR': None } - data.update( values ) + data = {"IGNORAR": None} + data.update(values) wd = QtWidgets.QWidget() - layout = QtWidgets.QHBoxLayout( wd ) + layout = QtWidgets.QHBoxLayout(wd) comboBox = self.getController().getFilterComboBoxWidget() - comboBox.loadItems( data ) - layout.addWidget( comboBox ) + comboBox.loadItems(data) + layout.addWidget(comboBox) return wd @QtCore.pyqtSlot(str) @@ -110,63 +110,59 @@ def on_searchLe_textEdited(self, text): def loadAttributes(self, attributesConfig): self.clearAllItems() for attributeName in attributesConfig: - if 'map' in attributesConfig[ attributeName ]: + if "map" in attributesConfig[attributeName]: widget = self.createComboBox( - self.formatMapValues(attributesConfig[ attributeName ]['map']) + self.formatMapValues(attributesConfig[attributeName]["map"]) ) else: widget = self.createLineEdit() - self.addRow( None, attributeName, widget ) + self.addRow(None, attributeName, widget) self.adjustColumns() self.adjustRows() def formatMapValues(self, mapValues): - if not(type(mapValues) is list): + if not (type(mapValues) is list): return mapValues newMapValues = {} for field in mapValues: newMapValues.update(field) return newMapValues - + def setAttributesValues(self, attributesValues): - attributeNames = [ key for key in attributesValues ] + attributeNames = [key for key in attributesValues] for rowIndex in range(self.tableWidget.rowCount()): attributeName = self.tableWidget.model().index(rowIndex, 1).data() - if not( attributeName in attributeNames ): + if not (attributeName in attributeNames): continue - attributeValue = attributesValues[ attributeName ] - widget = self.tableWidget.cellWidget(rowIndex, 2).layout().itemAt(0).widget() - if isinstance( widget, QtWidgets.QLineEdit ): - widget.setText( attributeValue ) + attributeValue = attributesValues[attributeName] + widget = ( + self.tableWidget.cellWidget(rowIndex, 2).layout().itemAt(0).widget() + ) + if isinstance(widget, QtWidgets.QLineEdit): + widget.setText(attributeValue) else: - widget.setCurrentIndex( widget.findText( attributeValue ) ) + widget.setCurrentIndex(widget.findText(attributeValue)) def getAttributes(self): attributes = {} - for row in self.getAllTableData(): - attributes[ row['attribute'] ] = row['value'] + for row in self.getAllTableData(): + attributes[row["attribute"]] = row["value"] return attributes - - def addRow(self, - attributeId, - attributeName, - widget - ): - idx = self.getRowIndex( attributeId ) + + def addRow(self, attributeId, attributeName, widget): + idx = self.getRowIndex(attributeId) if idx < 0: idx = self.tableWidget.rowCount() self.tableWidget.insertRow(idx) - self.tableWidget.setItem(idx, 0, self.createNotEditableItem( attributeId )) - self.tableWidget.setItem(idx, 1, self.createNotEditableItem( attributeName )) - self.tableWidget.setCellWidget(idx, 2, widget ) + self.tableWidget.setItem(idx, 0, self.createNotEditableItem(attributeId)) + self.tableWidget.setItem(idx, 1, self.createNotEditableItem(attributeName)) + self.tableWidget.setCellWidget(idx, 2, widget) def getRowIndex(self, tabId): if not tabId: return -1 for idx in range(self.tableWidget.rowCount()): - if not ( - tabId == self.tableWidget.model().index(idx, 0).data() - ): + if not (tabId == self.tableWidget.model().index(idx, 0).data()): continue return idx return -1 @@ -174,13 +170,17 @@ def getRowIndex(self, tabId): def getAllTableData(self): rowsData = [] for idx in range(self.tableWidget.rowCount()): - rowsData.append( self.getRowData(idx) ) + rowsData.append(self.getRowData(idx)) return rowsData def getRowData(self, rowIndex): widget = self.tableWidget.cellWidget(rowIndex, 2).layout().itemAt(0).widget() - value = widget.text() if isinstance( widget, QtWidgets.QLineEdit ) else widget.itemText( widget.currentIndex() ) + value = ( + widget.text() + if isinstance(widget, QtWidgets.QLineEdit) + else widget.itemText(widget.currentIndex()) + ) return { - 'attribute': self.tableWidget.model().index(rowIndex, 1).data(), - 'value': value + "attribute": self.tableWidget.model().index(rowIndex, 1).data(), + "value": value, } diff --git a/DsgTools/Modules/acquisitionMenu/widgets/buttonEditorWidget.py b/DsgTools/Modules/acquisitionMenu/widgets/buttonEditorWidget.py index d98ae1e5b..d509a364c 100644 --- a/DsgTools/Modules/acquisitionMenu/widgets/buttonEditorWidget.py +++ b/DsgTools/Modules/acquisitionMenu/widgets/buttonEditorWidget.py @@ -3,13 +3,10 @@ from .tableEditorWidget import TableEditorWidget import json -class ButtonEditorWidget( TableEditorWidget ): - def __init__( - self, - controller - ): - super( ButtonEditorWidget, self).__init__( controller=controller ) +class ButtonEditorWidget(TableEditorWidget): + def __init__(self, controller): + super(ButtonEditorWidget, self).__init__(controller=controller) self.tableWidget.setColumnHidden(0, True) self.tableWidget.setColumnHidden(1, True) self.tableWidget.setColumnHidden(3, True) @@ -19,101 +16,87 @@ def createEditRowWidget(self, row, col): layout = QtWidgets.QHBoxLayout(wd) index = QtCore.QPersistentModelIndex(self.tableWidget.model().index(row, col)) - editBtn = self.createTableToolButton( 'Editar', self.getEditIconPath() ) - editBtn.clicked.connect( - lambda *args, index=index: self.handleEditBtn(index) - ) + editBtn = self.createTableToolButton("Editar", self.getEditIconPath()) + editBtn.clicked.connect(lambda *args, index=index: self.handleEditBtn(index)) layout.addWidget(editBtn) - deleteBtn = self.createTableToolButton( 'Excluir', self.getDeleteIconPath() ) + deleteBtn = self.createTableToolButton("Excluir", self.getDeleteIconPath()) deleteBtn.clicked.connect( lambda *args, index=index: self.handleDeleteBtn(index) ) layout.addWidget(deleteBtn) - cloneBtn = self.createTableToolButton( 'Clonar', self.getCloneIconPath() ) - cloneBtn.clicked.connect( - lambda *args, index=index: self.handleCloneBtn(index) - ) + cloneBtn = self.createTableToolButton("Clonar", self.getCloneIconPath()) + cloneBtn.clicked.connect(lambda *args, index=index: self.handleCloneBtn(index)) layout.addWidget(cloneBtn) layout.setAlignment(QtCore.Qt.AlignCenter) - layout.setContentsMargins(0,0,0,0) + layout.setContentsMargins(0, 0, 0, 0) return wd def getCloneIconPath(self): return os.path.join( - os.path.abspath(os.path.dirname(__file__)), - '..', - 'icons', - "clone.png" + os.path.abspath(os.path.dirname(__file__)), "..", "icons", "clone.png" ) def handleEditBtn(self, index): - self.showEditButton( self.getRowData( index.row() ) ) - + self.showEditButton(self.getRowData(index.row())) + def handleDeleteBtn(self, index): try: - deletedButtonData = self.getRowData( index.row() ) - self.getController().deleteButtonMenuEditor( deletedButtonData ) - self.tableWidget.removeRow( index.row() ) + deletedButtonData = self.getRowData(index.row()) + self.getController().deleteButtonMenuEditor(deletedButtonData) + self.tableWidget.removeRow(index.row()) except Exception as e: - self.showError('Erro', str(e)) + self.showError("Erro", str(e)) def handleCloneBtn(self, index): self.getController().openCloneButtonDialog( - self.getRowData( index.row() ), - self.addButton + self.getRowData(index.row()), self.addButton ) def showEditButton(self, buttonConfig): try: self.getController().openEditButtonDialog( buttonConfig, - lambda data, oldData=buttonConfig, callback=self.showEditButton: self.updateButton( data, oldData, callback ) + lambda data, oldData=buttonConfig, callback=self.showEditButton: self.updateButton( + data, oldData, callback + ), ) except Exception as e: - self.showError('Erro', str(e)) - - def addRow(self, - buttonId, - buttonTab, - buttonName, - buttonConfig - ): - idx = self.getRowIndex( buttonId ) + self.showError("Erro", str(e)) + + def addRow(self, buttonId, buttonTab, buttonName, buttonConfig): + idx = self.getRowIndex(buttonId) if idx < 0: idx = self.tableWidget.rowCount() self.tableWidget.insertRow(idx) - self.tableWidget.setItem(idx, 0, self.createNotEditableItem( buttonId )) - self.tableWidget.setItem(idx, 1, self.createNotEditableItem( buttonTab )) - self.tableWidget.setItem(idx, 2, self.createNotEditableItem( buttonName )) - self.tableWidget.setItem(idx, 3, self.createNotEditableItem( json.dumps( buttonConfig ) )) - self.tableWidget.setCellWidget(idx, 4, self.createEditRowWidget(idx, 4) ) + self.tableWidget.setItem(idx, 0, self.createNotEditableItem(buttonId)) + self.tableWidget.setItem(idx, 1, self.createNotEditableItem(buttonTab)) + self.tableWidget.setItem(idx, 2, self.createNotEditableItem(buttonName)) + self.tableWidget.setItem( + idx, 3, self.createNotEditableItem(json.dumps(buttonConfig)) + ) + self.tableWidget.setCellWidget(idx, 4, self.createEditRowWidget(idx, 4)) self.adjustRows() - + def addRows(self, tabs): self.clearAllItems() - for tab in tabs: - self.addRow( - tab['id'], - tab['name'] - ) + for tab in tabs: + self.addRow(tab["id"], tab["name"]) self.adjustColumns() def getRowIndex(self, buttonId): if not buttonId: return -1 for idx in range(self.tableWidget.rowCount()): - if not ( - buttonId == self.tableWidget.model().index(idx, 0).data() - ): + if not (buttonId == self.tableWidget.model().index(idx, 0).data()): continue return idx return -1 def getRowData(self, rowIndex): - return json.loads( self.tableWidget.model().index(rowIndex, 3).data() ) + return json.loads(self.tableWidget.model().index(rowIndex, 3).data()) def getColumnsIndexToSearch(self): return [1] @@ -121,28 +104,31 @@ def getColumnsIndexToSearch(self): def getUiPath(self): return os.path.join( os.path.abspath(os.path.dirname(__file__)), - '..', - 'uis', - "buttonEditorWidget.ui" + "..", + "uis", + "buttonEditorWidget.ui", ) @QtCore.pyqtSlot(bool) def on_addBtn_clicked(self): try: - self.getController().openAddButtonDialog( self.addButton ) + self.getController().openAddButtonDialog(self.addButton) except Exception as e: - self.showError('Erro', str(e)) + self.showError("Erro", str(e)) def addButton(self, data): if not data: return - self.getController().addButtonMenuEditor( data, self.showEditButton ) - self.addRow( data['buttonId'], data['buttonTabName'], data['buttonName'], data ) + self.getController().addButtonMenuEditor(data, self.showEditButton) + self.addRow(data["buttonId"], data["buttonTabName"], data["buttonName"], data) def updateButton(self, newData, oldData, callback): if not newData: return - self.getController().updateButtonMenuEditor( newData, oldData, callback ) - self.addRow( newData['buttonId'], newData['buttonTabName'], newData['buttonName'], newData ) - - \ No newline at end of file + self.getController().updateButtonMenuEditor(newData, oldData, callback) + self.addRow( + newData["buttonId"], + newData["buttonTabName"], + newData["buttonName"], + newData, + ) diff --git a/DsgTools/Modules/acquisitionMenu/widgets/customComboBox.py b/DsgTools/Modules/acquisitionMenu/widgets/customComboBox.py index 689e9b12a..64e3c3450 100644 --- a/DsgTools/Modules/acquisitionMenu/widgets/customComboBox.py +++ b/DsgTools/Modules/acquisitionMenu/widgets/customComboBox.py @@ -3,45 +3,48 @@ from PyQt5 import QtGui -class CustomComboBox( QComboBox ): - def __init__( self, parent = None): - super( CustomComboBox, self ).__init__( parent ) - self.setFocusPolicy( Qt.StrongFocus ) - self.setEditable( True ) - self.completer = QCompleter( self ) - self.completer.setCompletionMode( QCompleter.UnfilteredPopupCompletion ) - self.pFilterModel = QSortFilterProxyModel( self ) - self.pFilterModel.setFilterCaseSensitivity( Qt.CaseInsensitive ) - self.completer.setPopup( self.view() ) - self.setCompleter( self.completer ) - self.lineEdit().textEdited.connect( self.pFilterModel.setFilterFixedString ) +class CustomComboBox(QComboBox): + def __init__(self, parent=None): + super(CustomComboBox, self).__init__(parent) + self.setFocusPolicy(Qt.StrongFocus) + self.setEditable(True) + self.completer = QCompleter(self) + self.completer.setCompletionMode(QCompleter.UnfilteredPopupCompletion) + self.pFilterModel = QSortFilterProxyModel(self) + self.pFilterModel.setFilterCaseSensitivity(Qt.CaseInsensitive) + self.completer.setPopup(self.view()) + self.setCompleter(self.completer) + self.lineEdit().textEdited.connect(self.pFilterModel.setFilterFixedString) self.completer.activated.connect(self.setTextIfCompleterIsClicked) def loadItems(self, items): self.items = items model = QtGui.QStandardItemModel() - [ model.setItem(i, 0, QtGui.QStandardItem(word)) for i, word in enumerate(self.items) ] + [ + model.setItem(i, 0, QtGui.QStandardItem(word)) + for i, word in enumerate(self.items) + ] self.setModel(model) self.setModelColumn(0) self.setInsertPolicy(QComboBox.NoInsert) - def setModel( self, model ): - super(CustomComboBox, self).setModel( model ) - self.pFilterModel.setSourceModel( model ) + def setModel(self, model): + super(CustomComboBox, self).setModel(model) + self.pFilterModel.setSourceModel(model) self.completer.setModel(self.pFilterModel) - def setModelColumn( self, column ): - self.completer.setCompletionColumn( column ) - self.pFilterModel.setFilterKeyColumn( column ) - super(CustomComboBox, self).setModelColumn( column ) + def setModelColumn(self, column): + self.completer.setCompletionColumn(column) + self.pFilterModel.setFilterKeyColumn(column) + super(CustomComboBox, self).setModelColumn(column) - def view( self ): + def view(self): return self.completer.popup() - def index( self ): + def index(self): return self.currentIndex() def setTextIfCompleterIsClicked(self, text): if text: index = self.findText(text) - self.setCurrentIndex(index) \ No newline at end of file + self.setCurrentIndex(index) diff --git a/DsgTools/Modules/acquisitionMenu/widgets/menuDock.py b/DsgTools/Modules/acquisitionMenu/widgets/menuDock.py index 6350b9ddd..9370def26 100644 --- a/DsgTools/Modules/acquisitionMenu/widgets/menuDock.py +++ b/DsgTools/Modules/acquisitionMenu/widgets/menuDock.py @@ -3,28 +3,26 @@ import json from DsgTools.Modules.utils.factories.utilsFactory import UtilsFactory -class MenuDock( QtWidgets.QDockWidget ): - + +class MenuDock(QtWidgets.QDockWidget): def __init__( - self, - controller, - messageFactory=UtilsFactory().createMessageFactory() - ): + self, controller, messageFactory=UtilsFactory().createMessageFactory() + ): super(MenuDock, self).__init__() - uic.loadUi( self.getUiPath(), self ) + uic.loadUi(self.getUiPath(), self) self.controller = controller self.menuWidget = None self.currentMenu = None self.currentButton = None self.messageFactory = messageFactory - self.menusCb.currentIndexChanged.connect( self.setCurrentMenu ) - + self.menusCb.currentIndexChanged.connect(self.setCurrentMenu) + def showError(self, title, message): - errorMessageBox = self.messageFactory.createMessage('ErrorMessageBox') + errorMessageBox = self.messageFactory.createMessage("ErrorMessageBox") errorMessageBox.show(self, title, message) def showInfo(self, title, message): - infoMessageBox = self.messageFactory.createMessage('InfoMessageBox') + infoMessageBox = self.messageFactory.createMessage("InfoMessageBox") infoMessageBox.show(self, title, message) def getController(self): @@ -32,25 +30,22 @@ def getController(self): def getUiPath(self): return os.path.join( - os.path.abspath(os.path.dirname(__file__)), - '..', - 'uis', - "menuDock.ui" + os.path.abspath(os.path.dirname(__file__)), "..", "uis", "menuDock.ui" ) def loadMenus(self, menuConfigs): self.menusCb.clear() for menuConfig in menuConfigs: - self.menusCb.addItem( menuConfig["menuName"], menuConfig ) + self.menusCb.addItem(menuConfig["menuName"], menuConfig) def setCurrentMenu(self, menuIndex): - self.currentMenu = self.menusCb.itemData( menuIndex ) - self.getMenuWidget().load( self.currentMenu, self.setCurrentButton ) + self.currentMenu = self.menusCb.itemData(menuIndex) + self.getMenuWidget().load(self.currentMenu, self.setCurrentButton) def setMenuWidget(self, menuWidget): self.menuWidget = menuWidget - self.menuLayout.addWidget( self.menuWidget ) - + self.menuLayout.addWidget(self.menuWidget) + def getMenuWidget(self): return self.menuWidget @@ -58,14 +53,14 @@ def setCurrentButton(self, buttonConfig): try: currentButton = self.getCurrentButtonConfig() if currentButton: - self.getController().deactiveMenuButton( currentButton ) - self.setCurrentButtonConfig( buttonConfig ) - self.getController().activeMenuButton( buttonConfig ) + self.getController().deactiveMenuButton(currentButton) + self.setCurrentButtonConfig(buttonConfig) + self.getController().activeMenuButton(buttonConfig) if not self.reclassifyCkb.isChecked(): return - self.getController().openReclassifyDialog( buttonConfig, self.reclassify ) + self.getController().openReclassifyDialog(buttonConfig, self.reclassify) except Exception as e: - self.showError('Erro', str(e)) + self.showError("Erro", str(e)) def getCurrentButtonConfig(self): return self.currentButton @@ -75,9 +70,9 @@ def setCurrentButtonConfig(self, buttonConfig): @QtCore.pyqtSlot(str) def on_searchButtonLe_textEdited(self, text): - self.getMenuWidget().searchButtons( text ) + self.getMenuWidget().searchButtons(text) def reclassify(self, reclassifyData): if not reclassifyData: return - self.getController().reclassify( self.getCurrentButtonConfig(), reclassifyData ) + self.getController().reclassify(self.getCurrentButtonConfig(), reclassifyData) diff --git a/DsgTools/Modules/acquisitionMenu/widgets/menuEditorDialog.py b/DsgTools/Modules/acquisitionMenu/widgets/menuEditorDialog.py index 994408cc8..00712b0ca 100644 --- a/DsgTools/Modules/acquisitionMenu/widgets/menuEditorDialog.py +++ b/DsgTools/Modules/acquisitionMenu/widgets/menuEditorDialog.py @@ -3,15 +3,13 @@ import json from DsgTools.Modules.utils.factories.utilsFactory import UtilsFactory -class MenuEditorDialog( QtWidgets.QDialog ): +class MenuEditorDialog(QtWidgets.QDialog): def __init__( - self, - controller, - messageFactory=UtilsFactory().createMessageFactory() - ): + self, controller, messageFactory=UtilsFactory().createMessageFactory() + ): super(MenuEditorDialog, self).__init__() - uic.loadUi( self.getUiPath(), self ) + uic.loadUi(self.getUiPath(), self) self.controller = controller self.messageFactory = messageFactory self.previewMenu.setAcceptDrops(True) @@ -24,8 +22,8 @@ def previewDragEnterEvent(self, e): def previewDropEvent(self, e): pos = e.pos() widget = e.source() - tabLayout = self.menuWidget.getTabLayout( widget.buttonConfig[ 'buttonTabId' ] ) - buttonIndexs = range(tabLayout.count()) + tabLayout = self.menuWidget.getTabLayout(widget.buttonConfig["buttonTabId"]) + buttonIndexs = range(tabLayout.count()) isUpper = widget.y() > pos.y() widgetIndex = None selectedIndex = None @@ -36,9 +34,13 @@ def previewDropEvent(self, e): widgetIndex = n continue if selectedY: - valid = ( isUpper and pos.y() < w.y() and w.y() < selectedY ) or ( not isUpper and pos.y() > w.y() and w.y() > selectedY ) + valid = (isUpper and pos.y() < w.y() and w.y() < selectedY) or ( + not isUpper and pos.y() > w.y() and w.y() > selectedY + ) else: - valid = ( isUpper and pos.y() < w.y() ) or ( not isUpper and pos.y() > w.y() ) + valid = (isUpper and pos.y() < w.y()) or ( + not isUpper and pos.y() > w.y() + ) if not valid: continue selectedIndex = n @@ -46,7 +48,9 @@ def previewDropEvent(self, e): if selectedIndex is None or widgetIndex is None: e.accept() return - if (isUpper and widgetIndex < selectedIndex) or (not isUpper and widgetIndex > selectedIndex): + if (isUpper and widgetIndex < selectedIndex) or ( + not isUpper and widgetIndex > selectedIndex + ): pass else: tabLayout.insertWidget(selectedIndex, widget) @@ -54,11 +58,11 @@ def previewDropEvent(self, e): e.accept() def showError(self, title, message): - errorMessageBox = self.messageFactory.createMessage('ErrorMessageBox') + errorMessageBox = self.messageFactory.createMessage("ErrorMessageBox") errorMessageBox.show(self, title, message) def showInfo(self, title, message): - infoMessageBox = self.messageFactory.createMessage('InfoMessageBox') + infoMessageBox = self.messageFactory.createMessage("InfoMessageBox") infoMessageBox.show(self, title, message) def getController(self): @@ -66,34 +70,34 @@ def getController(self): def clearLayout(self, layout): for idx in list(range(layout.count())): - item = layout.takeAt( idx ) + item = layout.takeAt(idx) widget = item.widget() if widget: widget.deleteLater() layout = item.layout() if layout: - self.clearLayout( layout ) + self.clearLayout(layout) del item def setMenuWidget(self, menuWidget): self.menuWidget = menuWidget self.menuWidget.setMovable(True) - self.menuLayout.addWidget( self.menuWidget ) + self.menuLayout.addWidget(self.menuWidget) def setTabEditorWidget(self, tabEditorWidget): self.tabEditorWidget = tabEditorWidget - self.tabLayout.addWidget( self.tabEditorWidget ) + self.tabLayout.addWidget(self.tabEditorWidget) def setButtonEditorWidget(self, buttonEditorWidget): self.buttonEditorWidget = buttonEditorWidget - self.buttonLayout.addWidget( self.buttonEditorWidget ) + self.buttonLayout.addWidget(self.buttonEditorWidget) def getUiPath(self): return os.path.join( os.path.abspath(os.path.dirname(__file__)), - '..', - 'uis', - "menuEditorDialog.ui" + "..", + "uis", + "menuEditorDialog.ui", ) def showTopLevel(self): @@ -102,76 +106,77 @@ def showTopLevel(self): self.activateWindow() def addPreviewTab(self, tabId, tabName): - self.menuWidget.addTabContainer( tabId, tabName ) + self.menuWidget.addTabContainer(tabId, tabName) def updatePreviewTab(self, tabId, tabName): - self.menuWidget.updateTabContainer( tabId, tabName ) + self.menuWidget.updateTabContainer(tabId, tabName) def deletePreviewTab(self, tabId): - self.menuWidget.deleteTabContainer( tabId ) + self.menuWidget.deleteTabContainer(tabId) def getPreviewTabNames(self): return self.menuWidget.getTabContainerNames() def addButtonPreviewMenu(self, buttonConfig, callback): - self.menuWidget.addButton( buttonConfig, callback) + self.menuWidget.addButton(buttonConfig, callback) def updateButtonPreviewMenu(self, newButtonConfig, oldButtonConfig, callback): - self.menuWidget.updateButton( newButtonConfig, oldButtonConfig, callback) + self.menuWidget.updateButton(newButtonConfig, oldButtonConfig, callback) def deleteButtonPreviewMenu(self, buttonConfig): - self.menuWidget.deleteButton( buttonConfig ) + self.menuWidget.deleteButton(buttonConfig) @QtCore.pyqtSlot(bool) def on_importMenuBtn_clicked(self): - filePath = QtWidgets.QFileDialog.getOpenFileName(self, - '', - "Desktop", - '*.json') + filePath = QtWidgets.QFileDialog.getOpenFileName(self, "", "Desktop", "*.json") if not filePath[0]: return - with open( filePath[0], 'r') as f: - menuConfig = json.load( f ) + with open(filePath[0], "r") as f: + menuConfig = json.load(f) menuName = menuConfig["menuName"] - self.menuNameLe.setText( menuName ) - self.menuWidget.setMenuName( menuName ) + self.menuNameLe.setText(menuName) + self.menuWidget.setMenuName(menuName) for tabData in menuConfig["setup"]: - self.tabEditorWidget.addRow( tabData['tabId'], tabData['tabName'] ) - self.menuWidget.addTabContainer( tabData['tabId'], tabData['tabName'] ) - for buttonData in tabData['tabButtons']: - self.buttonEditorWidget.addRow( buttonData['buttonId'], buttonData['buttonTabName'], buttonData['buttonName'], buttonData ) - self.menuWidget.addButton( buttonData, self.buttonEditorWidget.showEditButton ) + self.tabEditorWidget.addRow(tabData["tabId"], tabData["tabName"]) + self.menuWidget.addTabContainer(tabData["tabId"], tabData["tabName"]) + for buttonData in tabData["tabButtons"]: + self.buttonEditorWidget.addRow( + buttonData["buttonId"], + buttonData["buttonTabName"], + buttonData["buttonName"], + buttonData, + ) + self.menuWidget.addButton( + buttonData, self.buttonEditorWidget.showEditButton + ) @QtCore.pyqtSlot(bool) def on_exportMenuBtn_clicked(self): menuName = self.menuNameLe.text() if not menuName: - self.showError('Erro', 'Informe o nome do menu!') + self.showError("Erro", "Informe o nome do menu!") return filePath = QtWidgets.QFileDialog.getSaveFileName( - self, - '', - "{0}.json".format( menuName ), - '*.json' + self, "", "{0}.json".format(menuName), "*.json" ) if not filePath[0]: return - self.menuWidget.setMenuName( menuName ) - with open( filePath[0], 'w') as f: - json.dump( self.menuWidget.dump(), f ) + self.menuWidget.setMenuName(menuName) + with open(filePath[0], "w") as f: + json.dump(self.menuWidget.dump(), f) @QtCore.pyqtSlot(bool) def on_createMenuBtn_clicked(self): menuName = self.menuNameLe.text() if not menuName: - self.showError('Erro', 'Informe o nome do menu!') + self.showError("Erro", "Informe o nome do menu!") return - self.menuWidget.setMenuName( menuName ) - self.getController().createMenuDock( [ self.menuWidget.dump() ] ) + self.menuWidget.setMenuName(menuName) + self.getController().createMenuDock([self.menuWidget.dump()]) @QtCore.pyqtSlot(bool) def on_deleteMenuBtn_clicked(self): - self.menuWidget.setMenuName( "" ) + self.menuWidget.setMenuName("") self.menuWidget.clean() self.tabEditorWidget.clearAllItems() - self.buttonEditorWidget.clearAllItems() \ No newline at end of file + self.buttonEditorWidget.clearAllItems() diff --git a/DsgTools/Modules/acquisitionMenu/widgets/menuWidget.py b/DsgTools/Modules/acquisitionMenu/widgets/menuWidget.py index 8a2e5a176..29cd5c729 100644 --- a/DsgTools/Modules/acquisitionMenu/widgets/menuWidget.py +++ b/DsgTools/Modules/acquisitionMenu/widgets/menuWidget.py @@ -1,12 +1,9 @@ import os, sys, copy from PyQt5 import QtCore, uic, QtWidgets, QtGui -class MenuWidget( QtWidgets.QTabWidget ): - def __init__( - self, - controller - ): +class MenuWidget(QtWidgets.QTabWidget): + def __init__(self, controller): super(MenuWidget, self).__init__() self.controller = controller self.menuName = None @@ -16,90 +13,86 @@ def __init__( self.setElideMode(QtCore.Qt.ElideNone) self.setStyleSheet( "QTabBar::tab::disabled {width: 0; heigth: 0; margin: 0; padding: 0; border: none;}" - ) + ) def addTabContainer(self, tabId, tabName, tabIndex=1): tab = QtWidgets.QWidget() - tab.setObjectName( tabName ) + tab.setObjectName(tabName) tab.id = tabId layout_tab = QtWidgets.QVBoxLayout(tab) - layout_tab.setObjectName(u'area') + layout_tab.setObjectName("area") scroll = QtWidgets.QScrollArea(tab) scroll.setWidgetResizable(True) scroll_widget = QtWidgets.QWidget() scroll_widget.setGeometry(QtCore.QRect(0, 0, 328, 386)) - scroll_widget.setObjectName(u'scroll') + scroll_widget.setObjectName("scroll") layout_button = QtWidgets.QVBoxLayout(scroll_widget) - layout_button.setObjectName(u'layout') + layout_button.setObjectName("layout") scroll.setWidget(scroll_widget) layout_tab.addWidget(scroll) self.insertTab(tabIndex, tab, tabName) self.setCurrentIndex(0) - def updateTabContainer(self, tabId, tabName): - tabIndex = self.getTabIndexFromId( tabId ) - self.setTabText( tabIndex, tabName) + def updateTabContainer(self, tabId, tabName): + tabIndex = self.getTabIndexFromId(tabId) + self.setTabText(tabIndex, tabName) - def deleteTabContainer(self, tabId): - tabIndex = self.getTabIndexFromId( tabId ) + def deleteTabContainer(self, tabId): + tabIndex = self.getTabIndexFromId(tabId) if tabIndex is None: return """ if not self.emptyTab( tabIndex ): raise Exception('Aba com botões') """ - self.removeTab( tabIndex ) + self.removeTab(tabIndex) def getTabContainerNames(self): return [ - { - 'name': self.tabText( idx ), - 'id': self.widget( idx ).id - } - for idx in range(self.count()) + {"name": self.tabText(idx), "id": self.widget(idx).id} + for idx in range(self.count()) ] def getTabIndexFromId(self, tabId): for idx in range(self.count()): - tabWidget = self.widget( idx ) - if not( tabWidget.id == tabId ): + tabWidget = self.widget(idx) + if not (tabWidget.id == tabId): continue return idx def emptyTab(self, tabIndex): - tabWidget = self.widget( tabIndex ) - tabScroll = tabWidget.findChildren(QtWidgets.QScrollArea)[0].children()[0].children()[0] + tabWidget = self.widget(tabIndex) + tabScroll = ( + tabWidget.findChildren(QtWidgets.QScrollArea)[0].children()[0].children()[0] + ) tabLayout = tabScroll.children()[0] return tabLayout.count() == 0 def addButton(self, buttonConfig, callback): - tabLayout = self.getTabLayout( buttonConfig[ 'buttonTabId' ] ) + tabLayout = self.getTabLayout(buttonConfig["buttonTabId"]) button = QtWidgets.QPushButton() button.mouseMoveEvent = lambda e, b=button: self.buttonMouseMoveEvent(e, b) - button.id = buttonConfig['buttonId'] + button.id = buttonConfig["buttonId"] button.buttonConfig = buttonConfig - button.setStyleSheet( - '''background-color: rgb({0}); color: rgb({1});'''.format( - buttonConfig[ 'buttonBackgroundColor' ], - buttonConfig[ 'buttonTextColor' ] - ) + button.setStyleSheet( + """background-color: rgb({0}); color: rgb({1});""".format( + buttonConfig["buttonBackgroundColor"], buttonConfig["buttonTextColor"] + ) ) - buttonName = buttonConfig['buttonName'] - button.setObjectName( buttonName ) - button.setText( buttonName ) - button.setToolTip( buttonConfig[ 'buttonTooltip' ] ) - button.clicked.connect(lambda b, button=button: callback( button.buttonConfig )) + buttonName = buttonConfig["buttonName"] + button.setObjectName(buttonName) + button.setText(buttonName) + button.setToolTip(buttonConfig["buttonTooltip"]) + button.clicked.connect(lambda b, button=button: callback(button.buttonConfig)) tabLayout.addWidget(button) self.refreshTabShortcuts(tabLayout) def refreshTabShortcuts(self, tabLayout): for n in range(tabLayout.count()): button = tabLayout.itemAt(n).widget() - if not(n >=0 and n <= 8): + if not (n >= 0 and n <= 8): continue buttonName = button.objectName() - button.setText("{0}_[{1}]".format(buttonName, n+1 )) - button.setShortcut( - self.getButtonShortcut(n) - ) + button.setText("{0}_[{1}]".format(buttonName, n + 1)) + button.setShortcut(self.getButtonShortcut(n)) def buttonMouseMoveEvent(self, e, button): if e.buttons() == QtCore.Qt.LeftButton: @@ -110,52 +103,54 @@ def buttonMouseMoveEvent(self, e, button): def getButtonShortcut(self, no): shortcuts = { - 0 : QtCore.Qt.Key_1, - 1 : QtCore.Qt.Key_2, - 2 : QtCore.Qt.Key_3, - 3 : QtCore.Qt.Key_4, - 4 : QtCore.Qt.Key_5, - 5 : QtCore.Qt.Key_6, - 6 : QtCore.Qt.Key_7, - 7 : QtCore.Qt.Key_8, - 8 : QtCore.Qt.Key_9 + 0: QtCore.Qt.Key_1, + 1: QtCore.Qt.Key_2, + 2: QtCore.Qt.Key_3, + 3: QtCore.Qt.Key_4, + 4: QtCore.Qt.Key_5, + 5: QtCore.Qt.Key_6, + 6: QtCore.Qt.Key_7, + 7: QtCore.Qt.Key_8, + 8: QtCore.Qt.Key_9, } return shortcuts[no] def updateButton(self, newButtonConfig, oldButtonConfig, callback): - self.deleteButton( oldButtonConfig ) - self.addButton( newButtonConfig, callback ) + self.deleteButton(oldButtonConfig) + self.addButton(newButtonConfig, callback) def deleteButton(self, buttonConfig): - tabLayout = self.getTabLayout( buttonConfig['buttonTabId'] ) + tabLayout = self.getTabLayout(buttonConfig["buttonTabId"]) for idx in range(tabLayout.count()): - if not( tabLayout.itemAt(idx).widget().id == buttonConfig['buttonId'] ): + if not (tabLayout.itemAt(idx).widget().id == buttonConfig["buttonId"]): continue - item = tabLayout.takeAt( idx ) + item = tabLayout.takeAt(idx) widget = item.widget() if widget: widget.deleteLater() del item return - raise Exception('Botão não encontrado!') + raise Exception("Botão não encontrado!") def getTabButtons(self, tabIndex): - tabLayout = self.getTabLayout( self.widget( tabIndex ).id ) - return [ - tabLayout.itemAt(idx).widget() - for idx in range(tabLayout.count()) - ] - + tabLayout = self.getTabLayout(self.widget(tabIndex).id) + return [tabLayout.itemAt(idx).widget() for idx in range(tabLayout.count())] + def getTabLayout(self, tabId): - tabIdx = self.getTabIndexFromId( tabId ) - tabScroll = self.widget( tabIdx ).findChildren(QtWidgets.QScrollArea)[0].children()[0].children()[0] + tabIdx = self.getTabIndexFromId(tabId) + tabScroll = ( + self.widget(tabIdx) + .findChildren(QtWidgets.QScrollArea)[0] + .children()[0] + .children()[0] + ) tabLayout = tabScroll.children()[0] return tabLayout def clean(self): while self.count() > 0: - tabWidget = self.widget( 0 ) - self.deleteTabContainer( tabWidget.id ) + tabWidget = self.widget(0) + self.deleteTabContainer(tabWidget.id) def setMenuName(self, menuName): self.menuName = menuName @@ -164,47 +159,49 @@ def getMenuName(self): return self.menuName def dump(self): - menuDump = { - "menuName": self.getMenuName(), - "setup": [] - } + menuDump = {"menuName": self.getMenuName(), "setup": []} for idx in range(self.count()): - tabWidget = self.widget( idx ) + tabWidget = self.widget(idx) tabData = { - "tabName": self.tabText( idx ), + "tabName": self.tabText(idx), "tabId": tabWidget.id, - "tabButtons": [] + "tabButtons": [], } - tabLayout = self.getTabLayout( tabWidget.id ) + tabLayout = self.getTabLayout(tabWidget.id) for idx in range(tabLayout.count()): - tabData['tabButtons'].append( tabLayout.itemAt(idx).widget().buttonConfig ) - menuDump["setup"].append( tabData ) + tabData["tabButtons"].append( + tabLayout.itemAt(idx).widget().buttonConfig + ) + menuDump["setup"].append(tabData) return menuDump def load(self, menuConfig, buttonCallback): self.buttonCallback = buttonCallback self.buttonList = [] - self.setMenuName( menuConfig["menuName"] ) + self.setMenuName(menuConfig["menuName"]) for tabData in menuConfig["setup"]: - self.addTabContainer( tabData['tabId'], tabData['tabName'] ) - for buttonData in tabData['tabButtons']: - self.buttonList.append( buttonData ) - self.addButton( buttonData, self.buttonCallback ) + self.addTabContainer(tabData["tabId"], tabData["tabName"]) + for buttonData in tabData["tabButtons"]: + self.buttonList.append(buttonData) + self.addButton(buttonData, self.buttonCallback) def searchButtons(self, name): - tabSearchId = '****' + tabSearchId = "****" found = [] if not name: - self.deleteTabContainer( tabSearchId ) + self.deleteTabContainer(tabSearchId) return for buttonData in self.buttonList: - if not( name in buttonData['buttonName'] or name in buttonData['buttonKeyWords'].split(';') ): + if not ( + name in buttonData["buttonName"] + or name in buttonData["buttonKeyWords"].split(";") + ): continue - buttonData['buttonTabId'] = tabSearchId - found.append( buttonData ) + buttonData["buttonTabId"] = tabSearchId + found.append(buttonData) if not found: - self.deleteTabContainer( tabSearchId ) + self.deleteTabContainer(tabSearchId) return - self.deleteTabContainer( tabSearchId ) - self.addTabContainer( tabSearchId, '***Pesquisa***', 0 ) - [ self.addButton( buttonData, self.buttonCallback ) for buttonData in found ] \ No newline at end of file + self.deleteTabContainer(tabSearchId) + self.addTabContainer(tabSearchId, "***Pesquisa***", 0) + [self.addButton(buttonData, self.buttonCallback) for buttonData in found] diff --git a/DsgTools/Modules/acquisitionMenu/widgets/reclassifyDialog.py b/DsgTools/Modules/acquisitionMenu/widgets/reclassifyDialog.py index 3056dde5a..1f7b46dc6 100644 --- a/DsgTools/Modules/acquisitionMenu/widgets/reclassifyDialog.py +++ b/DsgTools/Modules/acquisitionMenu/widgets/reclassifyDialog.py @@ -2,6 +2,7 @@ from PyQt5 import QtCore, uic, QtWidgets, QtGui import os, sys + class ReclassifyDialog(QtWidgets.QDialog): success = QtCore.pyqtSignal(dict) @@ -17,10 +18,10 @@ def __init__(self, controller): def getUiPath(self): return os.path.join( - os.path.abspath(os.path.dirname(__file__)), - '..', - 'uis', - 'reclassifyDialog.ui' + os.path.abspath(os.path.dirname(__file__)), + "..", + "uis", + "reclassifyDialog.ui", ) def getController(self): @@ -28,29 +29,29 @@ def getController(self): def setAttributeTableWidget(self, attributeTableWidget): self.attributeTable = attributeTableWidget - self.attributeLayout.addWidget( attributeTableWidget ) + self.attributeLayout.addWidget(attributeTableWidget) def getAttributeTableWidget(self): return self.attributeTable def loadLayersStatus(self, layers): self.layers = layers - for l in layers: - checkBox = self.addLayerCheckBox( l ) + for l in layers: + checkBox = self.addLayerCheckBox(l) checkBox.setChecked(True) - self.layersCheckbox.append( checkBox ) + self.layersCheckbox.append(checkBox) def loadAttributes(self, attributesConfig): - self.getAttributeTableWidget().loadAttributes( attributesConfig ) + self.getAttributeTableWidget().loadAttributes(attributesConfig) def setAttributesValues(self, attributesValues): - self.getAttributeTableWidget().setAttributesValues( attributesValues ) - + self.getAttributeTableWidget().setAttributesValues(attributesValues) + def addLayerCheckBox(self, layer): - checkBox = QtWidgets.QCheckBox( - 'Camada : {0} >>> Quantidade de selecionados : {1}'.format( + checkBox = QtWidgets.QCheckBox( + "Camada : {0} >>> Quantidade de selecionados : {1}".format( layer.name(), layer.selectedFeatureCount() - ) + ) ) checkBox.layerId = layer.id() self.layersFrame.layout().addWidget(checkBox) @@ -61,21 +62,17 @@ def getSelectedLayers(self): for checkBox in self.layersCheckbox: if not checkBox.isChecked(): continue - selectedLayerIds.append( checkBox.layerId ) - return [ - l - for l in self.layers - if l.id() in selectedLayerIds - ] + selectedLayerIds.append(checkBox.layerId) + return [l for l in self.layers if l.id() in selectedLayerIds] def getData(self): return { - 'layers': self.getSelectedLayers(), - 'attributes': self.getAttributeTableWidget().getAttributes() + "layers": self.getSelectedLayers(), + "attributes": self.getAttributeTableWidget().getAttributes(), } def showTopLevel(self): - return self.exec_() == QtWidgets.QDialog.Accepted + return self.exec_() == QtWidgets.QDialog.Accepted @QtCore.pyqtSlot(bool) def on_saveBtn_clicked(self): @@ -83,8 +80,8 @@ def on_saveBtn_clicked(self): self.reject() else: self.accept() - self.success.emit( self.getData() ) + self.success.emit(self.getData()) @QtCore.pyqtSlot(bool) def on_cancelBtn_clicked(self): - self.reject() \ No newline at end of file + self.reject() diff --git a/DsgTools/Modules/acquisitionMenu/widgets/tabEditorWidget.py b/DsgTools/Modules/acquisitionMenu/widgets/tabEditorWidget.py index e03745e9c..ed435d8ea 100644 --- a/DsgTools/Modules/acquisitionMenu/widgets/tabEditorWidget.py +++ b/DsgTools/Modules/acquisitionMenu/widgets/tabEditorWidget.py @@ -2,68 +2,56 @@ from PyQt5 import QtCore, uic, QtWidgets, QtGui from .tableEditorWidget import TableEditorWidget -class TabEditorWidget( TableEditorWidget ): - def __init__( - self, - controller - ): - super( TabEditorWidget, self).__init__( controller=controller ) +class TabEditorWidget(TableEditorWidget): + def __init__(self, controller): + super(TabEditorWidget, self).__init__(controller=controller) self.tableWidget.setColumnHidden(0, True) def handleEditBtn(self, index): try: self.getController().openEditTabDialog( - self.getRowData( index.row() ), - self.updateTab + self.getRowData(index.row()), self.updateTab ) except Exception as e: - self.showError('Erro', str(e)) + self.showError("Erro", str(e)) def handleDeleteBtn(self, index): try: - deletedTabData = self.getRowData( index.row() ) - self.getController().deleteTabMenuEditor( deletedTabData['id'] ) - self.tableWidget.removeRow( index.row() ) + deletedTabData = self.getRowData(index.row()) + self.getController().deleteTabMenuEditor(deletedTabData["id"]) + self.tableWidget.removeRow(index.row()) except Exception as e: - self.showError('Erro', str(e)) - - def addRow(self, - tabId, - tabName - ): - idx = self.getRowIndex( tabId ) + self.showError("Erro", str(e)) + + def addRow(self, tabId, tabName): + idx = self.getRowIndex(tabId) if idx < 0: idx = self.tableWidget.rowCount() self.tableWidget.insertRow(idx) - self.tableWidget.setItem(idx, 0, self.createNotEditableItem( tabId )) + self.tableWidget.setItem(idx, 0, self.createNotEditableItem(tabId)) self.tableWidget.setItem(idx, 1, self.createNotEditableItem(tabName)) - self.tableWidget.setCellWidget(idx, 2, self.createEditRowWidget(idx, 2) ) - + self.tableWidget.setCellWidget(idx, 2, self.createEditRowWidget(idx, 2)) + def addRows(self, tabs): self.clearAllItems() - for tab in tabs: - self.addRow( - tab['id'], - tab['name'] - ) + for tab in tabs: + self.addRow(tab["id"], tab["name"]) self.adjustColumns() def getRowIndex(self, tabId): if not tabId: return -1 for idx in range(self.tableWidget.rowCount()): - if not ( - tabId == self.tableWidget.model().index(idx, 0).data() - ): + if not (tabId == self.tableWidget.model().index(idx, 0).data()): continue return idx return -1 def getRowData(self, rowIndex): return { - 'id': self.tableWidget.model().index(rowIndex, 0).data(), - 'name': self.tableWidget.model().index(rowIndex, 1).data() + "id": self.tableWidget.model().index(rowIndex, 0).data(), + "name": self.tableWidget.model().index(rowIndex, 1).data(), } def getColumnsIndexToSearch(self): @@ -72,26 +60,26 @@ def getColumnsIndexToSearch(self): def getUiPath(self): return os.path.join( os.path.abspath(os.path.dirname(__file__)), - '..', - 'uis', - "tabEditorWidget.ui" + "..", + "uis", + "tabEditorWidget.ui", ) @QtCore.pyqtSlot(bool) def on_addBtn_clicked(self): try: - self.getController().openAddTabDialog( self.addTab ) + self.getController().openAddTabDialog(self.addTab) except Exception as e: - self.showError('Erro', str(e)) + self.showError("Erro", str(e)) def addTab(self, data): if not data: return - self.getController().addTabMenuEditor( data['id'], data['name'] ) - self.addRow( data['id'], data['name'] ) + self.getController().addTabMenuEditor(data["id"], data["name"]) + self.addRow(data["id"], data["name"]) def updateTab(self, data): if not data: return - self.getController().updateTabMenuEditor( data['id'], data['name'] ) - self.addRow( data['id'], data['name'] ) \ No newline at end of file + self.getController().updateTabMenuEditor(data["id"], data["name"]) + self.addRow(data["id"], data["name"]) diff --git a/DsgTools/Modules/acquisitionMenu/widgets/tableEditorWidget.py b/DsgTools/Modules/acquisitionMenu/widgets/tableEditorWidget.py index 2729f2600..b354d1954 100644 --- a/DsgTools/Modules/acquisitionMenu/widgets/tableEditorWidget.py +++ b/DsgTools/Modules/acquisitionMenu/widgets/tableEditorWidget.py @@ -2,27 +2,25 @@ from PyQt5 import QtCore, uic, QtWidgets, QtGui from DsgTools.Modules.utils.factories.utilsFactory import UtilsFactory -class TableEditorWidget( QtWidgets.QWidget ): +class TableEditorWidget(QtWidgets.QWidget): def __init__( - self, - controller, - messageFactory=UtilsFactory().createMessageFactory() - ): - super( TableEditorWidget, self).__init__() - uic.loadUi( self.getUiPath(), self ) + self, controller, messageFactory=UtilsFactory().createMessageFactory() + ): + super(TableEditorWidget, self).__init__() + uic.loadUi(self.getUiPath(), self) self.controller = controller self.messageFactory = messageFactory self.tableWidget.horizontalHeader().sortIndicatorOrder() self.tableWidget.setSortingEnabled(True) - + def getController(self): return self.controller - def createTableToolButton(self, tooltip, iconPath ): - button = QtWidgets.QPushButton('', self.tableWidget) - button.setToolTip( tooltip ) - button.setIcon(QtGui.QIcon( iconPath )) + def createTableToolButton(self, tooltip, iconPath): + button = QtWidgets.QPushButton("", self.tableWidget) + button.setToolTip(tooltip) + button.setIcon(QtGui.QIcon(iconPath)) button.setFixedSize(QtCore.QSize(30, 30)) button.setIconSize(QtCore.QSize(20, 20)) return button @@ -30,25 +28,25 @@ def createTableToolButton(self, tooltip, iconPath ): def getSelectedRowData(self): rowsData = [] for item in self.tableWidget.selectionModel().selectedRows(): - rowsData.append( self.getRowData(item.row()) ) + rowsData.append(self.getRowData(item.row())) return rowsData def getAllTableData(self): rowsData = [] for idx in range(self.tableWidget.rowCount()): - rowsData.append( self.getRowData(idx) ) + rowsData.append(self.getRowData(idx)) return rowsData def validateValue(self, value): if value is None: - return '' + return "" return str(value) def createNotEditableItem(self, value): item = QtWidgets.QTableWidgetItem(self.validateValue(value)) item.setFlags(QtCore.Qt.ItemIsEnabled | QtCore.Qt.ItemIsSelectable) return item - + def createEditableItem(self, value): item = QtWidgets.QTableWidgetItem(self.validateValue(value)) return item @@ -58,19 +56,19 @@ def searchRows(self, text): if text and not self.hasTextOnRow(idx, text): self.tableWidget.setRowHidden(idx, True) else: - self.tableWidget.setRowHidden(idx, False) + self.tableWidget.setRowHidden(idx, False) def showError(self, title, message): - errorMessageBox = self.messageFactory.createMessage('ErrorMessageBox') + errorMessageBox = self.messageFactory.createMessage("ErrorMessageBox") errorMessageBox.show(self, title, message) def showInfo(self, title, message): - infoMessageBox = self.messageFactory.createMessage('InfoMessageBox') + infoMessageBox = self.messageFactory.createMessage("InfoMessageBox") infoMessageBox.show(self, title, message) def clearAllItems(self): self.tableWidget.setRowCount(0) - + def adjustColumns(self): self.tableWidget.resizeColumnsToContents() @@ -78,8 +76,10 @@ def adjustRows(self): self.tableWidget.resizeRowsToContents() def removeSelected(self): - while self.tableWidget.selectionModel().selectedRows() : - self.tableWidget.removeRow(self.tableWidget.selectionModel().selectedRows()[0].row()) + while self.tableWidget.selectionModel().selectedRows(): + self.tableWidget.removeRow( + self.tableWidget.selectionModel().selectedRows()[0].row() + ) def hasTextOnRow(self, rowIdx, text): for colIdx in self.getColumnsIndexToSearch(): @@ -93,36 +93,28 @@ def createEditRowWidget(self, row, col): layout = QtWidgets.QHBoxLayout(wd) index = QtCore.QPersistentModelIndex(self.tableWidget.model().index(row, col)) - editBtn = self.createTableToolButton( 'Editar', self.getEditIconPath() ) - editBtn.clicked.connect( - lambda *args, index=index: self.handleEditBtn(index) - ) + editBtn = self.createTableToolButton("Editar", self.getEditIconPath()) + editBtn.clicked.connect(lambda *args, index=index: self.handleEditBtn(index)) layout.addWidget(editBtn) - deleteBtn = self.createTableToolButton( 'Excluir', self.getDeleteIconPath() ) + deleteBtn = self.createTableToolButton("Excluir", self.getDeleteIconPath()) deleteBtn.clicked.connect( lambda *args, index=index: self.handleDeleteBtn(index) ) layout.addWidget(deleteBtn) layout.setAlignment(QtCore.Qt.AlignCenter) - layout.setContentsMargins(0,0,0,0) + layout.setContentsMargins(0, 0, 0, 0) return wd def getEditIconPath(self): return os.path.join( - os.path.abspath(os.path.dirname(__file__)), - '..', - 'icons', - "edit.png" + os.path.abspath(os.path.dirname(__file__)), "..", "icons", "edit.png" ) def getDeleteIconPath(self): return os.path.join( - os.path.abspath(os.path.dirname(__file__)), - '..', - 'icons', - "delete.png" + os.path.abspath(os.path.dirname(__file__)), "..", "icons", "delete.png" ) @QtCore.pyqtSlot(str) diff --git a/DsgTools/Modules/qgis/actions/addPointFeature.py b/DsgTools/Modules/qgis/actions/addPointFeature.py index 33b621ad1..60bb42858 100644 --- a/DsgTools/Modules/qgis/actions/addPointFeature.py +++ b/DsgTools/Modules/qgis/actions/addPointFeature.py @@ -2,8 +2,8 @@ from qgis.utils import iface from PyQt5 import QtCore, uic, QtWidgets, QtGui -class AddPointFeature: +class AddPointFeature: def execute(self): iface.activeLayer().startEditing() - iface.actionAddFeature().trigger() \ No newline at end of file + iface.actionAddFeature().trigger() diff --git a/DsgTools/Modules/qgis/actions/addRing.py b/DsgTools/Modules/qgis/actions/addRing.py index f39d2ab78..9763e4a9f 100644 --- a/DsgTools/Modules/qgis/actions/addRing.py +++ b/DsgTools/Modules/qgis/actions/addRing.py @@ -2,15 +2,15 @@ from qgis.utils import iface from PyQt5 import QtCore, uic, QtWidgets, QtGui -class AddRing: +class AddRing: def __init__(self): - self.names = [ 'mActionAddRing' ] + self.names = ["mActionAddRing"] def execute(self): for a in gui.QgsGui.shortcutsManager().listActions(): - if not( a.objectName() in self.names ): + if not (a.objectName() in self.names): continue iface.activeLayer().startEditing() a.trigger() - break \ No newline at end of file + break diff --git a/DsgTools/Modules/qgis/actions/cutFeatures.py b/DsgTools/Modules/qgis/actions/cutFeatures.py index c12e0805d..3e1492d64 100644 --- a/DsgTools/Modules/qgis/actions/cutFeatures.py +++ b/DsgTools/Modules/qgis/actions/cutFeatures.py @@ -2,15 +2,15 @@ from qgis.utils import iface from PyQt5 import QtCore, uic, QtWidgets, QtGui -class CutFeatures: +class CutFeatures: def __init__(self): - self.names = [ 'mActionSplitFeatures' ] + self.names = ["mActionSplitFeatures"] def execute(self): for a in gui.QgsGui.shortcutsManager().listActions(): - if not( a.objectName() in self.names ): + if not (a.objectName() in self.names): continue iface.activeLayer().startEditing() a.trigger() - break \ No newline at end of file + break diff --git a/DsgTools/Modules/qgis/actions/deleteRing.py b/DsgTools/Modules/qgis/actions/deleteRing.py index 175a2c452..5fe3966df 100644 --- a/DsgTools/Modules/qgis/actions/deleteRing.py +++ b/DsgTools/Modules/qgis/actions/deleteRing.py @@ -2,15 +2,15 @@ from qgis.utils import iface from PyQt5 import QtCore, uic, QtWidgets, QtGui -class DeleteRing: +class DeleteRing: def __init__(self): - self.names = [ 'mActionDeleteRing' ] + self.names = ["mActionDeleteRing"] def execute(self): for a in gui.QgsGui.shortcutsManager().listActions(): - if not( a.objectName() in self.names ): + if not (a.objectName() in self.names): continue iface.activeLayer().startEditing() a.trigger() - break \ No newline at end of file + break diff --git a/DsgTools/Modules/qgis/actions/deleteSelected.py b/DsgTools/Modules/qgis/actions/deleteSelected.py index 9d80f1680..b4542c1d9 100644 --- a/DsgTools/Modules/qgis/actions/deleteSelected.py +++ b/DsgTools/Modules/qgis/actions/deleteSelected.py @@ -2,15 +2,15 @@ from qgis.utils import iface from PyQt5 import QtCore, uic, QtWidgets, QtGui -class DeleteSelected: +class DeleteSelected: def __init__(self): - self.names = [ 'mActionDeleteSelected' ] + self.names = ["mActionDeleteSelected"] def execute(self): for a in gui.QgsGui.shortcutsManager().listActions(): - if not( a.objectName() in self.names ): + if not (a.objectName() in self.names): continue iface.activeLayer().startEditing() a.trigger() - break \ No newline at end of file + break diff --git a/DsgTools/Modules/qgis/actions/freeHand.py b/DsgTools/Modules/qgis/actions/freeHand.py index 9d774a2c7..f4f8a8579 100644 --- a/DsgTools/Modules/qgis/actions/freeHand.py +++ b/DsgTools/Modules/qgis/actions/freeHand.py @@ -2,18 +2,18 @@ from qgis.utils import iface from PyQt5 import QtCore, uic, QtWidgets, QtGui -class FreeHand: +class FreeHand: def __init__(self): - self.names = [ - 'dsgtools: free hand acquisition', - 'dsgtools: ferramenta de aquisição à mão livre' + self.names = [ + "dsgtools: free hand acquisition", + "dsgtools: ferramenta de aquisição à mão livre", ] - + def execute(self): for a in gui.QgsGui.shortcutsManager().listActions(): - if not( a.text().lower() in self.names ): + if not (a.text().lower() in self.names): continue iface.activeLayer().startEditing() a.trigger() - break \ No newline at end of file + break diff --git a/DsgTools/Modules/qgis/actions/freeHandReshape.py b/DsgTools/Modules/qgis/actions/freeHandReshape.py index 9c1a48549..6cafb5244 100644 --- a/DsgTools/Modules/qgis/actions/freeHandReshape.py +++ b/DsgTools/Modules/qgis/actions/freeHandReshape.py @@ -2,18 +2,18 @@ from qgis.utils import iface from PyQt5 import QtCore, uic, QtWidgets, QtGui -class FreeHandReshape: +class FreeHandReshape: def __init__(self): - self.names = [ - 'dsgtools: free hand reshape', - 'dsgtools: ferramenta de remodelagem à mão livre' + self.names = [ + "dsgtools: free hand reshape", + "dsgtools: ferramenta de remodelagem à mão livre", ] - + def execute(self): for a in gui.QgsGui.shortcutsManager().listActions(): - if not( a.text().lower() in self.names ): + if not (a.text().lower() in self.names): continue iface.activeLayer().startEditing() a.trigger() - break \ No newline at end of file + break diff --git a/DsgTools/Modules/qgis/actions/lastLayer.py b/DsgTools/Modules/qgis/actions/lastLayer.py index 5e91aa94e..4273a07e5 100644 --- a/DsgTools/Modules/qgis/actions/lastLayer.py +++ b/DsgTools/Modules/qgis/actions/lastLayer.py @@ -2,8 +2,8 @@ from qgis.utils import iface from PyQt5 import QtCore, uic, QtWidgets, QtGui -class LastLayer: +class LastLayer: def __init__(self): self.layers = [] self.startSignals() @@ -19,6 +19,6 @@ def updateList(self, vectorLayer): self.layers.append(vectorLayer) def execute(self): - if not( len(self.layers) > 0 ): + if not (len(self.layers) > 0): return - iface.layerTreeView().setCurrentLayer( self.layers[0] ) \ No newline at end of file + iface.layerTreeView().setCurrentLayer(self.layers[0]) diff --git a/DsgTools/Modules/qgis/actions/mergeFeatureAttributes.py b/DsgTools/Modules/qgis/actions/mergeFeatureAttributes.py index 70db96290..b38e5bebe 100644 --- a/DsgTools/Modules/qgis/actions/mergeFeatureAttributes.py +++ b/DsgTools/Modules/qgis/actions/mergeFeatureAttributes.py @@ -2,15 +2,15 @@ from qgis.utils import iface from PyQt5 import QtCore, uic, QtWidgets, QtGui -class MergeFeatureAttributes: +class MergeFeatureAttributes: def __init__(self): - self.names = [ 'mActionMergeFeatureAttributes' ] + self.names = ["mActionMergeFeatureAttributes"] def execute(self): for a in gui.QgsGui.shortcutsManager().listActions(): - if not( a.objectName() in self.names ): + if not (a.objectName() in self.names): continue iface.activeLayer().startEditing() a.trigger() - break \ No newline at end of file + break diff --git a/DsgTools/Modules/qgis/actions/moveFeature.py b/DsgTools/Modules/qgis/actions/moveFeature.py index 40adca4a7..1e08d358f 100644 --- a/DsgTools/Modules/qgis/actions/moveFeature.py +++ b/DsgTools/Modules/qgis/actions/moveFeature.py @@ -2,15 +2,15 @@ from qgis.utils import iface from PyQt5 import QtCore, uic, QtWidgets, QtGui -class MoveFeature: +class MoveFeature: def __init__(self): - self.names = [ 'mActionMoveFeature' ] + self.names = ["mActionMoveFeature"] def execute(self): for a in gui.QgsGui.shortcutsManager().listActions(): - if not( a.objectName() in self.names ): + if not (a.objectName() in self.names): continue iface.activeLayer().startEditing() a.trigger() - break \ No newline at end of file + break diff --git a/DsgTools/Modules/qgis/actions/openAttributeTable.py b/DsgTools/Modules/qgis/actions/openAttributeTable.py index d2872ffd3..1cb29d7f4 100644 --- a/DsgTools/Modules/qgis/actions/openAttributeTable.py +++ b/DsgTools/Modules/qgis/actions/openAttributeTable.py @@ -2,7 +2,7 @@ from qgis.utils import iface from PyQt5 import QtCore, uic, QtWidgets, QtGui -class OpenAttributeTable: +class OpenAttributeTable: def execute(self): - iface.actionOpenTable().trigger() \ No newline at end of file + iface.actionOpenTable().trigger() diff --git a/DsgTools/Modules/qgis/actions/openAttributeTableOnlySelection.py b/DsgTools/Modules/qgis/actions/openAttributeTableOnlySelection.py index a5d89a35f..d6ffa01ea 100644 --- a/DsgTools/Modules/qgis/actions/openAttributeTableOnlySelection.py +++ b/DsgTools/Modules/qgis/actions/openAttributeTableOnlySelection.py @@ -2,16 +2,14 @@ from qgis.utils import iface from PyQt5 import QtCore, uic, QtWidgets, QtGui -class OpenAttributeTableOnlySelection: +class OpenAttributeTableOnlySelection: def __init__(self): - self.names = [ - 'attributeTableSelectedFeatures' - ] - + self.names = ["attributeTableSelectedFeatures"] + def execute(self): for a in gui.QgsGui.shortcutsManager().listShortcuts(): - if not( a.objectName() in self.names ): + if not (a.objectName() in self.names): continue a.activated.emit() - break \ No newline at end of file + break diff --git a/DsgTools/Modules/qgis/actions/restoreFields.py b/DsgTools/Modules/qgis/actions/restoreFields.py index 4ead96927..01a66493b 100644 --- a/DsgTools/Modules/qgis/actions/restoreFields.py +++ b/DsgTools/Modules/qgis/actions/restoreFields.py @@ -2,14 +2,14 @@ from qgis.utils import iface from PyQt5 import QtCore, uic, QtWidgets, QtGui -class RestoreFields: +class RestoreFields: def __init__(self): - self.names = [ 'restaurar camada' ] - + self.names = ["restaurar camada"] + def execute(self): for a in gui.QgsGui.shortcutsManager().listActions(): - if not( a.text().lower() in self.names ): + if not (a.text().lower() in self.names): continue a.trigger() - break \ No newline at end of file + break diff --git a/DsgTools/Modules/qgis/actions/rightDegreeAngleDigitizing.py b/DsgTools/Modules/qgis/actions/rightDegreeAngleDigitizing.py index 1dc524673..342b1aa72 100644 --- a/DsgTools/Modules/qgis/actions/rightDegreeAngleDigitizing.py +++ b/DsgTools/Modules/qgis/actions/rightDegreeAngleDigitizing.py @@ -2,18 +2,18 @@ from qgis.utils import iface from PyQt5 import QtCore, uic, QtWidgets, QtGui -class RightDegreeAngleDigitizing: +class RightDegreeAngleDigitizing: def __init__(self): - self.names = [ - 'dsgtools: right degree angle digitizing', - 'dsgtools: ferramenta de aquisição com ângulos retos' + self.names = [ + "dsgtools: right degree angle digitizing", + "dsgtools: ferramenta de aquisição com ângulos retos", ] - + def execute(self): for a in gui.QgsGui.shortcutsManager().listActions(): - if not( a.text().lower() in self.names ): + if not (a.text().lower() in self.names): continue iface.activeLayer().startEditing() a.trigger() - break \ No newline at end of file + break diff --git a/DsgTools/Modules/qgis/actions/selectFeature.py b/DsgTools/Modules/qgis/actions/selectFeature.py index 82af0c0a4..5f059b95e 100644 --- a/DsgTools/Modules/qgis/actions/selectFeature.py +++ b/DsgTools/Modules/qgis/actions/selectFeature.py @@ -2,7 +2,7 @@ from qgis.utils import iface from PyQt5 import QtCore, uic, QtWidgets, QtGui -class SelectFeature: +class SelectFeature: def execute(self): - iface.actionSelectRectangle().trigger() \ No newline at end of file + iface.actionSelectRectangle().trigger() diff --git a/DsgTools/Modules/qgis/actions/selectRaster.py b/DsgTools/Modules/qgis/actions/selectRaster.py index c1b678645..4ae0d7063 100644 --- a/DsgTools/Modules/qgis/actions/selectRaster.py +++ b/DsgTools/Modules/qgis/actions/selectRaster.py @@ -2,16 +2,16 @@ from qgis.utils import iface from PyQt5 import QtCore, uic, QtWidgets, QtGui -class SelectRaster: +class SelectRaster: def __init__(self): self.rasters = [] def execute(self): self.rasters = self.getRasters() - if not( len(self.rasters) > 0 ): + if not (len(self.rasters) > 0): return - self.openRastersMenu( self.rasters ) + self.openRastersMenu(self.rasters) def getRasters(self): rasters = [] @@ -27,25 +27,27 @@ def getRasters(self): return rasters def getCursorRect(self): - p = gui.QgsMapTool( iface.mapCanvas() ).toMapCoordinates( iface.mapCanvas().mouseLastXY() ) + p = gui.QgsMapTool(iface.mapCanvas()).toMapCoordinates( + iface.mapCanvas().mouseLastXY() + ) w = iface.mapCanvas().mapUnitsPerPixel() * 10 - return core.QgsRectangle(p.x()-w, p.y()-w, p.x()+w, p.y()+w) + return core.QgsRectangle(p.x() - w, p.y() - w, p.x() + w, p.y() + w) def openRastersMenu(self, rasters): menu = QtWidgets.QMenu() self.addRasterMenu(menu, rasters) - menu.exec_( QtGui.QCursor.pos() ) + menu.exec_(QtGui.QCursor.pos()) def addRasterMenu(self, menu, rasters): - rasterMenu = menu#QtWidgets.QMenu(title="Rasters", parent=menu) + rasterMenu = menu # QtWidgets.QMenu(title="Rasters", parent=menu) for raster in rasters: - action = rasterMenu.addAction( raster.name() ) + action = rasterMenu.addAction(raster.name()) action.triggered.connect(lambda b, raster=raster: self.selectOnly(raster)) - #menu.addMenu(rasterMenu) + # menu.addMenu(rasterMenu) def selectOnly(self, raster): for otherRaster in self.rasters: if otherRaster.id() == raster.id(): iface.layerTreeView().setLayerVisible(otherRaster, True) continue - iface.layerTreeView().setLayerVisible(otherRaster, False) \ No newline at end of file + iface.layerTreeView().setLayerVisible(otherRaster, False) diff --git a/DsgTools/Modules/qgis/actions/setDefaultFields.py b/DsgTools/Modules/qgis/actions/setDefaultFields.py index 89ce805e9..4b688005f 100644 --- a/DsgTools/Modules/qgis/actions/setDefaultFields.py +++ b/DsgTools/Modules/qgis/actions/setDefaultFields.py @@ -2,16 +2,14 @@ from qgis.utils import iface from PyQt5 import QtCore, uic, QtWidgets, QtGui -class SetDefaultFields: +class SetDefaultFields: def __init__(self): - self.names = [ - 'criar mais como esse' - ] + self.names = ["criar mais como esse"] def execute(self): for a in gui.QgsGui.shortcutsManager().listActions(): - if not( a.text().lower() in self.names ): + if not (a.text().lower() in self.names): continue a.trigger() - break \ No newline at end of file + break diff --git a/DsgTools/Modules/qgis/actions/setFeatureInspector.py b/DsgTools/Modules/qgis/actions/setFeatureInspector.py index 252381c46..6928526b1 100644 --- a/DsgTools/Modules/qgis/actions/setFeatureInspector.py +++ b/DsgTools/Modules/qgis/actions/setFeatureInspector.py @@ -2,17 +2,17 @@ from qgis.utils import iface from PyQt5 import QtCore, uic, QtWidgets, QtGui -class SetFeatureInspector: +class SetFeatureInspector: def __init__(self): - self.names = [ - 'dsgtools: set active layer on feature inspector', - 'dsgtools: definir a camada ativa no inspetor de feições' + self.names = [ + "dsgtools: set active layer on feature inspector", + "dsgtools: definir a camada ativa no inspetor de feições", ] - + def execute(self): for a in gui.QgsGui.shortcutsManager().listActions(): - if not( a.text().lower() in self.names ): + if not (a.text().lower() in self.names): continue a.trigger() - break \ No newline at end of file + break diff --git a/DsgTools/Modules/qgis/actions/topologicalSnapping.py b/DsgTools/Modules/qgis/actions/topologicalSnapping.py index 83cd125d3..04ffbf45d 100644 --- a/DsgTools/Modules/qgis/actions/topologicalSnapping.py +++ b/DsgTools/Modules/qgis/actions/topologicalSnapping.py @@ -2,14 +2,14 @@ from qgis.utils import iface from PyQt5 import QtCore, uic, QtWidgets, QtGui -class TopologicalSnapping: +class TopologicalSnapping: def __init__(self): - self.names = [ 'topologicaleditingaction' ] + self.names = ["topologicaleditingaction"] def execute(self): for a in gui.QgsGui.shortcutsManager().listActions(): - if not( a.objectName().lower() in self.names ): + if not (a.objectName().lower() in self.names): continue a.trigger() - break \ No newline at end of file + break diff --git a/DsgTools/Modules/qgis/actions/trimExtendFeature.py b/DsgTools/Modules/qgis/actions/trimExtendFeature.py index a79abc98c..dab7ada82 100644 --- a/DsgTools/Modules/qgis/actions/trimExtendFeature.py +++ b/DsgTools/Modules/qgis/actions/trimExtendFeature.py @@ -2,15 +2,15 @@ from qgis.utils import iface from PyQt5 import QtCore, uic, QtWidgets, QtGui -class TrimExtendFeature: +class TrimExtendFeature: def __init__(self): - self.names = [ 'mActionTrimExtendFeature' ] + self.names = ["mActionTrimExtendFeature"] def execute(self): for a in gui.QgsGui.shortcutsManager().listActions(): - if not( a.objectName() in self.names ): + if not (a.objectName() in self.names): continue iface.activeLayer().startEditing() a.trigger() - break \ No newline at end of file + break diff --git a/DsgTools/Modules/qgis/controllers/qgisCtrl.py b/DsgTools/Modules/qgis/controllers/qgisCtrl.py index 2f95fb8fc..36241dee9 100644 --- a/DsgTools/Modules/qgis/controllers/qgisCtrl.py +++ b/DsgTools/Modules/qgis/controllers/qgisCtrl.py @@ -4,42 +4,51 @@ import json from DsgTools.Modules.qgis.factories.actionsFactory import ActionsFactory + class QgisCtrl: - - def __init__( - self, - actionsFactory=ActionsFactory() - ): + def __init__(self, actionsFactory=ActionsFactory()): self.actionsFactory = actionsFactory def getLoadedVectorLayerNames(self): layerNames = [] for l in core.QgsProject.instance().mapLayers().values(): - if not( l.type() == core.QgsMapLayer.VectorLayer ): + if not (l.type() == core.QgsMapLayer.VectorLayer): continue layerName = None - if l.providerType() == 'postgres': + if l.providerType() == "postgres": layerName = l.dataProvider().uri().table() - elif l.providerType() == 'ogr': - layerName = l.dataProvider().uri().uri().split('|')[-1].split('=')[-1][1:-1] + elif l.providerType() == "ogr": + layerName = ( + l.dataProvider().uri().uri().split("|")[-1].split("=")[-1][1:-1] + ) + if layerName == '': + layerName = l.name() + else: + layerName = l.name() if not layerName: continue - layerNames.append( layerName ) + layerNames.append(layerName) return layerNames def getVectorLayerNames(self, layers): layerNames = [] for l in layers: - if not( l.type() == core.QgsMapLayer.VectorLayer ): + if not (l.type() == core.QgsMapLayer.VectorLayer): continue layerName = None - if l.providerType() == 'postgres': + if l.providerType() == "postgres": layerName = l.dataProvider().uri().table() - elif l.providerType() == 'ogr': - layerName = l.dataProvider().uri().uri().split('|')[-1].split('=')[-1][1:-1] + elif l.providerType() == "ogr": + layerName = ( + l.dataProvider().uri().uri().split("|")[-1].split("=")[-1][1:-1] + ) + if layerName == '': + layerName = l.name() + else: + layerName = l.name() if not layerName: continue - layerNames.append( layerName ) + layerNames.append(layerName) return layerNames def getLoadedVectorLayers(self): @@ -52,97 +61,105 @@ def getLoadedVectorLayers(self): def getVectorLayersByName(self, name): layers = [] for l in core.QgsProject.instance().mapLayers().values(): - if not( l.type() == core.QgsMapLayer.VectorLayer ): + if not (l.type() == core.QgsMapLayer.VectorLayer): continue layerName = None - if l.providerType() == 'postgres': + if l.providerType() == "postgres": layerName = l.dataProvider().uri().table() - elif l.providerType() == 'ogr': - layerName = l.dataProvider().uri().uri().split('|')[-1].split('=')[-1][1:-1] + elif l.providerType() == "ogr": + layerName = ( + l.dataProvider().uri().uri().split("|")[-1].split("=")[-1][1:-1] + ) + if layerName == '': + layerName = l.name() + else: + layerName = l.name() if not layerName or layerName != name: continue - layers.append( l ) + layers.append(l) return layers def getVectorLayerByName(self, name): - layers = self.getVectorLayersByName( name ) + layers = self.getVectorLayersByName(name) if not layers: return None return layers[0] def getAttributesConfigByLayerName( - self, - layerName, - withPrimaryKey=False, - withVirtualField=False - ): - layer = self.getVectorLayerByName( layerName ) + self, layerName, withPrimaryKey=False, withVirtualField=False + ): + layer = self.getVectorLayerByName(layerName) if not layer: return {} - return self.getAttributesConfigByLayer( layer, withPrimaryKey, withVirtualField ) - + return self.getAttributesConfigByLayer(layer, withPrimaryKey, withVirtualField) - def getAttributesConfigByLayer(self, layer, withPrimaryKey, withVirtualField): + def getAttributesConfigByLayer(self, layer, withPrimaryKey, withVirtualField): attrConfig = {} for fieldIndex in layer.attributeList(): - if not( withPrimaryKey ) and ( fieldIndex in self.getLayerPrimaryKeyIndexes( layer ) ): + if not (withPrimaryKey) and ( + fieldIndex in self.getLayerPrimaryKeyIndexes(layer) + ): continue - if not( withVirtualField ) and ( self.getFieldTypeName( layer, fieldIndex ) == '' ) : + if not (withVirtualField) and ( + self.getFieldTypeName(layer, fieldIndex) == "" + ): continue - fieldName = layer.fields().field( fieldIndex ).name() - fieldConfig = layer.fields().field( fieldIndex ).editorWidgetSetup().config() - attrConfig[ fieldName ] = fieldConfig + fieldName = layer.fields().field(fieldIndex).name() + fieldConfig = layer.fields().field(fieldIndex).editorWidgetSetup().config() + attrConfig[fieldName] = fieldConfig return attrConfig - + def getLayerPrimaryKeyIndexes(self, layer): return layer.dataProvider().pkAttributeIndexes() def getFieldTypeName(self, layer, fieldIndex): - return layer.fields().field( fieldIndex ).typeName() + return layer.fields().field(fieldIndex).typeName() def getAcquisitionToolNames(self): return { - 'Padrão': None, - 'Ângulo Reto': 'RightDegreeAngleDigitizing', - 'Mão Livre': 'FreeHand' + "Padrão": None, + "Ângulo Reto": "RightDegreeAngleDigitizing", + "Mão Livre": "FreeHand", } def addDockWidget(self, dockWidget, side=QtCore.Qt.LeftDockWidgetArea): iface.addDockWidget(side, dockWidget) def removeDockWidget(self, dockWidget): - iface.removeDockWidget( dockWidget ) + iface.removeDockWidget(dockWidget) def registerShortcut(self, shortcut): - gui.QgsGui.shortcutsManager().registerShortcut( shortcut ) - + gui.QgsGui.shortcutsManager().registerShortcut(shortcut) + def unregisterShortcut(self, shortcut): - gui.QgsGui.shortcutsManager().unregisterShortcut( shortcut ) + gui.QgsGui.shortcutsManager().unregisterShortcut(shortcut) def setDefaultFields(self, layer, attributes, reset=False): primaryKeyIndexes = layer.dataProvider().pkAttributeIndexes() for attributeName in attributes: - fieldIndex = layer.fields().indexFromName( attributeName ) + fieldIndex = layer.fields().indexFromName(attributeName) if fieldIndex in primaryKeyIndexes: continue - attributeValue = attributes[ attributeName ] - configField = layer.defaultValueDefinition( fieldIndex ) - isMapValue = ( 'map' in layer.editorWidgetSetup( fieldIndex ).config() ) + attributeValue = attributes[attributeName] + configField = layer.defaultValueDefinition(fieldIndex) + isMapValue = "map" in layer.editorWidgetSetup(fieldIndex).config() if isMapValue: - valueMap = self.formatMapValues( layer.editorWidgetSetup( fieldIndex ).config()['map'] ) - if not( attributeValue is None ) and attributeValue in valueMap: - configField.setExpression("{0}".format( valueMap[ attributeValue ] ) ) + valueMap = self.formatMapValues( + layer.editorWidgetSetup(fieldIndex).config()["map"] + ) + if not (attributeValue is None) and attributeValue in valueMap: + configField.setExpression("{0}".format(valueMap[attributeValue])) elif reset: configField.setExpression("") else: - if attributeValue != '': - configField.setExpression("'{0}'".format( attributeValue ) ) + if attributeValue != "": + configField.setExpression("'{0}'".format(attributeValue)) elif reset: configField.setExpression("") - layer.setDefaultValueDefinition( fieldIndex, configField ) + layer.setDefaultValueDefinition(fieldIndex, configField) def formatMapValues(self, mapValues): - if not(type(mapValues) is list): + if not (type(mapValues) is list): return mapValues newMapValues = {} for field in mapValues: @@ -153,53 +170,49 @@ def getDefaultFields(self, layer): attributesValues = {} primaryKeyIndexes = layer.dataProvider().pkAttributeIndexes() for fieldIndex in layer.attributeList(): - fieldName = layer.fields().field( fieldIndex ).name() + fieldName = layer.fields().field(fieldIndex).name() if fieldIndex in primaryKeyIndexes: continue - configField = layer.defaultValueDefinition( fieldIndex ) - attributesValues[ fieldName ] = configField.expression() + configField = layer.defaultValueDefinition(fieldIndex) + attributesValues[fieldName] = configField.expression() return attributesValues def setActiveLayer(self, layer): - iface.setActiveLayer( layer ) + iface.setActiveLayer(layer) layer.startEditing() - iface.actionAddFeature().trigger() + iface.actionAddFeature().trigger() def setLayerVariable(self, layer, key, value): - core.QgsExpressionContextUtils.setLayerVariable( - layer, - key, - value - ) + core.QgsExpressionContextUtils.setLayerVariable(layer, key, value) def getLayerVariable(self, layer, key): - return core.QgsExpressionContextUtils.layerScope( layer ).variable( key ) + return core.QgsExpressionContextUtils.layerScope(layer).variable(key) def attributeSelectedFeatures(self, layer, attributes): layer.startEditing() features = layer.selectedFeatures() for feature in features: - self.attributeFeature( feature, layer, attributes ) - layer.updateFeature( feature ) + self.attributeFeature(feature, layer, attributes) + layer.updateFeature(feature) self.canvasRefresh() def attributeFeature(self, feature, layer, attributes): for fieldName in attributes: - indx = layer.fields().indexFromName( fieldName ) + indx = layer.fields().indexFromName(fieldName) if indx < 0: continue - config = layer.editorWidgetSetup( indx ).config() - isMapValue = ('map' in config) - attributeValue = attributes[ fieldName ] + config = layer.editorWidgetSetup(indx).config() + isMapValue = "map" in config + attributeValue = attributes[fieldName] if isMapValue: - valueMap = self.formatMapValues( config['map'] ) + valueMap = self.formatMapValues(config["map"]) if attributeValue in valueMap: - feature.setAttribute( indx, valueMap[ attributeValue ] ) - elif attributeValue and not( attributeValue in ['NULL', 'IGNORAR'] ): - """ if re.match('^\@value\(".+"\)$', value): - variable = value.split('"')[-2] - value = ProjectQgis(self.iface).getVariableProject(variable) """ - feature.setAttribute( indx, attributeValue ) + feature.setAttribute(indx, valueMap[attributeValue]) + elif attributeValue and not (attributeValue in ["NULL", "IGNORAR"]): + """if re.match('^\@value\(".+"\)$', value): + variable = value.split('"')[-2] + value = ProjectQgis(self.iface).getVariableProject(variable)""" + feature.setAttribute(indx, attributeValue) def cutAndPasteSelectedFeatures(self, layer, destinatonLayer, attributes): layer.startEditing() @@ -208,49 +221,55 @@ def cutAndPasteSelectedFeatures(self, layer, destinatonLayer, attributes): newFeatures = [] for feature in features: newFeat = core.QgsFeature() - newFeat.setFields( destinatonLayer.fields() ) - newFeat.setGeometry( feature.geometry() ) - self.attributeFeature( newFeat, destinatonLayer, attributes ) - newFeatures.append( newFeat ) + newFeat.setFields(destinatonLayer.fields()) + newGeom = feature.geometry().pointOnSurface() \ + if destinatonLayer.geometryType() == core.QgsWkbTypes.PointGeometry \ + and layer.geometryType() == core.QgsWkbTypes.PolygonGeometry \ + else feature.geometry() + newFeat.setGeometry(newGeom) + self.attributeFeature(newFeat, destinatonLayer, attributes) + newFeatures.append(newFeat) layer.deleteSelectedFeatures() - destinatonLayer.addFeatures( newFeatures ) + destinatonLayer.addFeatures(newFeatures) self.canvasRefresh() def startToolByName(self, name): - action = self.actionsFactory.getAction( name ) + action = self.actionsFactory.getAction(name) action.execute() def connectSignal(self, signalName, callback): signals = self.getSignals() - signal = signals[ signalName ] if signalName in signals else None + signal = signals[signalName] if signalName in signals else None if not signal: return - signal.connect( callback ) + signal.connect(callback) def disconnectSignal(self, signalName, callback): signals = self.getSignals() - signal = signals[ signalName ] if signalName in signals else None + signal = signals[signalName] if signalName in signals else None if not signal: return try: - signal.disconnect( callback ) + signal.disconnect(callback) except Exception as e: pass def getSignals(self): return { - 'StartAddFeature': iface.actionAddFeature().toggled, - 'ClickLayerTreeView': iface.layerTreeView().clicked, - 'AddLayerTreeView': core.QgsProject.instance().legendLayersAdded, - 'StartEditing': iface.actionToggleEditing().triggered + "StartAddFeature": iface.actionAddFeature().toggled, + "ClickLayerTreeView": iface.layerTreeView().clicked, + "AddLayerTreeView": core.QgsProject.instance().legendLayersAdded, + "StartEditing": iface.actionToggleEditing().triggered, } - + def suppressLayerForm(self, layer, suppress): setup = layer.editFormConfig() setup.setSuppress( - core.QgsEditFormConfig.SuppressOn if suppress else core.QgsEditFormConfig.SuppressOff + core.QgsEditFormConfig.SuppressOn + if suppress + else core.QgsEditFormConfig.SuppressOff ) layer.setEditFormConfig(setup) def canvasRefresh(self): - iface.mapCanvas().refresh() \ No newline at end of file + iface.mapCanvas().refresh() diff --git a/DsgTools/Modules/qgis/factories/actionsFactory.py b/DsgTools/Modules/qgis/factories/actionsFactory.py index 2d5f405c2..b9c113df4 100644 --- a/DsgTools/Modules/qgis/factories/actionsFactory.py +++ b/DsgTools/Modules/qgis/factories/actionsFactory.py @@ -8,7 +8,9 @@ from DsgTools.Modules.qgis.actions.openAttributeTable import OpenAttributeTable from DsgTools.Modules.qgis.actions.restoreFields import RestoreFields from DsgTools.Modules.qgis.actions.setDefaultFields import SetDefaultFields -from DsgTools.Modules.qgis.actions.openAttributeTableOnlySelection import OpenAttributeTableOnlySelection +from DsgTools.Modules.qgis.actions.openAttributeTableOnlySelection import ( + OpenAttributeTableOnlySelection, +) from DsgTools.Modules.qgis.actions.moveFeature import MoveFeature from DsgTools.Modules.qgis.actions.mergeFeatureAttributes import MergeFeatureAttributes from DsgTools.Modules.qgis.actions.deleteSelected import DeleteSelected @@ -17,36 +19,36 @@ from DsgTools.Modules.qgis.actions.trimExtendFeature import TrimExtendFeature from DsgTools.Modules.qgis.actions.addRing import AddRing from DsgTools.Modules.qgis.actions.deleteRing import DeleteRing -from DsgTools.Modules.qgis.actions.rightDegreeAngleDigitizing import RightDegreeAngleDigitizing +from DsgTools.Modules.qgis.actions.rightDegreeAngleDigitizing import ( + RightDegreeAngleDigitizing, +) from DsgTools.Modules.qgis.actions.freeHandReshape import FreeHandReshape -class ActionsFactory: +class ActionsFactory: def __init__(self): pass def getAction(self, actionName): actions = { - 'SelectRaster': SelectRaster, - 'AddPointFeature': AddPointFeature, - 'SelectFeature': SelectFeature, - 'SetFeatureInspector': SetFeatureInspector, - 'TopologicalSnapping': TopologicalSnapping, - 'OpenAttributeTable': OpenAttributeTable, - 'RestoreFields': RestoreFields, - 'SetDefaultFields': SetDefaultFields, - 'OpenAttributeTableOnlySelection': OpenAttributeTableOnlySelection, - 'MoveFeature': MoveFeature, - 'MergeFeatureAttributes': MergeFeatureAttributes, - 'DeleteSelected': DeleteSelected, - 'FreeHand': FreeHand, - 'CutFeatures': CutFeatures, - 'TrimExtendFeature': TrimExtendFeature, - 'AddRing': AddRing, - 'DeleteRing': DeleteRing, - 'RightDegreeAngleDigitizing': RightDegreeAngleDigitizing, - 'FreeHandReshape': FreeHandReshape + "SelectRaster": SelectRaster, + "AddPointFeature": AddPointFeature, + "SelectFeature": SelectFeature, + "SetFeatureInspector": SetFeatureInspector, + "TopologicalSnapping": TopologicalSnapping, + "OpenAttributeTable": OpenAttributeTable, + "RestoreFields": RestoreFields, + "SetDefaultFields": SetDefaultFields, + "OpenAttributeTableOnlySelection": OpenAttributeTableOnlySelection, + "MoveFeature": MoveFeature, + "MergeFeatureAttributes": MergeFeatureAttributes, + "DeleteSelected": DeleteSelected, + "FreeHand": FreeHand, + "CutFeatures": CutFeatures, + "TrimExtendFeature": TrimExtendFeature, + "AddRing": AddRing, + "DeleteRing": DeleteRing, + "RightDegreeAngleDigitizing": RightDegreeAngleDigitizing, + "FreeHandReshape": FreeHandReshape, } return actions[actionName]() if actionName in actions else None - - diff --git a/DsgTools/Modules/utils/factories/messageFactory.py b/DsgTools/Modules/utils/factories/messageFactory.py index b02c80442..470f85ee9 100644 --- a/DsgTools/Modules/utils/factories/messageFactory.py +++ b/DsgTools/Modules/utils/factories/messageFactory.py @@ -1,16 +1,15 @@ -from DsgTools.Modules.utils.message.htmlMessageDialog import HtmlMessageDialog -from DsgTools.Modules.utils.message.infoMessageBox import InfoMessageBox -from DsgTools.Modules.utils.message.errorMessageBox import ErrorMessageBox -from DsgTools.Modules.utils.message.questionMessageBox import QuestionMessageBox +from DsgTools.Modules.utils.message.htmlMessageDialog import HtmlMessageDialog +from DsgTools.Modules.utils.message.infoMessageBox import InfoMessageBox +from DsgTools.Modules.utils.message.errorMessageBox import ErrorMessageBox +from DsgTools.Modules.utils.message.questionMessageBox import QuestionMessageBox -class MessageFactory: +class MessageFactory: def createMessage(self, messageType): messageTypes = { - 'HtmlMessageDialog': HtmlMessageDialog, - 'InfoMessageBox': InfoMessageBox, - 'ErrorMessageBox': ErrorMessageBox, - 'QuestionMessageBox': QuestionMessageBox - + "HtmlMessageDialog": HtmlMessageDialog, + "InfoMessageBox": InfoMessageBox, + "ErrorMessageBox": ErrorMessageBox, + "QuestionMessageBox": QuestionMessageBox, } - return messageTypes[messageType]() \ No newline at end of file + return messageTypes[messageType]() diff --git a/DsgTools/Modules/utils/factories/utilsFactory.py b/DsgTools/Modules/utils/factories/utilsFactory.py index 36bd1a098..0ca8a8bbb 100644 --- a/DsgTools/Modules/utils/factories/utilsFactory.py +++ b/DsgTools/Modules/utils/factories/utilsFactory.py @@ -1,6 +1,6 @@ -from DsgTools.Modules.utils.factories.messageFactory import MessageFactory +from DsgTools.Modules.utils.factories.messageFactory import MessageFactory -class UtilsFactory: +class UtilsFactory: def createMessageFactory(self): - return MessageFactory() \ No newline at end of file + return MessageFactory() diff --git a/DsgTools/Modules/utils/message/errorMessageBox.py b/DsgTools/Modules/utils/message/errorMessageBox.py index f2ba49851..ac45ad987 100644 --- a/DsgTools/Modules/utils/message/errorMessageBox.py +++ b/DsgTools/Modules/utils/message/errorMessageBox.py @@ -1,14 +1,10 @@ import os from PyQt5 import QtWidgets, uic -class ErrorMessageBox: +class ErrorMessageBox: def __init__(self): super(ErrorMessageBox, self).__init__() def show(self, parent, title, text): - QtWidgets.QMessageBox.critical( - parent, - title, - text - ) \ No newline at end of file + QtWidgets.QMessageBox.critical(parent, title, text) diff --git a/DsgTools/Modules/utils/message/htmlMessageDialog.py b/DsgTools/Modules/utils/message/htmlMessageDialog.py index 8118a75e5..99c96c096 100644 --- a/DsgTools/Modules/utils/message/htmlMessageDialog.py +++ b/DsgTools/Modules/utils/message/htmlMessageDialog.py @@ -1,22 +1,21 @@ - import os from PyQt5 import QtWidgets, uic -class HtmlMessageDialog(QtWidgets.QDialog): +class HtmlMessageDialog(QtWidgets.QDialog): def __init__(self): super(HtmlMessageDialog, self).__init__() uic.loadUi(self.getUIPath(), self) - + def getUIPath(self): return os.path.join( os.path.abspath(os.path.dirname(__file__)), - '..', - 'uis', - 'htmlMessageDialog.ui' + "..", + "uis", + "htmlMessageDialog.ui", ) def show(self, parent, title, html): self.setWindowTitle(title) self.textEdit.setHtml(html) - self.exec_() \ No newline at end of file + self.exec_() diff --git a/DsgTools/Modules/utils/message/infoMessageBox.py b/DsgTools/Modules/utils/message/infoMessageBox.py index 6e68a8861..01c69cb78 100644 --- a/DsgTools/Modules/utils/message/infoMessageBox.py +++ b/DsgTools/Modules/utils/message/infoMessageBox.py @@ -1,14 +1,10 @@ import os from PyQt5 import QtWidgets, uic -class InfoMessageBox: +class InfoMessageBox: def __init__(self): super(InfoMessageBox, self).__init__() def show(self, parent, title, text): - QtWidgets.QMessageBox.information( - parent, - title, - text - ) \ No newline at end of file + QtWidgets.QMessageBox.information(parent, title, text) diff --git a/DsgTools/Modules/utils/message/questionMessageBox.py b/DsgTools/Modules/utils/message/questionMessageBox.py index 64028e291..1c6fdf0a9 100644 --- a/DsgTools/Modules/utils/message/questionMessageBox.py +++ b/DsgTools/Modules/utils/message/questionMessageBox.py @@ -1,15 +1,11 @@ import os from PyQt5 import QtWidgets, uic -class QuestionMessageBox: +class QuestionMessageBox: def __init__(self): super(QuestionMessageBox, self).__init__() def show(self, parent, title, text): - result = QtWidgets.QMessageBox.question( - parent, - title, - text - ) - return result == 16384 \ No newline at end of file + result = QtWidgets.QMessageBox.question(parent, title, text) + return result == 16384 diff --git a/DsgTools/core/DSGToolsProcessingAlgs/Algs/EditingAlgs/createEditingGridAlgorithm.py b/DsgTools/core/DSGToolsProcessingAlgs/Algs/EditingAlgs/createEditingGridAlgorithm.py index cb0c9b2b5..04eb51241 100644 --- a/DsgTools/core/DSGToolsProcessingAlgs/Algs/EditingAlgs/createEditingGridAlgorithm.py +++ b/DsgTools/core/DSGToolsProcessingAlgs/Algs/EditingAlgs/createEditingGridAlgorithm.py @@ -25,53 +25,56 @@ from qgis.PyQt.Qt import QVariant from PyQt5.QtCore import QCoreApplication from ....EditingTools.gridAndLabelCreator import GridAndLabelCreator -from qgis.core import (QgsProcessing, - QgsFeatureSink, - QgsProcessingAlgorithm, - QgsProcessingParameterFeatureSource, - QgsProcessingParameterFeatureSink, - QgsFeature, - QgsDataSourceUri, - QgsProcessingOutputVectorLayer, - QgsProcessingParameterVectorLayer, - QgsWkbTypes, - QgsProcessingParameterBoolean, - QgsProcessingParameterEnum, - QgsProcessingParameterNumber, - QgsProcessingParameterMultipleLayers, - QgsProcessingUtils, - QgsSpatialIndex, - QgsGeometry, - QgsProcessingParameterField, - QgsProcessingMultiStepFeedback, - QgsProcessingParameterFile, - QgsProcessingParameterExpression, - QgsProcessingException, - QgsProcessingParameterString, - QgsProcessingParameterDefinition, - QgsProcessingParameterType, - QgsProcessingParameterCrs, - QgsCoordinateTransform, - QgsProject, - QgsCoordinateReferenceSystem, - QgsField, - QgsFields) +from qgis.core import ( + QgsProcessing, + QgsFeatureSink, + QgsProcessingAlgorithm, + QgsProcessingParameterFeatureSource, + QgsProcessingParameterFeatureSink, + QgsFeature, + QgsDataSourceUri, + QgsProcessingOutputVectorLayer, + QgsProcessingParameterVectorLayer, + QgsWkbTypes, + QgsProcessingParameterBoolean, + QgsProcessingParameterEnum, + QgsProcessingParameterNumber, + QgsProcessingParameterMultipleLayers, + QgsProcessingUtils, + QgsSpatialIndex, + QgsGeometry, + QgsProcessingParameterField, + QgsProcessingMultiStepFeedback, + QgsProcessingParameterFile, + QgsProcessingParameterExpression, + QgsProcessingException, + QgsProcessingParameterString, + QgsProcessingParameterDefinition, + QgsProcessingParameterType, + QgsProcessingParameterCrs, + QgsCoordinateTransform, + QgsProject, + QgsCoordinateReferenceSystem, + QgsField, + QgsFields, +) + class CreateEditingGridAlgorithm(QgsProcessingAlgorithm): - INPUT = 'INPUT' - ATTRIBUTE_INDEX = 'ATTRIBUTE_INDEX' - ATTRIBUTE_ID = 'ATTRIBUTE_ID' - ID_VALUE = 'ID_VALUE' - CROSSES_X = 'CROSSES_X' - CROSSES_Y = 'CROSSES_Y' - SPACING = 'SPACING' - MAP_SCALE = 'MAP_SCALE' - COLOR = 'COLOR' - FONT = 'FONT' - FONT_SIZE = 'FONT_SIZE' - FONT_LL = 'FONT_LL' - COLOR_LL = 'COLOR_LL' - OUTPUT = 'OUTPUT' + INPUT = "INPUT" + ATTRIBUTE_INDEX = "ATTRIBUTE_INDEX" + ATTRIBUTE_ID = "ATTRIBUTE_ID" + ID_VALUE = "ID_VALUE" + CROSSES_X = "CROSSES_X" + CROSSES_Y = "CROSSES_Y" + SPACING = "SPACING" + MAP_SCALE = "MAP_SCALE" + COLOR = "COLOR" + FONT = "FONT" + FONT_SIZE = "FONT_SIZE" + FONT_LL = "FONT_LL" + COLOR_LL = "COLOR_LL" + OUTPUT = "OUTPUT" def initAlgorithm(self, config): """ @@ -79,142 +82,140 @@ def initAlgorithm(self, config): """ self.addParameter( QgsProcessingParameterVectorLayer( - self.INPUT, - self.tr('Input Layer'), - [QgsProcessing.TypeVectorPolygon] + self.INPUT, self.tr("Input Layer"), [QgsProcessing.TypeVectorPolygon] ) ) self.addParameter( QgsProcessingParameterField( - self.ATTRIBUTE_INDEX, - self.tr('INOM Field'), - None, - 'INPUT', - QgsProcessingParameterField.Any + self.ATTRIBUTE_INDEX, + self.tr("INOM Field"), + None, + "INPUT", + QgsProcessingParameterField.Any, ) ) self.addParameter( QgsProcessingParameterField( - self.ATTRIBUTE_ID, - self.tr('ID Field'), - None, - 'INPUT', - QgsProcessingParameterField.Any + self.ATTRIBUTE_ID, + self.tr("ID Field"), + None, + "INPUT", + QgsProcessingParameterField.Any, ) ) self.addParameter( QgsProcessingParameterNumber( self.ID_VALUE, - self.tr('ID Field Value'), + self.tr("ID Field Value"), minValue=0, type=QgsProcessingParameterNumber.Integer, - defaultValue=1 + defaultValue=1, ) ) self.addParameter( QgsProcessingParameterNumber( self.CROSSES_X, - self.tr('Number of horizontal crosses'), + self.tr("Number of horizontal crosses"), minValue=0, type=QgsProcessingParameterNumber.Integer, - defaultValue=4 + defaultValue=4, ) ) self.addParameter( QgsProcessingParameterNumber( self.CROSSES_Y, - self.tr('Number of vertical crosses'), + self.tr("Number of vertical crosses"), minValue=0, type=QgsProcessingParameterNumber.Integer, - defaultValue=4 + defaultValue=4, ) ) self.addParameter( QgsProcessingParameterNumber( self.SPACING, - self.tr('UTM Grid Spacing'), + self.tr("UTM Grid Spacing"), minValue=0, type=QgsProcessingParameterNumber.Integer, - defaultValue=4000 + defaultValue=4000, ) ) self.addParameter( QgsProcessingParameterNumber( self.MAP_SCALE, - self.tr('Map scale (in thousands)'), + self.tr("Map scale (in thousands)"), minValue=0, type=QgsProcessingParameterNumber.Double, - defaultValue=25 + defaultValue=25, ) ) - colorParameter = ParameterColor( - self.COLOR, - description=self.tr('Color') - ) - colorParameter.setMetadata({ - 'widget_wrapper' : 'DsgTools.gui.ProcessingUI.colorWidgetWrapper.ColorWidgetWrapper' - }) + colorParameter = ParameterColor(self.COLOR, description=self.tr("Color")) + colorParameter.setMetadata( + { + "widget_wrapper": "DsgTools.gui.ProcessingUI.colorWidgetWrapper.ColorWidgetWrapper" + } + ) self.addParameter(colorParameter) fontParameter = ParameterFont( - self.FONT, - description=self.tr('Font of the label') - ) - fontParameter.setMetadata({ - 'widget_wrapper' : 'DsgTools.gui.ProcessingUI.fontWidgetWrapper.FontWidgetWrapper' - }) + self.FONT, description=self.tr("Font of the label") + ) + fontParameter.setMetadata( + { + "widget_wrapper": "DsgTools.gui.ProcessingUI.fontWidgetWrapper.FontWidgetWrapper" + } + ) self.addParameter(fontParameter) self.addParameter( QgsProcessingParameterNumber( self.FONT_SIZE, - self.tr('Font Size'), + self.tr("Font Size"), minValue=0, type=QgsProcessingParameterNumber.Double, - defaultValue=1.5 + defaultValue=1.5, ) ) fontParameter = ParameterFont( - self.FONT_LL, - description=self.tr('Font of the LatLong label') - ) - fontParameter.setMetadata({ - 'widget_wrapper' : 'DsgTools.gui.ProcessingUI.fontWidgetWrapper.FontWidgetWrapper' - }) + self.FONT_LL, description=self.tr("Font of the LatLong label") + ) + fontParameter.setMetadata( + { + "widget_wrapper": "DsgTools.gui.ProcessingUI.fontWidgetWrapper.FontWidgetWrapper" + } + ) self.addParameter(fontParameter) colorParameter = ParameterColor( - self.COLOR_LL, - description=self.tr('Lat Long Color') - ) - colorParameter.setMetadata({ - 'widget_wrapper' : 'DsgTools.gui.ProcessingUI.colorWidgetWrapper.ColorWidgetWrapper' - }) + self.COLOR_LL, description=self.tr("Lat Long Color") + ) + colorParameter.setMetadata( + { + "widget_wrapper": "DsgTools.gui.ProcessingUI.colorWidgetWrapper.ColorWidgetWrapper" + } + ) self.addParameter(colorParameter) self.addOutput( QgsProcessingOutputVectorLayer( - self.OUTPUT, - self.tr('Original layer with assigned styles') + self.OUTPUT, self.tr("Original layer with assigned styles") ) ) - + def parameterAsColor(self, parameters, name, context): return parameters[name] - + def parameterAsFont(self, parameters, name, context): return parameters[name] - def processAlgorithm(self, parameters, context, feedback): """ Here is where the processing itself takes place. @@ -232,7 +233,21 @@ def processAlgorithm(self, parameters, context, feedback): font = self.parameterAsFont(parameters, self.FONT, context) fontLL = self.parameterAsFont(parameters, self.FONT_LL, context) llcolor = self.parameterAsColor(parameters, self.COLOR_LL, context) - GridAndLabelCreator().geo_test(inputLyr, attribute, id_attribute, id_value, spacing, crossX, crossY, scale, color, fontSize, font, fontLL, llcolor) + GridAndLabelCreator().geo_test( + inputLyr, + attribute, + id_attribute, + id_value, + spacing, + crossX, + crossY, + scale, + color, + fontSize, + font, + fontLL, + llcolor, + ) return {self.OUTPUT: inputLyr} @@ -244,21 +259,21 @@ def name(self): lowercase alphanumeric characters only and no spaces or other formatting characters. """ - return 'createeditinggrid' + return "createeditinggrid" def displayName(self): """ Returns the translated algorithm name, which should be used for any user-visible display of the algorithm name. """ - return self.tr('Create Editing Grid') + return self.tr("Create Editing Grid") def group(self): """ Returns the name of the group this algorithm belongs to. This string should be localised. """ - return self.tr('Editing Algorithms') + return self.tr("Editing Algorithms") def groupId(self): """ @@ -268,17 +283,16 @@ def groupId(self): contain lowercase alphanumeric characters only and no spaces or other formatting characters. """ - return 'DSGTools: Editing Algorithms' + return "DSGTools: Editing Algorithms" def tr(self, string): - return QCoreApplication.translate('CreateEditingGridAlgorithm', string) + return QCoreApplication.translate("CreateEditingGridAlgorithm", string) def createInstance(self): return CreateEditingGridAlgorithm() class ParameterFontType(QgsProcessingParameterType): - def __init__(self): super().__init__() @@ -286,20 +300,22 @@ def create(self, name): return ParameterFont(name) def metadata(self): - return {'widget_wrapper': 'DsgTools.gui.ProcessingUI.fontWidgetWrapper.FontWidgetWrapper'} + return { + "widget_wrapper": "DsgTools.gui.ProcessingUI.fontWidgetWrapper.FontWidgetWrapper" + } def name(self): - return QCoreApplication.translate('Processing', 'Font Parameter') + return QCoreApplication.translate("Processing", "Font Parameter") def id(self): - return 'font' + return "font" def description(self): - return QCoreApplication.translate('Processing', 'Font parameter.') + return QCoreApplication.translate("Processing", "Font parameter.") -class ParameterFont(QgsProcessingParameterDefinition): - def __init__(self, name, description=''): +class ParameterFont(QgsProcessingParameterDefinition): + def __init__(self, name, description=""): super().__init__(name, description) def clone(self): @@ -311,7 +327,7 @@ def type(self): @staticmethod def typeName(): - return 'font' + return "font" def checkValueIsAcceptable(self, value, context=None): return True @@ -326,8 +342,8 @@ def asScriptCode(self): def fromScriptCode(cls, name, description, isOptional, definition): raise NotImplementedError() -class ParameterColorType(QgsProcessingParameterType): +class ParameterColorType(QgsProcessingParameterType): def __init__(self): super().__init__() @@ -335,20 +351,22 @@ def create(self, name): return ParameterColor(name) def metadata(self): - return {'widget_wrapper': 'DsgTools.gui.ProcessingUI.fontWidgetWrapper.ColorWidgetWrapper'} + return { + "widget_wrapper": "DsgTools.gui.ProcessingUI.fontWidgetWrapper.ColorWidgetWrapper" + } def name(self): - return QCoreApplication.translate('Processing', 'Color Parameter') + return QCoreApplication.translate("Processing", "Color Parameter") def id(self): - return 'color' + return "color" def description(self): - return QCoreApplication.translate('Processing', 'Color parameter.') + return QCoreApplication.translate("Processing", "Color parameter.") -class ParameterColor(QgsProcessingParameterDefinition): - def __init__(self, name, description=''): +class ParameterColor(QgsProcessingParameterDefinition): + def __init__(self, name, description=""): super().__init__(name, description) def clone(self): @@ -360,7 +378,7 @@ def type(self): @staticmethod def typeName(): - return 'color' + return "color" def checkValueIsAcceptable(self, value, context=None): return True @@ -373,4 +391,4 @@ def asScriptCode(self): @classmethod def fromScriptCode(cls, name, description, isOptional, definition): - raise NotImplementedError() \ No newline at end of file + raise NotImplementedError() diff --git a/DsgTools/core/DSGToolsProcessingAlgs/Algs/EnvironmentSetterAlgs/setFreeHandToolParametersAlgorithm.py b/DsgTools/core/DSGToolsProcessingAlgs/Algs/EnvironmentSetterAlgs/setFreeHandToolParametersAlgorithm.py index a654da589..27dcd481f 100644 --- a/DsgTools/core/DSGToolsProcessingAlgs/Algs/EnvironmentSetterAlgs/setFreeHandToolParametersAlgorithm.py +++ b/DsgTools/core/DSGToolsProcessingAlgs/Algs/EnvironmentSetterAlgs/setFreeHandToolParametersAlgorithm.py @@ -26,47 +26,50 @@ from time import sleep from PyQt5.QtCore import QCoreApplication from qgis.PyQt.QtCore import QSettings -from qgis.core import (QgsProcessing, - QgsFeatureSink, - QgsProcessingAlgorithm, - QgsProcessingParameterFeatureSource, - QgsProcessingParameterFeatureSink, - QgsFeature, - QgsDataSourceUri, - QgsProcessingOutputVectorLayer, - QgsProcessingParameterVectorLayer, - QgsWkbTypes, - QgsProcessingParameterBoolean, - QgsProcessingParameterEnum, - QgsProcessingParameterNumber, - QgsProcessingParameterMultipleLayers, - QgsProcessingUtils, - QgsSpatialIndex, - QgsGeometry, - QgsProcessingParameterField, - QgsProcessingMultiStepFeedback, - QgsProcessingParameterFile, - QgsProcessingParameterExpression, - QgsProcessingException, - QgsProcessingParameterString, - QgsProcessingParameterDefinition, - QgsProcessingParameterType) +from qgis.core import ( + QgsProcessing, + QgsFeatureSink, + QgsProcessingAlgorithm, + QgsProcessingParameterFeatureSource, + QgsProcessingParameterFeatureSink, + QgsFeature, + QgsDataSourceUri, + QgsProcessingOutputVectorLayer, + QgsProcessingParameterVectorLayer, + QgsWkbTypes, + QgsProcessingParameterBoolean, + QgsProcessingParameterEnum, + QgsProcessingParameterNumber, + QgsProcessingParameterMultipleLayers, + QgsProcessingUtils, + QgsSpatialIndex, + QgsGeometry, + QgsProcessingParameterField, + QgsProcessingMultiStepFeedback, + QgsProcessingParameterFile, + QgsProcessingParameterExpression, + QgsProcessingException, + QgsProcessingParameterString, + QgsProcessingParameterDefinition, + QgsProcessingParameterType, +) + class SetFreeHandToolParametersAlgorithm(QgsProcessingAlgorithm): - FREE_HAND_TOLERANCE = 'FREE_HAND_TOLERANCE' - FREE_HAND_SMOOTH_ITERATIONS = 'FREE_HAND_SMOOTH_ITERATIONS' - FREE_HAND_SMOOTH_OFFSET = 'FREE_HAND_SMOOTH_OFFSET' - ALG_ITERATIONS = 'ALG_ITERATIONS' - UNDO_POINTS = 'UNDO_POINTS' - FREE_HAND_FINAL_SIMPLIFY_TOLERANCE = 'FREE_HAND_FINAL_SIMPLIFY_TOLERANCE' + FREE_HAND_TOLERANCE = "FREE_HAND_TOLERANCE" + FREE_HAND_SMOOTH_ITERATIONS = "FREE_HAND_SMOOTH_ITERATIONS" + FREE_HAND_SMOOTH_OFFSET = "FREE_HAND_SMOOTH_OFFSET" + ALG_ITERATIONS = "ALG_ITERATIONS" + UNDO_POINTS = "UNDO_POINTS" + FREE_HAND_FINAL_SIMPLIFY_TOLERANCE = "FREE_HAND_FINAL_SIMPLIFY_TOLERANCE" QSETTINGS_DICT = { - 'FREE_HAND_TOLERANCE' : 'freeHandTolerance', - 'FREE_HAND_SMOOTH_ITERATIONS' : 'freeHandSmoothIterations', - 'FREE_HAND_SMOOTH_OFFSET' : 'freeHandSmoothOffset', - 'ALG_ITERATIONS' : 'algIterations', - 'UNDO_POINTS' : 'undoPoints', - 'FREE_HAND_FINAL_SIMPLIFY_TOLERANCE' : 'freeHandFinalSimplifyTolerance' + "FREE_HAND_TOLERANCE": "freeHandTolerance", + "FREE_HAND_SMOOTH_ITERATIONS": "freeHandSmoothIterations", + "FREE_HAND_SMOOTH_OFFSET": "freeHandSmoothOffset", + "ALG_ITERATIONS": "algIterations", + "UNDO_POINTS": "undoPoints", + "FREE_HAND_FINAL_SIMPLIFY_TOLERANCE": "freeHandFinalSimplifyTolerance", } def initAlgorithm(self, config): @@ -76,68 +79,68 @@ def initAlgorithm(self, config): self.addParameter( QgsProcessingParameterNumber( self.FREE_HAND_TOLERANCE, - self.tr('Free hand tolerance'), + self.tr("Free hand tolerance"), minValue=0, type=QgsProcessingParameterNumber.Double, - defaultValue=2 + defaultValue=2, ) ) self.addParameter( QgsProcessingParameterNumber( self.FREE_HAND_SMOOTH_ITERATIONS, - self.tr('Free hand smooth iterations'), + self.tr("Free hand smooth iterations"), minValue=0, type=QgsProcessingParameterNumber.Integer, - defaultValue=3 + defaultValue=3, ) ) self.addParameter( QgsProcessingParameterNumber( self.FREE_HAND_SMOOTH_OFFSET, - self.tr('Free hand smooth offset'), + self.tr("Free hand smooth offset"), minValue=0, type=QgsProcessingParameterNumber.Double, - defaultValue=0.25 + defaultValue=0.25, ) ) self.addParameter( QgsProcessingParameterNumber( self.ALG_ITERATIONS, - self.tr('Free hand algorithm iterations'), + self.tr("Free hand algorithm iterations"), minValue=0, type=QgsProcessingParameterNumber.Integer, - defaultValue=2 + defaultValue=2, ) ) self.addParameter( QgsProcessingParameterNumber( self.UNDO_POINTS, - self.tr('Number of points removed on undo action'), + self.tr("Number of points removed on undo action"), minValue=0, type=QgsProcessingParameterNumber.Integer, - defaultValue=50 + defaultValue=50, ) ) self.addParameter( QgsProcessingParameterNumber( self.FREE_HAND_FINAL_SIMPLIFY_TOLERANCE, - self.tr('Free hand tolerance'), + self.tr("Free hand tolerance"), minValue=0, type=QgsProcessingParameterNumber.Double, - defaultValue=1 + defaultValue=1, ) ) - + def getValueFromQSettings(self, v): settings = QSettings() - settings.beginGroup('PythonPlugins/DsgTools/Options') + settings.beginGroup("PythonPlugins/DsgTools/Options") value = settings.value(v) settings.endGroup() return value - + def storeParametersInConfig(self, parameters): settings = QSettings() - settings.beginGroup('PythonPlugins/DsgTools/Options') + settings.beginGroup("PythonPlugins/DsgTools/Options") for key, value in parameters.items(): settings.setValue(self.QSETTINGS_DICT[key], value) settings.endGroup() @@ -158,21 +161,21 @@ def name(self): lowercase alphanumeric characters only and no spaces or other formatting characters. """ - return 'setfreehandtoolparametersalgorithm' + return "setfreehandtoolparametersalgorithm" def displayName(self): """ Returns the translated algorithm name, which should be used for any user-visible display of the algorithm name. """ - return self.tr('Set Free Hand Tool Parameters') + return self.tr("Set Free Hand Tool Parameters") def group(self): """ Returns the name of the group this algorithm belongs to. This string should be localised. """ - return self.tr('Environment Setters') + return self.tr("Environment Setters") def groupId(self): """ @@ -182,10 +185,10 @@ def groupId(self): contain lowercase alphanumeric characters only and no spaces or other formatting characters. """ - return 'DSGTools: Environment Setters' + return "DSGTools: Environment Setters" def tr(self, string): - return QCoreApplication.translate('SetFreeHandToolParametersAlgorithm', string) + return QCoreApplication.translate("SetFreeHandToolParametersAlgorithm", string) def createInstance(self): return SetFreeHandToolParametersAlgorithm() diff --git a/DsgTools/core/DSGToolsProcessingAlgs/Algs/GeometricAlgs/buildTerrainSlicingFromContoursAlgorihtm.py b/DsgTools/core/DSGToolsProcessingAlgs/Algs/GeometricAlgs/buildTerrainSlicingFromContoursAlgorihtm.py deleted file mode 100644 index acc8c6a4f..000000000 --- a/DsgTools/core/DSGToolsProcessingAlgs/Algs/GeometricAlgs/buildTerrainSlicingFromContoursAlgorihtm.py +++ /dev/null @@ -1,485 +0,0 @@ -# -*- coding: utf-8 -*- -""" -/*************************************************************************** - DsgTools - A QGIS plugin - Brazilian Army Cartographic Production Tools - ------------------- - begin : 2022-08-16 - git sha : $Format:%H$ - copyright : (C) 2022 by Philipe Borba - Cartographic Engineer @ Brazilian Army - email : borba.philipe@eb.mil.br - ***************************************************************************/ - -/*************************************************************************** - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - ***************************************************************************/ -""" - -import numpy as np -import processing -from osgeo import gdal -from PyQt5.QtCore import QCoreApplication, QVariant -from qgis.core import (QgsFeature, QgsFeatureSink, QgsField, QgsFields, - QgsGeometry, QgsProcessing, QgsProcessingAlgorithm, - QgsProcessingMultiStepFeedback, - QgsProcessingParameterFeatureSink, - QgsProcessingParameterFeatureSource, - QgsProcessingParameterNumber, - QgsProcessingParameterRasterDestination, - QgsProcessingParameterRasterLayer, QgsProcessingUtils, - QgsProject, QgsVectorLayer, QgsWkbTypes) - -from DsgTools.core.DSGToolsProcessingAlgs.algRunner import AlgRunner -from DsgTools.core.GeometricTools.geometryHandler import GeometryHandler - - -class BuildTerrainSlicingFromContoursAlgorihtm(QgsProcessingAlgorithm): - - INPUT = 'INPUT' - CONTOUR_INTERVAL = 'CONTOUR_INTERVAL' - GEOGRAPHIC_BOUNDARY = 'GEOGRAPHIC_BOUNDARY' - AREA_WITHOUT_INFORMATION_POLYGONS = 'AREA_WITHOUT_INFORMATION_POLYGONS' - WATER_BODIES_POLYGONS = 'WATER_BODIES_POLYGONS' - MIN_PIXEL_GROUP_SIZE = 'MIN_PIXEL_GROUP_SIZE' - SMOOTHING_PARAMETER = 'SMOOTHING_PARAMETER' - OUTPUT_POLYGONS = 'OUTPUT_POLYGONS' - OUTPUT_RASTER = 'OUTPUT_RASTER' - - def initAlgorithm(self, config=None): - self.addParameter( - QgsProcessingParameterRasterLayer( - self.INPUT, - self.tr('Input DEM'), - ) - ) - self.addParameter( - QgsProcessingParameterNumber( - self.CONTOUR_INTERVAL, - self.tr('Equidistance value'), - type=QgsProcessingParameterNumber.Integer, - minValue=0, - defaultValue=10 - ) - ) - - self.addParameter( - QgsProcessingParameterFeatureSource( - self.GEOGRAPHIC_BOUNDARY, - self.tr('Geographic bounds layer'), - [QgsProcessing.TypeVectorPolygon], - optional=False - ) - ) - - self.addParameter( - QgsProcessingParameterFeatureSource( - self.AREA_WITHOUT_INFORMATION_POLYGONS, - self.tr('Area without information layer'), - [QgsProcessing.TypeVectorPolygon], - optional=True - ) - ) - - self.addParameter( - QgsProcessingParameterFeatureSource( - self.WATER_BODIES_POLYGONS, - self.tr('Water bodies layer'), - [QgsProcessing.TypeVectorPolygon], - optional=True - ) - ) - - self.addParameter( - QgsProcessingParameterNumber( - self.MIN_PIXEL_GROUP_SIZE, - self.tr('Minimum pixel group size'), - type=QgsProcessingParameterNumber.Integer, - minValue=0, - defaultValue=100 - ) - ) - - self.addParameter( - QgsProcessingParameterNumber( - self.SMOOTHING_PARAMETER, - self.tr('Smoothing parameter'), - type=QgsProcessingParameterNumber.Double, - minValue=0, - defaultValue=0.001 - ) - ) - - self.addParameter( - QgsProcessingParameterFeatureSink( - self.OUTPUT_POLYGONS, - self.tr('Output polygons') - ) - ) - - self.addParameter( - QgsProcessingParameterRasterDestination( - self.OUTPUT_RASTER, - self.tr('Output slicing') - ) - ) - - def processAlgorithm(self, parameters, context, feedback): - algRunner = AlgRunner() - self.geometryHandler = GeometryHandler() - inputRaster = self.parameterAsRasterLayer(parameters, self.INPUT, context) - threshold = self.parameterAsInt( - parameters, self.CONTOUR_INTERVAL, context) - geoBoundsSource = self.parameterAsSource( - parameters, self.GEOGRAPHIC_BOUNDARY, context) - areaWithoutInformationSource = self.parameterAsSource( - parameters, self.AREA_WITHOUT_INFORMATION_POLYGONS, context) - waterBodiesSource = self.parameterAsSource( - parameters, self.WATER_BODIES_POLYGONS, context) - minPixelGroupSize = self.parameterAsInt( - parameters, self.MIN_PIXEL_GROUP_SIZE, context - ) - smoothingThreshold = self.parameterAsDouble( - parameters, self.SMOOTHING_PARAMETER, context - ) - outputRaster = self.parameterAsOutputLayer(parameters, self.OUTPUT_RASTER, context) - outputFields = self.getOutputFields() - (output_sink, output_sink_id) = self.getOutputSink(inputRaster, outputFields, parameters, context) - - multiStepFeedback = QgsProcessingMultiStepFeedback(15, feedback) #ajustar depois - currentStep = 0 - multiStepFeedback.setCurrentStep(currentStep) - - geographicBounds = self.overlayPolygonLayer( - inputLyr=parameters[self.GEOGRAPHIC_BOUNDARY], - polygonLyr=parameters[self.AREA_WITHOUT_INFORMATION_POLYGONS], - crs=inputRaster.crs() if inputRaster is not None else QgsProject.instance().crs(), - context=context, - feedback=multiStepFeedback, - operator=2 - ) if areaWithoutInformationSource is not None and \ - areaWithoutInformationSource.featureCount() > 0 else parameters[self.GEOGRAPHIC_BOUNDARY] - - currentStep += 1 - - multiStepFeedback.setCurrentStep(currentStep) - geographicBounds = self.overlayPolygonLayer( - inputLyr=geographicBounds, - polygonLyr=parameters[self.WATER_BODIES_POLYGONS], - crs=inputRaster.crs() if inputRaster is not None else QgsProject.instance().crs(), - context=context, - feedback=multiStepFeedback, - operator=2 - ) if waterBodiesSource is not None and \ - waterBodiesSource.featureCount() > 0 else geographicBounds - currentStep += 1 - - multiStepFeedback.setCurrentStep(currentStep) - clippedRaster = algRunner.runClipRasterLayer( - inputRaster, - mask=geographicBounds, - context=context, - feedback=multiStepFeedback, - noData=-9999 - ) - currentStep += 1 - - multiStepFeedback.setCurrentStep(currentStep) - slicedDEM = algRunner.runGrassMapCalcSimple( - inputA=clippedRaster, - expression=f'{threshold} * floor(A / {threshold})', - context=context, - feedback=multiStepFeedback - ) - currentStep += 1 - - multiStepFeedback.setCurrentStep(currentStep) - slicingThresholdDict = self.findSlicingThresholdDict(slicedDEM) - expression = '\n'.join( - [ - f"{a} thru {b} = {i}" for i, (a, b) in slicingThresholdDict.items() - ] - ) - currentStep += 1 - - multiStepFeedback.setCurrentStep(currentStep) - bufferedGeographicBounds = algRunner.runBuffer( - parameters[self.GEOGRAPHIC_BOUNDARY], - distance=10*smoothingThreshold, - context=context, - feedback=multiStepFeedback - ) - currentStep += 1 - multiStepFeedback.setCurrentStep(currentStep) - clippedRaster = algRunner.runClipRasterLayer( - inputRaster, - mask=bufferedGeographicBounds, - context=context, - feedback=multiStepFeedback - ) - currentStep += 1 - - multiStepFeedback.setCurrentStep(currentStep) - classifiedRaster = algRunner.runGrassReclass( - clippedRaster, expression, context=context, feedback=multiStepFeedback - ) - currentStep += 1 - - multiStepFeedback.setCurrentStep(currentStep) - sieveOutput = algRunner.runSieve( - classifiedRaster, - threshold=minPixelGroupSize, - context=context, - feedback=multiStepFeedback, - ) - currentStep += 1 - - multiStepFeedback.setCurrentStep(currentStep) - finalRaster = algRunner.runClipRasterLayer( - sieveOutput, - mask=geographicBounds, - context=context, - feedback=multiStepFeedback, - outputRaster=outputRaster - ) - currentStep += 1 - - multiStepFeedback.setCurrentStep(currentStep) - polygonLayer = algRunner.runGdalPolygonize( - sieveOutput, - context=context, - feedback=multiStepFeedback, - is_child_algorithm=True - ) - currentStep += 1 - - multiStepFeedback.setCurrentStep(currentStep) - smoothPolygons = algRunner.runChaikenSmoothing( - polygonLayer, - threshold=smoothingThreshold, - context=context, - feedback=multiStepFeedback, - is_child_algorithm=True, - ) if smoothingThreshold > 0 else polygonLayer - currentStep += 1 - - multiStepFeedback.setCurrentStep(currentStep) - overlayedPolygons = self.overlayPolygonLayer( - inputLyr=smoothPolygons, - polygonLyr=geographicBounds, - crs=inputRaster.crs() if inputRaster is not None else QgsProject.instance().crs(), - context=context, - feedback=multiStepFeedback - ) - currentStep += 1 - # multiStepFeedback.setCurrentStep(currentStep) - # cleanedPolygons = self.cleanPolyonLayer() - # currentStep += 1 - multiStepFeedback.setCurrentStep(currentStep) - algRunner.runCreateSpatialIndex(overlayedPolygons, context, feedback=multiStepFeedback) - currentStep += 1 - - featCount = overlayedPolygons.featureCount() - if featCount == 0: - return { - "OUTPUT_POLYGONS": output_sink_id, - "OUTPUT_RASTER": finalRaster, - } - - multiStepFeedback.setCurrentStep(currentStep) - stepSize = 100/featCount - valueSet = set(int(feat['a_DN']) for feat in overlayedPolygons.getFeatures()) - diff = valueSet.difference(set(range(len(valueSet)))) - def classLambda(x): - x = int(x) - if x == 0: - return x - return x - 1 if diff != set() else x - - for current, feat in enumerate(overlayedPolygons.getFeatures()): - if multiStepFeedback.isCanceled(): - break - newFeat = QgsFeature(outputFields) - newFeat['class'] = classLambda(feat['a_DN']) - newFeat['class_min'], newFeat['class_max'] = slicingThresholdDict[feat['a_DN']] - geom = self.validatePolygon(feat, overlayedPolygons) - newFeat.setGeometry(geom) - output_sink.addFeature(newFeat, QgsFeatureSink.FastInsert) - multiStepFeedback.setProgress(current * stepSize) - - return { - "OUTPUT_POLYGONS": output_sink_id, - "OUTPUT_RASTER": finalRaster, - } - - def validatePolygon(self, feat, overlayerPolygons): - geom = feat.geometry() - _, donutholes = self.geometryHandler.getOuterShellAndHoles(geom, False) - filteredHoles = [] - holesIdsToDelete = set() - if donutholes == []: - return geom - def holeWithValue(centerPoint): - centerPointBB = centerPoint.boundingBox() - for polygonFeat in overlayerPolygons.getFeatures(centerPointBB): - polygonGeom = polygonFeat.geometry() - if polygonGeom.equals(geom): - continue - if polygonGeom.intersects(centerPoint): - return True - return False - for idx, hole in enumerate(donutholes): - centerPoint = hole.pointOnSurface() - hasValue = holeWithValue(centerPoint) - if not hasValue: - holesIdsToDelete.add(idx+1) - continue - filteredHoles.append(hole) - if donutholes == filteredHoles: - return geom - geom = QgsGeometry(geom) - for idx in holesIdsToDelete: - geom.deleteRing(idx) - return geom - - def overlayPolygonLayer(self, inputLyr, polygonLyr, crs, context, feedback, operator=0): - parameters = { - 'ainput': inputLyr, - 'atype': 0, - 'binput': polygonLyr, - 'btype': 0, - 'operator': operator, - 'snap': 0, - '-t': False, - 'output': 'TEMPORARY_OUTPUT', - 'GRASS_REGION_PARAMETER': None, - 'GRASS_SNAP_TOLERANCE_PARAMETER': -1, - 'GRASS_MIN_AREA_PARAMETER': 1e-15, - 'GRASS_OUTPUT_TYPE_PARAMETER': 3, - 'GRASS_VECTOR_DSCO': '', - 'GRASS_VECTOR_LCO': '', - 'GRASS_VECTOR_EXPORT_NOCAT': False - } - x = processing.run( - 'grass7:v.overlay', - parameters, - context=context, - feedback=feedback - ) - lyr = QgsProcessingUtils.mapLayerFromString(x['output'], context) - lyr.setCrs(crs) - return lyr - - def findSlicingThresholdDict(self, inputRaster): - ds = gdal.Open(inputRaster) - npRaster = np.array(ds.GetRasterBand(1).ReadAsArray()) - npRaster = npRaster[~np.isnan(npRaster)] # removes nodata values - minValue = np.amin(npRaster) - maxValue = np.amax(npRaster) - numberOfElevationBands = self.getNumberOfElevationBands(maxValue - minValue) - areaRatioList = self.getAreaRatioList(numberOfElevationBands) - uniqueValues, uniqueCount = np.unique(npRaster, return_counts=True) - cumulativePercentage = np.cumsum(uniqueCount) / np.prod(npRaster.shape) - areaPercentageValues = uniqueCount / np.prod(npRaster.shape) - if any(areaPercentageValues >= 0.48) and numberOfElevationBands > 2: - """ - The MTM spec states that if there is an elevation slice that covers more than - 50% of the map, there must only be 2 elevation bands. - """ - idx = np.argmax(areaPercentageValues >= 0.5) - if idx == 0: - return { - 0: (int(uniqueValues[0]), int(uniqueValues[1])), - 1: (int(uniqueValues[1]), int(uniqueValues[-1])), - } - elif idx == len(areaPercentageValues): - return { - 0: (int(uniqueValues[0]), int(uniqueValues[-2])), - 1: (int(uniqueValues[-2]), int(uniqueValues[-1])), - } - else: - return { - 0: (int(uniqueValues[0]), int(uniqueValues[idx])), - 1: (int(uniqueValues[idx]), int(uniqueValues[idx+1])), - } - - if numberOfElevationBands == 2 and np.argmax(areaPercentageValues >= 0.5) == 0: - return { - 0: (int(uniqueValues[0]), int(uniqueValues[1])), - 1: (int(uniqueValues[1]), int(uniqueValues[-1])), - } - - classThresholds = list(uniqueValues[ - np.searchsorted( - cumulativePercentage, - np.cumsum(areaRatioList) - ) - ] - ) - classDict = dict() - lowerBounds = [minValue]+classThresholds if minValue not in classThresholds else classThresholds - for i, (a, b) in enumerate(zip(lowerBounds, classThresholds)): - classDict[i] = (int(a), int(b)) - return classDict - - - def getAreaRatioList(self, numberOfElevationBands): - bandDict = { - 2: [0.6, 0.4], - 3: [0.3, 0.4, 0.3], - 4: [0.2, 0.3, 0.3, 0.2], - } - return bandDict[numberOfElevationBands] - - def getOutputSink(self, inputRaster, outputFields, parameters, context): - return self.parameterAsSink( - parameters, - self.OUTPUT_POLYGONS, - context, - outputFields, - QgsWkbTypes.Polygon, - inputRaster.crs() if inputRaster is not None else QgsProject.instance().crs() - ) - - def getNumberOfElevationBands(self, range): - if range <= 100: - return 2 - elif range <= 600: - return 3 - else: - return 4 - - def getOutputFields(self): - fields = QgsFields() - fields.append(QgsField('class', QVariant.Int)) - fields.append(QgsField('class_min', QVariant.Int)) - fields.append(QgsField('class_max', QVariant.Int)) - - return fields - - - def tr(self, string): - return QCoreApplication.translate('BuildTerrainSlicingFromContoursAlgorihtm', string) - - def createInstance(self): - return BuildTerrainSlicingFromContoursAlgorihtm() - - def name(self): - return 'buildterrainslicingfromcontours' - - def displayName(self): - return self.tr('Build Terrain Slicing from Contours') - - def group(self): - return self.tr('Geometric Algorithms') - - def groupId(self): - return 'DSGTools: Geometric Algorithms' - - def shortHelpString(self): - return self.tr("O algoritmo constrói o fatiamento do terreno baseado nas curvas de nível.") diff --git a/DsgTools/core/DSGToolsProcessingAlgs/Algs/GeometricAlgs/donutHoleExtractorAlgorithm.py b/DsgTools/core/DSGToolsProcessingAlgs/Algs/GeometricAlgs/donutHoleExtractorAlgorithm.py index 3cde3c46f..2ce6f967c 100644 --- a/DsgTools/core/DSGToolsProcessingAlgs/Algs/GeometricAlgs/donutHoleExtractorAlgorithm.py +++ b/DsgTools/core/DSGToolsProcessingAlgs/Algs/GeometricAlgs/donutHoleExtractorAlgorithm.py @@ -21,35 +21,39 @@ """ - -from DsgTools.core.DSGToolsProcessingAlgs.Algs.ValidationAlgs.validationAlgorithm import ValidationAlgorithm +from DsgTools.core.DSGToolsProcessingAlgs.Algs.ValidationAlgs.validationAlgorithm import ( + ValidationAlgorithm, +) from DsgTools.core.GeometricTools.geometryHandler import GeometryHandler from DsgTools.core.GeometricTools.featureHandler import FeatureHandler from PyQt5.QtCore import QCoreApplication import processing -from qgis.core import (QgsProcessing, - QgsFeatureSink, - QgsProcessingAlgorithm, - QgsProcessingParameterFeatureSource, - QgsProcessingParameterFeatureSink, - QgsFeature, - QgsDataSourceUri, - QgsProcessingOutputVectorLayer, - QgsProcessingParameterVectorLayer, - QgsWkbTypes, - QgsProcessingParameterBoolean, - QgsProcessingParameterMultipleLayers, - QgsWkbTypes, - QgsProcessingUtils, - QgsProject) +from qgis.core import ( + QgsProcessing, + QgsFeatureSink, + QgsProcessingAlgorithm, + QgsProcessingParameterFeatureSource, + QgsProcessingParameterFeatureSink, + QgsFeature, + QgsDataSourceUri, + QgsProcessingOutputVectorLayer, + QgsProcessingParameterVectorLayer, + QgsWkbTypes, + QgsProcessingParameterBoolean, + QgsProcessingParameterMultipleLayers, + QgsWkbTypes, + QgsProcessingUtils, + QgsProject, +) + class DonutHoleExtractorAlgorithm(ValidationAlgorithm): - INPUT = 'INPUT' - SELECTED = 'SELECTED' - OUTERSHELL = 'OUTERSHELL' - DONUTHOLE = 'DONUTHOLE' + INPUT = "INPUT" + SELECTED = "SELECTED" + OUTERSHELL = "OUTERSHELL" + DONUTHOLE = "DONUTHOLE" def initAlgorithm(self, config): """ @@ -58,29 +62,22 @@ def initAlgorithm(self, config): self.addParameter( QgsProcessingParameterVectorLayer( self.INPUT, - self.tr('Input Polygon Layer'), - [QgsProcessing.TypeVectorPolygon] + self.tr("Input Polygon Layer"), + [QgsProcessing.TypeVectorPolygon], ) ) self.addParameter( QgsProcessingParameterBoolean( - self.SELECTED, - self.tr('Process only selected features') + self.SELECTED, self.tr("Process only selected features") ) ) self.addParameter( - QgsProcessingParameterFeatureSink( - self.OUTERSHELL, - self.tr('Outer Shell') - ) + QgsProcessingParameterFeatureSink(self.OUTERSHELL, self.tr("Outer Shell")) ) self.addParameter( - QgsProcessingParameterFeatureSink( - self.DONUTHOLE, - self.tr('Donut Hole') - ) + QgsProcessingParameterFeatureSink(self.DONUTHOLE, self.tr("Donut Hole")) ) def processAlgorithm(self, parameters, context, feedback): @@ -90,38 +87,61 @@ def processAlgorithm(self, parameters, context, feedback): featureHandler = FeatureHandler() inputLyr = self.parameterAsVectorLayer(parameters, self.INPUT, context) if inputLyr is None: - raise QgsProcessingException(self.invalidSourceError(parameters, self.INPUT)) - + raise QgsProcessingException( + self.invalidSourceError(parameters, self.INPUT) + ) + inputType = inputLyr.wkbType() - isMulti = QgsWkbTypes.isMultiType(int(inputType)) + isMulti = QgsWkbTypes.isMultiType(inputType) inputFields = inputLyr.fields() - + onlySelected = self.parameterAsBool(parameters, self.SELECTED, context) - (outershell_sink, outershell_dest_id) = self.parameterAsSink(parameters, self.OUTERSHELL, - context, inputFields, inputType, inputLyr.sourceCrs()) + (outershell_sink, outershell_dest_id) = self.parameterAsSink( + parameters, + self.OUTERSHELL, + context, + inputFields, + inputType, + inputLyr.sourceCrs(), + ) if outershell_sink is None: - raise QgsProcessingException(self.invalidSinkError(parameters, self.OUTERSHELL)) + raise QgsProcessingException( + self.invalidSinkError(parameters, self.OUTERSHELL) + ) - (donuthole_sink, donuthole_dest_id) = self.parameterAsSink(parameters, self.DONUTHOLE, - context, inputFields, inputType, inputLyr.sourceCrs()) + (donuthole_sink, donuthole_dest_id) = self.parameterAsSink( + parameters, + self.DONUTHOLE, + context, + inputFields, + inputType, + inputLyr.sourceCrs(), + ) if outershell_sink is None: - raise QgsProcessingException(self.invalidSinkError(parameters, self.DONUTHOLE)) + raise QgsProcessingException( + self.invalidSinkError(parameters, self.DONUTHOLE) + ) # Compute the number of steps to display within the progress bar and # get features from source - featureList, total = self.getIteratorAndFeatureCount(inputLyr, onlySelected=onlySelected) #only selected is not applied because we are using an inner layer, not the original ones + featureList, total = self.getIteratorAndFeatureCount( + inputLyr, onlySelected=onlySelected + ) # only selected is not applied because we are using an inner layer, not the original ones for current, feat in enumerate(featureList): # Stop the algorithm if cancel button has been clicked if feedback.isCanceled(): break - outerShellFeatList, donutHoleFeatList = featureHandler.getFeatureOuterShellAndHoles(feat, isMulti) + ( + outerShellFeatList, + donutHoleFeatList, + ) = featureHandler.getFeatureOuterShellAndHoles(feat, isMulti) for feat in outerShellFeatList: outershell_sink.addFeature(feat, QgsFeatureSink.FastInsert) for feat in donutHoleFeatList: donuthole_sink.addFeature(feat, QgsFeatureSink.FastInsert) # # Update the progress bar - feedback.setProgress(int(current * total)) - return {self.DONUTHOLE:outershell_dest_id, self.OUTERSHELL:outershell_dest_id} + feedback.setProgress(int(current * total)) + return {self.DONUTHOLE: donuthole_dest_id, self.OUTERSHELL: outershell_dest_id} def name(self): """ @@ -131,21 +151,21 @@ def name(self): lowercase alphanumeric characters only and no spaces or other formatting characters. """ - return 'donutholeextractor' + return "donutholeextractor" def displayName(self): """ Returns the translated algorithm name, which should be used for any user-visible display of the algorithm name. """ - return self.tr('Donut Hole Extractor') + return self.tr("Donut Hole Extractor") def group(self): """ Returns the name of the group this algorithm belongs to. This string should be localised. """ - return self.tr('Geometric Algorithms') + return self.tr("Geometric Algorithms") def groupId(self): """ @@ -155,10 +175,10 @@ def groupId(self): contain lowercase alphanumeric characters only and no spaces or other formatting characters. """ - return 'DSGTools: Geometric Algorithms' + return "DSGTools: Geometric Algorithms" def tr(self, string): - return QCoreApplication.translate('DonutHoleExtractorAlgorithm', string) + return QCoreApplication.translate("DonutHoleExtractorAlgorithm", string) def createInstance(self): return DonutHoleExtractorAlgorithm() diff --git a/DsgTools/core/DSGToolsProcessingAlgs/Algs/GeometricAlgs/extractByDE9IM.py b/DsgTools/core/DSGToolsProcessingAlgs/Algs/GeometricAlgs/extractByDE9IM.py new file mode 100644 index 000000000..9875090a4 --- /dev/null +++ b/DsgTools/core/DSGToolsProcessingAlgs/Algs/GeometricAlgs/extractByDE9IM.py @@ -0,0 +1,229 @@ +# -*- coding: utf-8 -*- +""" +/*************************************************************************** + DsgTools + A QGIS plugin + Brazilian Army Cartographic Production Tools + ------------------- + begin : 2023-04-28 + git sha : $Format:%H$ + copyright : (C) 2023 by Philipe Borba - Cartographic Engineer @ Brazilian Army + email : borba.philipe@eb.mil.br + ***************************************************************************/ +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ +""" + +from collections import defaultdict +import itertools +import json +import os + +import concurrent.futures + +from DsgTools.core.DSGToolsProcessingAlgs.Algs.ValidationAlgs.validationAlgorithm import ( + ValidationAlgorithm, +) +from DsgTools.core.DSGToolsProcessingAlgs.algRunner import AlgRunner +from DsgTools.core.GeometricTools.featureHandler import FeatureHandler +from DsgTools.core.GeometricTools.layerHandler import LayerHandler + +from qgis.PyQt.Qt import QVariant +from PyQt5.QtCore import QCoreApplication, QRegExp, QCoreApplication +from qgis.PyQt.QtGui import QRegExpValidator + +from qgis.core import ( + QgsProcessing, + QgsProcessingParameterFeatureSink, + QgsProcessingParameterVectorLayer, + QgsProcessingParameterBoolean, + QgsProcessingParameterField, + QgsProcessingException, + QgsProcessingParameterDistance, + QgsProcessingMultiStepFeedback, + QgsProcessingFeatureSourceDefinition, + QgsGeometry, + QgsProcessingParameterString, + QgsProcessingParameterNumber, + QgsProcessingParameterExpression, + QgsFeatureRequest, + QgsProcessingContext, + QgsProcessingAlgorithm, + QgsProcessingParameterFeatureSource, + QgsSpatialIndex, +) + + +class ValidationString(QgsProcessingParameterString): + """ + Auxiliary class for pre validation on measurer's names. + """ + + # __init__ not necessary + + def __init__(self, name, description=""): + super().__init__(name, description) + + def checkValueIsAcceptable(self, value, context=None): + regex = QRegExp("[FfTt012\*]{9}") + acceptable = QRegExpValidator.Acceptable + return ( + isinstance(value, str) + and QRegExpValidator(regex).validate(value, 9)[0] == acceptable + ) + + +class ExtractByDE9IMAlgorithm(QgsProcessingAlgorithm): + INPUT = "INPUT" + INTERSECT = "INTERSECT" + DE9IM = "DE9IM" + OUTPUT = "OUTPUT" + + def initAlgorithm(self, config): + """ + Parameter setting. + """ + self.addParameter( + QgsProcessingParameterFeatureSource( + self.INPUT, + self.tr("Select features from"), + [QgsProcessing.TypeVectorAnyGeometry], + ) + ) + + self.addParameter( + QgsProcessingParameterFeatureSource( + self.INTERSECT, + self.tr("By comparing features from"), + [QgsProcessing.TypeVectorAnyGeometry], + ) + ) + + param = ValidationString(self.DE9IM, description=self.tr("DE9IM")) + self.addParameter(param) + + self.addParameter( + QgsProcessingParameterFeatureSink(self.OUTPUT, self.tr("Output")) + ) + + def processAlgorithm(self, parameters, context, feedback): + """ + Here is where the processing itself takes place. + """ + self.layerHandler = LayerHandler() + self.algRunner = AlgRunner() + source = self.parameterAsSource(parameters, self.INPUT, context) + layer = self.parameterAsVectorLayer(parameters, self.INPUT, context) + intersectSource = self.parameterAsSource(parameters, self.INTERSECT, context) + de9im = self.parameterAsString(parameters, self.DE9IM, context) + + (sink, dest_id) = self.parameterAsSink( + parameters, + self.OUTPUT, + context, + source.fields(), + source.wkbType(), + source.sourceCrs(), + ) + + nFeats = intersectSource.featureCount() + if nFeats == 0: + return {self.OUTPUT: dest_id} + if de9im == "FF1FF0102": + return self.algRunner.runExtractByLocation( + inputLyr=parameters[self.INPUT], + intersectLyr=parameters[self.INTERSECT], + context=context, + feedback=feedback, + predicate=[2], + method=0, + is_child_algorithm=False, + ) + nSteps = 2 + multiStepFeedback = QgsProcessingMultiStepFeedback(nSteps, feedback) + currentStep = 0 + multiStepFeedback.setCurrentStep(currentStep) + selectedLyr = self.algRunner.runExtractByLocation( + inputLyr=parameters[self.INPUT], + intersectLyr=parameters[self.INTERSECT], + context=context, + feedback=multiStepFeedback, + predicate=[2] if de9im == "FF1FF0102" else [0], + ) + currentStep += 1 + multiStepFeedback.setCurrentStep(currentStep) + nFeats = selectedLyr.featureCount() + if nFeats == 0: + return {self.OUTPUT: dest_id} + stepSize = 100 / nFeats + + def compute(feat): + returnSet = set() + geom = feat.geometry() + bbox = geom.boundingBox() + engine = QgsGeometry.createGeometryEngine(geom.constGet()) + engine.prepareGeometry() + for f in selectedLyr.getFeatures(bbox): + if multiStepFeedback.isCanceled(): + return {} + intersectGeom = f.geometry() + if intersectGeom.isEmpty() or intersectGeom.isNull(): + continue + if engine.relatePattern(intersectGeom.constGet(), de9im): + returnSet.add(f) + return returnSet + + for current, feat in enumerate(intersectSource.getFeatures()): + if multiStepFeedback.isCanceled(): + return {} + outputSet = compute(feat) + sink.addFeatures(list(outputSet)) + multiStepFeedback.setProgress(current * stepSize) + + return {self.OUTPUT: dest_id} + + def name(self): + """ + Returns the algorithm name, used for identifying the algorithm. This + string should be fixed for the algorithm, and must not be localised. + The name should be unique within each provider. Names should contain + lowercase alphanumeric characters only and no spaces or other + formatting characters. + """ + return "extractbyde9im" + + def displayName(self): + """ + Returns the translated algorithm name, which should be used for any + user-visible display of the algorithm name. + """ + return self.tr("Extract features by DE9IM") + + def group(self): + """ + Returns the name of the group this algorithm belongs to. This string + should be localised. + """ + return self.tr("Geometric Algorithms") + + def groupId(self): + """ + Returns the unique ID of the group this algorithm belongs to. This + string should be fixed for the algorithm, and must not be localised. + The group id should be unique within each provider. Group id should + contain lowercase alphanumeric characters only and no spaces or other + formatting characters. + """ + return "DSGTools: Geometric Algorithms" + + def tr(self, string): + return QCoreApplication.translate("ExtractByDE9IMAlgorithm", string) + + def createInstance(self): + return ExtractByDE9IMAlgorithm() diff --git a/DsgTools/core/DSGToolsProcessingAlgs/Algs/GeometricAlgs/line2Multiline.py b/DsgTools/core/DSGToolsProcessingAlgs/Algs/GeometricAlgs/line2Multiline.py new file mode 100644 index 000000000..91a2326d0 --- /dev/null +++ b/DsgTools/core/DSGToolsProcessingAlgs/Algs/GeometricAlgs/line2Multiline.py @@ -0,0 +1,224 @@ +# -*- coding: utf-8 -*- +""" +/*************************************************************************** + DsgTools + A QGIS plugin + Brazilian Army Cartographic Production Tools + ------------------- + begin : 2023-05-01 + git sha : $Format:%H$ + copyright : (C) 2023 by Jossan + email : + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ +""" + +from collections import defaultdict +from qgis.PyQt.QtCore import QCoreApplication, QVariant +from qgis.core import ( + QgsProcessing, + QgsFeatureSink, + QgsProcessingAlgorithm, + QgsProcessingParameterFeatureSink, + QgsFeature, + QgsProcessingParameterFeatureSource, + QgsGeometry, + QgsLineString, + QgsProcessingMultiStepFeedback, + QgsWkbTypes, + QgsFields, + QgsField, + QgsMultiLineString, +) + +from DsgTools.core.DSGToolsProcessingAlgs.algRunner import AlgRunner + + +class Line2Multiline(QgsProcessingAlgorithm): + + INPUT = "INPUT" + OUTPUT = "OUTPUT" + + def initAlgorithm(self, config=None): + self.addParameter( + QgsProcessingParameterFeatureSource( + self.INPUT, self.tr("Select line layer"), [QgsProcessing.TypeVectorLine] + ) + ) + + self.addParameter( + QgsProcessingParameterFeatureSink(self.OUTPUT, self.tr("Output")) + ) + + def processAlgorithm(self, parameters, context, feedback): + self.algRunner = AlgRunner() + lines = self.parameterAsSource(parameters, self.INPUT, context) + + fields = QgsFields() + fields.append(QgsField("length", QVariant.String)) + (sink_l, sinkId_l) = self.parameterAsSink( + parameters, + self.OUTPUT, + context, + fields, + QgsWkbTypes.MultiLineString, + lines.sourceCrs(), + ) + multiStepFeedback = QgsProcessingMultiStepFeedback(6, feedback) + currentStep = 0 + multiStepFeedback.setCurrentStep(currentStep) + + lines = self.algRunner.runAddAutoIncrementalField( + inputLyr=parameters[self.INPUT], + context=context, + feedback=multiStepFeedback, + fieldName="AUTO", + ) + currentStep += 1 + + multiStepFeedback.setCurrentStep(currentStep) + self.algRunner.runCreateSpatialIndex( + inputLyr=lines, + context=context, + feedback=multiStepFeedback, + ) + currentStep += 1 + + multiStepFeedback.setCurrentStep(currentStep) + spatialJoinOutput = self.algRunner.runJoinAttributesByLocation( + inputLyr=lines, + joinLyr=lines, + context=context, + feedback=multiStepFeedback, + ) + currentStep += 1 + + multiStepFeedback.setCurrentStep(currentStep) + self.populateAuxStructure(lines, feedback=multiStepFeedback) + currentStep += 1 + + multiStepFeedback.setCurrentStep(currentStep) + self.buildMatchingFeaturesDict(spatialJoinOutput, feedback=multiStepFeedback) + currentStep += 1 + + multiStepFeedback.setCurrentStep(currentStep) + self.processFeatures(fields, sink_l, feedback=multiStepFeedback) + + return {self.OUTPUT: sinkId_l} + + def processFeatures(self, fields, sink_l, feedback): + nFeats = len(self.ids_in_stack) + if nFeats == 0: + return + stepSize = 100 / nFeats + current = 0 + while len(self.ids_in_stack) > 0: + if feedback.isCanceled(): + break + currentid = self.ids_in_stack.pop() + current = nFeats - len(self.ids_in_stack) + + mls_array = self.aggregate(currentid, feedback=feedback) + + mls = QgsMultiLineString() + for el in mls_array: + mls.addGeometry(QgsLineString(list(el.vertices()))) + self.addSink(QgsGeometry(mls), sink_l, fields) + feedback.setProgress(current * stepSize) + + def buildMatchingFeaturesDict(self, spatialJoinOutput, feedback): + self.matching_features = defaultdict(list) + nFeats = spatialJoinOutput.featureCount() + if nFeats == 0: + return + stepSize = 100 / nFeats + for current, feat in enumerate(spatialJoinOutput.getFeatures()): + if feedback.isCanceled(): + break + if feat["AUTO"] == feat["AUTO_2"]: + continue + self.matching_features[feat["AUTO"]].append(feat["AUTO_2"]) + feedback.setProgress(current * stepSize) + + def populateAuxStructure(self, lines, feedback): + self.id_to_feature = {} + self.ids_in_stack = set() + nFeats = lines.featureCount() + if nFeats == 0: + return + stepSize = 100 / nFeats + for current, currentFeature in enumerate(lines.getFeatures()): + if feedback.isCanceled(): + break + self.id_to_feature[currentFeature["AUTO"]] = currentFeature + self.ids_in_stack.add(currentFeature["AUTO"]) + feedback.setCurrentStep(current * stepSize) + + def aggregate(self, featureId, feedback): + stack = [featureId] + mls_array = [] + + while stack: + current_id = stack.pop() + currentfeature = self.id_to_feature[current_id] + currentgeom = currentfeature.geometry() + mls_array.append(currentgeom) + + if feedback.isCanceled(): + return mls_array + + matching_features_ids = set( + el for el in self.matching_features[current_id] if el in self.ids_in_stack + ) + + self.ids_in_stack = self.ids_in_stack - matching_features_ids + + stack.extend(matching_features_ids) + + return mls_array + + def addSink(self, geom, sink, fields): + newFeat = QgsFeature(fields) + newFeat.setGeometry(geom) + newFeat["length"] = geom.length() + sink.addFeature(newFeat, QgsFeatureSink.FastInsert) + + def tr(self, string): + return QCoreApplication.translate("Processing", string) + + def createInstance(self): + return Line2Multiline() + + def name(self): + return "line2multiline" + + def displayName(self): + return self.tr("Convert Line to Multiline") + + def group(self): + """ + Returns the name of the group this algorithm belongs to. This string + should be localised. + """ + return self.tr("Geometric Algorithms") + + def groupId(self): + """ + Returns the unique ID of the group this algorithm belongs to. This + string should be fixed for the algorithm, and must not be localised. + The group id should be unique within each provider. Group id should + contain lowercase alphanumeric characters only and no spaces or other + formatting characters. + """ + return "DSGTools: Geometric Algorithms" + + def shortHelpString(self): + return self.tr("O algoritmo converte linhas que se tocam para multilinha") diff --git a/DsgTools/core/DSGToolsProcessingAlgs/Algs/GeometricAlgs/pointsInPolygonGridAlgorithm.py b/DsgTools/core/DSGToolsProcessingAlgs/Algs/GeometricAlgs/pointsInPolygonGridAlgorithm.py new file mode 100644 index 000000000..d333eaad6 --- /dev/null +++ b/DsgTools/core/DSGToolsProcessingAlgs/Algs/GeometricAlgs/pointsInPolygonGridAlgorithm.py @@ -0,0 +1,150 @@ +# -*- coding: utf-8 -*- +""" +/*************************************************************************** + DsgTools + A QGIS plugin + Brazilian Army Cartographic Production Tools + ------------------- + begin : 2023-04-15 + git sha : $Format:%H$ + copyright : (C) 2023 by Felipe Diniz - Cartographic Engineer @ Brazilian Army + email : diniz.felipe@eb.mil.br + ***************************************************************************/ +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ +""" + +from qgis.PyQt.QtCore import QCoreApplication +from qgis.core import ( + QgsProcessing, + QgsProcessingAlgorithm, + QgsProcessingParameterFeatureSource, + QgsProcessingParameterDistance, + QgsProcessingParameterFeatureSink, +) +import math +from qgis.core import QgsFeature, QgsGeometry, QgsPointXY, QgsWkbTypes +from itertools import product + + +class PointsInPolygonGridAlgorithm(QgsProcessingAlgorithm): + INPUT = "INPUT" + X_DISTANCE = "X_DISTANCE" + Y_DISTANCE = "Y_DISTANCE" + OUTPUT = "OUTPUT" + + def tr(self, string): + return QCoreApplication.translate("Processing", string) + + def createInstance(self): + return PointsInPolygonGridAlgorithm() + + def name(self): + return "points_in_polygon_grid_old" + + def displayName(self): + return self.tr("Points In Polygon Grid old") + + def group(self): + """ + Returns the name of the group this algorithm belongs to. This string + should be localised. + """ + return self.tr("Geometric Algorithms") + + def groupId(self): + """ + Returns the unique ID of the group this algorithm belongs to. This + string should be fixed for the algorithm, and must not be localised. + The group id should be unique within each provider. Group id should + contain lowercase alphanumeric characters only and no spaces or other + formatting characters. + """ + return "DSGTools: Geometric Algorithms" + + def shortHelpString(self): + return self.tr( + "Create a layer of points evenly spaced with X and Y distances for each polygon in the input layer." + ) + + def initAlgorithm(self, config=None): + self.addParameter( + QgsProcessingParameterFeatureSource( + self.INPUT, self.tr("Input layer"), [QgsProcessing.TypeVectorPolygon] + ) + ) + self.addParameter( + QgsProcessingParameterDistance( + self.X_DISTANCE, self.tr("X Distance"), defaultValue=0.01 + ) + ) + self.addParameter( + QgsProcessingParameterDistance( + self.Y_DISTANCE, self.tr("Y Distance"), defaultValue=0.01 + ) + ) + self.addParameter( + QgsProcessingParameterFeatureSink( + self.OUTPUT, self.tr("Output point layer") + ) + ) + + def processAlgorithm(self, parameters, context, feedback): + source = self.parameterAsSource(parameters, self.INPUT, context) + x_distance = self.parameterAsDouble(parameters, self.X_DISTANCE, context) + y_distance = self.parameterAsDouble(parameters, self.Y_DISTANCE, context) + + fields = source.fields() + (sink, dest_id) = self.parameterAsSink( + parameters, + self.OUTPUT, + context, + fields, + QgsWkbTypes.Point, + source.sourceCrs(), + ) + + total = 100.0 / source.featureCount() if source.featureCount() else 0 + + for current, feature in enumerate(source.getFeatures()): + if feedback.isCanceled(): + break + + geometry = feature.geometry() + if geometry.isEmpty() or geometry.isNull(): + continue + + bbox = geometry.boundingBox() + x_min, y_min, x_max, y_max = ( + bbox.xMinimum(), + bbox.yMinimum(), + bbox.xMaximum(), + bbox.yMaximum(), + ) + + point_coordinates = ( + QgsGeometry.fromPointXY( + QgsPointXY(x_min + i * x_distance, y_min + j * y_distance) + ) + for i, j in product( + range(int(math.ceil((x_max - x_min) / x_distance)) + 1), + range(int(math.ceil((y_max - y_min) / y_distance)) + 1), + ) + ) + + for point_geom in point_coordinates: + if geometry.contains(point_geom): + new_feature = QgsFeature(fields) + new_feature.setGeometry(point_geom) + new_feature.setAttributes(feature.attributes()) + sink.addFeature(new_feature) + + feedback.setProgress(int(current * total)) + + return {self.OUTPUT: dest_id} diff --git a/DsgTools/core/DSGToolsProcessingAlgs/Algs/GeometricAlgs/reclassifyAdjecentPolygonsAlgorithm.py b/DsgTools/core/DSGToolsProcessingAlgs/Algs/GeometricAlgs/reclassifyAdjecentPolygonsAlgorithm.py new file mode 100644 index 000000000..48e4892cb --- /dev/null +++ b/DsgTools/core/DSGToolsProcessingAlgs/Algs/GeometricAlgs/reclassifyAdjecentPolygonsAlgorithm.py @@ -0,0 +1,500 @@ +# -*- coding: utf-8 -*- +""" +/*************************************************************************** + DsgTools + A QGIS plugin + Brazilian Army Cartographic Production Tools + ------------------- + begin : 2023-01-18 + git sha : $Format:%H$ + copyright : (C) 2023 by Philipe Borba - Cartographic Engineer @ Brazilian Army + email : borba.philipe@eb.mil.br + ***************************************************************************/ +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ +""" + +from collections import defaultdict +import itertools +import json +import os + +import concurrent.futures + +from DsgTools.core.DSGToolsProcessingAlgs.Algs.ValidationAlgs.validationAlgorithm import ( + ValidationAlgorithm, +) +from DsgTools.core.DSGToolsProcessingAlgs.algRunner import AlgRunner +from DsgTools.core.GeometricTools.featureHandler import FeatureHandler +from DsgTools.core.GeometricTools.layerHandler import LayerHandler + +from qgis.PyQt.Qt import QVariant +from PyQt5.QtCore import QCoreApplication + +from qgis.core import ( + QgsProcessing, + QgsProcessingParameterFeatureSink, + QgsProcessingParameterVectorLayer, + QgsProcessingParameterBoolean, + QgsProcessingParameterField, + QgsProcessingException, + QgsProcessingParameterDistance, + QgsProcessingMultiStepFeedback, + QgsProcessingFeatureSourceDefinition, + QgsGeometry, + QgsProcessingParameterString, + QgsProcessingParameterNumber, + QgsProcessingParameterExpression, + QgsFeatureRequest, + QgsProcessingContext +) + + +class ReclassifyAdjacentPolygonsAlgorithm(ValidationAlgorithm): + INPUT = "INPUT" + SELECTED = "SELECTED" + FILTER_EXPRESSION = "FILTER_EXPRESSION" + LABEL_FIELD = "LABEL_FIELD" + LABEL_ORDER = "LABEL_RULES" + DISSOLVE_ATTRIBUTE_LIST = "DISSOLVE_ATTRIBUTE_LIST" + DISSOLVE_OUTPUT = "DISSOLVE_OUTPUT" + OUTPUT = "OUTPUT" + + def initAlgorithm(self, config): + """ + Parameter setting. + """ + self.addParameter( + QgsProcessingParameterVectorLayer( + self.INPUT, + self.tr("Input Polygon Layer"), + [QgsProcessing.TypeVectorPolygon], + ) + ) + + self.addParameter( + QgsProcessingParameterBoolean( + self.SELECTED, self.tr("Process only selected features") + ) + ) + + self.addParameter( + QgsProcessingParameterField( + self.LABEL_FIELD, + self.tr("Class label field on input polygons"), + None, + self.INPUT, + QgsProcessingParameterField.Any, + allowMultiple=False, + ) + ) + + self.addParameter( + QgsProcessingParameterExpression( + self.FILTER_EXPRESSION, + self.tr("Filter expression for input"), + None, + self.INPUT, + optional=True + ) + ) + + self.addParameter( + QgsProcessingParameterString( + self.LABEL_ORDER, + description=self.tr("Label order"), + multiLine=False, + defaultValue="", + optional=True, + ) + ) + + self.addParameter( + QgsProcessingParameterBoolean( + self.DISSOLVE_OUTPUT, self.tr("Dissolve Output") + ) + ) + + self.addParameter( + QgsProcessingParameterField( + self.DISSOLVE_ATTRIBUTE_LIST, + self.tr("Fields to consider on dissolve"), + None, + "INPUT", + QgsProcessingParameterField.Any, + allowMultiple=True, + optional=True, + ) + ) + self.addParameter( + QgsProcessingParameterFeatureSink(self.OUTPUT, self.tr("Output")) + ) + + def processAlgorithm(self, parameters, context, feedback): + """ + Here is where the processing itself takes place. + """ + try: + import networkx as nx + except ImportError: + raise QgsProcessingException( + self.tr( + "This algorithm requires the Python networkx library. Please install this library and try again." + ) + ) + self.algRunner = AlgRunner() + self.layerHandler = LayerHandler() + inputLyr = self.parameterAsVectorLayer(parameters, self.INPUT, context) + if inputLyr is None: + raise QgsProcessingException( + self.invalidSourceError(parameters, self.INPUT) + ) + onlySelected = self.parameterAsBool(parameters, self.SELECTED, context) + filterExpression = self.parameterAsExpression(parameters, self.FILTER_EXPRESSION, context) + if filterExpression == '': + filterExpression = None + classFieldName = self.parameterAsFields(parameters, self.LABEL_FIELD, context)[0] + labelListStr = self.parameterAsString(parameters, self.LABEL_ORDER, context) + classOrderList = None if labelListStr == '' else labelListStr.split(",") + field = [f for f in inputLyr.fields() if f.name() == classFieldName][0] + if field.type() == QVariant.Int: + classOrderList = list(map(int, classOrderList)) + elif field.type() == QVariant.Double: + classOrderList = list(map(float, classOrderList)) + dissolveOutput = self.parameterAsBool(parameters, self.DISSOLVE_OUTPUT, context) + dissolveFields = self.parameterAsFields( + parameters, self.DISSOLVE_ATTRIBUTE_LIST, context + ) + dissolveFields = list(set(dissolveFields).union({classFieldName})) + (output_sink, output_sink_id) = self.parameterAsSink( + parameters, + self.OUTPUT, + context, + inputLyr.fields(), + inputLyr.wkbType(), + inputLyr.sourceCrs(), + ) + if output_sink is None: + raise QgsProcessingException(self.invalidSinkError(parameters, self.OUTPUT)) + nSteps = 6 + (dissolveOutput is True) + multiStepFeedback = QgsProcessingMultiStepFeedback(nSteps, feedback) + currentStep = 0 + multiStepFeedback.setCurrentStep(currentStep) + multiStepFeedback.setProgressText(self.tr("Creating cache layer")) + cacheLyr = self.algRunner.runCreateFieldWithExpression( + inputLyr=inputLyr + if not onlySelected + else QgsProcessingFeatureSourceDefinition(inputLyr.id(), True), + expression="$id", + fieldType=1, + fieldName="featid", + feedback=multiStepFeedback, + context=context, + ) + currentStep += 1 + + multiStepFeedback.setCurrentStep(currentStep) + multiStepFeedback.setProgressText(self.tr("Creating spatial index on cache")) + self.algRunner.runCreateSpatialIndex(cacheLyr, context, feedback=multiStepFeedback) + currentStep += 1 + + multiStepFeedback.setCurrentStep(currentStep) + multiStepFeedback.setProgressText(self.tr("Building aux structures")) + G, featDict, idSet = self.buildAuxStructures( + nx, cacheLyr, context, filterExpression=filterExpression, feedback=multiStepFeedback + ) + currentStep += 1 + + multiStepFeedback.setCurrentStep(currentStep) + anchorIdsSet = set(featDict.keys()).difference(idSet) + fieldNames = [field.name() for field in inputLyr.fields()] + multiStepFeedback.setProgressText(self.tr("Performing reclassification")) + featureIdsToUpdateSet = self.reclassifyPolygons( + G=G, + featDict=featDict, + anchorIdsSet=anchorIdsSet, + candidateIdSet=idSet, + fieldNames=dissolveFields, + feedback=multiStepFeedback, + classFieldName=classFieldName, + classOrderList=classOrderList, + ) + currentStep += 1 + + multiStepFeedback.setProgressText(self.tr("Changing attributes from cache")) + multiStepFeedback.setCurrentStep(currentStep) + nFeatsToUpdate = len(featureIdsToUpdateSet) + if nFeatsToUpdate == 0: + return {self.OUTPUT: output_sink_id} + stepSize = 100 / nFeatsToUpdate + cacheLyr.startEditing() + cacheLyr.beginEditCommand("Updating features") + cacheLyrDataProvider = cacheLyr.dataProvider() + fieldIdx = cacheLyrDataProvider.fields().indexFromName(classFieldName) + for current, (featid, classValue) in enumerate(featureIdsToUpdateSet): + if multiStepFeedback.isCanceled(): + break + cacheLyrDataProvider.changeAttributeValues( + { + featid: { + fieldIdx: classValue + } + } + ) + multiStepFeedback.setProgress(current * stepSize) + currentStep += 1 + cacheLyr.endEditCommand() + + multiStepFeedback.setCurrentStep(currentStep) + if dissolveOutput: + multiStepFeedback.setProgressText(self.tr("Dissolving Polygons")) + mergedLyr = self.algRunner.runDissolve( + inputLyr=cacheLyr, + context=context, + feedback=multiStepFeedback, + field=dissolveFields, + is_child_algorithm=True, + ) + currentStep += 1 + multiStepFeedback.setCurrentStep(currentStep) + mergedLyr = self.algRunner.runMultipartToSingleParts( + inputLayer=mergedLyr, context=context, feedback=multiStepFeedback + ) + currentStep += 1 + else: + mergedLyr = cacheLyr + + nFeats = mergedLyr.featureCount() + if nFeats == 0: + return {self.OUPUT: output_sink_id} + stepSize = 100 / nFeats + multiStepFeedback.setProgressText(self.tr("Building Outputs")) + for current, feat in enumerate(mergedLyr.getFeatures()): + if multiStepFeedback.isCanceled(): + break + output_sink.addFeature(feat) + multiStepFeedback.setProgress(current * stepSize) + + # Compute the number of steps to display within the progress bar and + # get features from source + + return {self.OUTPUT: output_sink_id} + + def buildAuxStructures(self, nx, inputLyr, context, filterExpression=None, feedback=None): + G = nx.Graph() + featDict = dict() + idSet = set() + multiStepFeedback = QgsProcessingMultiStepFeedback(3, feedback) + multiStepFeedback.setCurrentStep(0) + candidatesLayer = self.algRunner.runFilterExpression( + inputLyr=inputLyr, expression=filterExpression, context=context, feedback=multiStepFeedback + ) + nFeats = candidatesLayer.featureCount() + multiStepFeedback.setCurrentStep(1) + + def compute(feat, featLayer): + context = QgsProcessingContext() + algRunner = AlgRunner() + itemSet = set() + featId = feat['featid'] + if multiStepFeedback.isCanceled(): + return itemSet + extractedFeaturesLayer = algRunner.runExtractByLocation( + inputLyr=inputLyr, + intersectLyr=featLayer, + context=context, + is_child_algorithm=True + ) + if multiStepFeedback.isCanceled(): + return itemSet + extractedBoundariesLayer = algRunner.runPolygonsToLines( + inputLyr=extractedFeaturesLayer, context=context + ) + if multiStepFeedback.isCanceled(): + return itemSet + algRunner.runCreateSpatialIndex( + inputLyr=extractedBoundariesLayer, + context=context + ) + if multiStepFeedback.isCanceled(): + return itemSet + splitBounds = algRunner.runClip(extractedBoundariesLayer, featLayer, context=context) + if multiStepFeedback.isCanceled(): + return itemSet + for candidateFeat in splitBounds.getFeatures(): + if multiStepFeedback.isCanceled(): + return set((None, None, None, -1)) + candidateFeatId = candidateFeat['featid'] + if candidateFeatId == featId: + continue + candidateLength = candidateFeat.geometry().length() + if candidateLength <= 0: + continue + itemSet.add( + (featId, candidateFeatId, candidateFeat, candidateLength) + ) + return itemSet + + def build_graph(item): + featId, candidateFeatId, candidateFeat, intersectionLength = item + if featId is None: + return + if candidateFeatId not in featDict: + featDict[candidateFeatId] = candidateFeat + G.add_edge(featId, candidateFeatId) + G[featId][candidateFeatId]["length"] = intersectionLength + + if nFeats == 0: + return G, featDict, idSet + multiStepFeedback.pushInfo(f"Submitting {nFeats} features to thread.") + stepSize = 100 / nFeats + logInterval = 1000 + futures = set() + executor = concurrent.futures.ThreadPoolExecutor(max_workers=os.cpu_count()-1) + for current, feat in enumerate(candidatesLayer.getFeatures()): + if multiStepFeedback.isCanceled(): + break + featId = feat['featid'] + featDict[featId] = feat + idSet.add(featId) + featLayer = self.layerHandler.createMemoryLayerWithFeature(inputLyr, feat, context) + # result = compute(feat, featLayer) + # list(map(build_graph, result)) + futures.add(executor.submit(compute, feat, featLayer)) + multiStepFeedback.setProgress(current * stepSize) + multiStepFeedback.setCurrentStep(1) + nFeats = len(featDict) + stepSize = 100/nFeats + if nFeats == 0: + return G, featDict, idSet + + multiStepFeedback.setProgressText(self.tr(f"Starting the processess of building graph using parallel computing. Evaluating {nFeats:n} features.")) + candidateCount = 0 + for candidateCount, future in enumerate(concurrent.futures.as_completed(futures)): + if multiStepFeedback.isCanceled(): + break + result = future.result() + list(map(build_graph, result)) + if candidateCount % logInterval == 0: + multiStepFeedback.setProgressText(self.tr(f"Evaluated {candidateCount:n} / {nFeats:n} features.")) + multiStepFeedback.setProgress(candidateCount * stepSize) + + multiStepFeedback.pushInfo(self.tr(f"{nFeats:n} evaluated. Found {candidateCount:n} candidates to evaluate in next step.")) + return G, featDict, idSet + + def reclassifyPolygons( + self, G, featDict, anchorIdsSet, candidateIdSet, fieldNames, classFieldName, feedback, classOrderList=None + ): + visitedSet = set() + featureIdsToUpdateSet = set() + nIds = len(candidateIdSet) + if nIds == 0: + return featureIdsToUpdateSet + stepSize = 100 / nIds + processedFeats = 0 + + def chooseId(G, id, candidateIdSet): + if classOrderList is None: + return max(candidateIdSet, key=lambda x: G[id][x]["length"]) + auxDict = defaultdict(list) + sortedIdsByLength = sorted(candidateIdSet, key=lambda x:G[id][x]["length"], reverse=True) + if len(sortedIdsByLength) == 1: + return sortedIdsByLength[0] + for i in sortedIdsByLength: + auxDict[featDict[i][classFieldName]].append(i) + for key in classOrderList: + if key not in auxDict or len(auxDict[key]) == 0: + continue + return auxDict[key][0] + for id in set(node for node in G.nodes if G.degree(node) == 1) - anchorIdsSet: + if feedback.isCanceled(): + return featureIdsToUpdateSet + anchorId = set(G.neighbors(id)).pop() + featDict[id][classFieldName] = featDict[anchorId][classFieldName] + featureIdsToUpdateSet.add((id, featDict[id][classFieldName])) + visitedSet.add(id) + processedFeats += 1 + feedback.setProgress(processedFeats * stepSize) + visitedHolesSet = set(visitedSet) + originalAnchorIdSet = anchorIdsSet + while True: + newAnchors = set() + for anchorId in anchorIdsSet: + if feedback.isCanceled(): + return featureIdsToUpdateSet + anchorNeighborIdsSet = set(G.neighbors(anchorId)) - originalAnchorIdSet + for id in sorted( + anchorNeighborIdsSet - visitedSet - anchorIdsSet - originalAnchorIdSet, + key=lambda x: featDict[x].geometry().area(), + ): + if feedback.isCanceled(): + return featureIdsToUpdateSet + # d = set(G.neighbors(id)) - anchorIdsSet - visitedSet + candidateIdSet = set(G.neighbors(id)).intersection(anchorIdsSet) + if candidateIdSet == set(): + continue + if len(candidateIdSet) > 1: + newAnchors.add(id) + visitedSet.add(id) + processedFeats += 1 + chosenId = chooseId(G, id, candidateIdSet) + featDict[id][classFieldName] = featDict[chosenId][classFieldName] + featureIdsToUpdateSet.add((id, featDict[chosenId][classFieldName])) + newAnchors.add(id) + feedback.setProgress(processedFeats * stepSize) + anchorIdsSet = newAnchors + if anchorIdsSet == set(): + break + return featureIdsToUpdateSet + + def getAttributesFromFeature(self, newFeat, originalFeat): + pass + + def reclassifyPolygonsInParalel(self, G, featDict, anchorIdsSet, idSet): + pass + + def name(self): + """ + Returns the algorithm name, used for identifying the algorithm. This + string should be fixed for the algorithm, and must not be localised. + The name should be unique within each provider. Names should contain + lowercase alphanumeric characters only and no spaces or other + formatting characters. + """ + return "reclassifyadjacentpolygonsalgorithm" + + def displayName(self): + """ + Returns the translated algorithm name, which should be used for any + user-visible display of the algorithm name. + """ + return self.tr("Reclassify Adjacent Polygons") + + def group(self): + """ + Returns the name of the group this algorithm belongs to. This string + should be localised. + """ + return self.tr("Geometric Algorithms") + + def groupId(self): + """ + Returns the unique ID of the group this algorithm belongs to. This + string should be fixed for the algorithm, and must not be localised. + The group id should be unique within each provider. Group id should + contain lowercase alphanumeric characters only and no spaces or other + formatting characters. + """ + return "DSGTools: Geometric Algorithms" + + def tr(self, string): + return QCoreApplication.translate("ReclassifyAdjacentPolygonsAlgorithm", string) + + def createInstance(self): + return ReclassifyAdjacentPolygonsAlgorithm() diff --git a/DsgTools/core/DSGToolsProcessingAlgs/Algs/GeometricAlgs/selectByDE9IM.py b/DsgTools/core/DSGToolsProcessingAlgs/Algs/GeometricAlgs/selectByDE9IM.py new file mode 100644 index 000000000..055100b1b --- /dev/null +++ b/DsgTools/core/DSGToolsProcessingAlgs/Algs/GeometricAlgs/selectByDE9IM.py @@ -0,0 +1,228 @@ +# -*- coding: utf-8 -*- +""" +/*************************************************************************** + DsgTools + A QGIS plugin + Brazilian Army Cartographic Production Tools + ------------------- + begin : 2023-04-28 + git sha : $Format:%H$ + copyright : (C) 2023 by Philipe Borba - Cartographic Engineer @ Brazilian Army + email : borba.philipe@eb.mil.br + ***************************************************************************/ +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ +""" + + +from PyQt5.QtCore import QCoreApplication, QRegExp +from qgis.core import (QgsGeometry, QgsProcessing, + QgsProcessingAlgorithm, QgsProcessingMultiStepFeedback, + QgsProcessingParameterEnum, + QgsProcessingParameterFeatureSource, + QgsProcessingParameterString, Qgis) +from qgis.PyQt.QtGui import QRegExpValidator + +from DsgTools.core.DSGToolsProcessingAlgs.algRunner import AlgRunner +from DsgTools.core.GeometricTools.layerHandler import LayerHandler + + +class ValidationString(QgsProcessingParameterString): + """ + Auxiliary class for pre validation on measurer's names. + """ + + # __init__ not necessary + + def __init__(self, name, description=""): + super().__init__(name, description) + + def checkValueIsAcceptable(self, value, context=None): + regex = QRegExp("[FfTt012\*]{9}") + acceptable = QRegExpValidator.Acceptable + return ( + isinstance(value, str) + and QRegExpValidator(regex).validate(value, 9)[0] == acceptable + ) + + +class SelectByDE9IMAlgorithm(QgsProcessingAlgorithm): + INPUT = "INPUT" + INTERSECT = "INTERSECT" + DE9IM = "DE9IM" + METHOD = "METHOD" + + def initAlgorithm(self, config): + """ + Parameter setting. + """ + self.addParameter( + QgsProcessingParameterFeatureSource( + self.INPUT, + self.tr("Select features from"), + [QgsProcessing.TypeVectorAnyGeometry], + ) + ) + + self.addParameter( + QgsProcessingParameterFeatureSource( + self.INTERSECT, + self.tr("By comparing features from"), + [QgsProcessing.TypeVectorAnyGeometry], + ) + ) + + param = ValidationString(self.DE9IM, description=self.tr("DE9IM")) + self.addParameter(param) + self.method = [ + self.tr("creating new selection"), + self.tr("adding to current selection"), + self.tr("selecting within current selection"), + self.tr("removing from current selection"), + ] + + self.addParameter( + QgsProcessingParameterEnum( + self.METHOD, self.tr("Modify current selection by"), options=self.method, defaultValue=0 + ) + ) + self.selectionIdDict = { + 0: Qgis.SelectBehavior.SetSelection, + 1: Qgis.SelectBehavior.AddToSelection, + 2: Qgis.SelectBehavior.IntersectSelection, + 3: Qgis.SelectBehavior.RemoveFromSelection, + } + + def processAlgorithm(self, parameters, context, feedback): + """ + Here is where the processing itself takes place. + """ + self.layerHandler = LayerHandler() + self.algRunner = AlgRunner() + source = self.parameterAsSource(parameters, self.INPUT, context) + layer = self.parameterAsVectorLayer(parameters, self.INPUT, context) + intersectSource = self.parameterAsSource(parameters, self.INTERSECT, context) + method = self.parameterAsEnum(parameters, self.METHOD, context) + de9im = self.parameterAsString(parameters, self.DE9IM, context) + nFeats = intersectSource.featureCount() + if nFeats == 0: + return {} + if de9im == "FF1FF0102": + self.algRunner.runSelectByLocation( + inputLyr=parameters[self.INPUT], + intersectLyr=parameters[self.INTERSECT], + context=context, + feedback=feedback, + predicate=[2], + method=self.selectionIdDict[method], + is_child_algorithm=True, + ) + return + nSteps = 4 + multiStepFeedback = QgsProcessingMultiStepFeedback(nSteps, feedback) + currentStep = 0 + multiStepFeedback.setCurrentStep(currentStep) + lyrWithId = self.algRunner.runCreateFieldWithExpression( + inputLyr=parameters[self.INPUT], + expression="$id", + fieldType=1, + fieldName="featid", + feedback=multiStepFeedback, + context=context, + is_child_algorithm=False, + ) + currentStep += 1 + multiStepFeedback.setCurrentStep(currentStep) + self.algRunner.runCreateSpatialIndex( + lyrWithId, + context=context, + feedback=multiStepFeedback, + is_child_algorithm=True, + ) + currentStep += 1 + multiStepFeedback.setCurrentStep(currentStep) + selectedLyr = self.algRunner.runExtractByLocation( + inputLyr=lyrWithId, + intersectLyr=parameters[self.INTERSECT], + context=context, + feedback=multiStepFeedback, + predicate=[2] if de9im == "FF1FF0102" else [0], + ) + currentStep += 1 + multiStepFeedback.setCurrentStep(currentStep) + nFeats = selectedLyr.featureCount() + if nFeats == 0: + return {} + selectedSet = set() + stepSize = 100 / nFeats + + def compute(feat): + returnSet = set() + geom = feat.geometry() + bbox = geom.boundingBox() + engine = QgsGeometry.createGeometryEngine(geom.constGet()) + engine.prepareGeometry() + for f in selectedLyr.getFeatures(bbox): + if multiStepFeedback.isCanceled(): + return {} + intersectGeom = f.geometry() + if intersectGeom.isEmpty() or intersectGeom.isNull(): + continue + if engine.relatePattern(intersectGeom.constGet(), de9im): + returnSet.add(f["featid"]) + return returnSet + + for current, feat in enumerate(intersectSource.getFeatures()): + if multiStepFeedback.isCanceled(): + return {} + selectedSet.update(compute(feat)) + multiStepFeedback.setProgress(current * stepSize) + layer.selectByIds(list(selectedSet), self.selectionIdDict[method]) + + return {} + + def name(self): + """ + Returns the algorithm name, used for identifying the algorithm. This + string should be fixed for the algorithm, and must not be localised. + The name should be unique within each provider. Names should contain + lowercase alphanumeric characters only and no spaces or other + formatting characters. + """ + return "selectbyde9im" + + def displayName(self): + """ + Returns the translated algorithm name, which should be used for any + user-visible display of the algorithm name. + """ + return self.tr("Select features by DE9IM") + + def group(self): + """ + Returns the name of the group this algorithm belongs to. This string + should be localised. + """ + return self.tr("Geometric Algorithms") + + def groupId(self): + """ + Returns the unique ID of the group this algorithm belongs to. This + string should be fixed for the algorithm, and must not be localised. + The group id should be unique within each provider. Group id should + contain lowercase alphanumeric characters only and no spaces or other + formatting characters. + """ + return "DSGTools: Geometric Algorithms" + + def tr(self, string): + return QCoreApplication.translate("SelectByDE9IMAlgorithm", string) + + def createInstance(self): + return SelectByDE9IMAlgorithm() diff --git a/DsgTools/core/DSGToolsProcessingAlgs/Algs/GeometricAlgs/smallHoleRemoverAlgorithm.py b/DsgTools/core/DSGToolsProcessingAlgs/Algs/GeometricAlgs/smallHoleRemoverAlgorithm.py new file mode 100644 index 000000000..e4fdec8f3 --- /dev/null +++ b/DsgTools/core/DSGToolsProcessingAlgs/Algs/GeometricAlgs/smallHoleRemoverAlgorithm.py @@ -0,0 +1,291 @@ +# -*- coding: utf-8 -*- +""" +/*************************************************************************** + DsgTools + A QGIS plugin + Brazilian Army Cartographic Production Tools + ------------------- + begin : 2023-01-16 + git sha : $Format:%H$ + copyright : (C) 2023 by Philipe Borba - Cartographic Engineer @ Brazilian Army + email : borba.philipe@eb.mil.br + ***************************************************************************/ +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ +""" + +import concurrent.futures +import os +from DsgTools.core.DSGToolsProcessingAlgs.Algs.ValidationAlgs.validationAlgorithm import ( + ValidationAlgorithm, +) +from DsgTools.core.DSGToolsProcessingAlgs.algRunner import AlgRunner + +from PyQt5.QtCore import QCoreApplication + +from qgis.core import ( + QgsProcessing, + QgsProcessingParameterFeatureSink, + QgsProcessingParameterVectorLayer, + QgsProcessingParameterBoolean, + QgsProcessingException, + QgsProcessingMultiStepFeedback, + QgsProcessingFeatureSourceDefinition, + QgsProcessingParameterNumber, + QgsProcessingParameterField +) + + +class SmallHoleRemoverAlgorithm(ValidationAlgorithm): + INPUT = "INPUT" + SELECTED = "SELECTED" + DISSOLVE_OUTPUT = "DISSOLVE_OUTPUT" + DISSOLVE_ATTRIBUTE_LIST = "DISSOLVE_ATTRIBUTE_LIST" + MAX_HOLE_AREA_TO_ELIMINATE = "MAX_HOLE_AREA_TO_ELIMINATE" + OUPUT = "OUPUT" + + def initAlgorithm(self, config): + """ + Parameter setting. + """ + self.addParameter( + QgsProcessingParameterVectorLayer( + self.INPUT, + self.tr("Input Polygon Layer"), + [QgsProcessing.TypeVectorPolygon], + ) + ) + + self.addParameter( + QgsProcessingParameterBoolean( + self.SELECTED, self.tr("Process only selected features") + ) + ) + + self.addParameter( + QgsProcessingParameterBoolean( + self.DISSOLVE_OUTPUT, self.tr("Dissolve Output") + ) + ) + + + self.addParameter( + QgsProcessingParameterField( + self.DISSOLVE_ATTRIBUTE_LIST, + self.tr("Fields to consider on dissolve"), + None, + "INPUT", + QgsProcessingParameterField.Any, + allowMultiple=True, + optional=True, + ) + ) + self.addParameter( + QgsProcessingParameterNumber( + self.MAX_HOLE_AREA_TO_ELIMINATE, + self.tr("Max hole area to eliminate"), + defaultValue=15625, + minValue=0, + type=QgsProcessingParameterNumber.Double, + ) + ) + + self.addParameter( + QgsProcessingParameterFeatureSink(self.OUPUT, self.tr("Output")) + ) + def processAlgorithm(self, parameters, context, feedback): + """ + Here is where the processing itself takes place. + """ + inputLyr = self.parameterAsVectorLayer(parameters, self.INPUT, context) + maxHoleArea = self.parameterAsDouble(parameters, self.MAX_HOLE_AREA_TO_ELIMINATE, context) + dissolveAttributeList = self.parameterAsFields( + parameters, self.DISSOLVE_ATTRIBUTE_LIST, context + ) + algRunner = AlgRunner() + if inputLyr is None: + raise QgsProcessingException( + self.invalidSourceError(parameters, self.INPUT) + ) + + onlySelected = self.parameterAsBool(parameters, self.SELECTED, context) + dissolveOutput = self.parameterAsBool(parameters, self.DISSOLVE_OUTPUT, context) + (output_sink, output_sink_id) = self.parameterAsSink( + parameters, + self.OUPUT, + context, + inputLyr.fields(), + inputLyr.wkbType(), + inputLyr.sourceCrs(), + ) + multiStepFeedback = QgsProcessingMultiStepFeedback(10, feedback) + + multiStepFeedback.setCurrentStep(0) + multiStepFeedback.setProgressText(self.tr("Building Cache")) + cacheLyr = algRunner.runAddAutoIncrementalField( + inputLyr=inputLyr if not onlySelected else \ + QgsProcessingFeatureSourceDefinition(inputLyr.id(), True), + context=context, + feedback=multiStepFeedback + ) + cacheDict = {feat["featid"]:feat for feat in cacheLyr.getFeatures()} + multiStepFeedback.setCurrentStep(1) + multiStepFeedback.setProgressText(self.tr("Building Spatial Index")) + algRunner.runCreateSpatialIndex(inputLyr=cacheLyr, context=context, feedback=multiStepFeedback) + + multiStepFeedback.setCurrentStep(2) + multiStepFeedback.setProgressText(self.tr("Point on surface layer")) + pointOnSurfaceLyr = algRunner.runPointOnSurface( + inputLyr=cacheLyr, context=context, feedback=multiStepFeedback + ) + multiStepFeedback.setCurrentStep(3) + multiStepFeedback.setProgressText(self.tr("Building Spatial Index on point on surface layer")) + algRunner.runCreateSpatialIndex(inputLyr=pointOnSurfaceLyr, context=context, feedback=multiStepFeedback) + multiStepFeedback.setCurrentStep(4) + multiStepFeedback.setProgressText(self.tr("Extracting Donut Holes")) + _, donutHole = algRunner.runDonutHoleExtractor( + inputLyr=cacheLyr, + context=context, + feedback=multiStepFeedback, + ) + multiStepFeedback.setCurrentStep(5) + multiStepFeedback.setProgressText(self.tr("Submitting to thread")) + nFeats = donutHole.featureCount() + if nFeats == 0: + return {self.OUPUT: output_sink_id} + stepSize = 100 / nFeats + futures = set() + pool = concurrent.futures.ThreadPoolExecutor(max_workers=os.cpu_count() - 1) + fieldNames = [field.name() for field in inputLyr.fields()] + def compute(feat): + outputList = [] + if multiStepFeedback.isCanceled(): + return outputList + geom = feat.geometry() + if geom.area() > maxHoleArea: + return outputList + bbox = geom.boundingBox() + for newCandidate in cacheLyr.getFeatures(bbox): + newCandidateGeom = newCandidate.geometry() + if newCandidateGeom.equals(geom): + for fieldName in fieldNames: + newCandidate[fieldName] = feat[fieldName] + outputList.append(newCandidate) + return outputList + for candidateFeat in pointOnSurfaceLyr.getFeatures(bbox): + candidatePointGeom = candidateFeat.geometry() + if not geom.intersects(candidatePointGeom): + continue + candidateFeat = cacheDict[candidateFeat["featid"]] + for fieldName in fieldNames: + candidateFeat[fieldName] = feat[fieldName] + outputList.append(candidateFeat) + return outputList + + cacheLyr.startEditing() + cacheLyr.beginEditCommand("Updating holes") + for current, feat in enumerate(donutHole.getFeatures()): + if multiStepFeedback.isCanceled(): + break + futures.add(pool.submit(compute, feat)) + multiStepFeedback.setProgress(current * stepSize) + + multiStepFeedback.setCurrentStep(6) + multiStepFeedback.setProgressText(self.tr("Evaluating Results")) + cacheLyrDataProvider = cacheLyr.dataProvider() + indexDict = {fieldName:cacheLyrDataProvider.fields().indexFromName(fieldName) for fieldName in fieldNames} + def updateFunc(feat): + featid = cacheDict[feat['featid']].id() + cacheLyrDataProvider.changeAttributeValues({ + featid: { indexDict[fieldName]:feat[fieldName] for fieldName in fieldNames} + }) + for current, future in enumerate(concurrent.futures.as_completed(futures)): + if multiStepFeedback.isCanceled(): + break + results = future.result() + if results == []: + continue + list(map(updateFunc, results)) + # for featToUpdate in future.result(): + # # for featToUpdate in compute(feat): + # cacheLyr.updateFeature(featToUpdate) + multiStepFeedback.setProgress(current * stepSize) + cacheLyr.endEditCommand() + + multiStepFeedback.setCurrentStep(7) + if dissolveOutput: + multiStepFeedback.setProgressText(self.tr("Dissolving Polygons")) + mergedLyr = algRunner.runDissolve( + inputLyr=cacheLyr, + context=context, + feedback=multiStepFeedback, + field=dissolveAttributeList, + is_child_algorithm=True + ) + multiStepFeedback.setCurrentStep(8) + mergedLyr = algRunner.runMultipartToSingleParts( + inputLayer=mergedLyr, + context=context, + feedback=multiStepFeedback + ) + else: + mergedLyr = cacheLyr + multiStepFeedback.setCurrentStep(9) + nFeats = mergedLyr.featureCount() + if nFeats == 0: + return {self.OUPUT: output_sink_id} + stepSize = 100 / nFeats + multiStepFeedback.setProgressText(self.tr("Building Outputs")) + for current, feat in enumerate(mergedLyr.getFeatures()): + if multiStepFeedback.isCanceled(): + break + output_sink.addFeature(feat) + multiStepFeedback.setProgress(current * stepSize) + + return {self.OUPUT: output_sink_id} + + def name(self): + """ + Returns the algorithm name, used for identifying the algorithm. This + string should be fixed for the algorithm, and must not be localised. + The name should be unique within each provider. Names should contain + lowercase alphanumeric characters only and no spaces or other + formatting characters. + """ + return "smallholeremoveralgorithm" + + def displayName(self): + """ + Returns the translated algorithm name, which should be used for any + user-visible display of the algorithm name. + """ + return self.tr("Small Hole Remover Algorithm") + + def group(self): + """ + Returns the name of the group this algorithm belongs to. This string + should be localised. + """ + return self.tr("Geometric Algorithms") + + def groupId(self): + """ + Returns the unique ID of the group this algorithm belongs to. This + string should be fixed for the algorithm, and must not be localised. + The group id should be unique within each provider. Group id should + contain lowercase alphanumeric characters only and no spaces or other + formatting characters. + """ + return "DSGTools: Geometric Algorithms" + + def tr(self, string): + return QCoreApplication.translate("SmallHoleRemoverAlgorithm", string) + + def createInstance(self): + return SmallHoleRemoverAlgorithm() diff --git a/DsgTools/core/DSGToolsProcessingAlgs/Algs/GeometricAlgs/splitPolygonsAlgorithm.py b/DsgTools/core/DSGToolsProcessingAlgs/Algs/GeometricAlgs/splitPolygonsAlgorithm.py new file mode 100644 index 000000000..e9d36e76f --- /dev/null +++ b/DsgTools/core/DSGToolsProcessingAlgs/Algs/GeometricAlgs/splitPolygonsAlgorithm.py @@ -0,0 +1,271 @@ +# -*- coding: utf-8 -*- +""" +/*************************************************************************** + DsgTools + A QGIS plugin + Brazilian Army Cartographic Production Tools + ------------------- + begin : 2023-04-15 + git sha : $Format:%H$ + copyright : (C) 2023 by Felipe Diniz - Cartographic Engineer @ Brazilian Army + email : diniz.felipe@eb.mil.br + ***************************************************************************/ +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ +""" + +import math +from itertools import product + +from PyQt5.QtCore import QCoreApplication, QVariant +from qgis.core import ( + QgsFeature, + QgsFeatureRequest, + QgsFeatureSink, + QgsField, + QgsGeometry, + QgsProcessing, + QgsProcessingAlgorithm, + QgsProcessingParameterEnum, + QgsProcessingParameterFeatureSink, + QgsProcessingParameterFeatureSource, + QgsProcessingParameterNumber, + QgsRectangle, + QgsSpatialIndex, + QgsVectorLayer +) + + +class SplitPolygons(QgsProcessingAlgorithm): + INPUT = "INPUT" + PARAM = "PARAM" + OVERLAP = "OVERLAP" + OUTPUT = "OUTPUT" + SPLIT_FACTORS = ["1/1", "1/4", "1/9", "1/16", "1/25"] + + def initAlgorithm(self, config=None): + self.addParameter( + QgsProcessingParameterFeatureSource( + self.INPUT, "Input polygon layer", [QgsProcessing.TypeVectorPolygon] + ) + ) + + self.addParameter( + QgsProcessingParameterEnum( + self.PARAM, + "Splitting factor", + options=self.SPLIT_FACTORS, + defaultValue=0, + ) + ) + + self.addParameter( + QgsProcessingParameterNumber( + self.OVERLAP, + "Overlap value", + QgsProcessingParameterNumber.Double, + defaultValue=0.002, + ) + ) + + self.addParameter( + QgsProcessingParameterFeatureSink(self.OUTPUT, "Output split polygons") + ) + + def splitPol(self, features, overlap, fields, side_length, col_steps, row_steps, idToFeature, index, feedback): + polygons = [] + for feature in features: + if feedback.isCanceled(): + break + + geometry = feature.geometry() + source_fid = feature.id() + + xmin, ymin, xmax, ymax = geometry.boundingBox().toRectF().getCoords() + width = xmax - xmin + height = ymax - ymin + + for i, j in product(range(col_steps), range(row_steps)): + if feedback.isCanceled(): + break + x1 = xmin + (width * i * side_length) + y1 = ymin + (height * j * side_length) + x2 = xmin + (width * (i + 1) * side_length) + y2 = ymin + (height * (j + 1) * side_length) + + new_geom = QgsGeometry.fromRect(QgsRectangle(x1, y1, x2, y2)) + + # Buffer the new geometry + buffered_geom = new_geom.buffer( + overlap, 5 + ) # 5 is the default number of segments per quarter circle + + # Use the spatial index to find intersecting features + candidate_ids = index.intersects(buffered_geom.boundingBox()) + if not candidate_ids: + continue + + # Dissolve only intersecting features + dissolved_geometry = QgsGeometry.unaryUnion( + [idToFeature[cid].geometry() for cid in candidate_ids] + ) + + # Clip the buffered geometry by the dissolved geometry + intersected_geom = buffered_geom.intersection(dissolved_geometry) + + if intersected_geom.isEmpty(): + continue + + new_feature = QgsFeature(feature) + new_feature.setGeometry(intersected_geom) + new_feature.setFields(fields) + polygons.append(new_feature) + return polygons + + def processAlgorithm(self, parameters, context, feedback): + source = self.parameterAsSource(parameters, self.INPUT, context) + split_factor = self.parameterAsEnum(parameters, self.PARAM, context) + overlap = self.parameterAsDouble(parameters, self.OVERLAP, context) + + # Add a new field called "priority" to the output layer's fields + fields = source.fields() + fields.append(QgsField("priority", QVariant.Int)) + + (sink, dest_id) = self.parameterAsSink( + parameters, + self.OUTPUT, + context, + fields, + source.wkbType(), + source.sourceCrs(), + ) + + features = list(source.getFeatures()) + idToFeature = {} + for feat in features: + idToFeature[feat.id()] = feat + + # Create a spatial index + index = QgsSpatialIndex(source) + + parts = [1, 4, 9, 16, 25][split_factor] + side_length = math.sqrt(1 / parts) + col_steps = int(math.sqrt(parts)) + row_steps = col_steps + + polygons = self.splitPol(features, overlap, fields, side_length, col_steps, row_steps, idToFeature, index, feedback) + base_polygons = self.splitPol(features, overlap, fields, 1, 1, 1, idToFeature, index, feedback) + + tile_layer = QgsVectorLayer("Polygon?crs=" + source.sourceCrs().authid(), "tile_polygons", "memory") + tile_data_provider = tile_layer.dataProvider() + tile_data_provider.addAttributes(fields) + tile_layer.updateFields() + tile_data_provider.addFeatures(polygons) + tile_layer.updateExtents() + index_tile = QgsSpatialIndex(tile_layer) + idToFeatureTile = {} + for feat in tile_layer.getFeatures(): + idToFeatureTile[feat.id()] = feat + + base_layer = QgsVectorLayer("Polygon?crs=" + source.sourceCrs().authid(), "base_polygons", "memory") + base_data_provider = base_layer.dataProvider() + base_data_provider.addAttributes(fields) + base_layer.updateFields() + base_data_provider.addFeatures(base_polygons) + base_layer.updateExtents() + index_base = QgsSpatialIndex(base_layer) + idToFeatureBase = {} + for feat in base_layer.getFeatures(): + idToFeatureBase[feat.id()] = feat + + + priority = 1 + final_features = {} + base_used = [] + + sorted_source_features = sorted( + source.getFeatures(), + key=lambda x: ( + round(x.geometry().centroid().asPoint().y(),5), + -round(x.geometry().centroid().asPoint().x(),5), + ), + reverse=True, + ) + for feat in sorted_source_features: + # Use the spatial index to find intersecting features + geometry = feat.geometry() + candidate_ids = index_base.intersects(geometry.boundingBox()) + intersecting_features_base = [idToFeatureBase[cid] for cid in candidate_ids] + intersecting_features_base.sort( + key=lambda x: ( + round(x.geometry().centroid().asPoint().y(),5), + -round(x.geometry().centroid().asPoint().x(),5), + ) + if not x.geometry().isNull() + else (0, 0), + reverse=True, + ) + for base_polygon in intersecting_features_base: + if base_polygon.id() in base_used: + continue + base_used.append(base_polygon.id()) + + base_geometry = base_polygon.geometry() + candidate_ids = index_tile.intersects(base_geometry.boundingBox()) + intersecting_features = [idToFeatureTile[cid] for cid in candidate_ids] + + intersecting_features.sort( + key=lambda x: ( + round(x.geometry().centroid().asPoint().y(),5), + -round(x.geometry().centroid().asPoint().x(),5), + ) + if not x.geometry().isNull() + else (0, 0), + reverse=True, + ) + for polygon in intersecting_features: + if polygon.id() in final_features: + continue + polygon.setAttribute("priority", priority) + final_features[polygon.id()] = polygon + priority += 1 + + for polygon in final_features.values(): + sink.addFeature(polygon, QgsFeatureSink.FastInsert) + + return {self.OUTPUT: dest_id} + + def name(self): + return "splitpolygons" + + def displayName(self): + return "Split Polygons" + + def group(self): + """ + Returns the name of the group this algorithm belongs to. This string + should be localised. + """ + return self.tr("Geometric Algorithms") + + def groupId(self): + """ + Returns the unique ID of the group this algorithm belongs to. This + string should be fixed for the algorithm, and must not be localised. + The group id should be unique within each provider. Group id should + contain lowercase alphanumeric characters only and no spaces or other + formatting characters. + """ + return "DSGTools: Geometric Algorithms" + + def tr(self, string): + return QCoreApplication.translate("SplitPolygons", string) + + def createInstance(self): + return SplitPolygons() diff --git a/DsgTools/core/DSGToolsProcessingAlgs/Algs/GeometricAlgs/splitPolygonsByGrid.py b/DsgTools/core/DSGToolsProcessingAlgs/Algs/GeometricAlgs/splitPolygonsByGrid.py new file mode 100644 index 000000000..948862c34 --- /dev/null +++ b/DsgTools/core/DSGToolsProcessingAlgs/Algs/GeometricAlgs/splitPolygonsByGrid.py @@ -0,0 +1,439 @@ +# -*- coding: utf-8 -*- +""" +/*************************************************************************** + DsgTools + A QGIS plugin + Brazilian Army Cartographic Production Tools + ------------------- + begin : 2023-04-15 + git sha : $Format:%H$ + copyright : (C) 2023 by Felipe Diniz - Cartographic Engineer @ Brazilian Army + email : diniz.felipe@eb.mil.br + ***************************************************************************/ +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ +""" + +import concurrent.futures +import os +from DsgTools.core.Utils.threadingTools import concurrently + +from qgis.core import ( + QgsProcessing, + QgsProcessingAlgorithm, + QgsProcessingContext, + QgsProcessingMultiStepFeedback, + QgsProcessingParameterDistance, + QgsProcessingParameterFeatureSink, + QgsProcessingParameterFeatureSource, + QgsProcessingParameterField, + QgsSpatialIndex, + QgsProcessingParameterNumber, + QgsFields, + QgsVectorLayer, + QgsFeatureRequest, +) +from qgis.PyQt.QtCore import QCoreApplication + +from DsgTools.core.DSGToolsProcessingAlgs.algRunner import AlgRunner +from DsgTools.core.GeometricTools.layerHandler import LayerHandler + + +class SplitPolygonsByGrid(QgsProcessingAlgorithm): + INPUT = "INPUT" + X_DISTANCE = "X_DISTANCE" + Y_DISTANCE = "Y_DISTANCE" + MIN_AREA = "MIN_AREA" + NEIGHBOUR = "NEIGHBOUR" + CLASS_FIELD = "CLASS_FIELD" + MAX_CONCURRENCY = "MAX_CONCURRENCY" + OUTPUT = "OUTPUT" + + def tr(self, string): + return QCoreApplication.translate("SplitPolygonsByGrid", string) + + def createInstance(self): + return SplitPolygonsByGrid() + + def name(self): + return "polygon_split_by_grid" + + def displayName(self): + return self.tr("Polygon Split by Grid") + + def group(self): + """ + Returns the name of the group this algorithm belongs to. This string + should be localised. + """ + return self.tr("Geometric Algorithms") + + def groupId(self): + """ + Returns the unique ID of the group this algorithm belongs to. This + string should be fixed for the algorithm, and must not be localised. + The group id should be unique within each provider. Group id should + contain lowercase alphanumeric characters only and no spaces or other + formatting characters. + """ + return "DSGTools: Geometric Algorithms" + + def shortHelpString(self): + return self.tr( + "Splits input polygon layer by regular grid with user-defined X and Y distances and dissolves the intersection polygons based on the nearest neighbor's ID attribute." + ) + + def initAlgorithm(self, config=None): + self.addParameter( + QgsProcessingParameterFeatureSource( + self.INPUT, + self.tr("Input Polygon Layer"), + [QgsProcessing.TypeVectorPolygon], + ) + ) + self.addParameter( + QgsProcessingParameterDistance( + self.X_DISTANCE, + self.tr("X Distance"), + parentParameterName=self.INPUT, + minValue=0.0, + defaultValue=0.0001, + ) + ) + self.addParameter( + QgsProcessingParameterDistance( + self.Y_DISTANCE, + self.tr("Y Distance"), + parentParameterName=self.INPUT, + minValue=0.0, + defaultValue=0.0001, + ) + ) + self.addParameter( + QgsProcessingParameterDistance( + self.Y_DISTANCE, + self.tr("Y Distance"), + parentParameterName=self.INPUT, + minValue=0.0, + defaultValue=0.0001, + ) + ) + param = QgsProcessingParameterDistance( + self.MIN_AREA, + self.tr( + "Minimun area to process. If feature's area is smaller than this value, " + "the feature will not be split, but only reclassified to the nearest neighbour." + ), + parentParameterName=self.INPUT, + defaultValue=1e-8, + ) + param.setMetadata({"widget_wrapper": {"decimals": 10}}) + self.addParameter(param) + self.addParameter( + QgsProcessingParameterFeatureSource( + self.NEIGHBOUR, + self.tr("Neighbour Polygon Layer"), + [QgsProcessing.TypeVectorPolygon], + ) + ) + self.addParameter( + QgsProcessingParameterField( + self.CLASS_FIELD, + self.tr("Class attribute field"), + parentLayerParameterName=self.NEIGHBOUR, + type=QgsProcessingParameterField.Any, + ) + ) + self.addParameter( + QgsProcessingParameterNumber( + self.MAX_CONCURRENCY, + self.tr("Max Concurrency"), + type=QgsProcessingParameterNumber.Integer, + defaultValue=1, + minValue=1, + ) + ) + self.addParameter( + QgsProcessingParameterFeatureSink(self.OUTPUT, self.tr("Output Layer")) + ) + + def processAlgorithm(self, parameters, context, feedback): + self.algRunner = AlgRunner() + self.layerHandler = LayerHandler() + source = self.parameterAsSource(parameters, self.INPUT, context) + x_distance = self.parameterAsDouble(parameters, self.X_DISTANCE, context) + y_distance = self.parameterAsDouble(parameters, self.Y_DISTANCE, context) + min_area = self.parameterAsDouble(parameters, self.MIN_AREA, context) + neighbour_source = self.parameterAsSource(parameters, self.NEIGHBOUR, context) + classFieldName = self.parameterAsString(parameters, self.CLASS_FIELD, context) + max_concurrency = self.parameterAsInt(parameters, self.MAX_CONCURRENCY, context) + + (sink, dest_id) = self.parameterAsSink( + parameters, + self.OUTPUT, + context, + source.fields(), + source.wkbType(), + source.sourceCrs(), + ) + + nFeats = source.featureCount() + if nFeats == 0: + return {self.OUTPUT: dest_id} + request = QgsFeatureRequest() + clause = QgsFeatureRequest.OrderByClause("$area") + orderby = QgsFeatureRequest.OrderBy([clause]) + request.setOrderBy(orderby) + iterator = source.getFeatures(request) + nSteps = nFeats + 2 + multiStepFeedback = QgsProcessingMultiStepFeedback(nSteps, feedback) + multiStepFeedback.setCurrentStep(0) + multiStepFeedback.setProgressText(self.tr("Extracting vertexes...")) + verticesLyr = self.algRunner.runExtractVertices( + inputLyr=parameters[self.NEIGHBOUR], + context=context, + feedback=multiStepFeedback, + ) + multiStepFeedback.setCurrentStep(1) + multiStepFeedback.setProgressText(self.tr("Creating spatial index...")) + self.algRunner.runCreateSpatialIndex( + verticesLyr, context=context, feedback=multiStepFeedback + ) + multiStepFeedback.setProgressText(self.tr("Processing features...")) + + def prepare_data(feature): + geom = feature.geometry() + bbox = geom.boundingBox() + try: + featureLayer = self.layerHandler.createMemoryLayerWithFeature( + source, feature, context=context, isSource=True + ) + except: + return None, None + if bbox.isEmpty() or bbox.isNull() or not bbox.isFinite(): + return None, None + try: + localNeighborVertexes = self.algRunner.runExtractByExtent( + inputLayer=verticesLyr, extent=bbox, context=context, clip=True + ) + except: + return None, None + return featureLayer, localNeighborVertexes + + if max_concurrency == 1: + for current, feature in enumerate(iterator, start=2): + if multiStepFeedback.isCanceled(): + return {self.OUTPUT: dest_id} + multiStepFeedback.setCurrentStep(current) + geom = feature.geometry() + if geom.isNull() or geom.isEmpty(): + continue + featureLayer, localNeighborVertexes = prepare_data(feature) + if featureLayer is None: + continue + if multiStepFeedback.isCanceled(): + return {self.OUTPUT: dest_id} + outputFeatures = self.compute( + localNeighborVertexes=localNeighborVertexes, + feature=feature, + featureLayer=featureLayer, + x_distance=x_distance, + y_distance=y_distance, + classFieldName=classFieldName, + source_fields=source.fields(), + min_area=min_area, + feedback=multiStepFeedback, + ) + if outputFeatures is None or outputFeatures == set(): + if current % 500 == 0: + multiStepFeedback.pushInfo( + self.tr(f"Processed {current}/{nFeats}.") + ) + continue + sink.addFeatures(list(outputFeatures)) + if current % 500 == 0: + multiStepFeedback.pushInfo( + self.tr(f"Processed {current}/{nFeats}.") + ) + return {self.OUTPUT: dest_id} + + def compute_in_paralel(feature): + featureLayer, localNeighborVertexes = prepare_data(feature) + return self.compute( + localNeighborVertexes=localNeighborVertexes, + feature=feature, + featureLayer=featureLayer, + x_distance=x_distance, + y_distance=y_distance, + classFieldName=classFieldName, + source_fields=QgsFields(source.fields()), + min_area=min_area, + feedback=feedback, + ) + + for current, outputFeatures in enumerate( + concurrently(compute_in_paralel, iterator, max_concurrency=max_concurrency), + start=2, + ): + multiStepFeedback.setCurrentStep(current) + if multiStepFeedback.isCanceled(): + return {self.OUTPUT: dest_id} + if outputFeatures is None or outputFeatures == set(): + continue + sink.addFeatures(list(outputFeatures)) + if current % 500 == 0: + multiStepFeedback.pushInfo(self.tr(f"Processed {current}/{nFeats}.")) + + return {self.OUTPUT: dest_id} + + def compute( + self, + localNeighborVertexes, + feature, + featureLayer, + x_distance, + y_distance, + classFieldName, + source_fields, + min_area, + feedback=None, + ): + context = QgsProcessingContext() + algRunner = AlgRunner() + if feedback is not None and feedback.isCanceled(): + return set() + if ( + (feedback is not None and feedback.isCanceled()) + or feature is None + or localNeighborVertexes is None + or featureLayer is None + or isinstance(localNeighborVertexes, str) + or localNeighborVertexes.featureCount() == 0 + ): + return set() + neighbour_idx = QgsSpatialIndex(localNeighborVertexes.getFeatures()) + neighbourFeatDict = { + feat.id(): feat for feat in localNeighborVertexes.getFeatures() + } + geometry = feature.geometry() + if geometry.isEmpty() or geometry.isNull(): + return set() + bbox = geometry.boundingBox() + xmin, ymin, xmax, ymax = bbox.toRectF().getCoords() + xSpacing = ( + x_distance + if abs(xmax - xmin) > x_distance + else min(abs(xmax - xmin) / 2, abs(ymax - ymin) / 2) + ) + ySpacing = ( + y_distance + if abs(ymax - ymin) > y_distance + else min(abs(xmax - xmin) / 2, abs(ymax - ymin) / 2) + ) + if geometry.area() <= min_area or geometry.area() <= xSpacing * ySpacing: + nearest_neighbor_ids = neighbour_idx.nearestNeighbor( + geometry.centroid().asPoint(), 1 + ) + if nearest_neighbor_ids == []: + return set() + nearest_neighbor_id = nearest_neighbor_ids[0] + if nearest_neighbor_id not in neighbourFeatDict: + return set() + feature[classFieldName] = neighbourFeatDict[nearest_neighbor_id][ + classFieldName + ] + returnSet = set() + returnSet.add(feature) + return returnSet + gridLayer = algRunner.runCreateGrid( + extent=bbox, + crs=featureLayer.crs(), + hSpacing=xSpacing, + vSpacing=ySpacing, + context=context, + ) + if feedback is not None and feedback.isCanceled(): + return set() + algRunner.runCreateSpatialIndex(gridLayer, context=context) + if feedback is not None and feedback.isCanceled(): + return set() + try: + clippedPolygons = algRunner.runClip( + gridLayer, featureLayer, context=context + ) + except: + clippedPolygons = None + if ( + not isinstance(clippedPolygons, QgsVectorLayer) + or clippedPolygons.featureCount() < 4 + ): + nearest_neighbors = neighbour_idx.nearestNeighbor( + geometry.centroid().asPoint(), 1 + ) + if nearest_neighbors == []: + return set() + nearest_neighbor_id = nearest_neighbors[0] + if nearest_neighbor_id not in neighbourFeatDict: + return set() + feature[classFieldName] = neighbourFeatDict[nearest_neighbor_id][ + classFieldName + ] + returnSet = set() + returnSet.add(feature) + return returnSet + clippedPolygons.startEditing() + if feedback is not None and feedback.isCanceled(): + return set() + algRunner.runCreateSpatialIndex(clippedPolygons, context=context) + nFeats = clippedPolygons.featureCount() + if nFeats == 0: + return None + clippedPolygons.beginEditCommand("Updating features") + clippedPolygonsDataProvider = clippedPolygons.dataProvider() + if not any(i.name() == classFieldName for i in clippedPolygons.fields()): + clippedPolygonsDataProvider.addAttributes( + [i for i in source_fields if i.name() == classFieldName] + ) + clippedPolygons.updateFields() + fieldIdx = clippedPolygons.fields().indexFromName(classFieldName) + for feat in clippedPolygons.getFeatures(): + if feedback is not None and feedback.isCanceled(): + return set() + geom = feat.geometry() + if geom.isEmpty() or geom.isNull(): + continue + nearest_neighbor_ids = neighbour_idx.nearestNeighbor( + geom.centroid().asPoint(), 1 + ) + if nearest_neighbor_ids == []: + continue + nearest_neighbor_id = nearest_neighbor_ids[0] + destinationAttr = neighbourFeatDict[nearest_neighbor_id][classFieldName] + clippedPolygonsDataProvider.changeAttributeValues( + {feat.id(): {fieldIdx: destinationAttr}} + ) + clippedPolygons.endEditCommand() + if feedback is not None and feedback.isCanceled(): + return set() + snappedToGrid = algRunner.runSnapToGrid( + inputLayer=clippedPolygons, tol=1e-15, context=context + ) + if feedback is not None and feedback.isCanceled(): + return set() + dissolvedLyr = algRunner.runDissolve( + inputLyr=snappedToGrid, + field=[classFieldName], + context=context, + ) + if feedback is not None and feedback.isCanceled(): + return set() + retainedFields = algRunner.runRetainFields( + dissolvedLyr, [field.name() for field in source_fields], context=context + ) + return set(feat for feat in retainedFields.getFeatures()) diff --git a/DsgTools/core/DSGToolsProcessingAlgs/Algs/LayerManagementAlgs/applyStylesFromDatabaseToLayersAlgorithm.py b/DsgTools/core/DSGToolsProcessingAlgs/Algs/LayerManagementAlgs/applyStylesFromDatabaseToLayersAlgorithm.py index 3fda282c0..7a48da7ec 100644 --- a/DsgTools/core/DSGToolsProcessingAlgs/Algs/LayerManagementAlgs/applyStylesFromDatabaseToLayersAlgorithm.py +++ b/DsgTools/core/DSGToolsProcessingAlgs/Algs/LayerManagementAlgs/applyStylesFromDatabaseToLayersAlgorithm.py @@ -24,44 +24,48 @@ from PyQt5.QtCore import QCoreApplication from qgis.PyQt.Qt import QVariant from qgis.PyQt.QtXml import QDomDocument -from qgis.core import (QgsProcessing, - QgsFeatureSink, - QgsProcessingAlgorithm, - QgsProcessingParameterFeatureSource, - QgsProcessingParameterFeatureSink, - QgsFeature, - QgsDataSourceUri, - QgsProcessingOutputVectorLayer, - QgsProcessingParameterVectorLayer, - QgsWkbTypes, - QgsProcessingParameterBoolean, - QgsProcessingParameterEnum, - QgsProcessingParameterNumber, - QgsProcessingParameterMultipleLayers, - QgsProcessingUtils, - QgsSpatialIndex, - QgsGeometry, - QgsProcessingParameterField, - QgsProcessingMultiStepFeedback, - QgsProcessingParameterFile, - QgsProcessingParameterExpression, - QgsProcessingException, - QgsProcessingParameterString, - QgsProcessingParameterDefinition, - QgsProcessingParameterType, - QgsProcessingParameterCrs, - QgsCoordinateTransform, - QgsProject, - QgsCoordinateReferenceSystem, - QgsField, - QgsFields, - QgsProcessingOutputMultipleLayers, - QgsProcessingParameterString) +from qgis.core import ( + QgsProcessing, + QgsFeatureSink, + QgsProcessingAlgorithm, + QgsProcessingParameterFeatureSource, + QgsProcessingParameterFeatureSink, + QgsFeature, + QgsDataSourceUri, + QgsProcessingOutputVectorLayer, + QgsProcessingParameterVectorLayer, + QgsWkbTypes, + QgsProcessingParameterBoolean, + QgsProcessingParameterEnum, + QgsProcessingParameterNumber, + QgsProcessingParameterMultipleLayers, + QgsProcessingUtils, + QgsSpatialIndex, + QgsGeometry, + QgsProcessingParameterField, + QgsProcessingMultiStepFeedback, + QgsProcessingParameterFile, + QgsProcessingParameterExpression, + QgsProcessingException, + QgsProcessingParameterString, + QgsProcessingParameterDefinition, + QgsProcessingParameterType, + QgsProcessingParameterCrs, + QgsCoordinateTransform, + QgsProject, + QgsCoordinateReferenceSystem, + QgsField, + QgsFields, + QgsProcessingOutputMultipleLayers, + QgsProcessingParameterString, +) + class ApplyStylesFromDatabaseToLayersAlgorithm(QgsProcessingAlgorithm): - INPUT_LAYERS = 'INPUT_LAYERS' - STYLE_NAME = 'STYLE_NAME' - OUTPUT = 'OUTPUT' + INPUT_LAYERS = "INPUT_LAYERS" + STYLE_NAME = "STYLE_NAME" + OUTPUT = "OUTPUT" + def initAlgorithm(self, config): """ Parameter setting. @@ -69,22 +73,18 @@ def initAlgorithm(self, config): self.addParameter( QgsProcessingParameterMultipleLayers( self.INPUT_LAYERS, - self.tr('Input Layers'), - QgsProcessing.TypeVectorAnyGeometry + self.tr("Input Layers"), + QgsProcessing.TypeVectorAnyGeometry, ) ) self.addParameter( - QgsProcessingParameterString( - self.STYLE_NAME, - self.tr('Style Name') - ) + QgsProcessingParameterString(self.STYLE_NAME, self.tr("Style Name")) ) self.addOutput( QgsProcessingOutputMultipleLayers( - self.OUTPUT, - self.tr('Original layers with styles applied column') + self.OUTPUT, self.tr("Original layers with styles applied column") ) ) @@ -94,18 +94,10 @@ def processAlgorithm(self, parameters, context, feedback): This process matches the layer name to the qml name. """ - inputLyrList = self.parameterAsLayerList( - parameters, - self.INPUT_LAYERS, - context - ) - styleName = self.parameterAsString( - parameters, - self.STYLE_NAME, - context - ) + inputLyrList = self.parameterAsLayerList(parameters, self.INPUT_LAYERS, context) + styleName = self.parameterAsString(parameters, self.STYLE_NAME, context) listSize = len(inputLyrList) - progressStep = 100/listSize if listSize else 0 + progressStep = 100 / listSize if listSize else 0 for current, lyr in enumerate(inputLyrList): if feedback.isCanceled(): break @@ -114,17 +106,26 @@ def processAlgorithm(self, parameters, context, feedback): if styleName in styleDict: styleQml, _ = lyr.getStyleFromDatabase(styleDict[styleName]) self.applyStyle(lyr, styleQml) - elif '{style_name}/{layer_name}'.format(style_name=styleName, layer_name=lyr.name()) in styleDict: + elif ( + "{style_name}/{layer_name}".format( + style_name=styleName, layer_name=lyr.name() + ) + in styleDict + ): styleQml, _ = lyr.getStyleFromDatabase( - styleDict['{style_name}/{layer_name}'.format(style_name=styleName, layer_name=lyr.name())] + styleDict[ + "{style_name}/{layer_name}".format( + style_name=styleName, layer_name=lyr.name() + ) + ] ) self.applyStyle(lyr, styleQml) - feedback.setProgress(current*progressStep) + feedback.setProgress(current * progressStep) return {self.OUTPUT: [i.id() for i in inputLyrList]} - + def applyStyle(self, lyr, styleQml): - styleDoc = QDomDocument('qgis') + styleDoc = QDomDocument("qgis") styleDoc.setContent(styleQml) lyr.importNamedStyle(styleDoc) lyr.triggerRepaint() @@ -137,21 +138,21 @@ def name(self): lowercase alphanumeric characters only and no spaces or other formatting characters. """ - return 'applystylesfromdatabasetolayersalgorithm' + return "applystylesfromdatabasetolayersalgorithm" def displayName(self): """ Returns the translated algorithm name, which should be used for any user-visible display of the algorithm name. """ - return self.tr('Apply Styles from Database to Layers') + return self.tr("Apply Styles from Database to Layers") def group(self): """ Returns the name of the group this algorithm belongs to. This string should be localised. """ - return self.tr('Layer Management Algorithms') + return self.tr("Layer Management Algorithms") def groupId(self): """ @@ -161,10 +162,12 @@ def groupId(self): contain lowercase alphanumeric characters only and no spaces or other formatting characters. """ - return 'DSGTools: Layer Management Algorithms' + return "DSGTools: Layer Management Algorithms" def tr(self, string): - return QCoreApplication.translate('ApplyStylesFromDatabaseToLayersAlgorithm', string) + return QCoreApplication.translate( + "ApplyStylesFromDatabaseToLayersAlgorithm", string + ) def createInstance(self): - return ApplyStylesFromDatabaseToLayersAlgorithm() \ No newline at end of file + return ApplyStylesFromDatabaseToLayersAlgorithm() diff --git a/DsgTools/core/DSGToolsProcessingAlgs/Algs/LayerManagementAlgs/assignActionsToLayersAlgorithm.py b/DsgTools/core/DSGToolsProcessingAlgs/Algs/LayerManagementAlgs/assignActionsToLayersAlgorithm.py index 5b5d3f5a9..f8220d2ca 100644 --- a/DsgTools/core/DSGToolsProcessingAlgs/Algs/LayerManagementAlgs/assignActionsToLayersAlgorithm.py +++ b/DsgTools/core/DSGToolsProcessingAlgs/Algs/LayerManagementAlgs/assignActionsToLayersAlgorithm.py @@ -8,7 +8,7 @@ begin : 2020-08-11 git sha : $Format:%H$ copyright : (C) 2020 by Jossan - email : + email : ***************************************************************************/ /*************************************************************************** @@ -23,51 +23,54 @@ from PyQt5.QtCore import QCoreApplication from PyQt5.QtGui import QColor from qgis.PyQt.Qt import QVariant -from qgis.core import (QgsProcessing, - QgsFeatureSink, - QgsProcessingAlgorithm, - QgsProcessingParameterFeatureSource, - QgsProcessingParameterFeatureSink, - QgsFeature, - QgsDataSourceUri, - QgsProcessingOutputVectorLayer, - QgsProcessingParameterVectorLayer, - QgsWkbTypes, - QgsAction, - QgsProcessingParameterBoolean, - QgsProcessingParameterEnum, - QgsProcessingParameterNumber, - QgsProcessingParameterMultipleLayers, - QgsProcessingUtils, - QgsSpatialIndex, - QgsGeometry, - QgsProcessingParameterField, - QgsProcessingMultiStepFeedback, - QgsProcessingParameterFile, - QgsProcessingParameterExpression, - QgsProcessingException, - QgsProcessingParameterString, - QgsProcessingParameterDefinition, - QgsProcessingParameterType, - QgsProcessingParameterCrs, - QgsCoordinateTransform, - QgsProject, - QgsCoordinateReferenceSystem, - QgsField, - QgsFields, - QgsProcessingOutputMultipleLayers, - QgsProcessingParameterString, - QgsConditionalStyle) +from qgis.core import ( + QgsProcessing, + QgsFeatureSink, + QgsProcessingAlgorithm, + QgsProcessingParameterFeatureSource, + QgsProcessingParameterFeatureSink, + QgsFeature, + QgsDataSourceUri, + QgsProcessingOutputVectorLayer, + QgsProcessingParameterVectorLayer, + QgsWkbTypes, + QgsAction, + QgsProcessingParameterBoolean, + QgsProcessingParameterEnum, + QgsProcessingParameterNumber, + QgsProcessingParameterMultipleLayers, + QgsProcessingUtils, + QgsSpatialIndex, + QgsGeometry, + QgsProcessingParameterField, + QgsProcessingMultiStepFeedback, + QgsProcessingParameterFile, + QgsProcessingParameterExpression, + QgsProcessingException, + QgsProcessingParameterString, + QgsProcessingParameterDefinition, + QgsProcessingParameterType, + QgsProcessingParameterCrs, + QgsCoordinateTransform, + QgsProject, + QgsCoordinateReferenceSystem, + QgsField, + QgsFields, + QgsProcessingOutputMultipleLayers, + QgsProcessingParameterString, + QgsConditionalStyle, +) from operator import itemgetter from collections import defaultdict import json, os + class AssignActionsToLayersAlgorithm(QgsProcessingAlgorithm): - INPUT_LAYERS = 'INPUT_LAYERS' - FILE = 'FILE' - TEXT = 'TEXT' - OUTPUT = 'OUTPUT' + INPUT_LAYERS = "INPUT_LAYERS" + FILE = "FILE" + TEXT = "TEXT" + OUTPUT = "OUTPUT" def initAlgorithm(self, config): """ @@ -76,32 +79,29 @@ def initAlgorithm(self, config): self.addParameter( QgsProcessingParameterMultipleLayers( self.INPUT_LAYERS, - self.tr('Input Layers'), - QgsProcessing.TypeVectorAnyGeometry + self.tr("Input Layers"), + QgsProcessing.TypeVectorAnyGeometry, ) ) self.addParameter( QgsProcessingParameterFile( - self.FILE, - self.tr('Input json file'), - defaultValue = ".json" + self.FILE, self.tr("Input json file"), defaultValue=".json" ) ) self.addParameter( QgsProcessingParameterString( self.TEXT, - description = self.tr('Input json text'), - multiLine = True, - defaultValue = '[]' + description=self.tr("Input json text"), + multiLine=True, + defaultValue="[]", ) ) self.addOutput( QgsProcessingOutputMultipleLayers( - self.OUTPUT, - self.tr('Original layers id with actions') + self.OUTPUT, self.tr("Original layers id with actions") ) ) @@ -110,22 +110,10 @@ def processAlgorithm(self, parameters, context, feedback): Here is where the processing itself takes place. """ - inputLyrList = self.parameterAsLayerList( - parameters, - self.INPUT_LAYERS, - context - ) - inputJSONFile = self.parameterAsFile( - parameters, - self.FILE, - context - ) + inputLyrList = self.parameterAsLayerList(parameters, self.INPUT_LAYERS, context) + inputJSONFile = self.parameterAsFile(parameters, self.FILE, context) inputJSONData = json.loads( - self.parameterAsString( - parameters, - self.TEXT, - context - ) + self.parameterAsString(parameters, self.TEXT, context) ) if os.path.exists(inputJSONFile): self.loadActionsFromJSONFile(inputJSONFile, inputLyrList, feedback) @@ -138,40 +126,40 @@ def processAlgorithm(self, parameters, context, feedback): def loadActionsFromJSONFile(self, inputJSONFile, inputLyrList, feedback): inputJSONData = json.load(inputJSONFile) self.loadActionsFromJSONData(inputJSONData, inputLyrList, feedback) - + def loadActionsFromJSONData(self, inputJSONData, inputLyrList, feedback): actionType = { - 'Generic' : QgsAction.ActionType.Generic, - 'GenericPython' : QgsAction.ActionType.GenericPython, - 'Mac' : QgsAction.ActionType.Mac, - 'Windows' : QgsAction.ActionType.Windows, - 'Unix' : QgsAction.ActionType.Unix, - 'OpenUrl' : QgsAction.ActionType.OpenUrl + "Generic": QgsAction.ActionType.Generic, + "GenericPython": QgsAction.ActionType.GenericPython, + "Mac": QgsAction.ActionType.Mac, + "Windows": QgsAction.ActionType.Windows, + "Unix": QgsAction.ActionType.Unix, + "OpenUrl": QgsAction.ActionType.OpenUrl, } listSize = len(inputLyrList) - progressStep = 100/listSize if listSize else 0 - layerNames = [ item['camadaNome'] for item in inputJSONData] + progressStep = 100 / listSize if listSize else 0 + layerNames = [item["camadaNome"] for item in inputJSONData] for current, lyr in enumerate(inputLyrList): - + if feedback.isCanceled(): break - feedback.setProgress(current*progressStep) - - if not(lyr.dataProvider().uri().table() in layerNames): + feedback.setProgress(current * progressStep) + + if not (lyr.dataProvider().uri().table() in layerNames): continue - + layerIdx = layerNames.index(lyr.dataProvider().uri().table()) - - docPath = inputJSONData[layerIdx]['documentacao'] + + docPath = inputJSONData[layerIdx]["documentacao"] if not docPath: continue action = QgsAction( - actionType[inputJSONData[layerIdx]['tipo']], - inputJSONData[layerIdx]['descricao'], - "[%'{}'%]".format(docPath) + actionType[inputJSONData[layerIdx]["tipo"]], + inputJSONData[layerIdx]["descricao"], + "[%'{}'%]".format(docPath), ) - action.setActionScopes({'Feature', 'Canvas'}) + action.setActionScopes({"Feature", "Canvas"}) lyr.actions().addAction(action) def name(self): @@ -182,21 +170,21 @@ def name(self): lowercase alphanumeric characters only and no spaces or other formatting characters. """ - return 'assignactionstolayersalgorithm' + return "assignactionstolayersalgorithm" def displayName(self): """ Returns the translated algorithm name, which should be used for any user-visible display of the algorithm name. """ - return self.tr('Assign Actions To Layers') + return self.tr("Assign Actions To Layers") def group(self): """ Returns the name of the group this algorithm belongs to. This string should be localised. """ - return self.tr('Layer Management Algorithms') + return self.tr("Layer Management Algorithms") def groupId(self): """ @@ -206,10 +194,10 @@ def groupId(self): contain lowercase alphanumeric characters only and no spaces or other formatting characters. """ - return 'DSGTools: Layer Management Algorithms' + return "DSGTools: Layer Management Algorithms" def tr(self, string): - return QCoreApplication.translate('AssignActionsToLayersAlgorithm', string) + return QCoreApplication.translate("AssignActionsToLayersAlgorithm", string) def createInstance(self): - return AssignActionsToLayersAlgorithm() \ No newline at end of file + return AssignActionsToLayersAlgorithm() diff --git a/DsgTools/core/DSGToolsProcessingAlgs/Algs/LayerManagementAlgs/assignAliasesToLayersAlgorithm.py b/DsgTools/core/DSGToolsProcessingAlgs/Algs/LayerManagementAlgs/assignAliasesToLayersAlgorithm.py index f052622a2..053ace56b 100644 --- a/DsgTools/core/DSGToolsProcessingAlgs/Algs/LayerManagementAlgs/assignAliasesToLayersAlgorithm.py +++ b/DsgTools/core/DSGToolsProcessingAlgs/Algs/LayerManagementAlgs/assignAliasesToLayersAlgorithm.py @@ -21,59 +21,64 @@ ***************************************************************************/ """ from PyQt5.QtCore import QCoreApplication -from qgis.core import (QgsProcessing, - QgsProcessingAlgorithm, - QgsProcessingParameterMultipleLayers, - QgsProcessingParameterFile, - QgsProcessingParameterString, - QgsProcessingOutputMultipleLayers, - QgsProcessingParameterString, - QgsEditorWidgetSetup) +from qgis.core import ( + QgsProcessing, + QgsProcessingAlgorithm, + QgsProcessingParameterMultipleLayers, + QgsProcessingParameterFile, + QgsProcessingParameterString, + QgsProcessingOutputMultipleLayers, + QgsProcessingParameterString, + QgsEditorWidgetSetup, +) from PyQt5.QtGui import QColor from qgis.PyQt.Qt import QVariant -from qgis.core import (QgsProcessing, - QgsFeatureSink, - QgsProcessingAlgorithm, - QgsProcessingParameterFeatureSource, - QgsProcessingParameterFeatureSink, - QgsFeature, - QgsDataSourceUri, - QgsProcessingOutputVectorLayer, - QgsProcessingParameterVectorLayer, - QgsWkbTypes, - QgsProcessingParameterBoolean, - QgsProcessingParameterEnum, - QgsProcessingParameterNumber, - QgsProcessingParameterMultipleLayers, - QgsProcessingUtils, - QgsSpatialIndex, - QgsGeometry, - QgsProcessingParameterField, - QgsProcessingMultiStepFeedback, - QgsProcessingParameterFile, - QgsProcessingParameterExpression, - QgsProcessingException, - QgsProcessingParameterString, - QgsProcessingParameterDefinition, - QgsProcessingParameterType, - QgsProcessingParameterCrs, - QgsCoordinateTransform, - QgsProject, - QgsCoordinateReferenceSystem, - QgsField, - QgsFields, - QgsProcessingOutputMultipleLayers, - QgsProcessingParameterString, - QgsConditionalStyle) +from qgis.core import ( + QgsProcessing, + QgsFeatureSink, + QgsProcessingAlgorithm, + QgsProcessingParameterFeatureSource, + QgsProcessingParameterFeatureSink, + QgsFeature, + QgsDataSourceUri, + QgsProcessingOutputVectorLayer, + QgsProcessingParameterVectorLayer, + QgsWkbTypes, + QgsProcessingParameterBoolean, + QgsProcessingParameterEnum, + QgsProcessingParameterNumber, + QgsProcessingParameterMultipleLayers, + QgsProcessingUtils, + QgsSpatialIndex, + QgsGeometry, + QgsProcessingParameterField, + QgsProcessingMultiStepFeedback, + QgsProcessingParameterFile, + QgsProcessingParameterExpression, + QgsProcessingException, + QgsProcessingParameterString, + QgsProcessingParameterDefinition, + QgsProcessingParameterType, + QgsProcessingParameterCrs, + QgsCoordinateTransform, + QgsProject, + QgsCoordinateReferenceSystem, + QgsField, + QgsFields, + QgsProcessingOutputMultipleLayers, + QgsProcessingParameterString, + QgsConditionalStyle, +) from operator import itemgetter from collections import defaultdict import json, os + class AssignAliasesToLayersAlgorithm(QgsProcessingAlgorithm): - INPUT_LAYERS = 'INPUT_LAYERS' - FILE = 'FILE' - TEXT = 'TEXT' - OUTPUT = 'OUTPUT' + INPUT_LAYERS = "INPUT_LAYERS" + FILE = "FILE" + TEXT = "TEXT" + OUTPUT = "OUTPUT" def initAlgorithm(self, config): """ @@ -82,32 +87,29 @@ def initAlgorithm(self, config): self.addParameter( QgsProcessingParameterMultipleLayers( self.INPUT_LAYERS, - self.tr('Input Layers'), - QgsProcessing.TypeVectorAnyGeometry + self.tr("Input Layers"), + QgsProcessing.TypeVectorAnyGeometry, ) ) self.addParameter( QgsProcessingParameterFile( - self.FILE, - self.tr('Input json file'), - defaultValue = ".json" + self.FILE, self.tr("Input json file"), defaultValue=".json" ) ) self.addParameter( QgsProcessingParameterString( self.TEXT, - description = self.tr('Input json text'), - multiLine = True, - defaultValue = '[]' + description=self.tr("Input json text"), + multiLine=True, + defaultValue="[]", ) ) self.addOutput( QgsProcessingOutputMultipleLayers( - self.OUTPUT, - self.tr('Original layers id with aliases') + self.OUTPUT, self.tr("Original layers id with aliases") ) ) @@ -116,22 +118,10 @@ def processAlgorithm(self, parameters, context, feedback): Here is where the processing itself takes place. """ - inputLyrList = self.parameterAsLayerList( - parameters, - self.INPUT_LAYERS, - context - ) - inputJSONFile = self.parameterAsFile( - parameters, - self.FILE, - context - ) + inputLyrList = self.parameterAsLayerList(parameters, self.INPUT_LAYERS, context) + inputJSONFile = self.parameterAsFile(parameters, self.FILE, context) inputJSONData = json.loads( - self.parameterAsString( - parameters, - self.TEXT, - context - ) + self.parameterAsString(parameters, self.TEXT, context) ) if os.path.exists(inputJSONFile): self.loadAliasFromJSONFile(inputJSONFile, inputLyrList, feedback) @@ -144,34 +134,38 @@ def processAlgorithm(self, parameters, context, feedback): def loadAliasFromJSONFile(self, inputJSONFile, inputLyrList, feedback): inputJSONData = json.load(inputJSONFile) self.loadAliasFromJSONData(inputJSONData, inputLyrList, feedback) - + def loadAliasFromJSONData(self, inputJSONData, inputLyrList, feedback): listSize = len(inputLyrList) - progressStep = 100/listSize if listSize else 0 - layerNames = [ item['camadaNome'] for item in inputJSONData] + progressStep = 100 / listSize if listSize else 0 + layerNames = [item["camadaNome"] for item in inputJSONData] for current, lyr in enumerate(inputLyrList): - + if feedback.isCanceled(): break - feedback.setProgress(current*progressStep) - - if not(lyr.dataProvider().uri().table() in layerNames): + feedback.setProgress(current * progressStep) + + if not (lyr.dataProvider().uri().table() in layerNames): continue - + layerIdx = layerNames.index(lyr.dataProvider().uri().table()) - - layerAlias = inputJSONData[layerIdx]['camadaApelido'] + + layerAlias = inputJSONData[layerIdx]["camadaApelido"] if layerAlias: lyr.setName(layerAlias) - attributeAlias = inputJSONData[layerIdx]['atributosApelido'] + attributeAlias = inputJSONData[layerIdx]["atributosApelido"] if len(attributeAlias) > 0: for attr in attributeAlias: idx = lyr.fields().indexOf(attr["nome"]) - if not(idx > 0): + if not (idx > 0): continue - oldEditor = QgsEditorWidgetSetup(lyr.editorWidgetSetup(idx)) if lyr.editorWidgetSetup(idx).config() else None + oldEditor = ( + QgsEditorWidgetSetup(lyr.editorWidgetSetup(idx)) + if lyr.editorWidgetSetup(idx).config() + else None + ) lyr.setFieldAlias(idx, attr["alias"]) if oldEditor is not None: lyr.setEditorWidgetSetup(idx, oldEditor) @@ -184,21 +178,21 @@ def name(self): lowercase alphanumeric characters only and no spaces or other formatting characters. """ - return 'assignaliasestolayersalgorithm' + return "assignaliasestolayersalgorithm" def displayName(self): """ Returns the translated algorithm name, which should be used for any user-visible display of the algorithm name. """ - return self.tr('Assign Aliases to Layers') + return self.tr("Assign Aliases to Layers") def group(self): """ Returns the name of the group this algorithm belongs to. This string should be localised. """ - return self.tr('Layer Management Algorithms') + return self.tr("Layer Management Algorithms") def groupId(self): """ @@ -208,10 +202,10 @@ def groupId(self): contain lowercase alphanumeric characters only and no spaces or other formatting characters. """ - return 'DSGTools: Layer Management Algorithms' + return "DSGTools: Layer Management Algorithms" def tr(self, string): - return QCoreApplication.translate('AssignAliasesToLayersAlgorithm', string) + return QCoreApplication.translate("AssignAliasesToLayersAlgorithm", string) def createInstance(self): - return AssignAliasesToLayersAlgorithm() \ No newline at end of file + return AssignAliasesToLayersAlgorithm() diff --git a/DsgTools/core/DSGToolsProcessingAlgs/Algs/LayerManagementAlgs/assignBoundingBoxFilterToLayersAlgorithm.py b/DsgTools/core/DSGToolsProcessingAlgs/Algs/LayerManagementAlgs/assignBoundingBoxFilterToLayersAlgorithm.py index eab84846c..0fd5970bb 100644 --- a/DsgTools/core/DSGToolsProcessingAlgs/Algs/LayerManagementAlgs/assignBoundingBoxFilterToLayersAlgorithm.py +++ b/DsgTools/core/DSGToolsProcessingAlgs/Algs/LayerManagementAlgs/assignBoundingBoxFilterToLayersAlgorithm.py @@ -22,46 +22,50 @@ """ from PyQt5.QtCore import QCoreApplication from DsgTools.core.GeometricTools.geometryHandler import GeometryHandler -from qgis.core import (QgsProcessing, - QgsFeatureSink, - QgsProcessingAlgorithm, - QgsProcessingParameterFeatureSource, - QgsProcessingParameterFeatureSink, - QgsFeature, - QgsDataSourceUri, - QgsProcessingOutputVectorLayer, - QgsProcessingParameterVectorLayer, - QgsWkbTypes, - QgsProcessingParameterBoolean, - QgsProcessingParameterEnum, - QgsProcessingParameterNumber, - QgsProcessingParameterMultipleLayers, - QgsProcessingUtils, - QgsSpatialIndex, - QgsGeometry, - QgsProcessingParameterField, - QgsProcessingMultiStepFeedback, - QgsProcessingParameterFile, - QgsProcessingParameterExpression, - QgsProcessingException, - QgsProcessingParameterString, - QgsProcessingParameterDefinition, - QgsProcessingParameterType, - QgsProcessingParameterCrs, - QgsCoordinateTransform, - QgsProject, - QgsCoordinateReferenceSystem, - QgsField, - QgsFields, - QgsProcessingOutputMultipleLayers, - QgsProcessingParameterExtent) +from qgis.core import ( + QgsProcessing, + QgsFeatureSink, + QgsProcessingAlgorithm, + QgsProcessingParameterFeatureSource, + QgsProcessingParameterFeatureSink, + QgsFeature, + QgsDataSourceUri, + QgsProcessingOutputVectorLayer, + QgsProcessingParameterVectorLayer, + QgsWkbTypes, + QgsProcessingParameterBoolean, + QgsProcessingParameterEnum, + QgsProcessingParameterNumber, + QgsProcessingParameterMultipleLayers, + QgsProcessingUtils, + QgsSpatialIndex, + QgsGeometry, + QgsProcessingParameterField, + QgsProcessingMultiStepFeedback, + QgsProcessingParameterFile, + QgsProcessingParameterExpression, + QgsProcessingException, + QgsProcessingParameterString, + QgsProcessingParameterDefinition, + QgsProcessingParameterType, + QgsProcessingParameterCrs, + QgsCoordinateTransform, + QgsProject, + QgsCoordinateReferenceSystem, + QgsField, + QgsFields, + QgsProcessingOutputMultipleLayers, + QgsProcessingParameterExtent, +) + class AssignBoundingBoxFilterToLayersAlgorithm(QgsProcessingAlgorithm): - INPUT_LAYERS = 'INPUT_LAYERS' - BB_FILTER = 'BB_FILTER' - BEHAVIOR = 'BEHAVIOR' - OUTPUT = 'OUTPUT' + INPUT_LAYERS = "INPUT_LAYERS" + BB_FILTER = "BB_FILTER" + BEHAVIOR = "BEHAVIOR" + OUTPUT = "OUTPUT" AndMode, OrMode, ReplaceMode = list(range(3)) + def initAlgorithm(self, config): """ Parameter setting. @@ -69,36 +73,30 @@ def initAlgorithm(self, config): self.addParameter( QgsProcessingParameterMultipleLayers( self.INPUT_LAYERS, - self.tr('Input Layers'), - QgsProcessing.TypeVectorAnyGeometry + self.tr("Input Layers"), + QgsProcessing.TypeVectorAnyGeometry, ) ) self.addParameter( - QgsProcessingParameterExtent( - self.BB_FILTER, - self.tr('Filter') - ) + QgsProcessingParameterExtent(self.BB_FILTER, self.tr("Filter")) ) - self.modes = [self.tr('Append to existing filter with AND clause'), - self.tr('Append to existing filter with OR clause'), - self.tr('Replace filter') - ] + self.modes = [ + self.tr("Append to existing filter with AND clause"), + self.tr("Append to existing filter with OR clause"), + self.tr("Replace filter"), + ] self.addParameter( QgsProcessingParameterEnum( - self.BEHAVIOR, - self.tr('Behavior'), - options=self.modes, - defaultValue=0 + self.BEHAVIOR, self.tr("Behavior"), options=self.modes, defaultValue=0 ) ) self.addOutput( QgsProcessingOutputMultipleLayers( - self.OUTPUT, - self.tr('Original layers with assigned styles') + self.OUTPUT, self.tr("Original layers with assigned styles") ) ) @@ -106,34 +104,28 @@ def processAlgorithm(self, parameters, context, feedback): """ Here is where the processing itself takes place. """ - inputLyrList = self.parameterAsLayerList( - parameters, - self.INPUT_LAYERS, - context - ) + inputLyrList = self.parameterAsLayerList(parameters, self.INPUT_LAYERS, context) boundingBoxGeometry = self.parameterAsExtentGeometry( - parameters, - self.BB_FILTER, - context + parameters, self.BB_FILTER, context ) - behavior = self.parameterAsEnum( - parameters, - self.BEHAVIOR, - context - ) + behavior = self.parameterAsEnum(parameters, self.BEHAVIOR, context) progressStep = 100 / len(inputLyrList) if len(inputLyrList) else 0 for current, lyr in enumerate(inputLyrList): if feedback.isCanceled(): break - if lyr.dataProvider().name() != 'postgres': - feedback.pushInfo(self.tr('Operation only defined for postgres provider. Layer {layer} will be skipped.')) + if lyr.dataProvider().name() != "postgres": + feedback.pushInfo( + self.tr( + "Operation only defined for postgres provider. Layer {layer} will be skipped." + ) + ) continue bboxClause = self.buildSpatialClause(lyr, boundingBoxGeometry) - if bboxClause == '': + if bboxClause == "": continue filterExpression = self.adaptFilter(lyr, bboxClause, behavior) lyr.setSubsetString(filterExpression) - feedback.setProgress(current*progressStep) + feedback.setProgress(current * progressStep) return {self.OUTPUT: inputLyrList} @@ -142,24 +134,31 @@ def adaptFilter(self, lyr, bboxClause, behavior): Adapts filter according to the selected mode """ originalFilter = lyr.subsetString() - if behavior == AssignBoundingBoxFilterToLayersAlgorithm.ReplaceMode or originalFilter == '': + if ( + behavior == AssignBoundingBoxFilterToLayersAlgorithm.ReplaceMode + or originalFilter == "" + ): return bboxClause - clause = ' AND ' if behavior == AssignBoundingBoxFilterToLayersAlgorithm.AndMode else ' OR ' + clause = ( + " AND " + if behavior == AssignBoundingBoxFilterToLayersAlgorithm.AndMode + else " OR " + ) return clause.join([originalFilter, bboxClause]) - + def buildSpatialClause(self, lyr, boundingBoxGeometry): - geometryColumn = QgsDataSourceUri(lyr.dataProvider().dataSourceUri()).geometryColumn() - if geometryColumn == '': - return '' - epsg = lyr.crs().authid().replace('EPSG:','SRID=') + geometryColumn = QgsDataSourceUri( + lyr.dataProvider().dataSourceUri() + ).geometryColumn() + if geometryColumn == "": + return "" + epsg = lyr.crs().authid().replace("EPSG:", "SRID=") GeometryHandler().reprojectFeature(boundingBoxGeometry, lyr.crs()) - geomEwkt = ' ; '.join([epsg, boundingBoxGeometry.asWkt()]) + geomEwkt = " ; ".join([epsg, boundingBoxGeometry.asWkt()]) return """ST_INTERSECTS({geom}, ST_GEOMFROMEWKT('{ewkt}'))""".format( - geom=geometryColumn, - ewkt=geomEwkt + geom=geometryColumn, ewkt=geomEwkt ) - def name(self): """ Returns the algorithm name, used for identifying the algorithm. This @@ -168,21 +167,21 @@ def name(self): lowercase alphanumeric characters only and no spaces or other formatting characters. """ - return 'assignboundingboxfiltertolayers' + return "assignboundingboxfiltertolayers" def displayName(self): """ Returns the translated algorithm name, which should be used for any user-visible display of the algorithm name. """ - return self.tr('Assign Bounding Box Filter to Layers') + return self.tr("Assign Bounding Box Filter to Layers") def group(self): """ Returns the name of the group this algorithm belongs to. This string should be localised. """ - return self.tr('Layer Management Algorithms') + return self.tr("Layer Management Algorithms") def groupId(self): """ @@ -192,10 +191,12 @@ def groupId(self): contain lowercase alphanumeric characters only and no spaces or other formatting characters. """ - return 'DSGTools: Layer Management Algorithms' + return "DSGTools: Layer Management Algorithms" def tr(self, string): - return QCoreApplication.translate('AssignBoundingBoxFilterToLayersAlgorithm', string) + return QCoreApplication.translate( + "AssignBoundingBoxFilterToLayersAlgorithm", string + ) def createInstance(self): - return AssignBoundingBoxFilterToLayersAlgorithm() \ No newline at end of file + return AssignBoundingBoxFilterToLayersAlgorithm() diff --git a/DsgTools/core/DSGToolsProcessingAlgs/Algs/LayerManagementAlgs/assignConditionalStyleToLayersAlgorithm.py b/DsgTools/core/DSGToolsProcessingAlgs/Algs/LayerManagementAlgs/assignConditionalStyleToLayersAlgorithm.py index d26ad7697..46b5d808d 100644 --- a/DsgTools/core/DSGToolsProcessingAlgs/Algs/LayerManagementAlgs/assignConditionalStyleToLayersAlgorithm.py +++ b/DsgTools/core/DSGToolsProcessingAlgs/Algs/LayerManagementAlgs/assignConditionalStyleToLayersAlgorithm.py @@ -8,7 +8,7 @@ begin : 2020-08-11 git sha : $Format:%H$ copyright : (C) 2020 by Jossan - email : + email : ***************************************************************************/ /*************************************************************************** @@ -23,51 +23,54 @@ from PyQt5.QtCore import QCoreApplication from PyQt5.QtGui import QColor from qgis.PyQt.Qt import QVariant -from qgis.core import (QgsProcessing, - QgsFeatureSink, - QgsProcessingAlgorithm, - QgsProcessingParameterFeatureSource, - QgsProcessingParameterFeatureSink, - QgsFeature, - QgsDataSourceUri, - QgsProcessingOutputVectorLayer, - QgsProcessingParameterVectorLayer, - QgsWkbTypes, - QgsAction, - QgsProcessingParameterBoolean, - QgsProcessingParameterEnum, - QgsProcessingParameterNumber, - QgsProcessingParameterMultipleLayers, - QgsProcessingUtils, - QgsSpatialIndex, - QgsGeometry, - QgsProcessingParameterField, - QgsProcessingMultiStepFeedback, - QgsProcessingParameterFile, - QgsProcessingParameterExpression, - QgsProcessingException, - QgsProcessingParameterString, - QgsProcessingParameterDefinition, - QgsProcessingParameterType, - QgsProcessingParameterCrs, - QgsCoordinateTransform, - QgsProject, - QgsCoordinateReferenceSystem, - QgsField, - QgsFields, - QgsProcessingOutputMultipleLayers, - QgsProcessingParameterString, - QgsConditionalStyle) +from qgis.core import ( + QgsProcessing, + QgsFeatureSink, + QgsProcessingAlgorithm, + QgsProcessingParameterFeatureSource, + QgsProcessingParameterFeatureSink, + QgsFeature, + QgsDataSourceUri, + QgsProcessingOutputVectorLayer, + QgsProcessingParameterVectorLayer, + QgsWkbTypes, + QgsAction, + QgsProcessingParameterBoolean, + QgsProcessingParameterEnum, + QgsProcessingParameterNumber, + QgsProcessingParameterMultipleLayers, + QgsProcessingUtils, + QgsSpatialIndex, + QgsGeometry, + QgsProcessingParameterField, + QgsProcessingMultiStepFeedback, + QgsProcessingParameterFile, + QgsProcessingParameterExpression, + QgsProcessingException, + QgsProcessingParameterString, + QgsProcessingParameterDefinition, + QgsProcessingParameterType, + QgsProcessingParameterCrs, + QgsCoordinateTransform, + QgsProject, + QgsCoordinateReferenceSystem, + QgsField, + QgsFields, + QgsProcessingOutputMultipleLayers, + QgsProcessingParameterString, + QgsConditionalStyle, +) from operator import itemgetter from collections import defaultdict import json, os + class AssignConditionalStyleToLayersAlgorithm(QgsProcessingAlgorithm): - INPUT_LAYERS = 'INPUT_LAYERS' - FILE = 'FILE' - TEXT = 'TEXT' - OUTPUT = 'OUTPUT' + INPUT_LAYERS = "INPUT_LAYERS" + FILE = "FILE" + TEXT = "TEXT" + OUTPUT = "OUTPUT" def initAlgorithm(self, config): """ @@ -76,32 +79,29 @@ def initAlgorithm(self, config): self.addParameter( QgsProcessingParameterMultipleLayers( self.INPUT_LAYERS, - self.tr('Input Layers'), - QgsProcessing.TypeVectorAnyGeometry + self.tr("Input Layers"), + QgsProcessing.TypeVectorAnyGeometry, ) ) self.addParameter( QgsProcessingParameterFile( - self.FILE, - self.tr('Input json file'), - defaultValue = ".json" + self.FILE, self.tr("Input json file"), defaultValue=".json" ) ) self.addParameter( QgsProcessingParameterString( self.TEXT, - description = self.tr('Input json text'), - multiLine = True, - defaultValue = '[]' + description=self.tr("Input json text"), + multiLine=True, + defaultValue="[]", ) ) self.addOutput( QgsProcessingOutputMultipleLayers( - self.OUTPUT, - self.tr('Original layers id with default field value') + self.OUTPUT, self.tr("Original layers id with default field value") ) ) @@ -110,23 +110,11 @@ def processAlgorithm(self, parameters, context, feedback): Here is where the processing itself takes place. """ - inputLyrList = self.parameterAsLayerList( - parameters, - self.INPUT_LAYERS, - context - ) - inputJSONFile = self.parameterAsFile( - parameters, - self.FILE, - context - ) + inputLyrList = self.parameterAsLayerList(parameters, self.INPUT_LAYERS, context) + inputJSONFile = self.parameterAsFile(parameters, self.FILE, context) inputJSONData = json.loads( - self.parameterAsString( - parameters, - self.TEXT, - context - ) - ) + self.parameterAsString(parameters, self.TEXT, context) + ) if os.path.exists(inputJSONFile): self.loadConditionalStyleFromJSONFile(inputJSONFile, inputLyrList, feedback) elif len(inputJSONData) > 0: @@ -138,46 +126,44 @@ def processAlgorithm(self, parameters, context, feedback): def loadConditionalStyleFromJSONFile(self, inputJSONFile, inputLyrList, feedback): inputJSONData = json.load(inputJSONFile) self.loadConditionalStyleFromJSONData(inputJSONData, inputLyrList, feedback) - + def loadConditionalStyleFromJSONData(self, inputJSONData, inputLyrList, feedback): listSize = len(inputLyrList) - progressStep = 100/listSize if listSize else 0 - layerNames = [ item['camadaNome'] for item in inputJSONData] + progressStep = 100 / listSize if listSize else 0 + layerNames = [item["camadaNome"] for item in inputJSONData] for current, lyr in enumerate(inputLyrList): - + if feedback.isCanceled(): break - feedback.setProgress(current*progressStep) - - if not(lyr.dataProvider().uri().table() in layerNames): + feedback.setProgress(current * progressStep) + + if not (lyr.dataProvider().uri().table() in layerNames): continue - + layerIdx = layerNames.index(lyr.dataProvider().uri().table()) - conditionalStyles = inputJSONData[layerIdx]['estilos'] + conditionalStyles = inputJSONData[layerIdx]["estilos"] if not conditionalStyles: continue for order in reversed(sorted(conditionalStyles)): - for field in conditionalStyles[order]['atributos']: - if conditionalStyles[order]['tipo'].lower() == 'atributo': + for field in conditionalStyles[order]["atributos"]: + if conditionalStyles[order]["tipo"].lower() == "atributo": lyr.conditionalStyles().setFieldStyles( field, [ self.createConditionalStyle( - item['descricao'], - item['regra'], - item['corRgb'] + item["descricao"], item["regra"], item["corRgb"] ) - for item in conditionalStyles[order]['atributos'][field] - ] + for item in conditionalStyles[order]["atributos"][field] + ], ) def createConditionalStyle(self, description, rule, rgbString): conditionalStyle = QgsConditionalStyle() - conditionalStyle.setName( description ) - conditionalStyle.setRule( rule ) - r, g, b = rgbString.split(',') + conditionalStyle.setName(description) + conditionalStyle.setRule(rule) + r, g, b = rgbString.split(",") conditionalStyle.setBackgroundColor(QColor(int(r), int(g), int(b))) return conditionalStyle @@ -189,21 +175,21 @@ def name(self): lowercase alphanumeric characters only and no spaces or other formatting characters. """ - return 'assignconditionalstyletolayersalgorithm' + return "assignconditionalstyletolayersalgorithm" def displayName(self): """ Returns the translated algorithm name, which should be used for any user-visible display of the algorithm name. """ - return self.tr('Assign Conditional Style To Layers') + return self.tr("Assign Conditional Style To Layers") def group(self): """ Returns the name of the group this algorithm belongs to. This string should be localised. """ - return self.tr('Layer Management Algorithms') + return self.tr("Layer Management Algorithms") def groupId(self): """ @@ -213,10 +199,12 @@ def groupId(self): contain lowercase alphanumeric characters only and no spaces or other formatting characters. """ - return 'DSGTools: Layer Management Algorithms' + return "DSGTools: Layer Management Algorithms" def tr(self, string): - return QCoreApplication.translate('AssignConditionalStyleToLayersAlgorithm', string) + return QCoreApplication.translate( + "AssignConditionalStyleToLayersAlgorithm", string + ) def createInstance(self): - return AssignConditionalStyleToLayersAlgorithm() \ No newline at end of file + return AssignConditionalStyleToLayersAlgorithm() diff --git a/DsgTools/core/DSGToolsProcessingAlgs/Algs/LayerManagementAlgs/assignCustomFormAndFormatRulesToLayersAlgorithm.py b/DsgTools/core/DSGToolsProcessingAlgs/Algs/LayerManagementAlgs/assignCustomFormAndFormatRulesToLayersAlgorithm.py index 88044e154..fe8a1db1e 100644 --- a/DsgTools/core/DSGToolsProcessingAlgs/Algs/LayerManagementAlgs/assignCustomFormAndFormatRulesToLayersAlgorithm.py +++ b/DsgTools/core/DSGToolsProcessingAlgs/Algs/LayerManagementAlgs/assignCustomFormAndFormatRulesToLayersAlgorithm.py @@ -23,103 +23,97 @@ from PyQt5.QtCore import QCoreApplication from PyQt5.QtGui import QColor from qgis.PyQt.Qt import QVariant -from qgis.core import (QgsProcessing, - QgsFeatureSink, - QgsProcessingAlgorithm, - QgsProcessingParameterFeatureSource, - QgsProcessingParameterFeatureSink, - QgsFeature, - QgsDataSourceUri, - QgsProcessingOutputVectorLayer, - QgsProcessingParameterVectorLayer, - QgsWkbTypes, - QgsProcessingParameterBoolean, - QgsProcessingParameterEnum, - QgsProcessingParameterNumber, - QgsProcessingParameterMultipleLayers, - QgsProcessingUtils, - QgsSpatialIndex, - QgsGeometry, - QgsProcessingParameterField, - QgsProcessingMultiStepFeedback, - QgsProcessingParameterFile, - QgsProcessingParameterExpression, - QgsProcessingException, - QgsProcessingParameterString, - QgsProcessingParameterDefinition, - QgsProcessingParameterType, - QgsProcessingParameterCrs, - QgsCoordinateTransform, - QgsProject, - QgsCoordinateReferenceSystem, - QgsField, - QgsFields, - QgsProcessingOutputMultipleLayers, - QgsProcessingParameterString, - QgsConditionalStyle) +from qgis.core import ( + QgsProcessing, + QgsFeatureSink, + QgsProcessingAlgorithm, + QgsProcessingParameterFeatureSource, + QgsProcessingParameterFeatureSink, + QgsFeature, + QgsDataSourceUri, + QgsProcessingOutputVectorLayer, + QgsProcessingParameterVectorLayer, + QgsWkbTypes, + QgsProcessingParameterBoolean, + QgsProcessingParameterEnum, + QgsProcessingParameterNumber, + QgsProcessingParameterMultipleLayers, + QgsProcessingUtils, + QgsSpatialIndex, + QgsGeometry, + QgsProcessingParameterField, + QgsProcessingMultiStepFeedback, + QgsProcessingParameterFile, + QgsProcessingParameterExpression, + QgsProcessingException, + QgsProcessingParameterString, + QgsProcessingParameterDefinition, + QgsProcessingParameterType, + QgsProcessingParameterCrs, + QgsCoordinateTransform, + QgsProject, + QgsCoordinateReferenceSystem, + QgsField, + QgsFields, + QgsProcessingOutputMultipleLayers, + QgsProcessingParameterString, + QgsConditionalStyle, +) -from DsgTools.core.DSGToolsProcessingAlgs.Algs.OtherAlgs.ruleStatisticsAlgorithm import \ - RuleStatisticsAlgorithm -from DsgTools.core.LayerTools.CustomFormTools.customFormGenerator import CustomFormGenerator -from DsgTools.core.LayerTools.CustomFormTools.customInitCodeGenerator import \ - CustomInitCodeGenerator +from DsgTools.core.DSGToolsProcessingAlgs.Algs.OtherAlgs.ruleStatisticsAlgorithm import ( + RuleStatisticsAlgorithm, +) +from DsgTools.core.LayerTools.CustomFormTools.customFormGenerator import ( + CustomFormGenerator, +) +from DsgTools.core.LayerTools.CustomFormTools.customInitCodeGenerator import ( + CustomInitCodeGenerator, +) from operator import itemgetter from collections import defaultdict + class AssignCustomFormAndFormatRulesToLayersAlgorithm(RuleStatisticsAlgorithm): - CLEAN_BEFORE_ASSIGN = 'CLEAN_BEFORE_ASSIGN' - MODE = 'MODE' + CLEAN_BEFORE_ASSIGN = "CLEAN_BEFORE_ASSIGN" + MODE = "MODE" def initAlgorithm(self, config=None): - super(AssignCustomFormAndFormatRulesToLayersAlgorithm, self).initAlgorithm(config=config) + super(AssignCustomFormAndFormatRulesToLayersAlgorithm, self).initAlgorithm( + config=config + ) self.addParameter( QgsProcessingParameterBoolean( - self.CLEAN_BEFORE_ASSIGN, - self.tr('Clean before assign format rules') + self.CLEAN_BEFORE_ASSIGN, self.tr("Clean before assign format rules") ) ) self.modes = [ - self.tr('Assing only custom form'), - self.tr('Assign only format rules'), - self.tr('Assign custom form and format rules') + self.tr("Assing only custom form"), + self.tr("Assign only format rules"), + self.tr("Assign custom form and format rules"), ] self.addParameter( QgsProcessingParameterEnum( - self.MODE, - self.tr('Mode'), - options=self.modes, - defaultValue=0 + self.MODE, self.tr("Mode"), options=self.modes, defaultValue=0 ) ) - def processAlgorithm(self, parameters, context, feedback): """ Here is where the processing itself takes place. """ - inputLyrList = self.parameterAsLayerList( - parameters, - self.INPUTLAYERS, - context - ) + inputLyrList = self.parameterAsLayerList(parameters, self.INPUTLAYERS, context) if not inputLyrList: return {} input_data = self.load_rules_from_parameters(parameters) - mode = self.parameterAsEnum( - parameters, - self.MODE, - context - ) + mode = self.parameterAsEnum(parameters, self.MODE, context) cleanBefore = self.parameterAsBool( - parameters, - self.CLEAN_BEFORE_ASSIGN, - context - ) + parameters, self.CLEAN_BEFORE_ASSIGN, context + ) if cleanBefore: self.cleanRules(inputLyrList) listSize = len(inputLyrList) - stepSize = 100/listSize if listSize else 0 + stepSize = 100 / listSize if listSize else 0 self.ruleDict = self.buildRuleDict(input_data) self.customFormGenerator = CustomFormGenerator() self.customInitGenerator = CustomInitCodeGenerator() @@ -128,14 +122,14 @@ def processAlgorithm(self, parameters, context, feedback): if feedback.isCanceled(): break if mode == 0: - #only custom form + # only custom form self.assignFormToLayer(lyr) elif mode == 1: - #only format rules + # only format rules self.addRuleToLayer(lyr, feedback=feedback) self.createRuleVirtualField(lyr) else: - #both + # both self.assignFormToLayer(lyr) self.addRuleToLayer(lyr, feedback=feedback) self.createRuleVirtualField(lyr) @@ -146,39 +140,38 @@ def buildRuleDict(self, input_data): input_data = input_data[0] if isinstance(input_data, list) else input_data sortedRuleList = sorted( input_data.values(), - key=itemgetter('camada', 'atributo', 'ordem'), - reverse=False - ) - ruleDict = defaultdict( - lambda: defaultdict(list) + key=itemgetter("camada", "atributo", "ordem"), + reverse=False, ) + ruleDict = defaultdict(lambda: defaultdict(list)) for data in sortedRuleList: - ruleDict[data['camada']][data['atributo']].append(data) + ruleDict[data["camada"]][data["atributo"]].append(data) return ruleDict def addRuleToLayer(self, lyr, feedback=None): for field in lyr.fields(): if feedback is not None and feedback.isCanceled(): break - if lyr.name() not in self.ruleDict or \ - field.name() not in self.ruleDict[lyr.name()]: + if ( + lyr.name() not in self.ruleDict + or field.name() not in self.ruleDict[lyr.name()] + ): continue data = self.ruleDict[lyr.name()][field.name()] if not data: return fieldStyleList = [ - self.createConditionalStyle(i) \ - for i in data if i['tipo_regra'].lower() == 'atributo' + self.createConditionalStyle(i) + for i in data + if i["tipo_regra"].lower() == "atributo" ] rowStyleList = [ - self.createConditionalStyle(i) \ - for i in data if i['tipo_regra'].lower() != 'atributo' + self.createConditionalStyle(i) + for i in data + if i["tipo_regra"].lower() != "atributo" ] if fieldStyleList: - lyr.conditionalStyles().setFieldStyles( - field.name(), - fieldStyleList - ) + lyr.conditionalStyles().setFieldStyles(field.name(), fieldStyleList) elif rowStyleList: lyr.conditionalStyles().setRowStyes(rowStyleList) @@ -192,58 +185,50 @@ def createConditionalStyle(self, data): Returns a QgsConditionalStyle """ conditionalStyle = QgsConditionalStyle() - conditionalStyle.setName(data['descricao']) - conditionalStyle.setRule(data['regra']) + conditionalStyle.setName(data["descricao"]) + conditionalStyle.setRule(data["regra"]) conditionalStyle.setBackgroundColor( - QColor( - data['corRgb'][0], - data['corRgb'][1], - data['corRgb'][2] - ) + QColor(data["corRgb"][0], data["corRgb"][1], data["corRgb"][2]) ) return conditionalStyle - + def createRuleVirtualField(self, lyr): expressionString = """CASE\n""" for fieldName, dataList in self.ruleDict[lyr.name()].items(): for data in dataList: expressionString += """WHEN {condition} THEN '{result}'\n""".format( - condition=data['regra'], - result=data['descricao'] + condition=data["regra"], result=data["descricao"] ) expressionString += """ELSE ''\nEND""" lyr.addExpressionField( - expressionString, - QgsField( - 'attribute_error_description', - QVariant.String - ) - ) + expressionString, QgsField("attribute_error_description", QVariant.String) + ) def cleanRules(self, inputLayerList): for lyr in inputLayerList: for field in lyr.fields(): lyr.conditionalStyles().setFieldStyles(field.name(), []) - + def assignFormToLayer(self, lyr, layer_data): editFormConfig = lyr.editFormConfig() editFormConfig.setInitCodeSource(2) editFormConfig.setLayout(2) - file_name = self.customFormGenerator.create(lyr, layer_data) #TODO: Verificar esse layer_data no + file_name = self.customFormGenerator.create( + lyr, layer_data + ) # TODO: Verificar esse layer_data no editFormConfig.setUiForm(file_name) editFormConfig.setInitFunction("formOpen") code_init = self.create_custom_code_init(layer_data) editFormConfig.setInitCode(code_init) - + def create_custom_code_init(self, layer_data): rules_form = [] if self.rules: - rules_form = self.rules.get_rules_form(layer_data["layer_name"]) - if 'filter' in layer_data["layer_fields"]: + rules_form = self.rules.get_rules_form(layer_data["layer_name"]) + if "filter" in layer_data["layer_fields"]: filter_data = layer_data["layer_fields"]["filter"] code_init = self.customInitGenerator.getInitCodeWithFilter( - filter_data, - rules_form + filter_data, rules_form ) else: code_init = self.customInitGenerator.getInitCodeWithoutFilter(rules_form) @@ -257,21 +242,21 @@ def name(self): lowercase alphanumeric characters only and no spaces or other formatting characters. """ - return 'AssignCustomFormAndFormatRulesToLayersAlgorithm' + return "AssignCustomFormAndFormatRulesToLayersAlgorithm" def displayName(self): """ Returns the translated algorithm name, which should be used for any user-visible display of the algorithm name. """ - return self.tr('Assign Custom Form and Format Rules to Layers') + return self.tr("Assign Custom Form and Format Rules to Layers") def group(self): """ Returns the name of the group this algorithm belongs to. This string should be localised. """ - return self.tr('Layer Management Algorithms') + return self.tr("Layer Management Algorithms") def groupId(self): """ @@ -281,10 +266,12 @@ def groupId(self): contain lowercase alphanumeric characters only and no spaces or other formatting characters. """ - return 'DSGTools: Layer Management Algorithms' + return "DSGTools: Layer Management Algorithms" def tr(self, string): - return QCoreApplication.translate('AssignCustomFormAndFormatRulesToLayersAlgorithm', string) + return QCoreApplication.translate( + "AssignCustomFormAndFormatRulesToLayersAlgorithm", string + ) def createInstance(self): return AssignCustomFormAndFormatRulesToLayersAlgorithm() diff --git a/DsgTools/core/DSGToolsProcessingAlgs/Algs/LayerManagementAlgs/assignDefaultFieldValueToLayersAlgorithm.py b/DsgTools/core/DSGToolsProcessingAlgs/Algs/LayerManagementAlgs/assignDefaultFieldValueToLayersAlgorithm.py index f4ca0d107..34896b456 100644 --- a/DsgTools/core/DSGToolsProcessingAlgs/Algs/LayerManagementAlgs/assignDefaultFieldValueToLayersAlgorithm.py +++ b/DsgTools/core/DSGToolsProcessingAlgs/Algs/LayerManagementAlgs/assignDefaultFieldValueToLayersAlgorithm.py @@ -8,7 +8,7 @@ begin : 2020-08-11 git sha : $Format:%H$ copyright : (C) 2020 by Jossan - email : + email : ***************************************************************************/ /*************************************************************************** @@ -23,51 +23,54 @@ from PyQt5.QtCore import QCoreApplication from PyQt5.QtGui import QColor from qgis.PyQt.Qt import QVariant -from qgis.core import (QgsProcessing, - QgsFeatureSink, - QgsProcessingAlgorithm, - QgsProcessingParameterFeatureSource, - QgsProcessingParameterFeatureSink, - QgsFeature, - QgsDataSourceUri, - QgsProcessingOutputVectorLayer, - QgsProcessingParameterVectorLayer, - QgsWkbTypes, - QgsAction, - QgsProcessingParameterBoolean, - QgsProcessingParameterEnum, - QgsProcessingParameterNumber, - QgsProcessingParameterMultipleLayers, - QgsProcessingUtils, - QgsSpatialIndex, - QgsGeometry, - QgsProcessingParameterField, - QgsProcessingMultiStepFeedback, - QgsProcessingParameterFile, - QgsProcessingParameterExpression, - QgsProcessingException, - QgsProcessingParameterString, - QgsProcessingParameterDefinition, - QgsProcessingParameterType, - QgsProcessingParameterCrs, - QgsCoordinateTransform, - QgsProject, - QgsCoordinateReferenceSystem, - QgsField, - QgsFields, - QgsProcessingOutputMultipleLayers, - QgsProcessingParameterString, - QgsConditionalStyle) +from qgis.core import ( + QgsProcessing, + QgsFeatureSink, + QgsProcessingAlgorithm, + QgsProcessingParameterFeatureSource, + QgsProcessingParameterFeatureSink, + QgsFeature, + QgsDataSourceUri, + QgsProcessingOutputVectorLayer, + QgsProcessingParameterVectorLayer, + QgsWkbTypes, + QgsAction, + QgsProcessingParameterBoolean, + QgsProcessingParameterEnum, + QgsProcessingParameterNumber, + QgsProcessingParameterMultipleLayers, + QgsProcessingUtils, + QgsSpatialIndex, + QgsGeometry, + QgsProcessingParameterField, + QgsProcessingMultiStepFeedback, + QgsProcessingParameterFile, + QgsProcessingParameterExpression, + QgsProcessingException, + QgsProcessingParameterString, + QgsProcessingParameterDefinition, + QgsProcessingParameterType, + QgsProcessingParameterCrs, + QgsCoordinateTransform, + QgsProject, + QgsCoordinateReferenceSystem, + QgsField, + QgsFields, + QgsProcessingOutputMultipleLayers, + QgsProcessingParameterString, + QgsConditionalStyle, +) from operator import itemgetter from collections import defaultdict import json, os + class AssignDefaultFieldValueToLayersAlgorithm(QgsProcessingAlgorithm): - INPUT_LAYERS = 'INPUT_LAYERS' - FILE = 'FILE' - TEXT = 'TEXT' - OUTPUT = 'OUTPUT' + INPUT_LAYERS = "INPUT_LAYERS" + FILE = "FILE" + TEXT = "TEXT" + OUTPUT = "OUTPUT" def initAlgorithm(self, config): """ @@ -76,32 +79,29 @@ def initAlgorithm(self, config): self.addParameter( QgsProcessingParameterMultipleLayers( self.INPUT_LAYERS, - self.tr('Input Layers'), - QgsProcessing.TypeVectorAnyGeometry + self.tr("Input Layers"), + QgsProcessing.TypeVectorAnyGeometry, ) ) self.addParameter( QgsProcessingParameterFile( - self.FILE, - self.tr('Input json file'), - defaultValue = ".json" + self.FILE, self.tr("Input json file"), defaultValue=".json" ) ) self.addParameter( QgsProcessingParameterString( self.TEXT, - description = self.tr('Input json text'), - multiLine = True, - defaultValue = '[]' + description=self.tr("Input json text"), + multiLine=True, + defaultValue="[]", ) ) self.addOutput( QgsProcessingOutputMultipleLayers( - self.OUTPUT, - self.tr('Original layers id with default field value') + self.OUTPUT, self.tr("Original layers id with default field value") ) ) @@ -110,27 +110,19 @@ def processAlgorithm(self, parameters, context, feedback): Here is where the processing itself takes place. """ - inputLyrList = self.parameterAsLayerList( - parameters, - self.INPUT_LAYERS, - context - ) - inputJSONFile = self.parameterAsFile( - parameters, - self.FILE, - context - ) + inputLyrList = self.parameterAsLayerList(parameters, self.INPUT_LAYERS, context) + inputJSONFile = self.parameterAsFile(parameters, self.FILE, context) inputJSONData = json.loads( - self.parameterAsString( - parameters, - self.TEXT, - context - ) + self.parameterAsString(parameters, self.TEXT, context) ) if os.path.exists(inputJSONFile): - self.loadDefaultFieldValueFromJSONFile(inputJSONFile, inputLyrList, feedback) + self.loadDefaultFieldValueFromJSONFile( + inputJSONFile, inputLyrList, feedback + ) elif len(inputJSONData) > 0: - self.loadDefaultFieldValueFromJSONData(inputJSONData, inputLyrList, feedback) + self.loadDefaultFieldValueFromJSONData( + inputJSONData, inputLyrList, feedback + ) else: return {self.OUTPUT: []} return {self.OUTPUT: [i.id() for i in inputLyrList]} @@ -138,29 +130,29 @@ def processAlgorithm(self, parameters, context, feedback): def loadDefaultFieldValueFromJSONFile(self, inputJSONFile, inputLyrList, feedback): inputJSONData = json.load(inputJSONFile) self.loadDefaultFieldValueFromJSONData(inputJSONData, inputLyrList, feedback) - + def loadDefaultFieldValueFromJSONData(self, inputJSONData, inputLyrList, feedback): listSize = len(inputLyrList) - progressStep = 100/listSize if listSize else 0 - layerNames = [ item['camadaNome'] for item in inputJSONData] + progressStep = 100 / listSize if listSize else 0 + layerNames = [item["camadaNome"] for item in inputJSONData] for current, lyr in enumerate(inputLyrList): - + if feedback.isCanceled(): break - feedback.setProgress(current*progressStep) - - if not(lyr.dataProvider().uri().table() in layerNames): + feedback.setProgress(current * progressStep) + + if not (lyr.dataProvider().uri().table() in layerNames): continue - + layerIdx = layerNames.index(lyr.dataProvider().uri().table()) - for field in inputJSONData[layerIdx]['atributos']: - fieldIdx = lyr.fields().indexOf(field['nome']) - if fieldIdx < 0 or not field['valor']: + for field in inputJSONData[layerIdx]["atributos"]: + fieldIdx = lyr.fields().indexOf(field["nome"]) + if fieldIdx < 0 or not field["valor"]: continue configField = lyr.defaultValueDefinition(fieldIdx) - configField.setExpression("'{0}'".format(field['valor'])) + configField.setExpression("'{0}'".format(field["valor"])) lyr.setDefaultValueDefinition(fieldIdx, configField) def name(self): @@ -171,21 +163,21 @@ def name(self): lowercase alphanumeric characters only and no spaces or other formatting characters. """ - return 'assigndefaultfieldvaluetolayersalgorithm' + return "assigndefaultfieldvaluetolayersalgorithm" def displayName(self): """ Returns the translated algorithm name, which should be used for any user-visible display of the algorithm name. """ - return self.tr('Assign Default Field Value To Layers') + return self.tr("Assign Default Field Value To Layers") def group(self): """ Returns the name of the group this algorithm belongs to. This string should be localised. """ - return self.tr('Layer Management Algorithms') + return self.tr("Layer Management Algorithms") def groupId(self): """ @@ -195,10 +187,12 @@ def groupId(self): contain lowercase alphanumeric characters only and no spaces or other formatting characters. """ - return 'DSGTools: Layer Management Algorithms' + return "DSGTools: Layer Management Algorithms" def tr(self, string): - return QCoreApplication.translate('AssignDefaultFieldValueToLayersAlgorithm', string) + return QCoreApplication.translate( + "AssignDefaultFieldValueToLayersAlgorithm", string + ) def createInstance(self): - return AssignDefaultFieldValueToLayersAlgorithm() \ No newline at end of file + return AssignDefaultFieldValueToLayersAlgorithm() diff --git a/DsgTools/core/DSGToolsProcessingAlgs/Algs/LayerManagementAlgs/assignExpressionFieldToLayersAlgorithm.py b/DsgTools/core/DSGToolsProcessingAlgs/Algs/LayerManagementAlgs/assignExpressionFieldToLayersAlgorithm.py index 900763c9b..56a9c4734 100644 --- a/DsgTools/core/DSGToolsProcessingAlgs/Algs/LayerManagementAlgs/assignExpressionFieldToLayersAlgorithm.py +++ b/DsgTools/core/DSGToolsProcessingAlgs/Algs/LayerManagementAlgs/assignExpressionFieldToLayersAlgorithm.py @@ -8,7 +8,7 @@ begin : 2020-08-11 git sha : $Format:%H$ copyright : (C) 2020 by Jossan - email : + email : ***************************************************************************/ /*************************************************************************** @@ -23,51 +23,54 @@ from PyQt5.QtCore import QCoreApplication from PyQt5.QtGui import QColor from qgis.PyQt.Qt import QVariant -from qgis.core import (QgsProcessing, - QgsFeatureSink, - QgsProcessingAlgorithm, - QgsProcessingParameterFeatureSource, - QgsProcessingParameterFeatureSink, - QgsFeature, - QgsDataSourceUri, - QgsProcessingOutputVectorLayer, - QgsProcessingParameterVectorLayer, - QgsWkbTypes, - QgsAction, - QgsProcessingParameterBoolean, - QgsProcessingParameterEnum, - QgsProcessingParameterNumber, - QgsProcessingParameterMultipleLayers, - QgsProcessingUtils, - QgsSpatialIndex, - QgsGeometry, - QgsProcessingParameterField, - QgsProcessingMultiStepFeedback, - QgsProcessingParameterFile, - QgsProcessingParameterExpression, - QgsProcessingException, - QgsProcessingParameterString, - QgsProcessingParameterDefinition, - QgsProcessingParameterType, - QgsProcessingParameterCrs, - QgsCoordinateTransform, - QgsProject, - QgsCoordinateReferenceSystem, - QgsField, - QgsFields, - QgsProcessingOutputMultipleLayers, - QgsProcessingParameterString, - QgsConditionalStyle) +from qgis.core import ( + QgsProcessing, + QgsFeatureSink, + QgsProcessingAlgorithm, + QgsProcessingParameterFeatureSource, + QgsProcessingParameterFeatureSink, + QgsFeature, + QgsDataSourceUri, + QgsProcessingOutputVectorLayer, + QgsProcessingParameterVectorLayer, + QgsWkbTypes, + QgsAction, + QgsProcessingParameterBoolean, + QgsProcessingParameterEnum, + QgsProcessingParameterNumber, + QgsProcessingParameterMultipleLayers, + QgsProcessingUtils, + QgsSpatialIndex, + QgsGeometry, + QgsProcessingParameterField, + QgsProcessingMultiStepFeedback, + QgsProcessingParameterFile, + QgsProcessingParameterExpression, + QgsProcessingException, + QgsProcessingParameterString, + QgsProcessingParameterDefinition, + QgsProcessingParameterType, + QgsProcessingParameterCrs, + QgsCoordinateTransform, + QgsProject, + QgsCoordinateReferenceSystem, + QgsField, + QgsFields, + QgsProcessingOutputMultipleLayers, + QgsProcessingParameterString, + QgsConditionalStyle, +) from operator import itemgetter from collections import defaultdict import json, os + class AssignExpressionFieldToLayersAlgorithm(QgsProcessingAlgorithm): - INPUT_LAYERS = 'INPUT_LAYERS' - FILE = 'FILE' - TEXT = 'TEXT' - OUTPUT = 'OUTPUT' + INPUT_LAYERS = "INPUT_LAYERS" + FILE = "FILE" + TEXT = "TEXT" + OUTPUT = "OUTPUT" def initAlgorithm(self, config): """ @@ -76,32 +79,29 @@ def initAlgorithm(self, config): self.addParameter( QgsProcessingParameterMultipleLayers( self.INPUT_LAYERS, - self.tr('Input Layers'), - QgsProcessing.TypeVectorAnyGeometry + self.tr("Input Layers"), + QgsProcessing.TypeVectorAnyGeometry, ) ) self.addParameter( QgsProcessingParameterFile( - self.FILE, - self.tr('Input json file'), - defaultValue = ".json" + self.FILE, self.tr("Input json file"), defaultValue=".json" ) ) self.addParameter( QgsProcessingParameterString( self.TEXT, - description = self.tr('Input json text'), - multiLine = True, - defaultValue = '[]' + description=self.tr("Input json text"), + multiLine=True, + defaultValue="[]", ) ) self.addOutput( QgsProcessingOutputMultipleLayers( - self.OUTPUT, - self.tr('Original layers id with default field value') + self.OUTPUT, self.tr("Original layers id with default field value") ) ) @@ -110,22 +110,10 @@ def processAlgorithm(self, parameters, context, feedback): Here is where the processing itself takes place. """ - inputLyrList = self.parameterAsLayerList( - parameters, - self.INPUT_LAYERS, - context - ) - inputJSONFile = self.parameterAsFile( - parameters, - self.FILE, - context - ) + inputLyrList = self.parameterAsLayerList(parameters, self.INPUT_LAYERS, context) + inputJSONFile = self.parameterAsFile(parameters, self.FILE, context) inputJSONData = json.loads( - self.parameterAsString( - parameters, - self.TEXT, - context - ) + self.parameterAsString(parameters, self.TEXT, context) ) if os.path.exists(inputJSONFile): self.loadExpressionFieldFromJSONFile(inputJSONFile, inputLyrList, feedback) @@ -138,29 +126,28 @@ def processAlgorithm(self, parameters, context, feedback): def loadExpressionFieldFromJSONFile(self, inputJSONFile, inputLyrList, feedback): inputJSONData = json.load(inputJSONFile) self.loadExpressionFieldFromJSONData(inputJSONData, inputLyrList, feedback) - + def loadExpressionFieldFromJSONData(self, inputJSONData, inputLyrList, feedback): listSize = len(inputLyrList) - progressStep = 100/listSize if listSize else 0 - layerNames = [ item['camadaNome'] for item in inputJSONData] + progressStep = 100 / listSize if listSize else 0 + layerNames = [item["camadaNome"] for item in inputJSONData] for current, lyr in enumerate(inputLyrList): - + if feedback.isCanceled(): break - feedback.setProgress(current*progressStep) - - if not(lyr.dataProvider().uri().table() in layerNames): + feedback.setProgress(current * progressStep) + + if not (lyr.dataProvider().uri().table() in layerNames): continue - + layerIdx = layerNames.index(lyr.dataProvider().uri().table()) - for field in inputJSONData[layerIdx]['atributos']: - if lyr.fields().indexOf(field['nome']) < 0 or not field['valor']: + for field in inputJSONData[layerIdx]["atributos"]: + if lyr.fields().indexOf(field["nome"]) < 0 or not field["valor"]: continue lyr.addExpressionField( - field['valor'], - core.QgsField(field['nome'], QtCore.QVariant.String) + field["valor"], core.QgsField(field["nome"], QtCore.QVariant.String) ) def name(self): @@ -171,21 +158,21 @@ def name(self): lowercase alphanumeric characters only and no spaces or other formatting characters. """ - return 'assignexpressionfieldtolayersalgorithm' + return "assignexpressionfieldtolayersalgorithm" def displayName(self): """ Returns the translated algorithm name, which should be used for any user-visible display of the algorithm name. """ - return self.tr('Assign Expression Field To Layers') + return self.tr("Assign Expression Field To Layers") def group(self): """ Returns the name of the group this algorithm belongs to. This string should be localised. """ - return self.tr('Layer Management Algorithms') + return self.tr("Layer Management Algorithms") def groupId(self): """ @@ -195,10 +182,12 @@ def groupId(self): contain lowercase alphanumeric characters only and no spaces or other formatting characters. """ - return 'DSGTools: Layer Management Algorithms' + return "DSGTools: Layer Management Algorithms" def tr(self, string): - return QCoreApplication.translate('AssignExpressionFieldToLayersAlgorithm', string) + return QCoreApplication.translate( + "AssignExpressionFieldToLayersAlgorithm", string + ) def createInstance(self): - return AssignExpressionFieldToLayersAlgorithm() \ No newline at end of file + return AssignExpressionFieldToLayersAlgorithm() diff --git a/DsgTools/core/DSGToolsProcessingAlgs/Algs/LayerManagementAlgs/assignFilterToLayersAlgorithm.py b/DsgTools/core/DSGToolsProcessingAlgs/Algs/LayerManagementAlgs/assignFilterToLayersAlgorithm.py index 9c5d06415..78ee57436 100644 --- a/DsgTools/core/DSGToolsProcessingAlgs/Algs/LayerManagementAlgs/assignFilterToLayersAlgorithm.py +++ b/DsgTools/core/DSGToolsProcessingAlgs/Algs/LayerManagementAlgs/assignFilterToLayersAlgorithm.py @@ -21,46 +21,50 @@ ***************************************************************************/ """ from PyQt5.QtCore import QCoreApplication -from qgis.core import (QgsProcessing, - QgsFeatureSink, - QgsProcessingAlgorithm, - QgsProcessingParameterFeatureSource, - QgsProcessingParameterFeatureSink, - QgsFeature, - QgsDataSourceUri, - QgsProcessingOutputVectorLayer, - QgsProcessingParameterVectorLayer, - QgsWkbTypes, - QgsProcessingParameterBoolean, - QgsProcessingParameterEnum, - QgsProcessingParameterNumber, - QgsProcessingParameterMultipleLayers, - QgsProcessingUtils, - QgsSpatialIndex, - QgsGeometry, - QgsProcessingParameterField, - QgsProcessingMultiStepFeedback, - QgsProcessingParameterFile, - QgsProcessingParameterExpression, - QgsProcessingException, - QgsProcessingParameterString, - QgsProcessingParameterDefinition, - QgsProcessingParameterType, - QgsProcessingParameterCrs, - QgsCoordinateTransform, - QgsProject, - QgsCoordinateReferenceSystem, - QgsField, - QgsFields, - QgsProcessingOutputMultipleLayers, - QgsProcessingParameterString) +from qgis.core import ( + QgsProcessing, + QgsFeatureSink, + QgsProcessingAlgorithm, + QgsProcessingParameterFeatureSource, + QgsProcessingParameterFeatureSink, + QgsFeature, + QgsDataSourceUri, + QgsProcessingOutputVectorLayer, + QgsProcessingParameterVectorLayer, + QgsWkbTypes, + QgsProcessingParameterBoolean, + QgsProcessingParameterEnum, + QgsProcessingParameterNumber, + QgsProcessingParameterMultipleLayers, + QgsProcessingUtils, + QgsSpatialIndex, + QgsGeometry, + QgsProcessingParameterField, + QgsProcessingMultiStepFeedback, + QgsProcessingParameterFile, + QgsProcessingParameterExpression, + QgsProcessingException, + QgsProcessingParameterString, + QgsProcessingParameterDefinition, + QgsProcessingParameterType, + QgsProcessingParameterCrs, + QgsCoordinateTransform, + QgsProject, + QgsCoordinateReferenceSystem, + QgsField, + QgsFields, + QgsProcessingOutputMultipleLayers, + QgsProcessingParameterString, +) + class AssignFilterToLayersAlgorithm(QgsProcessingAlgorithm): - INPUT_LAYERS = 'INPUT_LAYERS' - FILTER = 'FILTER' - BEHAVIOR = 'BEHAVIOR' - OUTPUT = 'OUTPUT' + INPUT_LAYERS = "INPUT_LAYERS" + FILTER = "FILTER" + BEHAVIOR = "BEHAVIOR" + OUTPUT = "OUTPUT" AndMode, OrMode, ReplaceMode = list(range(3)) + def initAlgorithm(self, config): """ Parameter setting. @@ -68,36 +72,28 @@ def initAlgorithm(self, config): self.addParameter( QgsProcessingParameterMultipleLayers( self.INPUT_LAYERS, - self.tr('Input Layers'), - QgsProcessing.TypeVectorAnyGeometry + self.tr("Input Layers"), + QgsProcessing.TypeVectorAnyGeometry, ) ) - self.addParameter( - QgsProcessingParameterString( - self.FILTER, - self.tr('Filter') - ) - ) + self.addParameter(QgsProcessingParameterString(self.FILTER, self.tr("Filter"))) - self.modes = [self.tr('Append to existing filter with AND clause'), - self.tr('Append to existing filter with OR clause'), - self.tr('Replace filter') - ] + self.modes = [ + self.tr("Append to existing filter with AND clause"), + self.tr("Append to existing filter with OR clause"), + self.tr("Replace filter"), + ] self.addParameter( QgsProcessingParameterEnum( - self.BEHAVIOR, - self.tr('Behavior'), - options=self.modes, - defaultValue=0 + self.BEHAVIOR, self.tr("Behavior"), options=self.modes, defaultValue=0 ) ) self.addOutput( QgsProcessingOutputMultipleLayers( - self.OUTPUT, - self.tr('Original layers with assigned styles') + self.OUTPUT, self.tr("Original layers with assigned styles") ) ) @@ -105,23 +101,11 @@ def processAlgorithm(self, parameters, context, feedback): """ Here is where the processing itself takes place. """ - inputLyrList = self.parameterAsLayerList( - parameters, - self.INPUT_LAYERS, - context - ) - inputFilterExpression = self.parameterAsString( - parameters, - self.FILTER, - context - ) - behavior = self.parameterAsEnum( - parameters, - self.BEHAVIOR, - context - ) + inputLyrList = self.parameterAsLayerList(parameters, self.INPUT_LAYERS, context) + inputFilterExpression = self.parameterAsString(parameters, self.FILTER, context) + behavior = self.parameterAsEnum(parameters, self.BEHAVIOR, context) listSize = len(inputLyrList) - stepSize = 100/listSize if listSize else 0 + stepSize = 100 / listSize if listSize else 0 for current, lyr in enumerate(inputLyrList): if feedback.isCanceled(): break @@ -136,12 +120,16 @@ def adaptFilter(self, lyr, inputFilter, behavior): Adapts filter according to the selected mode """ originalFilter = lyr.subsetString() - if behavior == AssignFilterToLayersAlgorithm.ReplaceMode or originalFilter == '': + if ( + behavior == AssignFilterToLayersAlgorithm.ReplaceMode + or originalFilter == "" + ): return inputFilter - clause = ' AND ' if behavior == AssignFilterToLayersAlgorithm.AndMode else ' OR ' + clause = ( + " AND " if behavior == AssignFilterToLayersAlgorithm.AndMode else " OR " + ) return clause.join([originalFilter, inputFilter]) - def name(self): """ Returns the algorithm name, used for identifying the algorithm. This @@ -150,21 +138,21 @@ def name(self): lowercase alphanumeric characters only and no spaces or other formatting characters. """ - return 'assignfiltertolayers' + return "assignfiltertolayers" def displayName(self): """ Returns the translated algorithm name, which should be used for any user-visible display of the algorithm name. """ - return self.tr('Assign Filter to Layers') + return self.tr("Assign Filter to Layers") def group(self): """ Returns the name of the group this algorithm belongs to. This string should be localised. """ - return self.tr('Layer Management Algorithms') + return self.tr("Layer Management Algorithms") def groupId(self): """ @@ -174,10 +162,10 @@ def groupId(self): contain lowercase alphanumeric characters only and no spaces or other formatting characters. """ - return 'DSGTools: Layer Management Algorithms' + return "DSGTools: Layer Management Algorithms" def tr(self, string): - return QCoreApplication.translate('AssignFilterToLayersAlgorithm', string) + return QCoreApplication.translate("AssignFilterToLayersAlgorithm", string) def createInstance(self): - return AssignFilterToLayersAlgorithm() \ No newline at end of file + return AssignFilterToLayersAlgorithm() diff --git a/DsgTools/core/DSGToolsProcessingAlgs/Algs/LayerManagementAlgs/assignFormatRulesToLayersAlgorithm.py b/DsgTools/core/DSGToolsProcessingAlgs/Algs/LayerManagementAlgs/assignFormatRulesToLayersAlgorithm.py index dd769dedf..793cec4bf 100644 --- a/DsgTools/core/DSGToolsProcessingAlgs/Algs/LayerManagementAlgs/assignFormatRulesToLayersAlgorithm.py +++ b/DsgTools/core/DSGToolsProcessingAlgs/Algs/LayerManagementAlgs/assignFormatRulesToLayersAlgorithm.py @@ -24,81 +24,82 @@ from PyQt5.QtCore import QCoreApplication from PyQt5.QtGui import QColor from qgis.PyQt.Qt import QVariant -from qgis.core import (QgsProcessing, - QgsFeatureSink, - QgsProcessingAlgorithm, - QgsProcessingParameterFeatureSource, - QgsProcessingParameterFeatureSink, - QgsFeature, - QgsDataSourceUri, - QgsProcessingOutputVectorLayer, - QgsProcessingParameterVectorLayer, - QgsWkbTypes, - QgsProcessingParameterBoolean, - QgsProcessingParameterEnum, - QgsProcessingParameterNumber, - QgsProcessingParameterMultipleLayers, - QgsProcessingUtils, - QgsSpatialIndex, - QgsGeometry, - QgsProcessingParameterField, - QgsProcessingMultiStepFeedback, - QgsProcessingParameterFile, - QgsProcessingParameterExpression, - QgsProcessingException, - QgsProcessingParameterString, - QgsProcessingParameterDefinition, - QgsProcessingParameterType, - QgsProcessingParameterCrs, - QgsCoordinateTransform, - QgsProject, - QgsCoordinateReferenceSystem, - QgsField, - QgsFields, - QgsProcessingOutputMultipleLayers, - QgsProcessingParameterString, - QgsConditionalStyle, - QgsExpression) +from qgis.core import ( + QgsProcessing, + QgsFeatureSink, + QgsProcessingAlgorithm, + QgsProcessingParameterFeatureSource, + QgsProcessingParameterFeatureSink, + QgsFeature, + QgsDataSourceUri, + QgsProcessingOutputVectorLayer, + QgsProcessingParameterVectorLayer, + QgsWkbTypes, + QgsProcessingParameterBoolean, + QgsProcessingParameterEnum, + QgsProcessingParameterNumber, + QgsProcessingParameterMultipleLayers, + QgsProcessingUtils, + QgsSpatialIndex, + QgsGeometry, + QgsProcessingParameterField, + QgsProcessingMultiStepFeedback, + QgsProcessingParameterFile, + QgsProcessingParameterExpression, + QgsProcessingException, + QgsProcessingParameterString, + QgsProcessingParameterDefinition, + QgsProcessingParameterType, + QgsProcessingParameterCrs, + QgsCoordinateTransform, + QgsProject, + QgsCoordinateReferenceSystem, + QgsField, + QgsFields, + QgsProcessingOutputMultipleLayers, + QgsProcessingParameterString, + QgsConditionalStyle, + QgsExpression, +) from operator import itemgetter from collections import defaultdict import fnmatch + class AssignFormatRulesToLayersAlgorithm(QgsProcessingAlgorithm): - INPUT_LAYERS = 'INPUT_LAYERS' - FILE = 'FILE' - TEXT = 'TEXT' - CLEAN_BEFORE_ASSIGN = 'CLEAN_BEFORE_ASSIGN' + INPUT_LAYERS = "INPUT_LAYERS" + FILE = "FILE" + TEXT = "TEXT" + CLEAN_BEFORE_ASSIGN = "CLEAN_BEFORE_ASSIGN" def initAlgorithm(self, config=None): self.addParameter( QgsProcessingParameterMultipleLayers( - self.INPUT_LAYERS, - self.tr("Input layers") + self.INPUT_LAYERS, self.tr("Input layers") ) ) self.addParameter( QgsProcessingParameterString( self.TEXT, - description = self.tr('Input json text'), - multiLine = True, - defaultValue = '{}', + description=self.tr("Input json text"), + multiLine=True, + defaultValue="{}", optional=True, ) ) self.addParameter( QgsProcessingParameterFile( self.FILE, - description = self.tr('JSON File with rules'), + description=self.tr("JSON File with rules"), behavior=QgsProcessingParameterFile.File, - fileFilter='JSON (*.json)', + fileFilter="JSON (*.json)", optional=True, ) ) self.addParameter( QgsProcessingParameterBoolean( - self.CLEAN_BEFORE_ASSIGN, - self.tr('Clean before assign format rules') + self.CLEAN_BEFORE_ASSIGN, self.tr("Clean before assign format rules") ) ) @@ -106,28 +107,25 @@ def processAlgorithm(self, parameters, context, feedback): """ Here is where the processing itself takes place. """ - inputLyrList = self.parameterAsLayerList( - parameters, - self.INPUT_LAYERS, - context - ) - inputLyrList = [lyr for lyr in inputLyrList if lyr.dataProvider().name() == 'postgres'] + inputLyrList = self.parameterAsLayerList(parameters, self.INPUT_LAYERS, context) + inputLyrList = [ + lyr for lyr in inputLyrList if lyr.dataProvider().name() == "postgres" + ] if not inputLyrList: return {} - + inputData = self.loadRulesFromFile(parameters, context) cleanBefore = self.parameterAsBool( - parameters, - self.CLEAN_BEFORE_ASSIGN, - context - ) + parameters, self.CLEAN_BEFORE_ASSIGN, context + ) if cleanBefore: self.cleanRules(inputLyrList) self.cleanExpressionField(inputLyrList) listSize = len(inputLyrList) - stepSize = 100/listSize if listSize else 0 + stepSize = 100 / listSize if listSize else 0 inputLyrNamesWithSchemaList = [ - f"{lyr.dataProvider().uri().schema()}.{lyr.dataProvider().uri().table()}" for lyr in inputLyrList + f"{lyr.dataProvider().uri().schema()}.{lyr.dataProvider().uri().table()}" + for lyr in inputLyrList ] self.ruleDict = self.buildRuleDict(inputData, inputLyrNamesWithSchemaList) @@ -139,15 +137,8 @@ def processAlgorithm(self, parameters, context, feedback): feedback.setProgress(current * stepSize) return {} - def loadRulesFromFile(self, parameters, context): - inputText = json.loads( - self.parameterAsString( - parameters, - self.TEXT, - context - ) - ) + inputText = json.loads(self.parameterAsString(parameters, self.TEXT, context)) if inputText != {}: return inputText inputFile = self.parameterAsFile( @@ -155,8 +146,8 @@ def loadRulesFromFile(self, parameters, context): self.FILE, context, ) - - with open(inputFile, 'r') as f: + + with open(inputFile, "r") as f: rulesData = json.load(f) return rulesData @@ -165,8 +156,9 @@ def buildRuleDict(self, inputData, inputLyrNamesWithSchemaList): styleDict = { style["tipo_estilo"]: { "corRgb": list(map(int, style["cor_rgb"].split(","))), - "rank": idx - } for idx, style in enumerate(inputData["grupo_estilo"]) + "rank": idx, + } + for idx, style in enumerate(inputData["grupo_estilo"]) } for rule in inputData["regras"]: lyrSet = self.getLayerNames(rule["camadas"], inputLyrNamesWithSchemaList) @@ -177,36 +169,33 @@ def buildRuleDict(self, inputData, inputLyrNamesWithSchemaList): for lyr in ruleDict: for attribute in ruleDict[lyr]: ruleDict[lyr][attribute] = sorted( - ruleDict[lyr][attribute], - key=itemgetter('rank'), - reverse=False - ) #reverses the list so that it is already in the right order + ruleDict[lyr][attribute], key=itemgetter("rank"), reverse=False + ) # reverses the list so that it is already in the right order return ruleDict - + def getLayerNames(self, filterList, nameList): outputSet = set() - wildCardFilterList = [filterItem for filterItem in filterList if "*" in filterItem] + wildCardFilterList = [ + filterItem for filterItem in filterList if "*" in filterItem + ] for wildCardFilter in wildCardFilterList: outputSet = outputSet.union(set(fnmatch.filter(nameList, wildCardFilter))) - outputSet = outputSet.union(set(name for name in nameList if name in filterList)) + outputSet = outputSet.union( + set(name for name in nameList if name in filterList) + ) return outputSet - def addRuleToLayer(self, lyr, feedback=None): key = f"{lyr.dataProvider().uri().schema()}.{lyr.dataProvider().uri().table()}" for field in lyr.fields(): if feedback is not None and feedback.isCanceled(): break - if key not in self.ruleDict or \ - field.name() not in self.ruleDict[key]: + if key not in self.ruleDict or field.name() not in self.ruleDict[key]: continue fieldStyleList = [ self.createConditionalStyle(i) for i in self.ruleDict[key][field.name()] ] - lyr.conditionalStyles().setFieldStyles( - field.name(), - fieldStyleList - ) + lyr.conditionalStyles().setFieldStyles(field.name(), fieldStyleList) def createConditionalStyle(self, data): """ @@ -218,19 +207,17 @@ def createConditionalStyle(self, data): Returns a QgsConditionalStyle """ conditionalStyle = QgsConditionalStyle() - conditionalStyle.setName(data['descricao']) - conditionalStyle.setRule(data['regra']) + conditionalStyle.setName(data["descricao"]) + conditionalStyle.setRule(data["regra"]) conditionalStyle.setBackgroundColor( - QColor( - data['corRgb'][0], - data['corRgb'][1], - data['corRgb'][2] - ) + QColor(data["corRgb"][0], data["corRgb"][1], data["corRgb"][2]) ) if not conditionalStyle.isValid(): - raise Exception(f"Invalid conditional style: \n{data['descricao']}\n{data['regra']}") + raise Exception( + f"Invalid conditional style: \n{data['descricao']}\n{data['regra']}" + ) return conditionalStyle - + def createRuleVirtualField(self, lyr): expressionString = """CASE\n""" key = f"{lyr.dataProvider().uri().schema()}.{lyr.dataProvider().uri().table()}" @@ -241,36 +228,33 @@ def createRuleVirtualField(self, lyr): continue ruleList += dataList sortedRuleList = sorted( - ruleList, - key=itemgetter('rank', 'atributo'), - reverse=False + ruleList, key=itemgetter("rank", "atributo"), reverse=False ) for data in sortedRuleList: - fieldName = data['atributo'] + fieldName = data["atributo"] expressionString += """WHEN {condition} THEN '{result}'\n""".format( - condition=data['regra'], - result=data['descricao'] + condition=data["regra"], result=data["descricao"] ) if not self.expressionHasParseError(expressionString): - raise Exception(f"Error while trying to apply rule:\n {data}\ncurrent field: {fieldName}\ncurrent layer name: {key}") + raise Exception( + f"Error while trying to apply rule:\n {data}\ncurrent field: {fieldName}\ncurrent layer name: {key}" + ) expressionString += """ELSE ''\nEND""" - if expressionString == "CASE\nELSE ''\nEND": ## did not apply any rule + if expressionString == "CASE\nELSE ''\nEND": ## did not apply any rule return expression = QgsExpression(expressionString) if expression.hasParserError(): - raise Exception( - f"Invalid expression: \n{expressionString}" - ) + raise Exception(f"Invalid expression: \n{expressionString}") lyr.addExpressionField( - expressionString, - QgsField( - 'attribute_error_description', - QVariant.String - ) + expressionString, QgsField("attribute_error_description", QVariant.String) ) - + def expressionHasParseError(self, expressionString): - expr = expressionString if """ELSE ''\nEND""" in expressionString else expressionString + """ELSE ''\nEND""" + expr = ( + expressionString + if """ELSE ''\nEND""" in expressionString + else expressionString + """ELSE ''\nEND""" + ) expression = QgsExpression(expr) return expression.isValid() @@ -278,12 +262,12 @@ def cleanRules(self, inputLayerList): for lyr in inputLayerList: for field in lyr.fields(): lyr.conditionalStyles().setFieldStyles(field.name(), []) - + def cleanExpressionField(self, inputLayerList): for lyr in inputLayerList: errorDescriptionIndex = -1 for idx, field in enumerate(lyr.fields()): - if field.name() == 'attribute_error_description': + if field.name() == "attribute_error_description": errorDescriptionIndex = idx break if errorDescriptionIndex != -1: @@ -297,21 +281,21 @@ def name(self): lowercase alphanumeric characters only and no spaces or other formatting characters. """ - return 'assignformatrulestolayersalgorithm' + return "assignformatrulestolayersalgorithm" def displayName(self): """ Returns the translated algorithm name, which should be used for any user-visible display of the algorithm name. """ - return self.tr('Assign Format Rules to Layers') + return self.tr("Assign Format Rules to Layers") def group(self): """ Returns the name of the group this algorithm belongs to. This string should be localised. """ - return self.tr('Layer Management Algorithms') + return self.tr("Layer Management Algorithms") def groupId(self): """ @@ -321,10 +305,10 @@ def groupId(self): contain lowercase alphanumeric characters only and no spaces or other formatting characters. """ - return 'DSGTools: Layer Management Algorithms' + return "DSGTools: Layer Management Algorithms" def tr(self, string): - return QCoreApplication.translate('AssignFormatRulesToLayersAlgorithm', string) + return QCoreApplication.translate("AssignFormatRulesToLayersAlgorithm", string) def createInstance(self): return AssignFormatRulesToLayersAlgorithm() diff --git a/DsgTools/core/DSGToolsProcessingAlgs/Algs/LayerManagementAlgs/assignMeasureColumnToLayersAlgorithm.py b/DsgTools/core/DSGToolsProcessingAlgs/Algs/LayerManagementAlgs/assignMeasureColumnToLayersAlgorithm.py index 5ac90979b..3cbfa55e1 100644 --- a/DsgTools/core/DSGToolsProcessingAlgs/Algs/LayerManagementAlgs/assignMeasureColumnToLayersAlgorithm.py +++ b/DsgTools/core/DSGToolsProcessingAlgs/Algs/LayerManagementAlgs/assignMeasureColumnToLayersAlgorithm.py @@ -22,43 +22,47 @@ """ from PyQt5.QtCore import QCoreApplication from qgis.PyQt.Qt import QVariant -from qgis.core import (QgsProcessing, - QgsFeatureSink, - QgsProcessingAlgorithm, - QgsProcessingParameterFeatureSource, - QgsProcessingParameterFeatureSink, - QgsFeature, - QgsDataSourceUri, - QgsProcessingOutputVectorLayer, - QgsProcessingParameterVectorLayer, - QgsWkbTypes, - QgsProcessingParameterBoolean, - QgsProcessingParameterEnum, - QgsProcessingParameterNumber, - QgsProcessingParameterMultipleLayers, - QgsProcessingUtils, - QgsSpatialIndex, - QgsGeometry, - QgsProcessingParameterField, - QgsProcessingMultiStepFeedback, - QgsProcessingParameterFile, - QgsProcessingParameterExpression, - QgsProcessingException, - QgsProcessingParameterString, - QgsProcessingParameterDefinition, - QgsProcessingParameterType, - QgsProcessingParameterCrs, - QgsCoordinateTransform, - QgsProject, - QgsCoordinateReferenceSystem, - QgsField, - QgsFields, - QgsProcessingOutputMultipleLayers, - QgsProcessingParameterString) +from qgis.core import ( + QgsProcessing, + QgsFeatureSink, + QgsProcessingAlgorithm, + QgsProcessingParameterFeatureSource, + QgsProcessingParameterFeatureSink, + QgsFeature, + QgsDataSourceUri, + QgsProcessingOutputVectorLayer, + QgsProcessingParameterVectorLayer, + QgsWkbTypes, + QgsProcessingParameterBoolean, + QgsProcessingParameterEnum, + QgsProcessingParameterNumber, + QgsProcessingParameterMultipleLayers, + QgsProcessingUtils, + QgsSpatialIndex, + QgsGeometry, + QgsProcessingParameterField, + QgsProcessingMultiStepFeedback, + QgsProcessingParameterFile, + QgsProcessingParameterExpression, + QgsProcessingException, + QgsProcessingParameterString, + QgsProcessingParameterDefinition, + QgsProcessingParameterType, + QgsProcessingParameterCrs, + QgsCoordinateTransform, + QgsProject, + QgsCoordinateReferenceSystem, + QgsField, + QgsFields, + QgsProcessingOutputMultipleLayers, + QgsProcessingParameterString, +) + class AssignMeasureColumnToLayersAlgorithm(QgsProcessingAlgorithm): - INPUT_LAYERS = 'INPUT_LAYERS' - OUTPUT = 'OUTPUT' + INPUT_LAYERS = "INPUT_LAYERS" + OUTPUT = "OUTPUT" + def initAlgorithm(self, config): """ Parameter setting. @@ -66,15 +70,14 @@ def initAlgorithm(self, config): self.addParameter( QgsProcessingParameterMultipleLayers( self.INPUT_LAYERS, - self.tr('Input Layers'), - QgsProcessing.TypeVectorAnyGeometry + self.tr("Input Layers"), + QgsProcessing.TypeVectorAnyGeometry, ) ) self.addOutput( QgsProcessingOutputMultipleLayers( - self.OUTPUT, - self.tr('Original layers with measure column') + self.OUTPUT, self.tr("Original layers with measure column") ) ) @@ -82,13 +85,9 @@ def processAlgorithm(self, parameters, context, feedback): """ Here is where the processing itself takes place. """ - inputLyrList = self.parameterAsLayerList( - parameters, - self.INPUT_LAYERS, - context - ) + inputLyrList = self.parameterAsLayerList(parameters, self.INPUT_LAYERS, context) listSize = len(inputLyrList) - stepSize = 100/listSize if listSize else 0 + stepSize = 100 / listSize if listSize else 0 notSuccessfulList = [] for current, lyr in enumerate(inputLyrList): if feedback.isCanceled(): @@ -100,21 +99,9 @@ def processAlgorithm(self, parameters, context, feedback): def createMeasureColumn(self, layer): if layer.geometryType() == QgsWkbTypes.PolygonGeometry: - layer.addExpressionField( - '$area', - QgsField( - 'area_otf', - QVariant.Double - ) - ) + layer.addExpressionField("$area", QgsField("area_otf", QVariant.Double)) elif layer.geometryType() == QgsWkbTypes.LineGeometry: - layer.addExpressionField( - '$length', - QgsField( - 'length_otf', - QVariant.Double - ) - ) + layer.addExpressionField("$length", QgsField("length_otf", QVariant.Double)) return layer def name(self): @@ -125,21 +112,21 @@ def name(self): lowercase alphanumeric characters only and no spaces or other formatting characters. """ - return 'assignmeasurecolumntolayers' + return "assignmeasurecolumntolayers" def displayName(self): """ Returns the translated algorithm name, which should be used for any user-visible display of the algorithm name. """ - return self.tr('Assign Measure Column to Layers') + return self.tr("Assign Measure Column to Layers") def group(self): """ Returns the name of the group this algorithm belongs to. This string should be localised. """ - return self.tr('Layer Management Algorithms') + return self.tr("Layer Management Algorithms") def groupId(self): """ @@ -149,10 +136,12 @@ def groupId(self): contain lowercase alphanumeric characters only and no spaces or other formatting characters. """ - return 'DSGTools: Layer Management Algorithms' + return "DSGTools: Layer Management Algorithms" def tr(self, string): - return QCoreApplication.translate('AssignMeasureColumnToLayersAlgorithm', string) + return QCoreApplication.translate( + "AssignMeasureColumnToLayersAlgorithm", string + ) def createInstance(self): - return AssignMeasureColumnToLayersAlgorithm() \ No newline at end of file + return AssignMeasureColumnToLayersAlgorithm() diff --git a/DsgTools/core/DSGToolsProcessingAlgs/Algs/LayerManagementAlgs/assignValueMapToLayersAlgorithm.py b/DsgTools/core/DSGToolsProcessingAlgs/Algs/LayerManagementAlgs/assignValueMapToLayersAlgorithm.py index be00014ca..e15158318 100644 --- a/DsgTools/core/DSGToolsProcessingAlgs/Algs/LayerManagementAlgs/assignValueMapToLayersAlgorithm.py +++ b/DsgTools/core/DSGToolsProcessingAlgs/Algs/LayerManagementAlgs/assignValueMapToLayersAlgorithm.py @@ -22,48 +22,50 @@ """ import json -from qgis.core import (QgsEditorWidgetSetup, QgsProcessing, - QgsProcessingAlgorithm, - QgsProcessingOutputMultipleLayers, - QgsProcessingParameterFile, - QgsProcessingParameterMultipleLayers, - QgsProcessingParameterString) +from qgis.core import ( + QgsEditorWidgetSetup, + QgsProcessing, + QgsProcessingAlgorithm, + QgsProcessingOutputMultipleLayers, + QgsProcessingParameterFile, + QgsProcessingParameterMultipleLayers, + QgsProcessingParameterString, +) from qgis.PyQt.QtCore import QCoreApplication class AssignValueMapToLayersAlgorithm(QgsProcessingAlgorithm): - INPUT_LAYERS = 'INPUT_LAYERS' - VALUE_MAP_FILE = 'VALUE_MAP_FILE' - VALUE_MAP = 'VALUE_MAP' - OUTPUT = 'OUTPUT' + INPUT_LAYERS = "INPUT_LAYERS" + VALUE_MAP_FILE = "VALUE_MAP_FILE" + VALUE_MAP = "VALUE_MAP" + OUTPUT = "OUTPUT" def initAlgorithm(self, config=None): self.addParameter( QgsProcessingParameterMultipleLayers( self.INPUT_LAYERS, - self.tr('Input Layers'), - QgsProcessing.TypeVectorAnyGeometry + self.tr("Input Layers"), + QgsProcessing.TypeVectorAnyGeometry, ) ) self.addParameter( QgsProcessingParameterFile( self.VALUE_MAP_FILE, - description=self.tr('Json file with value maps'), - defaultValue='.json' + description=self.tr("Json file with value maps"), + defaultValue=".json", ) ) self.addParameter( QgsProcessingParameterString( self.VALUE_MAP, - description=self.tr('Json data'), + description=self.tr("Json data"), multiLine=True, - defaultValue='{}' + defaultValue="{}", ) ) self.addOutput( QgsProcessingOutputMultipleLayers( - self.OUTPUT, - self.tr('Original layers with values mapped') + self.OUTPUT, self.tr("Original layers with values mapped") ) ) @@ -71,28 +73,25 @@ def processAlgorithm(self, parameters, context, feedback): """ Here is where the processing itself takes place. """ - inputLyrList = self.parameterAsLayerList( - parameters, - self.INPUT_LAYERS, - context - ) - #self.domainDict = self.loadMapFromParameters(parameters) + inputLyrList = self.parameterAsLayerList(parameters, self.INPUT_LAYERS, context) + # self.domainDict = self.loadMapFromParameters(parameters) layerValueMaps = self.loadMapFromParameters(parameters) listSize = len(inputLyrList) - stepSize = 100/listSize if listSize else 0 + stepSize = 100 / listSize if listSize else 0 for current, lyr in enumerate(inputLyrList): if feedback.isCanceled(): break - if ( - lyr.dataProvider().uri().table() in layerValueMaps - and - len(layerValueMaps[lyr.dataProvider().uri().table()]) > 0 - ): - self.loadLayerValueMap(lyr, layerValueMaps[lyr.dataProvider().uri().table()]) + if ( + lyr.dataProvider().uri().table() in layerValueMaps + and len(layerValueMaps[lyr.dataProvider().uri().table()]) > 0 + ): + self.loadLayerValueMap( + lyr, layerValueMaps[lyr.dataProvider().uri().table()] + ) feedback.setProgress(current * stepSize) - return {self.OUTPUT: [ lyr.id() for lyr in inputLyrList]} + return {self.OUTPUT: [lyr.id() for lyr in inputLyrList]} def loadMapFromParameters(self, parameters): """ @@ -101,26 +100,26 @@ def loadMapFromParameters(self, parameters): """ rules_path = parameters[self.VALUE_MAP_FILE] rules_text = parameters[self.VALUE_MAP] - if rules_path and rules_path != '.json': - with open(rules_path, 'r') as f: + if rules_path and rules_path != ".json": + with open(rules_path, "r") as f: rules_input = json.load(f) - if rules_text and rules_text != '{}': + if rules_text and rules_text != "{}": rules_input = json.loads(rules_text) return rules_input def loadLayerValueMap(self, lyr, valueMap): pkIdxList = lyr.primaryKeyAttributes() - attributes = [ item['attribute'] for item in valueMap] + attributes = [item["attribute"] for item in valueMap] for i, field in enumerate(lyr.fields()): attrName = field.name() - if attrName == 'id' or 'id_' in attrName or i in pkIdxList: + if attrName == "id" or "id_" in attrName or i in pkIdxList: formConfig = lyr.editFormConfig() formConfig.setReadOnly(i, True) lyr.setEditFormConfig(formConfig) elif attrName in attributes: widgetSetup = QgsEditorWidgetSetup( - 'ValueMap', - {'map': valueMap[attributes.index(attrName)]['valueMap']} + "ValueMap", + {"map": valueMap[attributes.index(attrName)]["valueMap"]}, ) lyr.setEditorWidgetSetup(i, widgetSetup) return lyr @@ -133,21 +132,21 @@ def name(self): lowercase alphanumeric characters only and no spaces or other formatting characters. """ - return 'assignvaluemaptolayersalgorithm' + return "assignvaluemaptolayersalgorithm" def displayName(self): """ Returns the translated algorithm name, which should be used for any user-visible display of the algorithm name. """ - return self.tr('Assign Value Map to Layers') + return self.tr("Assign Value Map to Layers") def group(self): """ Returns the name of the group this algorithm belongs to. This string should be localised. """ - return self.tr('Layer Management Algorithms') + return self.tr("Layer Management Algorithms") def groupId(self): """ @@ -157,13 +156,10 @@ def groupId(self): contain lowercase alphanumeric characters only and no spaces or other formatting characters. """ - return 'DSGTools: Layer Management Algorithms' + return "DSGTools: Layer Management Algorithms" def tr(self, string): - return QCoreApplication.translate( - 'AssignValueMapToLayersAlgorithm', - string - ) + return QCoreApplication.translate("AssignValueMapToLayersAlgorithm", string) def createInstance(self): return AssignValueMapToLayersAlgorithm() diff --git a/DsgTools/core/DSGToolsProcessingAlgs/Algs/LayerManagementAlgs/buildJoinsOnLayersAlgorithm.py b/DsgTools/core/DSGToolsProcessingAlgs/Algs/LayerManagementAlgs/buildJoinsOnLayersAlgorithm.py index 14040d508..bb2483ca9 100644 --- a/DsgTools/core/DSGToolsProcessingAlgs/Algs/LayerManagementAlgs/buildJoinsOnLayersAlgorithm.py +++ b/DsgTools/core/DSGToolsProcessingAlgs/Algs/LayerManagementAlgs/buildJoinsOnLayersAlgorithm.py @@ -25,16 +25,23 @@ from PyQt5.QtCore import QCoreApplication -from qgis.core import (QgsDataSourceUri, QgsExpression, QgsExpressionContext, - QgsExpressionContextUtils, QgsProcessing, - QgsProcessingAlgorithm, - QgsProcessingOutputMultipleLayers, - QgsProcessingParameterBoolean, - QgsProcessingParameterExpression, - QgsProcessingParameterMultipleLayers, - QgsProcessingParameterNumber, - QgsProcessingParameterString, QgsProject, QgsRelation, - QgsVectorLayerJoinInfo) +from qgis.core import ( + QgsDataSourceUri, + QgsExpression, + QgsExpressionContext, + QgsExpressionContextUtils, + QgsProcessing, + QgsProcessingAlgorithm, + QgsProcessingOutputMultipleLayers, + QgsProcessingParameterBoolean, + QgsProcessingParameterExpression, + QgsProcessingParameterMultipleLayers, + QgsProcessingParameterNumber, + QgsProcessingParameterString, + QgsProject, + QgsRelation, + QgsVectorLayerJoinInfo, +) from qgis.utils import iface @@ -45,31 +52,28 @@ class BuildJoinsOnLayersAlgorithm(QgsProcessingAlgorithm): START_EDITING: starts edition of related layer if true OUTPUT: list of outputs """ - INPUT_LAYERS = 'INPUT_LAYERS' - START_EDITING = 'START_EDITING' - OUTPUT = 'OUTPUT' + + INPUT_LAYERS = "INPUT_LAYERS" + START_EDITING = "START_EDITING" + OUTPUT = "OUTPUT" + def initAlgorithm(self, config): """ Parameter setting. """ self.addParameter( QgsProcessingParameterMultipleLayers( - self.INPUT_LAYERS, - self.tr('Input Layers'), - QgsProcessing.TypeVector + self.INPUT_LAYERS, self.tr("Input Layers"), QgsProcessing.TypeVector ) ) self.addParameter( QgsProcessingParameterBoolean( - self.START_EDITING, - self.tr('Start Editing'), - defaultValue=True - ) + self.START_EDITING, self.tr("Start Editing"), defaultValue=True ) + ) self.addOutput( QgsProcessingOutputMultipleLayers( - self.OUTPUT, - self.tr('Original reorganized layers') + self.OUTPUT, self.tr("Original reorganized layers") ) ) @@ -77,22 +81,14 @@ def processAlgorithm(self, parameters, context, feedback): """ Here is where the processing itself takes place. """ - inputLyrList = self.parameterAsLayerList( - parameters, - self.INPUT_LAYERS, - context - ) - startEditing = self.parameterAsBoolean( - parameters, - self.START_EDITING, - context - ) + inputLyrList = self.parameterAsLayerList(parameters, self.INPUT_LAYERS, context) + startEditing = self.parameterAsBoolean(parameters, self.START_EDITING, context) listSize = len(inputLyrList) - progressStep = 100/listSize if listSize else 0 + progressStep = 100 / listSize if listSize else 0 relationManager = QgsProject.instance().relationManager() for current, relation in enumerate( - relationManager.discoverRelations([], inputLyrList) - ): + relationManager.discoverRelations([], inputLyrList) + ): if feedback.isCanceled(): break if relation.strength() != QgsRelation.Association: @@ -107,12 +103,19 @@ def processAlgorithm(self, parameters, context, feedback): originalLyrFieldName, joinnedLyr, joinLyrFieldName, - startEdit=startEditing + startEdit=startEditing, ) - feedback.setProgress(current*progressStep) + feedback.setProgress(current * progressStep) return {self.OUTPUT: [i.id() for i in inputLyrList]} - def buildJoin(self, originalLyr, originalLyrFieldName, joinnedLyr, joinLyrFieldName, startEdit=False): + def buildJoin( + self, + originalLyr, + originalLyrFieldName, + joinnedLyr, + joinLyrFieldName, + startEdit=False, + ): """ Builds a join bewteen lyr and joinnedLyr. :param originalLyr: QgsVectorLayer original layer; @@ -127,14 +130,13 @@ def buildJoin(self, originalLyr, originalLyrFieldName, joinnedLyr, joinLyrFieldN joinnedLyr.startEditing() joinObject.setJoinLayer(joinnedLyr) # joinObject.setJoinFieldNamesSubset([]) - joinObject.setUpsertOnEdit(True) #set to enable edit on original lyr + joinObject.setUpsertOnEdit(True) # set to enable edit on original lyr joinObject.setCascadedDelete(True) joinObject.setDynamicFormEnabled(True) joinObject.setEditable(True) joinObject.setUsingMemoryCache(True) originalLyr.addJoin(joinObject) - def name(self): """ Returns the algorithm name, used for identifying the algorithm. This @@ -143,21 +145,21 @@ def name(self): lowercase alphanumeric characters only and no spaces or other formatting characters. """ - return 'buildjoinsonlayersalgorithm' + return "buildjoinsonlayersalgorithm" def displayName(self): """ Returns the translated algorithm name, which should be used for any user-visible display of the algorithm name. """ - return self.tr('Build Joins on Layers') + return self.tr("Build Joins on Layers") def group(self): """ Returns the name of the group this algorithm belongs to. This string should be localised. """ - return self.tr('Layer Management Algorithms') + return self.tr("Layer Management Algorithms") def groupId(self): """ @@ -167,13 +169,13 @@ def groupId(self): contain lowercase alphanumeric characters only and no spaces or other formatting characters. """ - return 'DSGTools: Layer Management Algorithms' + return "DSGTools: Layer Management Algorithms" def tr(self, string): """ Translates input string. """ - return QCoreApplication.translate('BuildJoinsOnLayersAlgorithm', string) + return QCoreApplication.translate("BuildJoinsOnLayersAlgorithm", string) def createInstance(self): """ diff --git a/DsgTools/core/DSGToolsProcessingAlgs/Algs/LayerManagementAlgs/groupLayersAlgorithm.py b/DsgTools/core/DSGToolsProcessingAlgs/Algs/LayerManagementAlgs/groupLayersAlgorithm.py index 8f6bdb8df..45015903c 100644 --- a/DsgTools/core/DSGToolsProcessingAlgs/Algs/LayerManagementAlgs/groupLayersAlgorithm.py +++ b/DsgTools/core/DSGToolsProcessingAlgs/Algs/LayerManagementAlgs/groupLayersAlgorithm.py @@ -25,14 +25,20 @@ from PyQt5.QtCore import QCoreApplication -from qgis.core import (QgsDataSourceUri, QgsExpression, QgsExpressionContext, - QgsExpressionContextUtils, QgsProcessing, - QgsProcessingAlgorithm, - QgsProcessingOutputMultipleLayers, - QgsProcessingParameterExpression, - QgsProcessingParameterMultipleLayers, - QgsProcessingParameterNumber, - QgsProcessingParameterString, QgsProject) +from qgis.core import ( + QgsDataSourceUri, + QgsExpression, + QgsExpressionContext, + QgsExpressionContextUtils, + QgsProcessing, + QgsProcessingAlgorithm, + QgsProcessingOutputMultipleLayers, + QgsProcessingParameterExpression, + QgsProcessingParameterMultipleLayers, + QgsProcessingParameterNumber, + QgsProcessingParameterString, + QgsProject, +) from qgis.utils import iface @@ -44,31 +50,30 @@ class GroupLayersAlgorithm(QgsProcessingAlgorithm): CATEGORY_TOKEN_INDEX: index of the split list OUTPUT: list of outputs """ - INPUT_LAYERS = 'INPUT_LAYERS' - CATEGORY_EXPRESSION = 'CATEGORY_EXPRESSION' - OUTPUT = 'OUTPUT' + + INPUT_LAYERS = "INPUT_LAYERS" + CATEGORY_EXPRESSION = "CATEGORY_EXPRESSION" + OUTPUT = "OUTPUT" + def initAlgorithm(self, config): """ Parameter setting. """ self.addParameter( QgsProcessingParameterMultipleLayers( - self.INPUT_LAYERS, - self.tr('Input Layers'), - QgsProcessing.TypeVector + self.INPUT_LAYERS, self.tr("Input Layers"), QgsProcessing.TypeVector ) ) self.addParameter( QgsProcessingParameterExpression( self.CATEGORY_EXPRESSION, - self.tr('Expression used to find out the category'), - defaultValue="regexp_substr(@layer_name ,'([^_]+)')" + self.tr("Expression used to find out the category"), + defaultValue="regexp_substr(@layer_name ,'([^_]+)')", ) ) self.addOutput( QgsProcessingOutputMultipleLayers( - self.OUTPUT, - self.tr('Original reorganized layers') + self.OUTPUT, self.tr("Original reorganized layers") ) ) @@ -76,25 +81,19 @@ def processAlgorithm(self, parameters, context, feedback): """ Here is where the processing itself takes place. """ - inputLyrList = self.parameterAsLayerList( - parameters, - self.INPUT_LAYERS, - context - ) + inputLyrList = self.parameterAsLayerList(parameters, self.INPUT_LAYERS, context) categoryExpression = self.parameterAsExpression( - parameters, - self.CATEGORY_EXPRESSION, - context - ) + parameters, self.CATEGORY_EXPRESSION, context + ) listSize = len(inputLyrList) - progressStep = 100/listSize if listSize else 0 + progressStep = 100 / listSize if listSize else 0 rootNode = QgsProject.instance().layerTreeRoot() inputLyrList.sort(key=lambda x: (x.geometryType(), x.name())) geometryNodeDict = { - 0 : self.tr('Point'), - 1 : self.tr('Line'), - 2 : self.tr('Polygon'), - 4 : self.tr('Non spatial') + 0: self.tr("Point"), + 1: self.tr("Line"), + 2: self.tr("Polygon"), + 4: self.tr("Non spatial"), } iface.mapCanvas().freeze(True) for current, lyr in enumerate(inputLyrList): @@ -102,20 +101,17 @@ def processAlgorithm(self, parameters, context, feedback): break rootDatabaseNode = self.getLayerRootNode(lyr, rootNode) geometryNode = self.createGroup( - geometryNodeDict[lyr.geometryType()], - rootDatabaseNode + geometryNodeDict[lyr.geometryType()], rootDatabaseNode ) categoryNode = self.getLayerCategoryNode( - lyr, - geometryNode, - categoryExpression + lyr, geometryNode, categoryExpression ) lyrNode = rootNode.findLayer(lyr.id()) myClone = lyrNode.clone() categoryNode.addChildNode(myClone) # not thread safe, must set flag to FlagNoThreading rootNode.removeChildNode(lyrNode) - feedback.setProgress(current*progressStep) + feedback.setProgress(current * progressStep) iface.mapCanvas().freeze(False) return {self.OUTPUT: [i.id() for i in inputLyrList]} @@ -131,21 +127,21 @@ def getLayerRootNode(self, lyr, rootNode): rootNodeName = candidateUri.database() if not rootNodeName: rootNodeName = self.getRootNodeName(uriText) - #creates database root + # creates database root return self.createGroup(rootNodeName, rootNode) def getRootNodeName(self, uriText): """ Gets root node name from uri according to provider type. """ - if 'memory?' in uriText: - rootNodeName = 'memory' - elif 'dbname' in uriText: - rootNodeName = uriText.replace('dbname=', '').split(' ')[0] - elif '|' in uriText: - rootNodeName = os.path.dirname(uriText.split(' ')[0].split('|')[0]) + if "memory?" in uriText: + rootNodeName = "memory" + elif "dbname" in uriText: + rootNodeName = uriText.replace("dbname=", "").split(" ")[0] + elif "|" in uriText: + rootNodeName = os.path.dirname(uriText.split(" ")[0].split("|")[0]) else: - rootNodeName = 'unrecognised_format' + rootNodeName = "unrecognised_format" return rootNodeName def getLayerCategoryNode(self, lyr, rootNode, categoryExpression): @@ -155,9 +151,7 @@ def getLayerCategoryNode(self, lyr, rootNode, categoryExpression): """ exp = QgsExpression(categoryExpression) context = QgsExpressionContext() - context.appendScopes( - QgsExpressionContextUtils.globalProjectLayerScopes(lyr) - ) + context.appendScopes(QgsExpressionContextUtils.globalProjectLayerScopes(lyr)) if exp.hasParserError(): raise Exception(exp.parserErrorString()) if exp.hasEvalError(): @@ -180,21 +174,21 @@ def name(self): lowercase alphanumeric characters only and no spaces or other formatting characters. """ - return 'grouplayers' + return "grouplayers" def displayName(self): """ Returns the translated algorithm name, which should be used for any user-visible display of the algorithm name. """ - return self.tr('Group Layers') + return self.tr("Group Layers") def group(self): """ Returns the name of the group this algorithm belongs to. This string should be localised. """ - return self.tr('Layer Management Algorithms') + return self.tr("Layer Management Algorithms") def groupId(self): """ @@ -204,13 +198,13 @@ def groupId(self): contain lowercase alphanumeric characters only and no spaces or other formatting characters. """ - return 'DSGTools: Layer Management Algorithms' + return "DSGTools: Layer Management Algorithms" def tr(self, string): """ Translates input string. """ - return QCoreApplication.translate('GroupLayersAlgorithm', string) + return QCoreApplication.translate("GroupLayersAlgorithm", string) def createInstance(self): """ diff --git a/DsgTools/core/DSGToolsProcessingAlgs/Algs/LayerManagementAlgs/loadLayersFromPostgisAlgorithm.py b/DsgTools/core/DSGToolsProcessingAlgs/Algs/LayerManagementAlgs/loadLayersFromPostgisAlgorithm.py index 1b2b33f6d..53b3bc657 100644 --- a/DsgTools/core/DSGToolsProcessingAlgs/Algs/LayerManagementAlgs/loadLayersFromPostgisAlgorithm.py +++ b/DsgTools/core/DSGToolsProcessingAlgs/Algs/LayerManagementAlgs/loadLayersFromPostgisAlgorithm.py @@ -24,204 +24,158 @@ from DsgTools.core.dsgEnums import DsgEnums from DsgTools.core.Factories.DbFactory.dbFactory import DbFactory -from DsgTools.core.Factories.LayerLoaderFactory.layerLoaderFactory import \ - LayerLoaderFactory -from qgis.core import (QgsCoordinateReferenceSystem, QgsCoordinateTransform, - QgsDataSourceUri, QgsFeature, QgsFeatureSink, QgsField, - QgsFields, QgsGeometry, QgsProcessing, - QgsProcessingAlgorithm, QgsProcessingException, - QgsProcessingMultiStepFeedback, - QgsProcessingOutputMultipleLayers, - QgsProcessingOutputVectorLayer, - QgsProcessingParameterBoolean, - QgsProcessingParameterCrs, - QgsProcessingParameterDefinition, - QgsProcessingParameterEnum, - QgsProcessingParameterExpression, - QgsProcessingParameterFeatureSink, - QgsProcessingParameterFeatureSource, - QgsProcessingParameterField, QgsProcessingParameterFile, - QgsProcessingParameterMultipleLayers, - QgsProcessingParameterNumber, - QgsProcessingParameterString, - QgsProcessingParameterType, - QgsProcessingParameterVectorLayer, QgsProcessingUtils, - QgsProject, QgsSpatialIndex, QgsWkbTypes, - QgsMapLayer) +from DsgTools.core.Factories.LayerLoaderFactory.layerLoaderFactory import ( + LayerLoaderFactory, +) +from qgis.core import ( + QgsCoordinateReferenceSystem, + QgsCoordinateTransform, + QgsDataSourceUri, + QgsFeature, + QgsFeatureSink, + QgsField, + QgsFields, + QgsGeometry, + QgsProcessing, + QgsProcessingAlgorithm, + QgsProcessingException, + QgsProcessingMultiStepFeedback, + QgsProcessingOutputMultipleLayers, + QgsProcessingOutputVectorLayer, + QgsProcessingParameterBoolean, + QgsProcessingParameterCrs, + QgsProcessingParameterDefinition, + QgsProcessingParameterEnum, + QgsProcessingParameterExpression, + QgsProcessingParameterFeatureSink, + QgsProcessingParameterFeatureSource, + QgsProcessingParameterField, + QgsProcessingParameterFile, + QgsProcessingParameterMultipleLayers, + QgsProcessingParameterNumber, + QgsProcessingParameterString, + QgsProcessingParameterType, + QgsProcessingParameterVectorLayer, + QgsProcessingUtils, + QgsProject, + QgsSpatialIndex, + QgsWkbTypes, + QgsMapLayer, +) from qgis.utils import iface + class LoadLayersFromPostgisAlgorithm(QgsProcessingAlgorithm): - HOST = 'HOST' - PORT = 'PORT' - DATABASE = 'DATABASE' - USER = 'USER' - PASSWORD = 'PASSWORD' - LAYER_LIST = 'LAYER_LIST' - LOAD_TO_CANVAS = 'LOAD_TO_CANVAS' - UNIQUE_LOAD = 'UNIQUE_LOAD' - OUTPUT = 'OUTPUT' + HOST = "HOST" + PORT = "PORT" + DATABASE = "DATABASE" + USER = "USER" + PASSWORD = "PASSWORD" + LAYER_LIST = "LAYER_LIST" + LOAD_TO_CANVAS = "LOAD_TO_CANVAS" + UNIQUE_LOAD = "UNIQUE_LOAD" + OUTPUT = "OUTPUT" def initAlgorithm(self, config): """ Parameter setting. """ + self.addParameter(QgsProcessingParameterString(self.HOST, self.tr("Host"))) + self.addParameter(QgsProcessingParameterString(self.PORT, self.tr("Port"))) self.addParameter( - QgsProcessingParameterString( - self.HOST, - self.tr('Host') - ) + QgsProcessingParameterString(self.DATABASE, self.tr("Database")) ) + self.addParameter(QgsProcessingParameterString(self.USER, self.tr("User"))) self.addParameter( - QgsProcessingParameterString( - self.PORT, - self.tr('Port') - ) + QgsProcessingParameterString(self.PASSWORD, self.tr("Password")) ) self.addParameter( - QgsProcessingParameterString( - self.DATABASE, - self.tr('Database') - ) - ) - self.addParameter( - QgsProcessingParameterString( - self.USER, - self.tr('User') - ) - ) - self.addParameter( - QgsProcessingParameterString( - self.PASSWORD, - self.tr('Password') - ) - ) - self.addParameter( - QgsProcessingParameterString( - self.LAYER_LIST, - self.tr('Layer List') - ) + QgsProcessingParameterString(self.LAYER_LIST, self.tr("Layer List")) ) self.addParameter( QgsProcessingParameterBoolean( - self.LOAD_TO_CANVAS, - self.tr('Load layers to canvas'), - defaultValue=True + self.LOAD_TO_CANVAS, self.tr("Load layers to canvas"), defaultValue=True ) ) self.addParameter( QgsProcessingParameterBoolean( - self.UNIQUE_LOAD, - self.tr('Unique load'), - defaultValue=True + self.UNIQUE_LOAD, self.tr("Unique load"), defaultValue=True ) ) self.addOutput( - QgsProcessingOutputMultipleLayers( - self.OUTPUT, - self.tr('Loaded layers') - ) + QgsProcessingOutputMultipleLayers(self.OUTPUT, self.tr("Loaded layers")) ) def processAlgorithm(self, parameters, context, feedback): """ Here is where the processing itself takes place. """ - host = self.parameterAsString( - parameters, - self.HOST, - context - ) - port = self.parameterAsString( - parameters, - self.PORT, - context - ) - database = self.parameterAsString( - parameters, - self.DATABASE, - context - ) - user = self.parameterAsString( - parameters, - self.USER, - context - ) - password = self.parameterAsString( - parameters, - self.PASSWORD, - context - ) - layerStringList = self.parameterAsString( - parameters, - self.LAYER_LIST, - context - ) - loadToCanvas = self.parameterAsBool( - parameters, - self.LOAD_TO_CANVAS, - context - ) - uniqueLoad = self.parameterAsBool( - parameters, - self.UNIQUE_LOAD, - context - ) + host = self.parameterAsString(parameters, self.HOST, context) + port = self.parameterAsString(parameters, self.PORT, context) + database = self.parameterAsString(parameters, self.DATABASE, context) + user = self.parameterAsString(parameters, self.USER, context) + password = self.parameterAsString(parameters, self.PASSWORD, context) + layerStringList = self.parameterAsString(parameters, self.LAYER_LIST, context) + loadToCanvas = self.parameterAsBool(parameters, self.LOAD_TO_CANVAS, context) + uniqueLoad = self.parameterAsBool(parameters, self.UNIQUE_LOAD, context) abstractDb = self.getAbstractDb(host, port, database, user, password) - inputParamList = layerStringList.split(',') - unloadedLayerNames = self.getUnloadedLayerNames( inputParamList ) + inputParamList = layerStringList.split(",") + unloadedLayerNames = self.getUnloadedLayerNames(inputParamList) if not unloadedLayerNames: - return { self.OUTPUT: [] } - layerLoader = LayerLoaderFactory().makeLoader( - iface, abstractDb - ) + return {self.OUTPUT: []} + layerLoader = LayerLoaderFactory().makeLoader(iface, abstractDb) if loadToCanvas: iface.mapCanvas().freeze(True) outputLayers = layerLoader.loadLayersInsideProcessing( unloadedLayerNames, uniqueLoad=uniqueLoad, addToCanvas=loadToCanvas, - feedback=feedback + feedback=feedback, ) if loadToCanvas: iface.mapCanvas().freeze(False) - return { self.OUTPUT: self.getLoadedLayerIds(layerNamesFilter=unloadedLayerNames) } + return { + self.OUTPUT: self.getLoadedLayerIds(layerNamesFilter=unloadedLayerNames) + } def getLoadedLayerIds(self, layerNamesFilter): layerIds = [] for l in QgsProject.instance().mapLayers().values(): - if not( l.type() == QgsMapLayer.VectorLayer ): + if not (l.type() == QgsMapLayer.VectorLayer): continue layerName = None - if l.providerType() == 'postgres': + if l.providerType() == "postgres": layerName = l.dataProvider().uri().table() - elif l.providerType() == 'ogr': - layerName = l.dataProvider().uri().uri().split('|')[-1].split('=')[-1][1:-1] - if not layerName or not( layerName in layerNamesFilter ): + elif l.providerType() == "ogr": + layerName = ( + l.dataProvider().uri().uri().split("|")[-1].split("=")[-1][1:-1] + ) + if not layerName or not (layerName in layerNamesFilter): continue - layerIds.append( l.id() ) + layerIds.append(l.id()) return layerIds def getUnloadedLayerNames(self, layerNames): loadedLayerNames = [] for l in QgsProject.instance().mapLayers().values(): - if not( l.type() == QgsMapLayer.VectorLayer ): + if not (l.type() == QgsMapLayer.VectorLayer): continue layerName = None - if l.providerType() == 'postgres': + if l.providerType() == "postgres": layerName = l.dataProvider().uri().table() - elif l.providerType() == 'ogr': - layerName = l.dataProvider().uri().uri().split('|')[-1].split('=')[-1][1:-1] - if not layerName or not( layerName in layerNames ): + elif l.providerType() == "ogr": + layerName = ( + l.dataProvider().uri().uri().split("|")[-1].split("=")[-1][1:-1] + ) + if not layerName or not (layerName in layerNames): continue - loadedLayerNames.append( layerName ) + loadedLayerNames.append(layerName) return list(set(layerNames) - set(loadedLayerNames)) - + def getAbstractDb(self, host, port, database, user, password): abstractDb = DbFactory().createDbFactory(DsgEnums.DriverPostGIS) - abstractDb.connectDatabaseWithParameters( - host, port, database, user, password - ) + abstractDb.connectDatabaseWithParameters(host, port, database, user, password) return abstractDb def name(self): @@ -232,21 +186,21 @@ def name(self): lowercase alphanumeric characters only and no spaces or other formatting characters. """ - return 'loadlayersfrompostgisalgorithm' + return "loadlayersfrompostgisalgorithm" def displayName(self): """ Returns the translated algorithm name, which should be used for any user-visible display of the algorithm name. """ - return self.tr('Load Layers From Postgis') + return self.tr("Load Layers From Postgis") def group(self): """ Returns the name of the group this algorithm belongs to. This string should be localised. """ - return self.tr('Layer Management Algorithms') + return self.tr("Layer Management Algorithms") def groupId(self): """ @@ -256,10 +210,10 @@ def groupId(self): contain lowercase alphanumeric characters only and no spaces or other formatting characters. """ - return 'DSGTools: Layer Management Algorithms' + return "DSGTools: Layer Management Algorithms" def tr(self, string): - return QCoreApplication.translate('LoadLayersFromPostgisAlgorithm', string) + return QCoreApplication.translate("LoadLayersFromPostgisAlgorithm", string) def createInstance(self): return LoadLayersFromPostgisAlgorithm() diff --git a/DsgTools/core/DSGToolsProcessingAlgs/Algs/LayerManagementAlgs/loadNonSpatialLayersFromPostgreSQLAlgorithm.py b/DsgTools/core/DSGToolsProcessingAlgs/Algs/LayerManagementAlgs/loadNonSpatialLayersFromPostgreSQLAlgorithm.py index 8c5e864b1..ba6c7c7e3 100644 --- a/DsgTools/core/DSGToolsProcessingAlgs/Algs/LayerManagementAlgs/loadNonSpatialLayersFromPostgreSQLAlgorithm.py +++ b/DsgTools/core/DSGToolsProcessingAlgs/Algs/LayerManagementAlgs/loadNonSpatialLayersFromPostgreSQLAlgorithm.py @@ -24,164 +24,108 @@ from DsgTools.core.dsgEnums import DsgEnums from DsgTools.core.Factories.DbFactory.dbFactory import DbFactory -from DsgTools.core.Factories.LayerLoaderFactory.layerLoaderFactory import \ - LayerLoaderFactory +from DsgTools.core.Factories.LayerLoaderFactory.layerLoaderFactory import ( + LayerLoaderFactory, +) import processing -from qgis.core import (QgsCoordinateReferenceSystem, QgsCoordinateTransform, - QgsDataSourceUri, QgsFeature, QgsFeatureSink, QgsField, - QgsFields, QgsGeometry, QgsProcessing, - QgsProcessingAlgorithm, QgsProcessingException, - QgsProcessingMultiStepFeedback, - QgsProcessingOutputMultipleLayers, - QgsProcessingOutputVectorLayer, - QgsProcessingParameterBoolean, - QgsProcessingParameterCrs, - QgsProcessingParameterDefinition, - QgsProcessingParameterEnum, - QgsProcessingParameterExpression, - QgsProcessingParameterFeatureSink, - QgsProcessingParameterFeatureSource, - QgsProcessingParameterField, QgsProcessingParameterFile, - QgsProcessingParameterMultipleLayers, - QgsProcessingParameterNumber, - QgsProcessingParameterString, - QgsProcessingParameterType, - QgsProcessingParameterVectorLayer, QgsProcessingUtils, - QgsProject, QgsSpatialIndex, QgsWkbTypes) +from qgis.core import ( + QgsCoordinateReferenceSystem, + QgsCoordinateTransform, + QgsDataSourceUri, + QgsFeature, + QgsFeatureSink, + QgsField, + QgsFields, + QgsGeometry, + QgsProcessing, + QgsProcessingAlgorithm, + QgsProcessingException, + QgsProcessingMultiStepFeedback, + QgsProcessingOutputMultipleLayers, + QgsProcessingOutputVectorLayer, + QgsProcessingParameterBoolean, + QgsProcessingParameterCrs, + QgsProcessingParameterDefinition, + QgsProcessingParameterEnum, + QgsProcessingParameterExpression, + QgsProcessingParameterFeatureSink, + QgsProcessingParameterFeatureSource, + QgsProcessingParameterField, + QgsProcessingParameterFile, + QgsProcessingParameterMultipleLayers, + QgsProcessingParameterNumber, + QgsProcessingParameterString, + QgsProcessingParameterType, + QgsProcessingParameterVectorLayer, + QgsProcessingUtils, + QgsProject, + QgsSpatialIndex, + QgsWkbTypes, +) from qgis.utils import iface + class LoadNonSpatialLayersFromPostgreSQLAlgorithm(QgsProcessingAlgorithm): - HOST = 'HOST' - PORT = 'PORT' - DATABASE = 'DATABASE' - USER = 'USER' - PASSWORD = 'PASSWORD' - LAYER_LIST = 'LAYER_LIST' - LOAD_TO_CANVAS = 'LOAD_TO_CANVAS' - UNIQUE_LOAD = 'UNIQUE_LOAD' - SCHEMA_NAME = 'SCHEMA_NAME' - OUTPUT = 'OUTPUT' + HOST = "HOST" + PORT = "PORT" + DATABASE = "DATABASE" + USER = "USER" + PASSWORD = "PASSWORD" + LAYER_LIST = "LAYER_LIST" + LOAD_TO_CANVAS = "LOAD_TO_CANVAS" + UNIQUE_LOAD = "UNIQUE_LOAD" + SCHEMA_NAME = "SCHEMA_NAME" + OUTPUT = "OUTPUT" + def initAlgorithm(self, config): """ Parameter setting. """ + self.addParameter(QgsProcessingParameterString(self.HOST, self.tr("Host"))) + self.addParameter(QgsProcessingParameterString(self.PORT, self.tr("Port"))) self.addParameter( - QgsProcessingParameterString( - self.HOST, - self.tr('Host') - ) - ) - self.addParameter( - QgsProcessingParameterString( - self.PORT, - self.tr('Port') - ) + QgsProcessingParameterString(self.DATABASE, self.tr("Database")) ) + self.addParameter(QgsProcessingParameterString(self.USER, self.tr("User"))) self.addParameter( - QgsProcessingParameterString( - self.DATABASE, - self.tr('Database') - ) + QgsProcessingParameterString(self.PASSWORD, self.tr("Password")) ) self.addParameter( - QgsProcessingParameterString( - self.USER, - self.tr('User') - ) - ) - self.addParameter( - QgsProcessingParameterString( - self.PASSWORD, - self.tr('Password') - ) - ) - self.addParameter( - QgsProcessingParameterString( - self.LAYER_LIST, - self.tr('Layer List') - ) + QgsProcessingParameterString(self.LAYER_LIST, self.tr("Layer List")) ) self.addParameter( QgsProcessingParameterBoolean( - self.LOAD_TO_CANVAS, - self.tr('Load layers to canvas'), - defaultValue=True + self.LOAD_TO_CANVAS, self.tr("Load layers to canvas"), defaultValue=True ) ) self.addParameter( QgsProcessingParameterBoolean( - self.UNIQUE_LOAD, - self.tr('Unique load'), - defaultValue=True + self.UNIQUE_LOAD, self.tr("Unique load"), defaultValue=True ) ) self.addParameter( - QgsProcessingParameterString( - self.SCHEMA_NAME, - self.tr('Schema name') - ) + QgsProcessingParameterString(self.SCHEMA_NAME, self.tr("Schema name")) ) self.addOutput( - QgsProcessingOutputMultipleLayers( - self.OUTPUT, - self.tr('Loaded layers') - ) + QgsProcessingOutputMultipleLayers(self.OUTPUT, self.tr("Loaded layers")) ) def processAlgorithm(self, parameters, context, feedback): """ Here is where the processing itself takes place. """ - host = self.parameterAsString( - parameters, - self.HOST, - context - ) - port = self.parameterAsString( - parameters, - self.PORT, - context - ) - database = self.parameterAsString( - parameters, - self.DATABASE, - context - ) - user = self.parameterAsString( - parameters, - self.USER, - context - ) - password = self.parameterAsString( - parameters, - self.PASSWORD, - context - ) - layerStringList = self.parameterAsString( - parameters, - self.LAYER_LIST, - context - ) - loadToCanvas = self.parameterAsBoolean( - parameters, - self.LOAD_TO_CANVAS, - context - ) - uniqueLoad = self.parameterAsBoolean( - parameters, - self.UNIQUE_LOAD, - context - ) - tableSchema = self.parameterAsString( - parameters, - self.SCHEMA_NAME, - context - ) + host = self.parameterAsString(parameters, self.HOST, context) + port = self.parameterAsString(parameters, self.PORT, context) + database = self.parameterAsString(parameters, self.DATABASE, context) + user = self.parameterAsString(parameters, self.USER, context) + password = self.parameterAsString(parameters, self.PASSWORD, context) + layerStringList = self.parameterAsString(parameters, self.LAYER_LIST, context) + loadToCanvas = self.parameterAsBoolean(parameters, self.LOAD_TO_CANVAS, context) + uniqueLoad = self.parameterAsBoolean(parameters, self.UNIQUE_LOAD, context) + tableSchema = self.parameterAsString(parameters, self.SCHEMA_NAME, context) abstractDb = self.getAbstractDb(host, port, database, user, password) - inputParamList = [(tableSchema, i) for i in layerStringList.split(',')] - layerLoader = LayerLoaderFactory().makeLoader( - iface, abstractDb - ) + inputParamList = [(tableSchema, i) for i in layerStringList.split(",")] + layerLoader = LayerLoaderFactory().makeLoader(iface, abstractDb) if loadToCanvas: iface.mapCanvas().freeze(True) multiStepFeedback = QgsProcessingMultiStepFeedback(2, feedback) @@ -191,30 +135,26 @@ def processAlgorithm(self, parameters, context, feedback): uniqueLoad=uniqueLoad, addToCanvas=loadToCanvas, nonSpatial=True, - feedback=multiStepFeedback + feedback=multiStepFeedback, ) multiStepFeedback.setCurrentStep(1) output = processing.run( - 'dsgtools:grouplayers', + "dsgtools:grouplayers", { - 'INPUT_LAYERS' : outputLayers, - 'CATEGORY_EXPRESSION' : "to_string('{name}')".format( - name=tableSchema - ), - 'OUTPUT' : ':memory' + "INPUT_LAYERS": outputLayers, + "CATEGORY_EXPRESSION": "to_string('{name}')".format(name=tableSchema), + "OUTPUT": ":memory", }, context=context, - feedback=multiStepFeedback + feedback=multiStepFeedback, ) if loadToCanvas: iface.mapCanvas().freeze(False) return {self.OUTPUT: [i.id() for i in outputLayers]} - + def getAbstractDb(self, host, port, database, user, password): abstractDb = DbFactory().createDbFactory(DsgEnums.DriverPostGIS) - abstractDb.connectDatabaseWithParameters( - host, port, database, user, password - ) + abstractDb.connectDatabaseWithParameters(host, port, database, user, password) return abstractDb def name(self): @@ -225,21 +165,21 @@ def name(self): lowercase alphanumeric characters only and no spaces or other formatting characters. """ - return 'LoadNonSpatialLayersFromPostgreSQLAlgorithm' + return "LoadNonSpatialLayersFromPostgreSQLAlgorithm" def displayName(self): """ Returns the translated algorithm name, which should be used for any user-visible display of the algorithm name. """ - return self.tr('Load Non-Spatial Layers From PostgreSQL') + return self.tr("Load Non-Spatial Layers From PostgreSQL") def group(self): """ Returns the name of the group this algorithm belongs to. This string should be localised. """ - return self.tr('Layer Management Algorithms') + return self.tr("Layer Management Algorithms") def groupId(self): """ @@ -249,10 +189,12 @@ def groupId(self): contain lowercase alphanumeric characters only and no spaces or other formatting characters. """ - return 'DSGTools: Layer Management Algorithms' + return "DSGTools: Layer Management Algorithms" def tr(self, string): - return QCoreApplication.translate('LoadNonSpatialLayersFromPostgreSQLAlgorithm', string) + return QCoreApplication.translate( + "LoadNonSpatialLayersFromPostgreSQLAlgorithm", string + ) def createInstance(self): return LoadNonSpatialLayersFromPostgreSQLAlgorithm() diff --git a/DsgTools/core/DSGToolsProcessingAlgs/Algs/LayerManagementAlgs/loadShapefileAlgorithm.py b/DsgTools/core/DSGToolsProcessingAlgs/Algs/LayerManagementAlgs/loadShapefileAlgorithm.py index d3841d620..601ba04ca 100644 --- a/DsgTools/core/DSGToolsProcessingAlgs/Algs/LayerManagementAlgs/loadShapefileAlgorithm.py +++ b/DsgTools/core/DSGToolsProcessingAlgs/Algs/LayerManagementAlgs/loadShapefileAlgorithm.py @@ -23,17 +23,21 @@ import os from PyQt5.QtCore import QCoreApplication -from qgis.core import (QgsProcessingAlgorithm, - QgsProcessingOutputMultipleLayers, - QgsProcessingParameterFile, QgsProject, QgsVectorLayer, - QgsWkbTypes) +from qgis.core import ( + QgsProcessingAlgorithm, + QgsProcessingOutputMultipleLayers, + QgsProcessingParameterFile, + QgsProject, + QgsVectorLayer, + QgsWkbTypes, +) from qgis.utils import iface class LoadShapefileAlgorithm(QgsProcessingAlgorithm): - FOLDER_SHAPEFILES = 'FOLDER_SHAPEFILES' - OUTPUT = 'OUTPUT' + FOLDER_SHAPEFILES = "FOLDER_SHAPEFILES" + OUTPUT = "OUTPUT" def __init__(self): super().__init__() @@ -42,61 +46,49 @@ def initAlgorithm(self, config): self.addParameter( QgsProcessingParameterFile( self.FOLDER_SHAPEFILES, - self.tr('Pasta com Shapefiles'), - behavior = QgsProcessingParameterFile.Folder, + self.tr("Pasta com Shapefiles"), + behavior=QgsProcessingParameterFile.Folder, ) ) self.addOutput( - QgsProcessingOutputMultipleLayers( - self.OUTPUT, - self.tr('Loaded layers') - ) + QgsProcessingOutputMultipleLayers(self.OUTPUT, self.tr("Loaded layers")) ) def processAlgorithm(self, parameters, context, feedback): - folderPath = self.parameterAsString( - parameters, - self.FOLDER_SHAPEFILES, - context - ) + folderPath = self.parameterAsString(parameters, self.FOLDER_SHAPEFILES, context) output = [] - shapefileData = [ - { - 'name': fileName.split('.')[0], - 'path': os.path.join(folderPath, fileName) - } + shapefileData = [ + {"name": fileName.split(".")[0], "path": os.path.join(folderPath, fileName)} for fileName in os.listdir(folderPath) - if fileName.split('.')[1] == 'shp' + if fileName.split(".")[1] == "shp" ] - shapefileData = sorted(shapefileData, key=lambda k: k['name']) + shapefileData = sorted(shapefileData, key=lambda k: k["name"]) listSize = len(shapefileData) - progressStep = 100/listSize if listSize else 0 - rootNode = QgsProject.instance().layerTreeRoot().addGroup('shapefiles') + progressStep = 100 / listSize if listSize else 0 + rootNode = QgsProject.instance().layerTreeRoot().addGroup("shapefiles") groups = { - QgsWkbTypes.PointGeometry: self.createGroup('Ponto', rootNode), - QgsWkbTypes.LineGeometry: self.createGroup('Linha', rootNode), - QgsWkbTypes.PolygonGeometry: self.createGroup('Area', rootNode), - + QgsWkbTypes.PointGeometry: self.createGroup("Ponto", rootNode), + QgsWkbTypes.LineGeometry: self.createGroup("Linha", rootNode), + QgsWkbTypes.PolygonGeometry: self.createGroup("Area", rootNode), } for step, data in enumerate(shapefileData): if feedback.isCanceled(): break iface.mapCanvas().freeze(True) ml = QgsProject.instance().addMapLayer( - QgsVectorLayer(data['path'], data['name'], 'ogr'), - addToLegend = False + QgsVectorLayer(data["path"], data["name"], "ogr"), addToLegend=False ) groups[QgsWkbTypes.geometryType(ml.wkbType())].addLayer(ml) output.append(ml.id()) iface.mapCanvas().freeze(False) - feedback.setProgress(step*progressStep) + feedback.setProgress(step * progressStep) self.removeEmptyGroups(list(groups.values()), rootNode) return {self.OUTPUT: output} def createGroup(self, groupName, rootNode): return rootNode.addGroup(groupName) - + def removeEmptyGroups(self, groups, rootNode): for group in groups: if group.findLayers(): @@ -111,21 +103,21 @@ def name(self): lowercase alphanumeric characters only and no spaces or other formatting characters. """ - return 'loadshapefilealgorithm' + return "loadshapefilealgorithm" def displayName(self): """ Returns the translated algorithm name, which should be used for any user-visible display of the algorithm name. """ - return self.tr('Loads a shapefile (.shp)') + return self.tr("Loads a shapefile (.shp)") def group(self): """ Returns the name of the group this algorithm belongs to. This string should be localised. """ - return self.tr('Layer Management Algorithms') + return self.tr("Layer Management Algorithms") def groupId(self): """ @@ -135,13 +127,13 @@ def groupId(self): contain lowercase alphanumeric characters only and no spaces or other formatting characters. """ - return 'DSGTools: Layer Management Algorithms' + return "DSGTools: Layer Management Algorithms" def tr(self, string): """ Translates input string. """ - return QCoreApplication.translate('LoadShapefileAlgorithm', string) + return QCoreApplication.translate("LoadShapefileAlgorithm", string) def createInstance(self): """ diff --git a/DsgTools/core/DSGToolsProcessingAlgs/Algs/LayerManagementAlgs/lockAttributeEditingAlgorithm.py b/DsgTools/core/DSGToolsProcessingAlgs/Algs/LayerManagementAlgs/lockAttributeEditingAlgorithm.py index ce5f8c47e..34fe556b7 100644 --- a/DsgTools/core/DSGToolsProcessingAlgs/Algs/LayerManagementAlgs/lockAttributeEditingAlgorithm.py +++ b/DsgTools/core/DSGToolsProcessingAlgs/Algs/LayerManagementAlgs/lockAttributeEditingAlgorithm.py @@ -22,45 +22,49 @@ """ from PyQt5.QtCore import QCoreApplication from qgis.PyQt.Qt import QVariant -from qgis.core import (QgsProcessing, - QgsFeatureSink, - QgsProcessingAlgorithm, - QgsProcessingParameterFeatureSource, - QgsProcessingParameterFeatureSink, - QgsFeature, - QgsDataSourceUri, - QgsProcessingOutputVectorLayer, - QgsProcessingParameterVectorLayer, - QgsWkbTypes, - QgsProcessingParameterBoolean, - QgsProcessingParameterEnum, - QgsProcessingParameterNumber, - QgsProcessingParameterMultipleLayers, - QgsProcessingUtils, - QgsSpatialIndex, - QgsGeometry, - QgsProcessingParameterField, - QgsProcessingMultiStepFeedback, - QgsProcessingParameterFile, - QgsProcessingParameterExpression, - QgsProcessingException, - QgsProcessingParameterString, - QgsProcessingParameterDefinition, - QgsProcessingParameterType, - QgsProcessingParameterCrs, - QgsCoordinateTransform, - QgsProject, - QgsCoordinateReferenceSystem, - QgsField, - QgsFields, - QgsProcessingOutputMultipleLayers, - QgsVectorLayer, - QgsProcessingParameterString) +from qgis.core import ( + QgsProcessing, + QgsFeatureSink, + QgsProcessingAlgorithm, + QgsProcessingParameterFeatureSource, + QgsProcessingParameterFeatureSink, + QgsFeature, + QgsDataSourceUri, + QgsProcessingOutputVectorLayer, + QgsProcessingParameterVectorLayer, + QgsWkbTypes, + QgsProcessingParameterBoolean, + QgsProcessingParameterEnum, + QgsProcessingParameterNumber, + QgsProcessingParameterMultipleLayers, + QgsProcessingUtils, + QgsSpatialIndex, + QgsGeometry, + QgsProcessingParameterField, + QgsProcessingMultiStepFeedback, + QgsProcessingParameterFile, + QgsProcessingParameterExpression, + QgsProcessingException, + QgsProcessingParameterString, + QgsProcessingParameterDefinition, + QgsProcessingParameterType, + QgsProcessingParameterCrs, + QgsCoordinateTransform, + QgsProject, + QgsCoordinateReferenceSystem, + QgsField, + QgsFields, + QgsProcessingOutputMultipleLayers, + QgsVectorLayer, + QgsProcessingParameterString, +) + class LockAttributeEditingAlgorithm(QgsProcessingAlgorithm): - INPUT_LAYERS = 'INPUT_LAYERS' - COLUMN_NAMES = 'COLUMN_NAMES' - OUTPUT = 'OUTPUT' + INPUT_LAYERS = "INPUT_LAYERS" + COLUMN_NAMES = "COLUMN_NAMES" + OUTPUT = "OUTPUT" + def initAlgorithm(self, config): """ Parameter setting. @@ -68,24 +72,23 @@ def initAlgorithm(self, config): self.addParameter( QgsProcessingParameterMultipleLayers( self.INPUT_LAYERS, - self.tr('Input Layers'), - QgsProcessing.TypeVectorAnyGeometry + self.tr("Input Layers"), + QgsProcessing.TypeVectorAnyGeometry, ) ) self.addParameter( QgsProcessingParameterString( self.COLUMN_NAMES, - description = self.tr('Attributes to lock (separated by comma)'), - multiLine = False, - defaultValue = '' + description=self.tr("Attributes to lock (separated by comma)"), + multiLine=False, + defaultValue="", ) ) self.addOutput( QgsProcessingOutputMultipleLayers( - self.OUTPUT, - self.tr('Original layers with locked attributes edit') + self.OUTPUT, self.tr("Original layers with locked attributes edit") ) ) @@ -93,22 +96,16 @@ def processAlgorithm(self, parameters, context, feedback): """ Here is where the processing itself takes place. """ - inputLyrList = self.parameterAsLayerList( - parameters, - self.INPUT_LAYERS, - context - ) + inputLyrList = self.parameterAsLayerList(parameters, self.INPUT_LAYERS, context) inputColumnNames = self.parameterAsString( - parameters, - self.COLUMN_NAMES, - context + parameters, self.COLUMN_NAMES, context ) listSize = len(inputLyrList) - stepSize = 100/listSize if listSize else 0 + stepSize = 100 / listSize if listSize else 0 + + self.COLUMNS_TO_LOCK = list(map(str.strip, inputColumnNames.upper().split(","))) - self.COLUMNS_TO_LOCK = list(map(str.strip, inputColumnNames.upper().split(','))) - for current, lyr in enumerate(inputLyrList): if feedback.isCanceled(): break @@ -117,7 +114,7 @@ def processAlgorithm(self, parameters, context, feedback): return {self.OUTPUT: [lyr.id() for lyr in inputLyrList]} - def tryLockAttributeEditing(self, layer : QgsVectorLayer): + def tryLockAttributeEditing(self, layer: QgsVectorLayer): layerFields = layer.fields() layerFieldNames = list(map(str.upper, layerFields.names())) for columnToLockName in self.COLUMNS_TO_LOCK: @@ -129,7 +126,7 @@ def tryLockAttributeEditing(self, layer : QgsVectorLayer): formConfig = layer.editFormConfig() formConfig.setReadOnly(idxOnLayer, True) layer.setEditFormConfig(formConfig) - + return layer def name(self): @@ -140,21 +137,21 @@ def name(self): lowercase alphanumeric characters only and no spaces or other formatting characters. """ - return 'lockattributeediting' + return "lockattributeediting" def displayName(self): """ Returns the translated algorithm name, which should be used for any user-visible display of the algorithm name. """ - return self.tr('Lock Attribute Editing') + return self.tr("Lock Attribute Editing") def group(self): """ Returns the name of the group this algorithm belongs to. This string should be localised. """ - return self.tr('Layer Management Algorithms') + return self.tr("Layer Management Algorithms") def groupId(self): """ @@ -164,10 +161,10 @@ def groupId(self): contain lowercase alphanumeric characters only and no spaces or other formatting characters. """ - return 'DSGTools: Layer Management Algorithms' + return "DSGTools: Layer Management Algorithms" def tr(self, string): - return QCoreApplication.translate('LockAttributeEditingAlgorithm', string) + return QCoreApplication.translate("LockAttributeEditingAlgorithm", string) def createInstance(self): - return LockAttributeEditingAlgorithm() \ No newline at end of file + return LockAttributeEditingAlgorithm() diff --git a/DsgTools/core/DSGToolsProcessingAlgs/Algs/LayerManagementAlgs/matchAndApplyQmlStylesToLayersAlgorithm.py b/DsgTools/core/DSGToolsProcessingAlgs/Algs/LayerManagementAlgs/matchAndApplyQmlStylesToLayersAlgorithm.py index e4ec8414b..d03de753c 100644 --- a/DsgTools/core/DSGToolsProcessingAlgs/Algs/LayerManagementAlgs/matchAndApplyQmlStylesToLayersAlgorithm.py +++ b/DsgTools/core/DSGToolsProcessingAlgs/Algs/LayerManagementAlgs/matchAndApplyQmlStylesToLayersAlgorithm.py @@ -24,45 +24,49 @@ from PyQt5.QtCore import QCoreApplication from qgis.PyQt.Qt import QVariant from qgis.PyQt.QtXml import QDomDocument -from qgis.core import (QgsProcessing, - QgsFeatureSink, - QgsProcessingAlgorithm, - QgsProcessingParameterFeatureSource, - QgsProcessingParameterFeatureSink, - QgsFeature, - QgsDataSourceUri, - QgsProcessingOutputVectorLayer, - QgsProcessingParameterVectorLayer, - QgsWkbTypes, - QgsProcessingParameterBoolean, - QgsProcessingParameterEnum, - QgsProcessingParameterNumber, - QgsProcessingParameterMultipleLayers, - QgsProcessingUtils, - QgsSpatialIndex, - QgsGeometry, - QgsProcessingParameterField, - QgsProcessingMultiStepFeedback, - QgsProcessingParameterFile, - QgsProcessingParameterExpression, - QgsProcessingException, - QgsProcessingParameterString, - QgsProcessingParameterDefinition, - QgsProcessingParameterType, - QgsProcessingParameterCrs, - QgsCoordinateTransform, - QgsProject, - QgsCoordinateReferenceSystem, - QgsField, - QgsFields, - QgsProcessingOutputMultipleLayers, - QgsProcessingParameterString) +from qgis.core import ( + QgsProcessing, + QgsFeatureSink, + QgsProcessingAlgorithm, + QgsProcessingParameterFeatureSource, + QgsProcessingParameterFeatureSink, + QgsFeature, + QgsDataSourceUri, + QgsProcessingOutputVectorLayer, + QgsProcessingParameterVectorLayer, + QgsWkbTypes, + QgsProcessingParameterBoolean, + QgsProcessingParameterEnum, + QgsProcessingParameterNumber, + QgsProcessingParameterMultipleLayers, + QgsProcessingUtils, + QgsSpatialIndex, + QgsGeometry, + QgsProcessingParameterField, + QgsProcessingMultiStepFeedback, + QgsProcessingParameterFile, + QgsProcessingParameterExpression, + QgsProcessingException, + QgsProcessingParameterString, + QgsProcessingParameterDefinition, + QgsProcessingParameterType, + QgsProcessingParameterCrs, + QgsCoordinateTransform, + QgsProject, + QgsCoordinateReferenceSystem, + QgsField, + QgsFields, + QgsProcessingOutputMultipleLayers, + QgsProcessingParameterString, +) + class MatchAndApplyQmlStylesToLayersAlgorithm(QgsProcessingAlgorithm): - INPUT_LAYERS = 'INPUT_LAYERS' - QML_FOLDER = 'QML_FOLDER' - QML_MAP = 'QML_MAP' - OUTPUT = 'OUTPUT' + INPUT_LAYERS = "INPUT_LAYERS" + QML_FOLDER = "QML_FOLDER" + QML_MAP = "QML_MAP" + OUTPUT = "OUTPUT" + def initAlgorithm(self, config): """ Parameter setting. @@ -70,33 +74,34 @@ def initAlgorithm(self, config): self.addParameter( QgsProcessingParameterMultipleLayers( self.INPUT_LAYERS, - self.tr('Input Layers'), - QgsProcessing.TypeVectorAnyGeometry + self.tr("Input Layers"), + QgsProcessing.TypeVectorAnyGeometry, ) ) self.addParameter( QgsProcessingParameterFile( self.QML_FOLDER, - self.tr('Input QML Folder'), - behavior = QgsProcessingParameterFile.Folder, - defaultValue = "/path/to/qmlFolder" + self.tr("Input QML Folder"), + behavior=QgsProcessingParameterFile.Folder, + defaultValue="/path/to/qmlFolder", ) ) self.addParameter( QgsProcessingParameterString( self.QML_MAP, - description = self.tr('QML json map (e.g., [{"camada": "...", "qml": "..."}])'), - multiLine = True, - defaultValue = '[]' + description=self.tr( + 'QML json map (e.g., [{"camada": "...", "qml": "..."}])' + ), + multiLine=True, + defaultValue="[]", ) ) self.addOutput( QgsProcessingOutputMultipleLayers( - self.OUTPUT, - self.tr('Original layers with measure column') + self.OUTPUT, self.tr("Original layers with measure column") ) ) @@ -106,22 +111,10 @@ def processAlgorithm(self, parameters, context, feedback): This process matches the layer name to the qml name. """ - inputLyrList = self.parameterAsLayerList( - parameters, - self.INPUT_LAYERS, - context - ) - inputDirectory = self.parameterAsFile( - parameters, - self.QML_FOLDER, - context - ) + inputLyrList = self.parameterAsLayerList(parameters, self.INPUT_LAYERS, context) + inputDirectory = self.parameterAsFile(parameters, self.QML_FOLDER, context) inputJSONMap = json.loads( - self.parameterAsString( - parameters, - self.QML_MAP, - context - ) + self.parameterAsString(parameters, self.QML_MAP, context) ) if os.path.exists(inputDirectory): self.loadQMlFromFolder(inputDirectory, inputLyrList, feedback) @@ -133,7 +126,7 @@ def processAlgorithm(self, parameters, context, feedback): def loadQMlFromFolder(self, inputDirectory, inputLyrList, feedback): listSize = len(inputLyrList) - progressStep = 100/listSize if listSize else 0 + progressStep = 100 / listSize if listSize else 0 qmlDict = self.buildQmlDict(inputDirectory) for current, lyr in enumerate(inputLyrList): if feedback.isCanceled(): @@ -141,37 +134,44 @@ def loadQMlFromFolder(self, inputDirectory, inputLyrList, feedback): if lyr.dataProvider().uri().table() in qmlDict: lyr.loadNamedStyle(qmlDict[lyr.dataProvider().uri().table()], True) lyr.triggerRepaint() - feedback.setProgress(current*progressStep) - + feedback.setProgress(current * progressStep) + def loadQMlFromJSONMap(self, inputJSONMap, inputLyrList, feedback): listSize = len(inputLyrList) layerNames = [item["camada"] for item in inputJSONMap] - progressStep = 100/listSize if listSize else 0 + progressStep = 100 / listSize if listSize else 0 for current, lyr in enumerate(inputLyrList): if feedback.isCanceled(): break - if lyr.dataProvider().uri().table() in layerNames and inputJSONMap[layerNames.index(lyr.dataProvider().uri().table())]["qml"]: + if ( + lyr.dataProvider().uri().table() in layerNames + and inputJSONMap[layerNames.index(lyr.dataProvider().uri().table())][ + "qml" + ] + ): doc = QDomDocument() - doc.setContent(inputJSONMap[layerNames.index(lyr.dataProvider().uri().table())]["qml"]) + doc.setContent( + inputJSONMap[layerNames.index(lyr.dataProvider().uri().table())][ + "qml" + ] + ) lyr.importNamedStyle(doc) lyr.triggerRepaint() - feedback.setProgress(current*progressStep) + feedback.setProgress(current * progressStep) - def buildQmlDict(self, inputDir): """ - Builds a dict with the format + Builds a dict with the format {'fileName':'filePath'} """ qmlDict = dict() for fileNameWithExtension in os.listdir(inputDir): - if '.qml' not in fileNameWithExtension: + if ".qml" not in fileNameWithExtension: continue - fileName = fileNameWithExtension.split('.')[0] + fileName = fileNameWithExtension.split(".")[0] qmlDict[fileName] = os.path.join(inputDir, fileNameWithExtension) return qmlDict - def name(self): """ Returns the algorithm name, used for identifying the algorithm. This @@ -180,21 +180,21 @@ def name(self): lowercase alphanumeric characters only and no spaces or other formatting characters. """ - return 'matchandapplyqmlstylestolayersalgorithm' + return "matchandapplyqmlstylestolayersalgorithm" def displayName(self): """ Returns the translated algorithm name, which should be used for any user-visible display of the algorithm name. """ - return self.tr('Match and Apply QML Styles to Layers') + return self.tr("Match and Apply QML Styles to Layers") def group(self): """ Returns the name of the group this algorithm belongs to. This string should be localised. """ - return self.tr('Layer Management Algorithms') + return self.tr("Layer Management Algorithms") def groupId(self): """ @@ -204,10 +204,12 @@ def groupId(self): contain lowercase alphanumeric characters only and no spaces or other formatting characters. """ - return 'DSGTools: Layer Management Algorithms' + return "DSGTools: Layer Management Algorithms" def tr(self, string): - return QCoreApplication.translate('MatchAndApplyQmlStylesToLayersAlgorithm', string) + return QCoreApplication.translate( + "MatchAndApplyQmlStylesToLayersAlgorithm", string + ) def createInstance(self): - return MatchAndApplyQmlStylesToLayersAlgorithm() \ No newline at end of file + return MatchAndApplyQmlStylesToLayersAlgorithm() diff --git a/DsgTools/core/DSGToolsProcessingAlgs/Algs/LayerManagementAlgs/removeEmptyLayers.py b/DsgTools/core/DSGToolsProcessingAlgs/Algs/LayerManagementAlgs/removeEmptyLayers.py index bfa37e88e..40e85015b 100644 --- a/DsgTools/core/DSGToolsProcessingAlgs/Algs/LayerManagementAlgs/removeEmptyLayers.py +++ b/DsgTools/core/DSGToolsProcessingAlgs/Algs/LayerManagementAlgs/removeEmptyLayers.py @@ -9,7 +9,7 @@ git sha : $Format:%H$ copyright : (C) 2022 by Pedro Martins - Cartographic Engineer @ Brazilian Army (C) 2022 by Philipe Borba - Cartographic Engineer @ Brazilian Army - + email : borba.philipe@eb.mil.br ***************************************************************************/ @@ -23,72 +23,71 @@ ***************************************************************************/ """ from qgis.PyQt.QtCore import QCoreApplication -from qgis.core import (QgsProcessing, - QgsProcessingAlgorithm, - QgsProject, - QgsMapLayer, - Qgis) +from qgis.core import ( + QgsProcessing, + QgsProcessingAlgorithm, + QgsProject, + QgsMapLayer, + Qgis, +) from qgis import processing from qgis.utils import iface + class RemoveEmptyLayers(QgsProcessingAlgorithm): - OUTPUT = 'OUTPUT' + OUTPUT = "OUTPUT" + def initAlgorithm(self, config=None): - 'pass' + "pass" + def processAlgorithm(self, parameters, context, feedback): outputLayers = [] listSize = len(QgsProject.instance().mapLayers()) - progressStep = 100/listSize if listSize else 0 + progressStep = 100 / listSize if listSize else 0 toBeRemoved = [] - step=0 - feedback.setProgressText(self.tr('Removing layers...')) - + step = 0 + feedback.setProgressText(self.tr("Removing layers...")) + for key, layer in QgsProject.instance().mapLayers().items(): if feedback.isCanceled(): return {self.OUTPUT: outputLayers} if layer.type() == QgsMapLayer.VectorLayer and layer.featureCount() == 0: outputLayers.append(layer.name()) toBeRemoved.append(layer.id()) - step+=1 - feedback.setProgress(step*progressStep) + step += 1 + feedback.setProgress(step * progressStep) if toBeRemoved: - QgsProject.instance().removeMapLayers( toBeRemoved ) + QgsProject.instance().removeMapLayers(toBeRemoved) iface.messageBar().pushMessage( - self.tr("Executed."), + self.tr("Executed."), self.tr("Empty layers removed."), level=Qgis.Success, - duration=5 + duration=5, ) return {self.OUTPUT: outputLayers} - + def tr(self, string): - return QCoreApplication.translate('Processing', string) + return QCoreApplication.translate("Processing", string) def createInstance(self): return RemoveEmptyLayers() def name(self): - return 'remove_empty_layers' + return "remove_empty_layers" def displayName(self): - return self.tr('Remove Empty Layers') + return self.tr("Remove Empty Layers") def group(self): - return self.tr('Layer Management Algorithms') + return self.tr("Layer Management Algorithms") def groupId(self): - return 'DSGTools: Layer Management Algorithms' + return "DSGTools: Layer Management Algorithms" def shortHelpString(self): - return self.tr("The processing algorithm removes empty layers from the project.") - - - - - - - - + return self.tr( + "The processing algorithm removes empty layers from the project." + ) diff --git a/DsgTools/core/DSGToolsProcessingAlgs/Algs/LayerManagementAlgs/sapLoadLayersAlgorithm.py b/DsgTools/core/DSGToolsProcessingAlgs/Algs/LayerManagementAlgs/sapLoadLayersAlgorithm.py index ba954e921..ce88331fe 100644 --- a/DsgTools/core/DSGToolsProcessingAlgs/Algs/LayerManagementAlgs/sapLoadLayersAlgorithm.py +++ b/DsgTools/core/DSGToolsProcessingAlgs/Algs/LayerManagementAlgs/sapLoadLayersAlgorithm.py @@ -24,157 +24,111 @@ from DsgTools.core.dsgEnums import DsgEnums from DsgTools.core.Factories.DbFactory.dbFactory import DbFactory -from DsgTools.core.Factories.LayerLoaderFactory.layerLoaderFactory import \ - LayerLoaderFactory -from qgis.core import (QgsCoordinateReferenceSystem, QgsCoordinateTransform, - QgsDataSourceUri, QgsFeature, QgsFeatureSink, QgsField, - QgsFields, QgsGeometry, QgsProcessing, - QgsProcessingAlgorithm, QgsProcessingException, - QgsProcessingMultiStepFeedback, - QgsProcessingOutputMultipleLayers, - QgsProcessingOutputVectorLayer, - QgsProcessingParameterBoolean, - QgsProcessingParameterCrs, - QgsProcessingParameterDefinition, - QgsProcessingParameterEnum, - QgsProcessingParameterExpression, - QgsProcessingParameterFeatureSink, - QgsProcessingParameterFeatureSource, - QgsProcessingParameterField, QgsProcessingParameterFile, - QgsProcessingParameterMultipleLayers, - QgsProcessingParameterNumber, - QgsProcessingParameterString, - QgsProcessingParameterType, - QgsProcessingParameterVectorLayer, QgsProcessingUtils, - QgsProject, QgsSpatialIndex, QgsWkbTypes) +from DsgTools.core.Factories.LayerLoaderFactory.layerLoaderFactory import ( + LayerLoaderFactory, +) +from qgis.core import ( + QgsCoordinateReferenceSystem, + QgsCoordinateTransform, + QgsDataSourceUri, + QgsFeature, + QgsFeatureSink, + QgsField, + QgsFields, + QgsGeometry, + QgsProcessing, + QgsProcessingAlgorithm, + QgsProcessingException, + QgsProcessingMultiStepFeedback, + QgsProcessingOutputMultipleLayers, + QgsProcessingOutputVectorLayer, + QgsProcessingParameterBoolean, + QgsProcessingParameterCrs, + QgsProcessingParameterDefinition, + QgsProcessingParameterEnum, + QgsProcessingParameterExpression, + QgsProcessingParameterFeatureSink, + QgsProcessingParameterFeatureSource, + QgsProcessingParameterField, + QgsProcessingParameterFile, + QgsProcessingParameterMultipleLayers, + QgsProcessingParameterNumber, + QgsProcessingParameterString, + QgsProcessingParameterType, + QgsProcessingParameterVectorLayer, + QgsProcessingUtils, + QgsProject, + QgsSpatialIndex, + QgsWkbTypes, +) from qgis.utils import iface + class SapLoadLayersAlgorithm(QgsProcessingAlgorithm): - HOST = 'HOST' - PORT = 'PORT' - DATABASE = 'DATABASE' - USER = 'USER' - PASSWORD = 'PASSWORD' - LAYER_LIST = 'LAYER_LIST' - LOAD_TO_CANVAS = 'LOAD_TO_CANVAS' - UNIQUE_LOAD = 'UNIQUE_LOAD' - OUTPUT = 'OUTPUT' + HOST = "HOST" + PORT = "PORT" + DATABASE = "DATABASE" + USER = "USER" + PASSWORD = "PASSWORD" + LAYER_LIST = "LAYER_LIST" + LOAD_TO_CANVAS = "LOAD_TO_CANVAS" + UNIQUE_LOAD = "UNIQUE_LOAD" + OUTPUT = "OUTPUT" + def initAlgorithm(self, config): """ Parameter setting. """ + self.addParameter(QgsProcessingParameterString(self.HOST, self.tr("Host"))) + self.addParameter(QgsProcessingParameterString(self.PORT, self.tr("Port"))) self.addParameter( - QgsProcessingParameterString( - self.HOST, - self.tr('Host') - ) - ) - self.addParameter( - QgsProcessingParameterString( - self.PORT, - self.tr('Port') - ) - ) - self.addParameter( - QgsProcessingParameterString( - self.DATABASE, - self.tr('Database') - ) - ) - self.addParameter( - QgsProcessingParameterString( - self.USER, - self.tr('User') - ) + QgsProcessingParameterString(self.DATABASE, self.tr("Database")) ) + self.addParameter(QgsProcessingParameterString(self.USER, self.tr("User"))) self.addParameter( - QgsProcessingParameterString( - self.PASSWORD, - self.tr('Password') - ) + QgsProcessingParameterString(self.PASSWORD, self.tr("Password")) ) self.addParameter( - QgsProcessingParameterString( - self.LAYER_LIST, - self.tr('Layer List') - ) + QgsProcessingParameterString(self.LAYER_LIST, self.tr("Layer List")) ) self.addParameter( QgsProcessingParameterBoolean( - self.LOAD_TO_CANVAS, - self.tr('Load layers to canvas'), - defaultValue=True + self.LOAD_TO_CANVAS, self.tr("Load layers to canvas"), defaultValue=True ) ) self.addParameter( QgsProcessingParameterBoolean( - self.UNIQUE_LOAD, - self.tr('Unique load'), - defaultValue=True + self.UNIQUE_LOAD, self.tr("Unique load"), defaultValue=True ) ) self.addOutput( - QgsProcessingOutputMultipleLayers( - self.OUTPUT, - self.tr('Loaded layers') - ) + QgsProcessingOutputMultipleLayers(self.OUTPUT, self.tr("Loaded layers")) ) def processAlgorithm(self, parameters, context, feedback): """ Here is where the processing itself takes place. """ - host = self.parameterAsString( - parameters, - self.HOST, - context - ) - port = self.parameterAsString( - parameters, - self.PORT, - context - ) - database = self.parameterAsString( - parameters, - self.DATABASE, - context - ) - user = self.parameterAsString( - parameters, - self.USER, - context - ) - password = self.parameterAsString( - parameters, - self.PASSWORD, - context - ) - layerStringList = self.parameterAsString( - parameters, - self.LAYER_LIST, - context - ) - inputParamList = layerStringList.split(',') - layerLoader = LayerLoaderFactory().makeLoader( - iface, abstractDb - ) + host = self.parameterAsString(parameters, self.HOST, context) + port = self.parameterAsString(parameters, self.PORT, context) + database = self.parameterAsString(parameters, self.DATABASE, context) + user = self.parameterAsString(parameters, self.USER, context) + password = self.parameterAsString(parameters, self.PASSWORD, context) + layerStringList = self.parameterAsString(parameters, self.LAYER_LIST, context) + inputParamList = layerStringList.split(",") + layerLoader = LayerLoaderFactory().makeLoader(iface, abstractDb) iface.mapCanvas().freeze(True) outputLayers = layerLoader.loadLayersInsideProcessing( - inputParamList, - uniqueLoad=True, - addToCanvas=True, - feedback=feedback + inputParamList, uniqueLoad=True, addToCanvas=True, feedback=feedback ) iface.mapCanvas().freeze(False) - #TODO: Resto + # TODO: Resto return {self.OUTPUT: [i.id() for i in outputLayers]} - + def getAbstractDb(self, host, port, database, user, password): abstractDb = DbFactory().createDbFactory(DsgEnums.DriverPostGIS) - abstractDb.connectDatabaseWithParameters( - host, port, database, user, password - ) + abstractDb.connectDatabaseWithParameters(host, port, database, user, password) return abstractDb def name(self): @@ -185,21 +139,21 @@ def name(self): lowercase alphanumeric characters only and no spaces or other formatting characters. """ - return 'saploadlayersalgorithm' + return "saploadlayersalgorithm" def displayName(self): """ Returns the translated algorithm name, which should be used for any user-visible display of the algorithm name. """ - return self.tr('SAP Load Layers') + return self.tr("SAP Load Layers") def group(self): """ Returns the name of the group this algorithm belongs to. This string should be localised. """ - return self.tr('Layer Management Algorithms') + return self.tr("Layer Management Algorithms") def groupId(self): """ @@ -209,10 +163,10 @@ def groupId(self): contain lowercase alphanumeric characters only and no spaces or other formatting characters. """ - return 'DSGTools: Layer Management Algorithms' + return "DSGTools: Layer Management Algorithms" def tr(self, string): - return QCoreApplication.translate('SapLoadLayersAlgorithm', string) + return QCoreApplication.translate("SapLoadLayersAlgorithm", string) def createInstance(self): return SapLoadLayersAlgorithm() diff --git a/DsgTools/core/DSGToolsProcessingAlgs/Algs/LayerManagementAlgs/setRemoveDuplicateNodePropertyOnLayers.py b/DsgTools/core/DSGToolsProcessingAlgs/Algs/LayerManagementAlgs/setRemoveDuplicateNodePropertyOnLayers.py index 2a9bc8518..99c718c69 100644 --- a/DsgTools/core/DSGToolsProcessingAlgs/Algs/LayerManagementAlgs/setRemoveDuplicateNodePropertyOnLayers.py +++ b/DsgTools/core/DSGToolsProcessingAlgs/Algs/LayerManagementAlgs/setRemoveDuplicateNodePropertyOnLayers.py @@ -21,14 +21,18 @@ ***************************************************************************/ """ from PyQt5.QtCore import QCoreApplication -from qgis.core import (QgsProcessing, - QgsProcessingAlgorithm, - QgsProcessingParameterMultipleLayers, - QgsProcessingOutputMultipleLayers) +from qgis.core import ( + QgsProcessing, + QgsProcessingAlgorithm, + QgsProcessingParameterMultipleLayers, + QgsProcessingOutputMultipleLayers, +) + class SetRemoveDuplicateNodePropertyOnLayers(QgsProcessingAlgorithm): - INPUT_LAYERS = 'INPUT_LAYERS' - OUTPUT = 'OUTPUT' + INPUT_LAYERS = "INPUT_LAYERS" + OUTPUT = "OUTPUT" + def initAlgorithm(self, config): """ Parameter setting. @@ -36,15 +40,14 @@ def initAlgorithm(self, config): self.addParameter( QgsProcessingParameterMultipleLayers( self.INPUT_LAYERS, - self.tr('Input Layers'), - QgsProcessing.TypeVectorAnyGeometry + self.tr("Input Layers"), + QgsProcessing.TypeVectorAnyGeometry, ) ) self.addOutput( QgsProcessingOutputMultipleLayers( - self.OUTPUT, - self.tr('Original layers with measure column') + self.OUTPUT, self.tr("Original layers with measure column") ) ) @@ -52,13 +55,9 @@ def processAlgorithm(self, parameters, context, feedback): """ Here is where the processing itself takes place. """ - inputLyrList = self.parameterAsLayerList( - parameters, - self.INPUT_LAYERS, - context - ) + inputLyrList = self.parameterAsLayerList(parameters, self.INPUT_LAYERS, context) listSize = len(inputLyrList) - stepSize = 100/listSize if listSize else 0 + stepSize = 100 / listSize if listSize else 0 for current, lyr in enumerate(inputLyrList): if feedback.isCanceled(): break @@ -75,21 +74,21 @@ def name(self): lowercase alphanumeric characters only and no spaces or other formatting characters. """ - return 'setremoveduplicatenodepropertyonlayers' + return "setremoveduplicatenodepropertyonlayers" def displayName(self): """ Returns the translated algorithm name, which should be used for any user-visible display of the algorithm name. """ - return self.tr('Set Remove Duplicate Node Property On Layers') + return self.tr("Set Remove Duplicate Node Property On Layers") def group(self): """ Returns the name of the group this algorithm belongs to. This string should be localised. """ - return self.tr('Layer Management Algorithms') + return self.tr("Layer Management Algorithms") def groupId(self): """ @@ -99,10 +98,12 @@ def groupId(self): contain lowercase alphanumeric characters only and no spaces or other formatting characters. """ - return 'DSGTools: Layer Management Algorithms' + return "DSGTools: Layer Management Algorithms" def tr(self, string): - return QCoreApplication.translate('SetRemoveDuplicateNodePropertyOnLayers', string) + return QCoreApplication.translate( + "SetRemoveDuplicateNodePropertyOnLayers", string + ) def createInstance(self): return SetRemoveDuplicateNodePropertyOnLayers() diff --git a/DsgTools/core/DSGToolsProcessingAlgs/Algs/LayerManagementAlgs/spellChecker/datasets/ptBR.py b/DsgTools/core/DSGToolsProcessingAlgs/Algs/LayerManagementAlgs/spellChecker/datasets/ptBR.py index 2baaf57b3..a3dc4c356 100644 --- a/DsgTools/core/DSGToolsProcessingAlgs/Algs/LayerManagementAlgs/spellChecker/datasets/ptBR.py +++ b/DsgTools/core/DSGToolsProcessingAlgs/Algs/LayerManagementAlgs/spellChecker/datasets/ptBR.py @@ -3,57 +3,61 @@ import pickle import os from ..structures.ternarySearchTree import Trie, Node -from DsgTools.core.NetworkTools.ExternalFilesHandler import ExternalFileHandlerConfig, ExternalFileDownloadProcessor +from DsgTools.core.NetworkTools.ExternalFilesHandler import ( + ExternalFileHandlerConfig, + ExternalFileDownloadProcessor, +) WORLIST_FILE_PATH = os.path.join( - os.path.abspath(os.path.dirname(__file__)), - '..', - 'data', - 'wordDatasetPtBR.pbz2' + os.path.abspath(os.path.dirname(__file__)), "..", "data", "wordDatasetPtBR.pbz2" ) + @dataclass class WordDatasetPtBRFileConfig(ExternalFileHandlerConfig): - url = 'https://github.com/dsgoficial/external_files_plugins/releases/download/spell_checker_files/wordDatasetPtBR.pbz2' - file_name = 'wordDatasetPtBR.pbz2' + url = "https://github.com/dsgoficial/external_files_plugins/releases/download/spell_checker_files/wordDatasetPtBR.pbz2" + file_name = "wordDatasetPtBR.pbz2" output_folder = os.path.join( os.path.abspath(os.path.dirname(__file__)), - '..', - 'data', + "..", + "data", ) + @dataclass class PalavrasFileConfig(ExternalFileHandlerConfig): - url = 'https://github.com/dsgoficial/external_files_plugins/releases/download/spell_checker_files/palavras.txt' - file_name = 'palavras.txt' + url = "https://github.com/dsgoficial/external_files_plugins/releases/download/spell_checker_files/palavras.txt" + file_name = "palavras.txt" output_folder = os.path.join( os.path.abspath(os.path.dirname(__file__)), - '..', - 'data', + "..", + "data", ) + class CustomUnpickler(pickle.Unpickler): def find_class(self, module, name): - if name == 'Trie': + if name == "Trie": return Trie - if name == 'Node': + if name == "Node": return Node return super().find_class(module, name) + class PtBR: def __init__(self): if not os.path.exists(WORLIST_FILE_PATH): - raise Exception('Word list file not found.') + raise Exception("Word list file not found.") self.trie = self.decompress_pickle(WORLIST_FILE_PATH) def compressed_pickle(self, filePath, data): - with bz2.BZ2File(filePath, 'w') as f: + with bz2.BZ2File(filePath, "w") as f: pickle.dump(data, f) def decompress_pickle(self, filePath): - data = bz2.BZ2File(filePath, 'rb') + data = bz2.BZ2File(filePath, "rb") data = CustomUnpickler(data).load() return data def hasWord(self, word): - return word in self.trie \ No newline at end of file + return word in self.trie diff --git a/DsgTools/core/DSGToolsProcessingAlgs/Algs/LayerManagementAlgs/spellChecker/factories/datasetFactory.py b/DsgTools/core/DSGToolsProcessingAlgs/Algs/LayerManagementAlgs/spellChecker/factories/datasetFactory.py index 5ece6d34a..8394ba739 100644 --- a/DsgTools/core/DSGToolsProcessingAlgs/Algs/LayerManagementAlgs/spellChecker/factories/datasetFactory.py +++ b/DsgTools/core/DSGToolsProcessingAlgs/Algs/LayerManagementAlgs/spellChecker/factories/datasetFactory.py @@ -1,10 +1,8 @@ -from ..datasets.ptBR import PtBR +from ..datasets.ptBR import PtBR from ..structures.ternarySearchTree import Trie -class DatasetFactory: +class DatasetFactory: def getDataset(self, dataset): - methods = { - 'pt-BR': PtBR - } - return methods[dataset]() \ No newline at end of file + methods = {"pt-BR": PtBR} + return methods[dataset]() diff --git a/DsgTools/core/DSGToolsProcessingAlgs/Algs/LayerManagementAlgs/spellChecker/spellCheckerCtrl.py b/DsgTools/core/DSGToolsProcessingAlgs/Algs/LayerManagementAlgs/spellChecker/spellCheckerCtrl.py index a6ff5d630..08003c0c1 100644 --- a/DsgTools/core/DSGToolsProcessingAlgs/Algs/LayerManagementAlgs/spellChecker/spellCheckerCtrl.py +++ b/DsgTools/core/DSGToolsProcessingAlgs/Algs/LayerManagementAlgs/spellChecker/spellCheckerCtrl.py @@ -1,10 +1,12 @@ -from .factories.datasetFactory import DatasetFactory +from .factories.datasetFactory import DatasetFactory -class SpellCheckerCtrl: +class SpellCheckerCtrl: def __init__(self, dataset, datasetFactory=None, **kwargs): - self.datasetFactory = DatasetFactory() if datasetFactory is None else datasetFactory + self.datasetFactory = ( + DatasetFactory() if datasetFactory is None else datasetFactory + ) self.dataset = DatasetFactory().getDataset(dataset, **kwargs) def hasWord(self, word): - return self.dataset.hasWord(word) \ No newline at end of file + return self.dataset.hasWord(word) diff --git a/DsgTools/core/DSGToolsProcessingAlgs/Algs/LayerManagementAlgs/spellChecker/structures/ternarySearchTree.py b/DsgTools/core/DSGToolsProcessingAlgs/Algs/LayerManagementAlgs/spellChecker/structures/ternarySearchTree.py index 0070589c5..a2f382c82 100644 --- a/DsgTools/core/DSGToolsProcessingAlgs/Algs/LayerManagementAlgs/spellChecker/structures/ternarySearchTree.py +++ b/DsgTools/core/DSGToolsProcessingAlgs/Algs/LayerManagementAlgs/spellChecker/structures/ternarySearchTree.py @@ -1,37 +1,46 @@ - """ A ternary search tree implementation, inspired by: -http://www.drdobbs.com/database/ternary-search-trees/184410528 and +http://www.drdobbs.com/database/ternary-search-trees/184410528 and https://lukaszwrobel.pl/blog/ternary-search-tree/ https://github.com/djtrack16/tst/blob/master/ternarysearchtree.py """ + class Node: lo = None hi = None eq = None endpoint = False + def __init__(self, char): self.char = char + def __repr__(self): # useful in debugging - return ''.join(['[', self.char, - ('' if not self.endpoint else ' '), - ('' if self.lo is None else ' lo: ' + self.lo.__repr__()), - ('' if self.eq is None else ' eq: ' + self.eq.__repr__()), - ('' if self.hi is None else ' hi: ' + self.hi.__repr__()), ']']) + return "".join( + [ + "[", + self.char, + ("" if not self.endpoint else " "), + ("" if self.lo is None else " lo: " + self.lo.__repr__()), + ("" if self.eq is None else " eq: " + self.eq.__repr__()), + ("" if self.hi is None else " hi: " + self.hi.__repr__()), + "]", + ] + ) + def insert(node, string): if len(string) == 0: return node - + head = string[0] tail = string[1:] if node is None: node = Node(head) - + if head < node.char: node.lo = insert(node.lo, string) elif head > node.char: @@ -41,9 +50,10 @@ def insert(node, string): node.endpoint = True else: node.eq = insert(node.eq, tail) - + return node + def search(node, string): if node is None or len(string) == 0: return False @@ -61,6 +71,7 @@ def search(node, string): return True return search(node.eq, tail) + def suffixes(node): if node is not None: if node.endpoint: @@ -75,7 +86,8 @@ def suffixes(node): if node.eq: for s in suffixes(node.eq): yield node.char + s - + + def autocompletes(node, string): if node is None or len(string) == 0: return [] @@ -93,14 +105,19 @@ def autocompletes(node, string): return suffixes(node.eq) return autocompletes(node.eq, string[1:]) + class Trie: # a simple wrapper root = None + def __init__(self, string): self.append(string) + def append(self, string): self.root = insert(self.root, string) + def __contains__(self, string): return search(self.root, string) + def autocomplete(self, string): - return map(lambda x: string + x, autocompletes(self.root, string)) \ No newline at end of file + return map(lambda x: string + x, autocompletes(self.root, string)) diff --git a/DsgTools/core/DSGToolsProcessingAlgs/Algs/LayerManagementAlgs/spellCheckerAlgorithm.py b/DsgTools/core/DSGToolsProcessingAlgs/Algs/LayerManagementAlgs/spellCheckerAlgorithm.py deleted file mode 100644 index 6639006cf..000000000 --- a/DsgTools/core/DSGToolsProcessingAlgs/Algs/LayerManagementAlgs/spellCheckerAlgorithm.py +++ /dev/null @@ -1,157 +0,0 @@ -import re - -from PyQt5.QtCore import QCoreApplication -from qgis import core -from qgis.core import (QgsFeature, QgsField, QgsFields, QgsProcessing, - QgsProcessingAlgorithm, QgsProcessingParameterField, - QgsProcessingParameterFeatureSink, - QgsProcessingParameterVectorLayer, QgsWkbTypes, QgsProcessingException,) -from qgis.PyQt.Qt import QVariant - -from .spellChecker.spellCheckerCtrl import SpellCheckerCtrl - -class SpellCheckerAlgorithm(QgsProcessingAlgorithm): - - INPUT_LAYER = 'INPUT_LAYER' - ATTRIBUTE_NAME = 'ATTRIBUTE_NAME' - PRIMARY_KEY_FIELD = 'PRIMARY_KEY_FIELD' - OUTPUT = 'OUTPUT' - - def __init__(self): - super(SpellCheckerAlgorithm, self).__init__() - - def initAlgorithm(self, config): - self.addParameter( - QgsProcessingParameterVectorLayer( - self.INPUT_LAYER, - self.tr('Layer'), - [QgsProcessing.TypeVectorAnyGeometry] - ) - ) - - self.addParameter( - QgsProcessingParameterField( - self.ATTRIBUTE_NAME, - self.tr('Attribute name'), - type=QgsProcessingParameterField.String, - parentLayerParameterName=self.INPUT_LAYER, - allowMultiple=False, - defaultValue='nome') - ) - - self.addParameter( - QgsProcessingParameterField( - self.PRIMARY_KEY_FIELD, - self.tr('Primary key field'), - type=QgsProcessingParameterField.Any, - parentLayerParameterName=self.INPUT_LAYER, - allowMultiple=False, - defaultValue='id') - ) - - self.addParameter( - QgsProcessingParameterFeatureSink( - self.OUTPUT, - self.tr('Flags') - ) - ) - - def processAlgorithm(self, parameters, context, feedback): - layer = self.parameterAsVectorLayer( - parameters, - self.INPUT_LAYER, - context - ) - attributeName = self.parameterAsFields( - parameters, - self.ATTRIBUTE_NAME, - context - )[0] - pkField = self.parameterAsFields( - parameters, - self.PRIMARY_KEY_FIELD, - context - )[0] - - try: - spellchecker = SpellCheckerCtrl('pt-BR') - except: - raise QgsProcessingException(self.tr('Error loading spellchecker files. Please go to the DSGTools menu and run "Download external data".')) - - errorFieldName = '{}_erro'.format(attributeName) - - layer.startEditing() - attributeIndex = self.getAttributeIndex(attributeName, layer) - if attributeIndex < 0: - return {self.OUTPUT: 'Attribute index not found'} - fieldRelation = layer.fields().field(pkField) - auxLayer = core.QgsAuxiliaryStorage().createAuxiliaryLayer(fieldRelation, layer) - vdef = core.QgsPropertyDefinition( - errorFieldName, - core.QgsPropertyDefinition.DataType.DataTypeString, - "", - "", - "" - ) - auxLayer.addAuxiliaryField(vdef) - layer.setAuxiliaryLayer(auxLayer) - idx = layer.fields().indexOf('auxiliary_storage__{}'.format(errorFieldName)) - layer.setFieldAlias(idx, errorFieldName) - auxFields = auxLayer.fields() - for feature in layer.getFeatures(): - if feedback.isCanceled(): - return {self.OUTPUT: ''} - attributeValue = feature[attributeIndex] - if not attributeValue: - continue - attributeValue = ''.join(e for e in attributeValue if not(e in [',', ';', '&', '.'] or e.isdigit())) - wordlist = re.split(' |/', attributeValue) - wordlist = [ w for w in wordlist if not w in ['-'] ] - wrongWords = [ word for word in wordlist if not spellchecker.hasWord(word.lower())] - if len(wrongWords) == 0: - continue - auxFeature = QgsFeature(auxFields) - auxFeature['ASPK'] = feature[pkField] - auxFeature['_{}'.format(errorFieldName)] = ';'.join(wrongWords) - auxLayer.addFeature(auxFeature) - returnMessage = 'Field {} added/edited'.format(errorFieldName) - return {self.OUTPUT: returnMessage} - - def getAttributeIndex(self, attributeName, layer): - if not layer.fields().indexOf(attributeName) < 0: - return layer.fields().indexOf(attributeName) - for attrName, attrAlias in list(layer.attributeAliases().items()): - if not(attributeName in [attrName, attrAlias]): - continue - if layer.fields().indexOf(attrName) < 0: - return layer.fields().indexOf(attrAlias) - return layer.fields().indexOf(attrName) - return -1 - - def getFlagWkbType(self): - return QgsWkbTypes.Point - - def getFlagFields(self): - sinkFields = QgsFields() - sinkFields.append(QgsField('erro', QVariant.String)) - sinkFields.append(QgsField('correcao', QVariant.String)) - sinkFields.append(QgsField('outras_opcoes', QVariant.String)) - return sinkFields - - def name(self): - return 'spellchecker' - - def displayName(self): - return self.tr('Spell check') - - def group(self): - return self.tr('Layer Management Algorithms') - - def groupId(self): - return 'DSGTools: Layer Management Algorithms' - - def tr(self, string): - return QCoreApplication.translate('SpellCheckerAlgorithm', string) - - def createInstance(self): - return SpellCheckerAlgorithm() diff --git a/DsgTools/core/DSGToolsProcessingAlgs/Algs/OtherAlgs/batchRunAlgorithm.py b/DsgTools/core/DSGToolsProcessingAlgs/Algs/OtherAlgs/batchRunAlgorithm.py index 19f66a0ad..b6e817ace 100644 --- a/DsgTools/core/DSGToolsProcessingAlgs/Algs/OtherAlgs/batchRunAlgorithm.py +++ b/DsgTools/core/DSGToolsProcessingAlgs/Algs/OtherAlgs/batchRunAlgorithm.py @@ -24,48 +24,47 @@ from DsgTools.core.DSGToolsProcessingAlgs.algRunner import AlgRunner from qgis.PyQt.QtCore import QVariant import json, processing -from qgis.core import (QgsProcessing, - QgsFeatureSink, - QgsProcessingAlgorithm, - QgsProcessingParameterFeatureSource, - QgsProcessingParameterFeatureSink, - QgsFeature, - QgsDataSourceUri, - QgsProcessingOutputVectorLayer, - QgsProcessingParameterVectorLayer, - QgsProcessingParameterString, - QgsWkbTypes, - QgsProcessingParameterBoolean, - QgsProcessingParameterMultipleLayers, - QgsWkbTypes, - QgsProcessingUtils, - QgsProject, - QgsProcessingParameterEnum, - QgsProcessingParameterFile, - QgsVectorLayerUtils, - QgsProcessingMultiStepFeedback, - QgsFields, - QgsField) +from qgis.core import ( + QgsProcessing, + QgsFeatureSink, + QgsProcessingAlgorithm, + QgsProcessingParameterFeatureSource, + QgsProcessingParameterFeatureSink, + QgsFeature, + QgsDataSourceUri, + QgsProcessingOutputVectorLayer, + QgsProcessingParameterVectorLayer, + QgsProcessingParameterString, + QgsWkbTypes, + QgsProcessingParameterBoolean, + QgsProcessingParameterMultipleLayers, + QgsWkbTypes, + QgsProcessingUtils, + QgsProject, + QgsProcessingParameterEnum, + QgsProcessingParameterFile, + QgsVectorLayerUtils, + QgsProcessingMultiStepFeedback, + QgsFields, + QgsField, +) + class BatchRunAlgorithm(QgsProcessingAlgorithm): - INPUTLAYERS = 'INPUTLAYERS' - INPUT_LAYER_PARAMETER_NAME = 'INPUT_LAYER_PARAMETER_NAME' - ALG_NAME = 'ALG_NAME' - PARAMETER_DICT = 'PARAMETER_DICT' - OUTPUT_LAYER_PARAMETER_NAME = 'OUTPUT_LAYER_PARAMETER_NAME' - OUTPUT = 'OUTPUT' + INPUTLAYERS = "INPUTLAYERS" + INPUT_LAYER_PARAMETER_NAME = "INPUT_LAYER_PARAMETER_NAME" + ALG_NAME = "ALG_NAME" + PARAMETER_DICT = "PARAMETER_DICT" + OUTPUT_LAYER_PARAMETER_NAME = "OUTPUT_LAYER_PARAMETER_NAME" + OUTPUT = "OUTPUT" def __init__(self): super(BatchRunAlgorithm, self).__init__() self.flagSink = None self.flag_id = None self.flagFields = QgsFields() - self.flagFields.append( - QgsField('alg_name',QVariant.String) - ) - self.flagFields.append( - QgsField('layer_name',QVariant.String) - ) + self.flagFields.append(QgsField("alg_name", QVariant.String)) + self.flagFields.append(QgsField("layer_name", QVariant.String)) def initAlgorithm(self, config=None): """ @@ -73,80 +72,64 @@ def initAlgorithm(self, config=None): """ self.addParameter( QgsProcessingParameterString( - self.INPUTLAYERS, - self.tr('Comma separated Input Layer Names') + self.INPUTLAYERS, self.tr("Comma separated Input Layer Names") ) ) self.addParameter( QgsProcessingParameterString( - self.ALG_NAME, - self.tr('Name of the algorithm with provider') + self.ALG_NAME, self.tr("Name of the algorithm with provider") ) ) self.addParameter( QgsProcessingParameterString( - self.INPUT_LAYER_PARAMETER_NAME, - self.tr('Name of the key of the input') + self.INPUT_LAYER_PARAMETER_NAME, self.tr("Name of the key of the input") ) ) self.addParameter( QgsProcessingParameterString( self.PARAMETER_DICT, - description = self.tr('Json parameter dict'), - multiLine = True, - defaultValue = '{}' + description=self.tr("Json parameter dict"), + multiLine=True, + defaultValue="{}", ) ) self.addParameter( QgsProcessingParameterString( self.OUTPUT_LAYER_PARAMETER_NAME, - self.tr('Output layer parameter name'), - defaultValue = 'FLAGS', - optional=True + self.tr("Output layer parameter name"), + defaultValue="FLAGS", + optional=True, ) ) self.addParameter( - QgsProcessingParameterFeatureSink( - self.OUTPUT, - self.tr('Batch run output') - ) + QgsProcessingParameterFeatureSink(self.OUTPUT, self.tr("Batch run output")) ) def processAlgorithm(self, parameters, context, feedback): """ Here is where the processing itself takes place. """ - layerCsv = self.parameterAsString( - parameters, - self.INPUTLAYERS, - context - ) - algParameterDict = self.loadAlgorithmParametersDict(parameters, context, feedback) - algName = self.parameterAsString( - parameters, - self.ALG_NAME, - context + layerCsv = self.parameterAsString(parameters, self.INPUTLAYERS, context) + algParameterDict = self.loadAlgorithmParametersDict( + parameters, context, feedback ) + algName = self.parameterAsString(parameters, self.ALG_NAME, context) inputKey = self.parameterAsString( - parameters, - self.INPUT_LAYER_PARAMETER_NAME, - context + parameters, self.INPUT_LAYER_PARAMETER_NAME, context ) outputKey = self.parameterAsString( - parameters, - self.OUTPUT_LAYER_PARAMETER_NAME, - context + parameters, self.OUTPUT_LAYER_PARAMETER_NAME, context ) - layerNameList = layerCsv.split(',') + layerNameList = layerCsv.split(",") nSteps = len(layerNameList) if not nSteps: _, flag_id = self.parameterAsSink( - parameters, + parameters, self.OUTPUT, context, self.flagFields, QgsWkbTypes.Point, - QgsProject.instance().crs() + QgsProject.instance().crs(), ) return {"OUTPUT": flag_id} layerList = AlgRunner().runStringCsvToLayerList(layerCsv, context) @@ -158,77 +141,63 @@ def processAlgorithm(self, parameters, context, feedback): multiStepFeedback.setCurrentStep(idx) multiStepFeedback.pushInfo( self.tr( - 'Step {idx}/{total}: Running algorithm {algName} on {layerName}' - ).format( - idx=idx, - total=nSteps, - algName=algName, - layerName=layerName - ) + "Step {idx}/{total}: Running algorithm {algName} on {layerName}" + ).format(idx=idx, total=nSteps, algName=algName, layerName=layerName) ) if layer is None: multiStepFeedback.pushInfo( - self.tr( - 'Layer {layerName} not found. Skipping step.' - ).format(layerName=layerName) + self.tr("Layer {layerName} not found. Skipping step.").format( + layerName=layerName + ) ) continue - currentDict = dict(algParameterDict) #copy of the dict + currentDict = dict(algParameterDict) # copy of the dict currentDict[inputKey] = layerName output = self.runProcessingAlg( algName, outputKey, currentDict, context=context, - feedback=multiStepFeedback + feedback=multiStepFeedback, + ) + outputLyr = ( + QgsProcessingUtils.mapLayerFromString(output, context) + if isinstance(output, str) + else output ) - outputLyr = QgsProcessingUtils.mapLayerFromString(output, context) if isinstance(output, str) else output if outputLyr is None: continue if self.flagSink is None: - self.prepareFlagSink( - parameters, - outputLyr, - context - ) + self.prepareFlagSink(parameters, outputLyr, context) self.flagFeatures(outputLyr, algName, layerName, context) if self.flag_id is None: _, self.flag_id = self.parameterAsSink( - parameters, + parameters, self.OUTPUT, context, self.flagFields, QgsWkbTypes.Point, - QgsProject.instance().crs() + QgsProject.instance().crs(), ) - return { self.OUTPUT : self.flag_id} - + return {self.OUTPUT: self.flag_id} + def loadAlgorithmParametersDict(self, parameters, context, feedback): - rules_text = self.parameterAsString( - parameters, - self.PARAMETER_DICT, - context - ) + rules_text = self.parameterAsString(parameters, self.PARAMETER_DICT, context) feedback.pushInfo(rules_text) return json.loads(rules_text) - + def runProcessingAlg(self, algName, outputKey, parameters, context, feedback): - output = processing.run( - algName, - parameters, - context=context, - feedback=feedback - ) + output = processing.run(algName, parameters, context=context, feedback=feedback) return output[outputKey] if outputKey else None - + def flagFeatures(self, outputLyr, algName, inputLyrName, context): for feat in outputLyr.getFeatures(): newFeat = QgsFeature(self.flagFields) for field in feat.fields(): - newFeat[field.name()]=feat[field.name()] - newFeat['alg_name'] = algName - newFeat['layer_name'] = inputLyrName + newFeat[field.name()] = feat[field.name()] + newFeat["alg_name"] = algName + newFeat["layer_name"] = inputLyrName newFeat.setGeometry(feat.geometry()) self.flagSink.addFeature(newFeat, QgsFeatureSink.FastInsert) @@ -241,35 +210,30 @@ def prepareFlagSink(self, parameters, flagSource, context): context, self.flagFields, flagSource.wkbType(), - flagSource.sourceCrs() + flagSource.sourceCrs(), ) if self.flagSink is None: - raise QgsProcessingException( - self.invalidSinkError( - parameters, - self.OUTPUT - ) - ) + raise QgsProcessingException(self.invalidSinkError(parameters, self.OUTPUT)) def name(self): """ Here is where the processing itself takes place. """ - return 'batchrunalgorithm' + return "batchrunalgorithm" def displayName(self): """ Returns the translated algorithm name, which should be used for any user-visible display of the algorithm name. """ - return self.tr('Batch Run Algorithm') + return self.tr("Batch Run Algorithm") def group(self): """ Returns the name of the group this algorithm belongs to. This string should be localised. """ - return self.tr('Other Algorithms') + return self.tr("Other Algorithms") def groupId(self): """ @@ -279,10 +243,10 @@ def groupId(self): contain lowercase alphanumeric characters only and no spaces or other formatting characters. """ - return 'DSGTools: Other Algorithms' + return "DSGTools: Other Algorithms" def tr(self, string): - return QCoreApplication.translate('BatchRunAlgorithm', string) + return QCoreApplication.translate("BatchRunAlgorithm", string) def createInstance(self): return BatchRunAlgorithm() diff --git a/DsgTools/core/DSGToolsProcessingAlgs/Algs/OtherAlgs/convertLayer2LayerAlgorithm.py b/DsgTools/core/DSGToolsProcessingAlgs/Algs/OtherAlgs/convertLayer2LayerAlgorithm.py index cec6fba2c..b9c4ababd 100644 --- a/DsgTools/core/DSGToolsProcessingAlgs/Algs/OtherAlgs/convertLayer2LayerAlgorithm.py +++ b/DsgTools/core/DSGToolsProcessingAlgs/Algs/OtherAlgs/convertLayer2LayerAlgorithm.py @@ -24,37 +24,40 @@ from ...algRunner import AlgRunner import processing from PyQt5.QtCore import QCoreApplication -from qgis.core import (QgsProcessing, - QgsFeatureSink, - QgsProcessingAlgorithm, - QgsProcessingParameterFeatureSource, - QgsProcessingParameterFeatureSink, - QgsFeature, - QgsDataSourceUri, - QgsProcessingOutputVectorLayer, - QgsProcessingParameterVectorLayer, - QgsWkbTypes, - QgsProcessingParameterBoolean, - QgsProcessingParameterEnum, - QgsProcessingParameterNumber, - QgsProcessingParameterMultipleLayers, - QgsProcessingUtils, - QgsSpatialIndex, - QgsGeometry, - QgsProcessingParameterField, - QgsProcessingMultiStepFeedback, - QgsProcessingParameterFile, - QgsProcessingParameterExpression, - QgsProcessingException) +from qgis.core import ( + QgsProcessing, + QgsFeatureSink, + QgsProcessingAlgorithm, + QgsProcessingParameterFeatureSource, + QgsProcessingParameterFeatureSink, + QgsFeature, + QgsDataSourceUri, + QgsProcessingOutputVectorLayer, + QgsProcessingParameterVectorLayer, + QgsWkbTypes, + QgsProcessingParameterBoolean, + QgsProcessingParameterEnum, + QgsProcessingParameterNumber, + QgsProcessingParameterMultipleLayers, + QgsProcessingUtils, + QgsSpatialIndex, + QgsGeometry, + QgsProcessingParameterField, + QgsProcessingMultiStepFeedback, + QgsProcessingParameterFile, + QgsProcessingParameterExpression, + QgsProcessingException, +) + class ConvertLayer2LayerAlgorithm(QgsProcessingAlgorithm): - INPUT = 'INPUT' - INPUT_FILTER_EXPRESSION = 'INPUT_FILTER_EXPRESSION' - FILTER_LAYER = 'FILTER_LAYER' - FL_FILTER_EXPRESSION = 'FL_FILTER_EXPRESSION' - BEHAVIOR = 'BEHAVIOR' - OUTPUT = 'OUTPUT' - CONVERSION_MAP = 'CONVERSION_MAP' + INPUT = "INPUT" + INPUT_FILTER_EXPRESSION = "INPUT_FILTER_EXPRESSION" + FILTER_LAYER = "FILTER_LAYER" + FL_FILTER_EXPRESSION = "FL_FILTER_EXPRESSION" + BEHAVIOR = "BEHAVIOR" + OUTPUT = "OUTPUT" + CONVERSION_MAP = "CONVERSION_MAP" def initAlgorithm(self, config): """ @@ -63,125 +66,102 @@ def initAlgorithm(self, config): self.addParameter( QgsProcessingParameterVectorLayer( self.INPUT, - self.tr('Input layer'), - [QgsProcessing.TypeVectorAnyGeometry] + self.tr("Input layer"), + [QgsProcessing.TypeVectorAnyGeometry], ) ) self.addParameter( QgsProcessingParameterExpression( self.INPUT_FILTER_EXPRESSION, - description = self.tr('Input layer expression'), - parentLayerParameterName = self.INPUT, - optional = True + description=self.tr("Input layer expression"), + parentLayerParameterName=self.INPUT, + optional=True, ) ) self.addParameter( QgsProcessingParameterVectorLayer( self.FILTER_LAYER, - self.tr('Filter layer'), + self.tr("Filter layer"), [QgsProcessing.TypeVectorPolygon], - optional = True + optional=True, ) ) self.addParameter( QgsProcessingParameterExpression( self.FL_FILTER_EXPRESSION, - description = self.tr('Filter layer expression'), - parentLayerParameterName = self.FILTER_LAYER, - optional = True + description=self.tr("Filter layer expression"), + parentLayerParameterName=self.FILTER_LAYER, + optional=True, ) ) - self.modes = [self.tr('Select a spatial filtering option...'), - self.tr('Only features from input that intersect features from filter layer'), - self.tr('Clip features from input with features from filter layer and take inside features'), - self.tr('Clip features from input with features from buffer of filter layer and take inside features') - ] + self.modes = [ + self.tr("Select a spatial filtering option..."), + self.tr( + "Only features from input that intersect features from filter layer" + ), + self.tr( + "Clip features from input with features from filter layer and take inside features" + ), + self.tr( + "Clip features from input with features from buffer of filter layer and take inside features" + ), + ] self.addParameter( QgsProcessingParameterEnum( - self.BEHAVIOR, - self.tr('Behavior'), - options=self.modes, - optional = True + self.BEHAVIOR, self.tr("Behavior"), options=self.modes, optional=True ) ) self.addParameter( QgsProcessingParameterFile( self.CONVERSION_MAP, - description = self.tr('JSON Map'), - extension = '.json', - optional = True + description=self.tr("JSON Map"), + extension=".json", + optional=True, ) ) self.addParameter( QgsProcessingParameterVectorLayer( self.OUTPUT, - self.tr('Output layer'), - [QgsProcessing.TypeVectorAnyGeometry] + self.tr("Output layer"), + [QgsProcessing.TypeVectorAnyGeometry], ) ) - def processAlgorithm(self, parameters, context, feedback): """ Here is where the processing itself takes place. """ layerHandler = LayerHandler() - inputLyr = self.parameterAsVectorLayer( - parameters, - self.INPUT, - context - ) + inputLyr = self.parameterAsVectorLayer(parameters, self.INPUT, context) if inputLyr is None: raise QgsProcessingException( - self.invalidSourceError( - parameters, - self.INPUT - ) - ) - outputLyr = self.parameterAsVectorLayer( - parameters, - self.OUTPUT, - context + self.invalidSourceError(parameters, self.INPUT) ) + outputLyr = self.parameterAsVectorLayer(parameters, self.OUTPUT, context) if outputLyr is None: raise QgsProcessingException( - self.invalidSourceError( - parameters, - self.OUTPUT - ) - ) + self.invalidSourceError(parameters, self.OUTPUT) + ) if inputLyr == outputLyr: raise QgsProcessingException( - self.tr('Input must be different from output!') - ) - inputExpression = self.parameterAsExpression( - parameters, - self.INPUT_FILTER_EXPRESSION, - context - ) - filterLyr = self.parameterAsVectorLayer( - parameters, - self.FILTER_LAYER, - context + self.tr("Input must be different from output!") ) - behavior = self.parameterAsEnum( - parameters, - self.BEHAVIOR, - context - ) - + inputExpression = self.parameterAsExpression( + parameters, self.INPUT_FILTER_EXPRESSION, context + ) + filterLyr = self.parameterAsVectorLayer(parameters, self.FILTER_LAYER, context) + behavior = self.parameterAsEnum(parameters, self.BEHAVIOR, context) + prepairedLyr = layerHandler.prepareConversion( inputLyr=inputLyr, context=context, inputExpression=inputExpression, filterLyr=filterLyr, behavior=behavior, - feedback=feedback + feedback=feedback, ) - - return {self.INPUT: inputLyr} def name(self): @@ -192,21 +172,21 @@ def name(self): lowercase alphanumeric characters only and no spaces or other formatting characters. """ - return 'convertlayer2layer' + return "convertlayer2layer" def displayName(self): """ Returns the translated algorithm name, which should be used for any user-visible display of the algorithm name. """ - return self.tr('Convert layer to layer') + return self.tr("Convert layer to layer") def group(self): """ Returns the name of the group this algorithm belongs to. This string should be localised. """ - return self.tr('Other Algorithms') + return self.tr("Other Algorithms") def groupId(self): """ @@ -214,10 +194,10 @@ def groupId(self): string should be fixed for the algorithm, and must not be localised. The group id should be unique within each provider. """ - return 'DSGTools: Other Algorithms' + return "DSGTools: Other Algorithms" def tr(self, string): - return QCoreApplication.translate('ConvertLayer2LayerAlgorithm', string) + return QCoreApplication.translate("ConvertLayer2LayerAlgorithm", string) def createInstance(self): - return ConvertLayer2LayerAlgorithm() \ No newline at end of file + return ConvertLayer2LayerAlgorithm() diff --git a/DsgTools/core/DSGToolsProcessingAlgs/Algs/OtherAlgs/createFrameAlgorithm.py b/DsgTools/core/DSGToolsProcessingAlgs/Algs/OtherAlgs/createFrameAlgorithm.py index c50bbf98c..069a93145 100644 --- a/DsgTools/core/DSGToolsProcessingAlgs/Algs/OtherAlgs/createFrameAlgorithm.py +++ b/DsgTools/core/DSGToolsProcessingAlgs/Algs/OtherAlgs/createFrameAlgorithm.py @@ -27,125 +27,114 @@ from time import sleep from qgis.PyQt.Qt import QVariant from PyQt5.QtCore import QCoreApplication -from qgis.core import (QgsProcessing, - QgsFeatureSink, - QgsProcessingAlgorithm, - QgsProcessingParameterFeatureSource, - QgsProcessingParameterFeatureSink, - QgsFeature, - QgsDataSourceUri, - QgsProcessingOutputVectorLayer, - QgsProcessingParameterVectorLayer, - QgsWkbTypes, - QgsProcessingParameterBoolean, - QgsProcessingParameterEnum, - QgsProcessingParameterNumber, - QgsProcessingParameterMultipleLayers, - QgsProcessingUtils, - QgsSpatialIndex, - QgsGeometry, - QgsProcessingParameterField, - QgsProcessingMultiStepFeedback, - QgsProcessingParameterFile, - QgsProcessingParameterExpression, - QgsProcessingException, - QgsProcessingParameterString, - QgsProcessingParameterDefinition, - QgsProcessingParameterType, - QgsProcessingParameterCrs, - QgsCoordinateTransform, - QgsProject, - QgsCoordinateReferenceSystem, - QgsField, - QgsFields) +from qgis.core import ( + QgsProcessing, + QgsFeatureSink, + QgsProcessingAlgorithm, + QgsProcessingParameterFeatureSource, + QgsProcessingParameterFeatureSink, + QgsFeature, + QgsDataSourceUri, + QgsProcessingOutputVectorLayer, + QgsProcessingParameterVectorLayer, + QgsWkbTypes, + QgsProcessingParameterBoolean, + QgsProcessingParameterEnum, + QgsProcessingParameterNumber, + QgsProcessingParameterMultipleLayers, + QgsProcessingUtils, + QgsSpatialIndex, + QgsGeometry, + QgsProcessingParameterField, + QgsProcessingMultiStepFeedback, + QgsProcessingParameterFile, + QgsProcessingParameterExpression, + QgsProcessingException, + QgsProcessingParameterString, + QgsProcessingParameterDefinition, + QgsProcessingParameterType, + QgsProcessingParameterCrs, + QgsCoordinateTransform, + QgsProject, + QgsCoordinateReferenceSystem, + QgsField, + QgsFields, +) + class CreateFrameAlgorithm(QgsProcessingAlgorithm): - START_SCALE = 'START_SCALE' - STOP_SCALE = 'STOP_SCALE' - INDEX_TYPE = 'INDEX_TYPE' - INDEX = 'INDEX' - CRS = 'CRS' - XSUBDIVISIONS = 'XSUBDIVISIONS' - YSUBDIVISIONS = 'YSUBDIVISIONS' - OUTPUT = 'OUTPUT' + START_SCALE = "START_SCALE" + STOP_SCALE = "STOP_SCALE" + INDEX_TYPE = "INDEX_TYPE" + INDEX = "INDEX" + CRS = "CRS" + XSUBDIVISIONS = "XSUBDIVISIONS" + YSUBDIVISIONS = "YSUBDIVISIONS" + OUTPUT = "OUTPUT" def initAlgorithm(self, config): """ Parameter setting. """ self.setValidCharacters() - self.scales = ['1000k', - '500k', - '250k', - '100k', - '50k', - '25k', - '10k', - '5k', - '2k', - '1k'] + self.scales = [ + "1000k", + "500k", + "250k", + "100k", + "50k", + "25k", + "10k", + "5k", + "2k", + "1k", + ] self.addParameter( QgsProcessingParameterEnum( self.START_SCALE, - self.tr('Base scale'), + self.tr("Base scale"), options=self.scales, - defaultValue=0 + defaultValue=0, ) ) self.addParameter( QgsProcessingParameterEnum( self.STOP_SCALE, - self.tr('Desired scale'), + self.tr("Desired scale"), options=self.scales, - defaultValue=0 + defaultValue=0, ) ) - self.indexTypes = [ - 'MI/MIR', - 'INOM' - ] + self.indexTypes = ["MI/MIR", "INOM"] self.addParameter( QgsProcessingParameterEnum( self.INDEX_TYPE, - self.tr('Index type'), + self.tr("Index type"), options=self.indexTypes, - defaultValue=0 - ) - ) - self.addParameter( - QgsProcessingParameterString( - self.INDEX, - self.tr('Index') - ) - ) - self.addParameter( - QgsProcessingParameterCrs( - self.CRS, - self.tr('CRS') + defaultValue=0, ) ) + self.addParameter(QgsProcessingParameterString(self.INDEX, self.tr("Index"))) + self.addParameter(QgsProcessingParameterCrs(self.CRS, self.tr("CRS"))) self.addParameter( QgsProcessingParameterNumber( self.XSUBDIVISIONS, - self.tr('Number of subdivisions on x-axis'), - defaultValue=3 + self.tr("Number of subdivisions on x-axis"), + defaultValue=3, ) ) self.addParameter( QgsProcessingParameterNumber( self.YSUBDIVISIONS, - self.tr('Number of subdivisions on y-axis'), + self.tr("Number of subdivisions on y-axis"), defaultValue=3, minValue=0, type=QgsProcessingParameterNumber.Integer, ) ) self.addParameter( - QgsProcessingParameterFeatureSink( - self.OUTPUT, - self.tr('Created Frames') - ) + QgsProcessingParameterFeatureSink(self.OUTPUT, self.tr("Created Frames")) ) def processAlgorithm(self, parameters, context, feedback): @@ -156,33 +145,48 @@ def processAlgorithm(self, parameters, context, feedback): startScaleIdx = self.parameterAsEnum(parameters, self.START_SCALE, context) stopScaleIdx = self.parameterAsEnum(parameters, self.STOP_SCALE, context) stopScale = self.scales[stopScaleIdx] - stopScale = int(stopScale.replace('k', '')) + stopScale = int(stopScale.replace("k", "")) if startScaleIdx > stopScaleIdx: - raise QgsProcessingException(self.tr('The desired scale denominator must not be bigger than the base scale denominator.')) + raise QgsProcessingException( + self.tr( + "The desired scale denominator must not be bigger than the base scale denominator." + ) + ) indexTypeIdx = self.parameterAsEnum(parameters, self.INDEX_TYPE, context) inputIndex = self.parameterAsString(parameters, self.INDEX, context) - if startScaleIdx in [0,1] and indexTypeIdx == 0: - raise QgsProcessingException(self.tr('{index} is only valid for scales 250k and below.').format(index=self.indexTypes[indexTypeIdx])) - if inputIndex is None or inputIndex == '': - raise QgsProcessingException(self.tr('Invalid {index}').format(index=self.indexTypes[indexTypeIdx])) + if startScaleIdx in [0, 1] and indexTypeIdx == 0: + raise QgsProcessingException( + self.tr("{index} is only valid for scales 250k and below.").format( + index=self.indexTypes[indexTypeIdx] + ) + ) + if inputIndex is None or inputIndex == "": + raise QgsProcessingException( + self.tr("Invalid {index}").format(index=self.indexTypes[indexTypeIdx]) + ) index = self.getIndex(inputIndex, indexTypeIdx, startScaleIdx) if index is None or not self.validateIndex(index): - raise QgsProcessingException(self.tr('Invalid {index} format.').format(index=self.indexTypes[indexTypeIdx])) + raise QgsProcessingException( + self.tr("Invalid {index} format.").format( + index=self.indexTypes[indexTypeIdx] + ) + ) crs = self.parameterAsCrs(parameters, self.CRS, context) if crs is None or not crs.isValid(): - raise QgsProcessingException(self.tr('Invalid CRS.')) + raise QgsProcessingException(self.tr("Invalid CRS.")) xSubdivisions = self.parameterAsInt(parameters, self.XSUBDIVISIONS, context) ySubdivisions = self.parameterAsInt(parameters, self.YSUBDIVISIONS, context) fields = QgsFields() - fields.append(QgsField('inom', QVariant.String)) - fields.append(QgsField('mi', QVariant.String)) - (output_sink, output_sink_id) = self.parameterAsSink(parameters, self.OUTPUT, - context, fields, QgsWkbTypes.Polygon, crs) + fields.append(QgsField("inom", QVariant.String)) + fields.append(QgsField("mi", QVariant.String)) + (output_sink, output_sink_id) = self.parameterAsSink( + parameters, self.OUTPUT, context, fields, QgsWkbTypes.Polygon, crs + ) featureList = [] coordinateTransformer = QgsCoordinateTransform( QgsCoordinateReferenceSystem(crs.geographicCrsAuthId()), crs, - QgsProject.instance() + QgsProject.instance(), ) featureHandler.getSystematicGridFeatures( featureList, @@ -192,12 +196,12 @@ def processAlgorithm(self, parameters, context, feedback): fields, xSubdivisions=xSubdivisions, ySubdivisions=ySubdivisions, - feedback=feedback + feedback=feedback, ) for feat in featureList: output_sink.addFeature(feat, QgsFeatureSink.FastInsert) - return {'OUTPUT':output_sink_id} + return {"OUTPUT": output_sink_id} def name(self): """ @@ -207,21 +211,21 @@ def name(self): lowercase alphanumeric characters only and no spaces or other formatting characters. """ - return 'gridzonegenerator' + return "gridzonegenerator" def displayName(self): """ Returns the translated algorithm name, which should be used for any user-visible display of the algorithm name. """ - return self.tr('Generate Systematic Grid') + return self.tr("Generate Systematic Grid") def group(self): """ Returns the name of the group this algorithm belongs to. This string should be localised. """ - return self.tr('Other Algorithms') + return self.tr("Other Algorithms") def groupId(self): """ @@ -231,14 +235,14 @@ def groupId(self): contain lowercase alphanumeric characters only and no spaces or other formatting characters. """ - return 'DSGTools: Other Algorithms' + return "DSGTools: Other Algorithms" def tr(self, string): - return QCoreApplication.translate('CreateFrameAlgorithm', string) + return QCoreApplication.translate("CreateFrameAlgorithm", string) def createInstance(self): return CreateFrameAlgorithm() - + def getIndex(self, inputIndex, indexType, scaleType): """ Returns map_index @@ -249,48 +253,104 @@ def getIndex(self, inputIndex, indexType, scaleType): else: return UtmGrid().getINomenFromMI(inputIndex) return inputIndex - + def setValidCharacters(self): """ Method to define the valid characters """ self.chars = [] - chars = 'NS' + chars = "NS" self.chars.append(chars) - chars = 'ABCDEFGHIJKLMNOPQRSTUVZ' + chars = "ABCDEFGHIJKLMNOPQRSTUVZ" self.chars.append(chars) - chars = ['01','02','03','04','05','06','07','08','09','10', - '11','12','13','14','15','16','17','18','19','20', - '21','22','23','24','25','26','27','28','29','30', - '31','32','33','34','35','36','37','38','39','40', - '41','42','43','44','45','46','47','48','49','50', - '51','52','53','54','55','56','57','58','59','60'] + chars = [ + "01", + "02", + "03", + "04", + "05", + "06", + "07", + "08", + "09", + "10", + "11", + "12", + "13", + "14", + "15", + "16", + "17", + "18", + "19", + "20", + "21", + "22", + "23", + "24", + "25", + "26", + "27", + "28", + "29", + "30", + "31", + "32", + "33", + "34", + "35", + "36", + "37", + "38", + "39", + "40", + "41", + "42", + "43", + "44", + "45", + "46", + "47", + "48", + "49", + "50", + "51", + "52", + "53", + "54", + "55", + "56", + "57", + "58", + "59", + "60", + ] self.chars.append(chars) - chars = 'VXYZ' + chars = "VXYZ" self.chars.append(chars) - chars = 'ABCD' + chars = "ABCD" self.chars.append(chars) - chars = ['I','II','III','IV','V','VI'] + chars = ["I", "II", "III", "IV", "V", "VI"] self.chars.append(chars) - chars = '1234' + chars = "1234" self.chars.append(chars) - chars = ['NO','NE','SO','SE'] + chars = ["NO", "NE", "SO", "SE"] self.chars.append(chars) - chars = 'ABCDEF' + chars = "ABCDEF" self.chars.append(chars) - chars = ['I','II','III','IV'] + chars = ["I", "II", "III", "IV"] self.chars.append(chars) - chars = '123456' + chars = "123456" self.chars.append(chars) - chars = 'ABCD' + chars = "ABCD" self.chars.append(chars) - + def validateIndex(self, index): """ Parses the index to see if it is valid """ - for i, word in enumerate(index.split('-')): + for i, word in enumerate(index.split("-")): if len(word) == 0: return False if i == 0: @@ -378,4 +438,4 @@ def validateIndex(self, index): # @classmethod # def fromScriptCode(cls, name, description, isOptional, definition): -# raise NotImplementedError() \ No newline at end of file +# raise NotImplementedError() diff --git a/DsgTools/core/DSGToolsProcessingAlgs/Algs/OtherAlgs/createFramesWithConstraintAlgorithm.py b/DsgTools/core/DSGToolsProcessingAlgs/Algs/OtherAlgs/createFramesWithConstraintAlgorithm.py index ffec585cc..3324a4fc7 100644 --- a/DsgTools/core/DSGToolsProcessingAlgs/Algs/OtherAlgs/createFramesWithConstraintAlgorithm.py +++ b/DsgTools/core/DSGToolsProcessingAlgs/Algs/OtherAlgs/createFramesWithConstraintAlgorithm.py @@ -27,44 +27,47 @@ from time import sleep from qgis.PyQt.Qt import QVariant from PyQt5.QtCore import QCoreApplication -from qgis.core import (QgsProcessing, - QgsFeatureSink, - QgsProcessingAlgorithm, - QgsProcessingParameterFeatureSource, - QgsProcessingParameterFeatureSink, - QgsFeature, - QgsDataSourceUri, - QgsProcessingOutputVectorLayer, - QgsProcessingParameterVectorLayer, - QgsWkbTypes, - QgsProcessingParameterBoolean, - QgsProcessingParameterEnum, - QgsProcessingParameterNumber, - QgsProcessingParameterMultipleLayers, - QgsProcessingUtils, - QgsSpatialIndex, - QgsGeometry, - QgsProcessingParameterField, - QgsProcessingMultiStepFeedback, - QgsProcessingParameterFile, - QgsProcessingParameterExpression, - QgsProcessingException, - QgsProcessingParameterString, - QgsProcessingParameterDefinition, - QgsProcessingParameterType, - QgsProcessingParameterCrs, - QgsCoordinateTransform, - QgsProject, - QgsCoordinateReferenceSystem, - QgsField, - QgsFields) +from qgis.core import ( + QgsProcessing, + QgsFeatureSink, + QgsProcessingAlgorithm, + QgsProcessingParameterFeatureSource, + QgsProcessingParameterFeatureSink, + QgsFeature, + QgsDataSourceUri, + QgsProcessingOutputVectorLayer, + QgsProcessingParameterVectorLayer, + QgsWkbTypes, + QgsProcessingParameterBoolean, + QgsProcessingParameterEnum, + QgsProcessingParameterNumber, + QgsProcessingParameterMultipleLayers, + QgsProcessingUtils, + QgsSpatialIndex, + QgsGeometry, + QgsProcessingParameterField, + QgsProcessingMultiStepFeedback, + QgsProcessingParameterFile, + QgsProcessingParameterExpression, + QgsProcessingException, + QgsProcessingParameterString, + QgsProcessingParameterDefinition, + QgsProcessingParameterType, + QgsProcessingParameterCrs, + QgsCoordinateTransform, + QgsProject, + QgsCoordinateReferenceSystem, + QgsField, + QgsFields, +) + class CreateFramesWithConstraintAlgorithm(QgsProcessingAlgorithm): - INPUT = 'INPUT' - STOP_SCALE = 'STOP_SCALE' - XSUBDIVISIONS = 'XSUBDIVISIONS' - YSUBDIVISIONS = 'YSUBDIVISIONS' - OUTPUT = 'OUTPUT' + INPUT = "INPUT" + STOP_SCALE = "STOP_SCALE" + XSUBDIVISIONS = "XSUBDIVISIONS" + YSUBDIVISIONS = "YSUBDIVISIONS" + OUTPUT = "OUTPUT" def initAlgorithm(self, config): """ @@ -74,45 +77,45 @@ def initAlgorithm(self, config): self.addParameter( QgsProcessingParameterVectorLayer( self.INPUT, - self.tr('Input Polygon Layer'), - [QgsProcessing.TypeVectorPolygon] + self.tr("Input Polygon Layer"), + [QgsProcessing.TypeVectorPolygon], ) ) self.scales = [ - '1000k', - '500k', - '250k', - '100k', - '50k', - '25k', - '10k', - '5k', - '2k', - '1k' + "1000k", + "500k", + "250k", + "100k", + "50k", + "25k", + "10k", + "5k", + "2k", + "1k", ] self.addParameter( QgsProcessingParameterEnum( self.STOP_SCALE, - self.tr('Desired scale'), + self.tr("Desired scale"), options=self.scales, - defaultValue=0 + defaultValue=0, ) ) self.addParameter( QgsProcessingParameterNumber( self.XSUBDIVISIONS, - self.tr('Number of subdivisions on x-axis'), - defaultValue=3 + self.tr("Number of subdivisions on x-axis"), + defaultValue=3, ) ) self.addParameter( QgsProcessingParameterNumber( self.YSUBDIVISIONS, - self.tr('Number of subdivisions on y-axis'), + self.tr("Number of subdivisions on y-axis"), defaultValue=3, minValue=0, type=QgsProcessingParameterNumber.Integer, @@ -120,10 +123,7 @@ def initAlgorithm(self, config): ) self.addParameter( - QgsProcessingParameterFeatureSink( - self.OUTPUT, - self.tr('Created Frames') - ) + QgsProcessingParameterFeatureSink(self.OUTPUT, self.tr("Created Frames")) ) def processAlgorithm(self, parameters, context, feedback): @@ -131,44 +131,29 @@ def processAlgorithm(self, parameters, context, feedback): Here is where the processing itself takes place. """ featureHandler = FeatureHandler() - inputLyr = self.parameterAsVectorLayer( - parameters, - self.INPUT, - context - ) + inputLyr = self.parameterAsVectorLayer(parameters, self.INPUT, context) if inputLyr is None: raise QgsProcessingException( - self.invalidSourceError( - parameters, self.INPUT - ) + self.invalidSourceError(parameters, self.INPUT) ) - stopScaleIdx = self.parameterAsEnum( - parameters, - self.STOP_SCALE, - context - ) + stopScaleIdx = self.parameterAsEnum(parameters, self.STOP_SCALE, context) stopScale = self.scales[stopScaleIdx] - stopScale = int(stopScale.replace('k', '')) + stopScale = int(stopScale.replace("k", "")) fields = QgsFields() - fields.append(QgsField('inom', QVariant.String)) - fields.append(QgsField('mi', QVariant.String)) + fields.append(QgsField("inom", QVariant.String)) + fields.append(QgsField("mi", QVariant.String)) crs = inputLyr.crs() xSubdivisions = self.parameterAsInt(parameters, self.XSUBDIVISIONS, context) ySubdivisions = self.parameterAsInt(parameters, self.YSUBDIVISIONS, context) (output_sink, output_sink_id) = self.parameterAsSink( - parameters, - self.OUTPUT, - context, - fields, - QgsWkbTypes.Polygon, - crs + parameters, self.OUTPUT, context, fields, QgsWkbTypes.Polygon, crs ) featureList = [] coordinateTransformer = QgsCoordinateTransform( QgsCoordinateReferenceSystem(crs.geographicCrsAuthId()), crs, - QgsProject.instance() - ) + QgsProject.instance(), + ) featureHandler.getSystematicGridFeaturesWithConstraint( featureList, inputLyr, @@ -177,19 +162,16 @@ def processAlgorithm(self, parameters, context, feedback): fields, xSubdivisions=xSubdivisions, ySubdivisions=ySubdivisions, - feedback=feedback + feedback=feedback, ) list( map( - lambda x: output_sink.addFeature( - x, - QgsFeatureSink.FastInsert) - , - featureList + lambda x: output_sink.addFeature(x, QgsFeatureSink.FastInsert), + featureList, ) ) - return {'OUTPUT':output_sink_id} + return {"OUTPUT": output_sink_id} def name(self): """ @@ -199,21 +181,21 @@ def name(self): lowercase alphanumeric characters only and no spaces or other formatting characters. """ - return 'createframeswithconstraintalgorithm' + return "createframeswithconstraintalgorithm" def displayName(self): """ Returns the translated algorithm name, which should be used for any user-visible display of the algorithm name. """ - return self.tr('Generate Systematic Grid Related to Layer') + return self.tr("Generate Systematic Grid Related to Layer") def group(self): """ Returns the name of the group this algorithm belongs to. This string should be localised. """ - return self.tr('Other Algorithms') + return self.tr("Other Algorithms") def groupId(self): """ @@ -223,10 +205,10 @@ def groupId(self): contain lowercase alphanumeric characters only and no spaces or other formatting characters. """ - return 'DSGTools: Other Algorithms' + return "DSGTools: Other Algorithms" def tr(self, string): - return QCoreApplication.translate('CreateFramesWithConstraintAlgorithm', string) + return QCoreApplication.translate("CreateFramesWithConstraintAlgorithm", string) def createInstance(self): return CreateFramesWithConstraintAlgorithm() diff --git a/DsgTools/core/DSGToolsProcessingAlgs/Algs/OtherAlgs/createReviewGridAlgorithm.py b/DsgTools/core/DSGToolsProcessingAlgs/Algs/OtherAlgs/createReviewGridAlgorithm.py index d85ce77c3..489324f41 100644 --- a/DsgTools/core/DSGToolsProcessingAlgs/Algs/OtherAlgs/createReviewGridAlgorithm.py +++ b/DsgTools/core/DSGToolsProcessingAlgs/Algs/OtherAlgs/createReviewGridAlgorithm.py @@ -21,23 +21,31 @@ ***************************************************************************/ """ from PyQt5.QtCore import QCoreApplication -from qgis.core import (QgsFeature, QgsFeatureSink, QgsField, QgsFields, - QgsProcessing, QgsProcessingAlgorithm, - QgsProcessingException, QgsProcessingMultiStepFeedback, - QgsProcessingParameterFeatureSink, - QgsProcessingParameterFeatureSource, - QgsProcessingParameterNumber, QgsWkbTypes) +from qgis.core import ( + QgsFeature, + QgsFeatureSink, + QgsField, + QgsFields, + QgsProcessing, + QgsProcessingAlgorithm, + QgsProcessingException, + QgsProcessingMultiStepFeedback, + QgsProcessingParameterFeatureSink, + QgsProcessingParameterFeatureSource, + QgsProcessingParameterNumber, + QgsWkbTypes, +) from qgis.PyQt.Qt import QVariant from ...algRunner import AlgRunner class CreateReviewGridAlgorithm(QgsProcessingAlgorithm): - INPUT = 'INPUT' - RELATED_TASK_ID = 'RELATED_TASK_ID' - X_GRID_SIZE = 'X_GRID_SIZE' - Y_GRID_SIZE = 'Y_GRID_SIZE' - OUTPUT = 'OUTPUT' + INPUT = "INPUT" + RELATED_TASK_ID = "RELATED_TASK_ID" + X_GRID_SIZE = "X_GRID_SIZE" + Y_GRID_SIZE = "Y_GRID_SIZE" + OUTPUT = "OUTPUT" def initAlgorithm(self, config): """ @@ -47,16 +55,16 @@ def initAlgorithm(self, config): self.addParameter( QgsProcessingParameterFeatureSource( self.INPUT, - self.tr('Input Polygon Layer'), + self.tr("Input Polygon Layer"), [QgsProcessing.TypeVectorPolygon], - optional=False + optional=False, ) ) self.addParameter( QgsProcessingParameterNumber( self.X_GRID_SIZE, - self.tr('Grid size on x-axis'), + self.tr("Grid size on x-axis"), defaultValue=0.005, minValue=0, type=QgsProcessingParameterNumber.Double, @@ -66,7 +74,7 @@ def initAlgorithm(self, config): self.addParameter( QgsProcessingParameterNumber( self.Y_GRID_SIZE, - self.tr('Grid size on y-axis'), + self.tr("Grid size on y-axis"), defaultValue=0.005, minValue=0, type=QgsProcessingParameterNumber.Double, @@ -76,7 +84,7 @@ def initAlgorithm(self, config): self.addParameter( QgsProcessingParameterNumber( self.RELATED_TASK_ID, - self.tr('Related task id'), + self.tr("Related task id"), optional=True, type=QgsProcessingParameterNumber.Integer, ) @@ -84,8 +92,7 @@ def initAlgorithm(self, config): self.addParameter( QgsProcessingParameterFeatureSink( - self.OUTPUT, - self.tr('Created Review Grid') + self.OUTPUT, self.tr("Created Review Grid") ) ) @@ -94,16 +101,10 @@ def processAlgorithm(self, parameters, context, feedback): Here is where the processing itself takes place. """ algRunner = AlgRunner() - inputSource = self.parameterAsSource( - parameters, - self.INPUT, - context - ) + inputSource = self.parameterAsSource(parameters, self.INPUT, context) if inputSource is None: raise QgsProcessingException( - self.invalidSourceError( - parameters, self.INPUT - ) + self.invalidSourceError(parameters, self.INPUT) ) fields = self.getOutputFields() @@ -115,7 +116,7 @@ def processAlgorithm(self, parameters, context, feedback): context, fields, QgsWkbTypes.Polygon, - inputSource.sourceCrs() + inputSource.sourceCrs(), ) multiStepFeedback = QgsProcessingMultiStepFeedback(5, feedback) multiStepFeedback.setCurrentStep(0) @@ -125,7 +126,7 @@ def processAlgorithm(self, parameters, context, feedback): hSpacing=xGridSize, vSpacing=yGridSize, feedback=multiStepFeedback, - context=context + context=context, ) multiStepFeedback.setCurrentStep(1) algRunner.runCreateSpatialIndex( @@ -136,7 +137,7 @@ def processAlgorithm(self, parameters, context, feedback): inputLyr=grid, intersectLyr=parameters[self.INPUT], context=context, - feedback=multiStepFeedback + feedback=multiStepFeedback, ) multiStepFeedback.setCurrentStep(3) sortedFeatures = self.sortGridAndCreateOutputFetures( @@ -145,47 +146,47 @@ def processAlgorithm(self, parameters, context, feedback): multiStepFeedback.setCurrentStep(4) list( map( - lambda x: output_sink.addFeature( - x, - QgsFeatureSink.FastInsert) - , - sortedFeatures + lambda x: output_sink.addFeature(x, QgsFeatureSink.FastInsert), + sortedFeatures, ) ) - - return {'OUTPUT':output_sink_id} + return {"OUTPUT": output_sink_id} def getOutputFields(self): fields = QgsFields() - fields.append(QgsField('rank', QVariant.Int)) - fields.append(QgsField('visited', QVariant.Bool)) - fields.append(QgsField('atividade_id', QVariant.Int)) + fields.append(QgsField("rank", QVariant.Int)) + fields.append(QgsField("visited", QVariant.Bool)) + fields.append(QgsField("atividade_id", QVariant.Int)) return fields - - def sortGridAndCreateOutputFetures(self, grid, fields, parameters, context, feedback): + + def sortGridAndCreateOutputFetures( + self, grid, fields, parameters, context, feedback + ): featList = [feat for feat in grid.getFeatures()] - relatedTaskId = self.parameterAsInt( - parameters, self.RELATED_TASK_ID, context - ) + relatedTaskId = self.parameterAsInt(parameters, self.RELATED_TASK_ID, context) outputFeatList = [] nSteps = len(featList) if nSteps == 0: return outputFeatList - stepSize = 100/nSteps + stepSize = 100 / nSteps for current, feat in enumerate( sorted( - sorted(featList, key=lambda feat: feat.geometry().vertexAt(0).x(), reverse=False), + sorted( + featList, + key=lambda feat: feat.geometry().vertexAt(0).x(), + reverse=False, + ), key=lambda feat: feat.geometry().vertexAt(0).y(), - reverse=True + reverse=True, ) ): if feedback.isCanceled(): break newFeat = QgsFeature(fields) - newFeat['visited'] = False - newFeat['rank'] = current - newFeat['atividade_id'] = relatedTaskId + newFeat["visited"] = False + newFeat["rank"] = current + newFeat["atividade_id"] = relatedTaskId newFeat.setGeometry(feat.geometry()) outputFeatList.append(newFeat) feedback.setProgress(current * stepSize) @@ -199,21 +200,21 @@ def name(self): lowercase alphanumeric characters only and no spaces or other formatting characters. """ - return 'createreviewgridalgorithm' + return "createreviewgridalgorithm" def displayName(self): """ Returns the translated algorithm name, which should be used for any user-visible display of the algorithm name. """ - return self.tr('Create Review Grid') + return self.tr("Create Review Grid") def group(self): """ Returns the name of the group this algorithm belongs to. This string should be localised. """ - return self.tr('Other Algorithms') + return self.tr("Other Algorithms") def groupId(self): """ @@ -223,10 +224,10 @@ def groupId(self): contain lowercase alphanumeric characters only and no spaces or other formatting characters. """ - return 'DSGTools: Other Algorithms' + return "DSGTools: Other Algorithms" def tr(self, string): - return QCoreApplication.translate('CreateReviewGridAlgorithm', string) + return QCoreApplication.translate("CreateReviewGridAlgorithm", string) def createInstance(self): return CreateReviewGridAlgorithm() diff --git a/DsgTools/core/DSGToolsProcessingAlgs/Algs/OtherAlgs/exportToMemoryLayer.py b/DsgTools/core/DSGToolsProcessingAlgs/Algs/OtherAlgs/exportToMemoryLayer.py index 63e5bd506..6749114ce 100644 --- a/DsgTools/core/DSGToolsProcessingAlgs/Algs/OtherAlgs/exportToMemoryLayer.py +++ b/DsgTools/core/DSGToolsProcessingAlgs/Algs/OtherAlgs/exportToMemoryLayer.py @@ -23,49 +23,52 @@ from qgis.PyQt.QtXml import QDomDocument from DsgTools.core.GeometricTools.geometryHandler import GeometryHandler -from qgis.core import (QgsDataSourceUri, QgsFeature, QgsFeatureSink, - QgsProcessing, QgsProcessingAlgorithm, - QgsProcessingOutputVectorLayer, - QgsProcessingParameterString, - QgsProcessingParameterFeatureSink, - QgsProcessingParameterFeatureSource, - QgsProcessingParameterFile, - QgsProcessingParameterVectorLayer, - QgsWkbTypes, - QgsVectorLayer, - QgsProject) +from qgis.core import ( + QgsDataSourceUri, + QgsFeature, + QgsFeatureSink, + QgsProcessing, + QgsProcessingAlgorithm, + QgsProcessingOutputVectorLayer, + QgsProcessingParameterString, + QgsProcessingParameterFeatureSink, + QgsProcessingParameterFeatureSource, + QgsProcessingParameterFile, + QgsProcessingParameterVectorLayer, + QgsWkbTypes, + QgsVectorLayer, + QgsProject, +) from qgis.utils import iface + class ExportToMemoryLayer(QgsProcessingAlgorithm): - INPUT = 'INPUT_LAYER' - OUTPUT_NAME = 'OUTPUT_NAME' - OUTPUT_QML_STYLE = 'OUTPUT_QML_STYLE' + INPUT = "INPUT_LAYER" + OUTPUT_NAME = "OUTPUT_NAME" + OUTPUT_QML_STYLE = "OUTPUT_QML_STYLE" def initAlgorithm(self, config): """ Parameter setting. """ self.addParameter( - QgsProcessingParameterVectorLayer( - self.INPUT, - self.tr('Camada de entrada') - ) + QgsProcessingParameterVectorLayer(self.INPUT, self.tr("Camada de entrada")) ) self.addParameter( QgsProcessingParameterString( self.OUTPUT_NAME, - self.tr('Nome da camada de saída'), + self.tr("Nome da camada de saída"), optional=True, - defaultValue='resultado' + defaultValue="resultado", ) - ) + ) self.addParameter( QgsProcessingParameterString( self.OUTPUT_QML_STYLE, - self.tr('Estilo da camada de saída'), - multiLine = True, - optional=True + self.tr("Estilo da camada de saída"), + multiLine=True, + optional=True, ) ) @@ -75,16 +78,20 @@ def processAlgorithm(self, parameters, context, feedback): """ layer = self.parameterAsVectorLayer(parameters, self.INPUT, context) geom_types = { - 0 : 'Point', - 1 : 'LineString', - 2 : 'Polygon', + 0: "Point", + 1: "LineString", + 2: "Polygon", } outputLayerName = self.parameterAsString(parameters, self.OUTPUT_NAME, context) - outputLayerStyle = self.parameterAsString(parameters, self.OUTPUT_QML_STYLE, context) + outputLayerStyle = self.parameterAsString( + parameters, self.OUTPUT_QML_STYLE, context + ) temp = QgsVectorLayer( - '{0}?crs={1}'.format(geom_types[layer.geometryType()], layer.crs().authid()), - "{0}".format(outputLayerName), - "memory" + "{0}?crs={1}".format( + geom_types[layer.geometryType()], layer.crs().authid() + ), + "{0}".format(outputLayerName), + "memory", ) doc = QDomDocument() doc.setContent(outputLayerStyle) @@ -92,7 +99,7 @@ def processAlgorithm(self, parameters, context, feedback): temp_data = temp.dataProvider() temp_data.addAttributes(layer.dataProvider().fields().toList()) temp.updateFields() - temp_data.addFeatures([ feat for feat in layer.getFeatures() ]) + temp_data.addFeatures([feat for feat in layer.getFeatures()]) QgsProject().instance().addMapLayer(temp) return {} @@ -104,21 +111,21 @@ def name(self): lowercase alphanumeric characters only and no spaces or other formatting characters. """ - return 'exportToMemoryLayer' + return "exportToMemoryLayer" def displayName(self): """ Returns the translated algorithm name, which should be used for any user-visible display of the algorithm name. """ - return self.tr('Export To Memory Layer (works only on models)') + return self.tr("Export To Memory Layer (works only on models)") def group(self): """ Returns the name of the group this algorithm belongs to. This string should be localised. """ - return self.tr('Other Algorithms') + return self.tr("Other Algorithms") def groupId(self): """ @@ -128,10 +135,10 @@ def groupId(self): contain lowercase alphanumeric characters only and no spaces or other formatting characters. """ - return 'DSGTools: Other Algorithms' + return "DSGTools: Other Algorithms" def tr(self, string): - return QCoreApplication.translate('ExportToMemoryLayer', string) + return QCoreApplication.translate("ExportToMemoryLayer", string) def createInstance(self): - return ExportToMemoryLayer() \ No newline at end of file + return ExportToMemoryLayer() diff --git a/DsgTools/core/DSGToolsProcessingAlgs/Algs/OtherAlgs/fileInventoryAlgorithm.py b/DsgTools/core/DSGToolsProcessingAlgs/Algs/OtherAlgs/fileInventoryAlgorithm.py index 49c625c12..567fbfffe 100644 --- a/DsgTools/core/DSGToolsProcessingAlgs/Algs/OtherAlgs/fileInventoryAlgorithm.py +++ b/DsgTools/core/DSGToolsProcessingAlgs/Algs/OtherAlgs/fileInventoryAlgorithm.py @@ -26,45 +26,48 @@ from ...algRunner import AlgRunner import processing, os, requests from PyQt5.QtCore import QCoreApplication -from qgis.core import (QgsProcessing, - QgsFeatureSink, - QgsProcessingAlgorithm, - QgsProcessingParameterFeatureSource, - QgsProcessingParameterFeatureSink, - QgsFeature, - QgsDataSourceUri, - QgsProcessingOutputVectorLayer, - QgsProcessingParameterVectorLayer, - QgsWkbTypes, - QgsProcessingParameterBoolean, - QgsProcessingParameterEnum, - QgsProcessingParameterNumber, - QgsProcessingParameterMultipleLayers, - QgsProcessingUtils, - QgsSpatialIndex, - QgsGeometry, - QgsProcessingParameterField, - QgsProcessingMultiStepFeedback, - QgsProcessingParameterFolderDestination, - QgsProcessingParameterExpression, - QgsProcessingException, - QgsProcessingParameterString, - QgsProcessingParameterDefinition, - QgsProcessingParameterType, - QgsProcessingParameterMatrix, - QgsProcessingParameterFile, - QgsCoordinateReferenceSystem, - QgsFields) +from qgis.core import ( + QgsProcessing, + QgsFeatureSink, + QgsProcessingAlgorithm, + QgsProcessingParameterFeatureSource, + QgsProcessingParameterFeatureSink, + QgsFeature, + QgsDataSourceUri, + QgsProcessingOutputVectorLayer, + QgsProcessingParameterVectorLayer, + QgsWkbTypes, + QgsProcessingParameterBoolean, + QgsProcessingParameterEnum, + QgsProcessingParameterNumber, + QgsProcessingParameterMultipleLayers, + QgsProcessingUtils, + QgsSpatialIndex, + QgsGeometry, + QgsProcessingParameterField, + QgsProcessingMultiStepFeedback, + QgsProcessingParameterFolderDestination, + QgsProcessingParameterExpression, + QgsProcessingException, + QgsProcessingParameterString, + QgsProcessingParameterDefinition, + QgsProcessingParameterType, + QgsProcessingParameterMatrix, + QgsProcessingParameterFile, + QgsCoordinateReferenceSystem, + QgsFields, +) + class FileInventoryAlgorithm(QgsProcessingAlgorithm): - INPUT_FOLDER = 'INPUT_FOLDER' - ONLY_GEO = 'ONLY_GEO' - SEARCH_TYPE = 'SEARCH_TYPE' - FILE_FORMATS = 'FILE_FORMATS' - TYPE_LIST = 'TYPE_LIST' - COPY_FILES = 'COPY_FILES' - COPY_FOLDER= 'COPY_FOLDER' - OUTPUT = 'OUTPUT' + INPUT_FOLDER = "INPUT_FOLDER" + ONLY_GEO = "ONLY_GEO" + SEARCH_TYPE = "SEARCH_TYPE" + FILE_FORMATS = "FILE_FORMATS" + TYPE_LIST = "TYPE_LIST" + COPY_FILES = "COPY_FILES" + COPY_FOLDER = "COPY_FOLDER" + OUTPUT = "OUTPUT" def initAlgorithm(self, config): """ @@ -73,68 +76,60 @@ def initAlgorithm(self, config): self.addParameter( QgsProcessingParameterFile( self.INPUT_FOLDER, - self.tr('Input folder'), - behavior=QgsProcessingParameterFile.Folder + self.tr("Input folder"), + behavior=QgsProcessingParameterFile.Folder, ) ) self.addParameter( QgsProcessingParameterBoolean( self.ONLY_GEO, - self.tr('Search only georreferenced files'), - defaultValue=True + self.tr("Search only georreferenced files"), + defaultValue=True, ) ) - self.searchTypes = [ - 'Search only listed formats', - 'Exclude listed formats' - ] + self.searchTypes = ["Search only listed formats", "Exclude listed formats"] self.addParameter( QgsProcessingParameterEnum( self.SEARCH_TYPE, - self.tr('Search type'), + self.tr("Search type"), options=self.searchTypes, - defaultValue=0 + defaultValue=0, ) ) self.addParameter( QgsProcessingParameterMatrix( self.FILE_FORMATS, - self.tr('Formats'), - headers=[self.tr('File Formats')], + self.tr("Formats"), + headers=[self.tr("File Formats")], numberRows=1, - defaultValue=['shp','tif'] + defaultValue=["shp", "tif"], ) ) self.addParameter( QgsProcessingParameterBoolean( - self.COPY_FILES, - self.tr('Copy files to output'), - defaultValue=False + self.COPY_FILES, self.tr("Copy files to output"), defaultValue=False ) ) self.addParameter( QgsProcessingParameterFolderDestination( self.COPY_FOLDER, - self.tr('Copy files to folder'), + self.tr("Copy files to folder"), optional=True, - defaultValue=None + defaultValue=None, ) ) self.addParameter( - QgsProcessingParameterFeatureSink( - self.OUTPUT, - self.tr('Inventory layer') - ) + QgsProcessingParameterFeatureSink(self.OUTPUT, self.tr("Inventory layer")) ) def processAlgorithm(self, parameters, context, feedback): """ Here is where the processing itself takes place. """ - inventory = ThreadFactory().makeProcess('inventory') + inventory = ThreadFactory().makeProcess("inventory") inputFolder = self.parameterAsString(parameters, self.INPUT_FOLDER, context) if inputFolder is None: - raise QgsProcessingException(self.tr('Invalid input folder.')) + raise QgsProcessingException(self.tr("Invalid input folder.")) file_formats = self.parameterAsMatrix(parameters, self.FILE_FORMATS, context) copyFolder = self.parameterAsString(parameters, self.COPY_FOLDER, context) onlyGeo = self.parameterAsBool(parameters, self.ONLY_GEO, context) @@ -144,25 +139,25 @@ def processAlgorithm(self, parameters, context, feedback): sinkFields.append(field) (output_sink, output_dest_id) = self.parameterAsSink( - parameters, - self.OUTPUT, - context, - sinkFields, - QgsWkbTypes.Polygon, - QgsCoordinateReferenceSystem(4326) - ) - + parameters, + self.OUTPUT, + context, + sinkFields, + QgsWkbTypes.Polygon, + QgsCoordinateReferenceSystem(4326), + ) + featList = inventory.make_inventory_from_processing( - inputFolder, - file_formats, - make_copy=copyFiles, - onlyGeo=onlyGeo, - destination_folder=copyFolder - ) + inputFolder, + file_formats, + make_copy=copyFiles, + onlyGeo=onlyGeo, + destination_folder=copyFolder, + ) output_sink.addFeatures(featList, QgsFeatureSink.FastInsert) - return {'OUTPUT':output_dest_id} + return {"OUTPUT": output_dest_id} def name(self): """ @@ -172,21 +167,21 @@ def name(self): lowercase alphanumeric characters only and no spaces or other formatting characters. """ - return 'runfileinventory' + return "runfileinventory" def displayName(self): """ Returns the translated algorithm name, which should be used for any user-visible display of the algorithm name. """ - return self.tr('Run File Inventory') + return self.tr("Run File Inventory") def group(self): """ Returns the name of the group this algorithm belongs to. This string should be localised. """ - return self.tr('Other Algorithms') + return self.tr("Other Algorithms") def groupId(self): """ @@ -196,10 +191,10 @@ def groupId(self): contain lowercase alphanumeric characters only and no spaces or other formatting characters. """ - return 'DSGTools: Other Algorithms' + return "DSGTools: Other Algorithms" def tr(self, string): - return QCoreApplication.translate('FileInventoryAlgorithm', string) + return QCoreApplication.translate("FileInventoryAlgorithm", string) def createInstance(self): - return FileInventoryAlgorithm() \ No newline at end of file + return FileInventoryAlgorithm() diff --git a/DsgTools/core/DSGToolsProcessingAlgs/Algs/OtherAlgs/filterLayerListByGeometryType.py b/DsgTools/core/DSGToolsProcessingAlgs/Algs/OtherAlgs/filterLayerListByGeometryType.py new file mode 100644 index 000000000..8a149f23c --- /dev/null +++ b/DsgTools/core/DSGToolsProcessingAlgs/Algs/OtherAlgs/filterLayerListByGeometryType.py @@ -0,0 +1,116 @@ +# -*- coding: utf-8 -*- +""" +/*************************************************************************** + DsgTools + A QGIS plugin + Brazilian Army Cartographic Production Tools + ------------------- + begin : 2022-12-26 + git sha : $Format:%H$ + copyright : (C) 2022 by Philipe Borba - Cartographic Engineer @ Brazilian Army + email : borba.philipe@eb.mil.br + ***************************************************************************/ +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ +""" + +from PyQt5.QtCore import QCoreApplication +from qgis.core import (QgsProcessing, QgsProcessingAlgorithm, + QgsProcessingOutputMultipleLayers, + QgsProcessingParameterMultipleLayers, + QgsWkbTypes) + +class FilterLayerListByGeometryType(QgsProcessingAlgorithm): + INPUT_LAYERS = "INPUT_LAYERS" + POINT_OUTPUT = "POINT_OUTPUT" + LINE_OUTPUT = "LINE_OUTPUT" + POLYGON_OUTPUT = "POLYGON_OUTPUT" + + def __init__(self): + super(FilterLayerListByGeometryType, self).__init__() + + def initAlgorithm(self, config=None): + """ + Parameter setting. + """ + self.addParameter( + QgsProcessingParameterMultipleLayers( + self.INPUT_LAYERS, + self.tr("Input Layers"), + QgsProcessing.TypeVectorAnyGeometry, + ) + ) + self.addOutput( + QgsProcessingOutputMultipleLayers(self.POINT_OUTPUT, self.tr("Point layers")) + ) + self.addOutput( + QgsProcessingOutputMultipleLayers(self.LINE_OUTPUT, self.tr("Line layers")) + ) + self.addOutput( + QgsProcessingOutputMultipleLayers(self.POLYGON_OUTPUT, self.tr("Polygon layers")) + ) + + def processAlgorithm(self, parameters, context, feedback): + """ + Here is where the processing itself takes place. + """ + inputLyrList = self.parameterAsLayerList(parameters, self.INPUT_LAYERS, context) + listSize = len(inputLyrList) + stepSize = 100 / listSize if listSize else 0 + geometryDict = { + QgsWkbTypes.PointGeometry: [], + QgsWkbTypes.LineGeometry: [], + QgsWkbTypes.PolygonGeometry: [] + } + for current, lyr in enumerate(inputLyrList): + if feedback.isCanceled(): + break + geometryDict[lyr.geometryType()].append(lyr.id()) + feedback.setProgress(current * stepSize) + return { + self.POINT_OUTPUT: geometryDict[QgsWkbTypes.PointGeometry], + self.LINE_OUTPUT: geometryDict[QgsWkbTypes.LineGeometry], + self.POLYGON_OUTPUT: geometryDict[QgsWkbTypes.PolygonGeometry], + } + + def name(self): + """ + Here is where the processing itself takes place. + """ + return "filterlayerlistbygeometrytype" + + def displayName(self): + """ + Returns the translated algorithm name, which should be used for any + user-visible display of the algorithm name. + """ + return self.tr("Filter layer list by geometry type") + + def group(self): + """ + Returns the name of the group this algorithm belongs to. This string + should be localised. + """ + return self.tr("Other Algorithms") + + def groupId(self): + """ + Returns the unique ID of the group this algorithm belongs to. This + string should be fixed for the algorithm, and must not be localised. + The group id should be unique within each provider. Group id should + contain lowercase alphanumeric characters only and no spaces or other + formatting characters. + """ + return "DSGTools: Other Algorithms" + + def tr(self, string): + return QCoreApplication.translate("FilterLayerListByGeometryType", string) + + def createInstance(self): + return FilterLayerListByGeometryType() diff --git a/DsgTools/core/DSGToolsProcessingAlgs/Algs/OtherAlgs/multipleOutputUnitTestAlgorithm.py b/DsgTools/core/DSGToolsProcessingAlgs/Algs/OtherAlgs/multipleOutputUnitTestAlgorithm.py index 70511dcd2..c7a469515 100644 --- a/DsgTools/core/DSGToolsProcessingAlgs/Algs/OtherAlgs/multipleOutputUnitTestAlgorithm.py +++ b/DsgTools/core/DSGToolsProcessingAlgs/Algs/OtherAlgs/multipleOutputUnitTestAlgorithm.py @@ -24,27 +24,32 @@ from qgis.PyQt.Qt import QVariant from qgis.PyQt.QtCore import QCoreApplication -from qgis.core import (QgsProcessingAlgorithm, - QgsProcessingParameterFeatureSink, - QgsProcessingParameterEnum, - QgsFeatureSink, - QgsCoordinateReferenceSystem, - QgsFields, - QgsField, - QgsWkbTypes) +from qgis.core import ( + QgsProcessingAlgorithm, + QgsProcessingParameterFeatureSink, + QgsProcessingParameterEnum, + QgsFeatureSink, + QgsCoordinateReferenceSystem, + QgsFields, + QgsField, + QgsWkbTypes, +) from DsgTools.tests.test_ValidationAlgorithms import Tester from DsgTools.core.GeometricTools.featureHandler import FeatureHandler + class MultipleOutputUnitTestAlgorithm(QgsProcessingAlgorithm): - __description__ = """Runs unit tests for a set of DSGTools algorithms that""" \ - """has single output - in-place modified or otherwise.""" + __description__ = ( + """Runs unit tests for a set of DSGTools algorithms that""" + """has single output - in-place modified or otherwise.""" + ) AVAILABLE_ALGS = [ "dsgtools:unbuildpolygonsalgorithm", - "dsgtools:buildpolygonsfromcenterpointsandboundariesalgorithm" + "dsgtools:buildpolygonsfromcenterpointsandboundariesalgorithm", ] - INPUT_ALGS = 'INPUT_ALGS' - OUTPUT = 'OUTPUT' + INPUT_ALGS = "INPUT_ALGS" + OUTPUT = "OUTPUT" def __init__(self): super(MultipleOutputUnitTestAlgorithm, self).__init__() @@ -56,43 +61,41 @@ def initAlgorithm(self, config=None): self.addParameter( QgsProcessingParameterEnum( self.INPUT_ALGS, - self.tr('Algorithms to be tested'), + self.tr("Algorithms to be tested"), options=self.AVAILABLE_ALGS, optional=False, - allowMultiple=True - + allowMultiple=True, ) ) self.addParameter( QgsProcessingParameterFeatureSink( - self.OUTPUT, - self.tr("DSGTools Multiple Output Algorithms Unit Tests") + self.OUTPUT, self.tr("DSGTools Multiple Output Algorithms Unit Tests") ) ) - + def name(self): """ Returns the algorithm name, used for identifying the algorithm. This - string should be fixed for the algorithm, and must not be localised + string should be fixed for the algorithm, and must not be localised (e.g. must be ASCII). The name should be unique within each provider. - Names should contain lowercase alphanumeric characters only and no + Names should contain lowercase alphanumeric characters only and no spaces or other formatting characters. """ - return 'multipleoutputunittest' + return "multipleoutputunittest" def displayName(self): """ Returns the translated algorithm name, which should be used for any user-visible display of the algorithm name. """ - return self.tr('Multiple Output Algorithms Unit Test') + return self.tr("Multiple Output Algorithms Unit Test") def group(self): """ Returns the name of the group this algorithm belongs to. This string should be localised. """ - return self.tr('Other Algorithms') + return self.tr("Other Algorithms") def groupId(self): """ @@ -102,10 +105,10 @@ def groupId(self): contain lowercase alphanumeric characters only and no spaces or other formatting characters. """ - return 'DSGTools: Other Algorithms' + return "DSGTools: Other Algorithms" def tr(self, string): - return QCoreApplication.translate('MultipleOutputUnitTestAlgorithm', string) + return QCoreApplication.translate("MultipleOutputUnitTestAlgorithm", string) def createInstance(self): """ @@ -118,9 +121,9 @@ def getFields(self): Gets all fields for output layer. """ fields = QgsFields() - fields.append(QgsField('algorithm', QVariant.String)) - fields.append(QgsField('tests_output', QVariant.String)) - fields.append(QgsField('status', QVariant.String)) + fields.append(QgsField("algorithm", QVariant.String)) + fields.append(QgsField("tests_output", QVariant.String)) + fields.append(QgsField("status", QVariant.String)) return fields def processAlgorithm(self, parameters, context, feedback): @@ -128,8 +131,12 @@ def processAlgorithm(self, parameters, context, feedback): Here is where the processing itself takes place. """ algsOutput, dest_id = self.parameterAsSink( - parameters, self.OUTPUT, context, self.getFields(), - QgsWkbTypes.NoGeometry, QgsCoordinateReferenceSystem('EPSG:4326') + parameters, + self.OUTPUT, + context, + self.getFields(), + QgsWkbTypes.NoGeometry, + QgsCoordinateReferenceSystem("EPSG:4326"), ) tester = Tester() featureHandler = FeatureHandler() @@ -149,9 +156,10 @@ def processAlgorithm(self, parameters, context, feedback): msg = tester.testAlg( alg, multipleOutputs=True, - attributeBlackList=['path'], + attributeBlackList=["path"], addControlKey=True, - context=context) #, feedback=feedback, context=context) + context=context, + ) # , feedback=feedback, context=context) status = self.tr("Failed") if msg else self.tr("Passed") pushMethod = feedback.reportError if msg else feedback.pushDebugInfo failCount += 1 if msg else 0 @@ -160,14 +168,20 @@ def processAlgorithm(self, parameters, context, feedback): feats.add( featureHandler.createFeatureFromLayer( algsOutput, - attributes={"algorithm" : alg, "tests_output" : msg, "status" : status}, - fields=fields + attributes={ + "algorithm": alg, + "tests_output": msg, + "status": status, + }, + fields=fields, ) ) feedback.setProgress(currentStep * totalProgress) algsOutput.addFeatures(feats, QgsFeatureSink.FastInsert) if failCount: - feedback.reportError(self.tr("{0} algorithms failed their unit tests.").format(failCount)) + feedback.reportError( + self.tr("{0} algorithms failed their unit tests.").format(failCount) + ) else: feedback.pushDebugInfo(self.tr("All algorithms passed their unit tests.")) - return { self.OUTPUT : dest_id } + return {self.OUTPUT: dest_id} diff --git a/DsgTools/core/DSGToolsProcessingAlgs/Algs/OtherAlgs/pecCalculatorAlgorithm.py b/DsgTools/core/DSGToolsProcessingAlgs/Algs/OtherAlgs/pecCalculatorAlgorithm.py index 2e81c7339..14faaf31b 100644 --- a/DsgTools/core/DSGToolsProcessingAlgs/Algs/OtherAlgs/pecCalculatorAlgorithm.py +++ b/DsgTools/core/DSGToolsProcessingAlgs/Algs/OtherAlgs/pecCalculatorAlgorithm.py @@ -27,35 +27,38 @@ from ...algRunner import AlgRunner import processing from PyQt5.QtCore import QCoreApplication -from qgis.core import (QgsProcessing, - QgsFeatureSink, - QgsProcessingAlgorithm, - QgsProcessingParameterFeatureSource, - QgsProcessingParameterFeatureSink, - QgsFeature, - QgsDataSourceUri, - QgsProcessingOutputVectorLayer, - QgsProcessingParameterVectorLayer, - QgsWkbTypes, - QgsProcessingParameterBoolean, - QgsProcessingParameterEnum, - QgsProcessingParameterNumber, - QgsProcessingParameterMultipleLayers, - QgsProcessingUtils, - QgsSpatialIndex, - QgsGeometry, - QgsProcessingParameterField, - QgsProcessingMultiStepFeedback, - QgsProcessingParameterFile, - QgsProcessingParameterExpression, - QgsProcessingException, - QgsFeatureRequest, - QgsRectangle) +from qgis.core import ( + QgsProcessing, + QgsFeatureSink, + QgsProcessingAlgorithm, + QgsProcessingParameterFeatureSource, + QgsProcessingParameterFeatureSink, + QgsFeature, + QgsDataSourceUri, + QgsProcessingOutputVectorLayer, + QgsProcessingParameterVectorLayer, + QgsWkbTypes, + QgsProcessingParameterBoolean, + QgsProcessingParameterEnum, + QgsProcessingParameterNumber, + QgsProcessingParameterMultipleLayers, + QgsProcessingUtils, + QgsSpatialIndex, + QgsGeometry, + QgsProcessingParameterField, + QgsProcessingMultiStepFeedback, + QgsProcessingParameterFile, + QgsProcessingParameterExpression, + QgsProcessingException, + QgsFeatureRequest, + QgsRectangle, +) + class PecCalculatorAlgorithm(QgsProcessingAlgorithm): - INPUT = 'INPUT' - REFERENCE = 'REFERENCE' - TOLERANCE = 'TOLERANCE' + INPUT = "INPUT" + REFERENCE = "REFERENCE" + TOLERANCE = "TOLERANCE" # OUTPUT = 'OUTPUT' def initAlgorithm(self, config): @@ -64,51 +67,36 @@ def initAlgorithm(self, config): """ self.addParameter( QgsProcessingParameterVectorLayer( - self.INPUT, - self.tr('Input layer'), - [QgsProcessing.TypeVectorPoint] + self.INPUT, self.tr("Input layer"), [QgsProcessing.TypeVectorPoint] ) ) self.addParameter( QgsProcessingParameterVectorLayer( self.REFERENCE, - self.tr('Reference layer'), - [QgsProcessing.TypeVectorPoint] + self.tr("Reference layer"), + [QgsProcessing.TypeVectorPoint], ) ) self.addParameter( QgsProcessingParameterNumber( self.TOLERANCE, - self.tr('Max distance'), + self.tr("Max distance"), minValue=0, type=QgsProcessingParameterNumber.Double, - defaultValue=2 + defaultValue=2, ) ) - def processAlgorithm(self, parameters, context, feedback): """ Here is where the processing itself takes place. """ - inputLyr = self.parameterAsVectorLayer( - parameters, - self.INPUT, - context - ) - referenceLyr = self.parameterAsVectorLayer( - parameters, - self.REFERENCE, - context - ) - tol = self.parameterAsDouble( - parameters, - self.TOLERANCE, - context - ) + inputLyr = self.parameterAsVectorLayer(parameters, self.INPUT, context) + referenceLyr = self.parameterAsVectorLayer(parameters, self.REFERENCE, context) + tol = self.parameterAsDouble(parameters, self.TOLERANCE, context) distanceDict = dict() featList = [i for i in inputLyr.getFeatures()] - step = 100/len(featList) if featList else 0 + step = 100 / len(featList) if featList else 0 for current, feat in enumerate(featList): if feedback.isCanceled(): break @@ -118,12 +106,7 @@ def processAlgorithm(self, parameters, context, feedback): geom = feat.geometry().asGeometryCollection()[0].asPoint() x = geom.x() y = geom.y() - bbox = QgsRectangle( - x-tol, - y-tol, - x+tol, - y+tol - ) + bbox = QgsRectangle(x - tol, y - tol, x + tol, y + tol) request = QgsFeatureRequest() request.setFilterRect(bbox) minDistance = 0 @@ -139,26 +122,25 @@ def processAlgorithm(self, parameters, context, feedback): candidateId = candidateFeat.id() if candidateId is not None: distanceDict[id] = { - 'minDistance' : minDistance, - 'candidateId' : candidateId + "minDistance": minDistance, + "candidateId": candidateId, } - feedback.setProgress(current*step) - - - distanceList = [i['minDistance'] for i in distanceDict.values()] + feedback.setProgress(current * step) + + distanceList = [i["minDistance"] for i in distanceDict.values()] n = len(distanceList) - distanceSquared = [i['minDistance']**2 for i in distanceDict.values()] - rms = math.sqrt(sum(distanceSquared)/n) + distanceSquared = [i["minDistance"] ** 2 for i in distanceDict.values()] + rms = math.sqrt(sum(distanceSquared) / n) percFunc = functools.partial(self.percentile, frequency=0.9) perc = percFunc(distanceList) - mean = sum(distanceList)/n - feedback.pushInfo('MEAN: {mean}'.format(mean=mean)) - feedback.pushInfo('RMS: {rms}'.format(rms=rms)) - feedback.pushInfo('PERC: {perc}'.format(perc=perc)) + mean = sum(distanceList) / n + feedback.pushInfo("MEAN: {mean}".format(mean=mean)) + feedback.pushInfo("RMS: {rms}".format(rms=rms)) + feedback.pushInfo("PERC: {perc}".format(perc=perc)) return {} - - def percentile(self, N, frequency, key=lambda x:x): + + def percentile(self, N, frequency, key=lambda x: x): """ Find the percentile of a list of values. @@ -173,7 +155,7 @@ def percentile(self, N, frequency, key=lambda x:x): sortedN = sorted(N) if len(sortedN) < 1: return 0 if not sortedN else 1 - if frequency <= 0 : + if frequency <= 0: return sortedN[0] elif frequency >= 1: return sortedN[-1] @@ -183,8 +165,9 @@ def percentile(self, N, frequency, key=lambda x:x): top = math.ceil(position) if top == bottom: return sortedN[top] - return (sortedN[bottom] * (1. + bottom - position) + sortedN[top] * (1. + position - top) ) - + return sortedN[bottom] * (1.0 + bottom - position) + sortedN[top] * ( + 1.0 + position - top + ) def name(self): """ @@ -194,21 +177,21 @@ def name(self): lowercase alphanumeric characters only and no spaces or other formatting characters. """ - return 'peccalculator' + return "peccalculator" def displayName(self): """ Returns the translated algorithm name, which should be used for any user-visible display of the algorithm name. """ - return self.tr('Calculate RMS and Percentile 90 of Layer') + return self.tr("Calculate RMS and Percentile 90 of Layer") def group(self): """ Returns the name of the group this algorithm belongs to. This string should be localised. """ - return self.tr('Data Quality') + return self.tr("Data Quality") def groupId(self): """ @@ -216,10 +199,10 @@ def groupId(self): string should be fixed for the algorithm, and must not be localised. The group id should be unique within each provider. """ - return 'DSGTools: Data Quality' + return "DSGTools: Data Quality" def tr(self, string): - return QCoreApplication.translate('PecCalculatorAlgorithm', string) + return QCoreApplication.translate("PecCalculatorAlgorithm", string) def createInstance(self): - return PecCalculatorAlgorithm() \ No newline at end of file + return PecCalculatorAlgorithm() diff --git a/DsgTools/core/DSGToolsProcessingAlgs/Algs/OtherAlgs/raiseFlagsAlgorithm.py b/DsgTools/core/DSGToolsProcessingAlgs/Algs/OtherAlgs/raiseFlagsAlgorithm.py index b2d8d7d96..4ec29352a 100644 --- a/DsgTools/core/DSGToolsProcessingAlgs/Algs/OtherAlgs/raiseFlagsAlgorithm.py +++ b/DsgTools/core/DSGToolsProcessingAlgs/Algs/OtherAlgs/raiseFlagsAlgorithm.py @@ -27,48 +27,51 @@ from ...algRunner import AlgRunner import processing, os, requests from PyQt5.QtCore import QCoreApplication -from qgis.core import (QgsProcessing, - QgsFeatureSink, - QgsProcessingAlgorithm, - QgsProcessingParameterFeatureSource, - QgsProcessingParameterFeatureSink, - QgsFeature, - QgsDataSourceUri, - QgsProcessingOutputVectorLayer, - QgsProcessingParameterVectorLayer, - QgsWkbTypes, - QgsProcessingParameterBoolean, - QgsProcessingParameterEnum, - QgsProcessingParameterNumber, - QgsProcessingParameterMultipleLayers, - QgsProcessingUtils, - QgsSpatialIndex, - QgsGeometry, - QgsProcessingParameterField, - QgsProcessingMultiStepFeedback, - QgsProcessingParameterFolderDestination, - QgsProcessingParameterExpression, - QgsProcessingException, - QgsProcessingParameterString, - QgsProcessingParameterDefinition, - QgsProcessingParameterType, - QgsProcessingParameterMatrix, - QgsProcessingParameterFile, - QgsCoordinateReferenceSystem, - QgsProject, - QgsFields, - QgsProcessingParameterCrs, - QgsCoordinateTransform, - QgsVectorLayer) +from qgis.core import ( + QgsProcessing, + QgsFeatureSink, + QgsProcessingAlgorithm, + QgsProcessingParameterFeatureSource, + QgsProcessingParameterFeatureSink, + QgsFeature, + QgsDataSourceUri, + QgsProcessingOutputVectorLayer, + QgsProcessingParameterVectorLayer, + QgsWkbTypes, + QgsProcessingParameterBoolean, + QgsProcessingParameterEnum, + QgsProcessingParameterNumber, + QgsProcessingParameterMultipleLayers, + QgsProcessingUtils, + QgsSpatialIndex, + QgsGeometry, + QgsProcessingParameterField, + QgsProcessingMultiStepFeedback, + QgsProcessingParameterFolderDestination, + QgsProcessingParameterExpression, + QgsProcessingException, + QgsProcessingParameterString, + QgsProcessingParameterDefinition, + QgsProcessingParameterType, + QgsProcessingParameterMatrix, + QgsProcessingParameterFile, + QgsCoordinateReferenceSystem, + QgsProject, + QgsFields, + QgsProcessingParameterCrs, + QgsCoordinateTransform, + QgsVectorLayer, +) + class RaiseFlagsAlgorithm(QgsProcessingAlgorithm): - INPUT = 'INPUT' - FLAG_FIELD = 'FLAG_FIELD' - TABLE_SCHEMA = 'TABLE_SCHEMA' - TABLE_NAME = 'TABLE_NAME' - OUTPUT_FLAG_TEXT_FIELD = 'OUTPUT_FLAG_TEXT_FIELD' - GEOMETRY_COLUMN = 'GEOMETRY_COLUMN' - CRS = 'CRS' + INPUT = "INPUT" + FLAG_FIELD = "FLAG_FIELD" + TABLE_SCHEMA = "TABLE_SCHEMA" + TABLE_NAME = "TABLE_NAME" + OUTPUT_FLAG_TEXT_FIELD = "OUTPUT_FLAG_TEXT_FIELD" + GEOMETRY_COLUMN = "GEOMETRY_COLUMN" + CRS = "CRS" def initAlgorithm(self, config): """ @@ -76,49 +79,33 @@ def initAlgorithm(self, config): """ self.addParameter( QgsProcessingParameterVectorLayer( - self.INPUT, - self.tr('Input'), - [QgsProcessing.TypeVectorAnyGeometry] + self.INPUT, self.tr("Input"), [QgsProcessing.TypeVectorAnyGeometry] ) ) self.addParameter( QgsProcessingParameterField( self.FLAG_FIELD, - self.tr('Flag text field'), - parentLayerParameterName=self.INPUT + self.tr("Flag text field"), + parentLayerParameterName=self.INPUT, ) ) self.addParameter( - QgsProcessingParameterString( - self.TABLE_SCHEMA, - self.tr('Table schema') - ) + QgsProcessingParameterString(self.TABLE_SCHEMA, self.tr("Table schema")) ) self.addParameter( - QgsProcessingParameterString( - self.TABLE_NAME, - self.tr('Table name') - ) + QgsProcessingParameterString(self.TABLE_NAME, self.tr("Table name")) ) self.addParameter( QgsProcessingParameterString( - self.GEOMETRY_COLUMN, - self.tr('Geometry column') + self.GEOMETRY_COLUMN, self.tr("Geometry column") ) ) self.addParameter( QgsProcessingParameterString( - self.OUTPUT_FLAG_TEXT_FIELD, - self.tr('Flag text field') + self.OUTPUT_FLAG_TEXT_FIELD, self.tr("Flag text field") ) ) - self.addParameter( - QgsProcessingParameterCrs( - self.CRS, - self.tr('CRS') - ) - ) - + self.addParameter(QgsProcessingParameterCrs(self.CRS, self.tr("CRS"))) def processAlgorithm(self, parameters, context, feedback): """ @@ -128,59 +115,72 @@ def processAlgorithm(self, parameters, context, feedback): layerHandler = LayerHandler() inputLyr = self.parameterAsVectorLayer(parameters, self.INPUT, context) if inputLyr is None: - raise QgsProcessingException(self.invalidSourceError(parameters, self.INPUT)) + raise QgsProcessingException( + self.invalidSourceError(parameters, self.INPUT) + ) inputAttr = self.parameterAsFields(parameters, self.FLAG_FIELD, context) inputAttr = inputAttr[0] tableSchema = self.parameterAsString(parameters, self.TABLE_SCHEMA, context) - if tableSchema is None or tableSchema == '': - raise QgsProcessingException(self.tr('Invalid table schema')) - + if tableSchema is None or tableSchema == "": + raise QgsProcessingException(self.tr("Invalid table schema")) + tableName = self.parameterAsString(parameters, self.TABLE_NAME, context) - if tableName is None or tableName == '': - raise QgsProcessingException(self.tr('Invalid table name')) + if tableName is None or tableName == "": + raise QgsProcessingException(self.tr("Invalid table name")) - geometryColumn = self.parameterAsString(parameters, self.GEOMETRY_COLUMN, context) - if geometryColumn is None or geometryColumn == '': - raise QgsProcessingException(self.tr('Invalid geometry column')) - - flagTextAttr = self.parameterAsString(parameters, self.OUTPUT_FLAG_TEXT_FIELD, context) - if flagTextAttr is None or flagTextAttr == '': - raise QgsProcessingException(self.tr('Invalid flag attribute column')) + geometryColumn = self.parameterAsString( + parameters, self.GEOMETRY_COLUMN, context + ) + if geometryColumn is None or geometryColumn == "": + raise QgsProcessingException(self.tr("Invalid geometry column")) + + flagTextAttr = self.parameterAsString( + parameters, self.OUTPUT_FLAG_TEXT_FIELD, context + ) + if flagTextAttr is None or flagTextAttr == "": + raise QgsProcessingException(self.tr("Invalid flag attribute column")) crs = self.parameterAsCrs(parameters, self.CRS, context) if crs is None or not crs.isValid(): - raise QgsProcessingException(self.tr('Invalid CRS.')) - - outputLyr = self.getOutputFromInput(inputLyr, tableSchema, tableName, geometryColumn) + raise QgsProcessingException(self.tr("Invalid CRS.")) + + outputLyr = self.getOutputFromInput( + inputLyr, tableSchema, tableName, geometryColumn + ) if not outputLyr.isValid(): - raise QgsProcessingException(self.tr('Invalid output layer.')) + raise QgsProcessingException(self.tr("Invalid output layer.")) coordinateTransformer = QgsCoordinateTransform( QgsCoordinateReferenceSystem(crs.geographicCrsAuthId()), crs, - QgsProject.instance() - ) + QgsProject.instance(), + ) parameterDict = layerHandler.getDestinationParameters(outputLyr) outputLyr.startEditing() - outputLyr.beginEditCommand('Adding flag features') + outputLyr.beginEditCommand("Adding flag features") count = inputLyr.featureCount() progress_count = 100 / count if count else 0 for current, feat in enumerate(inputLyr.getFeatures()): if feedback.isCanceled(): break - for newFeat in featureHandler.handleConvertedFeature(feat, outputLyr, parameterDict=parameterDict, coordinateTransformer=coordinateTransformer): + for newFeat in featureHandler.handleConvertedFeature( + feat, + outputLyr, + parameterDict=parameterDict, + coordinateTransformer=coordinateTransformer, + ): newFeat[flagTextAttr] = feat[inputAttr] outputLyr.addFeature(newFeat) feedback.setProgress(current * progress_count) outputLyr.endEditCommand() outputLyr.commitChanges() return {} - + def getOutputFromInput(self, inputLyr, tableSchema, tableName, geometryColumn): lyrUri = inputLyr.dataProvider().dataSourceUri() uri = QgsDataSourceUri(lyrUri) uri.setDataSource(tableSchema, tableName, geometryColumn) - outputLyr = QgsVectorLayer(uri.uri(), tableName, 'postgres') + outputLyr = QgsVectorLayer(uri.uri(), tableName, "postgres") return outputLyr def name(self): @@ -191,21 +191,21 @@ def name(self): lowercase alphanumeric characters only and no spaces or other formatting characters. """ - return 'raiseflags' + return "raiseflags" def displayName(self): """ Returns the translated algorithm name, which should be used for any user-visible display of the algorithm name. """ - return self.tr('Raise Flags') + return self.tr("Raise Flags") def group(self): """ Returns the name of the group this algorithm belongs to. This string should be localised. """ - return self.tr('Other Algorithms') + return self.tr("Other Algorithms") def groupId(self): """ @@ -215,10 +215,10 @@ def groupId(self): contain lowercase alphanumeric characters only and no spaces or other formatting characters. """ - return 'DSGTools: Other Algorithms' + return "DSGTools: Other Algorithms" def tr(self, string): - return QCoreApplication.translate('RaiseFlagsAlgorithm', string) + return QCoreApplication.translate("RaiseFlagsAlgorithm", string) def createInstance(self): - return RaiseFlagsAlgorithm() \ No newline at end of file + return RaiseFlagsAlgorithm() diff --git a/DsgTools/core/DSGToolsProcessingAlgs/Algs/OtherAlgs/ruleStatisticsAlgorithm.py b/DsgTools/core/DSGToolsProcessingAlgs/Algs/OtherAlgs/ruleStatisticsAlgorithm.py index 7f2015194..9f031cc5b 100755 --- a/DsgTools/core/DSGToolsProcessingAlgs/Algs/OtherAlgs/ruleStatisticsAlgorithm.py +++ b/DsgTools/core/DSGToolsProcessingAlgs/Algs/OtherAlgs/ruleStatisticsAlgorithm.py @@ -22,33 +22,36 @@ from PyQt5.QtCore import QCoreApplication import json -from qgis.core import (QgsProcessing, - QgsFeatureSink, - QgsProcessingAlgorithm, - QgsProcessingParameterFeatureSource, - QgsProcessingParameterFeatureSink, - QgsFeature, - QgsDataSourceUri, - QgsProcessingOutputVectorLayer, - QgsProcessingParameterVectorLayer, - QgsProcessingParameterString, - QgsWkbTypes, - QgsProcessingParameterBoolean, - QgsProcessingParameterMultipleLayers, - QgsWkbTypes, - QgsProcessingUtils, - QgsProject, - QgsProcessingParameterEnum, - QgsProcessingParameterFile) +from qgis.core import ( + QgsProcessing, + QgsFeatureSink, + QgsProcessingAlgorithm, + QgsProcessingParameterFeatureSource, + QgsProcessingParameterFeatureSink, + QgsFeature, + QgsDataSourceUri, + QgsProcessingOutputVectorLayer, + QgsProcessingParameterVectorLayer, + QgsProcessingParameterString, + QgsWkbTypes, + QgsProcessingParameterBoolean, + QgsProcessingParameterMultipleLayers, + QgsWkbTypes, + QgsProcessingUtils, + QgsProject, + QgsProcessingParameterEnum, + QgsProcessingParameterFile, +) from operator import itemgetter from collections import defaultdict import fnmatch + class RuleStatisticsAlgorithm(QgsProcessingAlgorithm): - INPUTLAYERS = 'INPUTLAYERS' - RULEFILE = 'RULEFILE' - RULEDATA = 'RULEDATA' - OUTPUT = 'OUTPUT' + INPUTLAYERS = "INPUTLAYERS" + RULEFILE = "RULEFILE" + RULEDATA = "RULEDATA" + OUTPUT = "OUTPUT" def __init__(self): super(RuleStatisticsAlgorithm, self).__init__() @@ -59,23 +62,22 @@ def initAlgorithm(self, config=None): """ self.addParameter( QgsProcessingParameterMultipleLayers( - self.INPUTLAYERS, - 'Camadas de entrada :' + self.INPUTLAYERS, "Camadas de entrada :" ) ) self.addParameter( QgsProcessingParameterFile( self.RULEFILE, - description = 'Arquivo ".json" com regras :', - defaultValue = '.json' + description='Arquivo ".json" com regras :', + defaultValue=".json", ) ) self.addParameter( QgsProcessingParameterString( self.RULEDATA, - description = 'Regras no formato "json" :', - multiLine = True, - defaultValue = '{}' + description='Regras no formato "json" :', + multiLine=True, + defaultValue="{}", ) ) @@ -85,79 +87,96 @@ def processAlgorithm(self, parameters, context, feedback): """ layers_list = self.parameterAsLayerList(parameters, self.INPUTLAYERS, context) inputLyrNamesWithSchemaList = [ - f"{lyr.dataProvider().uri().schema()}.{lyr.dataProvider().uri().table()}" for lyr in layers_list + f"{lyr.dataProvider().uri().schema()}.{lyr.dataProvider().uri().table()}" + for lyr in layers_list ] input_data = self.load_rules_from_parameters(parameters) rows = self.buildRuleDict(input_data[0], inputLyrNamesWithSchemaList) result = {} for i, row in enumerate(rows): - if not row['type'] in result: - result[row['type']] = [] - failed = self.check_rules_on_layers( - row['attribute'], - row['rule'], + if not row["type"] in result: + result[row["type"]] = [] + failed = self.check_rules_on_layers( + row["attribute"], + row["rule"], [ - lyr for lyr in layers_list - if f"{lyr.dataProvider().uri().schema()}.{lyr.dataProvider().uri().table()}" in row['layers'] - ] + lyr + for lyr in layers_list + if f"{lyr.dataProvider().uri().schema()}.{lyr.dataProvider().uri().table()}" + in row["layers"] + ], ) - result[row['type']].append(failed) + result[row["type"]].append(failed) if not input_data: - self.print_log('Carregue um arquivos com as Regras ou insira as Regras!', feedback) + self.print_log( + "Carregue um arquivos com as Regras ou insira as Regras!", feedback + ) return {} - return { self.OUTPUT : self.format_output_result(result) } + return {self.OUTPUT: self.format_output_result(result)} def buildRuleDict(self, inputData, inputLyrNamesWithSchemaList): ruleDict = [] styleDict = { style["tipo_estilo"]: { "corRgb": list(map(int, style["cor_rgb"].split(","))), - "rank": idx - } for idx, style in enumerate(inputData["grupo_estilo"]) + "rank": idx, + } + for idx, style in enumerate(inputData["grupo_estilo"]) } for rule in inputData["regras"]: lyrSet = self.getLayerNames(rule["camadas"], inputLyrNamesWithSchemaList) - ruleDict.append({ - 'type': rule['tipo_estilo'], - 'name': rule['descricao'], - 'rule': rule['regra'], - 'attribute': rule['atributo'], - 'layers': list(lyrSet) - }) + ruleDict.append( + { + "type": rule["tipo_estilo"], + "name": rule["descricao"], + "rule": rule["regra"], + "attribute": rule["atributo"], + "layers": list(lyrSet), + } + ) return ruleDict - + def getLayerNames(self, filterList, nameList): outputSet = set() - wildCardFilterList = [filterItem for filterItem in filterList if "*" in filterItem] + wildCardFilterList = [ + filterItem for filterItem in filterList if "*" in filterItem + ] for wildCardFilter in wildCardFilterList: outputSet = outputSet.union(set(fnmatch.filter(nameList, wildCardFilter))) - outputSet = outputSet.union(set(name for name in nameList if name in filterList)) + outputSet = outputSet.union( + set(name for name in nameList if name in filterList) + ) return outputSet def print_log(self, number, text, feedback): - feedback.pushInfo("{0}{1}LOG START - {2}{1}{0}\n\n".format('*'*10, ' '*3, number+1)) + feedback.pushInfo( + "{0}{1}LOG START - {2}{1}{0}\n\n".format("*" * 10, " " * 3, number + 1) + ) feedback.pushInfo(text) - feedback.pushInfo("{0}{1}LOG END - {2}{1}{0}\n\n".format('*'*10, ' '*3, number+1)) - + feedback.pushInfo( + "{0}{1}LOG END - {2}{1}{0}\n\n".format("*" * 10, " " * 3, number + 1) + ) + def load_rules_from_parameters(self, parameters): rules_input = [] rules_path = parameters[self.RULEFILE] rules_text = parameters[self.RULEDATA] - if rules_path and rules_path != '.json': - with open(rules_path, 'r') as f: - rules_input.append( - json.load(f) - ) - if rules_text and rules_text != '{}': - rules_input.append( - json.loads(rules_text) - ) + if rules_path and rules_path != ".json": + with open(rules_path, "r") as f: + rules_input.append(json.load(f)) + if rules_text and rules_text != "{}": + rules_input.append(json.loads(rules_text)) return rules_input def hasAttribute(self, attribute, lyr): - return len([ c for c in lyr.attributeTableConfig().columns() if c.name == attribute ]) != 0 - + return ( + len( + [c for c in lyr.attributeTableConfig().columns() if c.name == attribute] + ) + != 0 + ) + def check_rules_on_layers(self, attribute, rule, layers): failed = {} for lyr in layers: @@ -171,7 +190,7 @@ def check_rules_on_layers(self, attribute, rule, layers): return failed def format_output_result(self, result): - html="" + html = "" for ruleName in sorted(result.keys()): row = "[REGRAS] : {0}\n\n".format(ruleName) html += row @@ -192,26 +211,26 @@ def format_output_result(self, result): rows = "As camadas passaram em todas as regras.\n\n" html += rows return html - + def name(self): """ Here is where the processing itself takes place. """ - return 'rulestatistics' + return "rulestatistics" def displayName(self): """ Returns the translated algorithm name, which should be used for any user-visible display of the algorithm name. """ - return self.tr('Rule Statistics') + return self.tr("Rule Statistics") def group(self): """ Returns the name of the group this algorithm belongs to. This string should be localised. """ - return self.tr('Other Algorithms') + return self.tr("Other Algorithms") def groupId(self): """ @@ -221,10 +240,10 @@ def groupId(self): contain lowercase alphanumeric characters only and no spaces or other formatting characters. """ - return 'DSGTools: Other Algorithms' + return "DSGTools: Other Algorithms" def tr(self, string): - return QCoreApplication.translate('RuleStatisticsAlgorithm', string) + return QCoreApplication.translate("RuleStatisticsAlgorithm", string) def createInstance(self): - return RuleStatisticsAlgorithm() \ No newline at end of file + return RuleStatisticsAlgorithm() diff --git a/DsgTools/core/DSGToolsProcessingAlgs/Algs/OtherAlgs/runFMESAPAlgorithm.py b/DsgTools/core/DSGToolsProcessingAlgs/Algs/OtherAlgs/runFMESAPAlgorithm.py index dfc7198ce..a417df9ff 100644 --- a/DsgTools/core/DSGToolsProcessingAlgs/Algs/OtherAlgs/runFMESAPAlgorithm.py +++ b/DsgTools/core/DSGToolsProcessingAlgs/Algs/OtherAlgs/runFMESAPAlgorithm.py @@ -8,7 +8,7 @@ begin : 2020-08-11 git sha : $Format:%H$ copyright : (C) 2020 by Jossan - email : + email : ***************************************************************************/ /*************************************************************************** @@ -23,49 +23,52 @@ from PyQt5.QtCore import QCoreApplication from PyQt5.QtGui import QColor from qgis.PyQt.Qt import QVariant -from qgis.core import (QgsProcessing, - QgsFeatureSink, - QgsProcessingAlgorithm, - QgsProcessingParameterFeatureSource, - QgsProcessingParameterFeatureSink, - QgsFeature, - QgsDataSourceUri, - QgsProcessingOutputVectorLayer, - QgsProcessingParameterVectorLayer, - QgsWkbTypes, - QgsProcessingParameterBoolean, - QgsProcessingParameterEnum, - QgsProcessingParameterNumber, - QgsProcessingParameterMultipleLayers, - QgsProcessingUtils, - QgsSpatialIndex, - QgsGeometry, - QgsProcessingParameterField, - QgsProcessingMultiStepFeedback, - QgsProcessingParameterFile, - QgsProcessingParameterExpression, - QgsProcessingException, - QgsProcessingParameterString, - QgsProcessingParameterDefinition, - QgsProcessingParameterType, - QgsProcessingParameterCrs, - QgsCoordinateTransform, - QgsProject, - QgsCoordinateReferenceSystem, - QgsField, - QgsFields, - QgsProcessingOutputMultipleLayers, - QgsProcessingParameterString, - QgsConditionalStyle) +from qgis.core import ( + QgsProcessing, + QgsFeatureSink, + QgsProcessingAlgorithm, + QgsProcessingParameterFeatureSource, + QgsProcessingParameterFeatureSink, + QgsFeature, + QgsDataSourceUri, + QgsProcessingOutputVectorLayer, + QgsProcessingParameterVectorLayer, + QgsWkbTypes, + QgsProcessingParameterBoolean, + QgsProcessingParameterEnum, + QgsProcessingParameterNumber, + QgsProcessingParameterMultipleLayers, + QgsProcessingUtils, + QgsSpatialIndex, + QgsGeometry, + QgsProcessingParameterField, + QgsProcessingMultiStepFeedback, + QgsProcessingParameterFile, + QgsProcessingParameterExpression, + QgsProcessingException, + QgsProcessingParameterString, + QgsProcessingParameterDefinition, + QgsProcessingParameterType, + QgsProcessingParameterCrs, + QgsCoordinateTransform, + QgsProject, + QgsCoordinateReferenceSystem, + QgsField, + QgsFields, + QgsProcessingOutputMultipleLayers, + QgsProcessingParameterString, + QgsConditionalStyle, +) from operator import itemgetter from collections import defaultdict import processing, os, requests, json from time import sleep + class RunFMESAPAlgorithm(QgsProcessingAlgorithm): - FILE = 'FILE' - TEXT = 'TEXT' - OUTPUT = 'OUTPUT' + FILE = "FILE" + TEXT = "TEXT" + OUTPUT = "OUTPUT" def initAlgorithm(self, config): """ @@ -73,26 +76,21 @@ def initAlgorithm(self, config): """ self.addParameter( QgsProcessingParameterFile( - self.FILE, - self.tr('Input json file'), - defaultValue = ".json" + self.FILE, self.tr("Input json file"), defaultValue=".json" ) ) self.addParameter( QgsProcessingParameterString( self.TEXT, - description = self.tr('Input json text'), - multiLine = True, - defaultValue = '[]' + description=self.tr("Input json text"), + multiLine=True, + defaultValue="[]", ) ) self.addOutput( - QgsProcessingOutputMultipleLayers( - self.OUTPUT, - self.tr('HTML text') - ) + QgsProcessingOutputMultipleLayers(self.OUTPUT, self.tr("HTML text")) ) def processAlgorithm(self, parameters, context, feedback): @@ -100,50 +98,42 @@ def processAlgorithm(self, parameters, context, feedback): Here is where the processing itself takes place. """ - inputJSONFile = self.parameterAsFile( - parameters, - self.FILE, - context - ) + inputJSONFile = self.parameterAsFile(parameters, self.FILE, context) inputJSONData = json.loads( - self.parameterAsString( - parameters, - self.TEXT, - context - ) + self.parameterAsString(parameters, self.TEXT, context) ) if os.path.exists(inputJSONFile): return self.runFMEFromJSONFile(inputJSONFile, feedback) elif len(inputJSONData) > 0: return self.runFMEFromJSONData(inputJSONData, feedback) - return {self.OUTPUT: ''} + return {self.OUTPUT: ""} def runFMEFromJSONFile(self, inputJSONFile, feedback): inputJSONData = json.load(inputJSONFile) return self.runFMEFromJSONData(inputJSONData, feedback) - + def runFMEFromJSONData(self, inputJSONData, feedback): - - header = {'content-type': 'application/json'} + + header = {"content-type": "application/json"} session = requests.Session() session.trust_env = False - url = '{server}/versions/{workspace_id}/jobs'.format( - server=inputJSONData['server'], - workspace_id=inputJSONData['workspace_id'] + url = "{server}/versions/{workspace_id}/jobs".format( + server=inputJSONData["server"], workspace_id=inputJSONData["workspace_id"] ) - response = session.post(url, data=json.dumps({ 'parameters' : inputJSONData}), headers=header) - + response = session.post( + url, data=json.dumps({"parameters": inputJSONData}), headers=header + ) + if not response: - return {self.OUTPUT: '

Erro ao iniciar rotina.

'} + return {self.OUTPUT: "

Erro ao iniciar rotina.

"} - url_to_status = '{server}/jobs/{uuid}'.format( - server=fmeDict['server'], - uuid=response.json()['data']['job_uuid'] + url_to_status = "{server}/jobs/{uuid}".format( + server=fmeDict["server"], uuid=response.json()["data"]["job_uuid"] ) for _ in range(150): if feedback.isCanceled(): - feedback.pushInfo(self.tr('Canceled by user.\n')) + feedback.pushInfo(self.tr("Canceled by user.\n")) break sleep(3) try: @@ -151,14 +141,14 @@ def runFMEFromJSONData(self, inputJSONData, feedback): session.trust_env = False response = session.get(url_to_status) session.close() - responseData = response.json()['data'] + responseData = response.json()["data"] except: - responseData = {'status': 'erro', 'log':'Erro no plugin!'} - if responseData['status'] in [2, 3, "erro"]: + responseData = {"status": "erro", "log": "Erro no plugin!"} + if responseData["status"] in [2, 3, "erro"]: break - output = u"

[rotina nome] : {0}

".format(inputJSONData['workspace_name']) - for flags in responseData['log'].split('|'): + output = "

[rotina nome] : {0}

".format(inputJSONData["workspace_name"]) + for flags in responseData["log"].split("|"): output += """

[rotina flags] : {0}

""".format(flags) return {self.OUTPUT: output} @@ -170,21 +160,21 @@ def name(self): lowercase alphanumeric characters only and no spaces or other formatting characters. """ - return 'runfmesap' + return "runfmesap" def displayName(self): """ Returns the translated algorithm name, which should be used for any user-visible display of the algorithm name. """ - return self.tr('Run FME SAP Workspace') + return self.tr("Run FME SAP Workspace") def group(self): """ Returns the name of the group this algorithm belongs to. This string should be localised. """ - return self.tr('Other Algorithms') + return self.tr("Other Algorithms") def groupId(self): """ @@ -194,10 +184,10 @@ def groupId(self): contain lowercase alphanumeric characters only and no spaces or other formatting characters. """ - return 'DSGTools: Other Algorithms' + return "DSGTools: Other Algorithms" def tr(self, string): - return QCoreApplication.translate('RunFMESAPAlgorithm', string) + return QCoreApplication.translate("RunFMESAPAlgorithm", string) def createInstance(self): - return RunFMESAPAlgorithm() \ No newline at end of file + return RunFMESAPAlgorithm() diff --git a/DsgTools/core/DSGToolsProcessingAlgs/Algs/OtherAlgs/runRemoteFMEAlgorithm.py b/DsgTools/core/DSGToolsProcessingAlgs/Algs/OtherAlgs/runRemoteFMEAlgorithm.py index f88302ee4..918ca4cae 100644 --- a/DsgTools/core/DSGToolsProcessingAlgs/Algs/OtherAlgs/runRemoteFMEAlgorithm.py +++ b/DsgTools/core/DSGToolsProcessingAlgs/Algs/OtherAlgs/runRemoteFMEAlgorithm.py @@ -25,10 +25,12 @@ import requests from time import sleep -from qgis.core import (QgsProcessingAlgorithm, - QgsProcessingException, - QgsProcessingParameterDefinition, - QgsProcessingParameterType) +from qgis.core import ( + QgsProcessingAlgorithm, + QgsProcessingException, + QgsProcessingParameterDefinition, + QgsProcessingParameterType, +) from qgis.PyQt.QtCore import QCoreApplication @@ -40,20 +42,27 @@ def initAlgorithm(self, config): Parameter setting. """ managerParameter = ParameterFMEManager( - self.FME_MANAGER, - description=self.tr("FME Manager Parameters") + self.FME_MANAGER, description=self.tr("FME Manager Parameters") + ) + managerParameter.setMetadata( + { + "widget_wrapper": "DsgTools.gui.ProcessingUI.fmeManagerWrapper.FMEManagerWrapper" + } ) - managerParameter.setMetadata({ - "widget_wrapper": "DsgTools.gui.ProcessingUI.fmeManagerWrapper.FMEManagerWrapper" - }) self.addParameter(managerParameter) def parameterAsFMEManager(self, parameters, name, context): return parameters[name] def getRequestFromServer( - self, url, proxyInfo=None, proxyAuth=None, useSsl=False, - useProxy=False, timeout=None): + self, + url, + proxyInfo=None, + proxyAuth=None, + useSsl=False, + useProxy=False, + timeout=None, + ): """ Sends a POST request to the FME Manager server. :param url: (str) FME Manager server's URL. @@ -75,20 +84,29 @@ def getRequestFromServer( proxies=proxyInfo, auth=proxyAuth, verify=useSsl, - timeout=timeout or 15 + timeout=timeout or 15, ) else: resp = requests.get(url, verify=useSsl, timeout=timeout or 15) except BaseException as e: raise QgsProcessingException( - self.tr("Unable to get the routine's output from " - "FME Manager: '{0}'".format(e)) + self.tr( + "Unable to get the routine's output from " + "FME Manager: '{0}'".format(e) + ) ) return resp.json() def postRequestFromServer( - self, url, fmeParameters, proxyInfo=None, proxyAuth=None, - useSsl=False, useProxy=False, timeout=None): + self, + url, + fmeParameters, + proxyInfo=None, + proxyAuth=None, + useSsl=False, + useProxy=False, + timeout=None, + ): """ Sends a POST request to the FME Manager server. :param url: (str) FME Manager server's URL. @@ -113,19 +131,18 @@ def postRequestFromServer( proxies=proxyInfo, auth=proxyAuth, verify=useSsl, - timeout=timeout or 15 + timeout=timeout or 15, ) else: resp = requests.post( - url, - json=fmeParameters, - verify=useSsl, - timeout=timeout or 15 + url, json=fmeParameters, verify=useSsl, timeout=timeout or 15 ) except BaseException as e: raise QgsProcessingException( - self.tr("Unable to send processing request to " - "FME Manager: '{0}'".format(e)) + self.tr( + "Unable to send processing request to " + "FME Manager: '{0}'".format(e) + ) ) return resp.json() @@ -152,22 +169,20 @@ def processAlgorithm(self, parameters, context, feedback): version = fmeDict.get("version") if version == "v1": url = "{server}/versions/{workspace_id}/jobs".format( - server=fmeDict["server"], - workspace_id=fmeDict["workspace_id"] + server=fmeDict["server"], workspace_id=fmeDict["workspace_id"] ) - url_to_status = "{server}/jobs/{{uuid}}".format( - server=fmeDict["server"]) + url_to_status = "{server}/jobs/{{uuid}}".format(server=fmeDict["server"]) dataKey = "data" jobNameKey = "workspace" summaryKey = "log" statusKey = "status" else: url = "{server}/api/rotinas/{workspace_id}/execucao".format( - server=fmeDict["server"], - workspace_id=fmeDict["workspace_id"] + server=fmeDict["server"], workspace_id=fmeDict["workspace_id"] ) url_to_status = "{server}/api/execucoes/{{uuid}}".format( - server=fmeDict["server"]) + server=fmeDict["server"] + ) dataKey = "dados" jobNameKey = "rotina" summaryKey = "sumario" @@ -177,16 +192,16 @@ def processAlgorithm(self, parameters, context, feedback): url, fmeDict.get("parameters"), fmeDict.get("proxy_dict"), - fmeDict.get("auth"), + fmeDict.get("auth"), fmeDict.get("use_ssl"), - fmeDict.get("use_proxy") + fmeDict.get("use_proxy"), ) feedback.pushInfo( - self.tr("Request successful. Waiting for the workspace to " - "be executed...") + self.tr( + "Request successful. Waiting for the workspace to " "be executed..." + ) ) - url_to_status = url_to_status.format( - uuid=jobRequest[dataKey]["job_uuid"]) + url_to_status = url_to_status.format(uuid=jobRequest[dataKey]["job_uuid"]) while True: if feedback.isCanceled(): feedback.pushInfo(self.tr("Canceled by user.\n")) @@ -195,30 +210,32 @@ def processAlgorithm(self, parameters, context, feedback): jobOutput = self.getRequestFromServer( url_to_status, fmeDict.get("proxy_dict"), - fmeDict.get("auth"), + fmeDict.get("auth"), fmeDict.get("use_ssl"), - fmeDict.get("use_proxy") + fmeDict.get("use_proxy"), ) outputData = jobOutput.get(dataKey) statusId = outputData.get(statusKey) if statusId == 2: feedback.pushInfo( - self.tr("Workspace {0} completed with success.\n")\ - .format(outputData[jobNameKey]) + self.tr("Workspace {0} completed with success.\n").format( + outputData[jobNameKey] + ) ) for flags in self.parseLog(outputData[summaryKey], version): if version == "v1": msg = self.tr("Number of flags: {0}\n").format(flags) else: - msg = self.tr("Number of flags in {0}: {1}\n")\ - .format(flags["classes"], flags["feicoes"]) + msg = self.tr("Number of flags in {0}: {1}\n").format( + flags["classes"], flags["feicoes"] + ) feedback.pushInfo(msg) break if statusId == 3: feedback.reportError(self.tr("Task completed with error.\n")) break - return {'result': jobOutput} + return {"result": jobOutput} def name(self): """ @@ -262,7 +279,6 @@ def createInstance(self): class ParameterFMEManagerType(QgsProcessingParameterType): - def __init__(self): super().__init__() @@ -270,7 +286,9 @@ def create(self, name): return ParameterFMEManager(name) def metadata(self): - return {"widget_wrapper": "DsgTools.gui.ProcessingUI.fmeManagerWrapper.FMEManagerWrapper"} + return { + "widget_wrapper": "DsgTools.gui.ProcessingUI.fmeManagerWrapper.FMEManagerWrapper" + } def name(self): return QCoreApplication.translate("Processing", "FME Manager Parameters") @@ -279,11 +297,12 @@ def id(self): return "fme_manager" def description(self): - return QCoreApplication.translate("Processing", "FME Manager parameters. Used on Run Remote FME Workspace") + return QCoreApplication.translate( + "Processing", "FME Manager parameters. Used on Run Remote FME Workspace" + ) class ParameterFMEManager(QgsProcessingParameterDefinition): - def __init__(self, name, description=""): super().__init__(name, description) diff --git a/DsgTools/core/DSGToolsProcessingAlgs/Algs/OtherAlgs/selectFeaturesOnCurrentCanvas.py b/DsgTools/core/DSGToolsProcessingAlgs/Algs/OtherAlgs/selectFeaturesOnCurrentCanvas.py new file mode 100644 index 000000000..77f7303c2 --- /dev/null +++ b/DsgTools/core/DSGToolsProcessingAlgs/Algs/OtherAlgs/selectFeaturesOnCurrentCanvas.py @@ -0,0 +1,105 @@ +# -*- coding: utf-8 -*- +""" +/*************************************************************************** + DsgTools + A QGIS plugin + Brazilian Army Cartographic Production Tools + ------------------- + begin : 2022-12-26 + git sha : $Format:%H$ + copyright : (C) 2022 by Philipe Borba - Cartographic Engineer @ Brazilian Army + email : borba.philipe@eb.mil.br + ***************************************************************************/ +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ +""" + +from PyQt5.QtCore import QCoreApplication +from qgis.core import (QgsProcessing, QgsProcessingAlgorithm, + QgsProcessingOutputMultipleLayers, + QgsProcessingParameterMultipleLayers) +from qgis.utils import iface + + +class SelectFeaturesOnCurrentCanvas(QgsProcessingAlgorithm): + INPUT_LAYERS = "INPUT_LAYERS" + OUTPUT = "OUTPUT" + + def __init__(self): + super(SelectFeaturesOnCurrentCanvas, self).__init__() + + def initAlgorithm(self, config=None): + """ + Parameter setting. + """ + self.addParameter( + QgsProcessingParameterMultipleLayers( + self.INPUT_LAYERS, + self.tr("Input Layers"), + QgsProcessing.TypeVectorAnyGeometry, + ) + ) + self.addOutput( + QgsProcessingOutputMultipleLayers(self.OUTPUT, self.tr("Layers with selected features")) + ) + + def processAlgorithm(self, parameters, context, feedback): + """ + Here is where the processing itself takes place. + """ + inputLyrList = self.parameterAsLayerList(parameters, self.INPUT_LAYERS, context) + listSize = len(inputLyrList) + stepSize = 100 / listSize if listSize else 0 + bbox = iface.mapCanvas().extent() + selectedLyrList = [] + for current, lyr in enumerate(inputLyrList): + if feedback.isCanceled(): + break + idsOnCanvas = [feat.id() for feat in lyr.getFeatures(bbox)] + if len(idsOnCanvas) > 0: + lyr.selectByIds(idsOnCanvas) + selectedLyrList.append(lyr.id()) + feedback.setProgress(current * stepSize) + return {self.OUTPUT: selectedLyrList} + + def name(self): + """ + Here is where the processing itself takes place. + """ + return "selectfeaturesoncurrentcanvas" + + def displayName(self): + """ + Returns the translated algorithm name, which should be used for any + user-visible display of the algorithm name. + """ + return self.tr("Select Features On Current Canvas") + + def group(self): + """ + Returns the name of the group this algorithm belongs to. This string + should be localised. + """ + return self.tr("Other Algorithms") + + def groupId(self): + """ + Returns the unique ID of the group this algorithm belongs to. This + string should be fixed for the algorithm, and must not be localised. + The group id should be unique within each provider. Group id should + contain lowercase alphanumeric characters only and no spaces or other + formatting characters. + """ + return "DSGTools: Other Algorithms" + + def tr(self, string): + return QCoreApplication.translate("SelectFeaturesOnCurrentCanvas", string) + + def createInstance(self): + return SelectFeaturesOnCurrentCanvas() diff --git a/DsgTools/core/DSGToolsProcessingAlgs/Algs/OtherAlgs/singleOutputUnitTestAlgorithm.py b/DsgTools/core/DSGToolsProcessingAlgs/Algs/OtherAlgs/singleOutputUnitTestAlgorithm.py index 1b4e804f2..dcc7dd3dd 100644 --- a/DsgTools/core/DSGToolsProcessingAlgs/Algs/OtherAlgs/singleOutputUnitTestAlgorithm.py +++ b/DsgTools/core/DSGToolsProcessingAlgs/Algs/OtherAlgs/singleOutputUnitTestAlgorithm.py @@ -24,44 +24,61 @@ from qgis.PyQt.Qt import QVariant from qgis.PyQt.QtCore import QCoreApplication -from qgis.core import (QgsProcessingAlgorithm, - QgsProcessingParameterFeatureSink, - QgsProcessingParameterEnum, - QgsFeatureSink, - QgsCoordinateReferenceSystem, - QgsFields, - QgsField, - QgsWkbTypes) +from qgis.core import ( + QgsProcessingAlgorithm, + QgsProcessingParameterFeatureSink, + QgsProcessingParameterEnum, + QgsFeatureSink, + QgsCoordinateReferenceSystem, + QgsFields, + QgsField, + QgsWkbTypes, +) from DsgTools.tests.test_ValidationAlgorithms import Tester from DsgTools.core.GeometricTools.featureHandler import FeatureHandler + class SingleOutputUnitTestAlgorithm(QgsProcessingAlgorithm): - __description__ = """Runs unit tests for a set of DSGTools algorithms that""" \ - """has single output - in-place modified or otherwise.""" + __description__ = ( + """Runs unit tests for a set of DSGTools algorithms that""" + """has single output - in-place modified or otherwise.""" + ) AVAILABLE_ALGS = [ # identification algs - "dsgtools:identifyoutofboundsangles", "dsgtools:identifyoutofboundsanglesincoverage", - "dsgtools:identifygaps", "dsgtools:identifyandfixinvalidgeometries", - "dsgtools:identifyduplicatedfeatures", "dsgtools:identifyduplicatedgeometries", - "dsgtools:identifyduplicatedlinesoncoverage", "dsgtools:identifysmalllines", - "dsgtools:identifyduplicatedpolygonsoncoverage", "dsgtools:identifysmallpolygons", - "dsgtools:identifydangles", "dsgtools:identifyduplicatedpointsoncoverage", - "dsgtools:identifyoverlaps", "dsgtools:identifyvertexnearedges", + "dsgtools:identifyoutofboundsangles", + "dsgtools:identifyoutofboundsanglesincoverage", + "dsgtools:identifygaps", + "dsgtools:identifyandfixinvalidgeometries", + "dsgtools:identifyduplicatedfeatures", + "dsgtools:identifyduplicatedgeometries", + "dsgtools:identifyduplicatedlinesoncoverage", + "dsgtools:identifysmalllines", + "dsgtools:identifyduplicatedpolygonsoncoverage", + "dsgtools:identifysmallpolygons", + "dsgtools:identifydangles", + "dsgtools:identifyduplicatedpointsoncoverage", + "dsgtools:identifyoverlaps", + "dsgtools:identifyvertexnearedges", # correction algs - "dsgtools:removeduplicatedfeatures", "dsgtools:removeduplicatedgeometries", - "dsgtools:removesmalllines", "dsgtools:removesmallpolygons", + "dsgtools:removeduplicatedfeatures", + "dsgtools:removeduplicatedgeometries", + "dsgtools:removesmalllines", + "dsgtools:removesmallpolygons", # manipulation algs - "dsgtools:lineonlineoverlayer", "dsgtools:mergelineswithsameattributeset", - "dsgtools:overlayelementswithareas", "dsgtools:deaggregategeometries", - "dsgtools:dissolvepolygonswithsameattributes", "dsgtools:removeemptyandupdate", + "dsgtools:lineonlineoverlayer", + "dsgtools:mergelineswithsameattributeset", + "dsgtools:overlayelementswithareas", + "dsgtools:deaggregategeometries", + "dsgtools:dissolvepolygonswithsameattributes", + "dsgtools:removeemptyandupdate", "dsgtools:snaplayeronlayer", # network algs "dsgtools:adjustnetworkconnectivity", - "dsgtools:identifyunsharedvertexonintersectionsalgorithm" + "dsgtools:identifyunsharedvertexonintersectionsalgorithm", ] - INPUT_ALGS = 'INPUT_ALGS' - OUTPUT = 'OUTPUT' + INPUT_ALGS = "INPUT_ALGS" + OUTPUT = "OUTPUT" def __init__(self): super(SingleOutputUnitTestAlgorithm, self).__init__() @@ -73,43 +90,41 @@ def initAlgorithm(self, config=None): self.addParameter( QgsProcessingParameterEnum( self.INPUT_ALGS, - self.tr('Algorithms to be tested'), + self.tr("Algorithms to be tested"), options=self.AVAILABLE_ALGS, optional=False, - allowMultiple=True - + allowMultiple=True, ) ) self.addParameter( QgsProcessingParameterFeatureSink( - self.OUTPUT, - self.tr("DSGTools Single Output Algorithms Unit Tests") + self.OUTPUT, self.tr("DSGTools Single Output Algorithms Unit Tests") ) ) - + def name(self): """ Returns the algorithm name, used for identifying the algorithm. This - string should be fixed for the algorithm, and must not be localised + string should be fixed for the algorithm, and must not be localised (e.g. must be ASCII). The name should be unique within each provider. - Names should contain lowercase alphanumeric characters only and no + Names should contain lowercase alphanumeric characters only and no spaces or other formatting characters. """ - return 'singleoutputunittest' + return "singleoutputunittest" def displayName(self): """ Returns the translated algorithm name, which should be used for any user-visible display of the algorithm name. """ - return self.tr('Single Output Algorithms Unit Test') + return self.tr("Single Output Algorithms Unit Test") def group(self): """ Returns the name of the group this algorithm belongs to. This string should be localised. """ - return self.tr('Other Algorithms') + return self.tr("Other Algorithms") def groupId(self): """ @@ -119,10 +134,10 @@ def groupId(self): contain lowercase alphanumeric characters only and no spaces or other formatting characters. """ - return 'DSGTools: Other Algorithms' + return "DSGTools: Other Algorithms" def tr(self, string): - return QCoreApplication.translate('SingleOutputUnitTestAlgorithm', string) + return QCoreApplication.translate("SingleOutputUnitTestAlgorithm", string) def createInstance(self): """ @@ -135,9 +150,9 @@ def getFields(self): Gets all fields for output layer. """ fields = QgsFields() - fields.append(QgsField('algorithm', QVariant.String)) - fields.append(QgsField('tests_output', QVariant.String)) - fields.append(QgsField('status', QVariant.String)) + fields.append(QgsField("algorithm", QVariant.String)) + fields.append(QgsField("tests_output", QVariant.String)) + fields.append(QgsField("status", QVariant.String)) return fields def processAlgorithm(self, parameters, context, feedback): @@ -145,8 +160,12 @@ def processAlgorithm(self, parameters, context, feedback): Here is where the processing itself takes place. """ algsOutput, dest_id = self.parameterAsSink( - parameters, self.OUTPUT, context, self.getFields(), - QgsWkbTypes.NoGeometry, QgsCoordinateReferenceSystem('EPSG:4326') + parameters, + self.OUTPUT, + context, + self.getFields(), + QgsWkbTypes.NoGeometry, + QgsCoordinateReferenceSystem("EPSG:4326"), ) tester = Tester() featureHandler = FeatureHandler() @@ -163,7 +182,9 @@ def processAlgorithm(self, parameters, context, feedback): alg = self.AVAILABLE_ALGS[algIdx] feedback.pushInfo(self.tr("Testing {alg}'s...").format(alg=alg)) # decided not to pass feedback to not pollute this alg's log - msg = tester.testAlg(alg, context=context) #, feedback=feedback, context=context) + msg = tester.testAlg( + alg, context=context + ) # , feedback=feedback, context=context) status = self.tr("Failed") if msg else self.tr("Passed") pushMethod = feedback.reportError if msg else feedback.pushDebugInfo failCount += 1 if msg else 0 @@ -172,14 +193,20 @@ def processAlgorithm(self, parameters, context, feedback): feats.add( featureHandler.createFeatureFromLayer( algsOutput, - attributes={"algorithm" : alg, "tests_output" : msg, "status" : status}, - fields=fields + attributes={ + "algorithm": alg, + "tests_output": msg, + "status": status, + }, + fields=fields, ) ) feedback.setProgress(currentStep * totalProgress) algsOutput.addFeatures(feats, QgsFeatureSink.FastInsert) if failCount: - feedback.reportError(self.tr("{0} algorithms failed their unit tests.").format(failCount)) + feedback.reportError( + self.tr("{0} algorithms failed their unit tests.").format(failCount) + ) else: feedback.pushDebugInfo(self.tr("All algorithms passed their unit tests.")) - return { self.OUTPUT : dest_id } + return {self.OUTPUT: dest_id} diff --git a/DsgTools/core/DSGToolsProcessingAlgs/Algs/OtherAlgs/stringCsvToFirstLayerWithElementsAlgorithm.py b/DsgTools/core/DSGToolsProcessingAlgs/Algs/OtherAlgs/stringCsvToFirstLayerWithElementsAlgorithm.py index 4fa8ea3d4..c34ee2690 100644 --- a/DsgTools/core/DSGToolsProcessingAlgs/Algs/OtherAlgs/stringCsvToFirstLayerWithElementsAlgorithm.py +++ b/DsgTools/core/DSGToolsProcessingAlgs/Algs/OtherAlgs/stringCsvToFirstLayerWithElementsAlgorithm.py @@ -21,15 +21,17 @@ """ from PyQt5.QtCore import QCoreApplication -from qgis.core import (QgsProcessingAlgorithm, - QgsProcessingOutputVectorLayer, - QgsProcessingParameterString, - QgsProcessingUtils) +from qgis.core import ( + QgsProcessingAlgorithm, + QgsProcessingOutputVectorLayer, + QgsProcessingParameterString, + QgsProcessingUtils, +) class StringCsvToFirstLayerWithElementsAlgorithm(QgsProcessingAlgorithm): - INPUTLAYERS = 'INPUTLAYERS' - OUTPUT = 'OUTPUT' + INPUTLAYERS = "INPUTLAYERS" + OUTPUT = "OUTPUT" def initAlgorithm(self, config=None): """ @@ -37,32 +39,24 @@ def initAlgorithm(self, config=None): """ self.addParameter( QgsProcessingParameterString( - self.INPUTLAYERS, - self.tr('Comma separated Input Layer Names') + self.INPUTLAYERS, self.tr("Comma separated Input Layer Names") ) ) - + self.addOutput( - QgsProcessingOutputVectorLayer( - self.OUTPUT, - self.tr('Loaded layer') - ) + QgsProcessingOutputVectorLayer(self.OUTPUT, self.tr("Loaded layer")) ) def processAlgorithm(self, parameters, context, feedback): """ Here is where the processing itself takes place. """ - layerCsv = self.parameterAsString( - parameters, - self.INPUTLAYERS, - context - ) - layerNameList = layerCsv.split(',') + layerCsv = self.parameterAsString(parameters, self.INPUTLAYERS, context) + layerNameList = layerCsv.split(",") nSteps = len(layerNameList) if not nSteps: - return {self.OUTPUT : None} - progressStep = 100/nSteps + return {self.OUTPUT: None} + progressStep = 100 / nSteps for idx, layerName in enumerate(layerNameList): if feedback.isCanceled(): break @@ -74,27 +68,27 @@ def processAlgorithm(self, parameters, context, feedback): return {"OUTPUT": lyr} feedback.setProgress(idx * progressStep) - return {"OUTPUT": None} # case where no layer from input has elements + return {"OUTPUT": None} # case where no layer from input has elements def name(self): """ Here is where the processing itself takes place. """ - return 'stringcsvtofirstlayerwithelementsalgorithm' + return "stringcsvtofirstlayerwithelementsalgorithm" def displayName(self): """ Returns the translated algorithm name, which should be used for any user-visible display of the algorithm name. """ - return self.tr('String CSV to First Layer With Elements') + return self.tr("String CSV to First Layer With Elements") def group(self): """ Returns the name of the group this algorithm belongs to. This string should be localised. """ - return self.tr('Other Algorithms') + return self.tr("Other Algorithms") def groupId(self): """ @@ -104,10 +98,12 @@ def groupId(self): contain lowercase alphanumeric characters only and no spaces or other formatting characters. """ - return 'DSGTools: Other Algorithms' + return "DSGTools: Other Algorithms" def tr(self, string): - return QCoreApplication.translate('StringCsvToFirstLayerWithElementsAlgorithm', string) + return QCoreApplication.translate( + "StringCsvToFirstLayerWithElementsAlgorithm", string + ) def createInstance(self): return StringCsvToFirstLayerWithElementsAlgorithm() diff --git a/DsgTools/core/DSGToolsProcessingAlgs/Algs/OtherAlgs/stringCsvToLayerListAlgorithm.py b/DsgTools/core/DSGToolsProcessingAlgs/Algs/OtherAlgs/stringCsvToLayerListAlgorithm.py index 211cc7658..e32434597 100644 --- a/DsgTools/core/DSGToolsProcessingAlgs/Algs/OtherAlgs/stringCsvToLayerListAlgorithm.py +++ b/DsgTools/core/DSGToolsProcessingAlgs/Algs/OtherAlgs/stringCsvToLayerListAlgorithm.py @@ -22,16 +22,19 @@ import fnmatch from PyQt5.QtCore import QCoreApplication -from qgis.core import (QgsMapLayer, QgsProcessingAlgorithm, - QgsProcessingOutputMultipleLayers, - QgsProcessingParameterString, - QgsProcessingUtils, - QgsProject) +from qgis.core import ( + QgsMapLayer, + QgsProcessingAlgorithm, + QgsProcessingOutputMultipleLayers, + QgsProcessingParameterString, + QgsProcessingUtils, + QgsProject, +) class StringCsvToLayerListAlgorithm(QgsProcessingAlgorithm): - INPUTLAYERS = 'INPUTLAYERS' - OUTPUT = 'OUTPUT' + INPUTLAYERS = "INPUTLAYERS" + OUTPUT = "OUTPUT" def initAlgorithm(self, config=None): """ @@ -39,15 +42,13 @@ def initAlgorithm(self, config=None): """ self.addParameter( QgsProcessingParameterString( - self.INPUTLAYERS, - self.tr('Comma separated Input Layer Names') + self.INPUTLAYERS, self.tr("Comma separated Input Layer Names") ) ) - + self.addOutput( QgsProcessingOutputMultipleLayers( - self.OUTPUT, - self.tr('Multiple layer list') + self.OUTPUT, self.tr("Multiple layer list") ) ) @@ -55,17 +56,13 @@ def processAlgorithm(self, parameters, context, feedback): """ Here is where the processing itself takes place. """ - layerCsv = self.parameterAsString( - parameters, - self.INPUTLAYERS, - context - ) - layerNameList = layerCsv.split(',') + layerCsv = self.parameterAsString(parameters, self.INPUTLAYERS, context) + layerNameList = layerCsv.split(",") if not len(layerNameList): - return {self.OUTPUT : None} + return {self.OUTPUT: None} layerSet = set() layerNamesToLoadSet = self.getLayerNameSetToLoad(layerNameList) - progressStep = 100/len(layerNamesToLoadSet) + progressStep = 100 / len(layerNamesToLoadSet) for idx, layerName in enumerate(layerNamesToLoadSet): if feedback.isCanceled(): break @@ -75,11 +72,12 @@ def processAlgorithm(self, parameters, context, feedback): layerSet.add(lyr.id()) feedback.setProgress(idx * progressStep) - return { self.OUTPUT : list(layerSet)} + return {self.OUTPUT: list(layerSet)} def getLayerNameSetToLoad(self, layerNameList): loadedLayerNamesSet = set( - l.name() for l in QgsProject.instance().mapLayers().values() \ + l.name() + for l in QgsProject.instance().mapLayers().values() if l.type() == QgsMapLayer.VectorLayer ) wildCardFilterList = [fi for fi in layerNameList if "*" in fi] @@ -88,28 +86,30 @@ def getLayerNameSetToLoad(self, layerNameList): wildCardLayersSet = wildCardLayersSet.union( set(fnmatch.filter(loadedLayerNamesSet, wildCardFilter)) ) - layerNamesToLoadSet = set(layerNameList) - set(wildCardFilterList) | wildCardLayersSet + layerNamesToLoadSet = ( + set(layerNameList) - set(wildCardFilterList) | wildCardLayersSet + ) return layerNamesToLoadSet def name(self): """ Here is where the processing itself takes place. """ - return 'stringcsvtolayerlistalgorithm' + return "stringcsvtolayerlistalgorithm" def displayName(self): """ Returns the translated algorithm name, which should be used for any user-visible display of the algorithm name. """ - return self.tr('String CSV to Layer List Algorithm') + return self.tr("String CSV to Layer List Algorithm") def group(self): """ Returns the name of the group this algorithm belongs to. This string should be localised. """ - return self.tr('Other Algorithms') + return self.tr("Other Algorithms") def groupId(self): """ @@ -119,10 +119,10 @@ def groupId(self): contain lowercase alphanumeric characters only and no spaces or other formatting characters. """ - return 'DSGTools: Other Algorithms' + return "DSGTools: Other Algorithms" def tr(self, string): - return QCoreApplication.translate('StringCsvToLayerListAlgorithm', string) + return QCoreApplication.translate("StringCsvToLayerListAlgorithm", string) def createInstance(self): return StringCsvToLayerListAlgorithm() diff --git a/DsgTools/core/DSGToolsProcessingAlgs/Algs/OtherAlgs/updateOriginalLayerAlgorithm.py b/DsgTools/core/DSGToolsProcessingAlgs/Algs/OtherAlgs/updateOriginalLayerAlgorithm.py index bb8a9c164..cd4650c4a 100644 --- a/DsgTools/core/DSGToolsProcessingAlgs/Algs/OtherAlgs/updateOriginalLayerAlgorithm.py +++ b/DsgTools/core/DSGToolsProcessingAlgs/Algs/OtherAlgs/updateOriginalLayerAlgorithm.py @@ -20,31 +20,36 @@ ***************************************************************************/ """ -from DsgTools.core.DSGToolsProcessingAlgs.Algs.ValidationAlgs.validationAlgorithm import ValidationAlgorithm +from DsgTools.core.DSGToolsProcessingAlgs.Algs.ValidationAlgs.validationAlgorithm import ( + ValidationAlgorithm, +) from DsgTools.core.GeometricTools.layerHandler import LayerHandler from PyQt5.QtCore import QCoreApplication import processing -from qgis.core import (QgsProcessing, - QgsFeatureSink, - QgsProcessingAlgorithm, - QgsProcessingParameterFeatureSource, - QgsProcessingParameterFeatureSink, - QgsFeature, - QgsDataSourceUri, - QgsProcessingParameterVectorLayer, - QgsWkbTypes, - QgsProcessingParameterField, - QgsProcessingParameterBoolean, - QgsWkbTypes, - QgsProcessingUtils, - QgsProject) +from qgis.core import ( + QgsProcessing, + QgsFeatureSink, + QgsProcessingAlgorithm, + QgsProcessingParameterFeatureSource, + QgsProcessingParameterFeatureSink, + QgsFeature, + QgsDataSourceUri, + QgsProcessingParameterVectorLayer, + QgsWkbTypes, + QgsProcessingParameterField, + QgsProcessingParameterBoolean, + QgsWkbTypes, + QgsProcessingUtils, + QgsProject, +) + class UpdateOriginalLayerAlgorithm(ValidationAlgorithm): - ORIGINALLAYER = 'ORIGINALLAYER' - PROCESSOUTPUTLAYER = 'PROCESSOUTPUTLAYER' - CONTROLID = 'CONTROLID' - KEEPFEATURES = 'KEEPFEATURES' + ORIGINALLAYER = "ORIGINALLAYER" + PROCESSOUTPUTLAYER = "PROCESSOUTPUTLAYER" + CONTROLID = "CONTROLID" + KEEPFEATURES = "KEEPFEATURES" def initAlgorithm(self, config): """ @@ -53,53 +58,66 @@ def initAlgorithm(self, config): self.addParameter( QgsProcessingParameterVectorLayer( self.ORIGINALLAYER, - self.tr('Original Layer'), - [QgsProcessing.TypeVectorAnyGeometry] + self.tr("Original Layer"), + [QgsProcessing.TypeVectorAnyGeometry], ) ) self.addParameter( QgsProcessingParameterField( self.CONTROLID, - self.tr('Control ID'), - parentLayerParameterName=self.ORIGINALLAYER + self.tr("Control ID"), + parentLayerParameterName=self.ORIGINALLAYER, ) ) self.addParameter( QgsProcessingParameterVectorLayer( self.PROCESSOUTPUTLAYER, - self.tr('Control Layer'), - [QgsProcessing.TypeVectorAnyGeometry] + self.tr("Control Layer"), + [QgsProcessing.TypeVectorAnyGeometry], ) ) self.addParameter( QgsProcessingParameterBoolean( self.KEEPFEATURES, - self.tr('Keep features from input that are not in update layer') + self.tr("Keep features from input that are not in update layer"), ) ) - def processAlgorithm(self, parameters, context, feedback): """ Here is where the processing itself takes place. """ layerHandler = LayerHandler() - originalLyr = self.parameterAsVectorLayer(parameters, self.ORIGINALLAYER, context) + originalLyr = self.parameterAsVectorLayer( + parameters, self.ORIGINALLAYER, context + ) if originalLyr is None: - raise QgsProcessingException(self.invalidSourceError(parameters, self.ORIGINALLAYER)) + raise QgsProcessingException( + self.invalidSourceError(parameters, self.ORIGINALLAYER) + ) - processOutputLyr = self.parameterAsVectorLayer(parameters, self.PROCESSOUTPUTLAYER, context) + processOutputLyr = self.parameterAsVectorLayer( + parameters, self.PROCESSOUTPUTLAYER, context + ) if processOutputLyr is None: - raise QgsProcessingException(self.invalidSourceError(parameters, self.PROCESSOUTPUTLAYER)) - + raise QgsProcessingException( + self.invalidSourceError(parameters, self.PROCESSOUTPUTLAYER) + ) + controlId = self.parameterAsFields(parameters, self.CONTROLID, context) keepFeatures = self.parameterAsBool(parameters, self.KEEPFEATURES, context) - layerHandler.updateOriginalLayer(originalLyr, processOutputLyr, field=str(controlId[0]), feedback=feedback, keepFeatures = keepFeatures) - return {self.ORIGINALLAYER:originalLyr} + layerHandler.updateOriginalLayer( + originalLyr, + processOutputLyr, + field=str(controlId[0]), + feedback=feedback, + keepFeatures=keepFeatures, + ) + return {self.ORIGINALLAYER: originalLyr} def name(self): """ @@ -109,21 +127,21 @@ def name(self): lowercase alphanumeric characters only and no spaces or other formatting characters. """ - return 'updatelayer' + return "updatelayer" def displayName(self): """ Returns the translated algorithm name, which should be used for any user-visible display of the algorithm name. """ - return self.tr('Update Layer') + return self.tr("Update Layer") def group(self): """ Returns the name of the group this algorithm belongs to. This string should be localised. """ - return self.tr('Other Algorithms') + return self.tr("Other Algorithms") def groupId(self): """ @@ -133,10 +151,10 @@ def groupId(self): contain lowercase alphanumeric characters only and no spaces or other formatting characters. """ - return 'DSGTools: Other Algorithms' + return "DSGTools: Other Algorithms" def tr(self, string): - return QCoreApplication.translate('UpdateOriginalLayerAlgorithm', string) + return QCoreApplication.translate("UpdateOriginalLayerAlgorithm", string) def createInstance(self): return UpdateOriginalLayerAlgorithm() diff --git a/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/addUnsharedVertexOnIntersectionsAlgorithm.py b/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/addUnsharedVertexOnIntersectionsAlgorithm.py index e04d58c35..eda36ff65 100644 --- a/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/addUnsharedVertexOnIntersectionsAlgorithm.py +++ b/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/addUnsharedVertexOnIntersectionsAlgorithm.py @@ -24,28 +24,36 @@ from PyQt5.QtCore import QCoreApplication from DsgTools.core.GeometricTools.layerHandler import LayerHandler -from qgis.core import (QgsDataSourceUri, QgsFeature, QgsFeatureSink, - QgsProcessing, QgsProcessingAlgorithm, - QgsProcessingException, QgsProcessingMultiStepFeedback, - QgsProcessingOutputVectorLayer, - QgsProcessingParameterBoolean, - QgsProcessingParameterDistance, - QgsProcessingParameterFeatureSink, - QgsProcessingParameterFeatureSource, - QgsProcessingParameterField, - QgsProcessingParameterMultipleLayers, - QgsProcessingParameterVectorLayer, QgsWkbTypes) +from qgis.core import ( + QgsDataSourceUri, + QgsFeature, + QgsFeatureSink, + QgsProcessing, + QgsProcessingAlgorithm, + QgsProcessingException, + QgsProcessingMultiStepFeedback, + QgsProcessingOutputVectorLayer, + QgsProcessingParameterBoolean, + QgsProcessingParameterDistance, + QgsProcessingParameterFeatureSink, + QgsProcessingParameterFeatureSource, + QgsProcessingParameterField, + QgsProcessingParameterMultipleLayers, + QgsProcessingParameterVectorLayer, + QgsWkbTypes, +) from ...algRunner import AlgRunner from .validationAlgorithm import ValidationAlgorithm class AddUnsharedVertexOnIntersectionsAlgorithm(ValidationAlgorithm): - INPUT_POINTS = 'INPUT_POINTS' - INPUT_LINES = 'INPUT_LINES' - INPUT_POLYGONS = 'INPUT_POLYGONS' - SELECTED = 'SELECTED' - GEOGRAPHIC_BOUNDARY = 'GEOGRAPHIC_BOUNDARY' + INPUT_POINTS = "INPUT_POINTS" + INPUT_LINES = "INPUT_LINES" + INPUT_POLYGONS = "INPUT_POLYGONS" + SELECTED = "SELECTED" + SEARCH_RADIUS = "SEARCH_RADIUS" + GEOGRAPHIC_BOUNDARY = "GEOGRAPHIC_BOUNDARY" def initAlgorithm(self, config): """ @@ -54,82 +62,75 @@ def initAlgorithm(self, config): self.addParameter( QgsProcessingParameterMultipleLayers( self.INPUT_POINTS, - self.tr('Point Layers'), + self.tr("Point Layers"), QgsProcessing.TypeVectorPoint, - optional=True + optional=True, ) ) self.addParameter( QgsProcessingParameterMultipleLayers( self.INPUT_LINES, - self.tr('Linestring Layers'), + self.tr("Linestring Layers"), QgsProcessing.TypeVectorLine, - optional=True + optional=True, ) ) self.addParameter( QgsProcessingParameterMultipleLayers( self.INPUT_POLYGONS, - self.tr('Polygon Layers'), + self.tr("Polygon Layers"), QgsProcessing.TypeVectorPolygon, - optional=True + optional=True, ) ) self.addParameter( QgsProcessingParameterBoolean( - self.SELECTED, - self.tr('Process only selected features') + self.SELECTED, self.tr("Process only selected features") ) ) - + + param = QgsProcessingParameterDistance( + self.SEARCH_RADIUS, self.tr("Search Radius"), defaultValue=1.0 + ) + param.setMetadata({"widget_wrapper": {"decimals": 8}}) + self.addParameter(param) + self.addParameter( QgsProcessingParameterVectorLayer( self.GEOGRAPHIC_BOUNDARY, - self.tr('Geographic Boundary'), + self.tr("Geographic Boundary"), [QgsProcessing.TypeVectorPolygon], - optional=True + optional=True, ) ) - def processAlgorithm(self, parameters, context, feedback): """ Here is where the processing itself takes place. """ algRunner = AlgRunner() inputPointLyrList = self.parameterAsLayerList( - parameters, - self.INPUT_POINTS, - context + parameters, self.INPUT_POINTS, context ) inputLineLyrList = self.parameterAsLayerList( - parameters, - self.INPUT_LINES, - context + parameters, self.INPUT_LINES, context ) inputPolygonLyrList = self.parameterAsLayerList( - parameters, - self.INPUT_POLYGONS, - context + parameters, self.INPUT_POLYGONS, context ) + searchRadius = self.parameterAsDouble(parameters, self.SEARCH_RADIUS, context) geographicBoundary = self.parameterAsVectorLayer( - parameters, - self.GEOGRAPHIC_BOUNDARY, - context + parameters, self.GEOGRAPHIC_BOUNDARY, context ) if inputPointLyrList + inputLineLyrList + inputPolygonLyrList == []: - raise QgsProcessingException( - self.tr('Select at least one layer') - ) - onlySelected = self.parameterAsBool( - parameters, - self.SELECTED, - context - ) + raise QgsProcessingException(self.tr("Select at least one layer")) + onlySelected = self.parameterAsBool(parameters, self.SELECTED, context) lyrList = list(chain(inputPointLyrList, inputLineLyrList, inputPolygonLyrList)) nLyrs = len(lyrList) - multiStepFeedback = QgsProcessingMultiStepFeedback(nLyrs + 4 + 2 * (geographicBoundary is not None), feedback) + multiStepFeedback = QgsProcessingMultiStepFeedback( + nLyrs + 4 + 2 * (geographicBoundary is not None), feedback + ) multiStepFeedback.setCurrentStep(0) flagsLyr = algRunner.runIdentifyUnsharedVertexOnIntersectionsAlgorithm( pointLayerList=inputPointLyrList, @@ -138,7 +139,7 @@ def processAlgorithm(self, parameters, context, feedback): onlySelected=onlySelected, context=context, feedback=multiStepFeedback, - is_child_algorithm=True + is_child_algorithm=True, ) if geographicBoundary is not None: multiStepFeedback.setCurrentStep(1) @@ -147,22 +148,24 @@ def processAlgorithm(self, parameters, context, feedback): geographicBoundary, context=context, feedback=multiStepFeedback, - is_child_algorithm=True + is_child_algorithm=True, ) for current, lyr in enumerate(lyrList): if feedback.isCanceled(): break - multiStepFeedback.setCurrentStep(current + 1 + (geographicBoundary is not None)) + multiStepFeedback.setCurrentStep( + current + 1 + (geographicBoundary is not None) + ) algRunner.runSnapLayerOnLayer( inputLayer=lyr, referenceLayer=flagsLyr, - tol=1e-5, + tol=searchRadius, context=context, onlySelected=onlySelected, feedback=multiStepFeedback, behavior=1, buildCache=False, - is_child_algorithm=True + is_child_algorithm=True, ) currentStep = current + 1 + (geographicBoundary is not None) multiStepFeedback.setCurrentStep(currentStep) @@ -172,7 +175,7 @@ def processAlgorithm(self, parameters, context, feedback): polygonLayerList=inputPolygonLyrList, onlySelected=onlySelected, context=context, - feedback=multiStepFeedback + feedback=multiStepFeedback, ) currentStep += 1 if geographicBoundary is not None: @@ -183,7 +186,7 @@ def processAlgorithm(self, parameters, context, feedback): currentStep += 1 if newFlagsLyr.featureCount() == 0: return {} - + multiStepFeedback.setCurrentStep(currentStep) algRunner.runCreateSpatialIndex(newFlagsLyr, context, multiStepFeedback) currentStep += 1 @@ -191,8 +194,8 @@ def processAlgorithm(self, parameters, context, feedback): LayerHandler().addVertexesToLayers( vertexLyr=newFlagsLyr, layerList=list(chain(inputLineLyrList, inputPolygonLyrList)), - searchRadius=1e-5, - feedback=multiStepFeedback + searchRadius=searchRadius, + feedback=multiStepFeedback, ) return {} @@ -205,21 +208,21 @@ def name(self): lowercase alphanumeric characters only and no spaces or other formatting characters. """ - return 'addunsharedvertexonintersectionsalgorithm' + return "addunsharedvertexonintersectionsalgorithm" def displayName(self): """ Returns the translated algorithm name, which should be used for any user-visible display of the algorithm name. """ - return self.tr('Add Unshared Vertex on Intersections') + return self.tr("Add Unshared Vertex on Intersections") def group(self): """ Returns the name of the group this algorithm belongs to. This string should be localised. """ - return self.tr('Quality Assurance Tools (Correction Processes)') + return self.tr("Quality Assurance Tools (Correction Processes)") def groupId(self): """ @@ -229,10 +232,12 @@ def groupId(self): contain lowercase alphanumeric characters only and no spaces or other formatting characters. """ - return 'Quality Assurance Tools (Correction Processes)' + return "DSGTools: Quality Assurance Tools (Correction Processes)" def tr(self, string): - return QCoreApplication.translate('AddUnsharedVertexOnIntersectionsAlgorithm', string) + return QCoreApplication.translate( + "AddUnsharedVertexOnIntersectionsAlgorithm", string + ) def createInstance(self): return AddUnsharedVertexOnIntersectionsAlgorithm() diff --git a/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/addUnsharedVertexOnSharedEdgesAlgorithm.py b/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/addUnsharedVertexOnSharedEdgesAlgorithm.py index b0dc85208..849eb4bd8 100644 --- a/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/addUnsharedVertexOnSharedEdgesAlgorithm.py +++ b/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/addUnsharedVertexOnSharedEdgesAlgorithm.py @@ -24,28 +24,35 @@ from PyQt5.QtCore import QCoreApplication from DsgTools.core.GeometricTools.layerHandler import LayerHandler -from qgis.core import (QgsDataSourceUri, QgsFeature, QgsFeatureSink, - QgsProcessing, QgsProcessingAlgorithm, - QgsProcessingException, QgsProcessingMultiStepFeedback, - QgsProcessingOutputVectorLayer, - QgsProcessingParameterBoolean, - QgsProcessingParameterDistance, - QgsProcessingParameterFeatureSink, - QgsProcessingParameterFeatureSource, - QgsProcessingParameterField, - QgsProcessingParameterMultipleLayers, - QgsProcessingParameterVectorLayer, QgsWkbTypes) +from qgis.core import ( + QgsDataSourceUri, + QgsFeature, + QgsFeatureSink, + QgsProcessing, + QgsProcessingAlgorithm, + QgsProcessingException, + QgsProcessingMultiStepFeedback, + QgsProcessingOutputVectorLayer, + QgsProcessingParameterBoolean, + QgsProcessingParameterDistance, + QgsProcessingParameterFeatureSink, + QgsProcessingParameterFeatureSource, + QgsProcessingParameterField, + QgsProcessingParameterMultipleLayers, + QgsProcessingParameterVectorLayer, + QgsWkbTypes, +) from ...algRunner import AlgRunner from .validationAlgorithm import ValidationAlgorithm class AddUnsharedVertexOnSharedEdgesAlgorithm(ValidationAlgorithm): - INPUT_LINES = 'INPUT_LINES' - INPUT_POLYGONS = 'INPUT_POLYGONS' - SELECTED = 'SELECTED' - SEARCH_RADIUS = 'SEARCH_RADIUS' - GEOGRAPHIC_BOUNDARY = 'GEOGRAPHIC_BOUNDARY' + INPUT_LINES = "INPUT_LINES" + INPUT_POLYGONS = "INPUT_POLYGONS" + SELECTED = "SELECTED" + SEARCH_RADIUS = "SEARCH_RADIUS" + GEOGRAPHIC_BOUNDARY = "GEOGRAPHIC_BOUNDARY" def initAlgorithm(self, config): """ @@ -54,78 +61,57 @@ def initAlgorithm(self, config): self.addParameter( QgsProcessingParameterMultipleLayers( self.INPUT_LINES, - self.tr('Linestring Layers'), + self.tr("Linestring Layers"), QgsProcessing.TypeVectorLine, - optional=True + optional=True, ) ) self.addParameter( QgsProcessingParameterMultipleLayers( self.INPUT_POLYGONS, - self.tr('Polygon Layers'), + self.tr("Polygon Layers"), QgsProcessing.TypeVectorPolygon, - optional=True + optional=True, ) ) self.addParameter( QgsProcessingParameterBoolean( - self.SELECTED, - self.tr('Process only selected features') + self.SELECTED, self.tr("Process only selected features") ) ) - - self.addParameter( - QgsProcessingParameterDistance( - self.SEARCH_RADIUS, - self.tr('Search Radius'), - defaultValue=1.0 - ) + param = QgsProcessingParameterDistance( + self.SEARCH_RADIUS, self.tr("Search Radius"), defaultValue=1.0 ) - + param.setMetadata({"widget_wrapper": {"decimals": 8}}) + self.addParameter(param) + self.addParameter( QgsProcessingParameterVectorLayer( self.GEOGRAPHIC_BOUNDARY, - self.tr('Geographic Boundary'), + self.tr("Geographic Boundary"), [QgsProcessing.TypeVectorPolygon], - optional=True + optional=True, ) ) - def processAlgorithm(self, parameters, context, feedback): """ Here is where the processing itself takes place. """ algRunner = AlgRunner() inputLineLyrList = self.parameterAsLayerList( - parameters, - self.INPUT_LINES, - context + parameters, self.INPUT_LINES, context ) inputPolygonLyrList = self.parameterAsLayerList( - parameters, - self.INPUT_POLYGONS, - context + parameters, self.INPUT_POLYGONS, context ) if inputLineLyrList + inputPolygonLyrList == []: - raise QgsProcessingException( - self.tr('Select at least one layer') - ) - onlySelected = self.parameterAsBool( - parameters, - self.SELECTED, - context - ) - searchRadius = self.parameterAsDouble( - parameters, - self.SEARCH_RADIUS, - context - ) + raise QgsProcessingException(self.tr("Select at least one layer")) + onlySelected = self.parameterAsBool(parameters, self.SELECTED, context) + searchRadius = self.parameterAsDouble(parameters, self.SEARCH_RADIUS, context) geographicBoundary = self.parameterAsVectorLayer( - parameters, - self.GEOGRAPHIC_BOUNDARY, - context + parameters, self.GEOGRAPHIC_BOUNDARY, context ) lyrList = list(chain(inputLineLyrList, inputPolygonLyrList)) nLyrs = len(lyrList) @@ -138,7 +124,7 @@ def processAlgorithm(self, parameters, context, feedback): searchRadius=searchRadius, context=context, feedback=multiStepFeedback, - is_child_algorithm=True + is_child_algorithm=True, ) if geographicBoundary is not None: multiStepFeedback.setCurrentStep(1) @@ -147,12 +133,25 @@ def processAlgorithm(self, parameters, context, feedback): geographicBoundary, context=context, feedback=multiStepFeedback, - is_child_algorithm=True + is_child_algorithm=True, ) + flagsLyr = algRunner.runSnapLayerOnLayer( + inputLayer=flagsLyr, + referenceLayer=flagsLyr, + tol=searchRadius, + context=context, + onlySelected=onlySelected, + feedback=multiStepFeedback, + behavior=6, + buildCache=False, + is_child_algorithm=True, + ) for current, lyr in enumerate(lyrList): if feedback.isCanceled(): break - multiStepFeedback.setCurrentStep(current + 1 + (geographicBoundary is not None)) + multiStepFeedback.setCurrentStep( + current + 2 + (geographicBoundary is not None) + ) algRunner.runSnapLayerOnLayer( inputLayer=lyr, referenceLayer=flagsLyr, @@ -160,8 +159,8 @@ def processAlgorithm(self, parameters, context, feedback): context=context, onlySelected=onlySelected, feedback=multiStepFeedback, - behavior=0, - is_child_algorithm=True + behavior=1, + is_child_algorithm=True, ) currentStep = current + 1 + (geographicBoundary is not None) multiStepFeedback.setCurrentStep(currentStep) @@ -204,21 +203,21 @@ def name(self): lowercase alphanumeric characters only and no spaces or other formatting characters. """ - return 'addunsharedvertexonsharededgesalgorithm' + return "addunsharedvertexonsharededgesalgorithm" def displayName(self): """ Returns the translated algorithm name, which should be used for any user-visible display of the algorithm name. """ - return self.tr('Add Unshared Vertex on Shared Edges') + return self.tr("Add Unshared Vertex on Shared Edges") def group(self): """ Returns the name of the group this algorithm belongs to. This string should be localised. """ - return self.tr('Quality Assurance Tools (Correction Processes)') + return self.tr("Quality Assurance Tools (Correction Processes)") def groupId(self): """ @@ -228,10 +227,12 @@ def groupId(self): contain lowercase alphanumeric characters only and no spaces or other formatting characters. """ - return 'Quality Assurance Tools (Correction Processes)' + return "DSGTools: Quality Assurance Tools (Correction Processes)" def tr(self, string): - return QCoreApplication.translate('AddUnsharedVertexOnSharedEdgesAlgorithm', string) + return QCoreApplication.translate( + "AddUnsharedVertexOnSharedEdgesAlgorithm", string + ) def createInstance(self): return AddUnsharedVertexOnSharedEdgesAlgorithm() diff --git a/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/adjustNetworkConnectivityAlgorithm.py b/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/adjustNetworkConnectivityAlgorithm.py index b207b7d5e..38f13416f 100644 --- a/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/adjustNetworkConnectivityAlgorithm.py +++ b/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/adjustNetworkConnectivityAlgorithm.py @@ -24,30 +24,39 @@ import processing from DsgTools.core.GeometricTools.layerHandler import LayerHandler -from qgis.core import (QgsDataSourceUri, QgsFeature, QgsFeatureSink, - QgsGeometry, QgsProcessing, QgsProcessingAlgorithm, - QgsProcessingMultiStepFeedback, - QgsProcessingOutputVectorLayer, - QgsProcessingParameterBoolean, - QgsProcessingParameterDistance, - QgsProcessingParameterEnum, - QgsProcessingParameterFeatureSink, - QgsProcessingParameterFeatureSource, - QgsProcessingParameterField, - QgsProcessingParameterMultipleLayers, - QgsProcessingParameterNumber, - QgsProcessingParameterVectorLayer, QgsProcessingUtils, - QgsSpatialIndex, QgsWkbTypes, QgsProject) +from qgis.core import ( + QgsDataSourceUri, + QgsFeature, + QgsFeatureSink, + QgsGeometry, + QgsProcessing, + QgsProcessingAlgorithm, + QgsProcessingMultiStepFeedback, + QgsProcessingOutputVectorLayer, + QgsProcessingParameterBoolean, + QgsProcessingParameterDistance, + QgsProcessingParameterEnum, + QgsProcessingParameterFeatureSink, + QgsProcessingParameterFeatureSource, + QgsProcessingParameterField, + QgsProcessingParameterMultipleLayers, + QgsProcessingParameterNumber, + QgsProcessingParameterVectorLayer, + QgsProcessingUtils, + QgsSpatialIndex, + QgsWkbTypes, + QgsProject, +) from ...algRunner import AlgRunner from .validationAlgorithm import ValidationAlgorithm class AdjustNetworkConnectivityAlgorithm(ValidationAlgorithm): - INPUT = 'INPUT' - SELECTED = 'SELECTED' - TOLERANCE = 'TOLERANCE' - OUTPUT = 'OUTPUT' + INPUT = "INPUT" + SELECTED = "SELECTED" + TOLERANCE = "TOLERANCE" + OUTPUT = "OUTPUT" def initAlgorithm(self, config): """ @@ -55,30 +64,26 @@ def initAlgorithm(self, config): """ self.addParameter( QgsProcessingParameterVectorLayer( - self.INPUT, - self.tr('Input layer'), - [QgsProcessing.TypeVectorLine ] + self.INPUT, self.tr("Input layer"), [QgsProcessing.TypeVectorLine] ) ) self.addParameter( QgsProcessingParameterBoolean( - self.SELECTED, - self.tr('Process only selected features') + self.SELECTED, self.tr("Process only selected features") ) ) self.addParameter( QgsProcessingParameterDistance( self.TOLERANCE, - self.tr('Snap radius'), + self.tr("Snap radius"), parentParameterName=self.INPUT, minValue=0, - defaultValue=1.0 + defaultValue=1.0, ) ) self.addOutput( QgsProcessingOutputVectorLayer( - self.OUTPUT, - self.tr('Adjusted original network layer') + self.OUTPUT, self.tr("Adjusted original network layer") ) ) @@ -94,14 +99,26 @@ def processAlgorithm(self, parameters, context, feedback): multiStepFeedback = QgsProcessingMultiStepFeedback(3, feedback) multiStepFeedback.setCurrentStep(0) - multiStepFeedback.pushInfo(self.tr('Identifying dangles on {layer}...').format(layer=inputLyr.name())) - dangleLyr = algRunner.runIdentifyDangles(inputLyr, tol, context, feedback=multiStepFeedback, onlySelected=onlySelected) + multiStepFeedback.pushInfo( + self.tr("Identifying dangles on {layer}...").format(layer=inputLyr.name()) + ) + dangleLyr = algRunner.runIdentifyDangles( + inputLyr, + tol, + context, + feedback=multiStepFeedback, + onlySelected=onlySelected, + ) multiStepFeedback.setCurrentStep(1) layerHandler.filterDangles(dangleLyr, tol, feedback=multiStepFeedback) multiStepFeedback.setCurrentStep(2) - multiStepFeedback.pushInfo(self.tr('Snapping layer {layer} to dangles...').format(layer=inputLyr.name())) + multiStepFeedback.pushInfo( + self.tr("Snapping layer {layer} to dangles...").format( + layer=inputLyr.name() + ) + ) algRunner.runSnapLayerOnLayer( inputLayer=inputLyr, referenceLayer=dangleLyr, @@ -109,7 +126,7 @@ def processAlgorithm(self, parameters, context, feedback): context=context, feedback=multiStepFeedback, onlySelected=onlySelected, - behavior=0 + behavior=0, ) QgsProject.instance().removeMapLayer(dangleLyr.id()) return {self.OUTPUT: inputLyr} @@ -122,21 +139,21 @@ def name(self): lowercase alphanumeric characters only and no spaces or other formatting characters. """ - return 'adjustnetworkconnectivity' + return "adjustnetworkconnectivity" def displayName(self): """ Returns the translated algorithm name, which should be used for any user-visible display of the algorithm name. """ - return self.tr('Adjust Network Connectivity') + return self.tr("Adjust Network Connectivity") def group(self): """ Returns the name of the group this algorithm belongs to. This string should be localised. """ - return self.tr('Quality Assurance Tools (Network Processes)') + return self.tr("Quality Assurance Tools (Network Processes)") def groupId(self): """ @@ -146,10 +163,10 @@ def groupId(self): contain lowercase alphanumeric characters only and no spaces or other formatting characters. """ - return 'DSGTools: Quality Assurance Tools (Network Processes)' + return "DSGTools: Quality Assurance Tools (Network Processes)" def tr(self, string): - return QCoreApplication.translate('AdjustNetworkConnectivityAlgorithm', string) + return QCoreApplication.translate("AdjustNetworkConnectivityAlgorithm", string) def createInstance(self): return AdjustNetworkConnectivityAlgorithm() diff --git a/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/buildPolygonsFromCenterPointsAndBoundariesAlgorithm.py b/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/buildPolygonsFromCenterPointsAndBoundariesAlgorithm.py index 4a805f3de..118db30e9 100644 --- a/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/buildPolygonsFromCenterPointsAndBoundariesAlgorithm.py +++ b/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/buildPolygonsFromCenterPointsAndBoundariesAlgorithm.py @@ -20,8 +20,12 @@ ***************************************************************************/ """ +import concurrent.futures +import os +from uuid import uuid4 from DsgTools.core.GeometricTools.spatialRelationsHandler import SpatialRelationsHandler import processing +from processing.tools import dataobjects from PyQt5.QtCore import QCoreApplication from DsgTools.core.GeometricTools.layerHandler import LayerHandler @@ -44,6 +48,9 @@ QgsProcessingParameterVectorLayer, QgsWkbTypes, QgsProcessingUtils, + QgsVectorLayer, + QgsProcessingFeatureSourceDefinition, + QgsProcessingContext, ) from ...algRunner import AlgRunner @@ -59,10 +66,12 @@ class BuildPolygonsFromCenterPointsAndBoundariesAlgorithm(ValidationAlgorithm): CONSTRAINT_POLYGON_LAYERS = "CONSTRAINT_POLYGON_LAYERS" GEOGRAPHIC_BOUNDARY = "GEOGRAPHIC_BOUNDARY" SUPPRESS_AREA_WITHOUT_CENTROID_FLAG = "SUPPRESS_AREA_WITHOUT_CENTROID_FLAG" + CHECK_UNUSED_BOUDARY_LINES = "CHECK_UNUSED_BOUNDARY_LINES" CHECK_INVALID_GEOMETRIES_ON_OUTPUT_POLYGONS = ( "CHECK_INVALID_GEOMETRIES_ON_OUTPUT_POLYGONS" ) MERGE_OUTPUT_POLYGONS = "MERGE_OUTPUT_POLYGONS" + GROUP_BY_SPATIAL_PARTITION = "GROUP_BY_SPATIAL_PARTITION" OUTPUT_POLYGONS = "OUTPUT_POLYGONS" INVALID_POLYGON_LOCATION = "INVALID_POLYGON_LOCATION" UNUSED_BOUNDARY_LINES = "UNUSED_BOUNDARY_LINES" @@ -141,6 +150,13 @@ def initAlgorithm(self, config): defaultValue=True, ) ) + self.addParameter( + QgsProcessingParameterBoolean( + self.CHECK_UNUSED_BOUDARY_LINES, + self.tr("Check unused boundary lines"), + defaultValue=True, + ) + ) self.addParameter( QgsProcessingParameterBoolean( self.SUPPRESS_AREA_WITHOUT_CENTROID_FLAG, @@ -148,6 +164,12 @@ def initAlgorithm(self, config): defaultValue=False, ) ) + self.addParameter( + QgsProcessingParameterBoolean( + self.GROUP_BY_SPATIAL_PARTITION, + self.tr("Run algothimn grouping by spatial partition"), + ) + ) self.addParameter( QgsProcessingParameterFeatureSink( self.OUTPUT_POLYGONS, self.tr("Output Polygons") @@ -177,8 +199,8 @@ def processAlgorithm(self, parameters, context, feedback): """ Here is where the processing itself takes place. """ - layerHandler = LayerHandler() - algRunner = AlgRunner() + self.layerHandler = LayerHandler() + self.algRunner = AlgRunner() inputCenterPointLyr = self.parameterAsVectorLayer( parameters, self.INPUT_CENTER_POINTS, context ) @@ -194,7 +216,9 @@ def processAlgorithm(self, parameters, context, feedback): ) if boundaryLineLyr is None and constraintLineLyrList == []: raise QgsProcessingException( - self.tr('There must be at least one boundary layer or one constraint line list.') + self.tr( + "There must be at least one boundary layer or one constraint line list." + ) ) constraintPolygonLyrList = self.parameterAsLayerList( parameters, self.CONSTRAINT_POLYGON_LAYERS, context @@ -206,9 +230,12 @@ def processAlgorithm(self, parameters, context, feedback): attributeBlackList = self.parameterAsFields( parameters, self.ATTRIBUTE_BLACK_LIST, context ) - fields = layerHandler.getFieldsFromAttributeBlackList( + fields = self.layerHandler.getFieldsFromAttributeBlackList( inputCenterPointLyr, attributeBlackList ) + groupBySpatialPartition = self.parameterAsBool( + parameters, self.GROUP_BY_SPATIAL_PARTITION, context + ) (output_polygon_sink, output_polygon_sink_id) = self.parameterAsSink( parameters, self.OUTPUT_POLYGONS, @@ -223,6 +250,9 @@ def processAlgorithm(self, parameters, context, feedback): checkInvalidOnOutput = self.parameterAsBool( parameters, self.CHECK_INVALID_GEOMETRIES_ON_OUTPUT_POLYGONS, context ) + checkUnusedBoundaries = self.parameterAsBool( + parameters, self.CHECK_UNUSED_BOUDARY_LINES, context + ) mergeOutput = self.parameterAsBool( parameters, self.MERGE_OUTPUT_POLYGONS, context ) @@ -239,27 +269,42 @@ def processAlgorithm(self, parameters, context, feedback): context, boundaryLineLyr.fields() if boundaryLineLyr is not None else QgsFields(), QgsWkbTypes.LineString, - boundaryLineLyr.sourceCrs() if boundaryLineLyr is not None else inputCenterPointLyr.sourceCrs(), + boundaryLineLyr.sourceCrs() + if boundaryLineLyr is not None + else inputCenterPointLyr.sourceCrs(), ) nSteps = ( - 3 + (mergeOutput + 1) + checkInvalidOnOutput + 3 + (mergeOutput + 1) + checkInvalidOnOutput + checkUnusedBoundaries ) # boolean sum, if true, sums 1 to each term currentStep = 0 multiStepFeedback = QgsProcessingMultiStepFeedback(nSteps, feedback) multiStepFeedback.setCurrentStep(currentStep) - polygonFeatList, flagDict = self.computePolygonsFromCenterPointAndBoundaries( - context, - layerHandler, - algRunner, - inputCenterPointLyr, - boundaryLineLyr, - constraintLineLyrList, - constraintPolygonLyrList, - onlySelected, - geographicBoundaryLyr, - attributeBlackList, - suppressPolygonWithoutCenterPointFlag, - multiStepFeedback, + polygonFeatList, flagDict = ( + self.computePolygonsFromCenterPointAndBoundaries( + context, + inputCenterPointLyr, + boundaryLineLyr, + constraintLineLyrList, + constraintPolygonLyrList, + onlySelected, + geographicBoundaryLyr, + attributeBlackList, + suppressPolygonWithoutCenterPointFlag, + multiStepFeedback, + ) + if not groupBySpatialPartition or geographicBoundaryLyr.featureCount() <= 1 + else self.computePolygonsFromCenterPointAndBoundariesGroupingBySpatialPartition( + context, + inputCenterPointLyr, + boundaryLineLyr, + constraintLineLyrList, + constraintPolygonLyrList, + onlySelected, + geographicBoundaryLyr, + attributeBlackList, + suppressPolygonWithoutCenterPointFlag, + multiStepFeedback, + ) ) currentStep += 1 multiStepFeedback.setCurrentStep(currentStep) @@ -268,29 +313,38 @@ def processAlgorithm(self, parameters, context, feedback): ) currentStep += 1 sink, sink_id = QgsProcessingUtils.createFeatureSink( - 'memory:', context, fields, QgsWkbTypes.Polygon, inputCenterPointLyr.sourceCrs()) - sink.addFeatures(polygonFeatList, QgsFeatureSink.FastInsert) - - multiStepFeedback.setCurrentStep(currentStep) - self.checkUnusedBoundariesAndWriteOutput( + "memory:", context, - boundaryLineLyr, - geographicBoundaryLyr, - sink_id, - unused_boundary_flag_sink, - multiStepFeedback, + fields, + QgsWkbTypes.Polygon, + inputCenterPointLyr.sourceCrs(), ) - currentStep += 1 + sink.addFeatures(polygonFeatList, QgsFeatureSink.FastInsert) + + if checkUnusedBoundaries: + multiStepFeedback.setCurrentStep(currentStep) + self.checkUnusedBoundariesAndWriteOutput( + context, + boundaryLineLyr, + geographicBoundaryLyr, + sink_id, + unused_boundary_flag_sink, + multiStepFeedback, + ) + currentStep += 1 if mergeOutput: multiStepFeedback.setCurrentStep(currentStep) multiStepFeedback.setProgressText(self.tr("Dissolving output...")) - dissolvedLyr = algRunner.runDissolve( - sink_id, context, feedback=multiStepFeedback, field=[field.name() for field in fields] + dissolvedLyr = self.algRunner.runDissolve( + sink_id, + context, + feedback=multiStepFeedback, + field=[field.name() for field in fields], ) currentStep += 1 multiStepFeedback.setCurrentStep(currentStep) - dissolvedLyr = algRunner.runMultipartToSingleParts( + dissolvedLyr = self.algRunner.runMultipartToSingleParts( dissolvedLyr, context=context, feedback=multiStepFeedback ) polygonFeatList = [feat for feat in dissolvedLyr.getFeatures()] @@ -301,15 +355,14 @@ def processAlgorithm(self, parameters, context, feedback): currentStep += 1 if checkInvalidOnOutput: multiStepFeedback.setCurrentStep(currentStep) + multiStepFeedback.setProgressText(self.tr("Checking invalid geometries...")) self.checkInvalidOnOutput( - layerHandler, inputCenterPointLyr, multiStepFeedback, polygonFeatList, invalid_polygon_sink, ) currentStep += 1 - return { self.OUTPUT_POLYGONS: output_polygon_sink_id, @@ -334,7 +387,8 @@ def checkUnusedBoundariesAndWriteOutput( multiStepFeedback.setProgressText(self.tr("Checking unused boundaries...")) currentStep = 0 multiStepFeedback.setCurrentStep(currentStep) - lyr = processing.run( + multiStepFeedback.setProgressText(self.tr("Building cache...")) + builtPolygonsLyr = processing.run( "native:addautoincrementalfield", parameters={ "INPUT": output_polygon_sink_id, @@ -348,101 +402,119 @@ def checkUnusedBoundariesAndWriteOutput( }, context=context, feedback=multiStepFeedback, + is_child_algorithm=True, )["OUTPUT"] currentStep += 1 + multiStepFeedback.setProgressText(self.tr("Converting built polygons to lines...")) multiStepFeedback.setCurrentStep(currentStep) - processing.run( - "native:createspatialindex", {"INPUT": lyr}, feedback=multiStepFeedback + polygonLines = self.algRunner.runPolygonsToLines( + inputLyr=builtPolygonsLyr, + context=context, + feedback=multiStepFeedback, + is_child_algorithm=True, ) currentStep += 1 + multiStepFeedback.setProgressText(self.tr("Exploding lines...")) multiStepFeedback.setCurrentStep(currentStep) - segments = AlgRunner().runExplodeLines(boundaryLineLyr, context, feedback=multiStepFeedback) + explodedPolygonLines = self.algRunner.runExplodeLines( + inputLyr=polygonLines, + context=context, + feedback=multiStepFeedback, + is_child_algorithm=True, + ) currentStep += 1 + multiStepFeedback.setProgressText(self.tr("Building spatial index...")) multiStepFeedback.setCurrentStep(currentStep) - segments = processing.run( - "native:addautoincrementalfield", - parameters={ - "INPUT": segments, - "FIELD_NAME": "featid", - "START": 1, - "GROUP_FIELDS": [], - "SORT_EXPRESSION": "", - "SORT_ASCENDING": True, - "SORT_NULLS_FIRST": False, - "OUTPUT": "TEMPORARY_OUTPUT", - }, + self.algRunner.runCreateSpatialIndex( + inputLyr=explodedPolygonLines, context=context, feedback=multiStepFeedback, - )["OUTPUT"] - currentStep += 1 + is_child_algorithm=True, + ) + multiStepFeedback.setProgressText(self.tr("Exploding boudary lines...")) multiStepFeedback.setCurrentStep(currentStep) - processing.run( - "native:createspatialindex", {"INPUT": segments}, feedback=multiStepFeedback + segments = self.algRunner.runExplodeLines( + boundaryLineLyr, context, feedback=multiStepFeedback, is_child_algorithm=True, + ) + currentStep += 1 + + self.algRunner.runCreateSpatialIndex( + inputLyr=segments, + context=context, + feedback=multiStepFeedback, + is_child_algorithm=True, ) currentStep += 1 if geographicBoundaryLyr is not None: multiStepFeedback.setCurrentStep(currentStep) - segments = AlgRunner().runClip(segments, geographicBoundaryLyr, context=context, feedback=multiStepFeedback) + segments = self.algRunner.runClip( + segments, + geographicBoundaryLyr, + context=context, + feedback=multiStepFeedback, + is_child_algorithm=True, + ) currentStep += 1 - - multiStepFeedback.setCurrentStep(currentStep) - processing.run( - "native:createspatialindex", {"INPUT": segments}, feedback=multiStepFeedback + self.algRunner.runCreateSpatialIndex( + inputLyr=segments, + context=context, + feedback=multiStepFeedback, + is_child_algorithm=True, ) currentStep += 1 + + multiStepFeedback.setProgressText(self.tr("Running spatial join...")) multiStepFeedback.setCurrentStep(currentStep) - flags = SpatialRelationsHandler().checkDE9IM( - layerA=segments, - layerB=lyr, - mask="*1*******", - cardinality="1..*", + unmatchedLines = processing.run( + "native:joinattributesbylocation", + { + 'INPUT':segments, + 'PREDICATE':[2], + 'JOIN':polygonLines, + 'JOIN_FIELDS':[], + 'METHOD':0, + 'DISCARD_NONMATCHING':False, + 'PREFIX':'', + 'NON_MATCHING':'memory:', + }, + context=context, feedback=multiStepFeedback, - ctx=context, - ) - currentStep += 1 - - featidList = list(set(i['featid'] for i in segments.getFeatures(list(flags.keys())))) - if len(featidList) == 0: - multiStepFeedback.setCurrentStep(8 if geographicBoundaryLyr is None else 10) - return - expressionStr = f"featid in {tuple(featidList)}" - if ',)' in expressionStr: - expressionStr = expressionStr.replace(',)',')') + is_child_algorithm=True + )['NON_MATCHING'] + multiStepFeedback.setCurrentStep(currentStep) - segmentedFlags = AlgRunner().runFilterExpression( - segments, - expression=expressionStr, + multiStepFeedback.setProgressText(self.tr("Preparing unused boundaries flags...")) + self.algRunner.runCreateSpatialIndex( + inputLyr=unmatchedLines, context=context, feedback=multiStepFeedback, + is_child_algorithm=True, ) - currentStep += 1 multiStepFeedback.setCurrentStep(currentStep) mergedSegments = processing.run( "native:dissolve", - { - "INPUT": segmentedFlags, - "OUTPUT": "TEMPORARY_OUTPUT" - }, + {"INPUT": unmatchedLines, "OUTPUT": "memory:"}, context=context, - feedback=multiStepFeedback + feedback=multiStepFeedback, )["OUTPUT"] currentStep += 1 multiStepFeedback.setCurrentStep(currentStep) - flagLyr = AlgRunner().runMultipartToSingleParts(mergedSegments, context, feedback=multiStepFeedback) + flagLyr = self.algRunner.runMultipartToSingleParts( + mergedSegments, context, feedback=multiStepFeedback + ) unused_boundary_flag_sink.addFeatures( flagLyr.getFeatures(), QgsFeatureSink.FastInsert ) def checkInvalidOnOutput( self, - layerHandler, inputCenterPointLyr, feedback, polygonFeatList, @@ -453,7 +525,7 @@ def checkInvalidOnOutput( self.tr("Checking for invalid geometries on output polygons...") ) multiStepFeedback.setCurrentStep(0) - invalidGeomFlagDict, _ = layerHandler.identifyInvalidGeometries( + invalidGeomFlagDict, _ = self.layerHandler.identifyInvalidGeometries( polygonFeatList, len(polygonFeatList), inputCenterPointLyr, @@ -496,8 +568,6 @@ def writeOutputPolygons( def computePolygonsFromCenterPointAndBoundaries( self, context, - layerHandler, - algRunner, inputCenterPointLyr, boundaryLineLyr, constraintLineLyrList, @@ -517,53 +587,366 @@ def computePolygonsFromCenterPointAndBoundaries( ( polygonFeatList, flagDict, - ) = layerHandler.getPolygonsFromCenterPointsAndBoundaries( + ) = self.layerHandler.getPolygonsFromCenterPointsAndBoundaries( inputCenterPointLyr, geographicBoundaryLyr=geographicBoundaryLyr, - constraintLineLyrList=constraintLineLyrList + [boundaryLineLyr] if boundaryLineLyr is not None else constraintLineLyrList, + constraintLineLyrList=constraintLineLyrList + [boundaryLineLyr] + if boundaryLineLyr is not None + else constraintLineLyrList, constraintPolygonLyrList=constraintPolygonLyrList, onlySelected=onlySelected, suppressPolygonWithoutCenterPointFlag=suppressPolygonWithoutCenterPointFlag, context=context, feedback=multiStepFeedback, attributeBlackList=attributeBlackList, - algRunner=algRunner, + algRunner=self.algRunner, ) return polygonFeatList, flagDict - def checkUnusedBoundaries( - self, boundaryLineLyr, output_polygon_sink_id, feedback=None, context=None + def computePolygonsFromCenterPointAndBoundariesGroupingBySpatialPartition( + self, + context, + inputCenterPointLyr, + boundaryLineLyr, + constraintLineLyrList, + constraintPolygonLyrList, + onlySelected, + geographicBoundaryLyr, + attributeBlackList, + suppressPolygonWithoutCenterPointFlag, + feedback, ): - multiStepFeedback = QgsProcessingMultiStepFeedback(3, feedback) - multiStepFeedback.setCurrentStep(0) - lyr = processing.run( - "native:addautoincrementalfield", - parameters={ - "INPUT": output_polygon_sink_id, - "FIELD_NAME": "featid", - "START": 1, - "GROUP_FIELDS": [], - "SORT_EXPRESSION": "", - "SORT_ASCENDING": True, - "SORT_NULLS_FIRST": False, - "OUTPUT": "TEMPORARY_OUTPUT", - }, + polygonFeatList = [] + flagDict = dict() + nSteps = 5 + 2 + multiStepFeedback = QgsProcessingMultiStepFeedback(nSteps, feedback) + currentStep = 0 + multiStepFeedback.setCurrentStep(currentStep) + multiStepFeedback.setProgressText(self.tr("Splitting geographic bounds")) + geographicBoundaryLayerList = self.layerHandler.createMemoryLayerForEachFeature( + layer=geographicBoundaryLyr, context=context, feedback=multiStepFeedback + ) + multiStepFeedback.setCurrentStep(currentStep) + multiStepFeedback.setProgressText(self.tr("Preparing constraint lines")) + constraintLinesLyr = ( + self.algRunner.runMergeVectorLayers( + inputList=constraintLineLyrList, + context=context, + feedback=multiStepFeedback, + ) + if len(constraintLineLyrList) > 0 + else None + ) + currentStep += 1 + multiStepFeedback.setCurrentStep(currentStep) + if constraintLinesLyr is not None: + self.algRunner.runCreateSpatialIndex( + constraintLinesLyr, context, multiStepFeedback + ) + currentStep += 1 + multiStepFeedback.setCurrentStep(currentStep) + multiStepFeedback.setProgressText(self.tr("Preparing constraint polygons")) + constraintPolygonsLyr = ( + self.algRunner.runMergeVectorLayers( + inputList=constraintPolygonLyrList, + context=context, + feedback=multiStepFeedback, + ) + if len(constraintPolygonLyrList) > 0 + else None + ) + currentStep += 1 + multiStepFeedback.setCurrentStep(currentStep) + if constraintPolygonsLyr is not None: + self.algRunner.runCreateSpatialIndex( + constraintPolygonsLyr, context, multiStepFeedback + ) + currentStep += 1 + + def compute(localGeographicBoundsLyr): + context = QgsProcessingContext() + if multiStepFeedback.isCanceled(): + return [], {} + localInputCenterPointLyr = self.extractFeaturesUsingGeographicBounds( + inputLyr=inputCenterPointLyr, + geographicBounds=localGeographicBoundsLyr, + feedback=None, + context=context, + onlySelected=onlySelected, + ) + if multiStepFeedback.isCanceled(): + return [], {} + localBoundaryLineLyr = self.extractFeaturesUsingGeographicBounds( + inputLyr=boundaryLineLyr, + geographicBounds=localGeographicBoundsLyr, + feedback=None, + context=context, + onlySelected=onlySelected, + ) + if multiStepFeedback.isCanceled(): + return [], {} + localLinesConstraintLyr = ( + self.extractFeaturesUsingGeographicBounds( + inputLyr=constraintLinesLyr, + geographicBounds=localGeographicBoundsLyr, + feedback=None, + context=context, + onlySelected=onlySelected, + ) + if constraintLinesLyr is not None + else None + ) + if multiStepFeedback.isCanceled(): + return [], {} + localPolygonsConstraintLyr = ( + self.extractFeaturesUsingGeographicBounds( + inputLyr=constraintPolygonsLyr, + geographicBounds=localGeographicBoundsLyr, + feedback=None, + context=context, + onlySelected=onlySelected, + ) + if constraintPolygonsLyr is not None + else None + ) + if multiStepFeedback.isCanceled(): + return [], {} + return self.layerHandler.getPolygonsFromCenterPointsAndBoundariesAlt( + localInputCenterPointLyr, + geographicBoundaryLyr=localGeographicBoundsLyr, + constraintLineLyrList=[localLinesConstraintLyr, localBoundaryLineLyr] + if localLinesConstraintLyr is not None + else [localBoundaryLineLyr], + constraintPolygonLyrList=[localPolygonsConstraintLyr] + if localPolygonsConstraintLyr is not None + else [], + onlySelected=False, # the selected features were already filtered + suppressPolygonWithoutCenterPointFlag=suppressPolygonWithoutCenterPointFlag, + context=context, + feedback=None, + attributeBlackList=attributeBlackList, + algRunner=AlgRunner(), + ) + + multiStepFeedback.setCurrentStep(currentStep) + nRegions = len(geographicBoundaryLayerList) + if nRegions == 0: + return polygonFeatList, flagDict + stepSize = 100 / nRegions + futures = set() + pool = concurrent.futures.ThreadPoolExecutor(max_workers=os.cpu_count() - 1) + multiStepFeedback.setProgressText( + self.tr("Submitting building polygon tasks to thread...") + ) + for current, localGeographicBoundsLyr in enumerate( + geographicBoundaryLayerList, start=0 + ): + if multiStepFeedback.isCanceled(): + pool.shutdown(cancel_futures=True) + break + futures.add(pool.submit(compute, localGeographicBoundsLyr)) + multiStepFeedback.setProgress(current * stepSize) + + currentStep += 1 + multiStepFeedback.setCurrentStep(currentStep) + + multiStepFeedback.setProgressText(self.tr("Evaluating results...")) + for current, future in enumerate(concurrent.futures.as_completed(futures)): + if multiStepFeedback.isCanceled(): + pool.shutdown(cancel_futures=True) + break + localPolygonFeatList, localFlagDict = future.result() + multiStepFeedback.pushInfo( + self.tr( + f"Building polygons from region {current+1}/{nRegions} is done." + ) + ) + multiStepFeedback.setProgress(current * stepSize) + polygonFeatList += localPolygonFeatList + flagDict.update(localFlagDict) + return polygonFeatList, flagDict + + def checkUnusedBoundariesAndWriteOutputGroupingBySpatialPartition( + self, + context, + boundaryLineLyr, + geographicBoundaryLyr, + output_polygon_sink_id, + unused_boundary_flag_sink, + feedback, + ): + if boundaryLineLyr is None: + return + nRegions = geographicBoundaryLyr.featureCount() + if nRegions == 0: + return + nSteps = 5 + multiStepFeedback = QgsProcessingMultiStepFeedback(nSteps, feedback) + multiStepFeedback.setProgressText(self.tr("Checking unused boundaries...")) + currentStep = 0 + multiStepFeedback.setCurrentStep(currentStep) + multiStepFeedback.setProgressText(self.tr("Building aux structures: creating local cache...")) + polygonLyr = self.algRunner.runAddAutoIncrementalField( + inputLyr=output_polygon_sink_id, + fieldName="featid", context=context, - feedback=multiStepFeedback, - )["OUTPUT"] - processing.run( - "native:createspatialindex", {"INPUT": lyr}, feedback=multiStepFeedback + feedback=multiStepFeedback, ) - multiStepFeedback.setCurrentStep(1) - flags = SpatialRelationsHandler().checkDE9IM( - layerA=boundaryLineLyr, - layerB=lyr, - mask="*1*******", - cardinality="1..*", + currentStep += 1 + + multiStepFeedback.setCurrentStep(currentStep) + self.algRunner.runCreateSpatialIndex( + inputLyr=polygonLyr, context=context, feedback=multiStepFeedback + ) + currentStep += 1 + + + multiStepFeedback.setCurrentStep(currentStep) + multiStepFeedback.setProgressText(self.tr("Splitting geographic bounds")) + geographicBoundaryLayerList = self.layerHandler.createMemoryLayerForEachFeature( + layer=geographicBoundaryLyr, context=context, feedback=multiStepFeedback + ) + currentStep += 1 + + def compute(localGeographicBoundsLyr): + context = QgsProcessingContext() + algRunner = AlgRunner() + if multiStepFeedback.isCanceled(): + return + localBoundaries = algRunner.runClip( + boundaryLineLyr, + localGeographicBoundsLyr, + context=context, + feedback=None, + is_child_algorithm=True, + ) + if multiStepFeedback.isCanceled(): + return + localBoundaries = algRunner.runAddAutoIncrementalField( + inputLyr=localBoundaries, + fieldName="local_featid", + context=context, + feedback=None + ) + if multiStepFeedback.isCanceled(): + return + segments = self.algRunner.runExplodeLines( + localBoundaries, context, feedback=None, is_child_algorithm=True + ) + if multiStepFeedback.isCanceled(): + return + segments = algRunner.runAddAutoIncrementalField( + inputLyr=segments, + fieldName="seg_featid", + context=context, + feedback=None + ) + if multiStepFeedback.isCanceled(): + return + flags = SpatialRelationsHandler().checkDE9IM( + layerA=segments, + layerB=polygonLyr, + mask="*1*******", + cardinality="1..*", + feedback=None, + ctx=context, + ) + if multiStepFeedback.isCanceled(): + return + featidList = list( + set(i["seg_featid"] for i in segments.getFeatures(list(flags.keys()))) + ) + if multiStepFeedback.isCanceled(): + return + if len(featidList) == 0: + return + expressionStr = f"seg_featid in {tuple(featidList)}" + if ",)" in expressionStr: + expressionStr = expressionStr.replace(",)", ")") + segmentedFlags = algRunner.runFilterExpression( + segments, + expression=expressionStr, + context=context, + feedback=None, + ) + if multiStepFeedback.isCanceled(): + return + mergedSegments = processing.run( + "native:dissolve", + {"INPUT": segmentedFlags, "OUTPUT": "memory:"}, + context=context, + feedback=None, + )["OUTPUT"] + if multiStepFeedback.isCanceled(): + return + flagLyr = algRunner.runMultipartToSingleParts( + mergedSegments, context, feedback=None + ) + return flagLyr + + + multiStepFeedback.setCurrentStep(currentStep) + + stepSize = 100 / nRegions + futures = set() + pool = concurrent.futures.ThreadPoolExecutor(max_workers=os.cpu_count() - 1) + multiStepFeedback.pushInfo( + self.tr("Submitting verifying unused boundaries tasks to thread...") + ) + for current, localGeographicBoundsLyr in enumerate( + geographicBoundaryLayerList, start=0 + ): + if multiStepFeedback.isCanceled(): + pool.shutdown(cancel_futures=True) + break + futures.add(pool.submit(compute, localGeographicBoundsLyr)) + multiStepFeedback.setProgress(current * stepSize) + + currentStep += 1 + multiStepFeedback.setCurrentStep(currentStep) + + multiStepFeedback.pushInfo(self.tr("Evaluating results...")) + for current, future in enumerate(concurrent.futures.as_completed(futures)): + if multiStepFeedback.isCanceled(): + break + localFlagLyr = future.result() + multiStepFeedback.pushInfo( + self.tr( + f"Verifying unused boundaries from region {current+1}/{nRegions} is done." + ) + ) + multiStepFeedback.setProgress(current * stepSize) + if localFlagLyr is None or localFlagLyr.featureCount() == 0: + continue + unused_boundary_flag_sink.addFeatures( + localFlagLyr.getFeatures(), QgsFeatureSink.FastInsert + ) + + def extractFeaturesUsingGeographicBounds( + self, inputLyr, geographicBounds, context, onlySelected=False, feedback=None + ): + multiStepFeedback = ( + QgsProcessingMultiStepFeedback(2, feedback) + if feedback is not None + else None + ) + if multiStepFeedback is not None: + multiStepFeedback.setCurrentStep(0) + extractedLyr = self.algRunner.runExtractByLocation( + inputLyr=inputLyr + if not onlySelected + else QgsProcessingFeatureSourceDefinition(inputLyr.id(), True), + intersectLyr=geographicBounds, + context=context, feedback=multiStepFeedback, - ctx=context, ) + if multiStepFeedback is not None: + multiStepFeedback.setCurrentStep(1) + self.algRunner.runCreateSpatialIndex( + inputLyr=extractedLyr, context=context, feedback=multiStepFeedback + ) + return extractedLyr def name(self): """ diff --git a/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/cleanGeometriesAlgorithm.py b/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/cleanGeometriesAlgorithm.py index d673de313..29a36f199 100644 --- a/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/cleanGeometriesAlgorithm.py +++ b/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/cleanGeometriesAlgorithm.py @@ -24,31 +24,41 @@ import processing from DsgTools.core.GeometricTools.layerHandler import LayerHandler -from qgis.core import (QgsDataSourceUri, QgsFeature, QgsFeatureSink, - QgsGeometry, QgsProcessing, QgsProcessingAlgorithm, - QgsProcessingException, QgsProcessingMultiStepFeedback, - QgsProcessingOutputVectorLayer, - QgsProcessingParameterBoolean, - QgsProcessingParameterDistance, - QgsProcessingParameterEnum, - QgsProcessingParameterFeatureSink, - QgsProcessingParameterFeatureSource, - QgsProcessingParameterMultipleLayers, - QgsProcessingParameterNumber, - QgsProcessingParameterVectorLayer, QgsProcessingUtils, - QgsProject, QgsSpatialIndex, QgsWkbTypes) +from qgis.core import ( + QgsDataSourceUri, + QgsFeature, + QgsFeatureSink, + QgsGeometry, + QgsProcessing, + QgsProcessingAlgorithm, + QgsProcessingException, + QgsProcessingMultiStepFeedback, + QgsProcessingOutputVectorLayer, + QgsProcessingParameterBoolean, + QgsProcessingParameterDistance, + QgsProcessingParameterEnum, + QgsProcessingParameterFeatureSink, + QgsProcessingParameterFeatureSource, + QgsProcessingParameterMultipleLayers, + QgsProcessingParameterNumber, + QgsProcessingParameterVectorLayer, + QgsProcessingUtils, + QgsProject, + QgsSpatialIndex, + QgsWkbTypes, +) from ...algRunner import AlgRunner from .validationAlgorithm import ValidationAlgorithm class CleanGeometriesAlgorithm(ValidationAlgorithm): - INPUT = 'INPUT' - SELECTED = 'SELECTED' - TOLERANCE = 'TOLERANCE' - MINAREA = 'MINAREA' - FLAGS = 'FLAGS' - OUTPUT = 'OUTPUT' + INPUT = "INPUT" + SELECTED = "SELECTED" + TOLERANCE = "TOLERANCE" + MINAREA = "MINAREA" + FLAGS = "FLAGS" + OUTPUT = "OUTPUT" def initAlgorithm(self, config): """ @@ -57,45 +67,42 @@ def initAlgorithm(self, config): self.addParameter( QgsProcessingParameterVectorLayer( self.INPUT, - self.tr('Input Layer'), - [QgsProcessing.TypeVectorAnyGeometry] + self.tr("Input Layer"), + [QgsProcessing.TypeVectorAnyGeometry], ) ) self.addParameter( QgsProcessingParameterBoolean( - self.SELECTED, - self.tr('Process only selected features') + self.SELECTED, self.tr("Process only selected features") ) ) self.addParameter( QgsProcessingParameterDistance( - self.TOLERANCE, - self.tr('Snap radius'), - parentParameterName=self.INPUT, - minValue=-1.0, - defaultValue=1.0 + self.TOLERANCE, + self.tr("Snap radius"), + parentParameterName=self.INPUT, + minValue=-1.0, + defaultValue=1.0, ) ) self.addParameter( QgsProcessingParameterNumber( self.MINAREA, - self.tr('Minimum area'), + self.tr("Minimum area"), minValue=0, defaultValue=0.0001, - type=QgsProcessingParameterNumber.Double + type=QgsProcessingParameterNumber.Double, ) ) - + self.addParameter( QgsProcessingParameterFeatureSink( - self.FLAGS, - self.tr('{0} Flags').format(self.displayName()) + self.FLAGS, self.tr("{0} Flags").format(self.displayName()) ) ) self.addOutput( QgsProcessingOutputVectorLayer( - self.OUTPUT, - self.tr('Cleaned original layer') + self.OUTPUT, self.tr("Cleaned original layer") ) ) @@ -108,7 +115,9 @@ def processAlgorithm(self, parameters, context, feedback): inputLyr = self.parameterAsVectorLayer(parameters, self.INPUT, context) if inputLyr is None: - raise QgsProcessingException(self.invalidSourceError(parameters, self.INPUT)) + raise QgsProcessingException( + self.invalidSourceError(parameters, self.INPUT) + ) onlySelected = self.parameterAsBool(parameters, self.SELECTED, context) snap = self.parameterAsDouble(parameters, self.TOLERANCE, context) # if snap < 0 and snap != -1: @@ -118,23 +127,35 @@ def processAlgorithm(self, parameters, context, feedback): multiStepFeedback = QgsProcessingMultiStepFeedback(3, feedback) multiStepFeedback.setCurrentStep(0) - multiStepFeedback.pushInfo(self.tr('Populating temp layer...')) - auxLyr = layerHandler.createAndPopulateUnifiedVectorLayer([inputLyr], geomType=inputLyr.wkbType(), onlySelected = onlySelected, feedback=multiStepFeedback) + multiStepFeedback.pushInfo(self.tr("Populating temp layer...")) + auxLyr = layerHandler.createAndPopulateUnifiedVectorLayer( + [inputLyr], + geomType=inputLyr.wkbType(), + onlySelected=onlySelected, + feedback=multiStepFeedback, + ) multiStepFeedback.setCurrentStep(1) - multiStepFeedback.pushInfo(self.tr('Running clean...')) - cleanedLyr, error = algRunner.runClean(auxLyr, \ - [algRunner.RMSA, algRunner.Break, algRunner.RmDupl, algRunner.RmDangle], \ - context, \ - returnError=True, \ - snap=snap, \ - minArea=minArea, - feedback=multiStepFeedback) + multiStepFeedback.pushInfo(self.tr("Running clean...")) + cleanedLyr, error = algRunner.runClean( + auxLyr, + [algRunner.RMSA, algRunner.Break, algRunner.RmDupl, algRunner.RmDangle], + context, + returnError=True, + snap=snap, + minArea=minArea, + feedback=multiStepFeedback, + ) multiStepFeedback.setCurrentStep(2) - multiStepFeedback.pushInfo(self.tr('Updating original layer...')) - layerHandler.updateOriginalLayersFromUnifiedLayer([inputLyr], cleanedLyr, feedback=multiStepFeedback, onlySelected=onlySelected) + multiStepFeedback.pushInfo(self.tr("Updating original layer...")) + layerHandler.updateOriginalLayersFromUnifiedLayer( + [inputLyr], + cleanedLyr, + feedback=multiStepFeedback, + onlySelected=onlySelected, + ) self.flagIssues(cleanedLyr, error, feedback) - return {self.OUTPUT : inputLyr, self.FLAGS : self.flag_id} + return {self.OUTPUT: inputLyr, self.FLAGS: self.flag_id} def flagIssues(self, cleanedLyr, error, feedback): overlapDict = dict() @@ -152,19 +173,22 @@ def flagIssues(self, cleanedLyr, error, feedback): if len(featList) > 1: txtList = [] for i in featList: - txtList += ['{0} (id={1})'.format(i['layer'], i['featid'])] - txt = ', '.join(txtList) - self.flagFeature(featList[0].geometry(), self.tr('Features from {0} overlap').format(txt)) + txtList += ["{0} (id={1})".format(i["layer"], i["featid"])] + txt = ", ".join(txtList) + self.flagFeature( + featList[0].geometry(), + self.tr("Features from {0} overlap").format(txt), + ) elif len(featList) == 1: attrList = featList[0].attributes() - if attrList == len(attrList)*[None]: - self.flagFeature(featList[0].geometry(), self.tr('Gap in layer.')) + if attrList == len(attrList) * [None]: + self.flagFeature(featList[0].geometry(), self.tr("Gap in layer.")) if error: for feat in error.getFeatures(): if feedback.isCanceled(): break - self.flagFeature(feat.geometry(), self.tr('Clean error on layer.')) + self.flagFeature(feat.geometry(), self.tr("Clean error on layer.")) def name(self): """ @@ -174,21 +198,21 @@ def name(self): lowercase alphanumeric characters only and no spaces or other formatting characters. """ - return 'cleangeometries' + return "cleangeometries" def displayName(self): """ Returns the translated algorithm name, which should be used for any user-visible display of the algorithm name. """ - return self.tr('Clean Geometries') + return self.tr("Clean Geometries") def group(self): """ Returns the name of the group this algorithm belongs to. This string should be localised. """ - return self.tr('Quality Assurance Tools (Manipulation Processes)') + return self.tr("Quality Assurance Tools (Manipulation Processes)") def groupId(self): """ @@ -198,10 +222,10 @@ def groupId(self): contain lowercase alphanumeric characters only and no spaces or other formatting characters. """ - return 'DSGTools: Quality Assurance Tools (Manipulation Processes)' + return "DSGTools: Quality Assurance Tools (Manipulation Processes)" def tr(self, string): - return QCoreApplication.translate('CleanGeometriesAlgorithm', string) + return QCoreApplication.translate("CleanGeometriesAlgorithm", string) def createInstance(self): return CleanGeometriesAlgorithm() diff --git a/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/createNetworkNodesAlgorithm.py b/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/createNetworkNodesAlgorithm.py index 3a0d2a5db..ef1199421 100644 --- a/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/createNetworkNodesAlgorithm.py +++ b/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/createNetworkNodesAlgorithm.py @@ -25,38 +25,49 @@ from DsgTools.core.DSGToolsProcessingAlgs.algRunner import AlgRunner from DsgTools.core.GeometricTools.layerHandler import LayerHandler from DsgTools.core.GeometricTools.networkHandler import NetworkHandler -from qgis.core import (QgsDataSourceUri, QgsFeature, QgsFeatureSink, QgsField, - QgsFields, QgsGeometry, QgsProcessing, - QgsProcessingAlgorithm, QgsProcessingException, - QgsProcessingMultiStepFeedback, - QgsProcessingOutputVectorLayer, - QgsProcessingParameterBoolean, - QgsProcessingParameterDistance, - QgsProcessingParameterEnum, - QgsProcessingParameterFeatureSink, - QgsProcessingParameterFeatureSource, - QgsProcessingParameterField, - QgsProcessingParameterMultipleLayers, - QgsProcessingParameterNumber, - QgsProcessingParameterVectorLayer, QgsProcessingUtils, - QgsProject, QgsSpatialIndex, QgsWkbTypes) +from qgis.core import ( + QgsDataSourceUri, + QgsFeature, + QgsFeatureSink, + QgsField, + QgsFields, + QgsGeometry, + QgsProcessing, + QgsProcessingAlgorithm, + QgsProcessingException, + QgsProcessingMultiStepFeedback, + QgsProcessingOutputVectorLayer, + QgsProcessingParameterBoolean, + QgsProcessingParameterDistance, + QgsProcessingParameterEnum, + QgsProcessingParameterFeatureSink, + QgsProcessingParameterFeatureSource, + QgsProcessingParameterField, + QgsProcessingParameterMultipleLayers, + QgsProcessingParameterNumber, + QgsProcessingParameterVectorLayer, + QgsProcessingUtils, + QgsProject, + QgsSpatialIndex, + QgsWkbTypes, +) from .validationAlgorithm import ValidationAlgorithm class CreateNetworkNodesAlgorithm(ValidationAlgorithm): - NETWORK_LAYER = 'NETWORK_LAYER' - ATTRIBUTE_BLACK_LIST = 'ATTRIBUTE_BLACK_LIST' - IGNORE_VIRTUAL_FIELDS = 'IGNORE_VIRTUAL_FIELDS' - IGNORE_PK_FIELDS = 'IGNORE_PK_FIELDS' - SINK_LAYER = 'SINK_LAYER' - SPILLWAY_LAYER = 'SPILLWAY_LAYER' - REF_LAYER = 'REF_LAYER' - WATER_BODY_LAYERS = 'WATER_BODY_LAYERS' - DITCH_LAYER = 'DITCH_LAYER' - SEARCH_RADIUS = 'SEARCH_RADIUS' - NETWORK_NODES = 'NETWORK_NODES' - FLAGS = 'FLAGS' + NETWORK_LAYER = "NETWORK_LAYER" + ATTRIBUTE_BLACK_LIST = "ATTRIBUTE_BLACK_LIST" + IGNORE_VIRTUAL_FIELDS = "IGNORE_VIRTUAL_FIELDS" + IGNORE_PK_FIELDS = "IGNORE_PK_FIELDS" + SINK_LAYER = "SINK_LAYER" + SPILLWAY_LAYER = "SPILLWAY_LAYER" + REF_LAYER = "REF_LAYER" + WATER_BODY_LAYERS = "WATER_BODY_LAYERS" + DITCH_LAYER = "DITCH_LAYER" + SEARCH_RADIUS = "SEARCH_RADIUS" + NETWORK_NODES = "NETWORK_NODES" + FLAGS = "FLAGS" def initAlgorithm(self, config): """ @@ -65,110 +76,104 @@ def initAlgorithm(self, config): self.addParameter( QgsProcessingParameterVectorLayer( self.NETWORK_LAYER, - self.tr('Network layer'), - [QgsProcessing.TypeVectorLine] + self.tr("Network layer"), + [QgsProcessing.TypeVectorLine], ) ) self.addParameter( QgsProcessingParameterField( self.ATTRIBUTE_BLACK_LIST, - self.tr('Fields to ignore'), + self.tr("Fields to ignore"), None, - 'NETWORK_LAYER', + "NETWORK_LAYER", QgsProcessingParameterField.Any, allowMultiple=True, - optional = True + optional=True, ) ) self.addParameter( QgsProcessingParameterBoolean( self.IGNORE_VIRTUAL_FIELDS, - self.tr('Ignore virtual fields'), - defaultValue=True + self.tr("Ignore virtual fields"), + defaultValue=True, ) ) self.addParameter( QgsProcessingParameterBoolean( self.IGNORE_PK_FIELDS, - self.tr('Ignore primary key fields'), - defaultValue=True + self.tr("Ignore primary key fields"), + defaultValue=True, ) ) self.addParameter( QgsProcessingParameterVectorLayer( self.REF_LAYER, - self.tr('Reference layer'), - [QgsProcessing.TypeVectorPolygon] + self.tr("Reference layer"), + [QgsProcessing.TypeVectorPolygon], ) ) self.addParameter( QgsProcessingParameterVectorLayer( self.SINK_LAYER, - self.tr('Water sink layer'), + self.tr("Water sink layer"), [QgsProcessing.TypeVectorPoint], - optional=True + optional=True, ) ) self.addParameter( QgsProcessingParameterVectorLayer( self.SPILLWAY_LAYER, - self.tr('Spillway layer'), + self.tr("Spillway layer"), [QgsProcessing.TypeVectorPoint], - optional=True + optional=True, ) ) self.addParameter( QgsProcessingParameterMultipleLayers( self.WATER_BODY_LAYERS, - self.tr('Water body layers'), + self.tr("Water body layers"), QgsProcessing.TypeVectorPolygon, - optional=True + optional=True, ) ) self.addParameter( QgsProcessingParameterVectorLayer( self.DITCH_LAYER, - self.tr('Ditch layer'), + self.tr("Ditch layer"), [QgsProcessing.TypeVectorLine], - optional=True + optional=True, ) ) self.addParameter( QgsProcessingParameterDistance( - self.SEARCH_RADIUS, - self.tr('Snap radius'), - parentParameterName=self.NETWORK_LAYER, - minValue=0, - defaultValue=1.0 + self.SEARCH_RADIUS, + self.tr("Snap radius"), + parentParameterName=self.NETWORK_LAYER, + minValue=0, + defaultValue=1.0, ) ) self.addParameter( - QgsProcessingParameterFeatureSink( - self.NETWORK_NODES, - self.tr('Node layer') - ) + QgsProcessingParameterFeatureSink(self.NETWORK_NODES, self.tr("Node layer")) ) self.addParameter( - QgsProcessingParameterFeatureSink( - self.FLAGS, - self.tr('Flags') - ) + QgsProcessingParameterFeatureSink(self.FLAGS, self.tr("Flags")) ) self.nodeIdDict = None self.nodeDict = None self.nodeTypeDict = None - + def getFields(self): fields = QgsFields() - fields.append(QgsField('node_type', QVariant.String)) - fields.append(QgsField('layer', QVariant.String)) + fields.append(QgsField("node_type", QVariant.String)) + fields.append(QgsField("layer", QVariant.String)) return fields def processAlgorithm(self, parameters, context, feedback): """ Here is where the processing itself takes place. """ - #get the network handler + # get the network handler layerHandler = LayerHandler() networkHandler = NetworkHandler() algRunner = AlgRunner() @@ -176,17 +181,31 @@ def processAlgorithm(self, parameters, context, feedback): # get network layer networkLayer = self.parameterAsLayer(parameters, self.NETWORK_LAYER, context) if networkLayer is None: - raise QgsProcessingException(self.invalidSourceError(parameters, self.NETWORK_LAYER)) - attributeBlackList = self.parameterAsFields(parameters, self.ATTRIBUTE_BLACK_LIST, context) - ignoreVirtual = self.parameterAsBool(parameters, self.IGNORE_VIRTUAL_FIELDS, context) + raise QgsProcessingException( + self.invalidSourceError(parameters, self.NETWORK_LAYER) + ) + attributeBlackList = self.parameterAsFields( + parameters, self.ATTRIBUTE_BLACK_LIST, context + ) + ignoreVirtual = self.parameterAsBool( + parameters, self.IGNORE_VIRTUAL_FIELDS, context + ) ignorePK = self.parameterAsBool(parameters, self.IGNORE_PK_FIELDS, context) # get network node layer - (nodeSink, dest_id) = self.parameterAsSink(parameters, self.NETWORK_NODES, - context, self.getFields(), QgsWkbTypes.MultiPoint, networkLayer.sourceCrs()) - #prepairs flag sink for raising errors + (nodeSink, dest_id) = self.parameterAsSink( + parameters, + self.NETWORK_NODES, + context, + self.getFields(), + QgsWkbTypes.MultiPoint, + networkLayer.sourceCrs(), + ) + # prepairs flag sink for raising errors self.prepareFlagSink(parameters, networkLayer, QgsWkbTypes.MultiPoint, context) - - waterBodyClasses = self.parameterAsLayer(parameters, self.WATER_BODY_LAYERS, context) + + waterBodyClasses = self.parameterAsLayer( + parameters, self.WATER_BODY_LAYERS, context + ) waterBodyClasses = waterBodyClasses if waterBodyClasses is not None else [] # get water sink layer waterSinkLayer = self.parameterAsLayer(parameters, self.SINK_LAYER, context) @@ -196,50 +215,61 @@ def processAlgorithm(self, parameters, context, feedback): frameLayer = self.parameterAsLayer(parameters, self.REF_LAYER, context) currStep = 0 if frameLayer is None: - raise QgsProcessingException(self.invalidSourceError(parameters, self.REF_LAYER)) + raise QgsProcessingException( + self.invalidSourceError(parameters, self.REF_LAYER) + ) multiStepFeedback = QgsProcessingMultiStepFeedback(3, feedback) multiStepFeedback.setCurrentStep(currStep) - multiStepFeedback.pushInfo(self.tr('Preparing bounds...')) - frame = layerHandler.getFrameOutterBounds(frameLayer, algRunner, context, feedback=multiStepFeedback) + multiStepFeedback.pushInfo(self.tr("Preparing bounds...")) + frame = layerHandler.getFrameOutterBounds( + frameLayer, algRunner, context, feedback=multiStepFeedback + ) currStep += 1 # get search radius searchRadius = self.parameterAsDouble(parameters, self.SEARCH_RADIUS, context) # get ditch layer ditchLayer = self.parameterAsLayer(parameters, self.DITCH_LAYER, context) - #new step + # new step multiStepFeedback.setCurrentStep(currStep) - multiStepFeedback.pushInfo(self.tr('Performing node identification...')) - self.nodeDict = networkHandler.identifyAllNodes(networkLayer=networkLayer, feedback=multiStepFeedback) #zoado, mudar lógica - multiStepFeedback.pushInfo(self.tr('{node_count} node(s) identificated...').format(node_count=len(self.nodeDict))) + multiStepFeedback.pushInfo(self.tr("Performing node identification...")) + self.nodeDict = networkHandler.identifyAllNodes( + networkLayer=networkLayer, feedback=multiStepFeedback + ) # zoado, mudar lógica + multiStepFeedback.pushInfo( + self.tr("{node_count} node(s) identificated...").format( + node_count=len(self.nodeDict) + ) + ) currStep += 1 - #new step + # new step multiStepFeedback.setCurrentStep(currStep) - multiStepFeedback.pushInfo(self.tr('Performing node classification...')) + multiStepFeedback.pushInfo(self.tr("Performing node classification...")) networkHandler.nodeDict = self.nodeDict self.nodeTypeDict, nodeFlagDict = networkHandler.classifyAllNodes( - networkLayer=networkLayer, - frameLyrContourList=frame, - waterBodiesLayers=waterBodyClasses, - searchRadius=searchRadius, - waterSinkLayer=waterSinkLayer, - spillwayLayer=spillwayLayer, - feedback=multiStepFeedback, - attributeBlackList=attributeBlackList, - excludePrimaryKeys=ignorePK, - ignoreVirtualFields=ignoreVirtual, - ditchLayer=ditchLayer - ) + networkLayer=networkLayer, + frameLyrContourList=frame, + waterBodiesLayers=waterBodyClasses, + searchRadius=searchRadius, + waterSinkLayer=waterSinkLayer, + spillwayLayer=spillwayLayer, + feedback=multiStepFeedback, + attributeBlackList=attributeBlackList, + excludePrimaryKeys=ignorePK, + ignoreVirtualFields=ignoreVirtual, + ditchLayer=ditchLayer, + ) currStep += 1 - #new step + # new step multiStepFeedback.setCurrentStep(currStep) - multiStepFeedback.pushInfo(self.tr('Writing nodes...')) + multiStepFeedback.pushInfo(self.tr("Writing nodes...")) self.fillNodeSink( nodeSink=nodeSink, networkLineLayerName=networkLayer.name(), nodeFlagDict=nodeFlagDict, - feedback=multiStepFeedback) - return {self.NETWORK_NODES : dest_id, self.FLAGS : self.flag_id} + feedback=multiStepFeedback, + ) + return {self.NETWORK_NODES: dest_id, self.FLAGS: self.flag_id} def fillNodeSink(self, nodeSink, networkLineLayerName, nodeFlagDict, feedback=None): """ @@ -250,7 +280,7 @@ def fillNodeSink(self, nodeSink, networkLineLayerName, nodeFlagDict, feedback=No # get fields from layer in order to create new feature with the same attribute map fields = self.getFields() nPoints = len(self.nodeTypeDict) - size = 100/nPoints if nPoints else 0 + size = 100 / nPoints if nPoints else 0 # to avoid unnecessary calculation inside loop nodeTypeKeys = self.nodeTypeDict.keys() # initiate new features list @@ -261,15 +291,17 @@ def fillNodeSink(self, nodeSink, networkLineLayerName, nodeFlagDict, feedback=No # set geometry nodeGeom = QgsGeometry.fromMultiPointXY([node]) feat.setGeometry(nodeGeom) - feat['node_type'] = self.nodeTypeDict[node] if node in nodeTypeKeys else None - feat['layer'] = networkLineLayerName + feat["node_type"] = ( + self.nodeTypeDict[node] if node in nodeTypeKeys else None + ) + feat["layer"] = networkLineLayerName if node in nodeFlagDict: self.flagFeature(nodeGeom, nodeFlagDict[node]) featList.append(feat) if feedback is not None: feedback.setProgress(size * current) nodeSink.addFeatures(featList, QgsFeatureSink.FastInsert) - + def flagNetworkProblems(self, nodeTypeDict): """ Raises problems in network as flags. @@ -286,21 +318,21 @@ def name(self): lowercase alphanumeric characters only and no spaces or other formatting characters. """ - return 'createnetworknodes' + return "createnetworknodes" def displayName(self): """ Returns the translated algorithm name, which should be used for any user-visible display of the algorithm name. """ - return self.tr('Create Drainage Network Nodes') + return self.tr("Create Drainage Network Nodes") def group(self): """ Returns the name of the group this algorithm belongs to. This string should be localised. """ - return self.tr('Quality Assurance Tools (Network Processes)') + return self.tr("Quality Assurance Tools (Network Processes)") def groupId(self): """ @@ -310,10 +342,10 @@ def groupId(self): contain lowercase alphanumeric characters only and no spaces or other formatting characters. """ - return 'DSGTools: Quality Assurance Tools (Network Processes)' + return "DSGTools: Quality Assurance Tools (Network Processes)" def tr(self, string): - return QCoreApplication.translate('CreateNetworkNodesAlgorithm', string) + return QCoreApplication.translate("CreateNetworkNodesAlgorithm", string) def createInstance(self): return CreateNetworkNodesAlgorithm() diff --git a/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/deaggregateGeometriesAlgorithm.py b/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/deaggregateGeometriesAlgorithm.py index 3a04927be..3e991c0b9 100644 --- a/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/deaggregateGeometriesAlgorithm.py +++ b/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/deaggregateGeometriesAlgorithm.py @@ -22,25 +22,28 @@ """ from PyQt5.QtCore import QCoreApplication -from qgis.core import (QgsProcessing, - QgsFeatureSink, - QgsProcessingAlgorithm, - QgsProcessingParameterFeatureSource, - QgsProcessingParameterFeatureSink, - QgsFeature, - QgsDataSourceUri, - QgsProcessingOutputVectorLayer, - QgsProcessingParameterVectorLayer, - QgsWkbTypes, - QgsProcessingParameterBoolean) +from qgis.core import ( + QgsProcessing, + QgsFeatureSink, + QgsProcessingAlgorithm, + QgsProcessingParameterFeatureSource, + QgsProcessingParameterFeatureSink, + QgsFeature, + QgsDataSourceUri, + QgsProcessingOutputVectorLayer, + QgsProcessingParameterVectorLayer, + QgsWkbTypes, + QgsProcessingParameterBoolean, +) from DsgTools.core.GeometricTools.layerHandler import LayerHandler from DsgTools.core.GeometricTools.featureHandler import FeatureHandler + class DeaggregatorAlgorithm(QgsProcessingAlgorithm): - OUTPUT = 'OUTPUT' - INPUT = 'INPUT' - SELECTED = 'SELECTED' + OUTPUT = "OUTPUT" + INPUT = "INPUT" + SELECTED = "SELECTED" def initAlgorithm(self, config): """ @@ -49,21 +52,20 @@ def initAlgorithm(self, config): self.addParameter( QgsProcessingParameterVectorLayer( self.INPUT, - self.tr('Input layer'), - [QgsProcessing.TypeVectorAnyGeometry] + self.tr("Input layer"), + [QgsProcessing.TypeVectorAnyGeometry], ) ) self.addParameter( QgsProcessingParameterBoolean( - self.SELECTED, - self.tr('Process only selected features') + self.SELECTED, self.tr("Process only selected features") ) ) - self.addOutput(QgsProcessingOutputVectorLayer( - self.INPUT, - self.tr('Original layer updated') + self.addOutput( + QgsProcessingOutputVectorLayer( + self.INPUT, self.tr("Original layer updated") ) ) @@ -76,17 +78,21 @@ def processAlgorithm(self, parameters, context, feedback): target = self.parameterAsVectorLayer(parameters, self.INPUT, context) target.startEditing() - target.beginEditCommand('Updating layer') + target.beginEditCommand("Updating layer") fields = target.fields() paramDict = LayerHandler().getDestinationParameters(target) featHandler = FeatureHandler() featuresToAdd = [] if onlySelected: - total = 100.0 / target.selectedFeatureCount() if target.selectedFeatureCount() else 0 + total = ( + 100.0 / target.selectedFeatureCount() + if target.selectedFeatureCount() + else 0 + ) features = target.getSelectedFeatures() else: total = 100.0 / target.featureCount() if target.featureCount() else 0 - features = target.getFeatures() + features = target.getFeatures() for current, feature in enumerate(features): if feedback.isCanceled(): @@ -95,7 +101,9 @@ def processAlgorithm(self, parameters, context, feedback): target.deleteFeature(feature.id()) feedback.setProgress(int(current * total)) continue - updtGeom, newFeatList, update = featHandler.handleFeature([feature], feature, target, paramDict) + updtGeom, newFeatList, update = featHandler.handleFeature( + [feature], feature, target, paramDict + ) if not update: feature.setGeometry(updtGeom) target.updateFeature(feature) @@ -120,21 +128,21 @@ def name(self): lowercase alphanumeric characters only and no spaces or other formatting characters. """ - return 'deaggregategeometries' + return "deaggregategeometries" def displayName(self): """ Returns the translated algorithm name, which should be used for any user-visible display of the algorithm name. """ - return self.tr('Deaggregate Geometries') + return self.tr("Deaggregate Geometries") def group(self): """ Returns the name of the group this algorithm belongs to. This string should be localised. """ - return self.tr('Quality Assurance Tools (Manipulation Processes)') + return self.tr("Quality Assurance Tools (Manipulation Processes)") def groupId(self): """ @@ -144,10 +152,10 @@ def groupId(self): contain lowercase alphanumeric characters only and no spaces or other formatting characters. """ - return 'DSGTools: Quality Assurance Tools (Manipulation Processes)' + return "DSGTools: Quality Assurance Tools (Manipulation Processes)" def tr(self, string): - return QCoreApplication.translate('DeaggregatorAlgorithm', string) + return QCoreApplication.translate("DeaggregatorAlgorithm", string) def createInstance(self): return DeaggregatorAlgorithm() diff --git a/DsgTools/core/DSGToolsProcessingAlgs/Algs/LayerManagementAlgs/detectNullGeometriesAlgorithm.py b/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/detectNullGeometriesAlgorithm.py similarity index 72% rename from DsgTools/core/DSGToolsProcessingAlgs/Algs/LayerManagementAlgs/detectNullGeometriesAlgorithm.py rename to DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/detectNullGeometriesAlgorithm.py index 669496382..74406244e 100644 --- a/DsgTools/core/DSGToolsProcessingAlgs/Algs/LayerManagementAlgs/detectNullGeometriesAlgorithm.py +++ b/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/detectNullGeometriesAlgorithm.py @@ -23,21 +23,23 @@ from PyQt5.QtCore import QCoreApplication from PyQt5.QtGui import QColor from qgis.PyQt.Qt import QVariant -from qgis.core import (QgsProcessingAlgorithm, - QgsProcessingParameterMultipleLayers, - QgsField, - QgsVectorLayer, - QgsConditionalStyle, - QgsExpression) +from qgis.core import ( + QgsProcessingAlgorithm, + QgsProcessingParameterMultipleLayers, + QgsField, + QgsVectorLayer, + QgsConditionalStyle, + QgsExpression, +) + class DetectNullGeometriesAlgorithm(QgsProcessingAlgorithm): - INPUT_LAYERS = 'INPUT_LAYERS' + INPUT_LAYERS = "INPUT_LAYERS" def initAlgorithm(self, config=None): self.addParameter( QgsProcessingParameterMultipleLayers( - self.INPUT_LAYERS, - self.tr("Input layers") + self.INPUT_LAYERS, self.tr("Input layers") ) ) @@ -45,17 +47,13 @@ def processAlgorithm(self, parameters, context, feedback): """ Here is where the processing itself takes place. """ - inputLyrList = self.parameterAsLayerList( - parameters, - self.INPUT_LAYERS, - context - ) - + inputLyrList = self.parameterAsLayerList(parameters, self.INPUT_LAYERS, context) + if not inputLyrList: return {} - + listSize = len(inputLyrList) - stepSize = 100/listSize if listSize else 0 + stepSize = 100 / listSize if listSize else 0 for current, lyr in enumerate(inputLyrList): if feedback.isCanceled(): @@ -65,12 +63,10 @@ def processAlgorithm(self, parameters, context, feedback): feedback.setProgress(current * stepSize) return {} - def addRuleToLayer(self, lyr:QgsVectorLayer, feedback=None): + def addRuleToLayer(self, lyr: QgsVectorLayer, feedback=None): conditionalStyle = self.createConditionalStyle() - lyr.conditionalStyles().setRowStyles( - [conditionalStyle] - ) + lyr.conditionalStyles().setRowStyles([conditionalStyle]) def createConditionalStyle(self) -> QgsConditionalStyle: """ @@ -79,34 +75,23 @@ def createConditionalStyle(self) -> QgsConditionalStyle: conditionalStyle = QgsConditionalStyle() conditionalStyle.setName("Geometria nula") conditionalStyle.setRule("is_empty_or_null($geometry)") - conditionalStyle.setBackgroundColor( - QColor(255,0,0) - ) - conditionalStyle.setTextColor( - QColor(255,255,255) - ) + conditionalStyle.setBackgroundColor(QColor(255, 0, 0)) + conditionalStyle.setTextColor(QColor(255, 255, 255)) return conditionalStyle - + def createRuleVirtualField(self, lyr): expressionString = """CASE\n""" expressionString += """WHEN {condition} THEN '{result}'\n""".format( - condition="is_empty_or_null($geometry)", - result="EMPTY/NULL GEOMETRY" - ) + condition="is_empty_or_null($geometry)", result="EMPTY/NULL GEOMETRY" + ) expressionString += """ELSE ''\nEND""" expression = QgsExpression(expressionString) if expression.hasParserError(): - raise Exception( - f"Invalid expression: \n{expressionString}" - ) + raise Exception(f"Invalid expression: \n{expressionString}") lyr.addExpressionField( - expressionString, - QgsField( - 'geometry_error', - QVariant.String - ) + expressionString, QgsField("geometry_error", QVariant.String) ) def name(self): @@ -117,21 +102,21 @@ def name(self): lowercase alphanumeric characters only and no spaces or other formatting characters. """ - return 'detectnullgeometriesalgorithm' + return "detectnullgeometriesalgorithm" def displayName(self): """ Returns the translated algorithm name, which should be used for any user-visible display of the algorithm name. """ - return self.tr('Detect Null Geometries') + return self.tr("Detect Null Geometries") def group(self): """ Returns the name of the group this algorithm belongs to. This string should be localised. """ - return self.tr('Layer Management Algorithms') + return self.tr("Quality Assurance Tools (Identification Processes)") def groupId(self): """ @@ -141,10 +126,10 @@ def groupId(self): contain lowercase alphanumeric characters only and no spaces or other formatting characters. """ - return 'DSGTools: Layer Management Algorithms' + return "DSGTools: Quality Assurance Tools (Identification Processes)" def tr(self, string): - return QCoreApplication.translate('DetectNullGeometriesAlgorithm', string) + return QCoreApplication.translate("DetectNullGeometriesAlgorithm", string) def createInstance(self): return DetectNullGeometriesAlgorithm() diff --git a/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/dissolvePolygonsWithSameAttributesAlgorithm.py b/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/dissolvePolygonsWithSameAttributesAlgorithm.py index 863246c92..d675d6a12 100644 --- a/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/dissolvePolygonsWithSameAttributesAlgorithm.py +++ b/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/dissolvePolygonsWithSameAttributesAlgorithm.py @@ -22,34 +22,30 @@ """ from PyQt5.QtCore import QCoreApplication -import processing from DsgTools.core.GeometricTools.layerHandler import LayerHandler -from qgis.core import (QgsDataSourceUri, QgsFeature, QgsFeatureSink, - QgsGeometry, QgsProcessing, QgsProcessingAlgorithm, - QgsProcessingMultiStepFeedback, - QgsProcessingOutputVectorLayer, - QgsProcessingParameterBoolean, - QgsProcessingParameterEnum, - QgsProcessingParameterFeatureSink, - QgsProcessingParameterFeatureSource, - QgsProcessingParameterField, - QgsProcessingParameterMultipleLayers, - QgsProcessingParameterNumber, - QgsProcessingParameterVectorLayer, QgsProcessingUtils, - QgsSpatialIndex, QgsWkbTypes) +from qgis.core import ( + QgsProcessing, + QgsProcessingMultiStepFeedback, + QgsProcessingOutputVectorLayer, + QgsProcessingParameterBoolean, + QgsProcessingParameterField, + QgsProcessingParameterVectorLayer, + QgsWkbTypes, + QgsProcessingParameterDistance, +) from ...algRunner import AlgRunner from .validationAlgorithm import ValidationAlgorithm class DissolvePolygonsWithSameAttributesAlgorithm(ValidationAlgorithm): - INPUT = 'INPUT' - SELECTED = 'SELECTED' - MIN_AREA = 'MIN_AREA' - ATTRIBUTE_BLACK_LIST = 'ATTRIBUTE_BLACK_LIST' - IGNORE_VIRTUAL_FIELDS = 'IGNORE_VIRTUAL_FIELDS' - IGNORE_PK_FIELDS = 'IGNORE_PK_FIELDS' - OUTPUT = 'OUTPUT' + INPUT = "INPUT" + SELECTED = "SELECTED" + MIN_AREA = "MIN_AREA" + ATTRIBUTE_BLACK_LIST = "ATTRIBUTE_BLACK_LIST" + IGNORE_VIRTUAL_FIELDS = "IGNORE_VIRTUAL_FIELDS" + IGNORE_PK_FIELDS = "IGNORE_PK_FIELDS" + OUTPUT = "OUTPUT" def initAlgorithm(self, config): """ @@ -57,54 +53,53 @@ def initAlgorithm(self, config): """ self.addParameter( QgsProcessingParameterVectorLayer( - self.INPUT, - self.tr('Input layer'), - [QgsProcessing.TypeVectorPolygon ] + self.INPUT, self.tr("Input layer"), [QgsProcessing.TypeVectorPolygon] ) ) self.addParameter( QgsProcessingParameterBoolean( - self.SELECTED, - self.tr('Process only selected features') + self.SELECTED, self.tr("Process only selected features") ) ) - self.addParameter( - QgsProcessingParameterNumber( - self.MIN_AREA, - self.tr('Max dissolve area'), - minValue=0, - optional = True - ) + param = QgsProcessingParameterDistance( + self.MIN_AREA, + self.tr("Max dissolve area"), + parentParameterName=self.INPUT, + minValue=0, + optional=True, ) + param.setMetadata( {'widget_wrapper': + { 'decimals': 10 } + }) + self.addParameter(param) self.addParameter( QgsProcessingParameterField( - self.ATTRIBUTE_BLACK_LIST, - self.tr('Fields to ignore'), - None, - 'INPUT', + self.ATTRIBUTE_BLACK_LIST, + self.tr("Fields to ignore"), + None, + "INPUT", QgsProcessingParameterField.Any, allowMultiple=True, - optional = True + optional=True, ) ) self.addParameter( QgsProcessingParameterBoolean( self.IGNORE_VIRTUAL_FIELDS, - self.tr('Ignore virtual fields'), - defaultValue=True + self.tr("Ignore virtual fields"), + defaultValue=True, ) ) self.addParameter( QgsProcessingParameterBoolean( self.IGNORE_PK_FIELDS, - self.tr('Ignore primary key fields'), - defaultValue=True + self.tr("Ignore primary key fields"), + defaultValue=True, ) ) self.addOutput( QgsProcessingOutputVectorLayer( - self.OUTPUT, - self.tr('Original layer with dissolved polygons') + self.OUTPUT, self.tr("Original layer with dissolved polygons") ) ) @@ -117,8 +112,12 @@ def processAlgorithm(self, parameters, context, feedback): inputLyr = self.parameterAsVectorLayer(parameters, self.INPUT, context) onlySelected = self.parameterAsBool(parameters, self.SELECTED, context) tol = self.parameterAsDouble(parameters, self.MIN_AREA, context) - attributeBlackList = self.parameterAsFields(parameters, self.ATTRIBUTE_BLACK_LIST, context) - ignoreVirtual = self.parameterAsBool(parameters, self.IGNORE_VIRTUAL_FIELDS, context) + attributeBlackList = self.parameterAsFields( + parameters, self.ATTRIBUTE_BLACK_LIST, context + ) + ignoreVirtual = self.parameterAsBool( + parameters, self.IGNORE_VIRTUAL_FIELDS, context + ) ignorePK = self.parameterAsBool(parameters, self.IGNORE_PK_FIELDS, context) tol = -1 if tol is None else tol @@ -126,20 +125,36 @@ def processAlgorithm(self, parameters, context, feedback): multiStepFeedback = QgsProcessingMultiStepFeedback(nSteps, feedback) currentStep = 0 multiStepFeedback.setCurrentStep(currentStep) - multiStepFeedback.pushInfo(self.tr('Populating temp layer...\n')) - unifiedLyr = layerHandler.createAndPopulateUnifiedVectorLayer([inputLyr], geomType=QgsWkbTypes.MultiPolygon, attributeBlackList = attributeBlackList, onlySelected=onlySelected, feedback=multiStepFeedback) + multiStepFeedback.pushInfo(self.tr("Populating temp layer...\n")) + unifiedLyr = layerHandler.createAndPopulateUnifiedVectorLayer( + [inputLyr], + geomType=QgsWkbTypes.MultiPolygon, + attributeBlackList=attributeBlackList, + onlySelected=onlySelected, + feedback=multiStepFeedback, + attributeTupple=False if tol == -1 else True, + ) currentStep += 1 - + if tol > 0: multiStepFeedback.setCurrentStep(currentStep) - multiStepFeedback.pushInfo(self.tr('Adding size constraint field...\n')) - unifiedLyr = layerHandler.addDissolveField(unifiedLyr, tol, feedback = multiStepFeedback) + multiStepFeedback.pushInfo(self.tr("Adding size constraint field...\n")) + unifiedLyr = layerHandler.addDissolveField( + unifiedLyr, tol, feedback=multiStepFeedback + ) currentStep += 1 - + multiStepFeedback.setCurrentStep(currentStep) - multiStepFeedback.pushInfo(self.tr('Running dissolve...\n')) - dissolvedLyr = algRunner.runDissolve(unifiedLyr, context, feedback=multiStepFeedback, field=['tupple']) - layerHandler.updateOriginalLayersFromUnifiedLayer([inputLyr], dissolvedLyr, feedback=multiStepFeedback, onlySelected=onlySelected) + multiStepFeedback.pushInfo(self.tr("Running dissolve...\n")) + dissolvedLyr = algRunner.runDissolve( + unifiedLyr, context, feedback=multiStepFeedback, field=["tupple"] + ) + layerHandler.updateOriginalLayersFromUnifiedLayer( + [inputLyr], + dissolvedLyr, + feedback=multiStepFeedback, + onlySelected=onlySelected, + ) return {self.OUTPUT: inputLyr} @@ -151,21 +166,21 @@ def name(self): lowercase alphanumeric characters only and no spaces or other formatting characters. """ - return 'dissolvepolygonswithsameattributes' + return "dissolvepolygonswithsameattributes" def displayName(self): """ Returns the translated algorithm name, which should be used for any user-visible display of the algorithm name. """ - return self.tr('Dissolve polygons with same attribute set') + return self.tr("Dissolve polygons with same attribute set") def group(self): """ Returns the name of the group this algorithm belongs to. This string should be localised. """ - return self.tr('Quality Assurance Tools (Manipulation Processes)') + return self.tr("Quality Assurance Tools (Manipulation Processes)") def groupId(self): """ @@ -175,10 +190,12 @@ def groupId(self): contain lowercase alphanumeric characters only and no spaces or other formatting characters. """ - return 'DSGTools: Quality Assurance Tools (Manipulation Processes)' + return "DSGTools: Quality Assurance Tools (Manipulation Processes)" def tr(self, string): - return QCoreApplication.translate('DissolvePolygonsWithSameAttributesAlgorithm', string) + return QCoreApplication.translate( + "DissolvePolygonsWithSameAttributesAlgorithm", string + ) def createInstance(self): return DissolvePolygonsWithSameAttributesAlgorithm() diff --git a/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/enforceAttributeRulesAlgorithm.py b/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/enforceAttributeRulesAlgorithm.py index 3b8567407..17ec5c9e8 100644 --- a/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/enforceAttributeRulesAlgorithm.py +++ b/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/enforceAttributeRulesAlgorithm.py @@ -23,19 +23,21 @@ from qgis.PyQt.QtCore import QCoreApplication from qgis.PyQt.QtGui import QColor, QFont -from qgis.core import (QgsFeature, - QgsFeatureRequest, - QgsProject, - QgsWkbTypes, - QgsConditionalStyle, - QgsFeatureSink, - QgsProcessingAlgorithm, - QgsProcessingException, - QgsProcessingParameterBoolean, - QgsProcessingParameterFeatureSink, - QgsProcessingParameterType, - QgsProcessingParameterDefinition) -from qgis.PyQt.QtWidgets import (QMessageBox) +from qgis.core import ( + QgsFeature, + QgsFeatureRequest, + QgsProject, + QgsWkbTypes, + QgsConditionalStyle, + QgsFeatureSink, + QgsProcessingAlgorithm, + QgsProcessingException, + QgsProcessingParameterBoolean, + QgsProcessingParameterFeatureSink, + QgsProcessingParameterType, + QgsProcessingParameterDefinition, +) +from qgis.PyQt.QtWidgets import QMessageBox from .validationAlgorithm import ValidationAlgorithm @@ -68,36 +70,31 @@ def initAlgorithm(self, config): Parameter setting. """ attributeRulesSetter = ParameterAttributeRulesSet( - self.RULES_SET, - description=self.tr("Attribute Rules Set") + self.RULES_SET, description=self.tr("Attribute Rules Set") + ) + attributeRulesSetter.setMetadata( + { + "widget_wrapper": "DsgTools.gui.ProcessingUI.enforceAttributeRulesWrapper.EnforceAttributeRulesWrapper" + } ) - attributeRulesSetter.setMetadata({ - "widget_wrapper": "DsgTools.gui.ProcessingUI.enforceAttributeRulesWrapper.EnforceAttributeRulesWrapper" - }) self.addParameter(attributeRulesSetter) self.addParameter( QgsProcessingParameterBoolean( - self.SELECTED, - self.tr("Process only selected features") + self.SELECTED, self.tr("Process only selected features") ) ) self.addParameter( - QgsProcessingParameterFeatureSink( - self.POINT_FLAGS, - self.tr("Point flags") - ) + QgsProcessingParameterFeatureSink(self.POINT_FLAGS, self.tr("Point flags")) ) self.addParameter( QgsProcessingParameterFeatureSink( - self.LINE_FLAGS, - self.tr("Linestring flags") + self.LINE_FLAGS, self.tr("Linestring flags") ) ) self.addParameter( QgsProcessingParameterFeatureSink( - self.POLYGON_FLAGS, - self.tr("Polygon flags") + self.POLYGON_FLAGS, self.tr("Polygon flags") ) ) @@ -125,54 +122,64 @@ def processAlgorithm(self, parameters, context, feedback): :return: (dict) filled flag layers. """ - rules = self.parameterAsAttributeRulesSet( - parameters, self.RULES_SET, context - ) + rules = self.parameterAsAttributeRulesSet(parameters, self.RULES_SET, context) if not rules: raise QgsProcessingException( self.invalidSourceError(parameters, self.RULES_SET) ) - onlySelected = self.parameterAsBool( - parameters, self.SELECTED, context) + onlySelected = self.parameterAsBool(parameters, self.SELECTED, context) crs = QgsProject.instance().crs() pointFlags, ptId = self.parameterAsSink( - parameters, self.POINT_FLAGS, context, - self.flagFields, QgsWkbTypes.Point, crs) + parameters, + self.POINT_FLAGS, + context, + self.flagFields, + QgsWkbTypes.Point, + crs, + ) if not pointFlags: raise QgsProcessingException( - self.invalidSourceError(parameters, self.POINT_FLAGS)) + self.invalidSourceError(parameters, self.POINT_FLAGS) + ) lineFlags, lId = self.parameterAsSink( - parameters, self.LINE_FLAGS, context, - self.flagFields, QgsWkbTypes.LineString, crs) + parameters, + self.LINE_FLAGS, + context, + self.flagFields, + QgsWkbTypes.LineString, + crs, + ) if not lineFlags: raise QgsProcessingException( - self.invalidSourceError(parameters, self.LINE_FLAGS)) + self.invalidSourceError(parameters, self.LINE_FLAGS) + ) polygonFlags, polId = self.parameterAsSink( - parameters, self.POLYGON_FLAGS, context, - self.flagFields, QgsWkbTypes.Polygon, crs) + parameters, + self.POLYGON_FLAGS, + context, + self.flagFields, + QgsWkbTypes.Polygon, + crs, + ) if not polygonFlags: raise QgsProcessingException( - self.invalidSourceError(parameters, self.POLYGON_FLAGS)) + self.invalidSourceError(parameters, self.POLYGON_FLAGS) + ) failedFeatures = self.applyAttrRules(rules, onlySelected) - self.flagsFromFailedList(failedFeatures, - pointFlags, - lineFlags, - polygonFlags, - feedback) - return { - self.POINT_FLAGS: ptId, - self.LINE_FLAGS: lId, - self.POLYGON_FLAGS: polId} + self.flagsFromFailedList( + failedFeatures, pointFlags, lineFlags, polygonFlags, feedback + ) + return {self.POINT_FLAGS: ptId, self.LINE_FLAGS: lId, self.POLYGON_FLAGS: polId} def applyAttrRules(self, attrRulesMap, onlySelected): """ @@ -190,16 +197,18 @@ def applyAttrRules(self, attrRulesMap, onlySelected): if onlySelected: lyr = proj.mapLayersByName(ruleParam["layerField"][0])[0] request = QgsFeatureRequest().setFilterExpression( - ruleParam["expression"]) + ruleParam["expression"] + ) selectedFeatures = lyr.getSelectedFeatures(request) - ruleParam["features"] = [ - feature for feature in selectedFeatures] + ruleParam["features"] = [feature for feature in selectedFeatures] else: lyr = proj.mapLayersByName(ruleParam["layerField"][0])[0] ruleParam["features"] = [ - feature for feature in lyr.getFeatures(ruleParam["expression"])] - self.applyConditionalStyle(proj.mapLayersByName( - ruleParam["layerField"][0])[0], ruleParam) + feature for feature in lyr.getFeatures(ruleParam["expression"]) + ] + self.applyConditionalStyle( + proj.mapLayersByName(ruleParam["layerField"][0])[0], ruleParam + ) return attrRulesMap def flagsFromFailedList(self, attrRulesMap, ptLayer, lLayer, polLayer, feedback): @@ -216,7 +225,7 @@ def flagsFromFailedList(self, attrRulesMap, ptLayer, lLayer, polLayer, feedback) layerMap = { QgsWkbTypes.PointGeometry: ptLayer, QgsWkbTypes.LineGeometry: lLayer, - QgsWkbTypes.PolygonGeometry: polLayer + QgsWkbTypes.PolygonGeometry: polLayer, } for ruleParam in attrRulesMap.values(): @@ -226,9 +235,7 @@ def flagsFromFailedList(self, attrRulesMap, ptLayer, lLayer, polLayer, feedback) newFeature = QgsFeature(self.flagFields) newFeature["reason"] = flagText newFeature.setGeometry(geom) - layerMap[geom.type()].addFeature( - newFeature, QgsFeatureSink.FastInsert - ) + layerMap[geom.type()].addFeature(newFeature, QgsFeatureSink.FastInsert) self.logResult(attrRulesMap, feedback) return (ptLayer, lLayer, polLayer) @@ -248,15 +255,15 @@ def applyConditionalStyle(self, lyr, values): if isinstance(values["color"], (list, tuple)): self.conditionalStyle.setBackgroundColor( QColor( - values["color"][0], - values["color"][1], - values["color"][2])) + values["color"][0], values["color"][1], values["color"][2] + ) + ) else: - self.conditionalStyle.setBackgroundColor( - QColor(values["color"])) + self.conditionalStyle.setBackgroundColor(QColor(values["color"])) lyr.conditionalStyles().setFieldStyles( - field.name(), [self.conditionalStyle]) + field.name(), [self.conditionalStyle] + ) def logResult(self, attrRulesMap, feedback): """ @@ -266,8 +273,7 @@ def logResult(self, attrRulesMap, feedback): :param feedback: (QgsProcessingFeedback) QGIS progress tracking component. """ - feedback.pushInfo("{0} {1} {0}\n".format( - "===" * 5, self.tr("LOG START"))) + feedback.pushInfo("{0} {1} {0}\n".format("===" * 5, self.tr("LOG START"))) for ruleParam in attrRulesMap.values(): if len(ruleParam["features"]) > 0: @@ -276,13 +282,15 @@ def logResult(self, attrRulesMap, feedback): ruleParam["errorType"], ruleParam["layerField"][0], len(ruleParam["features"]), - self.tr("features") if len(ruleParam["features"]) > 1 else self.tr("feature")) + self.tr("features") + if len(ruleParam["features"]) > 1 + else self.tr("feature"), + ) feedback.pushInfo(row) else: pass - feedback.pushInfo("{0} {1} {0}\n".format( - "===" * 5, self.tr("LOG END"))) + feedback.pushInfo("{0} {1} {0}\n".format("===" * 5, self.tr("LOG END"))) def name(self): """ @@ -332,7 +340,6 @@ def createInstance(self): class ParameterAttributeRulesSetType(QgsProcessingParameterType): - def __init__(self): super().__init__() @@ -340,7 +347,9 @@ def create(self, name): return ParameterAttributeRulesSet(name) def metadata(self): - return {"widget_wrapper": "DsgTools.gui.ProcessingUI.validationAttributeRulesWrapper.ValidationAttributeRulesWrapper"} + return { + "widget_wrapper": "DsgTools.gui.ProcessingUI.validationAttributeRulesWrapper.ValidationAttributeRulesWrapper" + } def name(self): return QCoreApplication.translate("Processing", self.tr("Attribute Rules Set")) @@ -349,11 +358,13 @@ def id(self): return "attribute_rules_set_type" def description(self): - return QCoreApplication.translate("Processing", self.tr("Set of attribute rules. Used on Attribute Rules Checker.")) + return QCoreApplication.translate( + "Processing", + self.tr("Set of attribute rules. Used on Attribute Rules Checker."), + ) class ParameterAttributeRulesSet(QgsProcessingParameterDefinition): - def __init__(self, name, description=""): super().__init__(name, description) diff --git a/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/enforceSpatialRulesAlgorithm.py b/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/enforceSpatialRulesAlgorithm.py index 17c1c0661..6084225bf 100644 --- a/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/enforceSpatialRulesAlgorithm.py +++ b/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/enforceSpatialRulesAlgorithm.py @@ -22,21 +22,28 @@ """ from qgis.PyQt.QtCore import QCoreApplication -from qgis.core import (QgsProject, - QgsFeature, - QgsWkbTypes, - QgsFeatureSink, - QgsProcessingContext, - QgsProcessingException, - QgsProcessingParameterType, - QgsProcessingParameterDefinition, - QgsProcessingParameterFeatureSink) - -from DsgTools.core.GeometricTools\ - .spatialRelationsHandler import SpatialRule, SpatialRelationsHandler +from qgis.core import ( + QgsProject, + QgsFeature, + QgsWkbTypes, + QgsFeatureSink, + QgsProcessingContext, + QgsProcessingException, + QgsProcessingParameterType, + QgsProcessingParameterDefinition, + QgsProcessingParameterFeatureSink, +) + +from DsgTools.core.GeometricTools.spatialRelationsHandler import ( + SpatialRule, + SpatialRelationsHandler, +) from DsgTools.core.GeometricTools.featureHandler import FeatureHandler from DsgTools.core.GeometricTools.geometryHandler import GeometryHandler -from DsgTools.core.DSGToolsProcessingAlgs.Algs.ValidationAlgs.validationAlgorithm import ValidationAlgorithm +from DsgTools.core.DSGToolsProcessingAlgs.Algs.ValidationAlgs.validationAlgorithm import ( + ValidationAlgorithm, +) + class EnforceSpatialRulesAlgorithm(ValidationAlgorithm): RULES_SET = "RULES_SET" @@ -49,32 +56,28 @@ def initAlgorithm(self, config): Parameter setting. """ spatialRulesSetter = ParameterSpatialRulesSet( - self.RULES_SET, - description=self.tr('Spatial rules set') + self.RULES_SET, description=self.tr("Spatial rules set") + ) + spatialRulesSetter.setMetadata( + { + "widget_wrapper": "DsgTools.gui.ProcessingUI.enforceSpatialRuleWrapper.EnforceSpatialRuleWrapper" + } ) - spatialRulesSetter.setMetadata({ - 'widget_wrapper' : 'DsgTools.gui.ProcessingUI.enforceSpatialRuleWrapper.EnforceSpatialRuleWrapper' - }) self.addParameter(spatialRulesSetter) self.addParameter( - QgsProcessingParameterFeatureSink( - self.POINT_FLAGS, - self.tr('Point flags') - ) + QgsProcessingParameterFeatureSink(self.POINT_FLAGS, self.tr("Point flags")) ) self.addParameter( QgsProcessingParameterFeatureSink( - self.LINE_FLAGS, - self.tr('Linestring flags') + self.LINE_FLAGS, self.tr("Linestring flags") ) ) self.addParameter( QgsProcessingParameterFeatureSink( - self.POLYGON_FLAGS, - self.tr('Polygon flags') + self.POLYGON_FLAGS, self.tr("Polygon flags") ) ) @@ -89,21 +92,21 @@ def name(self): lowercase alphanumeric characters only and no spaces or other formatting characters. """ - return 'enforcespatialrules' + return "enforcespatialrules" def displayName(self): """ Returns the translated algorithm name, which should be used for any user-visible display of the algorithm name. """ - return self.tr('Enforce spatial rules') + return self.tr("Enforce spatial rules") def group(self): """ Returns the name of the group this algorithm belongs to. This string should be localised. """ - return self.tr('Quality Assurance Tools (Identification Processes)') + return self.tr("Quality Assurance Tools (Identification Processes)") def groupId(self): """ @@ -113,10 +116,10 @@ def groupId(self): contain lowercase alphanumeric characters only and no spaces or other formatting characters. """ - return 'DSGTools: Quality Assurance Tools (Identification Processes)' + return "DSGTools: Quality Assurance Tools (Identification Processes)" def tr(self, string): - return QCoreApplication.translate('EnforceSpatialRulesAlgorithm', string) + return QCoreApplication.translate("EnforceSpatialRulesAlgorithm", string) def createInstance(self): return EnforceSpatialRulesAlgorithm() @@ -134,12 +137,10 @@ def setFlags(self, flagDict, ptLayer, lLayer, polLayer): layerMap = { QgsWkbTypes.PointGeometry: ptLayer, QgsWkbTypes.LineGeometry: lLayer, - QgsWkbTypes.PolygonGeometry: polLayer + QgsWkbTypes.PolygonGeometry: polLayer, } for ruleName, flags in flagDict.items(): - flagText = self.tr('Rule "{name}" broken: {{text}}').format( - name=ruleName - ) + flagText = self.tr('Rule "{name}" broken: {{text}}').format(name=ruleName) for flagList in flags.values(): for flag in flagList: geom = flag["geom"] @@ -147,7 +148,7 @@ def setFlags(self, flagDict, ptLayer, lLayer, polLayer): newFeature = QgsFeature(fields) newFeature["reason"] = flagText.format(text=flag["text"]) newFeature.setGeometry(g) - layerMap[geom.type()].addFeature( + layerMap[g.type()].addFeature( newFeature, QgsFeatureSink.FastInsert ) return (ptLayer, lLayer, polLayer) @@ -165,9 +166,7 @@ def processAlgorithm(self, parameters, context, feedback): """ Here is where the processing itself takes place. """ - rules = self.parameterAsSpatialRulesSet( - parameters, self.RULES_SET, context - ) + rules = self.parameterAsSpatialRulesSet(parameters, self.RULES_SET, context) # GUI was crashing when the SpatialRule was passed... rules = [SpatialRule(**r, checkLoadedLayer=False) for r in rules] if not rules or not self.validateRuleSet(rules): @@ -177,24 +176,31 @@ def processAlgorithm(self, parameters, context, feedback): flagFields = self.getFlagFields() crs = QgsProject.instance().crs() pointFlags, ptId = self.parameterAsSink( - parameters, self.POINT_FLAGS, context, - flagFields, QgsWkbTypes.Point, crs + parameters, self.POINT_FLAGS, context, flagFields, QgsWkbTypes.Point, crs ) if not pointFlags: raise QgsProcessingException( self.invalidSinkError(parameters, self.POINT_FLAGS) ) lineFlags, lId = self.parameterAsSink( - parameters, self.LINE_FLAGS, context, - flagFields, QgsWkbTypes.LineString, crs + parameters, + self.LINE_FLAGS, + context, + flagFields, + QgsWkbTypes.LineString, + crs, ) if not lineFlags: raise QgsProcessingException( self.invalidSinkError(parameters, self.LINE_FLAGS) ) polygonFlags, polId = self.parameterAsSink( - parameters, self.POLYGON_FLAGS, context, - flagFields, QgsWkbTypes.Polygon, crs + parameters, + self.POLYGON_FLAGS, + context, + flagFields, + QgsWkbTypes.Polygon, + crs, ) if not polygonFlags: raise QgsProcessingException( @@ -202,17 +208,12 @@ def processAlgorithm(self, parameters, context, feedback): ) # marked as 5 steps because I *arbitrarily* set the rule enforcing # steps to be 4:1 to the flag layers creation - flagsDict = SpatialRelationsHandler().enforceRules( - rules, context, feedback) + flagsDict = SpatialRelationsHandler().enforceRules(rules, context, feedback) self.setFlags(flagsDict, pointFlags, lineFlags, polygonFlags) - return { - self.POINT_FLAGS: ptId, - self.LINE_FLAGS: lId, - self.POLYGON_FLAGS: polId - } + return {self.POINT_FLAGS: ptId, self.LINE_FLAGS: lId, self.POLYGON_FLAGS: polId} -class ParameterSpatialRulesSetType(QgsProcessingParameterType): +class ParameterSpatialRulesSetType(QgsProcessingParameterType): def __init__(self): super().__init__() @@ -220,20 +221,24 @@ def create(self, name): return ParameterSpatialRulesSet(name) def metadata(self): - return {'widget_wrapper': 'DsgTools.gui.ProcessingUI.enforceSpatialRuleWrapper.EnforceSpatialRuleWrapper'} + return { + "widget_wrapper": "DsgTools.gui.ProcessingUI.enforceSpatialRuleWrapper.EnforceSpatialRuleWrapper" + } def name(self): - return QCoreApplication.translate('Processing', 'Spatial Rules Set') + return QCoreApplication.translate("Processing", "Spatial Rules Set") def id(self): - return 'spatial_rules_set_type' + return "spatial_rules_set_type" def description(self): - return QCoreApplication.translate('Processing', 'Set of spatial rules. Used on Spatial Rules Checker.') + return QCoreApplication.translate( + "Processing", "Set of spatial rules. Used on Spatial Rules Checker." + ) -class ParameterSpatialRulesSet(QgsProcessingParameterDefinition): - def __init__(self, name, description=''): +class ParameterSpatialRulesSet(QgsProcessingParameterDefinition): + def __init__(self, name, description=""): super().__init__(name, description) def clone(self): @@ -245,7 +250,7 @@ def type(self): @staticmethod def typeName(): - return 'spatial_rules_set' + return "spatial_rules_set" def checkValueIsAcceptable(self, value, context=None): return value is not None diff --git a/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/extendLinesToGeographicBoundsAlgorithm.py b/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/extendLinesToGeographicBoundsAlgorithm.py index 2598bfc76..5a29b63d7 100644 --- a/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/extendLinesToGeographicBoundsAlgorithm.py +++ b/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/extendLinesToGeographicBoundsAlgorithm.py @@ -23,24 +23,28 @@ from PyQt5.QtCore import QCoreApplication from DsgTools.core.GeometricTools.layerHandler import LayerHandler -from qgis.core import (QgsProcessing, QgsProcessingException, QgsProcessingMultiStepFeedback, - QgsProcessingOutputVectorLayer, - QgsProcessingParameterBoolean, - QgsProcessingParameterDistance, - QgsProcessingParameterEnum, - QgsProcessingParameterVectorLayer, - QgsProcessingParameterFeatureSource) +from qgis.core import ( + QgsProcessing, + QgsProcessingException, + QgsProcessingMultiStepFeedback, + QgsProcessingOutputVectorLayer, + QgsProcessingParameterBoolean, + QgsProcessingParameterDistance, + QgsProcessingParameterEnum, + QgsProcessingParameterVectorLayer, + QgsProcessingParameterFeatureSource, +) from ...algRunner import AlgRunner from .validationAlgorithm import ValidationAlgorithm class ExtendLinesToGeographicBoundsAlgorithm(ValidationAlgorithm): - INPUT = 'INPUT' - SELECTED = 'SELECTED' - GEOGRAPHIC_BOUNDS_LAYER = 'GEOGRAPHIC_BOUNDS_LAYER' - EXTEND_LENGTH = 'EXTEND_LENGTH' - OUTPUT = 'OUTPUT' + INPUT = "INPUT" + SELECTED = "SELECTED" + GEOGRAPHIC_BOUNDS_LAYER = "GEOGRAPHIC_BOUNDS_LAYER" + EXTEND_LENGTH = "EXTEND_LENGTH" + OUTPUT = "OUTPUT" def initAlgorithm(self, config): """ @@ -49,39 +53,37 @@ def initAlgorithm(self, config): self.addParameter( QgsProcessingParameterVectorLayer( self.INPUT, - self.tr('Input layer'), - [QgsProcessing.TypeVectorAnyGeometry ] + self.tr("Input layer"), + [QgsProcessing.TypeVectorAnyGeometry], ) ) self.addParameter( QgsProcessingParameterBoolean( - self.SELECTED, - self.tr('Process only selected features') + self.SELECTED, self.tr("Process only selected features") ) ) self.addParameter( QgsProcessingParameterFeatureSource( self.GEOGRAPHIC_BOUNDS_LAYER, - self.tr('Geographic bounds'), + self.tr("Geographic bounds"), [QgsProcessing.TypeVectorPolygon], - optional=False + optional=False, ) ) self.addParameter( QgsProcessingParameterDistance( - self.EXTEND_LENGTH, - self.tr('Extend length'), - parentParameterName=self.INPUT, - minValue=0, - defaultValue=0.0001 + self.EXTEND_LENGTH, + self.tr("Extend length"), + parentParameterName=self.INPUT, + minValue=0, + defaultValue=0.0001, ) ) self.addOutput( QgsProcessingOutputVectorLayer( - self.OUTPUT, - self.tr('Original layer with snapped features') + self.OUTPUT, self.tr("Original layer with snapped features") ) ) @@ -94,35 +96,19 @@ def processAlgorithm(self, parameters, context, feedback): inputLyr = self.parameterAsVectorLayer(parameters, self.INPUT, context) if inputLyr is None: raise QgsProcessingException( - self.invalidSourceError( - parameters, - self.INPUT - ) - ) - onlySelected = self.parameterAsBool( - parameters, - self.SELECTED, - context + self.invalidSourceError(parameters, self.INPUT) ) + onlySelected = self.parameterAsBool(parameters, self.SELECTED, context) refSource = self.parameterAsSource( - parameters, - self.GEOGRAPHIC_BOUNDS_LAYER, - context - ) + parameters, self.GEOGRAPHIC_BOUNDS_LAYER, context + ) if refSource is None: raise QgsProcessingException( - self.invalidSourceError( - parameters, - self.GEOGRAPHIC_BOUNDS_LAYER - ) - ) + self.invalidSourceError(parameters, self.GEOGRAPHIC_BOUNDS_LAYER) + ) if refSource.featureCount() == 0: return {self.OUTPUT: inputLyr} - tol = self.parameterAsDouble( - parameters, - self.EXTEND_LENGTH, - context - ) + tol = self.parameterAsDouble(parameters, self.EXTEND_LENGTH, context) nSteps = 5 currentStep = 0 @@ -133,7 +119,7 @@ def processAlgorithm(self, parameters, context, feedback): layerList=[inputLyr], geomType=inputLyr.wkbType(), onlySelected=onlySelected, - feedback=multiStepFeedback + feedback=multiStepFeedback, ) currentStep += 1 @@ -150,7 +136,7 @@ def processAlgorithm(self, parameters, context, feedback): tol=tol, context=context, feedback=multiStepFeedback, - startPoint=True + startPoint=True, ) currentStep += 1 @@ -161,7 +147,7 @@ def processAlgorithm(self, parameters, context, feedback): tol=tol, context=context, feedback=multiStepFeedback, - startPoint=False + startPoint=False, ) currentStep += 1 @@ -171,13 +157,10 @@ def processAlgorithm(self, parameters, context, feedback): multiStepFeedback.setCurrentStep(currentStep) multiStepFeedback.setProgressText(self.tr("Updating original layer...")) self.layerHandler.updateOriginalLayersFromUnifiedLayer( - [inputLyr], - auxLyr, - feedback=multiStepFeedback, - onlySelected=onlySelected + [inputLyr], auxLyr, feedback=multiStepFeedback, onlySelected=onlySelected ) return {self.OUTPUT: inputLyr} - + def extractGeographicBoundaryLines(self, tol, parameters, context, feedback): multiStepFeedback = QgsProcessingMultiStepFeedback(5, feedback) multiStepFeedback.setCurrentStep(0) @@ -210,15 +193,17 @@ def extractGeographicBoundaryLines(self, tol, parameters, context, feedback): bufferAroundBoundsLines, context, feedback=multiStepFeedback ) return bufferAroundBoundsLines - - def extendLinesByStartOrEndPoints(self, inputLyr, boundsBuffer, tol, context, feedback, startPoint=True): + + def extendLinesByStartOrEndPoints( + self, inputLyr, boundsBuffer, tol, context, feedback, startPoint=True + ): multiStepFeedback = QgsProcessingMultiStepFeedback(6, feedback) multiStepFeedback.setCurrentStep(0) lineExtremityPointLyr = self.algRunner.runExtractSpecificVertices( inputLyr=inputLyr, - vertices='0' if startPoint else '-1', + vertices="0" if startPoint else "-1", context=context, - feedback=multiStepFeedback + feedback=multiStepFeedback, ) multiStepFeedback.setCurrentStep(1) self.algRunner.runCreateSpatialIndex( @@ -226,10 +211,15 @@ def extendLinesByStartOrEndPoints(self, inputLyr, boundsBuffer, tol, context, fe ) multiStepFeedback.setCurrentStep(2) extractedPoints = self.algRunner.runExtractByLocation( - lineExtremityPointLyr, boundsBuffer, context=context, feedback=multiStepFeedback + lineExtremityPointLyr, + boundsBuffer, + context=context, + feedback=multiStepFeedback, ) multiStepFeedback.setCurrentStep(3) - expression = f"featid in {tuple(i['featid'] for i in extractedPoints.getFeatures())}" + expression = ( + f"featid in {tuple(i['featid'] for i in extractedPoints.getFeatures())}" + ) linesToExtend = self.algRunner.runFilterExpression( inputLyr=inputLyr, expression=expression, @@ -248,20 +238,23 @@ def extendLinesByStartOrEndPoints(self, inputLyr, boundsBuffer, tol, context, fe nFeats = extendedLines.featureCount() if nFeats == 0: return - stepSize = 100/nFeats + stepSize = 100 / nFeats originalFeaturesToUpdateDict = { - feat['featid']: feat for feat in inputLyr.getFeatures(expression) + feat["featid"]: feat for feat in inputLyr.getFeatures(expression) } inputLyr.startEditing() - editText = 'Extending lines from start points.' if startPoint \ - else 'Extending lines from end points.' + editText = ( + "Extending lines from start points." + if startPoint + else "Extending lines from end points." + ) inputLyr.beginEditCommand(editText) for current, feat in enumerate(extendedLines.getFeatures()): if multiStepFeedback.isCanceled(): return - + inputLyr.changeGeometry( - originalFeaturesToUpdateDict[feat['featid']].id(), + originalFeaturesToUpdateDict[feat["featid"]].id(), feat.geometry(), skipDefaultValue=True, ) @@ -276,21 +269,21 @@ def name(self): lowercase alphanumeric characters only and no spaces or other formatting characters. """ - return 'extendlinestogeographicbounds' + return "extendlinestogeographicbounds" def displayName(self): """ Returns the translated algorithm name, which should be used for any user-visible display of the algorithm name. """ - return self.tr('Extend Lines To Geographic Bounds Algorithm') + return self.tr("Extend Lines To Geographic Bounds Algorithm") def group(self): """ Returns the name of the group this algorithm belongs to. This string should be localised. """ - return self.tr('Quality Assurance Tools (Manipulation Processes)') + return self.tr("Quality Assurance Tools (Manipulation Processes)") def groupId(self): """ @@ -300,10 +293,12 @@ def groupId(self): contain lowercase alphanumeric characters only and no spaces or other formatting characters. """ - return 'DSGTools: Quality Assurance Tools (Manipulation Processes)' + return "DSGTools: Quality Assurance Tools (Manipulation Processes)" def tr(self, string): - return QCoreApplication.translate('ExtendLinesToGeographicBoundsAlgorithm', string) + return QCoreApplication.translate( + "ExtendLinesToGeographicBoundsAlgorithm", string + ) def createInstance(self): return ExtendLinesToGeographicBoundsAlgorithm() diff --git a/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/fixNetworkAlgorithm.py b/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/fixNetworkAlgorithm.py index b2ef76f80..ac7143eee 100644 --- a/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/fixNetworkAlgorithm.py +++ b/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/fixNetworkAlgorithm.py @@ -24,89 +24,93 @@ import processing from DsgTools.core.GeometricTools.layerHandler import LayerHandler -from qgis.core import (QgsDataSourceUri, QgsFeature, QgsFeatureSink, - QgsGeometry, QgsProcessing, QgsProcessingAlgorithm, - QgsProcessingMultiStepFeedback, - QgsProcessingOutputVectorLayer, - QgsProcessingParameterBoolean, - QgsProcessingParameterDistance, - QgsProcessingParameterEnum, - QgsProcessingParameterFeatureSink, - QgsProcessingParameterFeatureSource, - QgsProcessingParameterField, - QgsProcessingParameterMultipleLayers, - QgsProcessingParameterNumber, - QgsProcessingParameterVectorLayer, QgsProcessingUtils, - QgsSpatialIndex, QgsWkbTypes) +from qgis.core import ( + QgsDataSourceUri, + QgsFeature, + QgsFeatureSink, + QgsGeometry, + QgsProcessing, + QgsProcessingAlgorithm, + QgsProcessingMultiStepFeedback, + QgsProcessingOutputVectorLayer, + QgsProcessingParameterBoolean, + QgsProcessingParameterDistance, + QgsProcessingParameterEnum, + QgsProcessingParameterFeatureSink, + QgsProcessingParameterFeatureSource, + QgsProcessingParameterField, + QgsProcessingParameterMultipleLayers, + QgsProcessingParameterNumber, + QgsProcessingParameterVectorLayer, + QgsProcessingUtils, + QgsSpatialIndex, + QgsWkbTypes, +) from ...algRunner import AlgRunner from .validationAlgorithm import ValidationAlgorithm class FixNetworkAlgorithm(ValidationAlgorithm): - INPUT = 'INPUT' - SELECTED = 'SELECTED' - TOLERANCE = 'TOLERANCE' - ATTRIBUTE_BLACK_LIST = 'ATTRIBUTE_BLACK_LIST' - IGNORE_VIRTUAL_FIELDS = 'IGNORE_VIRTUAL_FIELDS' - IGNORE_PK_FIELDS = 'IGNORE_PK_FIELDS' - OUTPUT = 'OUTPUT' + INPUT = "INPUT" + SELECTED = "SELECTED" + TOLERANCE = "TOLERANCE" + ATTRIBUTE_BLACK_LIST = "ATTRIBUTE_BLACK_LIST" + IGNORE_VIRTUAL_FIELDS = "IGNORE_VIRTUAL_FIELDS" + IGNORE_PK_FIELDS = "IGNORE_PK_FIELDS" + OUTPUT = "OUTPUT" def initAlgorithm(self, config): """ Parameter setting. """ - self.addParameter( + self.addParameter( QgsProcessingParameterVectorLayer( - self.INPUT, - self.tr('Input layer'), - [QgsProcessing.TypeVectorLine ] + self.INPUT, self.tr("Input layer"), [QgsProcessing.TypeVectorLine] ) ) self.addParameter( QgsProcessingParameterBoolean( - self.SELECTED, - self.tr('Process only selected features') + self.SELECTED, self.tr("Process only selected features") ) ) self.addParameter( QgsProcessingParameterDistance( self.TOLERANCE, - self.tr('Topology radius'), + self.tr("Topology radius"), parentParameterName=self.INPUT, minValue=0, - defaultValue=1.0 + defaultValue=1.0, ) ) self.addParameter( QgsProcessingParameterField( - self.ATTRIBUTE_BLACK_LIST, - self.tr('Fields to ignore'), - None, - 'INPUT', + self.ATTRIBUTE_BLACK_LIST, + self.tr("Fields to ignore"), + None, + "INPUT", QgsProcessingParameterField.Any, allowMultiple=True, - optional = True + optional=True, ) ) self.addParameter( QgsProcessingParameterBoolean( self.IGNORE_VIRTUAL_FIELDS, - self.tr('Ignore virtual fields'), - defaultValue=True + self.tr("Ignore virtual fields"), + defaultValue=True, ) ) self.addParameter( QgsProcessingParameterBoolean( self.IGNORE_PK_FIELDS, - self.tr('Ignore primary key fields'), - defaultValue=True + self.tr("Ignore primary key fields"), + defaultValue=True, ) ) self.addOutput( QgsProcessingOutputVectorLayer( - self.OUTPUT, - self.tr('Original layer with merged lines') + self.OUTPUT, self.tr("Original layer with merged lines") ) ) @@ -118,36 +122,16 @@ def processAlgorithm(self, parameters, context, feedback): algRunner = AlgRunner() layerHandler = LayerHandler() - inputLyr = self.parameterAsVectorLayer( - parameters, - self.INPUT, - context - ) - onlySelected = self.parameterAsBool( - parameters, - self.SELECTED, - context - ) - tol = self.parameterAsDouble( - parameters, - self.TOLERANCE, - context - ) + inputLyr = self.parameterAsVectorLayer(parameters, self.INPUT, context) + onlySelected = self.parameterAsBool(parameters, self.SELECTED, context) + tol = self.parameterAsDouble(parameters, self.TOLERANCE, context) attributeBlackList = self.parameterAsFields( - parameters, - self.ATTRIBUTE_BLACK_LIST, - context - ) + parameters, self.ATTRIBUTE_BLACK_LIST, context + ) ignoreVirtual = self.parameterAsBool( - parameters, - self.IGNORE_VIRTUAL_FIELDS, - context - ) - ignorePK = self.parameterAsBool( - parameters, - self.IGNORE_PK_FIELDS, - context - ) + parameters, self.IGNORE_VIRTUAL_FIELDS, context + ) + ignorePK = self.parameterAsBool(parameters, self.IGNORE_PK_FIELDS, context) layerHandler.mergeLinesOnLayer( inputLyr, @@ -155,83 +139,90 @@ def processAlgorithm(self, parameters, context, feedback): onlySelected=onlySelected, ignoreVirtualFields=ignoreVirtual, attributeBlackList=attributeBlackList, - excludePrimaryKeys=ignorePK - ) - #aux layer + excludePrimaryKeys=ignorePK, + ) + # aux layer multiStepFeedback = QgsProcessingMultiStepFeedback(8, feedback) multiStepFeedback.setCurrentStep(0) if onlySelected: - multiStepFeedback.pushInfo(self.tr('Building auxiliar layer...')) + multiStepFeedback.pushInfo(self.tr("Building auxiliar layer...")) coverage = layerHandler.createAndPopulateUnifiedVectorLayer( [inputLyr], geomType=QgsWkbTypes.MultiPolygon, onlySelected=onlySelected, - feedback=multiStepFeedback - ) + feedback=multiStepFeedback, + ) else: coverage = inputLyr - #dangles + # dangles multiStepFeedback.setCurrentStep(1) - multiStepFeedback.pushInfo(self.tr('Identifying dangles on {layer}...').format(layer=coverage.name())) + multiStepFeedback.pushInfo( + self.tr("Identifying dangles on {layer}...").format(layer=coverage.name()) + ) dangleLyr = algRunner.runIdentifyDangles( inputLayer=coverage, searchRadius=tol, context=context, feedback=multiStepFeedback, - onlySelected=False - ) - #filter dangles + onlySelected=False, + ) + # filter dangles multiStepFeedback.setCurrentStep(2) - layerHandler.filterDangles( - dangleLyr, - tol, - feedback=multiStepFeedback - ) - #snap layer to dangles + layerHandler.filterDangles(dangleLyr, tol, feedback=multiStepFeedback) + # snap layer to dangles multiStepFeedback.setCurrentStep(3) - multiStepFeedback.pushInfo(self.tr('Snapping layer {layer} to dangles...').format(layer=coverage.name())) + multiStepFeedback.pushInfo( + self.tr("Snapping layer {layer} to dangles...").format( + layer=coverage.name() + ) + ) algRunner.runSnapLayerOnLayer( coverage, dangleLyr, tol, context, feedback=multiStepFeedback, - onlySelected=False, #this is done due to the aux layer usage - behavior=0 - ) - #inner layer snap + onlySelected=False, # this is done due to the aux layer usage + behavior=0, + ) + # inner layer snap multiStepFeedback.setCurrentStep(4) - multiStepFeedback.pushInfo(self.tr('Snapping layer {layer} with {layer}...').format(layer=coverage.name())) + multiStepFeedback.pushInfo( + self.tr("Snapping layer {layer} with {layer}...").format( + layer=coverage.name() + ) + ) algRunner.runSnapLayerOnLayer( coverage, coverage, tol, context, feedback=multiStepFeedback, - onlySelected=False, #this is done due to the aux layer usage - behavior=0 - ) - #clean to break lines + onlySelected=False, # this is done due to the aux layer usage + behavior=0, + ) + # clean to break lines multiStepFeedback.setCurrentStep(5) - multiStepFeedback.pushInfo(self.tr('Running clean on {layer}...').format(layer=coverage.name())) - multiStepFeedback.pushInfo(self.tr('Running clean on unified layer...')) + multiStepFeedback.pushInfo( + self.tr("Running clean on {layer}...").format(layer=coverage.name()) + ) + multiStepFeedback.pushInfo(self.tr("Running clean on unified layer...")) cleanedCoverage, error = algRunner.runClean( coverage, - [ - algRunner.RMSA, - algRunner.Break, - algRunner.RmDupl, - algRunner.RmDangle - ], + [algRunner.RMSA, algRunner.Break, algRunner.RmDupl, algRunner.RmDangle], context, returnError=True, snap=snap, minArea=minArea, - feedback=multiStepFeedback - ) - #remove duplicated features + feedback=multiStepFeedback, + ) + # remove duplicated features multiStepFeedback.setCurrentStep(6) - multiStepFeedback.pushInfo(self.tr('Removing duplicated features from {layer}...').format(layer=coverage.name())) + multiStepFeedback.pushInfo( + self.tr("Removing duplicated features from {layer}...").format( + layer=coverage.name() + ) + ) algRunner.runRemoveDuplicatedFeatures( inputLyr=cleanedCoverage, context=context, @@ -239,22 +230,23 @@ def processAlgorithm(self, parameters, context, feedback): attributeBlackList=attributeBlackList, excludePrimaryKeys=excludePrimaryKeys, ignorePK=ignorePK, - ignoreVirtual=ignoreVirtual + ignoreVirtual=ignoreVirtual, ) - #merging lines with same attributes + # merging lines with same attributes multiStepFeedback.setCurrentStep(6) - multiStepFeedback.pushInfo(self.tr('Merging lines from {layer} with same attribute set...').format(layer=coverage.name())) + multiStepFeedback.pushInfo( + self.tr("Merging lines from {layer} with same attribute set...").format( + layer=coverage.name() + ) + ) multiStepFeedback.setCurrentStep(7) - multiStepFeedback.pushInfo(self.tr('Updating original layers...')) + multiStepFeedback.pushInfo(self.tr("Updating original layers...")) layerHandler.updateOriginalLayersFromUnifiedLayer( - [inputLyr], - coverage, - feedback=multiStepFeedback, - onlySelected=onlySelected - ) + [inputLyr], coverage, feedback=multiStepFeedback, onlySelected=onlySelected + ) - return {self.INPUTLAYERS : inputLyrList} + return {self.INPUTLAYERS: inputLyrList} def name(self): """ @@ -264,21 +256,21 @@ def name(self): lowercase alphanumeric characters only and no spaces or other formatting characters. """ - return 'topologicallineconnectivityadjustment' + return "topologicallineconnectivityadjustment" def displayName(self): """ Returns the translated algorithm name, which should be used for any user-visible display of the algorithm name. """ - return self.tr('Topological adjustment of the connectivity of lines') + return self.tr("Topological adjustment of the connectivity of lines") def group(self): """ Returns the name of the group this algorithm belongs to. This string should be localised. """ - return self.tr('Quality Assurance Tools (Network Processes)') + return self.tr("Quality Assurance Tools (Network Processes)") def groupId(self): """ @@ -288,10 +280,12 @@ def groupId(self): contain lowercase alphanumeric characters only and no spaces or other formatting characters. """ - return 'DSGTools: Quality Assurance Tools (Network Processes)' + return "DSGTools: Quality Assurance Tools (Network Processes)" def tr(self, string): - return QCoreApplication.translate('TopologicalLineConnectivityAdjustment', string) + return QCoreApplication.translate( + "TopologicalLineConnectivityAdjustment", string + ) def createInstance(self): return TopologicalLineConnectivityAdjustment() diff --git a/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/hierarchicalSnapLayerOnLayerAndUpdateAlgorithm.py b/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/hierarchicalSnapLayerOnLayerAndUpdateAlgorithm.py index 975aeca65..b4b93759e 100644 --- a/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/hierarchicalSnapLayerOnLayerAndUpdateAlgorithm.py +++ b/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/hierarchicalSnapLayerOnLayerAndUpdateAlgorithm.py @@ -24,23 +24,26 @@ from PyQt5.QtCore import QCoreApplication -from qgis.core import (QgsProject, - QgsProcessingUtils, - QgsProcessingContext, - QgsProcessingParameterType, - QgsProcessingParameterEnum, - QgsProcessingParameterBoolean, - QgsProcessingMultiStepFeedback, - QgsProcessingParameterDefinition) +from qgis.core import ( + QgsProject, + QgsProcessingUtils, + QgsProcessingContext, + QgsProcessingParameterType, + QgsProcessingParameterEnum, + QgsProcessingParameterBoolean, + QgsProcessingMultiStepFeedback, + QgsProcessingParameterDefinition, +) from DsgTools.core.GeometricTools.layerHandler import LayerHandler from ...algRunner import AlgRunner from .validationAlgorithm import ValidationAlgorithm + class HierarchicalSnapLayerOnLayerAndUpdateAlgorithm(ValidationAlgorithm): - SELECTED = 'SELECTED' - SNAP_HIERARCHY = 'SNAP_HIERARCHY' - BEHAVIOR = 'BEHAVIOR' + SELECTED = "SELECTED" + SNAP_HIERARCHY = "SNAP_HIERARCHY" + BEHAVIOR = "BEHAVIOR" def initAlgorithm(self, config): """ @@ -48,30 +51,31 @@ def initAlgorithm(self, config): """ hierarchy = ParameterSnapHierarchy( - self.SNAP_HIERARCHY, - description=self.tr('Snap hierarchy') - ) - hierarchy.setMetadata({ - 'widget_wrapper': 'DsgTools.gui.ProcessingUI.snapHierarchyWrapper.SnapHierarchyWrapper' - }) + self.SNAP_HIERARCHY, description=self.tr("Snap hierarchy") + ) + hierarchy.setMetadata( + { + "widget_wrapper": "DsgTools.gui.ProcessingUI.snapHierarchyWrapper.SnapHierarchyWrapper" + } + ) self.addParameter(hierarchy) self.addParameter( QgsProcessingParameterBoolean( - self.SELECTED, - self.tr('Process only selected features') + self.SELECTED, self.tr("Process only selected features") ) ) - self.modes = [self.tr('Prefer aligning nodes, insert extra vertices where required'), - self.tr('Prefer closest point, insert extra vertices where required'), - self.tr('Prefer aligning nodes, don\'t insert new vertices'), - self.tr('Prefer closest point, don\'t insert new vertices'), - self.tr('Move end points only, prefer aligning nodes'), - self.tr('Move end points only, prefer closest point'), - self.tr('Snap end points to end points only')] + self.modes = [ + self.tr("Prefer aligning nodes, insert extra vertices where required"), + self.tr("Prefer closest point, insert extra vertices where required"), + self.tr("Prefer aligning nodes, don't insert new vertices"), + self.tr("Prefer closest point, don't insert new vertices"), + self.tr("Move end points only, prefer aligning nodes"), + self.tr("Move end points only, prefer closest point"), + self.tr("Snap end points to end points only"), + ] - def parameterAsSnapHierarchy(self, parameters, name, context): return parameters[name] @@ -91,38 +95,44 @@ def processAlgorithm(self, parameters, context, feedback): """ self.layerHandler = LayerHandler() self.algRunner = AlgRunner() - snapDictList = self.parameterAsSnapHierarchy(parameters, self.SNAP_HIERARCHY, context) + snapDictList = self.parameterAsSnapHierarchy( + parameters, self.SNAP_HIERARCHY, context + ) onlySelected = self.parameterAsBool(parameters, self.SELECTED, context) nSteps = 0 for item in snapDictList: - nSteps += len(item['snapLayerList']) - multiStepFeedback = QgsProcessingMultiStepFeedback(2*nSteps + 2, feedback) + nSteps += len(item["snapLayerList"]) + multiStepFeedback = QgsProcessingMultiStepFeedback(2 * nSteps + 2, feedback) currentStep = 0 multiStepFeedback.setCurrentStep(currentStep) - snapStructure = self.buildSnapStructure(snapDictList, onlySelected, context, multiStepFeedback) + snapStructure = self.buildSnapStructure( + snapDictList, onlySelected, context, multiStepFeedback + ) currentStep += 1 for item in snapDictList: multiStepFeedback.setCurrentStep(currentStep) - referenceLayerName = item['referenceLayer'] + referenceLayerName = item["referenceLayer"] if referenceLayerName not in snapStructure: currentStep += 2 continue multiStepFeedback.pushInfo( self.tr(f"Performing snap internally on {referenceLayerName}.") ) - snapStructure[referenceLayerName]['tempLayer'] = self.snapToReferenceAndUpdateSpatialIndex( - inputLayer=snapStructure[referenceLayerName]['tempLayer'], - referenceLayer=snapStructure[referenceLayerName]['tempLayer'], - tol=item['snap'], - behavior=item['mode'], + snapStructure[referenceLayerName][ + "tempLayer" + ] = self.snapToReferenceAndUpdateSpatialIndex( + inputLayer=snapStructure[referenceLayerName]["tempLayer"], + referenceLayer=snapStructure[referenceLayerName]["tempLayer"], + tol=item["snap"], + behavior=item["mode"], context=context, - feedback=multiStepFeedback + feedback=multiStepFeedback, ) currentStep += 1 multiStepFeedback.setCurrentStep(currentStep) - lyrList = [i for i in item['snapLayerList'] if i in snapStructure] + lyrList = [i for i in item["snapLayerList"] if i in snapStructure] multiStepFeedback.pushInfo( self.tr(f"Starting snapping with reference layer {referenceLayerName}.") ) @@ -130,36 +140,39 @@ def processAlgorithm(self, parameters, context, feedback): refLyrName=referenceLayerName, snapStructure=snapStructure, lyrList=lyrList, - tol=item['snap'], - behavior=item['mode'], + tol=item["snap"], + behavior=item["mode"], context=context, - feedback=multiStepFeedback + feedback=multiStepFeedback, ) currentStep += 1 multiStepFeedback.setCurrentStep(currentStep) - self.updateOriginalLayers(snapStructure, onlySelected=onlySelected, context=context, feedback=multiStepFeedback) + self.updateOriginalLayers( + snapStructure, + onlySelected=onlySelected, + context=context, + feedback=multiStepFeedback, + ) return {} - def snapLayersToReference(self, refLyrName, snapStructure, lyrList, tol, behavior, context, feedback): + def snapLayersToReference( + self, refLyrName, snapStructure, lyrList, tol, behavior, context, feedback + ): nSteps = len(lyrList) if nSteps == 0: return multiStepFeedback = QgsProcessingMultiStepFeedback(nSteps, feedback) - refLyr = snapStructure[refLyrName]['tempLayer'] + refLyr = snapStructure[refLyrName]["tempLayer"] for current, lyrName in enumerate(lyrList): multiStepFeedback.setCurrentStep(current) if multiStepFeedback.isCanceled(): return - lyr = snapStructure[lyrName]['tempLayer'] + lyr = snapStructure[lyrName]["tempLayer"] multiStepFeedback.pushInfo( self.tr( - 'Snapping geometries from layer {input} to {reference} with snap {snap}...' - ).format( - input=refLyrName, - reference=lyrName, - snap=tol - ) + "Snapping geometries from layer {input} to {reference} with snap {snap}..." + ).format(input=refLyrName, reference=lyrName, snap=tol) ) snappedLyr = self.snapToReferenceAndUpdateSpatialIndex( inputLayer=lyr, @@ -167,44 +180,46 @@ def snapLayersToReference(self, refLyrName, snapStructure, lyrList, tol, behavio tol=tol, behavior=behavior, context=context, - feedback=multiStepFeedback + feedback=multiStepFeedback, ) - snapStructure[lyrName]['tempLayer'] = snappedLyr + snapStructure[lyrName]["tempLayer"] = snappedLyr def buildSnapStructure(self, snapDictList, onlySelected, context, feedback): snapStructure = dict() nItems = len(snapDictList) if nItems == 0: return snapStructure - multiStepFeedback = QgsProcessingMultiStepFeedback(2*nItems, feedback) + multiStepFeedback = QgsProcessingMultiStepFeedback(2 * nItems, feedback) currentStep = 0 for item in snapDictList: multiStepFeedback.setCurrentStep(currentStep) if multiStepFeedback.isCanceled(): break - lyr = self.layerFromProject(item['referenceLayer']) - featCount = lyr.featureCount() if not onlySelected else lyr.selectedFeatureCount() + lyr = self.layerFromProject(item["referenceLayer"]) + featCount = ( + lyr.featureCount() if not onlySelected else lyr.selectedFeatureCount() + ) if featCount == 0: continue auxLyr = self.layerHandler.createAndPopulateUnifiedVectorLayer( [lyr], geomType=lyr.wkbType(), onlySelected=onlySelected, - feedback=multiStepFeedback + feedback=multiStepFeedback, ) currentStep += 1 multiStepFeedback.setCurrentStep(currentStep) - self.algRunner.runCreateSpatialIndex( - auxLyr, context, multiStepFeedback - ) + self.algRunner.runCreateSpatialIndex(auxLyr, context, multiStepFeedback) currentStep += 1 - snapStructure[item['referenceLayer']] = { - 'originalLayer': lyr, - 'tempLayer': auxLyr + snapStructure[item["referenceLayer"]] = { + "originalLayer": lyr, + "tempLayer": auxLyr, } return snapStructure - def snapToReferenceAndUpdateSpatialIndex(self, inputLayer, referenceLayer, tol, behavior, context, feedback): + def snapToReferenceAndUpdateSpatialIndex( + self, inputLayer, referenceLayer, tol, behavior, context, feedback + ): multiStepFeedback = QgsProcessingMultiStepFeedback(2, feedback) multiStepFeedback.setCurrentStep(0) snappedLyr = self.algRunner.runSnapGeometriesToLayer( @@ -214,26 +229,30 @@ def snapToReferenceAndUpdateSpatialIndex(self, inputLayer, referenceLayer, tol, behavior=behavior, context=context, feedback=multiStepFeedback, - is_child_algorithm=True + is_child_algorithm=True, ) multiStepFeedback.setCurrentStep(1) - self.algRunner.runCreateSpatialIndex(snappedLyr, context, multiStepFeedback, is_child_algorithm=True) + self.algRunner.runCreateSpatialIndex( + snappedLyr, context, multiStepFeedback, is_child_algorithm=True + ) return snappedLyr - + def updateOriginalLayers(self, snapStructure, onlySelected, context, feedback): multiStepFeedback = QgsProcessingMultiStepFeedback(len(snapStructure), feedback) for current, (lyrName, auxDict) in enumerate(snapStructure.items()): multiStepFeedback.setCurrentStep(current) - multiStepFeedback.pushInfo(self.tr(f'Updating changes on {lyrName}')) - tempLyr = QgsProcessingUtils.mapLayerFromString(auxDict['tempLayer'], context) + multiStepFeedback.pushInfo(self.tr(f"Updating changes on {lyrName}")) + tempLyr = QgsProcessingUtils.mapLayerFromString( + auxDict["tempLayer"], context + ) self.layerHandler.updateOriginalLayersFromUnifiedLayer( - [auxDict['originalLayer']], + [auxDict["originalLayer"]], tempLyr, feedback=multiStepFeedback, - onlySelected=onlySelected + onlySelected=onlySelected, ) QgsProject.instance().removeMapLayer(tempLyr.id()) - + def name(self): """ Returns the algorithm name, used for identifying the algorithm. This @@ -242,21 +261,21 @@ def name(self): lowercase alphanumeric characters only and no spaces or other formatting characters. """ - return 'hierarchicalsnaplayeronlayer' + return "hierarchicalsnaplayeronlayer" def displayName(self): """ Returns the translated algorithm name, which should be used for any user-visible display of the algorithm name. """ - return self.tr('Hierarchical Snap layer on layer') + return self.tr("Hierarchical Snap layer on layer") def group(self): """ Returns the name of the group this algorithm belongs to. This string should be localised. """ - return self.tr('Quality Assurance Tools (Manipulation Processes)') + return self.tr("Quality Assurance Tools (Manipulation Processes)") def groupId(self): """ @@ -266,37 +285,44 @@ def groupId(self): contain lowercase alphanumeric characters only and no spaces or other formatting characters. """ - return 'DSGTools: Quality Assurance Tools (Manipulation Processes)' + return "DSGTools: Quality Assurance Tools (Manipulation Processes)" def tr(self, string): - return QCoreApplication.translate('HierarchicalSnapLayerOnLayerAndUpdateAlgorithm', string) + return QCoreApplication.translate( + "HierarchicalSnapLayerOnLayerAndUpdateAlgorithm", string + ) def createInstance(self): return HierarchicalSnapLayerOnLayerAndUpdateAlgorithm() -class ParameterSnapHierarchyType(QgsProcessingParameterType): +class ParameterSnapHierarchyType(QgsProcessingParameterType): def __init__(self): super().__init__() def create(self, name): - return ParameterSnapHierarchy(name) #mudar + return ParameterSnapHierarchy(name) # mudar def metadata(self): - return {'widget_wrapper': 'DsgTools.gui.ProcessingUI.snapHierarchyWrapper.SnapHierarchyWrapper'} #mudar + return { + "widget_wrapper": "DsgTools.gui.ProcessingUI.snapHierarchyWrapper.SnapHierarchyWrapper" + } # mudar def name(self): - return QCoreApplication.translate('Processing', 'Snap Hierarchy') + return QCoreApplication.translate("Processing", "Snap Hierarchy") def id(self): - return 'snap_hierarchy' + return "snap_hierarchy" def description(self): - return QCoreApplication.translate('Processing', 'An hierarchical snapping type. Used in the Hierarchical Snap Layer on Layer algorithm.') + return QCoreApplication.translate( + "Processing", + "An hierarchical snapping type. Used in the Hierarchical Snap Layer on Layer algorithm.", + ) -class ParameterSnapHierarchy(QgsProcessingParameterDefinition): - def __init__(self, name, description=''): +class ParameterSnapHierarchy(QgsProcessingParameterDefinition): + def __init__(self, name, description=""): super().__init__(name, description) def clone(self): @@ -308,7 +334,7 @@ def type(self): @staticmethod def typeName(): - return 'snap_hierarchy' + return "snap_hierarchy" def checkValueIsAcceptable(self, value, context=None): # if not isinstance(value, list): diff --git a/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/identifyAndFixInvalidGeometriesAlgorithm.py b/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/identifyAndFixInvalidGeometriesAlgorithm.py index 331009ccb..086a18f36 100644 --- a/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/identifyAndFixInvalidGeometriesAlgorithm.py +++ b/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/identifyAndFixInvalidGeometriesAlgorithm.py @@ -25,33 +25,36 @@ from .validationAlgorithm import ValidationAlgorithm import processing from PyQt5.QtCore import QCoreApplication -from qgis.core import (QgsProcessing, - QgsFeatureSink, - QgsProcessingAlgorithm, - QgsProcessingParameterFeatureSource, - QgsProcessingParameterFeatureSink, - QgsFeature, - QgsDataSourceUri, - QgsProcessingOutputVectorLayer, - QgsProcessingParameterVectorLayer, - QgsWkbTypes, - QgsProcessingParameterBoolean, - QgsProcessingParameterEnum, - QgsProcessingParameterNumber, - QgsProcessingParameterMultipleLayers, - QgsProcessingUtils, - QgsSpatialIndex, - QgsGeometry, - QgsProcessingMultiStepFeedback, - QgsProcessingException) +from qgis.core import ( + QgsProcessing, + QgsFeatureSink, + QgsProcessingAlgorithm, + QgsProcessingParameterFeatureSource, + QgsProcessingParameterFeatureSink, + QgsFeature, + QgsDataSourceUri, + QgsProcessingOutputVectorLayer, + QgsProcessingParameterVectorLayer, + QgsWkbTypes, + QgsProcessingParameterBoolean, + QgsProcessingParameterEnum, + QgsProcessingParameterNumber, + QgsProcessingParameterMultipleLayers, + QgsProcessingUtils, + QgsSpatialIndex, + QgsGeometry, + QgsProcessingMultiStepFeedback, + QgsProcessingException, +) + class IdentifyAndFixInvalidGeometriesAlgorithm(ValidationAlgorithm): - INPUT = 'INPUT' - SELECTED = 'SELECTED' - IGNORE_CLOSED = 'IGNORE_CLOSED' - TYPE = 'TYPE' - FLAGS = 'FLAGS' - OUTPUT = 'OUTPUT' + INPUT = "INPUT" + SELECTED = "SELECTED" + IGNORE_CLOSED = "IGNORE_CLOSED" + TYPE = "TYPE" + FLAGS = "FLAGS" + OUTPUT = "OUTPUT" def initAlgorithm(self, config): """ @@ -60,40 +63,38 @@ def initAlgorithm(self, config): self.addParameter( QgsProcessingParameterVectorLayer( self.INPUT, - self.tr('Input layer'), - [QgsProcessing.TypeVectorAnyGeometry] + self.tr("Input layer"), + [QgsProcessing.TypeVectorAnyGeometry], ) ) self.addParameter( QgsProcessingParameterBoolean( - self.SELECTED, - self.tr('Process only selected features') + self.SELECTED, self.tr("Process only selected features") ) ) self.addParameter( QgsProcessingParameterBoolean( self.IGNORE_CLOSED, - self.tr('Ignore flags on start point or end points of closed linestrings'), - defaultValue=False + self.tr( + "Ignore flags on start point or end points of closed linestrings" + ), + defaultValue=False, ) ) self.addParameter( QgsProcessingParameterBoolean( - self.TYPE, - self.tr('Fix input geometries'), - defaultValue=False + self.TYPE, self.tr("Fix input geometries"), defaultValue=False ) ) self.addParameter( QgsProcessingParameterFeatureSink( - self.FLAGS, - self.tr('{0} Flags').format(self.displayName()) + self.FLAGS, self.tr("{0} Flags").format(self.displayName()) ) ) self.addOutput( QgsProcessingOutputVectorLayer( self.OUTPUT, - self.tr('Original layer (has fixed geometries if fix mode is chosen)') + self.tr("Original layer (has fixed geometries if fix mode is chosen)"), ) ) @@ -106,7 +107,9 @@ def processAlgorithm(self, parameters, context, feedback): onlySelected = self.parameterAsBool(parameters, self.SELECTED, context) ignoreClosed = self.parameterAsBool(parameters, self.IGNORE_CLOSED, context) fixInput = self.parameterAsBool(parameters, self.TYPE, context) - self.prepareFlagSink(parameters, inputLyr, QgsWkbTypes.Point, context) + self.prepareFlagSink( + parameters, inputLyr, QgsWkbTypes.Point, context, addFeatId=True + ) multiStepFeedback = QgsProcessingMultiStepFeedback(2, feedback) currentStep = 0 @@ -117,19 +120,20 @@ def processAlgorithm(self, parameters, context, feedback): ignoreClosed=ignoreClosed, fixInput=fixInput, onlySelected=onlySelected, - feedback=multiStepFeedback + feedback=multiStepFeedback, ) currentStep += 1 multiStepFeedback.setProgressText(self.tr("Raising Flags")) multiStepFeedback.setCurrentStep(currentStep) itemSize = len(flagDict) - progressSize = 100/itemSize if itemSize else 0 + progressSize = 100 / itemSize if itemSize else 0 for current, (key, outDict) in enumerate(flagDict.items()): if multiStepFeedback.isCanceled(): break self.flagFeature( - flagGeom=outDict['geom'], - flagText=outDict['reason'] + flagGeom=outDict["geom"], + flagText=f"""Reason: {outDict["reason"]}""", + featid=outDict["featid"], ) multiStepFeedback.setProgress(current * progressSize) @@ -143,21 +147,21 @@ def name(self): lowercase alphanumeric characters only and no spaces or other formatting characters. """ - return 'identifyandfixinvalidgeometries' + return "identifyandfixinvalidgeometries" def displayName(self): """ Returns the translated algorithm name, which should be used for any user-visible display of the algorithm name. """ - return self.tr('Identify And Fix Invalid Geometries') + return self.tr("Identify And Fix Invalid Geometries") def group(self): """ Returns the name of the group this algorithm belongs to. This string should be localised. """ - return self.tr('Quality Assurance Tools (Identification Processes)') + return self.tr("Quality Assurance Tools (Identification Processes)") def groupId(self): """ @@ -167,10 +171,12 @@ def groupId(self): contain lowercase alphanumeric characters only and no spaces or other formatting characters. """ - return 'DSGTools: Quality Assurance Tools (Identification Processes)' + return "DSGTools: Quality Assurance Tools (Identification Processes)" def tr(self, string): - return QCoreApplication.translate('IdentifyAndFixInvalidGeometriesAlgorithm', string) + return QCoreApplication.translate( + "IdentifyAndFixInvalidGeometriesAlgorithm", string + ) def createInstance(self): - return IdentifyAndFixInvalidGeometriesAlgorithm() \ No newline at end of file + return IdentifyAndFixInvalidGeometriesAlgorithm() diff --git a/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/identifyAnglesInInvalidRangeAlgorithm.py b/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/identifyAnglesInInvalidRangeAlgorithm.py index 59cc0c4da..a4ef69bb0 100644 --- a/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/identifyAnglesInInvalidRangeAlgorithm.py +++ b/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/identifyAnglesInInvalidRangeAlgorithm.py @@ -23,25 +23,31 @@ from PyQt5.QtCore import QCoreApplication from DsgTools.core.GeometricTools.geometryHandler import GeometryHandler -from qgis.core import (QgsDataSourceUri, QgsFeature, QgsFeatureSink, - QgsProcessing, QgsProcessingAlgorithm, - QgsProcessingOutputVectorLayer, - QgsProcessingParameterBoolean, - QgsProcessingParameterFeatureSink, - QgsProcessingParameterFeatureSource, - QgsProcessingParameterNumber, - QgsProcessingParameterVectorLayer, QgsWkbTypes, - QgsProcessingException) +from qgis.core import ( + QgsDataSourceUri, + QgsFeature, + QgsFeatureSink, + QgsProcessing, + QgsProcessingAlgorithm, + QgsProcessingOutputVectorLayer, + QgsProcessingParameterBoolean, + QgsProcessingParameterFeatureSink, + QgsProcessingParameterFeatureSource, + QgsProcessingParameterNumber, + QgsProcessingParameterVectorLayer, + QgsWkbTypes, + QgsProcessingException, +) from .validationAlgorithm import ValidationAlgorithm class IdentifyAnglesInInvalidRangeAlgorithm(ValidationAlgorithm): - FLAGS = 'FLAGS' - INPUT = 'INPUT' - SELECTED = 'SELECTED' - MIN_ANGLE = 'MIN_ANGLE' - MAX_ANGLE = 'MAX_ANGLE' + FLAGS = "FLAGS" + INPUT = "INPUT" + SELECTED = "SELECTED" + MIN_ANGLE = "MIN_ANGLE" + MAX_ANGLE = "MAX_ANGLE" def initAlgorithm(self, config): """ @@ -50,40 +56,32 @@ def initAlgorithm(self, config): self.addParameter( QgsProcessingParameterVectorLayer( self.INPUT, - self.tr('Input layer'), - [QgsProcessing.TypeVectorLine, QgsProcessing.TypeVectorPolygon] + self.tr("Input layer"), + [QgsProcessing.TypeVectorLine, QgsProcessing.TypeVectorPolygon], ) ) self.addParameter( QgsProcessingParameterBoolean( - self.SELECTED, - self.tr('Process only selected features') + self.SELECTED, self.tr("Process only selected features") ) ) self.addParameter( QgsProcessingParameterNumber( - self.MIN_ANGLE, - self.tr('Minimum angle'), - minValue=0, - defaultValue=80 + self.MIN_ANGLE, self.tr("Minimum angle"), minValue=0, defaultValue=80 ) ) self.addParameter( QgsProcessingParameterNumber( - self.MAX_ANGLE, - self.tr('Maximum angle'), - minValue=0, - defaultValue=100 + self.MAX_ANGLE, self.tr("Maximum angle"), minValue=0, defaultValue=100 ) ) self.addParameter( QgsProcessingParameterFeatureSink( - self.FLAGS, - self.tr('{0} Flags').format(self.displayName()) + self.FLAGS, self.tr("{0} Flags").format(self.displayName()) ) ) @@ -94,26 +92,40 @@ def processAlgorithm(self, parameters, context, feedback): geometryHandler = GeometryHandler() inputLyr = self.parameterAsVectorLayer(parameters, self.INPUT, context) if inputLyr is None: - raise QgsProcessingException(self.invalidSourceError(parameters, self.INPUT)) + raise QgsProcessingException( + self.invalidSourceError(parameters, self.INPUT) + ) onlySelected = self.parameterAsBool(parameters, self.SELECTED, context) minAngle = self.parameterAsDouble(parameters, self.MIN_ANGLE, context) maxAngle = self.parameterAsDouble(parameters, self.MAX_ANGLE, context) if maxAngle <= minAngle: - raise QgsProcessingException(self.tr('Invalid Range')) + raise QgsProcessingException(self.tr("Invalid Range")) self.prepareFlagSink(parameters, inputLyr, QgsWkbTypes.Point, context) # Compute the number of steps to display within the progress bar and # get features from source - featureList, total = self.getIteratorAndFeatureCount(inputLyr, onlySelected = onlySelected) + featureList, total = self.getIteratorAndFeatureCount( + inputLyr, onlySelected=onlySelected + ) for current, feat in enumerate(featureList): # Stop the algorithm if cancel button has been clicked if feedback.isCanceled(): break - outOfBoundsList = geometryHandler.getOutOfBoundsAngle(feat, 0, invalidRange=[minAngle, maxAngle]) + outOfBoundsList = geometryHandler.getOutOfBoundsAngle( + feat, 0, invalidRange=[minAngle, maxAngle] + ) if outOfBoundsList: for item in outOfBoundsList: - flagText = self.tr('Feature from layer {0} with id={1} has angle of value {2} degrees, which is in invalid interval [{3},{4}].').format(inputLyr.name(), item['feat_id'], item['angle'], minAngle, maxAngle) - self.flagFeature(item['geom'], flagText) + flagText = self.tr( + "Feature from layer {0} with id={1} has angle of value {2} degrees, which is in invalid interval [{3},{4}]." + ).format( + inputLyr.name(), + item["feat_id"], + item["angle"], + minAngle, + maxAngle, + ) + self.flagFeature(item["geom"], flagText) # Update the progress bar feedback.setProgress(int(current * total)) @@ -127,21 +139,21 @@ def name(self): lowercase alphanumeric characters only and no spaces or other formatting characters. """ - return 'identifyanglesininvalidrangealgorithm' + return "identifyanglesininvalidrangealgorithm" def displayName(self): """ Returns the translated algorithm name, which should be used for any user-visible display of the algorithm name. """ - return self.tr('Identify Angles in Invalid Range') + return self.tr("Identify Angles in Invalid Range") def group(self): """ Returns the name of the group this algorithm belongs to. This string should be localised. """ - return self.tr('Quality Assurance Tools (Identification Processes)') + return self.tr("Quality Assurance Tools (Identification Processes)") def groupId(self): """ @@ -151,10 +163,12 @@ def groupId(self): contain lowercase alphanumeric characters only and no spaces or other formatting characters. """ - return 'DSGTools: Quality Assurance Tools (Identification Processes)' + return "DSGTools: Quality Assurance Tools (Identification Processes)" def tr(self, string): - return QCoreApplication.translate('IdentifyAnglesInInvalidRangeAlgorithm', string) + return QCoreApplication.translate( + "IdentifyAnglesInInvalidRangeAlgorithm", string + ) def createInstance(self): return IdentifyAnglesInInvalidRangeAlgorithm() diff --git a/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/identifyCountourStreamIntersectionAlgorithm.py b/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/identifyCountourStreamIntersectionAlgorithm.py index 6f17a8d54..c02b9a1c6 100644 --- a/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/identifyCountourStreamIntersectionAlgorithm.py +++ b/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/identifyCountourStreamIntersectionAlgorithm.py @@ -23,11 +23,18 @@ import os import processing -from qgis.core import (QgsFeature, QgsFeatureSink, QgsField, QgsFields, - QgsProcessing, QgsProcessingMultiStepFeedback, - QgsProcessingParameterBoolean, - QgsProcessingParameterFeatureSink, - QgsProcessingParameterVectorLayer, QgsWkbTypes) +from qgis.core import ( + QgsFeature, + QgsFeatureSink, + QgsField, + QgsFields, + QgsProcessing, + QgsProcessingMultiStepFeedback, + QgsProcessingParameterBoolean, + QgsProcessingParameterFeatureSink, + QgsProcessingParameterVectorLayer, + QgsWkbTypes, +) from qgis.PyQt.QtCore import QCoreApplication, QVariant from qgis.utils import iface @@ -36,75 +43,88 @@ class IdentifyCountourStreamIntersectionAlgorithm(ValidationAlgorithm): - INPUT_STREAM = 'INPUT_STREAM' - INPUT_CONTOUR_LINES = 'INPUT_CONTOUR_LINES' - OUTPUT = 'OUTPUT' - RUNNING_INSIDE_MODEL = 'RUNNING_INSIDE_MODEL' + INPUT_STREAM = "INPUT_STREAM" + INPUT_CONTOUR_LINES = "INPUT_CONTOUR_LINES" + OUTPUT = "OUTPUT" + RUNNING_INSIDE_MODEL = "RUNNING_INSIDE_MODEL" def initAlgorithm(self, config=None): self.addParameter( QgsProcessingParameterVectorLayer( - 'INPUT_STREAM', - self.tr('Drainage layer'), - types=[QgsProcessing.TypeVectorLine] + "INPUT_STREAM", + self.tr("Drainage layer"), + types=[QgsProcessing.TypeVectorLine], ) ) self.addParameter( QgsProcessingParameterVectorLayer( - 'INPUT_COUNTOUR_LINES', - self.tr('Contour levels layer'), - types=[QgsProcessing.TypeVectorLine] + "INPUT_COUNTOUR_LINES", + self.tr("Contour levels layer"), + types=[QgsProcessing.TypeVectorLine], ) ) - + self.addParameter( QgsProcessingParameterBoolean( self.RUNNING_INSIDE_MODEL, - self.tr('Process is running inside model'), + self.tr("Process is running inside model"), defaultValue=False, ) ) self.addParameter( - QgsProcessingParameterFeatureSink( - self.OUTPUT, - self.tr('Flags') - ) + QgsProcessingParameterFeatureSink(self.OUTPUT, self.tr("Flags")) ) def processAlgorithm(self, parameters, context, feedback): - streamLayerInput = self.parameterAsVectorLayer( parameters,'INPUT_STREAM', context ) - + streamLayerInput = self.parameterAsVectorLayer( + parameters, "INPUT_STREAM", context + ) + outputLinesSet, outputPointsSet = set(), set() - countourLayer = self.parameterAsVectorLayer( parameters,'INPUT_COUNTOUR_LINES', context ) - runningInsideModel = self.parameterAsBool(parameters, self.RUNNING_INSIDE_MODEL, context) + countourLayer = self.parameterAsVectorLayer( + parameters, "INPUT_COUNTOUR_LINES", context + ) + runningInsideModel = self.parameterAsBool( + parameters, self.RUNNING_INSIDE_MODEL, context + ) + + feedback.setProgressText(self.tr("Verifying inconsistency")) - feedback.setProgressText(self.tr('Verifying inconsistency')) - multiStepFeedback = QgsProcessingMultiStepFeedback(7, feedback) multiStepFeedback.setCurrentStep(0) - multiStepFeedback.pushInfo(self.tr('Building intermediary structures')) + multiStepFeedback.pushInfo(self.tr("Building intermediary structures")) - auxStreamLayerInput = self.runAddCount(streamLayerInput, feedback=multiStepFeedback) + auxStreamLayerInput = self.runAddCount( + streamLayerInput, feedback=multiStepFeedback + ) multiStepFeedback.setCurrentStep(1) self.runCreateSpatialIndex(auxStreamLayerInput, feedback=multiStepFeedback) - + multiStepFeedback.setCurrentStep(2) auxCountourLayer = self.runAddCount(countourLayer, feedback=multiStepFeedback) multiStepFeedback.setCurrentStep(3) self.runCreateSpatialIndex(auxCountourLayer, feedback=multiStepFeedback) multiStepFeedback.setCurrentStep(4) - idDict = {feat['AUTO']: feat for feat in auxCountourLayer.getFeatures()} - + idDict = {feat["AUTO"]: feat for feat in auxCountourLayer.getFeatures()} + multiStepFeedback.setCurrentStep(5) - multiStepFeedback.pushInfo(self.tr('Doing spatial join')) - spatialJoinOutput = self.runSpatialJoin(auxStreamLayerInput, auxCountourLayer, feedback=multiStepFeedback) - + multiStepFeedback.pushInfo(self.tr("Doing spatial join")) + spatialJoinOutput = self.runSpatialJoin( + auxStreamLayerInput, auxCountourLayer, feedback=multiStepFeedback + ) + multiStepFeedback.setCurrentStep(6) - multiStepFeedback.pushInfo(self.tr('Finding flags')) - - self.findProblems(multiStepFeedback, outputPointsSet, outputLinesSet, spatialJoinOutput, idDict) + multiStepFeedback.pushInfo(self.tr("Finding flags")) + + self.findProblems( + multiStepFeedback, + outputPointsSet, + outputLinesSet, + spatialJoinOutput, + idDict, + ) if outputPointsSet == set() and outputLinesSet == set(): if runningInsideModel: @@ -114,88 +134,91 @@ def processAlgorithm(self, parameters, context, feedback): context, streamLayerInput.fields(), QgsWkbTypes.Point, - streamLayerInput.sourceCrs() + streamLayerInput.sourceCrs(), ) else: - sink_id = self.tr('No flags found') - - return {self.OUTPUT: sink_id} - - if outputPointsSet != set() : - sink_id = self.outLayer(parameters, context, outputPointsSet, streamLayerInput, 1) + sink_id = self.tr("No flags found") + + return {self.OUTPUT: sink_id} + + if outputPointsSet != set(): + sink_id = self.outLayer( + parameters, context, outputPointsSet, streamLayerInput, QgsWkbTypes.Point + ) if outputLinesSet != set(): - sink_id = self.outLayer(parameters, context, outputLinesSet, streamLayerInput, 2) + sink_id = self.outLayer( + parameters, context, outputLinesSet, streamLayerInput, QgsWkbTypes.LineString + ) return {self.OUTPUT: sink_id} def runSpatialJoin(self, streamLayerInput, countourLayer, feedback): output = processing.run( - 'native:joinattributesbylocation', + "native:joinattributesbylocation", { - 'INPUT': streamLayerInput, - 'JOIN': countourLayer, - 'PREDICATE': [0], - 'JOIN_FIELDS': [], - 'METHOD': 0, - 'DISCARD_NONMATCHING': True, - 'PREFIX': '', - 'OUTPUT': 'TEMPORARY_OUTPUT' + "INPUT": streamLayerInput, + "JOIN": countourLayer, + "PREDICATE": [0], + "JOIN_FIELDS": [], + "METHOD": 0, + "DISCARD_NONMATCHING": True, + "PREFIX": "", + "OUTPUT": "TEMPORARY_OUTPUT", }, - feedback=feedback + feedback=feedback, ) - return output['OUTPUT'] - + return output["OUTPUT"] + def runAddCount(self, inputLyr, feedback): output = processing.run( "native:addautoincrementalfield", { - 'INPUT':inputLyr, - 'FIELD_NAME':'AUTO', - 'START':0, - 'GROUP_FIELDS':[], - 'SORT_EXPRESSION':'', - 'SORT_ASCENDING':False, - 'SORT_NULLS_FIRST':False, - 'OUTPUT':'TEMPORARY_OUTPUT' + "INPUT": inputLyr, + "FIELD_NAME": "AUTO", + "START": 0, + "GROUP_FIELDS": [], + "SORT_EXPRESSION": "", + "SORT_ASCENDING": False, + "SORT_NULLS_FIRST": False, + "OUTPUT": "TEMPORARY_OUTPUT", }, - feedback=feedback + feedback=feedback, ) - return output['OUTPUT'] + return output["OUTPUT"] def runCreateSpatialIndex(self, inputLyr, feedback): processing.run( - "native:createspatialindex", - {'INPUT':inputLyr}, - feedback=feedback + "native:createspatialindex", {"INPUT": inputLyr}, feedback=feedback ) def findProblems(self, feedback, outputPointsSet, outputLinesSet, inputLyr, idDict): total = 100.0 / inputLyr.featureCount() if inputLyr.featureCount() else 0 + def buildOutputs(riverFeat, feedback): if feedback.isCanceled(): return riverGeom = riverFeat.geometry() - if riverFeat['AUTO_2'] not in idDict: + if riverFeat["AUTO_2"] not in idDict: return - countourGeom = idDict[riverFeat['AUTO_2']].geometry() + countourGeom = idDict[riverFeat["AUTO_2"]].geometry() intersection = countourGeom.intersection(riverGeom) - if intersection.isEmpty() or intersection.wkbType() == 1: + if intersection.isEmpty() or intersection.wkbType() == QgsWkbTypes.Point: return - if intersection.wkbType() == 4: + if intersection.wkbType() == QgsWkbTypes.MultiPoint: outputPointsSet.add(intersection) - if intersection.wkbType() in [2, 5]: + if intersection.wkbType() in [QgsWkbTypes.LineString, QgsWkbTypes.MultiLineString]: outputLinesSet.add(intersection) - + buildOutputsLambda = lambda x: buildOutputs(x, feedback) - + pool = concurrent.futures.ThreadPoolExecutor(os.cpu_count()) futures = set() current_idx = 0 - + for feat in inputLyr.getFeatures(): if feedback is not None and feedback.isCanceled(): break futures.add(pool.submit(buildOutputsLambda, feat)) - + for x in concurrent.futures.as_completed(futures): if feedback is not None and feedback.isCanceled(): break @@ -204,7 +227,7 @@ def buildOutputs(riverFeat, feedback): def outLayer(self, parameters, context, geometry, streamLayer, geomtype): newFields = QgsFields() - newFields.append(QgsField('id', QVariant.Int)) + newFields.append(QgsField("id", QVariant.Int)) (sink, sink_id) = self.parameterAsSink( parameters, @@ -212,13 +235,13 @@ def outLayer(self, parameters, context, geometry, streamLayer, geomtype): context, newFields, geomtype, - streamLayer.sourceCrs() + streamLayer.sourceCrs(), ) for idcounter, geom in enumerate(geometry): newFeat = QgsFeature() newFeat.setGeometry(geom) newFeat.setFields(newFields) - newFeat['id'] = idcounter + newFeat["id"] = idcounter sink.addFeature(newFeat, QgsFeatureSink.FastInsert) return sink_id @@ -230,21 +253,23 @@ def name(self): lowercase alphanumeric characters only and no spaces or other formatting characters. """ - return 'identifycountourstreamintersection' + return "identifycountourstreamintersection" def displayName(self): """ Returns the translated algorithm name, which should be used for any user-visible display of the algorithm name. """ - return self.tr('Identifies intersections between contour lines and drainage lines') + return self.tr( + "Identifies intersections between contour lines and drainage lines" + ) def group(self): """ Returns the name of the group this algorithm belongs to. This string should be localised. """ - return self.tr('Quality Assurance Tools (Identification Processes)') + return self.tr("Quality Assurance Tools (Identification Processes)") def groupId(self): """ @@ -254,10 +279,12 @@ def groupId(self): contain lowercase alphanumeric characters only and no spaces or other formatting characters. """ - return 'DSGTools: Quality Assurance Tools (Identification Processes)' + return "DSGTools: Quality Assurance Tools (Identification Processes)" def tr(self, string): - return QCoreApplication.translate('IdentifyCountourStreamIntersectionAlgorithm', string) + return QCoreApplication.translate( + "IdentifyCountourStreamIntersectionAlgorithm", string + ) def createInstance(self): return IdentifyCountourStreamIntersectionAlgorithm() diff --git a/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/identifyDanglesAlgorithm.py b/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/identifyDanglesAlgorithm.py index 51e63a982..413f73753 100644 --- a/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/identifyDanglesAlgorithm.py +++ b/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/identifyDanglesAlgorithm.py @@ -29,29 +29,37 @@ from DsgTools.core.DSGToolsProcessingAlgs.algRunner import AlgRunner from DsgTools.core.GeometricTools.layerHandler import LayerHandler from PyQt5.QtCore import QCoreApplication -from qgis.core import (QgsFeatureRequest, QgsGeometry, QgsPointXY, - QgsProcessing, QgsProcessingFeatureSourceDefinition, - QgsProcessingFeedback, QgsProcessingMultiStepFeedback, - QgsProcessingParameterBoolean, - QgsProcessingParameterFeatureSink, - QgsProcessingParameterMultipleLayers, - QgsProcessingParameterNumber, - QgsProcessingParameterVectorLayer, QgsSpatialIndex, - QgsVectorLayer, QgsWkbTypes) +from qgis.core import ( + QgsFeatureRequest, + QgsGeometry, + QgsPointXY, + QgsProcessing, + QgsProcessingFeatureSourceDefinition, + QgsProcessingFeedback, + QgsProcessingMultiStepFeedback, + QgsProcessingParameterBoolean, + QgsProcessingParameterFeatureSink, + QgsProcessingParameterMultipleLayers, + QgsProcessingParameterNumber, + QgsProcessingParameterVectorLayer, + QgsSpatialIndex, + QgsVectorLayer, + QgsWkbTypes, +) from .validationAlgorithm import ValidationAlgorithm class IdentifyDanglesAlgorithm(ValidationAlgorithm): - INPUT = 'INPUT' - SELECTED = 'SELECTED' - TOLERANCE = 'TOLERANCE' - LINEFILTERLAYERS = 'LINEFILTERLAYERS' - POLYGONFILTERLAYERS = 'POLYGONFILTERLAYERS' - IGNORE_DANGLES_ON_UNSEGMENTED_LINES = 'IGNORE_DANGLES_ON_UNSEGMENTED_LINES' - INPUT_IS_BOUDARY_LAYER = 'INPUT_IS_BOUDARY_LAYER' - GEOGRAPHIC_BOUNDARY = 'GEOGRAPHIC_BOUNDARY' - FLAGS = 'FLAGS' + INPUT = "INPUT" + SELECTED = "SELECTED" + TOLERANCE = "TOLERANCE" + LINEFILTERLAYERS = "LINEFILTERLAYERS" + POLYGONFILTERLAYERS = "POLYGONFILTERLAYERS" + IGNORE_DANGLES_ON_UNSEGMENTED_LINES = "IGNORE_DANGLES_ON_UNSEGMENTED_LINES" + INPUT_IS_BOUDARY_LAYER = "INPUT_IS_BOUDARY_LAYER" + GEOGRAPHIC_BOUNDARY = "GEOGRAPHIC_BOUNDARY" + FLAGS = "FLAGS" def initAlgorithm(self, config): """ @@ -59,69 +67,67 @@ def initAlgorithm(self, config): """ self.addParameter( QgsProcessingParameterVectorLayer( - self.INPUT, - self.tr('Input layer'), - [QgsProcessing.TypeVectorLine] + self.INPUT, self.tr("Input layer"), [QgsProcessing.TypeVectorLine] ) ) self.addParameter( QgsProcessingParameterBoolean( - self.SELECTED, - self.tr('Process only selected features') + self.SELECTED, self.tr("Process only selected features") ) ) self.addParameter( QgsProcessingParameterBoolean( self.INPUT_IS_BOUDARY_LAYER, self.tr( - 'Input is a boundary layer (every line must be connected ' - 'to an element of either the input layer or the filters)' - ) + "Input is a boundary layer (every line must be connected " + "to an element of either the input layer or the filters)" + ), ) ) self.addParameter( QgsProcessingParameterNumber( self.TOLERANCE, - self.tr('Search radius'), + self.tr("Search radius"), minValue=0, type=QgsProcessingParameterNumber.Double, - defaultValue=0.0001 + defaultValue=0.0001, ) ) self.addParameter( QgsProcessingParameterMultipleLayers( self.LINEFILTERLAYERS, - self.tr('Linestring Filter Layers'), + self.tr("Linestring Filter Layers"), QgsProcessing.TypeVectorLine, - optional=True + optional=True, ) ) self.addParameter( QgsProcessingParameterMultipleLayers( self.POLYGONFILTERLAYERS, - self.tr('Polygon Filter Layers'), + self.tr("Polygon Filter Layers"), QgsProcessing.TypeVectorPolygon, - optional=True + optional=True, ) ) self.addParameter( QgsProcessingParameterBoolean( self.IGNORE_DANGLES_ON_UNSEGMENTED_LINES, - self.tr('Ignore dangle on unsegmented lines') + self.tr("Ignore dangle on unsegmented lines"), ) ) self.addParameter( QgsProcessingParameterVectorLayer( self.GEOGRAPHIC_BOUNDARY, - self.tr('Geographic Boundary (this layer only filters the output dangles)'), + self.tr( + "Geographic Boundary (this layer only filters the output dangles)" + ), [QgsProcessing.TypeVectorPolygon], - optional=True + optional=True, ) ) self.addParameter( QgsProcessingParameterFeatureSink( - self.FLAGS, - self.tr('{0} Flags').format(self.displayName()) + self.FLAGS, self.tr("{0} Flags").format(self.displayName()) ) ) @@ -136,17 +142,22 @@ def processAlgorithm(self, parameters, context, feedback): if inputLyr is None: return {self.FLAGS: self.flag_id} onlySelected = self.parameterAsBool(parameters, self.SELECTED, context) - searchRadius = self.parameterAsDouble( - parameters, self.TOLERANCE, context) + searchRadius = self.parameterAsDouble(parameters, self.TOLERANCE, context) lineFilterLyrList = self.parameterAsLayerList( - parameters, self.LINEFILTERLAYERS, context) + parameters, self.LINEFILTERLAYERS, context + ) polygonFilterLyrList = self.parameterAsLayerList( - parameters, self.POLYGONFILTERLAYERS, context) + parameters, self.POLYGONFILTERLAYERS, context + ) ignoreDanglesOnUnsegmentedLines = self.parameterAsBool( - parameters, self.IGNORE_DANGLES_ON_UNSEGMENTED_LINES, context) + parameters, self.IGNORE_DANGLES_ON_UNSEGMENTED_LINES, context + ) inputIsBoundaryLayer = self.parameterAsBool( - parameters, self.INPUT_IS_BOUDARY_LAYER, context) - geographicBoundsLyr = self.parameterAsVectorLayer(parameters, self.GEOGRAPHIC_BOUNDARY, context) + parameters, self.INPUT_IS_BOUDARY_LAYER, context + ) + geographicBoundsLyr = self.parameterAsVectorLayer( + parameters, self.GEOGRAPHIC_BOUNDARY, context + ) # cacheInput = self.parameterAsBool(parameters, self.CACHE_INPUT, context) # Compute the number of steps to display within the progress bar and @@ -155,53 +166,49 @@ def processAlgorithm(self, parameters, context, feedback): feedbackTotal += 1 if lineFilterLyrList or polygonFilterLyrList else 0 feedbackTotal += 1 if not inputIsBoundaryLayer else 0 # feedbackTotal += 2 if cacheInput else 0 - multiStepFeedback = QgsProcessingMultiStepFeedback( - feedbackTotal, feedback) + multiStepFeedback = QgsProcessingMultiStepFeedback(feedbackTotal, feedback) currentStep = 0 multiStepFeedback.setCurrentStep(currentStep) - multiStepFeedback.pushInfo(self.tr('Building local cache...')) + multiStepFeedback.pushInfo(self.tr("Building local cache...")) inputLyr = algRunner.runAddAutoIncrementalField( - inputLyr=inputLyr if not onlySelected else QgsProcessingFeatureSourceDefinition( - inputLyr.id(), True - ), + inputLyr=inputLyr + if not onlySelected + else QgsProcessingFeatureSourceDefinition(inputLyr.id(), True), context=context, feedback=multiStepFeedback, - fieldName='AUTO' + fieldName="AUTO", ) onlySelected = False currentStep += 1 multiStepFeedback.setCurrentStep(currentStep) algRunner.runCreateSpatialIndex( - inputLyr=inputLyr, - context=context, - feedback=multiStepFeedback + inputLyr=inputLyr, context=context, feedback=multiStepFeedback ) currentStep += 1 multiStepFeedback.setCurrentStep(currentStep) - multiStepFeedback.pushInfo(self.tr('Building search structure...')) + multiStepFeedback.pushInfo(self.tr("Building search structure...")) endVerticesDict = self.buildInitialAndEndPointDict( inputLyr, algRunner, context=context, geographicBoundsLyr=geographicBoundsLyr, - feedback=multiStepFeedback + feedback=multiStepFeedback, ) # search for dangles candidates currentStep += 1 multiStepFeedback.setCurrentStep(currentStep) - multiStepFeedback.pushInfo(self.tr('Looking for dangle candidates...')) - pointSet = self.searchDanglesOnPointDict( - endVerticesDict, multiStepFeedback) + multiStepFeedback.pushInfo(self.tr("Looking for dangle candidates...")) + pointSet = self.searchDanglesOnPointDict(endVerticesDict, multiStepFeedback) # build filter layer filterLayer = self.buildFilterLayer( lineFilterLyrList, polygonFilterLyrList, context, multiStepFeedback, - onlySelected=onlySelected + onlySelected=onlySelected, ) # filter pointList with filterLayer dangleSet = set() @@ -211,7 +218,8 @@ def processAlgorithm(self, parameters, context, feedback): currentStep += 1 multiStepFeedback.setCurrentStep(currentStep) multiStepFeedback.pushInfo( - self.tr('Filtering dangles candidates with filter layer features...')) + self.tr("Filtering dangles candidates with filter layer features...") + ) danglesWithFilterLayersSet, relatedDict = self.getDanglesWithFilterLayers( pointSet, filterLayer, @@ -224,7 +232,8 @@ def processAlgorithm(self, parameters, context, feedback): currentStep += 1 multiStepFeedback.setCurrentStep(currentStep) multiStepFeedback.pushInfo( - self.tr('Filtering dangles candidates with input layer features...')) + self.tr("Filtering dangles candidates with input layer features...") + ) danglesOnInputLayerSet = self.getDanglesOnInputLayerFeatures( pointSet=pointSet, inputLyr=inputLyr, @@ -238,22 +247,24 @@ def processAlgorithm(self, parameters, context, feedback): # build flag list with filtered points currentStep += 1 multiStepFeedback.setCurrentStep(currentStep) - multiStepFeedback.pushInfo(self.tr('Raising flags...')) + multiStepFeedback.pushInfo(self.tr("Raising flags...")) if dangleSet: # currentValue = feedback.progress() - currentTotal = 100/len(dangleSet) + currentTotal = 100 / len(dangleSet) for current, point in enumerate(dangleSet): if multiStepFeedback.isCanceled(): break self.flagFeature( QgsGeometry.fromPointXY(point), - self.tr('Dangle on {0}').format(inputLyr.name()) + self.tr("Dangle on {0}").format(inputLyr.name()), ) - multiStepFeedback.setProgress(current*currentTotal) + multiStepFeedback.setProgress(current * currentTotal) # feedback.setProgress(100) return {self.FLAGS: self.flag_id} - def buildInitialAndEndPointDict(self, lyr, algRunner, context, feedback, geographicBoundsLyr=None): + def buildInitialAndEndPointDict( + self, lyr, algRunner, context, feedback, geographicBoundsLyr=None + ): pointDict = defaultdict(set) nSteps = 5 if geographicBoundsLyr is not None else 3 currentStep = 0 @@ -261,24 +272,17 @@ def buildInitialAndEndPointDict(self, lyr, algRunner, context, feedback, geograp multiStepFeedback.setCurrentStep(currentStep) # this process of extracting the boundary is intentionally without the feedback # to avoid the excessive amount of error messages that are generated due to closed lines. - boundaryLyr = algRunner.runBoundary( - inputLayer=lyr, - context=context - ) + boundaryLyr = algRunner.runBoundary(inputLayer=lyr, context=context) currentStep += 1 multiStepFeedback.setCurrentStep(currentStep) boundaryLyr = algRunner.runMultipartToSingleParts( - inputLayer=boundaryLyr, - context=context, - feedback=multiStepFeedback + inputLayer=boundaryLyr, context=context, feedback=multiStepFeedback ) currentStep += 1 multiStepFeedback.setCurrentStep(currentStep) if geographicBoundsLyr is not None: algRunner.runCreateSpatialIndex( - inputLyr=boundaryLyr, - context=context, - feedback=multiStepFeedback + inputLyr=boundaryLyr, context=context, feedback=multiStepFeedback ) currentStep += 1 multiStepFeedback.setCurrentStep(currentStep) @@ -286,7 +290,7 @@ def buildInitialAndEndPointDict(self, lyr, algRunner, context, feedback, geograp inputLyr=boundaryLyr, intersectLyr=geographicBoundsLyr, context=context, - feedback=multiStepFeedback + feedback=multiStepFeedback, ) currentStep += 1 @@ -294,7 +298,7 @@ def buildInitialAndEndPointDict(self, lyr, algRunner, context, feedback, geograp featCount = boundaryLyr.featureCount() if featCount == 0: return pointDict - step = 100/featCount + step = 100 / featCount for current, feat in enumerate(boundaryLyr.getFeatures()): if multiStepFeedback.isCanceled(): break @@ -302,14 +306,15 @@ def buildInitialAndEndPointDict(self, lyr, algRunner, context, feedback, geograp if geom is None or not geom.isGeosValid(): continue id = feat["AUTO"] - pointList = geom.asMultiPoint() if geom.isMultipart() else [ - geom.asPoint()] + pointList = geom.asMultiPoint() if geom.isMultipart() else [geom.asPoint()] for point in pointList: pointDict[point].add(id) multiStepFeedback.setProgress(current * step) return pointDict - def searchDanglesOnPointDict(self, endVerticesDict: Dict, feedback: QgsProcessingFeedback) -> set: + def searchDanglesOnPointDict( + self, endVerticesDict: Dict, feedback: QgsProcessingFeedback + ) -> set: """ Counts the number of points on each endVerticesDict's key and returns a set of QgsPoint built from key candidate. """ @@ -317,7 +322,7 @@ def searchDanglesOnPointDict(self, endVerticesDict: Dict, feedback: QgsProcessin nVertexes = len(endVerticesDict) if nVertexes == 0: return pointSet - localTotal = 100/nVertexes if nVertexes else 0 + localTotal = 100 / nVertexes if nVertexes else 0 # actual search for dangles for current, point in enumerate(endVerticesDict): if feedback.isCanceled(): @@ -325,16 +330,18 @@ def searchDanglesOnPointDict(self, endVerticesDict: Dict, feedback: QgsProcessin # this means we only have one occurrence of point, therefore it is a dangle if len(endVerticesDict[point]) <= 1: pointSet.add(point) - feedback.setProgress(localTotal*current) + feedback.setProgress(localTotal * current) return pointSet - def buildFilterLayer(self, lineLyrList, polygonLyrList, context, feedback, onlySelected=False): + def buildFilterLayer( + self, lineLyrList, polygonLyrList, context, feedback, onlySelected=False + ): """ Buils one layer of filter lines. Build unified layer is not used because we do not care for attributes here, only geometry. refLyr elements are also added. """ - if not(lineLyrList + polygonLyrList): + if not (lineLyrList + polygonLyrList): return [] lineLyrs = lineLyrList for polygonLyr in polygonLyrList: @@ -344,31 +351,31 @@ def buildFilterLayer(self, lineLyrList, polygonLyrList, context, feedback, onlyS if not lineLyrs: return None return self.layerHandler.createAndPopulateUnifiedVectorLayer( - lineLyrs, - QgsWkbTypes.MultiLineString, - onlySelected=onlySelected + lineLyrs, QgsWkbTypes.MultiLineString, onlySelected=onlySelected ) def makeBoundaries(self, lyr, context, feedback): - parameters = { - 'INPUT': lyr, - 'OUTPUT': 'memory:' - } + parameters = {"INPUT": lyr, "OUTPUT": "memory:"} output = processing.run("native:boundary", parameters, context=context) - return output['OUTPUT'] + return output["OUTPUT"] def getDanglesOnInputLayerFeatures( - self, pointSet: set, inputLyr: QgsVectorLayer, searchRadius: float, ignoreDanglesOnUnsegmentedLines: bool = False,\ - inputIsBoundaryLayer: bool = False, relatedDict: dict = None, feedback: QgsProcessingMultiStepFeedback = None + self, + pointSet: set, + inputLyr: QgsVectorLayer, + searchRadius: float, + ignoreDanglesOnUnsegmentedLines: bool = False, + inputIsBoundaryLayer: bool = False, + relatedDict: dict = None, + feedback: QgsProcessingMultiStepFeedback = None, ) -> set: inputLayerDangles = set() nPoints = len(pointSet) relatedDict = dict() if relatedDict is None else relatedDict if nPoints == 0: return inputLayerDangles - localTotal = 100/nPoints - pool = concurrent.futures.ThreadPoolExecutor( - max_workers=os.cpu_count()-1) + localTotal = 100 / nPoints + pool = concurrent.futures.ThreadPoolExecutor(max_workers=os.cpu_count() - 1) futures = set() def evaluate(point) -> Union[QgsPointXY, None]: @@ -378,8 +385,11 @@ def evaluate(point) -> Union[QgsPointXY, None]: # search radius to narrow down candidates request = QgsFeatureRequest().setFilterRect(bufferBB) bufferCount, intersectCount = 0, 0 - point_relationship_lambda = lambda x: qgisPoint.intersects(x) or qgisPoint.distance(x) < 1e-8 \ - if ignoreDanglesOnUnsegmentedLines else qgisPoint.touches(x) + point_relationship_lambda = ( + lambda x: qgisPoint.intersects(x) or qgisPoint.distance(x) < 1e-8 + if ignoreDanglesOnUnsegmentedLines + else qgisPoint.touches(x) + ) for feat in inputLyr.getFeatures(request): geom = feat.geometry() if feedback is not None and feedback.isCanceled(): @@ -393,13 +403,21 @@ def evaluate(point) -> Union[QgsPointXY, None]: if inputIsBoundaryLayer and intersectCount == 1 and bufferCount == 1: if relatedDict == dict(): return point - if point in relatedDict and relatedDict[point]["candidateCount"] == relatedDict[point]["bufferCount"] and relatedDict[point]["candidateCount"] > 0: + if ( + point in relatedDict + and relatedDict[point]["candidateCount"] + == relatedDict[point]["bufferCount"] + and relatedDict[point]["candidateCount"] > 0 + ): return None return point return point if bufferCount != intersectCount else None - multiStepFeedback = QgsProcessingMultiStepFeedback( - 2, feedback) if feedback is not None else None + multiStepFeedback = ( + QgsProcessingMultiStepFeedback(2, feedback) + if feedback is not None + else None + ) multiStepFeedback.setCurrentStep(0) for current, point in enumerate(pointSet): if multiStepFeedback is not None and multiStepFeedback.isCanceled(): @@ -419,12 +437,16 @@ def evaluate(point) -> Union[QgsPointXY, None]: return inputLayerDangles def getDanglesWithFilterLayers( - self, pointSet: set, filterLayer: QgsVectorLayer, searchRadius: float,\ - feedback: QgsProcessingMultiStepFeedback, ignoreNotSplit: bool = False - ) -> Tuple[set, Dict[QgsPointXY, dict]]: + self, + pointSet: set, + filterLayer: QgsVectorLayer, + searchRadius: float, + feedback: QgsProcessingMultiStepFeedback, + ignoreNotSplit: bool = False, + ) -> Tuple[set, Dict[QgsPointXY, dict]]: """ Builds buffer areas from each point and evaluates the intersecting lines. - If the number of candidates that intersect the buffer is different than the + If the number of candidates that intersect the buffer is different than the number of intersections of the point with the neighbors, it is a dangle. Returns the set containing the dangles. @@ -434,11 +456,12 @@ def getDanglesWithFilterLayers( relatedDict = dict() if nPoints == 0: return danglesWithFilterLayers, relatedDict - localTotal = 100/nPoints + localTotal = 100 / nPoints multiStepFeedback = QgsProcessingMultiStepFeedback(4, feedback) multiStepFeedback.setCurrentStep(0) spatialIdx, allFeatureDict = self.buildSpatialIndexAndIdDict( - filterLayer, feedback=multiStepFeedback) + filterLayer, feedback=multiStepFeedback + ) multiStepFeedback.setCurrentStep(1) def evaluate(point: QgsPointXY) -> dict: @@ -454,19 +477,18 @@ def evaluate(point: QgsPointXY) -> dict: return None if buffer.intersects(candidateGeom): bufferCount += 1 - if (qgisPoint.intersects(candidateGeom)): + if qgisPoint.intersects(candidateGeom): candidateCount += 1 return point, {"candidateCount": candidateCount, "bufferCount": bufferCount} futures = set() - pool = concurrent.futures.ThreadPoolExecutor( - max_workers=os.cpu_count()-1) + pool = concurrent.futures.ThreadPoolExecutor(max_workers=os.cpu_count() - 1) multiStepFeedback.setCurrentStep(2) for current, point in enumerate(pointSet): if multiStepFeedback.isCanceled(): break futures.add(pool.submit(evaluate, point)) - multiStepFeedback.setProgress(localTotal*current) + multiStepFeedback.setProgress(localTotal * current) multiStepFeedback.setCurrentStep(3) for current, future in enumerate(concurrent.futures.as_completed(futures)): if multiStepFeedback.isCanceled(): @@ -475,7 +497,7 @@ def evaluate(point: QgsPointXY) -> dict: relatedDict[dangle] = dangleDict if dangleDict["candidateCount"] != dangleDict["bufferCount"]: danglesWithFilterLayers.add(dangle) - multiStepFeedback.setProgress(localTotal*current) + multiStepFeedback.setProgress(localTotal * current) return danglesWithFilterLayers, relatedDict @@ -500,21 +522,21 @@ def name(self): lowercase alphanumeric characters only and no spaces or other formatting characters. """ - return 'identifydangles' + return "identifydangles" def displayName(self): """ Returns the translated algorithm name, which should be used for any user-visible display of the algorithm name. """ - return self.tr('Identify Dangles') + return self.tr("Identify Dangles") def group(self): """ Returns the name of the group this algorithm belongs to. This string should be localised. """ - return self.tr('Quality Assurance Tools (Identification Processes)') + return self.tr("Quality Assurance Tools (Identification Processes)") def groupId(self): """ @@ -524,10 +546,10 @@ def groupId(self): contain lowercase alphanumeric characters only and no spaces or other formatting characters. """ - return 'DSGTools: Quality Assurance Tools (Identification Processes)' + return "DSGTools: Quality Assurance Tools (Identification Processes)" def tr(self, string): - return QCoreApplication.translate('IdentifyDanglesAlgorithm', string) + return QCoreApplication.translate("IdentifyDanglesAlgorithm", string) def createInstance(self): return IdentifyDanglesAlgorithm() diff --git a/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/identifyDrainageAngleIssues.py b/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/identifyDrainageAngleIssues.py index 6213ce8ab..9a3559ac3 100644 --- a/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/identifyDrainageAngleIssues.py +++ b/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/identifyDrainageAngleIssues.py @@ -25,50 +25,55 @@ import os from PyQt5.QtCore import QCoreApplication, QVariant -from qgis.core import (QgsFeature, QgsFeatureRequest, QgsField, QgsFields, - QgsGeometry, QgsGeometryUtils, QgsPoint, QgsPointXY, - QgsProcessing, QgsProcessingParameterFeatureSink, - QgsProcessingParameterFeatureSource, - QgsProcessingParameterNumber, QgsProject, QgsWkbTypes, - QgsProcessingMultiStepFeedback) +from qgis.core import ( + QgsFeature, + QgsFeatureRequest, + QgsField, + QgsFields, + QgsGeometry, + QgsGeometryUtils, + QgsPoint, + QgsPointXY, + QgsProcessing, + QgsProcessingParameterFeatureSink, + QgsProcessingParameterFeatureSource, + QgsProcessingParameterNumber, + QgsProject, + QgsWkbTypes, + QgsProcessingMultiStepFeedback, +) from .validationAlgorithm import ValidationAlgorithm from DsgTools.core.GeometricTools.geometryHandler import GeometryHandler class IdentifyDrainageAngleIssues(ValidationAlgorithm): - FLAGS = 'FLAGS' - INPUT = 'INPUT' + FLAGS = "FLAGS" + INPUT = "INPUT" def initAlgorithm(self, config=None): self.addParameter( QgsProcessingParameterFeatureSource( self.INPUT, - self.tr('Input'), + self.tr("Input"), [ QgsProcessing.TypeVectorLine, - ] + ], ) ) self.addParameter( QgsProcessingParameterFeatureSink( - self.FLAGS, - self.tr('{0} Flags').format(self.displayName()) + self.FLAGS, self.tr("{0} Flags").format(self.displayName()) ) ) def processAlgorithm(self, parameters, context, feedback): - lines = self.parameterAsVectorLayer( - parameters, - 'INPUT', - context - ) + lines = self.parameterAsVectorLayer(parameters, "INPUT", context) self.prepareFlagSink(parameters, lines, QgsWkbTypes.Point, context) # Dictionary that stores azimuths entering and exiting the point pointInAndOutDictionary = {} - # Iterate over lines setting the dictionary content: lineCount = lines.featureCount() if lineCount == 0: @@ -76,7 +81,7 @@ def processAlgorithm(self, parameters, context, feedback): multiStepFeedback = QgsProcessingMultiStepFeedback(2, feedback) multiStepFeedback.setCurrentStep(0) multiStepFeedback.setProgressText(self.tr("Evaluating line structure...")) - stepSize = 100/lineCount + stepSize = 100 / lineCount for current, line in enumerate(lines.getFeatures()): if multiStepFeedback.isCanceled(): @@ -93,27 +98,38 @@ def processAlgorithm(self, parameters, context, feedback): incoming_azimuth = GeometryHandler.calcAzimuth(semilast_vertex, last_vertex) if first_vertex.asWkt() not in pointInAndOutDictionary: - pointInAndOutDictionary[first_vertex.asWkt()] = { "incoming": [], "outgoing": []} + pointInAndOutDictionary[first_vertex.asWkt()] = { + "incoming": [], + "outgoing": [], + } if last_vertex.asWkt() not in pointInAndOutDictionary: - pointInAndOutDictionary[last_vertex.asWkt()] = { "incoming": [], "outgoing": []} - - pointInAndOutDictionary[first_vertex.asWkt()]["outgoing"].append(outgoing_azimuth) - pointInAndOutDictionary[last_vertex.asWkt()]["incoming"].append(incoming_azimuth) + pointInAndOutDictionary[last_vertex.asWkt()] = { + "incoming": [], + "outgoing": [], + } + + pointInAndOutDictionary[first_vertex.asWkt()]["outgoing"].append( + outgoing_azimuth + ) + pointInAndOutDictionary[last_vertex.asWkt()]["incoming"].append( + incoming_azimuth + ) multiStepFeedback.setProgress(current * stepSize) - + multiStepFeedback.setCurrentStep(1) multiStepFeedback.setProgressText(self.tr("Raising flags...")) - stepSize = 100/len(pointInAndOutDictionary) + stepSize = 100 / len(pointInAndOutDictionary) # Iterate over dictionary: - for current, (pointStr, inAndOutLists) in enumerate(pointInAndOutDictionary.items()): + for current, (pointStr, inAndOutLists) in enumerate( + pointInAndOutDictionary.items() + ): if multiStepFeedback.isCanceled(): break errorMsg = self.errorWhenCheckingInAndOut(inAndOutLists) - if errorMsg != '': + if errorMsg != "": self.flagFeature( - flagGeom= QgsGeometry.fromWkt(pointStr), - flagText=self.tr(errorMsg) + flagGeom=QgsGeometry.fromWkt(pointStr), flagText=self.tr(errorMsg) ) multiStepFeedback.setProgress(current * stepSize) @@ -126,10 +142,10 @@ def errorWhenCheckingInAndOut(self, inAndOutLists): for azi_in in azimuths_in: for azi_out in azimuths_out: directionChange = self.deltaBetweenAzimuths(azi_in, azi_out) - if(directionChange > 90): - return 'There is an unexpected sharp turn here.' + if directionChange > 90: + return "There is an unexpected sharp turn here." - return '' + return "" def name(self): """ @@ -139,21 +155,21 @@ def name(self): lowercase alphanumeric characters only and no spaces or other formatting characters. """ - return 'identifydrainageangleissues' + return "identifydrainageangleissues" def displayName(self): """ Returns the translated algorithm name, which should be used for any user-visible display of the algorithm name. """ - return self.tr('Identify Drainage Angle Issues') + return self.tr("Identify Drainage Angle Issues") def group(self): """ Returns the name of the group this algorithm belongs to. This string should be localised. """ - return self.tr('Quality Assurance Tools (Identification Processes)') + return self.tr("Quality Assurance Tools (Identification Processes)") def groupId(self): """ @@ -163,10 +179,10 @@ def groupId(self): contain lowercase alphanumeric characters only and no spaces or other formatting characters. """ - return self.tr('DSGTools: Quality Assurance Tools (Identification Processes)') + return self.tr("DSGTools: Quality Assurance Tools (Identification Processes)") def tr(self, string): - return QCoreApplication.translate('IdentifyDrainageAngleIssues', string) + return QCoreApplication.translate("IdentifyDrainageAngleIssues", string) def createInstance(self): return IdentifyDrainageAngleIssues() @@ -176,9 +192,9 @@ def deltaBetweenAzimuths(az1: float, az2: float) -> float: delta_1 = az1 - az2 delta_2 = az2 - az1 - if(delta_1 < 0): + if delta_1 < 0: delta_1 += 360 - if(delta_2 < 0): + if delta_2 < 0: delta_2 += 360 return min(delta_1, delta_2) diff --git a/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/identifyDrainageFlowIssues.py b/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/identifyDrainageFlowIssues.py index 3c2743408..39e934df0 100644 --- a/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/identifyDrainageFlowIssues.py +++ b/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/identifyDrainageFlowIssues.py @@ -25,49 +25,54 @@ import os from PyQt5.QtCore import QCoreApplication, QVariant -from qgis.core import (QgsFeature, QgsFeatureRequest, QgsField, QgsFields, - QgsGeometry, QgsGeometryUtils, QgsPoint, QgsPointXY, - QgsProcessing, QgsProcessingParameterFeatureSink, - QgsProcessingParameterFeatureSource, - QgsProcessingParameterNumber, QgsProject, QgsWkbTypes, - QgsProcessingMultiStepFeedback) +from qgis.core import ( + QgsFeature, + QgsFeatureRequest, + QgsField, + QgsFields, + QgsGeometry, + QgsGeometryUtils, + QgsPoint, + QgsPointXY, + QgsProcessing, + QgsProcessingParameterFeatureSink, + QgsProcessingParameterFeatureSource, + QgsProcessingParameterNumber, + QgsProject, + QgsWkbTypes, + QgsProcessingMultiStepFeedback, +) from .validationAlgorithm import ValidationAlgorithm class IdentifyDrainageFlowIssues(ValidationAlgorithm): - FLAGS = 'FLAGS' - INPUT = 'INPUT' + FLAGS = "FLAGS" + INPUT = "INPUT" def initAlgorithm(self, config=None): self.addParameter( QgsProcessingParameterFeatureSource( self.INPUT, - self.tr('Input'), + self.tr("Input"), [ QgsProcessing.TypeVectorLine, - ] + ], ) ) self.addParameter( QgsProcessingParameterFeatureSink( - self.FLAGS, - self.tr('{0} Flags').format(self.displayName()) + self.FLAGS, self.tr("{0} Flags").format(self.displayName()) ) ) def processAlgorithm(self, parameters, context, feedback): - lines = self.parameterAsVectorLayer( - parameters, - 'INPUT', - context - ) + lines = self.parameterAsVectorLayer(parameters, "INPUT", context) self.prepareFlagSink(parameters, lines, QgsWkbTypes.Point, context) # Dictionary that indicates how many lines enter and how many lines exit a given point: pointInAndOutDictionary = {} - # Iterate over lines setting the dictionary counters: lineCount = lines.featureCount() if lineCount == 0: @@ -75,7 +80,7 @@ def processAlgorithm(self, parameters, context, feedback): multiStepFeedback = QgsProcessingMultiStepFeedback(2, feedback) multiStepFeedback.setCurrentStep(0) multiStepFeedback.setProgressText(self.tr("Evaluating line structure...")) - stepSize = 100/lineCount + stepSize = 100 / lineCount for current, line in enumerate(lines.getFeatures()): if multiStepFeedback.isCanceled(): @@ -87,27 +92,34 @@ def processAlgorithm(self, parameters, context, feedback): last_vertex = geom[-1] if first_vertex.asWkt() not in pointInAndOutDictionary: - pointInAndOutDictionary[first_vertex.asWkt()] = { "incoming": 0, "outgoing": 0} + pointInAndOutDictionary[first_vertex.asWkt()] = { + "incoming": 0, + "outgoing": 0, + } if last_vertex.asWkt() not in pointInAndOutDictionary: - pointInAndOutDictionary[last_vertex.asWkt()] = { "incoming": 0, "outgoing": 0} - + pointInAndOutDictionary[last_vertex.asWkt()] = { + "incoming": 0, + "outgoing": 0, + } + pointInAndOutDictionary[first_vertex.asWkt()]["outgoing"] += 1 pointInAndOutDictionary[last_vertex.asWkt()]["incoming"] += 1 multiStepFeedback.setProgress(current * stepSize) - + multiStepFeedback.setCurrentStep(1) multiStepFeedback.setProgressText(self.tr("Raising flags...")) - stepSize = 100/len(pointInAndOutDictionary) + stepSize = 100 / len(pointInAndOutDictionary) # Iterate over dictionary: - for current, (pointStr, inAndOutCounters) in enumerate(pointInAndOutDictionary.items()): + for current, (pointStr, inAndOutCounters) in enumerate( + pointInAndOutDictionary.items() + ): if multiStepFeedback.isCanceled(): break errorMsg = self.errorWhenCheckingInAndOut(inAndOutCounters) - if errorMsg != '': + if errorMsg != "": self.flagFeature( - flagGeom= QgsGeometry.fromWkt(pointStr), - flagText=self.tr(errorMsg) + flagGeom=QgsGeometry.fromWkt(pointStr), flagText=self.tr(errorMsg) ) multiStepFeedback.setProgress(current * stepSize) @@ -119,17 +131,19 @@ def errorWhenCheckingInAndOut(self, inAndOutCounters): total = incoming + outgoing if total == 1: - return '' + return "" if total >= 4: - return '4 or more lines conected to this point.' - - if (incoming == 0): - return 'There are lines coming from this point, but not lines going in.' + return "4 or more lines conected to this point." + + if incoming == 0: + return "There are lines coming from this point, but not lines going in." - if (outgoing == 0): - return 'There are lines going into this point, but not lines coming from it.' + if outgoing == 0: + return ( + "There are lines going into this point, but not lines coming from it." + ) - return '' + return "" def name(self): """ @@ -139,21 +153,21 @@ def name(self): lowercase alphanumeric characters only and no spaces or other formatting characters. """ - return 'identifydrainageflowissues' + return "identifydrainageflowissues" def displayName(self): """ Returns the translated algorithm name, which should be used for any user-visible display of the algorithm name. """ - return self.tr('Identify Drainage Flow Issues') + return self.tr("Identify Drainage Flow Issues") def group(self): """ Returns the name of the group this algorithm belongs to. This string should be localised. """ - return self.tr('Quality Assurance Tools (Identification Processes)') + return self.tr("Quality Assurance Tools (Identification Processes)") def groupId(self): """ @@ -163,10 +177,10 @@ def groupId(self): contain lowercase alphanumeric characters only and no spaces or other formatting characters. """ - return self.tr('DSGTools: Quality Assurance Tools (Identification Processes)') + return self.tr("DSGTools: Quality Assurance Tools (Identification Processes)") def tr(self, string): - return QCoreApplication.translate('IdentifyDrainageFlowIssues', string) + return QCoreApplication.translate("IdentifyDrainageFlowIssues", string) def createInstance(self): return IdentifyDrainageFlowIssues() diff --git a/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/identifyDrainageFlowIssuesWithOtherHydrographicClassesAlgorithm.py b/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/identifyDrainageFlowIssuesWithOtherHydrographicClassesAlgorithm.py index 5dd9c61c2..fb2c39fbd 100644 --- a/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/identifyDrainageFlowIssuesWithOtherHydrographicClassesAlgorithm.py +++ b/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/identifyDrainageFlowIssuesWithOtherHydrographicClassesAlgorithm.py @@ -29,20 +29,30 @@ from itertools import product, chain from DsgTools.core.GeometricTools.layerHandler import LayerHandler from DsgTools.core.GeometricTools.networkHandler import NetworkHandler -from qgis.core import (QgsDataSourceUri, QgsFeature, QgsFeatureSink, - QgsGeometry, QgsProcessing, QgsProcessingAlgorithm, - QgsProcessingException, QgsProcessingMultiStepFeedback, - QgsProcessingOutputVectorLayer, - QgsProcessingParameterBoolean, - QgsProcessingParameterDistance, - QgsProcessingParameterEnum, - QgsProcessingParameterFeatureSink, - QgsProcessingParameterFeatureSource, - QgsProcessingParameterField, - QgsProcessingParameterMultipleLayers, - QgsProcessingParameterNumber, - QgsProcessingParameterVectorLayer, QgsProcessingUtils, - QgsProject, QgsSpatialIndex, QgsWkbTypes) +from qgis.core import ( + QgsDataSourceUri, + QgsFeature, + QgsFeatureSink, + QgsGeometry, + QgsProcessing, + QgsProcessingAlgorithm, + QgsProcessingException, + QgsProcessingMultiStepFeedback, + QgsProcessingOutputVectorLayer, + QgsProcessingParameterBoolean, + QgsProcessingParameterDistance, + QgsProcessingParameterEnum, + QgsProcessingParameterFeatureSink, + QgsProcessingParameterFeatureSource, + QgsProcessingParameterField, + QgsProcessingParameterMultipleLayers, + QgsProcessingParameterNumber, + QgsProcessingParameterVectorLayer, + QgsProcessingUtils, + QgsProject, + QgsSpatialIndex, + QgsWkbTypes, +) from ....dsgEnums import DsgEnums from ...algRunner import AlgRunner @@ -50,16 +60,16 @@ class IdentifyDrainageFlowIssuesWithHydrographyElementsAlgorithm(ValidationAlgorithm): - INPUT_DRAINAGES = 'INPUT_DRAINAGES' - SINK_LAYER = 'SINK_LAYER' - SPILLWAY_LAYER = 'SPILLWAY_LAYER' - WATER_BODY_WITH_FLOW_LAYER = 'WATER_BODY_WITH_FLOW_LAYER' - WATER_BODY_WITHOUT_FLOW_LAYER = 'WATER_BODY_WITHOUT_FLOW_LAYER' - OCEAN_LAYER = 'OCEAN_LAYER' - DITCH_LAYER = 'DITCH_LAYER' - POINT_FLAGS = 'POINT_FLAGS' - LINE_FLAGS = 'LINE_FLAGS' - POLYGON_FLAGS = 'POLYGON_FLAGS' + INPUT_DRAINAGES = "INPUT_DRAINAGES" + SINK_LAYER = "SINK_LAYER" + SPILLWAY_LAYER = "SPILLWAY_LAYER" + WATER_BODY_WITH_FLOW_LAYER = "WATER_BODY_WITH_FLOW_LAYER" + WATER_BODY_WITHOUT_FLOW_LAYER = "WATER_BODY_WITHOUT_FLOW_LAYER" + OCEAN_LAYER = "OCEAN_LAYER" + DITCH_LAYER = "DITCH_LAYER" + POINT_FLAGS = "POINT_FLAGS" + LINE_FLAGS = "LINE_FLAGS" + POLYGON_FLAGS = "POLYGON_FLAGS" def initAlgorithm(self, config): """ @@ -68,7 +78,7 @@ def initAlgorithm(self, config): self.addParameter( QgsProcessingParameterVectorLayer( self.INPUT_DRAINAGES, - self.tr('Input Drainages layer'), + self.tr("Input Drainages layer"), [QgsProcessing.TypeVectorLine], ) ) @@ -76,7 +86,7 @@ def initAlgorithm(self, config): self.addParameter( QgsProcessingParameterVectorLayer( self.SINK_LAYER, - self.tr('Water sink layer'), + self.tr("Water sink layer"), [QgsProcessing.TypeVectorPoint], optional=True, ) @@ -84,7 +94,7 @@ def initAlgorithm(self, config): self.addParameter( QgsProcessingParameterVectorLayer( self.SPILLWAY_LAYER, - self.tr('Spillway layer'), + self.tr("Spillway layer"), [QgsProcessing.TypeVectorPoint], optional=True, ) @@ -92,7 +102,7 @@ def initAlgorithm(self, config): self.addParameter( QgsProcessingParameterVectorLayer( self.WATER_BODY_WITH_FLOW_LAYER, - self.tr('Water body with flow layer'), + self.tr("Water body with flow layer"), [QgsProcessing.TypeVectorPolygon], optional=True, ) @@ -100,7 +110,7 @@ def initAlgorithm(self, config): self.addParameter( QgsProcessingParameterVectorLayer( self.WATER_BODY_WITHOUT_FLOW_LAYER, - self.tr('Water body without flow layer'), + self.tr("Water body without flow layer"), [QgsProcessing.TypeVectorPolygon], optional=True, ) @@ -108,7 +118,7 @@ def initAlgorithm(self, config): self.addParameter( QgsProcessingParameterVectorLayer( self.OCEAN_LAYER, - self.tr('Ocean layer'), + self.tr("Ocean layer"), [QgsProcessing.TypeVectorPolygon], optional=True, ) @@ -116,27 +126,25 @@ def initAlgorithm(self, config): self.addParameter( QgsProcessingParameterVectorLayer( self.DITCH_LAYER, - self.tr('Ditch layer'), + self.tr("Ditch layer"), [QgsProcessing.TypeVectorLine], optional=True, ) ) self.addParameter( QgsProcessingParameterFeatureSink( - self.POINT_FLAGS, - self.tr('{0} point flags').format(self.displayName()) + self.POINT_FLAGS, self.tr("{0} point flags").format(self.displayName()) ) ) self.addParameter( QgsProcessingParameterFeatureSink( - self.LINE_FLAGS, - self.tr('{0} line flags').format(self.displayName()) + self.LINE_FLAGS, self.tr("{0} line flags").format(self.displayName()) ) ) self.addParameter( QgsProcessingParameterFeatureSink( self.POLYGON_FLAGS, - self.tr('{0} polygon flags').format(self.displayName()) + self.tr("{0} polygon flags").format(self.displayName()), ) ) @@ -145,42 +153,51 @@ def processAlgorithm(self, parameters, context, feedback): Here is where the processing itself takes place. """ self.algRunner = AlgRunner() - inputDrainagesLyr = self.parameterAsLayer(parameters, self.INPUT_DRAINAGES, context) + inputDrainagesLyr = self.parameterAsLayer( + parameters, self.INPUT_DRAINAGES, context + ) if inputDrainagesLyr is None: - raise QgsProcessingException(self.invalidSourceError(parameters, self.INPUT_DRAINAGES)) + raise QgsProcessingException( + self.invalidSourceError(parameters, self.INPUT_DRAINAGES) + ) waterSinkLayer = self.parameterAsLayer(parameters, self.SINK_LAYER, context) spillwayLayer = self.parameterAsLayer(parameters, self.SPILLWAY_LAYER, context) - waterBodyWithFlowLyr = self.parameterAsLayer(parameters, self.WATER_BODY_WITH_FLOW_LAYER, context) - waterBodyWithoutFlowLyr = self.parameterAsLayer(parameters, self.WATER_BODY_WITHOUT_FLOW_LAYER, context) + waterBodyWithFlowLyr = self.parameterAsLayer( + parameters, self.WATER_BODY_WITH_FLOW_LAYER, context + ) + waterBodyWithoutFlowLyr = self.parameterAsLayer( + parameters, self.WATER_BODY_WITHOUT_FLOW_LAYER, context + ) oceanLyr = self.parameterAsLayer(parameters, self.OCEAN_LAYER, context) ditchLyr = self.parameterAsLayer(parameters, self.DITCH_LAYER, context) (self.pointFlagSink, self.point_flag_id) = self.prepareAndReturnFlagSink( - parameters, - inputDrainagesLyr, - QgsWkbTypes.Point, - context, - self.POINT_FLAGS + parameters, inputDrainagesLyr, QgsWkbTypes.Point, context, self.POINT_FLAGS ) (self.lineFlagSink, self.line_flag_id) = self.prepareAndReturnFlagSink( parameters, inputDrainagesLyr, QgsWkbTypes.LineString, context, - self.LINE_FLAGS + self.LINE_FLAGS, ) (self.polygonFlagSink, self.polygon_flag_id) = self.prepareAndReturnFlagSink( parameters, inputDrainagesLyr, QgsWkbTypes.Polygon, context, - self.POLYGON_FLAGS + self.POLYGON_FLAGS, + ) + nSteps = ( + 4 + + (waterSinkLayer is not None) + + (spillwayLayer is not None) + + 2 * (oceanLyr is not None) + + (waterBodyWithoutFlowLyr is not None) + + (waterBodyWithFlowLyr is not None) ) - nSteps = 4 + (waterSinkLayer is not None) + \ - (spillwayLayer is not None) + 2*(oceanLyr is not None) + \ - (waterBodyWithoutFlowLyr is not None) + (waterBodyWithFlowLyr is not None) multiStepFeedback = QgsProcessingMultiStepFeedback(nSteps, feedback) currentStep = 0 - multiStepFeedback.setProgressText(self.tr('Building aux structures')) + multiStepFeedback.setProgressText(self.tr("Building aux structures")) multiStepFeedback.setCurrentStep(currentStep) ( waterSinkLayer, @@ -190,13 +207,20 @@ def processAlgorithm(self, parameters, context, feedback): oceanLyr, ditchLyr, ) = self.buildCacheAndSpatialIndexOnLayerList( - layerList=[waterSinkLayer, spillwayLayer, waterBodyWithFlowLyr, waterBodyWithoutFlowLyr, oceanLyr, ditchLyr], + layerList=[ + waterSinkLayer, + spillwayLayer, + waterBodyWithFlowLyr, + waterBodyWithoutFlowLyr, + oceanLyr, + ditchLyr, + ], context=context, - feedback=multiStepFeedback + feedback=multiStepFeedback, ) currentStep += 1 - - multiStepFeedback.setProgressText(self.tr('Building drainage aux structures')) + + multiStepFeedback.setProgressText(self.tr("Building drainage aux structures")) multiStepFeedback.setCurrentStep(currentStep) ( cachedDrainagesLyr, @@ -208,11 +232,13 @@ def processAlgorithm(self, parameters, context, feedback): ) = self.buildAuxStructures( inputDrainagesLyr=inputDrainagesLyr, context=context, - feedback=multiStepFeedback + feedback=multiStepFeedback, ) currentStep += 1 multiStepFeedback.setCurrentStep(currentStep) - multiStepFeedback.setProgressText(self.tr('Validating elements against each other')) + multiStepFeedback.setProgressText( + self.tr("Validating elements against each other") + ) self.validateElementsAgainstEachOther( waterSinkLayer, spillwayLayer, @@ -220,7 +246,7 @@ def processAlgorithm(self, parameters, context, feedback): waterBodyWithoutFlowLyr, oceanLyr, context=context, - feedback=multiStepFeedback + feedback=multiStepFeedback, ) currentStep += 1 @@ -229,31 +255,31 @@ def processAlgorithm(self, parameters, context, feedback): self.validateIntersection( lyrA=startPointsLyr, lyrB=waterSinkLayer, - flagText=self.tr('Drainage starting in a water sink.'), + flagText=self.tr("Drainage starting in a water sink."), context=context, - feedback=multiStepFeedback + feedback=multiStepFeedback, ) currentStep += 1 - + if spillwayLayer is not None: multiStepFeedback.setCurrentStep(currentStep) self.validateIntersection( lyrA=endPointsLyr, lyrB=spillwayLayer, - flagText=self.tr('Drainage ending in a spillway.'), + flagText=self.tr("Drainage ending in a spillway."), context=context, - feedback=multiStepFeedback + feedback=multiStepFeedback, ) currentStep += 1 - + if oceanLyr is not None: multiStepFeedback.setCurrentStep(currentStep) self.validateIntersection( lyrA=startPointsLyr, lyrB=oceanLyr, - flagText=self.tr('Drainage starting in the ocean.'), + flagText=self.tr("Drainage starting in the ocean."), context=context, - feedback=multiStepFeedback + feedback=multiStepFeedback, ) multiStepFeedback.setCurrentStep(currentStep) self.validateDrainagesWithWaterBody( @@ -261,7 +287,7 @@ def processAlgorithm(self, parameters, context, feedback): oceanLyr, startPointDict=startPointDict, endPointDict=endPointDict, - waterBodyName=self.tr('ocean'), + waterBodyName=self.tr("ocean"), feedback=multiStepFeedback, withFlow=False, ) @@ -274,12 +300,12 @@ def processAlgorithm(self, parameters, context, feedback): waterBodyWithoutFlowLyr, startPointDict=startPointDict, endPointDict=endPointDict, - waterBodyName=self.tr('water body without flow'), + waterBodyName=self.tr("water body without flow"), feedback=multiStepFeedback, withFlow=False, ) currentStep += 1 - + if waterBodyWithFlowLyr is not None: multiStepFeedback.setCurrentStep(currentStep) self.validateDrainagesWithWaterBody( @@ -287,7 +313,7 @@ def processAlgorithm(self, parameters, context, feedback): waterBodyWithFlowLyr, startPointDict=startPointDict, endPointDict=endPointDict, - waterBodyName=self.tr('water body with flow'), + waterBodyName=self.tr("water body with flow"), feedback=multiStepFeedback, withFlow=True, ) @@ -304,15 +330,15 @@ def processAlgorithm(self, parameters, context, feedback): oceanLyr, ditchLyr, ], - feedback=multiStepFeedback + feedback=multiStepFeedback, ) - + return { self.POINT_FLAGS: self.point_flag_id, self.LINE_FLAGS: self.line_flag_id, self.POLYGON_FLAGS: self.polygon_flag_id, } - + def buildCacheAndSpatialIndexOnLayerList(self, layerList, context, feedback): multiStepFeedback = QgsProcessingMultiStepFeedback(len(layerList), feedback) outputList = [] @@ -325,7 +351,7 @@ def buildCacheAndSpatialIndexOnLayerList(self, layerList, context, feedback): ) outputList.append(cachedLyr) return outputList - + def buildCacheAndSpatialIndex(self, layer, context, feedback): if layer is None or layer.featureCount() == 0: return None @@ -336,9 +362,7 @@ def buildCacheAndSpatialIndex(self, layer, context, feedback): ) multiStepFeedback.setCurrentStep(1) cacheLyr = self.algRunner.runAddAutoIncrementalField( - inputLyr=cacheLyr, - context=context, - feedback=multiStepFeedback + inputLyr=cacheLyr, context=context, feedback=multiStepFeedback ) multiStepFeedback.setCurrentStep(2) self.algRunner.runCreateSpatialIndex( @@ -354,23 +378,23 @@ def buildAuxStructures(self, inputDrainagesLyr, context, feedback): ) multiStepFeedback.setCurrentStep(1) cachedInputDrainagesLyr = self.buildCacheAndSpatialIndex( - layer=inputDrainagesLyr, - context=context, - feedback=multiStepFeedback + layer=inputDrainagesLyr, context=context, feedback=multiStepFeedback ) - drainageDict = {feat['featid']:feat for feat in cachedInputDrainagesLyr.getFeatures()} + drainageDict = { + feat["featid"]: feat for feat in cachedInputDrainagesLyr.getFeatures() + } multiStepFeedback.setCurrentStep(2) startPointsLyr = self.algRunner.runExtractSpecificVertices( inputLyr=cachedInputDrainagesLyr, - vertices='0', + vertices="0", context=context, - feedback=multiStepFeedback + feedback=multiStepFeedback, ) multiStepFeedback.setCurrentStep(3) startPointsLyr = self.algRunner.runMultipartToSingleParts( inputLayer=startPointsLyr, context=context, feedback=multiStepFeedback ) - startPointDict = {feat['featid']: feat for feat in startPointsLyr.getFeatures()} + startPointDict = {feat["featid"]: feat for feat in startPointsLyr.getFeatures()} multiStepFeedback.setCurrentStep(4) self.algRunner.runCreateSpatialIndex( inputLyr=startPointsLyr, context=context, feedback=multiStepFeedback @@ -378,15 +402,15 @@ def buildAuxStructures(self, inputDrainagesLyr, context, feedback): multiStepFeedback.setCurrentStep(5) endPointsLyr = self.algRunner.runExtractSpecificVertices( inputLyr=cachedInputDrainagesLyr, - vertices='-1', + vertices="-1", context=context, - feedback=multiStepFeedback + feedback=multiStepFeedback, ) multiStepFeedback.setCurrentStep(6) endPointsLyr = self.algRunner.runMultipartToSingleParts( inputLayer=endPointsLyr, context=context, feedback=multiStepFeedback ) - endPointDict = {feat['featid']: feat for feat in endPointsLyr.getFeatures()} + endPointDict = {feat["featid"]: feat for feat in endPointsLyr.getFeatures()} multiStepFeedback.setCurrentStep(7) self.algRunner.runCreateSpatialIndex( inputLyr=endPointsLyr, context=context, feedback=multiStepFeedback @@ -399,9 +423,27 @@ def buildAuxStructures(self, inputDrainagesLyr, context, feedback): startPointDict, endPointDict, ) - - def validateElementsAgainstEachOther(self, waterSinkLayer, spillwayLayer, waterBodyWithFlowLyr, waterBodyWithoutFlowLyr, oceanLyr, context, feedback): - if all(x is None for x in (waterSinkLayer, spillwayLayer, waterBodyWithFlowLyr, waterBodyWithoutFlowLyr, oceanLyr)): + + def validateElementsAgainstEachOther( + self, + waterSinkLayer, + spillwayLayer, + waterBodyWithFlowLyr, + waterBodyWithoutFlowLyr, + oceanLyr, + context, + feedback, + ): + if all( + x is None + for x in ( + waterSinkLayer, + spillwayLayer, + waterBodyWithFlowLyr, + waterBodyWithoutFlowLyr, + oceanLyr, + ) + ): return multiStepFeedback = QgsProcessingMultiStepFeedback(7, feedback) currentStep = 0 @@ -410,29 +452,35 @@ def validateElementsAgainstEachOther(self, waterSinkLayer, spillwayLayer, waterB self.validateIntersection( lyrA=waterSinkLayer, lyrB=spillwayLayer, - flagText=self.tr('Invalid intersection between water sink feature and spillway feature.'), + flagText=self.tr( + "Invalid intersection between water sink feature and spillway feature." + ), context=context, - feedback=multiStepFeedback + feedback=multiStepFeedback, ) currentStep += 1 pointList = [ - (self.tr('water sink'), waterSinkLayer), - (self.tr('spillway'), spillwayLayer), + (self.tr("water sink"), waterSinkLayer), + (self.tr("spillway"), spillwayLayer), ] polygonList = [ - (self.tr('water body with flow'), waterBodyWithFlowLyr), - (self.tr('water body without flow'), waterBodyWithoutFlowLyr), - (self.tr('ocean'), oceanLyr), + (self.tr("water body with flow"), waterBodyWithFlowLyr), + (self.tr("water body without flow"), waterBodyWithoutFlowLyr), + (self.tr("ocean"), oceanLyr), ] - for (pointStr, pointLyr), (polygonStr, polygonLyr) in product(pointList, polygonList): + for (pointStr, pointLyr), (polygonStr, polygonLyr) in product( + pointList, polygonList + ): multiStepFeedback.setCurrentStep(currentStep) if pointLyr is not None and polygonLyr is not None: self.validateIntersection( lyrA=pointLyr, lyrB=polygonLyr, - flagText=self.tr(f'Invalid intersection between {pointStr} feature and {polygonStr} feature.'), + flagText=self.tr( + f"Invalid intersection between {pointStr} feature and {polygonStr} feature." + ), context=context, - feedback=multiStepFeedback + feedback=multiStepFeedback, ) currentStep += 1 @@ -440,36 +488,51 @@ def validateIntersection(self, lyrA, lyrB, flagText, context, feedback): multiStepFeedback = QgsProcessingMultiStepFeedback(2, feedback) multiStepFeedback.setCurrentStep(0) invalidIntersection = self.algRunner.runExtractByLocation( - inputLyr=lyrA, intersectLyr=lyrB, context=context, feedback=multiStepFeedback - ) + inputLyr=lyrA, + intersectLyr=lyrB, + context=context, + feedback=multiStepFeedback, + ) multiStepFeedback.setCurrentStep(1) flagLambda = lambda x: self.flagFeature( - x.geometry(), - flagText=flagText, - sink=self.pointFlagSink + x.geometry(), flagText=flagText, sink=self.pointFlagSink ) list(map(flagLambda, invalidIntersection.getFeatures())) - - def validateDrainagesWithWaterBody(self, drainagesLyr, waterBodyLyr, startPointDict, endPointDict, waterBodyName, feedback, withFlow=False): + + def validateDrainagesWithWaterBody( + self, + drainagesLyr, + waterBodyLyr, + startPointDict, + endPointDict, + waterBodyName, + feedback, + withFlow=False, + ): nFeats = waterBodyLyr.featureCount() if nFeats == 0: return multiStepFeedback = QgsProcessingMultiStepFeedback(2, feedback) - multiStepFeedback.setProgressText(self.tr(f'Validating drainages with {waterBodyName}')) + multiStepFeedback.setProgressText( + self.tr(f"Validating drainages with {waterBodyName}") + ) multiStepFeedback.setCurrentStep(0) flagLineLambda = lambda geom: self.flagFeature( geom, - flagText=self.tr(f'Invalid intersection of drainage and {waterBodyName}.'), - sink=self.lineFlagSink + flagText=self.tr(f"Invalid intersection of drainage and {waterBodyName}."), + sink=self.lineFlagSink, ) flagPolygonLambda = lambda geom: self.flagFeature( geom, - flagText=self.tr(f'Invalid flow on polygon of {waterBodyName}'), - sink=self.polygonFlagSink + flagText=self.tr(f"Invalid flow on polygon of {waterBodyName}"), + sink=self.polygonFlagSink, ) - flowCheckLambda = lambda x: ( - (x[0] >= 0 and x[1] == 0) or (x[0] >= 0 and x[1] == 0) - ) if not withFlow else (x[0] > 0 and x[1] > 0) + flowCheckLambda = ( + lambda x: ((x[0] >= 0 and x[1] == 0) or (x[0] >= 0 and x[1] == 0)) + if not withFlow + else (x[0] > 0 and x[1] > 0) + ) + def evaluate(feat): geom = feat.geometry() bbox = geom.boundingBox() @@ -484,19 +547,29 @@ def evaluate(feat): if not geomEngine.intersects(drainageGeom.constGet()): continue # if geomEngine.relatePattern(drainageGeom.constGet(), 'FF2FF1102'): - + # continue intersection = geomEngine.intersection(drainageGeom.constGet()) - if QgsWkbTypes.geometryType(intersection.wkbType()) == QgsWkbTypes.PointGeometry: - outCount += geomEngine.intersects(startPointDict[drainageFeat['featid']].geometry().constGet()) - inCount += geomEngine.intersects(endPointDict[drainageFeat['featid']].geometry().constGet()) + if ( + QgsWkbTypes.geometryType(intersection.wkbType()) + == QgsWkbTypes.PointGeometry + ): + outCount += geomEngine.intersects( + startPointDict[drainageFeat["featid"]].geometry().constGet() + ) + inCount += geomEngine.intersects( + endPointDict[drainageFeat["featid"]].geometry().constGet() + ) continue interWkt = intersection.asWkt() - if withFlow and drainageGeom.equals(QgsGeometry.fromWkt(intersection.asWkt())): + if withFlow and drainageGeom.equals( + QgsGeometry.fromWkt(intersection.asWkt()) + ): continue intersectionSet.add(interWkt) polygonWithProblem = None if flowCheckLambda([inCount, outCount]) else geom return intersectionSet, polygonWithProblem + stepSize = 100 / nFeats pool = concurrent.futures.ThreadPoolExecutor(max_workers=os.cpu_count() - 1) futures = set() @@ -515,23 +588,29 @@ def evaluate(feat): # for wkt in intersectionSet: # flagLineLambda(QgsGeometry.fromWkt(wkt)) if intersectionSet != set(): - list(map(flagLineLambda, list(map(lambda x: QgsGeometry.fromWkt(x), intersectionSet)))) + list( + map( + flagLineLambda, + list(map(lambda x: QgsGeometry.fromWkt(x), intersectionSet)), + ) + ) if polygonWithProblem is not None: flagPolygonLambda(polygonWithProblem) multiStepFeedback.setProgress(current * stepSize) - + def validateDrainagesEndPoints(self, endPointDict, elementList, feedback): nFeats = len(endPointDict) if nFeats == 0: return multiStepFeedback = QgsProcessingMultiStepFeedback(2, feedback) - multiStepFeedback.setProgressText(self.tr(f'Validating drainages end points.')) + multiStepFeedback.setProgressText(self.tr(f"Validating drainages end points.")) multiStepFeedback.setCurrentStep(0) flagPointLambda = lambda geom: self.flagFeature( geom, - flagText=self.tr(f'Invalid intersection of drainage end point.'), - sink=self.pointFlagSink + flagText=self.tr(f"Invalid intersection of drainage end point."), + sink=self.pointFlagSink, ) + def evaluate(feat): geom = feat.geometry() bbox = geom.boundingBox() @@ -539,16 +618,21 @@ def evaluate(feat): geomEngine.prepareGeometry() getFeaturesLambda = lambda lyr: lyr.getFeatures(bbox) for candidateFeat in chain.from_iterable( - map(getFeaturesLambda, filter(lambda x: x is not None, elementList))): + map(getFeaturesLambda, filter(lambda x: x is not None, elementList)) + ): if multiStepFeedback.isCanceled(): return None candidateGeom = candidateFeat.geometry() - if QgsWkbTypes.geometryType(candidateGeom.wkbType()) == QgsWkbTypes.PointGeometry and \ - geomEngine.intersects(candidateGeom.constGet()): + if QgsWkbTypes.geometryType( + candidateGeom.wkbType() + ) == QgsWkbTypes.PointGeometry and geomEngine.intersects( + candidateGeom.constGet() + ): return None if geomEngine.touches(candidateGeom.constGet()): return None return geom + stepSize = 100 / nFeats pool = concurrent.futures.ThreadPoolExecutor(max_workers=os.cpu_count() - 1) futures = set() @@ -567,7 +651,6 @@ def evaluate(feat): flagPointLambda(geom) multiStepFeedback.setProgress(current * stepSize) - def name(self): """ Returns the algorithm name, used for identifying the algorithm. This @@ -576,21 +659,23 @@ def name(self): lowercase alphanumeric characters only and no spaces or other formatting characters. """ - return 'identifydrainageflowissueswithhydrographyelementsalgorithm' + return "identifydrainageflowissueswithhydrographyelementsalgorithm" def displayName(self): """ Returns the translated algorithm name, which should be used for any user-visible display of the algorithm name. """ - return self.tr('Identify Drainage Flow Issues With Hydrography Elements Algorithm') + return self.tr( + "Identify Drainage Flow Issues With Hydrography Elements Algorithm" + ) def group(self): """ Returns the name of the group this algorithm belongs to. This string should be localised. """ - return self.tr('Quality Assurance Tools (Network Processes)') + return self.tr("Quality Assurance Tools (Network Processes)") def groupId(self): """ @@ -600,10 +685,12 @@ def groupId(self): contain lowercase alphanumeric characters only and no spaces or other formatting characters. """ - return 'DSGTools: Quality Assurance Tools (Network Processes)' + return "DSGTools: Quality Assurance Tools (Network Processes)" def tr(self, string): - return QCoreApplication.translate('IdentifyDrainageFlowIssuesWithHydrographyElementsAlgorithm', string) + return QCoreApplication.translate( + "IdentifyDrainageFlowIssuesWithHydrographyElementsAlgorithm", string + ) def createInstance(self): return IdentifyDrainageFlowIssuesWithHydrographyElementsAlgorithm() diff --git a/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/identifyDrainageLoops.py b/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/identifyDrainageLoops.py index 357d108ae..e41aaa3f9 100644 --- a/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/identifyDrainageLoops.py +++ b/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/identifyDrainageLoops.py @@ -24,12 +24,17 @@ import os import concurrent.futures from PyQt5.QtCore import QCoreApplication -from qgis.core import (QgsProcessing, QgsProcessingException, - QgsProcessingMultiStepFeedback, - QgsProcessingParameterBoolean, - QgsProcessingParameterFeatureSink, - QgsProcessingParameterFeatureSource, QgsGeometry, - QgsWkbTypes, QgsPoint) +from qgis.core import ( + QgsProcessing, + QgsProcessingException, + QgsProcessingMultiStepFeedback, + QgsProcessingParameterBoolean, + QgsProcessingParameterFeatureSink, + QgsProcessingParameterFeatureSource, + QgsGeometry, + QgsWkbTypes, + QgsPoint, +) from DsgTools.core.DSGToolsProcessingAlgs.algRunner import AlgRunner from DsgTools.core.GeometricTools.geometryHandler import GeometryHandler @@ -38,30 +43,28 @@ class IdentifyDrainageLoops(ValidationAlgorithm): - INPUT = 'INPUT' - BUILD_CACHE = 'BUILD_CACHE' - FLAGS = 'FLAGS' + INPUT = "INPUT" + BUILD_CACHE = "BUILD_CACHE" + FLAGS = "FLAGS" def initAlgorithm(self, config=None): self.addParameter( QgsProcessingParameterFeatureSource( self.INPUT, - self.tr('Input'), + self.tr("Input"), [ QgsProcessing.TypeVectorLine, - ] + ], ) ) self.addParameter( QgsProcessingParameterBoolean( - self.BUILD_CACHE, - self.tr('Build local cache of the input layer') + self.BUILD_CACHE, self.tr("Build local cache of the input layer") ) ) self.addParameter( QgsProcessingParameterFeatureSink( - self.FLAGS, - self.tr('{0} Flags').format(self.displayName()) + self.FLAGS, self.tr("{0} Flags").format(self.displayName()) ) ) @@ -70,19 +73,15 @@ def processAlgorithm(self, parameters, context, feedback): import networkx as nx except ImportError: raise QgsProcessingException( - self.tr('This algorithm requires the Python networkx library. Please install this library and try again.') + self.tr( + "This algorithm requires the Python networkx library. Please install this library and try again." + ) ) algRunner = AlgRunner() geometryHandler = GeometryHandler() - inputLyr = self.parameterAsVectorLayer( - parameters, - 'INPUT', - context - ) - buildCache = self.parameterAsBool( - parameters, self.BUILD_CACHE, context - ) + inputLyr = self.parameterAsVectorLayer(parameters, "INPUT", context) + buildCache = self.parameterAsBool(parameters, self.BUILD_CACHE, context) self.prepareFlagSink(parameters, inputLyr, QgsWkbTypes.LineString, context) # Iterate over lines setting the dictionary counters: @@ -101,7 +100,7 @@ def processAlgorithm(self, parameters, context, feedback): inputLyr=inputLyr, context=context, feedback=multiStepFeedback ) currentStep += 1 - + multiStepFeedback.setProgressText(self.tr("Building loop area candidates...")) multiStepFeedback.setCurrentStep(currentStep) polygonLyr = algRunner.runPolygonize( @@ -111,13 +110,13 @@ def processAlgorithm(self, parameters, context, feedback): if polygonLyr.featureCount() == 0: return {self.FLAGS: self.flag_id} - + multiStepFeedback.setCurrentStep(currentStep) mergedPolygons = algRunner.runDissolve( inputLyr=polygonLyr, context=context, feedback=multiStepFeedback ) currentStep += 1 - + multiStepFeedback.setCurrentStep(currentStep) polygonLoops = algRunner.runMultipartToSingleParts( inputLayer=mergedPolygons, context=context, feedback=multiStepFeedback @@ -125,25 +124,30 @@ def processAlgorithm(self, parameters, context, feedback): currentStep += 1 polygonCount = polygonLoops.featureCount() if polygonCount == 0: - multiStepFeedback.setProgressText(self.tr("Building loop area candidates...")) + multiStepFeedback.setProgressText( + self.tr("Building loop area candidates...") + ) return {self.FLAGS: self.flag_id} multiStepFeedback.setCurrentStep(currentStep) - self.searchLoops(nx, geometryHandler, inputLyr, multiStepFeedback, polygonLoops, polygonCount) + self.searchLoops( + nx, geometryHandler, inputLyr, multiStepFeedback, polygonLoops, polygonCount + ) return {self.FLAGS: self.flag_id} - def searchLoops(self, nx, geometryHandler, inputLyr, feedback, polygonLoops, polygonCount): + def searchLoops( + self, nx, geometryHandler, inputLyr, feedback, polygonLoops, polygonCount + ): multiStepFeedback = QgsProcessingMultiStepFeedback(2, feedback) stepSize = 100 / polygonCount flagFeatLambda = lambda x: self.flagFeature( - flagGeom=x, flagText=self.tr('Loop on input drainages') - ) - firstAndLastNode = lambda x: geometryHandler.getFirstAndLastNode( - inputLyr, x + flagGeom=x, flagText=self.tr("Loop on input drainages") ) + firstAndLastNode = lambda x: geometryHandler.getFirstAndLastNode(inputLyr, x) multiStepFeedback.setCurrentStep(0) - multiStepFeedback.setProgressText(self.tr('Submitting tasks to thread')) + multiStepFeedback.setProgressText(self.tr("Submitting tasks to thread")) + def evaluate(polygonFeature): geom = polygonFeature.geometry() geomEngine = QgsGeometry.createGeometryEngine(geom.constGet()) @@ -154,14 +158,17 @@ def evaluate(polygonFeature): p0, pn = firstAndLastNode(feat) p0 = QgsGeometry.fromPointXY(p0) pn = QgsGeometry.fromPointXY(pn) - if not geomEngine.intersects(p0.constGet()) or not geomEngine.intersects(pn.constGet()): + if not geomEngine.intersects( + p0.constGet() + ) or not geomEngine.intersects(pn.constGet()): continue vertexList = list(feat.geometry().vertices()) for v1, v2 in zip(vertexList, vertexList[1:]): graph.add_edge(v1.asWkt(), v2.asWkt()) loopSet = self.findLoopsOnEdgeSet(nx, graph, feedback=multiStepFeedback) return loopSet - pool = concurrent.futures.ThreadPoolExecutor(os.cpu_count()-1) + + pool = concurrent.futures.ThreadPoolExecutor(os.cpu_count() - 1) futures = set() for current, polygonFeature in enumerate(polygonLoops.getFeatures()): if multiStepFeedback.isCanceled(): @@ -170,8 +177,8 @@ def evaluate(polygonFeature): multiStepFeedback.setCurrentStep(current * stepSize) multiStepFeedback.setCurrentStep(1) - multiStepFeedback.setProgressText(self.tr('Evaluating results')) - + multiStepFeedback.setProgressText(self.tr("Evaluating results")) + for current, future in enumerate(concurrent.futures.as_completed(futures)): if multiStepFeedback.isCanceled(): break @@ -193,14 +200,12 @@ def findLoopsOnEdgeSet(self, nx, graph, feedback): continue pointFromWkt = lambda x: QgsPoint(QgsGeometry.fromWkt(x).asPoint()) loopGeom = QgsGeometry.fromPolyline( - [pointFromWkt(initialNode)] + - list(map(pointFromWkt, nodeList)) + [pointFromWkt(initialNode)] + + list(map(pointFromWkt, nodeList)) + + [pointFromWkt(initialNode)] ) loopSet.add(loopGeom) return loopSet - - def name(self): """ @@ -210,21 +215,21 @@ def name(self): lowercase alphanumeric characters only and no spaces or other formatting characters. """ - return 'identifydrainageloops' + return "identifydrainageloops" def displayName(self): """ Returns the translated algorithm name, which should be used for any user-visible display of the algorithm name. """ - return self.tr('Identify Drainage Loops') + return self.tr("Identify Drainage Loops") def group(self): """ Returns the name of the group this algorithm belongs to. This string should be localised. """ - return self.tr('Quality Assurance Tools (Identification Processes)') + return self.tr("Quality Assurance Tools (Identification Processes)") def groupId(self): """ @@ -234,10 +239,10 @@ def groupId(self): contain lowercase alphanumeric characters only and no spaces or other formatting characters. """ - return self.tr('DSGTools: Quality Assurance Tools (Identification Processes)') + return self.tr("DSGTools: Quality Assurance Tools (Identification Processes)") def tr(self, string): - return QCoreApplication.translate('IdentifyDrainageLoops', string) + return QCoreApplication.translate("IdentifyDrainageLoops", string) def createInstance(self): return IdentifyDrainageLoops() diff --git a/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/identifyDuplicatedFeaturesAlgorithm.py b/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/identifyDuplicatedFeaturesAlgorithm.py index fa98930b2..188b8ce71 100644 --- a/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/identifyDuplicatedFeaturesAlgorithm.py +++ b/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/identifyDuplicatedFeaturesAlgorithm.py @@ -23,27 +23,34 @@ from PyQt5.QtCore import QCoreApplication from DsgTools.core.GeometricTools.layerHandler import LayerHandler -from qgis.core import (QgsDataSourceUri, QgsFeature, QgsFeatureSink, - QgsProcessing, QgsProcessingAlgorithm, - QgsProcessingException, QgsProcessingMultiStepFeedback, - QgsProcessingOutputVectorLayer, - QgsProcessingParameterBoolean, - QgsProcessingParameterFeatureSink, - QgsProcessingParameterFeatureSource, - QgsProcessingParameterField, - QgsProcessingParameterVectorLayer, QgsWkbTypes) +from qgis.core import ( + QgsDataSourceUri, + QgsFeature, + QgsFeatureSink, + QgsProcessing, + QgsProcessingAlgorithm, + QgsProcessingException, + QgsProcessingMultiStepFeedback, + QgsProcessingOutputVectorLayer, + QgsProcessingParameterBoolean, + QgsProcessingParameterFeatureSink, + QgsProcessingParameterFeatureSource, + QgsProcessingParameterField, + QgsProcessingParameterVectorLayer, + QgsWkbTypes, +) from ...algRunner import AlgRunner from .validationAlgorithm import ValidationAlgorithm class IdentifyDuplicatedFeaturesAlgorithm(ValidationAlgorithm): - FLAGS = 'FLAGS' - INPUT = 'INPUT' - SELECTED = 'SELECTED' - ATTRIBUTE_BLACK_LIST = 'ATTRIBUTE_BLACK_LIST' - IGNORE_VIRTUAL_FIELDS = 'IGNORE_VIRTUAL_FIELDS' - IGNORE_PK_FIELDS = 'IGNORE_PK_FIELDS' + FLAGS = "FLAGS" + INPUT = "INPUT" + SELECTED = "SELECTED" + ATTRIBUTE_BLACK_LIST = "ATTRIBUTE_BLACK_LIST" + IGNORE_VIRTUAL_FIELDS = "IGNORE_VIRTUAL_FIELDS" + IGNORE_PK_FIELDS = "IGNORE_PK_FIELDS" def initAlgorithm(self, config): """ @@ -52,48 +59,46 @@ def initAlgorithm(self, config): self.addParameter( QgsProcessingParameterVectorLayer( self.INPUT, - self.tr('Input layer'), - [QgsProcessing.TypeVectorAnyGeometry ] + self.tr("Input layer"), + [QgsProcessing.TypeVectorAnyGeometry], ) ) self.addParameter( QgsProcessingParameterBoolean( - self.SELECTED, - self.tr('Process only selected features') + self.SELECTED, self.tr("Process only selected features") ) ) self.addParameter( QgsProcessingParameterField( - self.ATTRIBUTE_BLACK_LIST, - self.tr('Fields to ignore'), - None, - 'INPUT', + self.ATTRIBUTE_BLACK_LIST, + self.tr("Fields to ignore"), + None, + "INPUT", QgsProcessingParameterField.Any, allowMultiple=True, - optional = True + optional=True, ) ) self.addParameter( QgsProcessingParameterBoolean( self.IGNORE_VIRTUAL_FIELDS, - self.tr('Ignore virtual fields'), - defaultValue=True + self.tr("Ignore virtual fields"), + defaultValue=True, ) ) self.addParameter( QgsProcessingParameterBoolean( self.IGNORE_PK_FIELDS, - self.tr('Ignore primary key fields'), - defaultValue=True + self.tr("Ignore primary key fields"), + defaultValue=True, ) ) self.addParameter( QgsProcessingParameterFeatureSink( - self.FLAGS, - self.tr('{0} Flags').format(self.displayName()) + self.FLAGS, self.tr("{0} Flags").format(self.displayName()) ) ) @@ -104,10 +109,16 @@ def processAlgorithm(self, parameters, context, feedback): layerHandler = LayerHandler() inputLyr = self.parameterAsVectorLayer(parameters, self.INPUT, context) if inputLyr is None: - raise QgsProcessingException(self.invalidSourceError(parameters, self.INPUT)) + raise QgsProcessingException( + self.invalidSourceError(parameters, self.INPUT) + ) onlySelected = self.parameterAsBool(parameters, self.SELECTED, context) - attributeBlackList = self.parameterAsFields(parameters, self.ATTRIBUTE_BLACK_LIST, context) - ignoreVirtual = self.parameterAsBool(parameters, self.IGNORE_VIRTUAL_FIELDS, context) + attributeBlackList = self.parameterAsFields( + parameters, self.ATTRIBUTE_BLACK_LIST, context + ) + ignoreVirtual = self.parameterAsBool( + parameters, self.IGNORE_VIRTUAL_FIELDS, context + ) ignorePK = self.parameterAsBool(parameters, self.IGNORE_PK_FIELDS, context) self.prepareFlagSink(parameters, inputLyr, inputLyr.wkbType(), context) # Compute the number of steps to display within the progress bar and @@ -115,27 +126,29 @@ def processAlgorithm(self, parameters, context, feedback): multiStepFeedback = QgsProcessingMultiStepFeedback(2, feedback) multiStepFeedback.setCurrentStep(0) geomDict = layerHandler.getDuplicatedFeaturesDict( - inputLyr, - onlySelected=onlySelected, - attributeBlackList=attributeBlackList, - excludePrimaryKeys=ignorePK, - ignoreVirtualFields=ignoreVirtual, - useAttributes=True, - feedback=multiStepFeedback - ) + inputLyr, + onlySelected=onlySelected, + attributeBlackList=attributeBlackList, + excludePrimaryKeys=ignorePK, + ignoreVirtualFields=ignoreVirtual, + useAttributes=True, + feedback=multiStepFeedback, + ) multiStepFeedback.setCurrentStep(1) self.raiseDuplicatedFeaturesFlags(inputLyr, geomDict, multiStepFeedback) return {self.FLAGS: self.flag_id} def raiseDuplicatedFeaturesFlags(self, inputLyr, geomDict, feedback): - size = 100/len(geomDict) if geomDict else 0 + size = 100 / len(geomDict) if geomDict else 0 for current, featList in enumerate(geomDict.values()): if feedback.isCanceled(): break if len(featList) > 1: - idStrList = ', '.join(map(str, [feat.id() for feat in featList])) - flagText = self.tr('Features from layer {0} with ids=({1}) have the same set of attributes.').format(inputLyr.name(), idStrList) + idStrList = ", ".join(map(str, [feat.id() for feat in featList])) + flagText = self.tr( + "Features from layer {0} with ids=({1}) have the same set of attributes." + ).format(inputLyr.name(), idStrList) self.flagFeature(featList[0].geometry(), flagText) feedback.setProgress(size * current) @@ -147,21 +160,21 @@ def name(self): lowercase alphanumeric characters only and no spaces or other formatting characters. """ - return 'identifyduplicatedfeatures' + return "identifyduplicatedfeatures" def displayName(self): """ Returns the translated algorithm name, which should be used for any user-visible display of the algorithm name. """ - return self.tr('Identify Duplicated Features') + return self.tr("Identify Duplicated Features") def group(self): """ Returns the name of the group this algorithm belongs to. This string should be localised. """ - return self.tr('Quality Assurance Tools (Identification Processes)') + return self.tr("Quality Assurance Tools (Identification Processes)") def groupId(self): """ @@ -171,10 +184,10 @@ def groupId(self): contain lowercase alphanumeric characters only and no spaces or other formatting characters. """ - return 'DSGTools: Quality Assurance Tools (Identification Processes)' + return "DSGTools: Quality Assurance Tools (Identification Processes)" def tr(self, string): - return QCoreApplication.translate('IdentifyDuplicatedFeaturesAlgorithm', string) + return QCoreApplication.translate("IdentifyDuplicatedFeaturesAlgorithm", string) def createInstance(self): return IdentifyDuplicatedFeaturesAlgorithm() diff --git a/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/identifyDuplicatedGeometriesAlgorithm.py b/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/identifyDuplicatedGeometriesAlgorithm.py index 5ddfdb25f..51a8d38a7 100644 --- a/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/identifyDuplicatedGeometriesAlgorithm.py +++ b/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/identifyDuplicatedGeometriesAlgorithm.py @@ -20,22 +20,30 @@ ***************************************************************************/ """ from DsgTools.core.GeometricTools.layerHandler import LayerHandler -from qgis.core import (QgsDataSourceUri, QgsFeature, QgsFeatureSink, - QgsProcessing, QgsProcessingAlgorithm, - QgsProcessingException, QgsProcessingMultiStepFeedback, - QgsProcessingOutputVectorLayer, - QgsProcessingParameterBoolean, - QgsProcessingParameterFeatureSink, - QgsProcessingParameterFeatureSource, - QgsProcessingParameterVectorLayer, QgsWkbTypes) +from qgis.core import ( + QgsDataSourceUri, + QgsFeature, + QgsFeatureSink, + QgsProcessing, + QgsProcessingAlgorithm, + QgsProcessingException, + QgsProcessingMultiStepFeedback, + QgsProcessingOutputVectorLayer, + QgsProcessingParameterBoolean, + QgsProcessingParameterFeatureSink, + QgsProcessingParameterFeatureSource, + QgsProcessingParameterVectorLayer, + QgsWkbTypes, +) from qgis.PyQt.QtCore import QCoreApplication from .validationAlgorithm import ValidationAlgorithm + class IdentifyDuplicatedGeometriesAlgorithm(ValidationAlgorithm): - FLAGS = 'FLAGS' - INPUT = 'INPUT' - SELECTED = 'SELECTED' + FLAGS = "FLAGS" + INPUT = "INPUT" + SELECTED = "SELECTED" def initAlgorithm(self, config): """ @@ -44,22 +52,20 @@ def initAlgorithm(self, config): self.addParameter( QgsProcessingParameterVectorLayer( self.INPUT, - self.tr('Input layer'), - [QgsProcessing.TypeVectorAnyGeometry] + self.tr("Input layer"), + [QgsProcessing.TypeVectorAnyGeometry], ) ) self.addParameter( QgsProcessingParameterBoolean( - self.SELECTED, - self.tr('Process only selected features') + self.SELECTED, self.tr("Process only selected features") ) ) self.addParameter( QgsProcessingParameterFeatureSink( - self.FLAGS, - self.tr('{0} Flags').format(self.displayName()) + self.FLAGS, self.tr("{0} Flags").format(self.displayName()) ) ) @@ -70,7 +76,8 @@ def processAlgorithm(self, parameters, context, feedback): inputLyr = self.parameterAsVectorLayer(parameters, self.INPUT, context) if inputLyr is None: raise QgsProcessingException( - self.invalidSourceError(parameters, self.INPUT)) + self.invalidSourceError(parameters, self.INPUT) + ) onlySelected = self.parameterAsBool(parameters, self.SELECTED, context) self.prepareFlagSink(parameters, inputLyr, inputLyr.wkbType(), context) # Compute the number of steps to display within the progress bar and @@ -82,22 +89,22 @@ def processAlgorithm(self, parameters, context, feedback): self.tr("Building duplicated features dictionary...") ) geomDict = layerHandler.getDuplicatedFeaturesDict( - inputLyr, onlySelected=onlySelected, feedback=multiStepFeedback) + inputLyr, onlySelected=onlySelected, feedback=multiStepFeedback + ) multiStepFeedback.setCurrentStep(1) - self.raiseDuplicatedFeaturesFlags( - inputLyr, geomDict, multiStepFeedback) + self.raiseDuplicatedFeaturesFlags(inputLyr, geomDict, multiStepFeedback) return {self.FLAGS: self.flag_id} def raiseDuplicatedFeaturesFlags(self, inputLyr, geomDict, feedback): - size = 100/len(geomDict) if geomDict else 0 + size = 100 / len(geomDict) if geomDict else 0 for current, featList in enumerate(geomDict.values()): if feedback.isCanceled(): break if len(featList) > 1: - idStrList = ', '.join( - map(str, [feat.id() for feat in featList])) - flagText = self.tr('Features from layer {0} with ids=({1}) have the same set of attributes.').format( - inputLyr.name(), idStrList) + idStrList = ", ".join(map(str, [feat.id() for feat in featList])) + flagText = self.tr( + "Features from layer {0} with ids=({1}) have the same set of attributes." + ).format(inputLyr.name(), idStrList) self.flagFeature(featList[0].geometry(), flagText) feedback.setProgress(size * current) @@ -109,21 +116,21 @@ def name(self): lowercase alphanumeric characters only and no spaces or other formatting characters. """ - return 'identifyduplicatedgeometries' + return "identifyduplicatedgeometries" def displayName(self): """ Returns the translated algorithm name, which should be used for any user-visible display of the algorithm name. """ - return self.tr('Identify Duplicated Geometries') + return self.tr("Identify Duplicated Geometries") def group(self): """ Returns the name of the group this algorithm belongs to. This string should be localised. """ - return self.tr('Quality Assurance Tools (Identification Processes)') + return self.tr("Quality Assurance Tools (Identification Processes)") def groupId(self): """ @@ -133,10 +140,12 @@ def groupId(self): contain lowercase alphanumeric characters only and no spaces or other formatting characters. """ - return 'DSGTools: Quality Assurance Tools (Identification Processes)' + return "DSGTools: Quality Assurance Tools (Identification Processes)" def tr(self, string): - return QCoreApplication.translate('IdentifyDuplicatedGeometriesAlgorithm', string) + return QCoreApplication.translate( + "IdentifyDuplicatedGeometriesAlgorithm", string + ) def createInstance(self): return IdentifyDuplicatedGeometriesAlgorithm() diff --git a/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/identifyDuplicatedLinesBetweenLayersAlgorithm.py b/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/identifyDuplicatedLinesBetweenLayersAlgorithm.py index 39f50cab4..2575f5620 100644 --- a/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/identifyDuplicatedLinesBetweenLayersAlgorithm.py +++ b/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/identifyDuplicatedLinesBetweenLayersAlgorithm.py @@ -22,23 +22,30 @@ from PyQt5.QtCore import QCoreApplication -from qgis.core import (QgsDataSourceUri, QgsFeature, QgsFeatureSink, - QgsProcessing, QgsProcessingAlgorithm, - QgsProcessingException, QgsProcessingMultiStepFeedback, - QgsProcessingOutputVectorLayer, - QgsProcessingParameterBoolean, - QgsProcessingParameterFeatureSink, - QgsProcessingParameterFeatureSource, - QgsProcessingParameterMultipleLayers, - QgsProcessingParameterVectorLayer, QgsWkbTypes) +from qgis.core import ( + QgsDataSourceUri, + QgsFeature, + QgsFeatureSink, + QgsProcessing, + QgsProcessingAlgorithm, + QgsProcessingException, + QgsProcessingMultiStepFeedback, + QgsProcessingOutputVectorLayer, + QgsProcessingParameterBoolean, + QgsProcessingParameterFeatureSink, + QgsProcessingParameterFeatureSource, + QgsProcessingParameterMultipleLayers, + QgsProcessingParameterVectorLayer, + QgsWkbTypes, +) from .validationAlgorithm import ValidationAlgorithm class IdentifyDuplicatedLinesBetweenLayersAlgorithm(ValidationAlgorithm): - FLAGS = 'FLAGS' - INPUTLAYERS = 'INPUTLAYERS' - SELECTED = 'SELECTED' + FLAGS = "FLAGS" + INPUTLAYERS = "INPUTLAYERS" + SELECTED = "SELECTED" def initAlgorithm(self, config): """ @@ -47,22 +54,20 @@ def initAlgorithm(self, config): self.addParameter( QgsProcessingParameterMultipleLayers( self.INPUTLAYERS, - self.tr('Coverage Linestring Layers'), - QgsProcessing.TypeVectorLine + self.tr("Coverage Linestring Layers"), + QgsProcessing.TypeVectorLine, ) ) self.addParameter( QgsProcessingParameterBoolean( - self.SELECTED, - self.tr('Process only selected features') + self.SELECTED, self.tr("Process only selected features") ) ) self.addParameter( QgsProcessingParameterFeatureSink( - self.FLAGS, - self.tr('{0} Flags').format(self.displayName()) + self.FLAGS, self.tr("{0} Flags").format(self.displayName()) ) ) @@ -73,18 +78,26 @@ def processAlgorithm(self, parameters, context, feedback): inputLyrList = self.parameterAsLayerList(parameters, self.INPUTLAYERS, context) if inputLyrList == []: - raise QgsProcessingException(self.invalidSourceError(parameters, self.INPUTLAYERS)) + raise QgsProcessingException( + self.invalidSourceError(parameters, self.INPUTLAYERS) + ) onlySelected = self.parameterAsBool(parameters, self.SELECTED, context) - self.prepareFlagSink(parameters, inputLyrList[0], QgsWkbTypes.LineString, context) + self.prepareFlagSink( + parameters, inputLyrList[0], QgsWkbTypes.LineString, context + ) # Compute the number of steps to display within the progress bar and # get features from source geomDict = dict() - multiStepFeedback = QgsProcessingMultiStepFeedback(len(inputLyrList)+1, feedback) + multiStepFeedback = QgsProcessingMultiStepFeedback( + len(inputLyrList) + 1, feedback + ) for currentLyrIdx, lyr in enumerate(inputLyrList): multiStepFeedback.setCurrentStep(currentLyrIdx) - featIterator, total = self.getIteratorAndFeatureCount(lyr, onlySelected=onlySelected) - size = 100/total if total else 0 - lyrName = lyr.name() + featIterator, total = self.getIteratorAndFeatureCount( + lyr, onlySelected=onlySelected + ) + size = 100 / total if total else 0 + lyrName = lyr.name() for current, feat in enumerate(featIterator): # Stop the algorithm if cancel button has been clicked if multiStepFeedback.isCanceled(): @@ -93,17 +106,24 @@ def processAlgorithm(self, parameters, context, feedback): geomKey = geom.asWkb() if geomKey not in geomDict: geomDict[geomKey] = [] - geomDict[geomKey].append({'feat':feat, 'layerName':lyrName}) + geomDict[geomKey].append({"feat": feat, "layerName": lyrName}) # # Update the progress bar multiStepFeedback.setProgress(current * size) for v in geomDict.values(): if multiStepFeedback.isCanceled(): break if len(v) > 1: - flagStrList = ['{lyrName} (id={id})'.format(lyrName=featDict['layerName'], id=featDict['feat'].id()) for featDict in v] - flagStr = ', '.join(flagStrList) - flagText = self.tr('Features from coverage with same geometry: {0}.').format(flagStr) - self.flagFeature(v[0]['feat'].geometry(), flagText) + flagStrList = [ + "{lyrName} (id={id})".format( + lyrName=featDict["layerName"], id=featDict["feat"].id() + ) + for featDict in v + ] + flagStr = ", ".join(flagStrList) + flagText = self.tr( + "Features from coverage with same geometry: {0}." + ).format(flagStr) + self.flagFeature(v[0]["feat"].geometry(), flagText) return {self.FLAGS: self.flag_id} @@ -115,21 +135,21 @@ def name(self): lowercase alphanumeric characters only and no spaces or other formatting characters. """ - return 'identifyduplicatedlinesoncoverage' + return "identifyduplicatedlinesoncoverage" def displayName(self): """ Returns the translated algorithm name, which should be used for any user-visible display of the algorithm name. """ - return self.tr('Identify Duplicated Lines Between Layers') + return self.tr("Identify Duplicated Lines Between Layers") def group(self): """ Returns the name of the group this algorithm belongs to. This string should be localised. """ - return self.tr('Quality Assurance Tools (Identification Processes)') + return self.tr("Quality Assurance Tools (Identification Processes)") def groupId(self): """ @@ -139,10 +159,12 @@ def groupId(self): contain lowercase alphanumeric characters only and no spaces or other formatting characters. """ - return 'DSGTools: Quality Assurance Tools (Identification Processes)' + return "DSGTools: Quality Assurance Tools (Identification Processes)" def tr(self, string): - return QCoreApplication.translate('IdentifyDuplicatedLinesBetweenLayersAlgorithm', string) + return QCoreApplication.translate( + "IdentifyDuplicatedLinesBetweenLayersAlgorithm", string + ) def createInstance(self): return IdentifyDuplicatedLinesBetweenLayersAlgorithm() diff --git a/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/identifyDuplicatedPointsBetweenLayersAlgorithm.py b/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/identifyDuplicatedPointsBetweenLayersAlgorithm.py index 735c4175f..db27e5b4d 100644 --- a/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/identifyDuplicatedPointsBetweenLayersAlgorithm.py +++ b/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/identifyDuplicatedPointsBetweenLayersAlgorithm.py @@ -22,23 +22,30 @@ from PyQt5.QtCore import QCoreApplication -from qgis.core import (QgsDataSourceUri, QgsFeature, QgsFeatureSink, - QgsProcessing, QgsProcessingAlgorithm, - QgsProcessingException, QgsProcessingMultiStepFeedback, - QgsProcessingOutputVectorLayer, - QgsProcessingParameterBoolean, - QgsProcessingParameterFeatureSink, - QgsProcessingParameterFeatureSource, - QgsProcessingParameterMultipleLayers, - QgsProcessingParameterVectorLayer, QgsWkbTypes) +from qgis.core import ( + QgsDataSourceUri, + QgsFeature, + QgsFeatureSink, + QgsProcessing, + QgsProcessingAlgorithm, + QgsProcessingException, + QgsProcessingMultiStepFeedback, + QgsProcessingOutputVectorLayer, + QgsProcessingParameterBoolean, + QgsProcessingParameterFeatureSink, + QgsProcessingParameterFeatureSource, + QgsProcessingParameterMultipleLayers, + QgsProcessingParameterVectorLayer, + QgsWkbTypes, +) from .validationAlgorithm import ValidationAlgorithm class IdentifyDuplicatedPointsBetweenLayersAlgorithm(ValidationAlgorithm): - FLAGS = 'FLAGS' - INPUTLAYERS = 'INPUTLAYERS' - SELECTED = 'SELECTED' + FLAGS = "FLAGS" + INPUTLAYERS = "INPUTLAYERS" + SELECTED = "SELECTED" def initAlgorithm(self, config): """ @@ -46,23 +53,19 @@ def initAlgorithm(self, config): """ self.addParameter( QgsProcessingParameterMultipleLayers( - self.INPUTLAYERS, - self.tr('Point Layers'), - QgsProcessing.TypeVectorPoint + self.INPUTLAYERS, self.tr("Point Layers"), QgsProcessing.TypeVectorPoint ) ) self.addParameter( QgsProcessingParameterBoolean( - self.SELECTED, - self.tr('Process only selected features') + self.SELECTED, self.tr("Process only selected features") ) ) self.addParameter( QgsProcessingParameterFeatureSink( - self.FLAGS, - self.tr('{0} Flags').format(self.displayName()) + self.FLAGS, self.tr("{0} Flags").format(self.displayName()) ) ) @@ -73,18 +76,24 @@ def processAlgorithm(self, parameters, context, feedback): inputLyrList = self.parameterAsLayerList(parameters, self.INPUTLAYERS, context) if inputLyrList == []: - raise QgsProcessingException(self.invalidSourceError(parameters, self.INPUTLAYERS)) + raise QgsProcessingException( + self.invalidSourceError(parameters, self.INPUTLAYERS) + ) onlySelected = self.parameterAsBool(parameters, self.SELECTED, context) self.prepareFlagSink(parameters, inputLyrList[0], QgsWkbTypes.Point, context) # Compute the number of steps to display within the progress bar and # get features from source geomDict = dict() - multiStepFeedback = QgsProcessingMultiStepFeedback(len(inputLyrList)+1, feedback) + multiStepFeedback = QgsProcessingMultiStepFeedback( + len(inputLyrList) + 1, feedback + ) for currentLyrIdx, lyr in enumerate(inputLyrList): multiStepFeedback.setCurrentStep(currentLyrIdx) - featIterator, total = self.getIteratorAndFeatureCount(lyr, onlySelected=onlySelected) - size = 100/total if total else 0 - lyrName = lyr.name() + featIterator, total = self.getIteratorAndFeatureCount( + lyr, onlySelected=onlySelected + ) + size = 100 / total if total else 0 + lyrName = lyr.name() for current, feat in enumerate(featIterator): # Stop the algorithm if cancel button has been clicked if multiStepFeedback.isCanceled(): @@ -93,17 +102,24 @@ def processAlgorithm(self, parameters, context, feedback): geomKey = geom.asWkb() if geomKey not in geomDict: geomDict[geomKey] = [] - geomDict[geomKey].append({'feat':feat, 'layerName':lyrName}) + geomDict[geomKey].append({"feat": feat, "layerName": lyrName}) # # Update the progress bar multiStepFeedback.setProgress(current * size) for v in geomDict.values(): if multiStepFeedback.isCanceled(): break if len(v) > 1: - flagStrList = ['{lyrName} (id={id})'.format(lyrName=featDict['layerName'], id=featDict['feat'].id()) for featDict in v] - flagStr = ', '.join(flagStrList) - flagText = self.tr('Features from coverage with same geometry: {0}.').format(flagStr) - self.flagFeature(v[0]['feat'].geometry(), flagText) + flagStrList = [ + "{lyrName} (id={id})".format( + lyrName=featDict["layerName"], id=featDict["feat"].id() + ) + for featDict in v + ] + flagStr = ", ".join(flagStrList) + flagText = self.tr( + "Features from coverage with same geometry: {0}." + ).format(flagStr) + self.flagFeature(v[0]["feat"].geometry(), flagText) return {self.FLAGS: self.flag_id} @@ -115,21 +131,21 @@ def name(self): lowercase alphanumeric characters only and no spaces or other formatting characters. """ - return 'identifyduplicatedpointsoncoverage' + return "identifyduplicatedpointsoncoverage" def displayName(self): """ Returns the translated algorithm name, which should be used for any user-visible display of the algorithm name. """ - return self.tr('Identify Duplicated Points Between Layers') + return self.tr("Identify Duplicated Points Between Layers") def group(self): """ Returns the name of the group this algorithm belongs to. This string should be localised. """ - return self.tr('Quality Assurance Tools (Identification Processes)') + return self.tr("Quality Assurance Tools (Identification Processes)") def groupId(self): """ @@ -139,10 +155,12 @@ def groupId(self): contain lowercase alphanumeric characters only and no spaces or other formatting characters. """ - return 'DSGTools: Quality Assurance Tools (Identification Processes)' + return "DSGTools: Quality Assurance Tools (Identification Processes)" def tr(self, string): - return QCoreApplication.translate('IdentifyDuplicatedPointsBetweenLayersAlgorithm', string) + return QCoreApplication.translate( + "IdentifyDuplicatedPointsBetweenLayersAlgorithm", string + ) def createInstance(self): return IdentifyDuplicatedPointsBetweenLayersAlgorithm() diff --git a/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/identifyDuplicatedPolygonsBetweenLayersAlgorithm.py b/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/identifyDuplicatedPolygonsBetweenLayersAlgorithm.py index 04ab4e49e..f711bf72b 100644 --- a/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/identifyDuplicatedPolygonsBetweenLayersAlgorithm.py +++ b/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/identifyDuplicatedPolygonsBetweenLayersAlgorithm.py @@ -22,23 +22,30 @@ from PyQt5.QtCore import QCoreApplication -from qgis.core import (QgsDataSourceUri, QgsFeature, QgsFeatureSink, - QgsProcessing, QgsProcessingAlgorithm, - QgsProcessingException, QgsProcessingMultiStepFeedback, - QgsProcessingOutputVectorLayer, - QgsProcessingParameterBoolean, - QgsProcessingParameterFeatureSink, - QgsProcessingParameterFeatureSource, - QgsProcessingParameterMultipleLayers, - QgsProcessingParameterVectorLayer, QgsWkbTypes) +from qgis.core import ( + QgsDataSourceUri, + QgsFeature, + QgsFeatureSink, + QgsProcessing, + QgsProcessingAlgorithm, + QgsProcessingException, + QgsProcessingMultiStepFeedback, + QgsProcessingOutputVectorLayer, + QgsProcessingParameterBoolean, + QgsProcessingParameterFeatureSink, + QgsProcessingParameterFeatureSource, + QgsProcessingParameterMultipleLayers, + QgsProcessingParameterVectorLayer, + QgsWkbTypes, +) from .validationAlgorithm import ValidationAlgorithm class IdentifyDuplicatedPolygonsBetweenLayersAlgorithm(ValidationAlgorithm): - FLAGS = 'FLAGS' - INPUTLAYERS = 'INPUTLAYERS' - SELECTED = 'SELECTED' + FLAGS = "FLAGS" + INPUTLAYERS = "INPUTLAYERS" + SELECTED = "SELECTED" def initAlgorithm(self, config): """ @@ -47,22 +54,20 @@ def initAlgorithm(self, config): self.addParameter( QgsProcessingParameterMultipleLayers( self.INPUTLAYERS, - self.tr('Coverage Polygon Layers'), - QgsProcessing.TypeVectorPolygon + self.tr("Coverage Polygon Layers"), + QgsProcessing.TypeVectorPolygon, ) ) self.addParameter( QgsProcessingParameterBoolean( - self.SELECTED, - self.tr('Process only selected features') + self.SELECTED, self.tr("Process only selected features") ) ) self.addParameter( QgsProcessingParameterFeatureSink( - self.FLAGS, - self.tr('{0} Flags').format(self.displayName()) + self.FLAGS, self.tr("{0} Flags").format(self.displayName()) ) ) @@ -73,18 +78,24 @@ def processAlgorithm(self, parameters, context, feedback): inputLyrList = self.parameterAsLayerList(parameters, self.INPUTLAYERS, context) if inputLyrList == []: - raise QgsProcessingException(self.invalidSourceError(parameters, self.INPUTLAYERS)) + raise QgsProcessingException( + self.invalidSourceError(parameters, self.INPUTLAYERS) + ) onlySelected = self.parameterAsBool(parameters, self.SELECTED, context) self.prepareFlagSink(parameters, inputLyrList[0], QgsWkbTypes.Polygon, context) # Compute the number of steps to display within the progress bar and # get features from source geomDict = dict() - multiStepFeedback = QgsProcessingMultiStepFeedback(len(inputLyrList)+1, feedback) + multiStepFeedback = QgsProcessingMultiStepFeedback( + len(inputLyrList) + 1, feedback + ) for currentLyrIdx, lyr in enumerate(inputLyrList): multiStepFeedback.setCurrentStep(currentLyrIdx) - featIterator, total = self.getIteratorAndFeatureCount(lyr, onlySelected=onlySelected) - size = 100/total if total else 0 - lyrName = lyr.name() + featIterator, total = self.getIteratorAndFeatureCount( + lyr, onlySelected=onlySelected + ) + size = 100 / total if total else 0 + lyrName = lyr.name() for current, feat in enumerate(featIterator): # Stop the algorithm if cancel button has been clicked if multiStepFeedback.isCanceled(): @@ -93,17 +104,24 @@ def processAlgorithm(self, parameters, context, feedback): geomKey = geom.asWkb() if geomKey not in geomDict: geomDict[geomKey] = [] - geomDict[geomKey].append({'feat':feat, 'layerName':lyrName}) + geomDict[geomKey].append({"feat": feat, "layerName": lyrName}) # # Update the progress bar multiStepFeedback.setProgress(current * size) for v in geomDict.values(): if multiStepFeedback.isCanceled(): break if len(v) > 1: - flagStrList = ['{lyrName} (id={id})'.format(lyrName=featDict['layerName'], id=featDict['feat'].id()) for featDict in v] - flagStr = ', '.join(flagStrList) - flagText = self.tr('Features from coverage with same geometry: {0}.').format(flagStr) - self.flagFeature(v[0]['feat'].geometry(), flagText) + flagStrList = [ + "{lyrName} (id={id})".format( + lyrName=featDict["layerName"], id=featDict["feat"].id() + ) + for featDict in v + ] + flagStr = ", ".join(flagStrList) + flagText = self.tr( + "Features from coverage with same geometry: {0}." + ).format(flagStr) + self.flagFeature(v[0]["feat"].geometry(), flagText) return {self.FLAGS: self.flag_id} @@ -115,21 +133,21 @@ def name(self): lowercase alphanumeric characters only and no spaces or other formatting characters. """ - return 'identifyduplicatedpolygonsoncoverage' + return "identifyduplicatedpolygonsoncoverage" def displayName(self): """ Returns the translated algorithm name, which should be used for any user-visible display of the algorithm name. """ - return self.tr('Identify Duplicated Polygons Between Layers') + return self.tr("Identify Duplicated Polygons Between Layers") def group(self): """ Returns the name of the group this algorithm belongs to. This string should be localised. """ - return self.tr('Quality Assurance Tools (Identification Processes)') + return self.tr("Quality Assurance Tools (Identification Processes)") def groupId(self): """ @@ -139,10 +157,12 @@ def groupId(self): contain lowercase alphanumeric characters only and no spaces or other formatting characters. """ - return 'DSGTools: Quality Assurance Tools (Identification Processes)' + return "DSGTools: Quality Assurance Tools (Identification Processes)" def tr(self, string): - return QCoreApplication.translate('IdentifyDuplicatedPolygonsBetweenLayersAlgorithm', string) + return QCoreApplication.translate( + "IdentifyDuplicatedPolygonsBetweenLayersAlgorithm", string + ) def createInstance(self): return IdentifyDuplicatedPolygonsBetweenLayersAlgorithm() diff --git a/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/identifyDuplicatedVertexesAlgorithm.py b/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/identifyDuplicatedVertexesAlgorithm.py index 397322b77..ba3d35b78 100644 --- a/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/identifyDuplicatedVertexesAlgorithm.py +++ b/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/identifyDuplicatedVertexesAlgorithm.py @@ -25,21 +25,34 @@ from PyQt5.QtCore import QCoreApplication from DsgTools.core.GeometricTools.layerHandler import LayerHandler -from qgis.core import (QgsDataSourceUri, QgsFeature, QgsFeatureSink, QgsProcessing, - QgsProcessingAlgorithm, QgsProcessingException, QgsProcessingMultiStepFeedback, - QgsProcessingOutputVectorLayer, QgsProcessingParameterBoolean, QgsProcessingParameterDistance, - QgsProcessingParameterFeatureSink, QgsProcessingParameterFeatureSource, - QgsProcessingParameterField, QgsProcessingParameterVectorLayer, QgsWkbTypes, QgsProcessingFeatureSourceDefinition, - QgsFeatureRequest) +from qgis.core import ( + QgsDataSourceUri, + QgsFeature, + QgsFeatureSink, + QgsProcessing, + QgsProcessingAlgorithm, + QgsProcessingException, + QgsProcessingMultiStepFeedback, + QgsProcessingOutputVectorLayer, + QgsProcessingParameterBoolean, + QgsProcessingParameterDistance, + QgsProcessingParameterFeatureSink, + QgsProcessingParameterFeatureSource, + QgsProcessingParameterField, + QgsProcessingParameterVectorLayer, + QgsWkbTypes, + QgsProcessingFeatureSourceDefinition, + QgsFeatureRequest, +) from ...algRunner import AlgRunner from .validationAlgorithm import ValidationAlgorithm class IdentifyDuplicatedVertexesAlgorithm(ValidationAlgorithm): - FLAGS = 'FLAGS' - INPUT = 'INPUT' - SELECTED = 'SELECTED' + FLAGS = "FLAGS" + INPUT = "INPUT" + SELECTED = "SELECTED" def initAlgorithm(self, config): """ @@ -48,25 +61,20 @@ def initAlgorithm(self, config): self.addParameter( QgsProcessingParameterVectorLayer( self.INPUT, - self.tr('Input layer'), - [ - QgsProcessing.TypeVectorLine, - QgsProcessing.TypeVectorPolygon - ] + self.tr("Input layer"), + [QgsProcessing.TypeVectorLine, QgsProcessing.TypeVectorPolygon], ) ) self.addParameter( QgsProcessingParameterBoolean( - self.SELECTED, - self.tr('Process only selected features') + self.SELECTED, self.tr("Process only selected features") ) ) self.addParameter( QgsProcessingParameterFeatureSink( - self.FLAGS, - self.tr('{0} Flags').format(self.displayName()) + self.FLAGS, self.tr("{0} Flags").format(self.displayName()) ) ) @@ -75,38 +83,29 @@ def processAlgorithm(self, parameters, context, feedback): Here is where the processing itself takes place. """ algRunner = AlgRunner() - inputLyr = self.parameterAsVectorLayer( - parameters, - self.INPUT, - context - ) + inputLyr = self.parameterAsVectorLayer(parameters, self.INPUT, context) if inputLyr is None: raise QgsProcessingException( self.invalidSourceError(parameters, self.INPUT) ) - onlySelected = self.parameterAsBool( - parameters, - self.SELECTED, - context - ) + onlySelected = self.parameterAsBool(parameters, self.SELECTED, context) self.prepareFlagSink(parameters, inputLyr, QgsWkbTypes.Point, context) multiStepFeedback = QgsProcessingMultiStepFeedback(5, feedback) multiStepFeedback.setCurrentStep(0) multiStepFeedback.setProgressText(self.tr("Building aux structure...")) - usedInput = inputLyr if not onlySelected else QgsProcessingFeatureSourceDefinition( - inputLyr.id(), True) + usedInput = ( + inputLyr + if not onlySelected + else QgsProcessingFeatureSourceDefinition(inputLyr.id(), True) + ) incrementedLayer = algRunner.runAddAutoIncrementalField( - usedInput, - context, - feedback=multiStepFeedback + usedInput, context, feedback=multiStepFeedback ) multiStepFeedback.setCurrentStep(1) multiStepFeedback.setProgressText(self.tr("Extracting vertexes...")) vertexLayer = algRunner.runExtractVertices( - inputLyr=incrementedLayer, - context=context, - feedback=multiStepFeedback + inputLyr=incrementedLayer, context=context, feedback=multiStepFeedback ) multiStepFeedback.setCurrentStep(2) multiStepFeedback.setProgressText(self.tr("Building search structure...")) @@ -119,7 +118,7 @@ def processAlgorithm(self, parameters, context, feedback): self.raiseFlags(flagDict, feedback=multiStepFeedback) return {self.FLAGS: self.flag_id} - + def buildPointDict(self, inputLyr, feedback=None): featCount = inputLyr.featureCount() if featCount == 0: @@ -130,7 +129,7 @@ def buildPointDict(self, inputLyr, feedback=None): if feedback is not None and feedback.isCanceled(): break geom = feat.geometry() - pointDict[feat['featid']][geom.asWkb()].append(geom) + pointDict[feat["featid"]][geom.asWkb()].append(geom) if feedback is not None: feedback.setProgress(current * total) return pointDict @@ -159,7 +158,6 @@ def raiseFlags(self, flagSet, feedback=None): if feedback is not None: feedback.setProgress(current * size) - def name(self): """ Returns the algorithm name, used for identifying the algorithm. This @@ -168,21 +166,21 @@ def name(self): lowercase alphanumeric characters only and no spaces or other formatting characters. """ - return 'identifyduplicatedvertexesalgorithm' + return "identifyduplicatedvertexesalgorithm" def displayName(self): """ Returns the translated algorithm name, which should be used for any user-visible display of the algorithm name. """ - return self.tr('Identify Duplicated Vertexes') + return self.tr("Identify Duplicated Vertexes") def group(self): """ Returns the name of the group this algorithm belongs to. This string should be localised. """ - return self.tr('Quality Assurance Tools (Identification Processes)') + return self.tr("Quality Assurance Tools (Identification Processes)") def groupId(self): """ @@ -192,10 +190,10 @@ def groupId(self): contain lowercase alphanumeric characters only and no spaces or other formatting characters. """ - return 'DSGTools: Quality Assurance Tools (Identification Processes)' + return "DSGTools: Quality Assurance Tools (Identification Processes)" def tr(self, string): - return QCoreApplication.translate('IdentifyDuplicatedVertexesAlgorithm', string) + return QCoreApplication.translate("IdentifyDuplicatedVertexesAlgorithm", string) def createInstance(self): return IdentifyDuplicatedVertexesAlgorithm() diff --git a/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/identifyGapsAlgorithm.py b/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/identifyGapsAlgorithm.py index 81a8e228e..5f5467e70 100644 --- a/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/identifyGapsAlgorithm.py +++ b/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/identifyGapsAlgorithm.py @@ -22,28 +22,25 @@ from PyQt5.QtCore import QCoreApplication -import processing -from DsgTools.core.GeometricTools.geometryHandler import GeometryHandler -from DsgTools.core.GeometricTools.layerHandler import LayerHandler -from qgis.core import (QgsDataSourceUri, QgsFeature, QgsFeatureSink, - QgsProcessing, QgsProcessingAlgorithm, - QgsProcessingException, QgsProcessingMultiStepFeedback, - QgsProcessingOutputVectorLayer, - QgsProcessingParameterBoolean, - QgsProcessingParameterFeatureSink, - QgsProcessingParameterFeatureSource, - QgsProcessingParameterMultipleLayers, - QgsProcessingParameterVectorLayer, QgsProcessingUtils, - QgsProject, QgsWkbTypes) +from qgis.core import ( + QgsProcessing, + QgsProcessingException, + QgsProcessingMultiStepFeedback, + QgsProcessingParameterBoolean, + QgsProcessingParameterFeatureSink, + QgsProcessingParameterVectorLayer, + QgsProject, + QgsWkbTypes, +) from ...algRunner import AlgRunner from .validationAlgorithm import ValidationAlgorithm class IdentifyGapsAlgorithm(ValidationAlgorithm): - FLAGS = 'FLAGS' - INPUT = 'INPUT' - SELECTED = 'SELECTED' + FLAGS = "FLAGS" + INPUT = "INPUT" + SELECTED = "SELECTED" def initAlgorithm(self, config): """ @@ -52,53 +49,59 @@ def initAlgorithm(self, config): self.addParameter( QgsProcessingParameterVectorLayer( self.INPUT, - self.tr('Input Polygon Layer'), - [QgsProcessing.TypeVectorPolygon] + self.tr("Input Polygon Layer"), + [QgsProcessing.TypeVectorPolygon], ) ) self.addParameter( QgsProcessingParameterBoolean( - self.SELECTED, - self.tr('Process only selected features') + self.SELECTED, self.tr("Process only selected features") ) ) self.addParameter( QgsProcessingParameterFeatureSink( - self.FLAGS, - self.tr('{0} Flags').format(self.displayName()) + self.FLAGS, self.tr("{0} Flags").format(self.displayName()) ) ) - - def getGapLyr(self, inputLyr, context, multiStepFeedback, onlySelected = False): + def getGapLyr(self, inputLyr, context, multiStepFeedback, onlySelected=False): algRunner = AlgRunner() multiStepFeedback.setCurrentStep(0) - dissolvedLyr = algRunner.runDissolve(inputLyr, context, feedback=multiStepFeedback) + dissolvedLyr = algRunner.runDissolve( + inputLyr, context, feedback=multiStepFeedback + ) multiStepFeedback.setCurrentStep(1) - deletedHolesLyr = algRunner.runDeleteHoles(dissolvedLyr, context, feedback=multiStepFeedback) + deletedHolesLyr = algRunner.runDeleteHoles( + dissolvedLyr, context, feedback=multiStepFeedback + ) multiStepFeedback.setCurrentStep(2) - gapLyr = algRunner.runOverlay(deletedHolesLyr, deletedHolesLyr, context, feedback=multiStepFeedback) + gapLyr = algRunner.runOverlay( + deletedHolesLyr, deletedHolesLyr, context, feedback=multiStepFeedback + ) return gapLyr def processAlgorithm(self, parameters, context, feedback): """ Here is where the processing itself takes place. """ - geometryHandler = GeometryHandler() - layerHandler = LayerHandler() inputLyr = self.parameterAsVectorLayer(parameters, self.INPUT, context) if inputLyr is None: - raise QgsProcessingException(self.invalidSourceError(parameters, self.INPUT)) - isMulti = QgsWkbTypes.isMultiType(int(inputLyr.wkbType())) + raise QgsProcessingException( + self.invalidSourceError(parameters, self.INPUT) + ) onlySelected = self.parameterAsBool(parameters, self.SELECTED, context) self.prepareFlagSink(parameters, inputLyr, QgsWkbTypes.Polygon, context) # Compute the number of steps to display within the progress bar and # get features from source - multiStepFeedback = QgsProcessingMultiStepFeedback(4, feedback) - lyr = self.getGapLyr(inputLyr, context, multiStepFeedback, onlySelected=onlySelected) - featureList, total = self.getIteratorAndFeatureCount(lyr) #only selected is not applied because we are using an inner layer, not the original ones + multiStepFeedback = QgsProcessingMultiStepFeedback(4, feedback) + lyr = self.getGapLyr( + inputLyr, context, multiStepFeedback, onlySelected=onlySelected + ) + featureList, total = self.getIteratorAndFeatureCount( + lyr + ) # only selected is not applied because we are using an inner layer, not the original ones QgsProject.instance().removeMapLayer(lyr) geomDict = dict() @@ -108,9 +111,11 @@ def processAlgorithm(self, parameters, context, feedback): if feedback.isCanceled(): break attrList = feat.attributes() - if attrList == len(attrList)*[None]: + if attrList == len(attrList) * [None]: geom = feat.geometry() - self.flagFeature(geom, self.tr('Gap in layer {0}.').format(inputLyr.name())) + self.flagFeature( + geom, self.tr("Gap in layer {0}.").format(inputLyr.name()) + ) # # Update the progress bar multiStepFeedback.setProgress(current * total) return {self.FLAGS: self.flag_id} @@ -123,21 +128,21 @@ def name(self): lowercase alphanumeric characters only and no spaces or other formatting characters. """ - return 'identifygaps' + return "identifygaps" def displayName(self): """ Returns the translated algorithm name, which should be used for any user-visible display of the algorithm name. """ - return self.tr('Identify Gaps') + return self.tr("Identify Gaps") def group(self): """ Returns the name of the group this algorithm belongs to. This string should be localised. """ - return self.tr('Quality Assurance Tools (Identification Processes)') + return self.tr("Quality Assurance Tools (Identification Processes)") def groupId(self): """ @@ -147,10 +152,10 @@ def groupId(self): contain lowercase alphanumeric characters only and no spaces or other formatting characters. """ - return 'DSGTools: Quality Assurance Tools (Identification Processes)' + return "DSGTools: Quality Assurance Tools (Identification Processes)" def tr(self, string): - return QCoreApplication.translate('IdentifyGapsAlgorithm', string) + return QCoreApplication.translate("IdentifyGapsAlgorithm", string) def createInstance(self): return IdentifyGapsAlgorithm() diff --git a/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/identifyGapsAndOverlapsInCoverageAlgorithm.py b/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/identifyGapsAndOverlapsInCoverageAlgorithm.py index 5968f71a8..0f2dfe783 100644 --- a/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/identifyGapsAndOverlapsInCoverageAlgorithm.py +++ b/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/identifyGapsAndOverlapsInCoverageAlgorithm.py @@ -21,29 +21,39 @@ ***************************************************************************/ """ +from collections import defaultdict from PyQt5.QtCore import QCoreApplication import processing from DsgTools.core.GeometricTools.geometryHandler import GeometryHandler from DsgTools.core.GeometricTools.layerHandler import LayerHandler -from qgis.core import (QgsDataSourceUri, QgsFeature, QgsFeatureSink, - QgsProcessing, QgsProcessingAlgorithm, - QgsProcessingException, QgsProcessingOutputVectorLayer, - QgsProcessingParameterBoolean, - QgsProcessingParameterFeatureSink, - QgsProcessingParameterFeatureSource, - QgsProcessingParameterMultipleLayers, - QgsProcessingParameterVectorLayer, QgsProcessingUtils, - QgsProject, QgsWkbTypes) +from qgis.core import ( + QgsDataSourceUri, + QgsFeature, + QgsFeatureSink, + QgsProcessing, + QgsProcessingAlgorithm, + QgsProcessingException, + QgsProcessingOutputVectorLayer, + QgsProcessingParameterBoolean, + QgsProcessingParameterFeatureSink, + QgsProcessingParameterFeatureSource, + QgsProcessingParameterMultipleLayers, + QgsProcessingParameterVectorLayer, + QgsProcessingUtils, + QgsProject, + QgsWkbTypes, + QgsProcessingMultiStepFeedback +) from .validationAlgorithm import ValidationAlgorithm class IdentifyGapsAndOverlapsInCoverageAlgorithm(ValidationAlgorithm): - FLAGS = 'FLAGS' - INPUTLAYERS = 'INPUTLAYERS' - FRAMELAYER = 'FRAMELAYER' - SELECTED = 'SELECTED' + FLAGS = "FLAGS" + INPUTLAYERS = "INPUTLAYERS" + FRAMELAYER = "FRAMELAYER" + SELECTED = "SELECTED" def initAlgorithm(self, config): """ @@ -52,31 +62,29 @@ def initAlgorithm(self, config): self.addParameter( QgsProcessingParameterMultipleLayers( self.INPUTLAYERS, - self.tr('Coverage Polygon Layers'), - QgsProcessing.TypeVectorPolygon + self.tr("Coverage Polygon Layers"), + QgsProcessing.TypeVectorPolygon, ) ) self.addParameter( QgsProcessingParameterBoolean( - self.SELECTED, - self.tr('Process only selected features') + self.SELECTED, self.tr("Process only selected features") ) ) self.addParameter( QgsProcessingParameterVectorLayer( self.FRAMELAYER, - self.tr('Frame Layer'), + self.tr("Frame Layer"), [QgsProcessing.TypeVectorPolygon], - optional = True + optional=True, ) ) self.addParameter( QgsProcessingParameterFeatureSink( - self.FLAGS, - self.tr('{0} Flags').format(self.displayName()) + self.FLAGS, self.tr("{0} Flags").format(self.displayName()) ) ) @@ -88,52 +96,77 @@ def processAlgorithm(self, parameters, context, feedback): layerHandler = LayerHandler() inputLyrList = self.parameterAsLayerList(parameters, self.INPUTLAYERS, context) if inputLyrList == []: - raise QgsProcessingException(self.invalidSourceError(parameters, self.INPUTLAYERS)) + raise QgsProcessingException( + self.invalidSourceError(parameters, self.INPUTLAYERS) + ) frameLyr = self.parameterAsVectorLayer(parameters, self.FRAMELAYER, context) if frameLyr and frameLyr in inputLyrList: - raise QgsProcessingException(self.invalidSourceError(parameters, self.FRAMELAYER)) + raise QgsProcessingException( + self.invalidSourceError(parameters, self.FRAMELAYER) + ) isMulti = True for inputLyr in inputLyrList: - isMulti &= QgsWkbTypes.isMultiType(int(inputLyr.wkbType())) + isMulti &= QgsWkbTypes.isMultiType(inputLyr.wkbType()) onlySelected = self.parameterAsBool(parameters, self.SELECTED, context) self.prepareFlagSink(parameters, inputLyrList[0], QgsWkbTypes.Polygon, context) # Compute the number of steps to display within the progress bar and # get features from source - - coverage = layerHandler.createAndPopulateUnifiedVectorLayer(inputLyrList, QgsWkbTypes.Polygon, onlySelected = onlySelected) - lyr = self.overlayCoverage(coverage, context) + nSteps = 4 if not frameLyr else 5 + multiStepFeedback = QgsProcessingMultiStepFeedback(nSteps, feedback) + currentStep = 0 + multiStepFeedback.setCurrentStep(currentStep) + multiStepFeedback.setProgressText(self.tr("Creating unified layer")) + coverage = layerHandler.createAndPopulateUnifiedVectorLayer( + inputLyrList, QgsWkbTypes.Polygon, onlySelected=onlySelected, feedback=multiStepFeedback + ) + currentStep += 1 + multiStepFeedback.setCurrentStep(currentStep) + multiStepFeedback.setProgressText(self.tr("Overlaying coverage")) + lyr = self.overlayCoverage(coverage, context, feedback=multiStepFeedback) + currentStep += 1 if frameLyr: + multiStepFeedback.setCurrentStep(currentStep) + multiStepFeedback.setProgressText(self.tr("Getting gaps with geographic bounds")) self.getGapsOfCoverageWithFrame(lyr, frameLyr, context) - featureList, total = self.getIteratorAndFeatureCount(lyr) #only selected is not applied because we are using an inner layer, not the original ones - geomDict = self.getGeomDict(featureList, isMulti, feedback, total) - self.raiseFlags(geomDict, feedback) + currentStep += 1 + multiStepFeedback.setCurrentStep(currentStep) + featureList, total = self.getIteratorAndFeatureCount( + lyr + ) # only selected is not applied because we are using an inner layer, not the original ones + multiStepFeedback.setProgressText(self.tr("Raising flags")) + geomDict = self.getGeomDict(featureList, isMulti, multiStepFeedback, total) + currentStep += 1 + multiStepFeedback.setCurrentStep(currentStep) + self.raiseFlags(geomDict, multiStepFeedback) QgsProject.instance().removeMapLayer(lyr) return {self.FLAGS: self.flag_id} - def overlayCoverage(self, coverage, context): - output = QgsProcessingUtils.generateTempFilename('output.shp') + def overlayCoverage(self, coverage, context, feedback): + output = QgsProcessingUtils.generateTempFilename("output.shp") parameters = { - 'ainput':coverage, - 'atype':0, - 'binput':coverage, - 'btype':0, - 'operator':0, - 'snap':0, - '-t':False, - 'output':output, - 'GRASS_REGION_PARAMETER':None, - 'GRASS_SNAP_TOLERANCE_PARAMETER':-1, - 'GRASS_MIN_AREA_PARAMETER':0.0001, - 'GRASS_OUTPUT_TYPE_PARAMETER':0, - 'GRASS_VECTOR_DSCO':'', - 'GRASS_VECTOR_LCO':'' - } - x = processing.run('grass7:v.overlay', parameters, context = context) - lyr = QgsProcessingUtils.mapLayerFromString(x['output'], context) + "ainput": coverage, + "atype": 0, + "binput": coverage, + "btype": 0, + "operator": 0, + "snap": 0, + "-t": False, + "output": output, + "GRASS_REGION_PARAMETER": None, + "GRASS_SNAP_TOLERANCE_PARAMETER": -1, + "GRASS_MIN_AREA_PARAMETER": 0.0001, + "GRASS_OUTPUT_TYPE_PARAMETER": 0, + "GRASS_VECTOR_DSCO": "", + "GRASS_VECTOR_LCO": "", + } + x = processing.run("grass7:v.overlay", parameters, context=context, feedback=feedback) + lyr = QgsProcessingUtils.mapLayerFromString(x["output"], context) lyr.setCrs(coverage.crs()) return lyr - - def getGapsOfCoverageWithFrame(self, coverage, frameLyr, context, feedback=None, onFinish=None): + + def getGapsOfCoverageWithFrame( + self, coverage, frameLyr, context, feedback=None, onFinish=None + ): """ Identifies all gaps inside coverage layer and between coverage and frame layer. :param coverage: (QgsVectorLayer) unified coverage layer. @@ -143,22 +176,22 @@ def getGapsOfCoverageWithFrame(self, coverage, frameLyr, context, feedback=None, :param onFinish: (list-of-str) list of alg names to be executed after difference alg. """ # identify all holes in coverage layer first - coverageHolesParam = { - 'INPUT' : coverage, - 'FLAGS':'memory:', - 'SELECTED': False - } - coverageHoles = processing.run('dsgtools:identifygaps', coverageHolesParam, None, feedback, context)['FLAGS'] + coverageHolesParam = {"INPUT": coverage, "FLAGS": "memory:", "SELECTED": False} + coverageHoles = processing.run( + "dsgtools:identifygaps", coverageHolesParam, None, feedback, context + )["FLAGS"] geometryHandler = GeometryHandler() gapSet = set() for feat in coverageHoles.getFeatures(): for geom in geometryHandler.deaggregateGeometry(feat.geometry()): - self.flagFeature(geom, self.tr('Gap in coverage layer')) + self.flagFeature(geom, self.tr("Gap in coverage layer")) gapSet.add(geom) # missing possible holes between coverage and frame, but gaps in coverage may cause invalid geometries # while executing difference alg. Since its already identified, "add" them to the coverage layerHandler = LayerHandler() - filledCoverage = layerHandler.createAndPopulateUnifiedVectorLayer([coverage, coverageHoles], QgsWkbTypes.Polygon) + filledCoverage = layerHandler.createAndPopulateUnifiedVectorLayer( + [coverage, coverageHoles], QgsWkbTypes.Polygon + ) # dissolveParameters = { # 'INPUT' : filledCoverage, # 'FIELD':[], @@ -167,18 +200,20 @@ def getGapsOfCoverageWithFrame(self, coverage, frameLyr, context, feedback=None, # dissolveOutput = processing.run('native:dissolve', dissolveParameters, context = context)['OUTPUT'] dissolveOutput = LayerHandler().runGrassDissolve(filledCoverage, context) differenceParameters = { - 'INPUT' : frameLyr, - 'OVERLAY' : dissolveOutput, - 'OUTPUT':'memory:' + "INPUT": frameLyr, + "OVERLAY": dissolveOutput, + "OUTPUT": "memory:", } - differenceOutput = processing.run('native:difference', differenceParameters, onFinish, feedback, context) - for feat in differenceOutput['OUTPUT'].getFeatures(): + differenceOutput = processing.run( + "native:difference", differenceParameters, onFinish, feedback, context + ) + for feat in differenceOutput["OUTPUT"].getFeatures(): for geom in geometryHandler.deaggregateGeometry(feat.geometry()): if geom not in gapSet: - self.flagFeature(geom, self.tr('Gap in coverage with frame')) + self.flagFeature(geom, self.tr("Gap in coverage with frame")) def getGeomDict(self, featureList, isMulti, feedback, total): - geomDict = dict() + geomDict = defaultdict(list) for current, feat in enumerate(featureList): # Stop the algorithm if cancel button has been clicked if feedback.isCanceled(): @@ -187,14 +222,12 @@ def getGeomDict(self, featureList, isMulti, feedback, total): if isMulti and not geom.isMultipart(): geom.convertToMultiType() geomKey = geom.asWkb() - if geomKey not in geomDict: - geomDict[geomKey] = [] geomDict[geomKey].append(feat) # # Update the progress bar attrList = feat.attributes() - if attrList == len(attrList)*[None]: - self.flagFeature(geom, self.tr('Gap in coverage layer.')) - feedback.setProgress(int(current * total)) + if attrList == len(attrList) * [None]: + self.flagFeature(geom, self.tr("Gap in coverage layer.")) + feedback.setProgress(int(current * total)) return geomDict def raiseFlags(self, geomDict, feedback): @@ -204,9 +237,11 @@ def raiseFlags(self, geomDict, feedback): if len(v) > 1: textList = [] for feat in v: - textList += ['({0},{1})'.format(feat['a_featid'], feat['a_layer'])] - flagText = self.tr('Overlapping features (id,layer): {0}').format(', '.join(set(textList))) - self.flagFeature(v[0].geometry(), flagText) + textList += ["({0},{1})".format(feat["a_featid"], feat["a_layer"])] + flagText = self.tr("Overlapping features (id,layer): {0}").format( + ", ".join(set(textList)) + ) + self.flagFeature(v[0].geometry(), flagText) def name(self): """ @@ -216,21 +251,21 @@ def name(self): lowercase alphanumeric characters only and no spaces or other formatting characters. """ - return 'identifygapsandoverlaps' + return "identifygapsandoverlaps" def displayName(self): """ Returns the translated algorithm name, which should be used for any user-visible display of the algorithm name. """ - return self.tr('Identify Gaps and Overlaps in Coverage Layers') + return self.tr("Identify Gaps and Overlaps in Coverage Layers") def group(self): """ Returns the name of the group this algorithm belongs to. This string should be localised. """ - return self.tr('Quality Assurance Tools (Identification Processes)') + return self.tr("Quality Assurance Tools (Identification Processes)") def groupId(self): """ @@ -240,10 +275,12 @@ def groupId(self): contain lowercase alphanumeric characters only and no spaces or other formatting characters. """ - return 'DSGTools: Quality Assurance Tools (Identification Processes)' + return "DSGTools: Quality Assurance Tools (Identification Processes)" def tr(self, string): - return QCoreApplication.translate('IdentifyGapsAndOverlapsInCoverageAlgorithm', string) + return QCoreApplication.translate( + "IdentifyGapsAndOverlapsInCoverageAlgorithm", string + ) def createInstance(self): return IdentifyGapsAndOverlapsInCoverageAlgorithm() diff --git a/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/identifyGeometriesWithLargeVertexDensityAlgorithm.py b/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/identifyGeometriesWithLargeVertexDensityAlgorithm.py index 1a60618dd..882dfdc5f 100644 --- a/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/identifyGeometriesWithLargeVertexDensityAlgorithm.py +++ b/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/identifyGeometriesWithLargeVertexDensityAlgorithm.py @@ -20,27 +20,34 @@ ***************************************************************************/ """ +import os +import concurrent.futures + from collections import defaultdict -from dataclasses import dataclass from PyQt5.QtCore import QCoreApplication -from DsgTools.core.GeometricTools.layerHandler import LayerHandler -from qgis.core import (QgsDataSourceUri, QgsFeature, QgsFeatureSink, QgsProcessing, - QgsProcessingAlgorithm, QgsProcessingException, QgsProcessingMultiStepFeedback, - QgsProcessingOutputVectorLayer, QgsProcessingParameterBoolean, QgsProcessingParameterDistance, - QgsProcessingParameterFeatureSink, QgsProcessingParameterFeatureSource, - QgsProcessingParameterField, QgsProcessingParameterVectorLayer, QgsWkbTypes, QgsProcessingFeatureSourceDefinition, - QgsFeatureRequest) +from qgis.core import ( + QgsProcessing, + QgsProcessingException, + QgsProcessingMultiStepFeedback, + QgsProcessingParameterBoolean, + QgsProcessingParameterDistance, + QgsProcessingParameterFeatureSink, + QgsProcessingParameterVectorLayer, + QgsWkbTypes, + QgsProcessingFeatureSourceDefinition, + QgsFeatureRequest, +) from ...algRunner import AlgRunner from .validationAlgorithm import ValidationAlgorithm class IdentifyGeometriesWithLargeVertexDensityAlgorithm(ValidationAlgorithm): - FLAGS = 'FLAGS' - INPUT = 'INPUT' - SELECTED = 'SELECTED' - SEARCH_RADIUS = 'SEARCH_RADIUS' + FLAGS = "FLAGS" + INPUT = "INPUT" + SELECTED = "SELECTED" + SEARCH_RADIUS = "SEARCH_RADIUS" def initAlgorithm(self, config): """ @@ -49,33 +56,26 @@ def initAlgorithm(self, config): self.addParameter( QgsProcessingParameterVectorLayer( self.INPUT, - self.tr('Input layer'), - [ - QgsProcessing.TypeVectorLine, - QgsProcessing.TypeVectorPolygon - ] + self.tr("Input layer"), + [QgsProcessing.TypeVectorLine, QgsProcessing.TypeVectorPolygon], ) ) self.addParameter( QgsProcessingParameterBoolean( - self.SELECTED, - self.tr('Process only selected features') + self.SELECTED, self.tr("Process only selected features") ) ) self.addParameter( QgsProcessingParameterDistance( - self.SEARCH_RADIUS, - self.tr('Search Radius'), - defaultValue = 1.0 + self.SEARCH_RADIUS, self.tr("Search Radius"), defaultValue=1.0 ) ) self.addParameter( QgsProcessingParameterFeatureSink( - self.FLAGS, - self.tr('{0} Flags').format(self.displayName()) + self.FLAGS, self.tr("{0} Flags").format(self.displayName()) ) ) @@ -84,26 +84,14 @@ def processAlgorithm(self, parameters, context, feedback): Here is where the processing itself takes place. """ algRunner = AlgRunner() - inputLyr = self.parameterAsVectorLayer( - parameters, - self.INPUT, - context - ) + inputLyr = self.parameterAsVectorLayer(parameters, self.INPUT, context) if inputLyr is None: raise QgsProcessingException( self.invalidSourceError(parameters, self.INPUT) ) - onlySelected = self.parameterAsBool( - parameters, - self.SELECTED, - context - ) - searchRadius = self.parameterAsDouble( - parameters, - self.SEARCH_RADIUS, - context - ) - # output flag type is a polygon because the flag will be a circle with + onlySelected = self.parameterAsBool(parameters, self.SELECTED, context) + searchRadius = self.parameterAsDouble(parameters, self.SEARCH_RADIUS, context) + # output flag type is a polygon because the flag will be a circle with # radius tol and center as the vertex self.prepareFlagSink(parameters, inputLyr, QgsWkbTypes.Point, context) # Compute the number of steps to display within the progress bar and @@ -111,30 +99,31 @@ def processAlgorithm(self, parameters, context, feedback): multiStepFeedback = QgsProcessingMultiStepFeedback(5, feedback) multiStepFeedback.setCurrentStep(0) multiStepFeedback.setProgressText(self.tr("Building aux structure...")) - usedInput = inputLyr if not onlySelected else QgsProcessingFeatureSourceDefinition( - inputLyr.id(), True) + usedInput = ( + inputLyr + if not onlySelected + else QgsProcessingFeatureSourceDefinition(inputLyr.id(), True) + ) incrementedLayer = algRunner.runAddAutoIncrementalField( - usedInput, - context, - feedback=multiStepFeedback + usedInput, context, feedback=multiStepFeedback ) multiStepFeedback.setCurrentStep(1) multiStepFeedback.setProgressText(self.tr("Extracting vertexes...")) vertexLayer = algRunner.runExtractVertices( - inputLyr=incrementedLayer, - context=context, - feedback=multiStepFeedback + inputLyr=incrementedLayer, context=context, feedback=multiStepFeedback ) multiStepFeedback.setCurrentStep(2) - multiStepFeedback.setProgressText(self.tr("Building spatial index on extracted vertexes...")) + multiStepFeedback.setProgressText( + self.tr("Building spatial index on extracted vertexes...") + ) algRunner.runCreateSpatialIndex( - inputLyr=vertexLayer, - context=context, - feedback=multiStepFeedback + inputLyr=vertexLayer, context=context, feedback=multiStepFeedback ) multiStepFeedback.setCurrentStep(3) multiStepFeedback.setProgressText(self.tr("Searching close vertexes...")) - flagDict = self.getCloseVertexes(vertexLayer, searchRadius, feedback=multiStepFeedback) + flagDict = self.getCloseVertexes( + vertexLayer, searchRadius, feedback=multiStepFeedback + ) multiStepFeedback.setCurrentStep(4) multiStepFeedback.setProgressText(self.tr("Raising flags (if any)...")) self.raiseFlags(flagDict, feedback=multiStepFeedback) @@ -162,25 +151,58 @@ def raiseFlags(self, flagDict, feedback=None): feedback.setProgress(current * size) def getCloseVertexes(self, vertexLayer, searchRadius, feedback=None): - flagDict = defaultdict(set) # key: featid, value: set of vertexes + flagDict = defaultdict(set) # key: featid, value: set of vertexes featCount = vertexLayer.featureCount() if featCount == 0: return flagDict size = 100 / featCount - for current, feat in enumerate(vertexLayer.getFeatures()): - if feedback is not None and feedback.isCanceled(): - break + multiStepFeedback = QgsProcessingMultiStepFeedback(2, feedback) + multiStepFeedback.setCurrentStep(0) + multiStepFeedback.setProgressText(self.tr("Submitting to thread")) + def compute(feat): + outputDict = defaultdict(set) + if feedback.isCanceled(): + return None geom = feat.geometry() buffer = geom.buffer(searchRadius, -1) bufferBB = buffer.boundingBox() - request = QgsFeatureRequest().setFilterExpression(f"featid = {feat['featid']}").setFilterRect(bufferBB) + request = ( + QgsFeatureRequest() + .setFilterExpression(f"featid = {feat['featid']}") + .setFilterRect(bufferBB) + ) + if "vertex_part_ring" in feat: + request.setFilterExpression(f"vertex_part_ring = {feat['vertex_part_ring']}") for candidateFeat in vertexLayer.getFeatures(request): - if candidateFeat.id() == feat.id() or candidateFeat.geometry() in flagDict[feat["featid"]]: + if candidateFeat.id() == feat.id(): continue - if candidateFeat.geometry().intersects(buffer): - flagDict[feat["featid"]].add(geom.asWkb()) - if feedback is not None: - feedback.setProgress(size * current) + candidateGeom = candidateFeat.geometry() + if candidateFeat.geometry().intersects( + buffer + ) and not candidateGeom.equals(geom): + outputDict[feat["featid"]].add(candidateGeom.asWkb()) + return outputDict + pool = concurrent.futures.ThreadPoolExecutor(max_workers=os.cpu_count() - 1) + futures = set() + + for current, feat in enumerate(vertexLayer.getFeatures()): + if feedback is not None and feedback.isCanceled(): + break + futures.add(pool.submit(compute, feat)) + if multiStepFeedback is not None: + multiStepFeedback.setProgress(size * current) + multiStepFeedback.setCurrentStep(1) + multiStepFeedback.setProgressText(self.tr("Evaluating Results")) + + for current, future in enumerate(concurrent.futures.as_completed(futures)): + if feedback.isCanceled(): + return None + output = future.result() + if output is None: + continue + for featid, geomSet in output.items(): + flagDict[featid] = flagDict[featid].union(geomSet) + multiStepFeedback.setProgress(size * current) return flagDict def name(self): @@ -191,21 +213,21 @@ def name(self): lowercase alphanumeric characters only and no spaces or other formatting characters. """ - return 'identifygeometrieswithlargevertexdensityalgorithm' + return "identifygeometrieswithlargevertexdensityalgorithm" def displayName(self): """ Returns the translated algorithm name, which should be used for any user-visible display of the algorithm name. """ - return self.tr('Identify Geometries With Large Vertex Density') + return self.tr("Identify Geometries With Large Vertex Density") def group(self): """ Returns the name of the group this algorithm belongs to. This string should be localised. """ - return self.tr('Quality Assurance Tools (Identification Processes)') + return self.tr("Quality Assurance Tools (Identification Processes)") def groupId(self): """ @@ -215,10 +237,12 @@ def groupId(self): contain lowercase alphanumeric characters only and no spaces or other formatting characters. """ - return 'DSGTools: Quality Assurance Tools (Identification Processes)' + return "DSGTools: Quality Assurance Tools (Identification Processes)" def tr(self, string): - return QCoreApplication.translate('IdentifyGeometriesWithLargeVertexDensityAlgorithm', string) + return QCoreApplication.translate( + "IdentifyGeometriesWithLargeVertexDensityAlgorithm", string + ) def createInstance(self): return IdentifyGeometriesWithLargeVertexDensityAlgorithm() diff --git a/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/identifyInvalidAttributeCombinationsAlgorithm.py b/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/identifyInvalidAttributeCombinationsAlgorithm.py index 56837c301..fa502a2e4 100644 --- a/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/identifyInvalidAttributeCombinationsAlgorithm.py +++ b/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/identifyInvalidAttributeCombinationsAlgorithm.py @@ -24,29 +24,39 @@ import processing from DsgTools.core.GeometricTools.layerHandler import LayerHandler -from qgis.core import (QgsDataSourceUri, QgsFeature, QgsFeatureSink, - QgsGeometry, QgsProcessing, QgsProcessingAlgorithm, - QgsProcessingException, QgsProcessingMultiStepFeedback, - QgsProcessingOutputVectorLayer, - QgsProcessingParameterBoolean, - QgsProcessingParameterDefinition, - QgsProcessingParameterDistance, - QgsProcessingParameterEnum, - QgsProcessingParameterFeatureSink, - QgsProcessingParameterFeatureSource, - QgsProcessingParameterField, - QgsProcessingParameterMultipleLayers, - QgsProcessingParameterNumber, - QgsProcessingParameterType, - QgsProcessingParameterVectorLayer, QgsProcessingUtils, - QgsSpatialIndex, QgsWkbTypes) +from qgis.core import ( + QgsDataSourceUri, + QgsFeature, + QgsFeatureSink, + QgsGeometry, + QgsProcessing, + QgsProcessingAlgorithm, + QgsProcessingException, + QgsProcessingMultiStepFeedback, + QgsProcessingOutputVectorLayer, + QgsProcessingParameterBoolean, + QgsProcessingParameterDefinition, + QgsProcessingParameterDistance, + QgsProcessingParameterEnum, + QgsProcessingParameterFeatureSink, + QgsProcessingParameterFeatureSource, + QgsProcessingParameterField, + QgsProcessingParameterMultipleLayers, + QgsProcessingParameterNumber, + QgsProcessingParameterType, + QgsProcessingParameterVectorLayer, + QgsProcessingUtils, + QgsSpatialIndex, + QgsWkbTypes, +) from ...algRunner import AlgRunner from .validationAlgorithm import ValidationAlgorithm + class IdentifyInvalidAttributeCombinationsAlgorithm(ValidationAlgorithm): - ATTRIBUTE_RULES = 'ATTRIBUTE_RULES' - BEHAVIOR = 'BEHAVIOR' + ATTRIBUTE_RULES = "ATTRIBUTE_RULES" + BEHAVIOR = "BEHAVIOR" def initAlgorithm(self, config): """ @@ -54,31 +64,31 @@ def initAlgorithm(self, config): """ hierarchy = ParameterAttributeRules( - self.ATTRIBUTE_RULES, - description=self.tr('Attribute Rules') - ) - hierarchy.setMetadata({ - 'widget_wrapper': 'DsgTools.gui.ProcessingUI.attributeRulesWrapper.AttributeRulesWrapper' - }) + self.ATTRIBUTE_RULES, description=self.tr("Attribute Rules") + ) + hierarchy.setMetadata( + { + "widget_wrapper": "DsgTools.gui.ProcessingUI.attributeRulesWrapper.AttributeRulesWrapper" + } + ) self.addParameter(hierarchy) - self.modes = [self.tr('Prefer aligning nodes, insert extra vertices where required'), - self.tr('Prefer closest point, insert extra vertices where required'), - self.tr('Prefer aligning nodes, don\'t insert new vertices'), - self.tr('Prefer closest point, don\'t insert new vertices'), - self.tr('Move end points only, prefer aligning nodes'), - self.tr('Move end points only, prefer closest point'), - self.tr('Snap end points to end points only')] + self.modes = [ + self.tr("Prefer aligning nodes, insert extra vertices where required"), + self.tr("Prefer closest point, insert extra vertices where required"), + self.tr("Prefer aligning nodes, don't insert new vertices"), + self.tr("Prefer closest point, don't insert new vertices"), + self.tr("Move end points only, prefer aligning nodes"), + self.tr("Move end points only, prefer closest point"), + self.tr("Snap end points to end points only"), + ] self.addParameter( QgsProcessingParameterEnum( - self.BEHAVIOR, - self.tr('Behavior'), - options=self.modes, - defaultValue=0 + self.BEHAVIOR, self.tr("Behavior"), options=self.modes, defaultValue=0 ) ) - + def parameterAsAttributeRules(self, parameters, name, context): return parameters[name] @@ -87,37 +97,39 @@ def processAlgorithm(self, parameters, context, feedback): Here is where the processing itself takes place. """ layerHandler = LayerHandler() - snapDict = self.parameterAsSnapHierarchy(parameters, self.SNAP_HIERARCHY, context) + snapDict = self.parameterAsSnapHierarchy( + parameters, self.SNAP_HIERARCHY, context + ) onlySelected = self.parameterAsBool(parameters, self.SELECTED, context) behavior = self.parameterAsEnum(parameters, self.BEHAVIOR, context) nSteps = 0 for item in snapDict: - nSteps += len(item['snapLayerList']) + nSteps += len(item["snapLayerList"]) currStep = 0 multiStepFeedback = QgsProcessingMultiStepFeedback(nSteps, feedback) for current, item in enumerate(snapDict): - refLyr = item['referenceLayer'] - for i, lyr in enumerate(item['snapLayerList']): + refLyr = item["referenceLayer"] + for i, lyr in enumerate(item["snapLayerList"]): if multiStepFeedback.isCanceled(): break multiStepFeedback.setCurrentStep(currStep) multiStepFeedback.pushInfo( - self.tr('Snapping geometries from layer {input} to {reference} with snap {snap}...').format( - input=lyr.name(), - reference=refLyr.name(), - snap=item['snap'] - ) + self.tr( + "Snapping geometries from layer {input} to {reference} with snap {snap}..." + ).format( + input=lyr.name(), reference=refLyr.name(), snap=item["snap"] ) + ) layerHandler.snapToLayer( lyr, refLyr, - item['snap'], + item["snap"], behavior, onlySelected=onlySelected, - feedback=multiStepFeedback - ) + feedback=multiStepFeedback, + ) currStep += 1 return {} @@ -129,21 +141,21 @@ def name(self): lowercase alphanumeric characters only and no spaces or other formatting characters. """ - return 'identifyinvalidattributecombinations' + return "identifyinvalidattributecombinations" def displayName(self): """ Returns the translated algorithm name, which should be used for any user-visible display of the algorithm name. """ - return self.tr('Identify Invalid Attribute Combinations') + return self.tr("Identify Invalid Attribute Combinations") def group(self): """ Returns the name of the group this algorithm belongs to. This string should be localised. """ - return self.tr('Quality Assurance Tools (Identification Processes)') + return self.tr("Quality Assurance Tools (Identification Processes)") def groupId(self): """ @@ -153,37 +165,44 @@ def groupId(self): contain lowercase alphanumeric characters only and no spaces or other formatting characters. """ - return 'DSGTools: Quality Assurance Tools (Identification Processes)' + return "DSGTools: Quality Assurance Tools (Identification Processes)" def tr(self, string): - return QCoreApplication.translate('IdentifyInvalidAttributeCombinationsAlgorithm', string) + return QCoreApplication.translate( + "IdentifyInvalidAttributeCombinationsAlgorithm", string + ) def createInstance(self): return IdentifyInvalidAttributeCombinationsAlgorithm() -class ParameterAttributeRulesType(QgsProcessingParameterType): +class ParameterAttributeRulesType(QgsProcessingParameterType): def __init__(self): super().__init__() def create(self, name): - return ParameterAttributeRules(name) #mudar + return ParameterAttributeRules(name) # mudar def metadata(self): - return {'widget_wrapper': 'DSGTools.gui.ProcessingUI.attributeRulesWrapper.AttributeRulesWrapper'} #mudar + return { + "widget_wrapper": "DSGTools.gui.ProcessingUI.attributeRulesWrapper.AttributeRulesWrapper" + } # mudar def name(self): - return QCoreApplication.translate('Processing', 'Attribute Rules') + return QCoreApplication.translate("Processing", "Attribute Rules") def id(self): - return 'attribute_rules' + return "attribute_rules" def description(self): - return QCoreApplication.translate('Processing', 'An attribute rules type. Used in the Identify Invalid Attribute Combinations algorithm.') + return QCoreApplication.translate( + "Processing", + "An attribute rules type. Used in the Identify Invalid Attribute Combinations algorithm.", + ) -class ParameterAttributeRules(QgsProcessingParameterDefinition): - def __init__(self, name, description=''): +class ParameterAttributeRules(QgsProcessingParameterDefinition): + def __init__(self, name, description=""): super().__init__(name, description) def clone(self): @@ -195,7 +214,7 @@ def type(self): @staticmethod def typeName(): - return 'attribute_rules' + return "attribute_rules" def checkValueIsAcceptable(self, value, context=None): # if not isinstance(value, list): diff --git a/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/identifyInvalidSpatialRelationshipAlgorithm.py b/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/identifyInvalidSpatialRelationshipAlgorithm.py index 297f2f8b0..c62c67cd3 100644 --- a/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/identifyInvalidSpatialRelationshipAlgorithm.py +++ b/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/identifyInvalidSpatialRelationshipAlgorithm.py @@ -23,33 +23,40 @@ from PyQt5.QtCore import QCoreApplication from DsgTools.core.GeometricTools.layerHandler import LayerHandler -from qgis.core import (QgsDataSourceUri, QgsFeature, QgsFeatureSink, - QgsProcessing, QgsProcessingAlgorithm, - QgsProcessingException, QgsProcessingMultiStepFeedback, - QgsProcessingOutputVectorLayer, - QgsProcessingParameterBoolean, - QgsProcessingParameterFeatureSink, - QgsProcessingParameterFeatureSource, - QgsProcessingParameterField, - QgsProcessingParameterVectorLayer, QgsWkbTypes) +from qgis.core import ( + QgsDataSourceUri, + QgsFeature, + QgsFeatureSink, + QgsProcessing, + QgsProcessingAlgorithm, + QgsProcessingException, + QgsProcessingMultiStepFeedback, + QgsProcessingOutputVectorLayer, + QgsProcessingParameterBoolean, + QgsProcessingParameterFeatureSink, + QgsProcessingParameterFeatureSource, + QgsProcessingParameterField, + QgsProcessingParameterVectorLayer, + QgsWkbTypes, +) from ...algRunner import AlgRunner from .validationAlgorithm import ValidationAlgorithm class IdentifyInvalidSpatialRelationshipAlgorithm(ValidationAlgorithm): - FLAGS = 'FLAGS' - INPUT_A = 'INPUT_A' - SELECTED_A = 'SELECTED_A' - EXPRESSION_A = 'EXPRESSION_A' - GROUPBY_A = 'GROUPBY_A' - PREDICATE = 'PREDICATE' - INPUT_B = 'INPUT_B' - EXPRESSION_B = 'EXPRESSION_B' - SELECTED_B = 'SELECTED_B' - GROUPBY_B = 'GROUPBY_B' - MIN_CASES = 'MIN_CASES' - MAX_CASES = 'MAX_CASES' + FLAGS = "FLAGS" + INPUT_A = "INPUT_A" + SELECTED_A = "SELECTED_A" + EXPRESSION_A = "EXPRESSION_A" + GROUPBY_A = "GROUPBY_A" + PREDICATE = "PREDICATE" + INPUT_B = "INPUT_B" + EXPRESSION_B = "EXPRESSION_B" + SELECTED_B = "SELECTED_B" + GROUPBY_B = "GROUPBY_B" + MIN_CASES = "MIN_CASES" + MAX_CASES = "MAX_CASES" FEATID_ON_GROUPBY = FEATID_ON_GROUPBY def initAlgorithm(self, config): @@ -59,64 +66,59 @@ def initAlgorithm(self, config): self.addParameter( QgsProcessingParameterVectorLayer( self.INPUT_A, - self.tr('Input layer'), - [QgsProcessing.TypeVectorAnyGeometry] + self.tr("Input layer"), + [QgsProcessing.TypeVectorAnyGeometry], ) ) self.addParameter( QgsProcessingParameterBoolean( - self.SELECTED_A, - self.tr('Process only selected features from input') + self.SELECTED_A, self.tr("Process only selected features from input") ) ) self.addParameter( QgsProcessingParameterExpression( - self.EXPRESSION_A, - self.tr('Filter expression for input'), - None, - 'INPUT_A', - optional = True + self.EXPRESSION_A, + self.tr("Filter expression for input"), + None, + "INPUT_A", + optional=True, ) ) self.predicates = [ - self.tr('Prefer aligning nodes, insert extra vertices where required'), - self.tr('Prefer closest point, insert extra vertices where required'), - self.tr('Prefer aligning nodes, don\'t insert new vertices'), - self.tr('Prefer closest point, don\'t insert new vertices'), - self.tr('Move end points only, prefer aligning nodes'), - self.tr('Move end points only, prefer closest point'), - self.tr('Snap end points to end points only') - ] + self.tr("Prefer aligning nodes, insert extra vertices where required"), + self.tr("Prefer closest point, insert extra vertices where required"), + self.tr("Prefer aligning nodes, don't insert new vertices"), + self.tr("Prefer closest point, don't insert new vertices"), + self.tr("Move end points only, prefer aligning nodes"), + self.tr("Move end points only, prefer closest point"), + self.tr("Snap end points to end points only"), + ] self.addParameter( QgsProcessingParameterEnum( - self.BEHAVIOR, - self.tr('Behavior'), - options=self.modes, - defaultValue=0 + self.BEHAVIOR, self.tr("Behavior"), options=self.modes, defaultValue=0 ) ) self.addParameter( QgsProcessingParameterBoolean( self.IGNORE_VIRTUAL_FIELDS, - self.tr('Ignore virtual fields'), - defaultValue=True + self.tr("Ignore virtual fields"), + defaultValue=True, ) ) self.addParameter( QgsProcessingParameterBoolean( self.IGNORE_PK_FIELDS, - self.tr('Ignore primary key fields'), - defaultValue=True + self.tr("Ignore primary key fields"), + defaultValue=True, ) ) self.addParameter( QgsProcessingParameterFeatureSink( - self.FLAGS, - self.tr('{0} Flags').format(self.displayName()) + self.FLAGS, self.tr("{0} Flags").format(self.displayName()) ) ) @@ -127,24 +129,37 @@ def processAlgorithm(self, parameters, context, feedback): layerHandler = LayerHandler() inputLyr = self.parameterAsVectorLayer(parameters, self.INPUT, context) if inputLyr is None: - raise QgsProcessingException(self.invalidSourceError(parameters, self.INPUT)) + raise QgsProcessingException( + self.invalidSourceError(parameters, self.INPUT) + ) onlySelected = self.parameterAsBool(parameters, self.SELECTED, context) - attributeBlackList = self.parameterAsFields(parameters, self.ATTRIBUTE_BLACK_LIST, context) - ignoreVirtual = self.parameterAsBool(parameters, self.IGNORE_VIRTUAL_FIELDS, context) + attributeBlackList = self.parameterAsFields( + parameters, self.ATTRIBUTE_BLACK_LIST, context + ) + ignoreVirtual = self.parameterAsBool( + parameters, self.IGNORE_VIRTUAL_FIELDS, context + ) ignorePK = self.parameterAsBool(parameters, self.IGNORE_PK_FIELDS, context) self.prepareFlagSink(parameters, inputLyr, inputLyr.wkbType(), context) # Compute the number of steps to display within the progress bar and # get features from source multiStepFeedback = QgsProcessingMultiStepFeedback(2, feedback) multiStepFeedback.setCurrentStep(0) - geomDict = layerHandler.getDuplicatedFeaturesDict(inputLyr, onlySelected=onlySelected, attributeBlackList=attributeBlackList, excludePrimaryKeys=ignorePK, ignoreVirtualFields=ignoreVirtual, feedback=multiStepFeedback) + geomDict = layerHandler.getDuplicatedFeaturesDict( + inputLyr, + onlySelected=onlySelected, + attributeBlackList=attributeBlackList, + excludePrimaryKeys=ignorePK, + ignoreVirtualFields=ignoreVirtual, + feedback=multiStepFeedback, + ) multiStepFeedback.setCurrentStep(1) self.raiseDuplicatedFeaturesFlags(inputLyr, geomDict, multiStepFeedback) return {self.FLAGS: self.flag_id} def raiseDuplicatedFeaturesFlags(self, inputLyr, geomDict, feedback): - size = 100/len(geomDict) if geomDict else 0 + size = 100 / len(geomDict) if geomDict else 0 for current, attrDict in enumerate(geomDict.values()): if feedback.isCanceled(): break @@ -152,8 +167,10 @@ def raiseDuplicatedFeaturesFlags(self, inputLyr, geomDict, feedback): if feedback.isCanceled(): break if len(featList) > 1: - idStrList = ','.join(map(str, [feat.id() for feat in featList])) - flagText = self.tr('Features from layer {0} with ids=({1}) have the same set of attributes.').format(inputLyr.name(), idStrList) + idStrList = ",".join(map(str, [feat.id() for feat in featList])) + flagText = self.tr( + "Features from layer {0} with ids=({1}) have the same set of attributes." + ).format(inputLyr.name(), idStrList) self.flagFeature(featList[0].geometry(), flagText) feedback.setProgress(size * current) @@ -165,21 +182,21 @@ def name(self): lowercase alphanumeric characters only and no spaces or other formatting characters. """ - return 'identifyinvalidspatialrelationship' + return "identifyinvalidspatialrelationship" def displayName(self): """ Returns the translated algorithm name, which should be used for any user-visible display of the algorithm name. """ - return self.tr('Identify Invalid Spatial Relationship Features') + return self.tr("Identify Invalid Spatial Relationship Features") def group(self): """ Returns the name of the group this algorithm belongs to. This string should be localised. """ - return self.tr('Quality Assurance Tools (Identification Processes)') + return self.tr("Quality Assurance Tools (Identification Processes)") def groupId(self): """ @@ -189,10 +206,12 @@ def groupId(self): contain lowercase alphanumeric characters only and no spaces or other formatting characters. """ - return 'DSGTools: Quality Assurance Tools (Identification Processes)' + return "DSGTools: Quality Assurance Tools (Identification Processes)" def tr(self, string): - return QCoreApplication.translate('IdentifyInvalidSpatialRelationshipAlgorithm', string) + return QCoreApplication.translate( + "IdentifyInvalidSpatialRelationshipAlgorithm", string + ) def createInstance(self): return IdentifyInvalidSpatialRelationshipAlgorithm() diff --git a/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/identifyInvalidUUIDsAlgorithm.py b/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/identifyInvalidUUIDsAlgorithm.py index e5806db98..33be03ee0 100644 --- a/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/identifyInvalidUUIDsAlgorithm.py +++ b/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/identifyInvalidUUIDsAlgorithm.py @@ -22,13 +22,18 @@ import uuid -from qgis.core import (QgsField, QgsFields, QgsProcessing, - QgsProcessingParameterBoolean, - QgsFeature, - QgsGeometry, - QgsProcessingParameterFeatureSink, - QgsProcessingParameterMultipleLayers, - QgsProcessingParameterString, QgsWkbTypes) +from qgis.core import ( + QgsField, + QgsFields, + QgsProcessing, + QgsProcessingParameterBoolean, + QgsFeature, + QgsGeometry, + QgsProcessingParameterFeatureSink, + QgsProcessingParameterMultipleLayers, + QgsProcessingParameterString, + QgsWkbTypes, +) from qgis.PyQt.QtCore import QCoreApplication, QVariant from .validationAlgorithm import ValidationAlgorithm @@ -36,11 +41,11 @@ class IdentifyInvalidUUIDsAlgorithm(ValidationAlgorithm): - INPUT_LAYERS = 'INPUT_LAYERS' - ATTRIBUTE_NAME = 'ATTRIBUTE_NAME' - CORRECT = 'CORRECT' - COMPARE_LAYER = 'COMPARE_LAYER' - OUTPUT = 'OUTPUT' + INPUT_LAYERS = "INPUT_LAYERS" + ATTRIBUTE_NAME = "ATTRIBUTE_NAME" + CORRECT = "CORRECT" + COMPARE_LAYER = "COMPARE_LAYER" + OUTPUT = "OUTPUT" def __init__(self): super().__init__() @@ -49,64 +54,58 @@ def initAlgorithm(self, config): self.addParameter( QgsProcessingParameterMultipleLayers( self.INPUT_LAYERS, - self.tr('Input layer(s)'), - QgsProcessing.TypeVectorAnyGeometry + self.tr("Input layer(s)"), + QgsProcessing.TypeVectorAnyGeometry, ) ) self.addParameter( QgsProcessingParameterString( self.ATTRIBUTE_NAME, - description = self.tr('Attribute name'), + description=self.tr("Attribute name"), ) ) - self.addParameter( - QgsProcessingParameterBoolean( - self.CORRECT, - self.tr('Fix?') - ) - ) + self.addParameter(QgsProcessingParameterBoolean(self.CORRECT, self.tr("Fix?"))) self.addParameter( QgsProcessingParameterBoolean( - self.COMPARE_LAYER, - self.tr('Compare only within same layer?') + self.COMPARE_LAYER, self.tr("Compare only within same layer?") ) ) self.addParameter( - QgsProcessingParameterFeatureSink( - self.OUTPUT, - self.tr('Flags') - ) + QgsProcessingParameterFeatureSink(self.OUTPUT, self.tr("Flags")) ) def getAttributeIndex(self, attributeName, layer): - for attrName, attrAlias in list(layer.attributeAliases().items()): - if not(attributeName in [attrName, attrAlias]): + for attrName, attrAlias in list(layer.attributeAliases().items()): + if not (attributeName in [attrName, attrAlias]): continue if layer.fields().indexOf(attrName) < 0: return layer.fields().indexOf(attrAlias) - return layer.fields().indexOf(attrName) + return layer.fields().indexOf(attrName) return -1 def getFlagGeometry(self, feature): - if QgsWkbTypes.geometryType(feature.geometry().wkbType()) == QgsWkbTypes.LineGeometry: + if ( + QgsWkbTypes.geometryType(feature.geometry().wkbType()) + == QgsWkbTypes.LineGeometry + ): multiPoints = feature.geometry().convertToType(0, True) pointList = multiPoints.asMultiPoint() - return QgsGeometry.fromPointXY(pointList[int(len(pointList)/2)]) + return QgsGeometry.fromPointXY(pointList[int(len(pointList) / 2)]) else: return feature.geometry().centroid() - def createFlagLayer(self, parameters, context ,crs): + def createFlagLayer(self, parameters, context, crs): return self.parameterAsSink( parameters, self.OUTPUT, context, self.getFlagFields(), self.getFlagWkbType(), - crs + crs, ) def createFlagFeature(self, attributes, geometry): @@ -117,35 +116,19 @@ def createFlagFeature(self, attributes, geometry): return feat def processAlgorithm(self, parameters, context, feedback): - inputLyrList = self.parameterAsLayerList( - parameters, - self.INPUT_LAYERS, - context - ) - attributeName = self.parameterAsFile( - parameters, - self.ATTRIBUTE_NAME, - context - ) - correct = self.parameterAsBool( - parameters, - self.CORRECT, - context - ) - compare_layer = self.parameterAsBool( - parameters, - self.COMPARE_LAYER, - context - ) + inputLyrList = self.parameterAsLayerList(parameters, self.INPUT_LAYERS, context) + attributeName = self.parameterAsFile(parameters, self.ATTRIBUTE_NAME, context) + correct = self.parameterAsBool(parameters, self.CORRECT, context) + compare_layer = self.parameterAsBool(parameters, self.COMPARE_LAYER, context) - output_dest_id = '' + output_dest_id = "" uuids = {} errors = [] listSize = len(inputLyrList) - progressStep = 100/listSize if listSize else 0 + progressStep = 100 / listSize if listSize else 0 for step, layer in enumerate(inputLyrList): - layer_name = layer.name() if compare_layer else 'single_layer' - if not(layer_name in uuids): + layer_name = layer.name() if compare_layer else "single_layer" + if not (layer_name in uuids): uuids[layer_name] = [] attributeIndex = self.getAttributeIndex(attributeName, layer) if attributeIndex < 0: @@ -157,7 +140,9 @@ def processAlgorithm(self, parameters, context, feedback): return {self.OUTPUT: output_dest_id} attributeValue = feature[attributeIndex] isValidUuid = self.isValidUuid(attributeValue) - hasDuplicateValues = self.hasDuplicateValues(attributeValue, uuids[layer_name]) + hasDuplicateValues = self.hasDuplicateValues( + attributeValue, uuids[layer_name] + ) if isValidUuid and not hasDuplicateValues: uuids[layer_name].append(attributeValue) continue @@ -166,24 +151,32 @@ def processAlgorithm(self, parameters, context, feedback): layer.updateFeature(feature) continue [ - errors.append({ - 'geometry': self.getFlagGeometry(feature), - 'fields' : {'erro': descr, 'classe': layer.name(), 'feature_id': feature.id()} - }) + errors.append( + { + "geometry": self.getFlagGeometry(feature), + "fields": { + "erro": descr, + "classe": layer.name(), + "feature_id": feature.id(), + }, + } + ) for descr, hasError in [ - ('uuid inválido', not isValidUuid), - ('uuid duplicado', hasDuplicateValues) + ("uuid inválido", not isValidUuid), + ("uuid duplicado", hasDuplicateValues), ] if hasError ] - feedback.setProgress(step*progressStep) - + feedback.setProgress(step * progressStep) + crs = inputLyrList[0].sourceCrs() if not correct and len(errors) > 0: - (output_sink, output_dest_id) = self.createFlagLayer(parameters, context, crs) + (output_sink, output_dest_id) = self.createFlagLayer( + parameters, context, crs + ) for error in errors: output_sink.addFeature( - self.createFlagFeature(error['fields'], error['geometry']) + self.createFlagFeature(error["fields"], error["geometry"]) ) return {self.OUTPUT: output_dest_id} @@ -192,9 +185,9 @@ def getFlagWkbType(self): def getFlagFields(self): sinkFields = QgsFields() - sinkFields.append(QgsField('erro', QVariant.String)) - sinkFields.append(QgsField('classe', QVariant.String)) - sinkFields.append(QgsField('feature_id', QVariant.Int)) + sinkFields.append(QgsField("erro", QVariant.String)) + sinkFields.append(QgsField("classe", QVariant.String)) + sinkFields.append(QgsField("feature_id", QVariant.Int)) return sinkFields def hasDuplicateValues(self, value, valueList): @@ -207,7 +200,6 @@ def isValidUuid(self, uuidToTest, version=4): return False return str(uuidObj) == uuidToTest - def name(self): """ Returns the algorithm name, used for identifying the algorithm. This @@ -216,7 +208,7 @@ def name(self): lowercase alphanumeric characters only and no spaces or other formatting characters. """ - return 'identifyinvaliduuidsalgorithm' + return "identifyinvaliduuidsalgorithm" def displayName(self): """ @@ -230,7 +222,7 @@ def group(self): Returns the name of the group this algorithm belongs to. This string should be localised. """ - return self.tr('Quality Assurance Tools (Identification Processes)') + return self.tr("Quality Assurance Tools (Identification Processes)") def groupId(self): """ @@ -240,10 +232,10 @@ def groupId(self): contain lowercase alphanumeric characters only and no spaces or other formatting characters. """ - return 'DSGTools: Quality Assurance Tools (Identification Processes)' + return "DSGTools: Quality Assurance Tools (Identification Processes)" def tr(self, string): - return QCoreApplication.translate('IdentifyInvalidUUIDsAlgorithm', string) + return QCoreApplication.translate("IdentifyInvalidUUIDsAlgorithm", string) def createInstance(self): return IdentifyInvalidUUIDsAlgorithm() diff --git a/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/identifyMultiPartGeometriesAlgorithm.py b/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/identifyMultiPartGeometriesAlgorithm.py index f9e69f0e8..fa11d3edd 100644 --- a/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/identifyMultiPartGeometriesAlgorithm.py +++ b/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/identifyMultiPartGeometriesAlgorithm.py @@ -27,24 +27,35 @@ import concurrent.futures from DsgTools.core.GeometricTools.geometryHandler import GeometryHandler from DsgTools.core.GeometricTools.layerHandler import LayerHandler -from qgis.core import (QgsDataSourceUri, QgsFeature, QgsFeatureSink, - QgsProcessing, QgsProcessingAlgorithm, - QgsProcessingException, QgsProcessingMultiStepFeedback, - QgsProcessingOutputVectorLayer, - QgsProcessingParameterBoolean, - QgsProcessingParameterFeatureSink, - QgsProcessingParameterFeatureSource, - QgsProcessingParameterMultipleLayers, - QgsProcessingParameterVectorLayer, QgsProcessingUtils, - QgsProject, QgsWkbTypes, QgsProcessingFeatureSourceDefinition, QgsExpression, QgsFeatureRequest) +from qgis.core import ( + QgsDataSourceUri, + QgsFeature, + QgsFeatureSink, + QgsProcessing, + QgsProcessingAlgorithm, + QgsProcessingException, + QgsProcessingMultiStepFeedback, + QgsProcessingOutputVectorLayer, + QgsProcessingParameterBoolean, + QgsProcessingParameterFeatureSink, + QgsProcessingParameterFeatureSource, + QgsProcessingParameterMultipleLayers, + QgsProcessingParameterVectorLayer, + QgsProcessingUtils, + QgsProject, + QgsWkbTypes, + QgsProcessingFeatureSourceDefinition, + QgsExpression, + QgsFeatureRequest, +) from .validationAlgorithm import ValidationAlgorithm class IdentifyMultiPartGeometriesAlgorithm(ValidationAlgorithm): - FLAGS = 'FLAGS' - INPUT = 'INPUT' - SELECTED = 'SELECTED' + FLAGS = "FLAGS" + INPUT = "INPUT" + SELECTED = "SELECTED" def initAlgorithm(self, config): """ @@ -53,24 +64,22 @@ def initAlgorithm(self, config): self.addParameter( QgsProcessingParameterVectorLayer( self.INPUT, - self.tr('Input layer'), + self.tr("Input layer"), [ QgsProcessing.TypeVectorAnyGeometry, - ] + ], ) ) self.addParameter( QgsProcessingParameterBoolean( - self.SELECTED, - self.tr('Process only selected features') + self.SELECTED, self.tr("Process only selected features") ) ) self.addParameter( QgsProcessingParameterFeatureSink( - self.FLAGS, - self.tr('{0} Flags').format(self.displayName()) + self.FLAGS, self.tr("{0} Flags").format(self.displayName()) ) ) @@ -80,7 +89,9 @@ def processAlgorithm(self, parameters, context, feedback): """ inputLyr = self.parameterAsVectorLayer(parameters, self.INPUT, context) if inputLyr is None: - raise QgsProcessingException(self.invalidSourceError(parameters, self.INPUT)) + raise QgsProcessingException( + self.invalidSourceError(parameters, self.INPUT) + ) onlySelected = self.parameterAsBool(parameters, self.SELECTED, context) self.prepareFlagSink(parameters, inputLyr, inputLyr.wkbType(), context) request = QgsFeatureRequest() @@ -95,7 +106,9 @@ def processAlgorithm(self, parameters, context, feedback): for current, feat in enumerate(featuresWithProblem): if feedback is not None and feedback.isCanceled(): break - self.flagFeature(feat.geometry(), flagText=self.tr('Geometry with multi part.')) + self.flagFeature( + feat.geometry(), flagText=self.tr("Geometry with multi part.") + ) if feedback is not None: feedback.setProgress(current * stepSize) @@ -109,21 +122,21 @@ def name(self): lowercase alphanumeric characters only and no spaces or other formatting characters. """ - return 'identifymultigeometries' + return "identifymultigeometries" def displayName(self): """ Returns the translated algorithm name, which should be used for any user-visible display of the algorithm name. """ - return self.tr('Identify Multipart Geometries') + return self.tr("Identify Multipart Geometries") def group(self): """ Returns the name of the group this algorithm belongs to. This string should be localised. """ - return self.tr('Quality Assurance Tools (Identification Processes)') + return self.tr("Quality Assurance Tools (Identification Processes)") def groupId(self): """ @@ -133,10 +146,12 @@ def groupId(self): contain lowercase alphanumeric characters only and no spaces or other formatting characters. """ - return 'DSGTools: Quality Assurance Tools (Identification Processes)' + return "DSGTools: Quality Assurance Tools (Identification Processes)" def tr(self, string): - return QCoreApplication.translate('IdentifyMultiPartGeometriesAlgorithm', string) + return QCoreApplication.translate( + "IdentifyMultiPartGeometriesAlgorithm", string + ) def createInstance(self): return IdentifyMultiPartGeometriesAlgorithm() diff --git a/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/identifyNetworkConstructionIssuesAlgorithm.py b/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/identifyNetworkConstructionIssuesAlgorithm.py index 3d5f0bd5f..577243066 100644 --- a/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/identifyNetworkConstructionIssuesAlgorithm.py +++ b/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/identifyNetworkConstructionIssuesAlgorithm.py @@ -40,20 +40,20 @@ QgsProcessingMultiStepFeedback, QgsFeatureRequest, QgsGeometry, - QgsPoint + QgsPoint, ) class IdentifyNetworkConstructionIssuesAlgorithm(ValidationAlgorithm): INPUT_LINES = "INPUT_LINES" - SELECTED = 'SELECTED' + SELECTED = "SELECTED" TOLERANCE = "TOLERANCE" LINEFILTERLAYERS = "LINEFILTERLAYERS" POLYGONFILTERLAYERS = "POLYGONFILTERLAYERS" - IGNORE_DANGLES_ON_UNSEGMENTED_LINES = 'IGNORE_DANGLES_ON_UNSEGMENTED_LINES' - INPUT_IS_BOUDARY_LAYER = 'INPUT_IS_BOUDARY_LAYER' - GEOGRAPHIC_BOUNDARY = 'GEOGRAPHIC_BOUNDARY' - FLAGS = 'FLAGS' + IGNORE_DANGLES_ON_UNSEGMENTED_LINES = "IGNORE_DANGLES_ON_UNSEGMENTED_LINES" + INPUT_IS_BOUDARY_LAYER = "INPUT_IS_BOUDARY_LAYER" + GEOGRAPHIC_BOUNDARY = "GEOGRAPHIC_BOUNDARY" + FLAGS = "FLAGS" def initAlgorithm(self, config): """ @@ -69,17 +69,16 @@ def initAlgorithm(self, config): ) self.addParameter( QgsProcessingParameterBoolean( - self.SELECTED, - self.tr('Process only selected features') + self.SELECTED, self.tr("Process only selected features") ) ) self.addParameter( QgsProcessingParameterBoolean( self.INPUT_IS_BOUDARY_LAYER, self.tr( - 'Input is a boundary layer (every line must be connected ' - 'to an element of either the input layer or the filters)' - ) + "Input is a boundary layer (every line must be connected " + "to an element of either the input layer or the filters)" + ), ) ) self.addParameter( @@ -110,15 +109,17 @@ def initAlgorithm(self, config): self.addParameter( QgsProcessingParameterBoolean( self.IGNORE_DANGLES_ON_UNSEGMENTED_LINES, - self.tr('Ignore dangle on unsegmented lines') + self.tr("Ignore dangle on unsegmented lines"), ) ) self.addParameter( QgsProcessingParameterVectorLayer( self.GEOGRAPHIC_BOUNDARY, - self.tr('Geographic Boundary (this layer only filters the output dangles)'), + self.tr( + "Geographic Boundary (this layer only filters the output dangles)" + ), [QgsProcessing.TypeVectorPolygon], - optional=True + optional=True, ) ) self.addParameter( @@ -133,23 +134,31 @@ def processAlgorithm(self, parameters, context, feedback): """ self.layerHandler = LayerHandler() algRunner = AlgRunner() - lineLyrList = self.parameterAsLayerList( - parameters, self.INPUT_LINES, context - ) + lineLyrList = self.parameterAsLayerList(parameters, self.INPUT_LINES, context) onlySelected = self.parameterAsBool(parameters, self.SELECTED, context) searchRadius = self.parameterAsDouble(parameters, self.TOLERANCE, context) - lineFilterLyrList = self.parameterAsLayerList(parameters, self.LINEFILTERLAYERS, context) - polygonFilterLyrList = self.parameterAsLayerList(parameters, self.POLYGONFILTERLAYERS, context) + lineFilterLyrList = self.parameterAsLayerList( + parameters, self.LINEFILTERLAYERS, context + ) + polygonFilterLyrList = self.parameterAsLayerList( + parameters, self.POLYGONFILTERLAYERS, context + ) ignoreDanglesOnUnsegmentedLines = self.parameterAsBool( - parameters, self.IGNORE_DANGLES_ON_UNSEGMENTED_LINES, context) + parameters, self.IGNORE_DANGLES_ON_UNSEGMENTED_LINES, context + ) inputIsBoundaryLayer = self.parameterAsBool( - parameters, self.INPUT_IS_BOUDARY_LAYER, context) - geographicBoundsLyr = self.parameterAsVectorLayer(parameters, self.GEOGRAPHIC_BOUNDARY, context) + parameters, self.INPUT_IS_BOUDARY_LAYER, context + ) + geographicBoundsLyr = self.parameterAsVectorLayer( + parameters, self.GEOGRAPHIC_BOUNDARY, context + ) self.prepareFlagSink(parameters, lineLyrList[0], QgsWkbTypes.Point, context) multiStepFeedback = QgsProcessingMultiStepFeedback(4, feedback) multiStepFeedback.setCurrentStep(0) multiStepFeedback.pushInfo(self.tr("Building unified lines layer...")) - mergedLines = self.getInputLineLayers(context, algRunner, lineLyrList, onlySelected, multiStepFeedback) + mergedLines = self.getInputLineLayers( + context, algRunner, lineLyrList, onlySelected, multiStepFeedback + ) multiStepFeedback.setCurrentStep(1) outputLyr = algRunner.runIdentifyDangles( inputLayer=mergedLines, @@ -166,38 +175,52 @@ def processAlgorithm(self, parameters, context, feedback): self.flagSink.addFeatures(outputLyr.getFeatures(), QgsFeatureSink.FastInsert) multiStepFeedback.setCurrentStep(3) self.getUnsegmentedErrors( - mergedLines, + mergedLines, lineFilter=lineFilterLyrList, polygonFilter=polygonFilterLyrList, flagSet=set(i.geometry().asWkb() for i in outputLyr.getFeatures()), - algRunner=algRunner, context=context, feedback=multiStepFeedback) - return { - "FLAGS": self.flag_id - } + algRunner=algRunner, + context=context, + feedback=multiStepFeedback, + ) + return {"FLAGS": self.flag_id} - def getInputLineLayers(self, context, algRunner, lineLyrList, onlySelected, feedback): + def getInputLineLayers( + self, context, algRunner, lineLyrList, onlySelected, feedback + ): nSteps = 2 if not onlySelected else 2 + len(lyrList) multiStepFeedback = QgsProcessingMultiStepFeedback(nSteps, feedback) + def getLineLayer(currentStep, lineLyr): multiStepFeedback.setCurrentStep(currentStep) - return lineLyr if not onlySelected \ + return ( + lineLyr + if not onlySelected else algRunner.runSaveSelectedFeatures( - lineLyr, - context, - feedback=multiStepFeedback + lineLyr, context, feedback=multiStepFeedback ) - + ) + lyrList = [ getLineLayer(currentStep, lineLyr) for currentStep, lineLyr in enumerate(lineLyrList) ] - multiStepFeedback.setCurrentStep(nSteps-1) + multiStepFeedback.setCurrentStep(nSteps - 1) mergedLines = algRunner.runMergeVectorLayers( inputList=lyrList, feedback=multiStepFeedback, context=context ) return mergedLines - - def getUnsegmentedErrors(self, mergedLines, lineFilter, polygonFilter, flagSet, algRunner, context, feedback): + + def getUnsegmentedErrors( + self, + mergedLines, + lineFilter, + polygonFilter, + flagSet, + algRunner, + context, + feedback, + ): # build spatial index on mergedLines multiStepFeedback = QgsProcessingMultiStepFeedback(4, feedback) multiStepFeedback.setCurrentStep(0) @@ -209,13 +232,16 @@ def getUnsegmentedErrors(self, mergedLines, lineFilter, polygonFilter, flagSet, multiStepFeedback.setCurrentStep(1) # run intersect # merge and build spatial index on line filters and polygon filters - filterLayer = self.getFilterLayers(lineFilter, polygonFilter, algRunner, multiStepFeedback, context) + filterLayer = self.getFilterLayers( + lineFilter, polygonFilter, algRunner, multiStepFeedback, context + ) multiStepFeedback.setCurrentStep(2) nFeats = mergedLines.featureCount() if nFeats == 0: return stepSize = 100 / nFeats errorSet = set() + def evaluate(feat): outputSet = set() if multiStepFeedback.isCanceled(): @@ -227,54 +253,75 @@ def evaluate(feat): request = QgsFeatureRequest().setFilterRect(bbox) # inner search for candidateFeat in itertools.chain.from_iterable( - [mergedLines.getFeatures(request), filterLayer.getFeatures(request)]): + [mergedLines.getFeatures(request), filterLayer.getFeatures(request)] + ): if multiStepFeedback.isCanceled(): return outputSet candidateGeom = candidateFeat.geometry() candidateConstGetGeom = candidateGeom.constGet() if not engine.intersects(candidateConstGetGeom): continue - if geom.equals(candidateGeom): #same geom + if geom.equals(candidateGeom): # same geom continue intersection = engine.intersection(candidateConstGetGeom) - intersectionPoints = [intersection] if isinstance(intersection, QgsPoint) else intersection.vertices() + intersectionPoints = ( + [intersection] + if isinstance(intersection, QgsPoint) + else intersection.vertices() + ) for i in intersectionPoints: wkb = i.asWkb() - if not engine.touches(i) and wkb not in flagSet and wkb not in outputSet: + if ( + not engine.touches(i) + and wkb not in flagSet + and wkb not in outputSet + ): outputSet.add(wkb) return outputSet - - pool = concurrent.futures.ThreadPoolExecutor(max_workers=os.cpu_count()-1) + + pool = concurrent.futures.ThreadPoolExecutor(max_workers=os.cpu_count() - 1) futures = set() for current, feat in enumerate(mergedLines.getFeatures()): if multiStepFeedback.isCanceled(): break - #put this into a thread after it is working + # put this into a thread after it is working futures.add(pool.submit(evaluate, feat)) multiStepFeedback.setProgress(current * stepSize) - concurrent.futures.wait(futures, timeout=None, return_when=concurrent.futures.ALL_COMPLETED) + concurrent.futures.wait( + futures, timeout=None, return_when=concurrent.futures.ALL_COMPLETED + ) multiStepFeedback.setCurrentStep(3) - stepSize = 100/len(futures) + stepSize = 100 / len(futures) for current, future in enumerate(concurrent.futures.as_completed(futures)): if multiStepFeedback.isCanceled(): break outputSet = future.result() errorSet = errorSet.union(outputSet) multiStepFeedback.setProgress(current * stepSize) - flagLambda = lambda x: self.flagFeature(x, self.tr("Line from input not split on intersection."), fromWkb=True) + flagLambda = lambda x: self.flagFeature( + x, self.tr("Line from input not split on intersection."), fromWkb=True + ) list(map(flagLambda, errorSet)) - + def getFilterLayers(self, lineFilter, polygonFilter, algRunner, feedback, context): nSteps = len(polygonFilter) + 2 multiStepFeedback = QgsProcessingMultiStepFeedback(nSteps, feedback) + def makeBoundary(currentStep, layer): multiStepFeedback.setCurrentStep(currentStep) - return algRunner.runBoundary(layer, feedback=multiStepFeedback, context=context) - - lineFilterList = lineFilter + [makeBoundary(currentStep, layer) for currentStep, layer in enumerate(polygonFilter)] + return algRunner.runBoundary( + layer, feedback=multiStepFeedback, context=context + ) + + lineFilterList = lineFilter + [ + makeBoundary(currentStep, layer) + for currentStep, layer in enumerate(polygonFilter) + ] currentStep = len(polygonFilter) + 1 multiStepFeedback.setCurrentStep(currentStep) - mergedFilters = algRunner.runMergeVectorLayers(lineFilterList, context=context, feedback=multiStepFeedback) + mergedFilters = algRunner.runMergeVectorLayers( + lineFilterList, context=context, feedback=multiStepFeedback + ) currentStep += 1 multiStepFeedback.setCurrentStep(currentStep) @@ -285,8 +332,6 @@ def makeBoundary(currentStep, layer): ) return mergedFilters - - def name(self): """ Returns the algorithm name, used for identifying the algorithm. This diff --git a/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/identifyOutOfBoundsAnglesAlgorithm.py b/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/identifyOutOfBoundsAnglesAlgorithm.py index 1be082cf5..2c123a0c1 100644 --- a/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/identifyOutOfBoundsAnglesAlgorithm.py +++ b/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/identifyOutOfBoundsAnglesAlgorithm.py @@ -23,24 +23,30 @@ from PyQt5.QtCore import QCoreApplication from DsgTools.core.GeometricTools.geometryHandler import GeometryHandler -from qgis.core import (QgsDataSourceUri, QgsFeature, QgsFeatureSink, - QgsProcessing, QgsProcessingAlgorithm, - QgsProcessingOutputVectorLayer, - QgsProcessingParameterBoolean, - QgsProcessingParameterFeatureSink, - QgsProcessingParameterFeatureSource, - QgsProcessingParameterNumber, - QgsProcessingParameterVectorLayer, QgsWkbTypes, - QgsProcessingException) +from qgis.core import ( + QgsDataSourceUri, + QgsFeature, + QgsFeatureSink, + QgsProcessing, + QgsProcessingAlgorithm, + QgsProcessingOutputVectorLayer, + QgsProcessingParameterBoolean, + QgsProcessingParameterFeatureSink, + QgsProcessingParameterFeatureSource, + QgsProcessingParameterNumber, + QgsProcessingParameterVectorLayer, + QgsWkbTypes, + QgsProcessingException, +) from .validationAlgorithm import ValidationAlgorithm class IdentifyOutOfBoundsAnglesAlgorithm(ValidationAlgorithm): - FLAGS = 'FLAGS' - INPUT = 'INPUT' - SELECTED = 'SELECTED' - TOLERANCE = 'TOLERANCE' + FLAGS = "FLAGS" + INPUT = "INPUT" + SELECTED = "SELECTED" + TOLERANCE = "TOLERANCE" def initAlgorithm(self, config): """ @@ -49,31 +55,26 @@ def initAlgorithm(self, config): self.addParameter( QgsProcessingParameterVectorLayer( self.INPUT, - self.tr('Input layer'), - [QgsProcessing.TypeVectorLine, QgsProcessing.TypeVectorPolygon] + self.tr("Input layer"), + [QgsProcessing.TypeVectorLine, QgsProcessing.TypeVectorPolygon], ) ) self.addParameter( QgsProcessingParameterBoolean( - self.SELECTED, - self.tr('Process only selected features') + self.SELECTED, self.tr("Process only selected features") ) ) self.addParameter( QgsProcessingParameterNumber( - self.TOLERANCE, - self.tr('Minimum angle'), - minValue=0, - defaultValue=10 + self.TOLERANCE, self.tr("Minimum angle"), minValue=0, defaultValue=10 ) ) self.addParameter( QgsProcessingParameterFeatureSink( - self.FLAGS, - self.tr('{0} Flags').format(self.displayName()) + self.FLAGS, self.tr("{0} Flags").format(self.displayName()) ) ) @@ -84,13 +85,17 @@ def processAlgorithm(self, parameters, context, feedback): geometryHandler = GeometryHandler() inputLyr = self.parameterAsVectorLayer(parameters, self.INPUT, context) if inputLyr is None: - raise QgsProcessingException(self.invalidSourceError(parameters, self.INPUT)) + raise QgsProcessingException( + self.invalidSourceError(parameters, self.INPUT) + ) onlySelected = self.parameterAsBool(parameters, self.SELECTED, context) tol = self.parameterAsDouble(parameters, self.TOLERANCE, context) self.prepareFlagSink(parameters, inputLyr, QgsWkbTypes.Point, context) # Compute the number of steps to display within the progress bar and # get features from source - featureList, total = self.getIteratorAndFeatureCount(inputLyr, onlySelected = onlySelected) + featureList, total = self.getIteratorAndFeatureCount( + inputLyr, onlySelected=onlySelected + ) for current, feat in enumerate(featureList): # Stop the algorithm if cancel button has been clicked @@ -99,8 +104,10 @@ def processAlgorithm(self, parameters, context, feedback): outOfBoundsList = geometryHandler.getOutOfBoundsAngle(feat, tol) if outOfBoundsList: for item in outOfBoundsList: - flagText = self.tr('Feature from layer {0} with id={1} has angle of value {2} degrees, which is lesser than the tolerance of {3} degrees.').format(inputLyr.name(), item['feat_id'], item['angle'], tol) - self.flagFeature(item['geom'], flagText) + flagText = self.tr( + "Feature from layer {0} with id={1} has angle of value {2} degrees, which is lesser than the tolerance of {3} degrees." + ).format(inputLyr.name(), item["feat_id"], item["angle"], tol) + self.flagFeature(item["geom"], flagText) # Update the progress bar feedback.setProgress(int(current * total)) @@ -114,21 +121,21 @@ def name(self): lowercase alphanumeric characters only and no spaces or other formatting characters. """ - return 'identifyoutofboundsangles' + return "identifyoutofboundsangles" def displayName(self): """ Returns the translated algorithm name, which should be used for any user-visible display of the algorithm name. """ - return self.tr('Identify Out Of Bounds Angles') + return self.tr("Identify Out Of Bounds Angles") def group(self): """ Returns the name of the group this algorithm belongs to. This string should be localised. """ - return self.tr('Quality Assurance Tools (Identification Processes)') + return self.tr("Quality Assurance Tools (Identification Processes)") def groupId(self): """ @@ -138,10 +145,10 @@ def groupId(self): contain lowercase alphanumeric characters only and no spaces or other formatting characters. """ - return 'DSGTools: Quality Assurance Tools (Identification Processes)' + return "DSGTools: Quality Assurance Tools (Identification Processes)" def tr(self, string): - return QCoreApplication.translate('IdentifyOutOfBoundsAnglesAlgorithm', string) + return QCoreApplication.translate("IdentifyOutOfBoundsAnglesAlgorithm", string) def createInstance(self): return IdentifyOutOfBoundsAnglesAlgorithm() diff --git a/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/identifyOutOfBoundsAnglesInCoverageAlgorithm.py b/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/identifyOutOfBoundsAnglesInCoverageAlgorithm.py index 5b8b8764b..c67400f52 100644 --- a/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/identifyOutOfBoundsAnglesInCoverageAlgorithm.py +++ b/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/identifyOutOfBoundsAnglesInCoverageAlgorithm.py @@ -138,62 +138,55 @@ def processAlgorithm(self, parameters, context, feedback): onlySelected = self.parameterAsBool(parameters, self.SELECTED, context) tol = self.parameterAsDouble(parameters, self.TOLERANCE, context) self.prepareFlagSink(parameters, inputLyrList[0], QgsWkbTypes.Point, context) - multiStepFeedback = QgsProcessingMultiStepFeedback( - 6, feedback - ) + multiStepFeedback = QgsProcessingMultiStepFeedback(6, feedback) currentStep = 0 - #merge all layers into one - multiStepFeedback.setProgressText(self.tr('Building unified layer')) + # merge all layers into one + multiStepFeedback.setProgressText(self.tr("Building unified layer")) multiStepFeedback.setCurrentStep(currentStep) mergedLayers = algRunner.runMergeVectorLayers( inputList=inputLyrList, context=context, feedback=multiStepFeedback ) currentStep += 1 - multiStepFeedback.setCurrentStep(currentStep) - multiStepFeedback.setProgressText(self.tr('Exploding lines')) + multiStepFeedback.setProgressText(self.tr("Exploding lines")) splitSegments = algRunner.runExplodeLines( inputLyr=mergedLayers, context=context, feedback=multiStepFeedback ) currentStep += 1 multiStepFeedback.setCurrentStep(currentStep) - multiStepFeedback.setProgressText(self.tr('Building spatial index')) + multiStepFeedback.setProgressText(self.tr("Building spatial index")) algRunner.runCreateSpatialIndex( - inputLyr=splitSegments, - context=context, - feedback=multiStepFeedback + inputLyr=splitSegments, context=context, feedback=multiStepFeedback ) currentStep += 1 - - #split segments with clean + # split segments with clean multiStepFeedback.setCurrentStep(currentStep) - multiStepFeedback.setProgressText(self.tr('Splitting lines')) + multiStepFeedback.setProgressText(self.tr("Splitting lines")) cleanedLyr = algRunner.runSplitLinesWithLines( inputLyr=splitSegments, linesLyr=splitSegments, context=context, - feedback=multiStepFeedback + feedback=multiStepFeedback, ) - + currentStep += 1 multiStepFeedback.setCurrentStep(currentStep) - multiStepFeedback.setProgressText(self.tr('Building node angle dict')) + multiStepFeedback.setProgressText(self.tr("Building node angle dict")) nodeAngleDict = self.buildNodeAngleDict(cleanedLyr, feedback=multiStepFeedback) - currentStep += 1 multiStepFeedback.setCurrentStep(currentStep) - multiStepFeedback.setProgressText(self.tr('Evaluating flags')) + multiStepFeedback.setProgressText(self.tr("Evaluating flags")) self.computeSmallAnglesInCoverage( nodeAngleDict, tol, feedback=multiStepFeedback ) return {self.FLAGS: self.flag_id} - + def buildNodeAngleDict(self, splitSegments, feedback=None): nodeAngleDict = defaultdict(set) # nodeAngleDict = dict() @@ -202,15 +195,21 @@ def buildNodeAngleDict(self, splitSegments, feedback=None): return nodeAngleDict multiStepFeedback = QgsProcessingMultiStepFeedback(3, feedback) multiStepFeedback.setCurrentStep(0) - multiStepFeedback.setProgressText(self.tr('Building node angle dict: building dict')) - multiStepFeedback.pushInfo(self.tr(f'Iterating over {nFeats} segments...')) + multiStepFeedback.setProgressText( + self.tr("Building node angle dict: building dict") + ) + multiStepFeedback.pushInfo(self.tr(f"Iterating over {nFeats} segments...")) for current, feat in enumerate(splitSegments.getFeatures()): if feedback is not None and feedback.isCanceled(): break geom = feat.geometry() if geom.isNull(): continue - p1, p2 = geom.asPolyline() if not geom.isMultipart() else geom.asMultiPolyline()[0] + p1, p2 = ( + geom.asPolyline() + if not geom.isMultipart() + else geom.asMultiPolyline()[0] + ) geom1 = QgsGeometry.fromPointXY(p1) wkb1 = geom1.asWkb() geom2 = QgsGeometry.fromPointXY(p2) @@ -219,9 +218,11 @@ def buildNodeAngleDict(self, splitSegments, feedback=None): nodeAngleDict[wkb2].add(wkb1) if feedback is not None: multiStepFeedback.setProgress(current * 100 / nFeats) - + multiStepFeedback.setCurrentStep(1) - multiStepFeedback.setProgressText(self.tr('Building node angle dict: identifying nodes to pop')) + multiStepFeedback.setProgressText( + self.tr("Building node angle dict: identifying nodes to pop") + ) keysToPop = set() nNodes = len(nodeAngleDict) for current, (point, pointSet) in enumerate(nodeAngleDict.items()): @@ -232,7 +233,9 @@ def buildNodeAngleDict(self, splitSegments, feedback=None): if feedback is not None: multiStepFeedback.setProgress(current * 100 / nNodes) multiStepFeedback.setCurrentStep(2) - multiStepFeedback.setProgressText(self.tr('Building node angle dict: removing single nodes')) + multiStepFeedback.setProgressText( + self.tr("Building node angle dict: removing single nodes") + ) nItems = len(keysToPop) for current, point in enumerate(keysToPop): if feedback is not None and feedback.isCanceled(): @@ -242,9 +245,7 @@ def buildNodeAngleDict(self, splitSegments, feedback=None): multiStepFeedback.setProgress(current * 100 / nItems) return nodeAngleDict - def computeSmallAnglesInCoverage( - self, nodeAngleDict, tol, feedback=None - ): + def computeSmallAnglesInCoverage(self, nodeAngleDict, tol, feedback=None): flagWkbSet = set() nIntersections = len(nodeAngleDict) if nIntersections == 0: diff --git a/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/identifyOverlapsAlgorithm.py b/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/identifyOverlapsAlgorithm.py index 2ffc3a05d..d59625cfa 100644 --- a/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/identifyOverlapsAlgorithm.py +++ b/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/identifyOverlapsAlgorithm.py @@ -27,24 +27,33 @@ import concurrent.futures from DsgTools.core.GeometricTools.geometryHandler import GeometryHandler from DsgTools.core.GeometricTools.layerHandler import LayerHandler -from qgis.core import (QgsDataSourceUri, QgsFeature, QgsFeatureSink, - QgsProcessing, QgsProcessingAlgorithm, - QgsProcessingException, QgsProcessingMultiStepFeedback, - QgsProcessingOutputVectorLayer, - QgsProcessingParameterBoolean, - QgsProcessingParameterFeatureSink, - QgsProcessingParameterFeatureSource, - QgsProcessingParameterMultipleLayers, - QgsProcessingParameterVectorLayer, QgsProcessingUtils, - QgsProject, QgsWkbTypes, QgsProcessingFeatureSourceDefinition) +from qgis.core import ( + QgsDataSourceUri, + QgsFeature, + QgsFeatureSink, + QgsProcessing, + QgsProcessingAlgorithm, + QgsProcessingException, + QgsProcessingMultiStepFeedback, + QgsProcessingOutputVectorLayer, + QgsProcessingParameterBoolean, + QgsProcessingParameterFeatureSink, + QgsProcessingParameterFeatureSource, + QgsProcessingParameterMultipleLayers, + QgsProcessingParameterVectorLayer, + QgsProcessingUtils, + QgsProject, + QgsWkbTypes, + QgsProcessingFeatureSourceDefinition, +) from .validationAlgorithm import ValidationAlgorithm class IdentifyOverlapsAlgorithm(ValidationAlgorithm): - FLAGS = 'FLAGS' - INPUT = 'INPUT' - SELECTED = 'SELECTED' + FLAGS = "FLAGS" + INPUT = "INPUT" + SELECTED = "SELECTED" def initAlgorithm(self, config): """ @@ -53,25 +62,23 @@ def initAlgorithm(self, config): self.addParameter( QgsProcessingParameterVectorLayer( self.INPUT, - self.tr('Input layer'), + self.tr("Input layer"), [ QgsProcessing.TypeVectorLine, QgsProcessing.TypeVectorPolygon, - ] + ], ) ) self.addParameter( QgsProcessingParameterBoolean( - self.SELECTED, - self.tr('Process only selected features') + self.SELECTED, self.tr("Process only selected features") ) ) self.addParameter( QgsProcessingParameterFeatureSink( - self.FLAGS, - self.tr('{0} Flags').format(self.displayName()) + self.FLAGS, self.tr("{0} Flags").format(self.displayName()) ) ) @@ -84,7 +91,9 @@ def processAlgorithm(self, parameters, context, feedback): algRunner = AlgRunner() inputLyr = self.parameterAsVectorLayer(parameters, self.INPUT, context) if inputLyr is None: - raise QgsProcessingException(self.invalidSourceError(parameters, self.INPUT)) + raise QgsProcessingException( + self.invalidSourceError(parameters, self.INPUT) + ) onlySelected = self.parameterAsBool(parameters, self.SELECTED, context) self.prepareFlagSink(parameters, inputLyr, inputLyr.wkbType(), context) # Compute the number of steps to display within the progress bar and @@ -92,7 +101,9 @@ def processAlgorithm(self, parameters, context, feedback): multiStepFeedback = QgsProcessingMultiStepFeedback(3, feedback) multiStepFeedback.setCurrentStep(0) multiStepFeedback.setProgressText(self.tr("Building aux structure...")) - joinLyr, idDict = self.prepareAuxStructure(context, multiStepFeedback, algRunner, inputLyr, onlySelected) + joinLyr, idDict = self.prepareAuxStructure( + context, multiStepFeedback, algRunner, inputLyr, onlySelected + ) multiStepFeedback.setCurrentStep(1) multiStepFeedback.setProgressText(self.tr("Finding overlaps...")) geometrySet = self.findOverlaps(joinLyr, idDict, feedback) @@ -102,7 +113,9 @@ def processAlgorithm(self, parameters, context, feedback): for current, geom in enumerate(geometrySet): if multiStepFeedback.isCanceled(): break - self.flagFeature(geom, self.tr('Overlap on layer {0}').format(inputLyr.name())) + self.flagFeature( + geom, self.tr("Overlap on layer {0}").format(inputLyr.name()) + ) multiStepFeedback.setProgress(current * total) return {self.FLAGS: self.flag_id} @@ -110,36 +123,42 @@ def processAlgorithm(self, parameters, context, feedback): def prepareAuxStructure(self, context, feedback, algRunner, inputLyr, onlySelected): multiStepFeedback = QgsProcessingMultiStepFeedback(4, feedback) multiStepFeedback.setCurrentStep(0) - multiStepFeedback.setProgressText(self.tr("Building aux structure: creating incremental field layer...")) + multiStepFeedback.setProgressText( + self.tr("Building aux structure: creating incremental field layer...") + ) incrementedLyr = algRunner.runAddAutoIncrementalField( - inputLyr=inputLyr if not onlySelected else QgsProcessingFeatureSourceDefinition( - inputLyr.id(), True), + inputLyr=inputLyr + if not onlySelected + else QgsProcessingFeatureSourceDefinition(inputLyr.id(), True), context=context, feedback=multiStepFeedback, start=0, sortAscending=False, - sortNullsFirst=False + sortNullsFirst=False, ) multiStepFeedback.setCurrentStep(1) - multiStepFeedback.setProgressText(self.tr("Building aux structure: spatial index...")) + multiStepFeedback.setProgressText( + self.tr("Building aux structure: spatial index...") + ) algRunner.runCreateSpatialIndex( - inputLyr=incrementedLyr, - context=context, - feedback=multiStepFeedback + inputLyr=incrementedLyr, context=context, feedback=multiStepFeedback ) multiStepFeedback.setCurrentStep(2) - multiStepFeedback.setProgressText(self.tr("Building aux structure: feature dict...")) - idDict = {feat['featid']: feat for feat in incrementedLyr.getFeatures()} + multiStepFeedback.setProgressText( + self.tr("Building aux structure: feature dict...") + ) + idDict = {feat["featid"]: feat for feat in incrementedLyr.getFeatures()} multiStepFeedback.setCurrentStep(3) - multiStepFeedback.setProgressText(self.tr("Building aux structure: Running spatial join...")) + multiStepFeedback.setProgressText( + self.tr("Building aux structure: Running spatial join...") + ) joinLyr = algRunner.runJoinAttributesByLocation( inputLyr=incrementedLyr, joinLyr=incrementedLyr, context=context, - feedback=multiStepFeedback + feedback=multiStepFeedback, ) - - + return joinLyr, idDict def findOverlaps(self, inputLyr, idDict, feedback=None): @@ -147,22 +166,35 @@ def findOverlaps(self, inputLyr, idDict, feedback=None): geomType = inputLyr.geometryType() if not total: return set() + def _processFeature(feat, feedback): outputSet = set() - if (feedback is not None and feedback.isCanceled()) or feat["featid_2"] not in idDict or feat['featid_2'] <= feat['featid']: + if ( + (feedback is not None and feedback.isCanceled()) + or feat["featid_2"] not in idDict + or feat["featid_2"] <= feat["featid"] + ): return outputSet geom1 = feat.geometry() - geom2 = idDict[feat['featid_2']].geometry() + geom2 = idDict[feat["featid_2"]].geometry() if not geom1.intersects(geom2): return outputSet intersects = geom1.intersection(geom2) - return outputSet.union( - set(intersects.asGeometryCollection()) if intersects.isMultipart() else {intersects} - ) if intersects.type() == geomType else outputSet - + return ( + outputSet.union( + set(intersects.asGeometryCollection()) + if intersects.isMultipart() + else {intersects} + ) + if intersects.type() == geomType + else outputSet + ) + multiStepFeedback = QgsProcessingMultiStepFeedback(2, feedback) multiStepFeedback.setCurrentStep(0) - multiStepFeedback.setProgressText(self.tr("Finding overlaps: submitting to thread...")) + multiStepFeedback.setProgressText( + self.tr("Finding overlaps: submitting to thread...") + ) processLambda = lambda x: _processFeature(x, multiStepFeedback) pool = concurrent.futures.ThreadPoolExecutor(os.cpu_count()) futures = set() @@ -171,9 +203,11 @@ def _processFeature(feat, feedback): if multiStepFeedback is not None and multiStepFeedback.isCanceled(): break futures.add(pool.submit(processLambda, feat)) - + multiStepFeedback.setCurrentStep(1) - multiStepFeedback.setProgressText(self.tr("Finding overlaps: processing thread outputs...")) + multiStepFeedback.setProgressText( + self.tr("Finding overlaps: processing thread outputs...") + ) outputSet = set() for current, future in enumerate(concurrent.futures.as_completed(futures)): if multiStepFeedback is not None and multiStepFeedback.isCanceled(): @@ -191,21 +225,21 @@ def name(self): lowercase alphanumeric characters only and no spaces or other formatting characters. """ - return 'identifyoverlaps' + return "identifyoverlaps" def displayName(self): """ Returns the translated algorithm name, which should be used for any user-visible display of the algorithm name. """ - return self.tr('Identify Overlaps') + return self.tr("Identify Overlaps") def group(self): """ Returns the name of the group this algorithm belongs to. This string should be localised. """ - return self.tr('Quality Assurance Tools (Identification Processes)') + return self.tr("Quality Assurance Tools (Identification Processes)") def groupId(self): """ @@ -215,10 +249,10 @@ def groupId(self): contain lowercase alphanumeric characters only and no spaces or other formatting characters. """ - return 'DSGTools: Quality Assurance Tools (Identification Processes)' + return "DSGTools: Quality Assurance Tools (Identification Processes)" def tr(self, string): - return QCoreApplication.translate('IdentifyOverlapsAlgorithm', string) + return QCoreApplication.translate("IdentifyOverlapsAlgorithm", string) def createInstance(self): return IdentifyOverlapsAlgorithm() diff --git a/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/identifyPolygonSliverAlgorithm.py b/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/identifyPolygonSliverAlgorithm.py index b1b26bef3..413bd186f 100644 --- a/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/identifyPolygonSliverAlgorithm.py +++ b/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/identifyPolygonSliverAlgorithm.py @@ -20,19 +20,22 @@ ***************************************************************************/ """ -from qgis.core import (QgsProcessing, - QgsProcessingException, - QgsProcessingParameterNumber, - QgsProcessingParameterBoolean, - QgsProcessingMultiStepFeedback, - QgsProcessingParameterFeatureSink, - QgsProcessingParameterFeatureSource, - QgsProcessingParameterMultipleLayers) +from qgis.core import ( + QgsProcessing, + QgsProcessingException, + QgsProcessingParameterNumber, + QgsProcessingParameterBoolean, + QgsProcessingMultiStepFeedback, + QgsProcessingParameterFeatureSink, + QgsProcessingParameterFeatureSource, + QgsProcessingParameterMultipleLayers, +) from qgis.PyQt.QtCore import QCoreApplication from DsgTools.core.GeometricTools.layerHandler import LayerHandler -from DsgTools.core.DSGToolsProcessingAlgs.Algs.ValidationAlgs\ - .validationAlgorithm import ValidationAlgorithm +from DsgTools.core.DSGToolsProcessingAlgs.Algs.ValidationAlgs.validationAlgorithm import ( + ValidationAlgorithm, +) class IdentifyPolygonSliverAlgorithm(ValidationAlgorithm): @@ -41,6 +44,7 @@ class IdentifyPolygonSliverAlgorithm(ValidationAlgorithm): elongated areas which do not represent an entity in reality and, therefore, need to be removed. """ + FLAGS = "FLAGS" INPUT_LAYERS = "INPUT_LAYERS" SELECTED = "SELECTED" @@ -55,19 +59,17 @@ def initAlgorithm(self, config): QgsProcessingParameterMultipleLayers( self.INPUT_LAYERS, self.tr("Polygons to be checked"), - QgsProcessing.TypeVectorPolygon + QgsProcessing.TypeVectorPolygon, ) ) self.addParameter( QgsProcessingParameterBoolean( - self.SELECTED, - self.tr("Process only selected features") + self.SELECTED, self.tr("Process only selected features") ) ) self.addParameter( QgsProcessingParameterBoolean( - self.SILENT, - self.tr("Ignore empty and invalid geometries") + self.SILENT, self.tr("Ignore empty and invalid geometries") ) ) self.addParameter( @@ -76,13 +78,12 @@ def initAlgorithm(self, config): self.tr("Tolerance area-perimeter ratio"), minValue=0, type=QgsProcessingParameterNumber.Double, - defaultValue=10 + defaultValue=10, ) ) self.addParameter( QgsProcessingParameterFeatureSink( - self.FLAGS, - self.tr("{0} flags").format(self.displayName()) + self.FLAGS, self.tr("{0} flags").format(self.displayName()) ) ) @@ -96,21 +97,9 @@ def getParameters(self, parameters, context, feedback): algorithm's progress/status. :return: (tuple) input parameters provided. """ - layers = self.parameterAsLayerList( - parameters, - self.INPUT_LAYERS, - context - ) - selected = self.parameterAsBoolean( - parameters, - self.SELECTED, - context - ) - silent = self.parameterAsBoolean( - parameters, - self.SILENT, - context - ) + layers = self.parameterAsLayerList(parameters, self.INPUT_LAYERS, context) + selected = self.parameterAsBoolean(parameters, self.SELECTED, context) + silent = self.parameterAsBoolean(parameters, self.SILENT, context) ratio = self.parameterAsDouble(parameters, self.RATIO_TOL, context) return (layers, selected, silent, ratio) @@ -125,7 +114,8 @@ def processAlgorithm(self, parameters, context, feedback): :return: (dict) output mapping for identified flags. """ layers, selected, silent, ratio = self.getParameters( - parameters, context, feedback) + parameters, context, feedback + ) if not layers: raise QgsProcessingException(self.tr("No layers were provided.")) for layer in layers: @@ -139,24 +129,24 @@ def processAlgorithm(self, parameters, context, feedback): lh = LayerHandler() flagCount = 0 # a step for each input + 1 for loading flags into sink - multiStepFeedback = QgsProcessingMultiStepFeedback( - len(layers) + 1, feedback) + multiStepFeedback = QgsProcessingMultiStepFeedback(len(layers) + 1, feedback) multiStepFeedback.setCurrentStep(0) for step, layer in enumerate(layers): if multiStepFeedback.isCanceled(): break # running polygon slivers to purposely raise an exception if an # empty geometry is found - multiStepFeedback.pushInfo( - self.tr("Checking {0}...").format(layer.name())) + multiStepFeedback.pushInfo(self.tr("Checking {0}...").format(layer.name())) slivers = lh.getPolygonSlivers( - layer, ratio, selected, silent, multiStepFeedback) + layer, ratio, selected, silent, multiStepFeedback + ) if slivers: # pushWarnign is only avalailable on 3.16.2+ # multiStepFeedback.pushWarning( multiStepFeedback.pushDebugInfo( - self.tr("{0} slivers were found on {1}!")\ - .format(len(slivers), layer.name()) + self.tr("{0} slivers were found on {1}!").format( + len(slivers), layer.name() + ) ) flags[layer] = slivers flagCount += len(slivers) @@ -187,10 +177,9 @@ def flagPolygonSlivers(self, flags, flagCount, feedback): geom = feat.geometry() self.flagFeature( geom, - self.tr("Feature {0} from layer {1} has ratio {2:.2f}")\ - .format( - feat.id(), layername, geom.area() / geom.length() - ) + self.tr("Feature {0} from layer {1} has ratio {2:.2f}").format( + feat.id(), layername, geom.area() / geom.length() + ), ) current += 1 feedback.setProgress(current * stepSize) @@ -230,8 +219,7 @@ def groupId(self): return "DSGTools: Quality Assurance Tools (Identification Processes)" def tr(self, string): - return QCoreApplication.translate( - "IdentifyPolygonSliverAlgorithm", string) + return QCoreApplication.translate("IdentifyPolygonSliverAlgorithm", string) def createInstance(self): return IdentifyPolygonSliverAlgorithm() diff --git a/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/identifyPolygonUndershoots.py b/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/identifyPolygonUndershoots.py index 321057fec..6d6048b72 100644 --- a/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/identifyPolygonUndershoots.py +++ b/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/identifyPolygonUndershoots.py @@ -26,10 +26,14 @@ from DsgTools.core.DSGToolsProcessingAlgs.algRunner import AlgRunner from DsgTools.core.GeometricTools.layerHandler import LayerHandler from PyQt5.QtCore import QCoreApplication -from qgis.core import (QgsProcessing, QgsProcessingMultiStepFeedback, - QgsProcessingParameterFeatureSink, - QgsProcessingParameterFeatureSource, - QgsProcessingParameterNumber, QgsWkbTypes) +from qgis.core import ( + QgsProcessing, + QgsProcessingMultiStepFeedback, + QgsProcessingParameterFeatureSink, + QgsProcessingParameterFeatureSource, + QgsProcessingParameterNumber, + QgsWkbTypes, +) from .validationAlgorithm import ValidationAlgorithm @@ -167,8 +171,8 @@ def evaluate(feat): if geom.distance(boundGeom) > 10**-9: return geom return None - - pool = concurrent.futures.ThreadPoolExecutor(max_workers=os.cpu_count()-1) + + pool = concurrent.futures.ThreadPoolExecutor(max_workers=os.cpu_count() - 1) futures = set() multiStepFeedback = QgsProcessingMultiStepFeedback(2, feedback) multiStepFeedback.setCurrentStep(0) @@ -210,7 +214,7 @@ def prepareInputFeatures(self, context, algRunner, inputSource, multiStepFeedbac inputSource, context, feedback=multiStepFeedback ) currentStep += 1 - + multiStepFeedback.setCurrentStep(currentStep) if boundaryLyr.geometryType() == QgsWkbTypes.LineGeometry: boundaryLyr = algRunner.runExplodeLines( diff --git a/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/identifySmallFirstOrderDangle.py b/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/identifySmallFirstOrderDangle.py index efc3ca2fa..ee0a01084 100644 --- a/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/identifySmallFirstOrderDangle.py +++ b/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/identifySmallFirstOrderDangle.py @@ -23,24 +23,28 @@ from DsgTools.core.DSGToolsProcessingAlgs.algRunner import AlgRunner from .validationAlgorithm import ValidationAlgorithm from PyQt5.QtCore import QCoreApplication -from qgis.core import (QgsProcessing, - QgsProcessingParameterFeatureSink, - QgsProcessingParameterVectorLayer, - QgsProcessingParameterBoolean, - QgsProcessingParameterNumber, - QgsProcessingParameterMultipleLayers, - QgsProcessingMultiStepFeedback, - QgsFeatureRequest, QgsWkbTypes) +from qgis.core import ( + QgsProcessing, + QgsProcessingParameterFeatureSink, + QgsProcessingParameterVectorLayer, + QgsProcessingParameterBoolean, + QgsProcessingParameterNumber, + QgsProcessingParameterMultipleLayers, + QgsProcessingMultiStepFeedback, + QgsFeatureRequest, + QgsWkbTypes, +) + class IdentifySmallFirstOrderDanglesAlgorithm(ValidationAlgorithm): - INPUT = 'INPUT' - SELECTED = 'SELECTED' - SEARCH_RADIUS = 'SEARCH_RADIUS' - MIN_LENGTH = 'MIN_LENGTH' - LINEFILTERLAYERS = 'LINEFILTERLAYERS' - POLYGONFILTERLAYERS = 'POLYGONFILTERLAYERS' - GEOGRAPHIC_BOUNDARY = 'GEOGRAPHIC_BOUNDARY' - FLAGS = 'FLAGS' + INPUT = "INPUT" + SELECTED = "SELECTED" + SEARCH_RADIUS = "SEARCH_RADIUS" + MIN_LENGTH = "MIN_LENGTH" + LINEFILTERLAYERS = "LINEFILTERLAYERS" + POLYGONFILTERLAYERS = "POLYGONFILTERLAYERS" + GEOGRAPHIC_BOUNDARY = "GEOGRAPHIC_BOUNDARY" + FLAGS = "FLAGS" def initAlgorithm(self, config): """ @@ -48,63 +52,61 @@ def initAlgorithm(self, config): """ self.addParameter( QgsProcessingParameterVectorLayer( - self.INPUT, - self.tr('Input layer'), - [QgsProcessing.TypeVectorLine ] + self.INPUT, self.tr("Input layer"), [QgsProcessing.TypeVectorLine] ) ) self.addParameter( QgsProcessingParameterBoolean( - self.SELECTED, - self.tr('Process only selected features') + self.SELECTED, self.tr("Process only selected features") ) ) self.addParameter( QgsProcessingParameterNumber( self.MIN_LENGTH, - self.tr('Minimum size'), + self.tr("Minimum size"), minValue=0, type=QgsProcessingParameterNumber.Double, - defaultValue=0.001 + defaultValue=0.001, ) ) self.addParameter( QgsProcessingParameterNumber( self.SEARCH_RADIUS, - self.tr('Search radius'), + self.tr("Search radius"), minValue=0, type=QgsProcessingParameterNumber.Double, - defaultValue=0.0001 + defaultValue=0.0001, ) ) self.addParameter( QgsProcessingParameterMultipleLayers( self.LINEFILTERLAYERS, - self.tr('Linestring Filter Layers'), + self.tr("Linestring Filter Layers"), QgsProcessing.TypeVectorLine, - optional=True + optional=True, ) ) self.addParameter( QgsProcessingParameterMultipleLayers( self.POLYGONFILTERLAYERS, - self.tr('Polygon Filter Layers'), + self.tr("Polygon Filter Layers"), QgsProcessing.TypeVectorPolygon, - optional=True + optional=True, ) ) self.addParameter( QgsProcessingParameterVectorLayer( self.GEOGRAPHIC_BOUNDARY, - self.tr('Geographic Boundary (this layer only filters the output dangles)'), + self.tr( + "Geographic Boundary (this layer only filters the output dangles)" + ), [QgsProcessing.TypeVectorPolygon], - optional=True + optional=True, ) ) self.addParameter( QgsProcessingParameterFeatureSink( - self.FLAGS, - self.tr('{0} Flags').format(self.displayName()) + self.FLAGS, self.tr("{0} Flags").format(self.displayName()) ) ) @@ -115,13 +117,16 @@ def processAlgorithm(self, parameters, context, feedback): inputLyr = self.parameterAsVectorLayer(parameters, self.INPUT, context) onlySelected = self.parameterAsBool(parameters, self.SELECTED, context) minLength = self.parameterAsDouble(parameters, self.MIN_LENGTH, context) - searchRadius = self.parameterAsDouble( - parameters, self.SEARCH_RADIUS, context) + searchRadius = self.parameterAsDouble(parameters, self.SEARCH_RADIUS, context) lineFilterLyrList = self.parameterAsLayerList( - parameters, self.LINEFILTERLAYERS, context) + parameters, self.LINEFILTERLAYERS, context + ) polygonFilterLyrList = self.parameterAsLayerList( - parameters, self.POLYGONFILTERLAYERS, context) - geographicBoundsLyr = self.parameterAsVectorLayer(parameters, self.GEOGRAPHIC_BOUNDARY, context) + parameters, self.POLYGONFILTERLAYERS, context + ) + geographicBoundsLyr = self.parameterAsVectorLayer( + parameters, self.GEOGRAPHIC_BOUNDARY, context + ) self.prepareFlagSink(parameters, inputLyr, QgsWkbTypes.LineString, context) if inputLyr is None: return {self.FLAGS: self.flag_id} @@ -130,7 +135,7 @@ def processAlgorithm(self, parameters, context, feedback): feedbackTotal = 2 multiStepFeedback = QgsProcessingMultiStepFeedback(feedbackTotal, feedback) multiStepFeedback.setCurrentStep(0) - multiStepFeedback.setProgressText(self.tr('Getting Dangles...')) + multiStepFeedback.setProgressText(self.tr("Getting Dangles...")) dangleLyr = AlgRunner().runIdentifyDangles( inputLayer=inputLyr, searchRadius=searchRadius, @@ -141,30 +146,36 @@ def processAlgorithm(self, parameters, context, feedback): ignoreDanglesOnUnsegmentedLines=True, inputIsBoundaryLayer=True, geographicBoundsLyr=geographicBoundsLyr, - feedback=multiStepFeedback + feedback=multiStepFeedback, ) - + multiStepFeedback.setCurrentStep(1) - multiStepFeedback.setProgressText(self.tr('Raising flags...')) + multiStepFeedback.setProgressText(self.tr("Raising flags...")) nDangles = dangleLyr.featureCount() if nDangles == 0: return {self.FLAGS: self.flag_id} # currentValue = feedback.progress() - currentTotal = 100/nDangles + currentTotal = 100 / nDangles for current, feat in enumerate(dangleLyr.getFeatures()): if multiStepFeedback.isCanceled(): break dangleGeom = feat.geometry() dangleBB = dangleGeom.boundingBox() request = QgsFeatureRequest().setNoAttributes().setFilterRect(dangleBB) - lineGeometry = [i.geometry() for i in inputLyr.getFeatures(request) if i.geometry().intersects(dangleGeom)][0] + lineGeometry = [ + i.geometry() + for i in inputLyr.getFeatures(request) + if i.geometry().intersects(dangleGeom) + ][0] if lineGeometry.length() > minLength: continue self.flagFeature( lineGeometry, - self.tr(f'First order dangle on {inputLyr.name()} smaller than {minLength}') - ) - multiStepFeedback.setProgress(current*currentTotal) + self.tr( + f"First order dangle on {inputLyr.name()} smaller than {minLength}" + ), + ) + multiStepFeedback.setProgress(current * currentTotal) return {self.FLAGS: self.flag_id} def name(self): @@ -175,21 +186,21 @@ def name(self): lowercase alphanumeric characters only and no spaces or other formatting characters. """ - return 'identifysmallfirstorderdangles' + return "identifysmallfirstorderdangles" def displayName(self): """ Returns the translated algorithm name, which should be used for any user-visible display of the algorithm name. """ - return self.tr('Identify Small First Order Dangles') + return self.tr("Identify Small First Order Dangles") def group(self): """ Returns the name of the group this algorithm belongs to. This string should be localised. """ - return self.tr('Quality Assurance Tools (Identification Processes)') + return self.tr("Quality Assurance Tools (Identification Processes)") def groupId(self): """ @@ -199,10 +210,12 @@ def groupId(self): contain lowercase alphanumeric characters only and no spaces or other formatting characters. """ - return 'DSGTools: Quality Assurance Tools (Identification Processes)' + return "DSGTools: Quality Assurance Tools (Identification Processes)" def tr(self, string): - return QCoreApplication.translate('IdentifySmallFirstOrderDanglesAlgorithm', string) + return QCoreApplication.translate( + "IdentifySmallFirstOrderDanglesAlgorithm", string + ) def createInstance(self): - return IdentifySmallFirstOrderDanglesAlgorithm() \ No newline at end of file + return IdentifySmallFirstOrderDanglesAlgorithm() diff --git a/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/identifySmallHolesAlgorithm.py b/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/identifySmallHolesAlgorithm.py index 0eb240c57..06a9db7ba 100644 --- a/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/identifySmallHolesAlgorithm.py +++ b/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/identifySmallHolesAlgorithm.py @@ -22,17 +22,18 @@ # from qgis.PyQt.QtCore import (QCoreApplication, QVariant) from PyQt5.QtCore import QCoreApplication, QVariant -from qgis.core import (QgsProcessing, - QgsFeatureSink, - QgsProcessingParameterFeatureSink, - QgsProcessingParameterNumber, - QgsCoordinateReferenceSystem, - QgsGeometry, - QgsField, - QgsFeature, - QgsFields, - QgsProcessingParameterMultipleLayers - ) +from qgis.core import ( + QgsProcessing, + QgsFeatureSink, + QgsProcessingParameterFeatureSink, + QgsProcessingParameterNumber, + QgsCoordinateReferenceSystem, + QgsGeometry, + QgsField, + QgsFeature, + QgsFields, + QgsProcessingParameterMultipleLayers, +) from qgis.utils import iface from .validationAlgorithm import ValidationAlgorithm @@ -40,45 +41,42 @@ class IdentifySmallHolesAlgorithm(ValidationAlgorithm): - INPUT_LAYER_LIST = 'INPUT_LAYER_LIST' - MAX_HOLE_SIZE = 'MAX_HOLE_SIZE' - OUTPUT = 'OUTPUT' - + INPUT_LAYER_LIST = "INPUT_LAYER_LIST" + MAX_HOLE_SIZE = "MAX_HOLE_SIZE" + OUTPUT = "OUTPUT" def initAlgorithm(self, config): self.addParameter( QgsProcessingParameterMultipleLayers( - 'INPUT_LAYER_LIST', - self.tr('Input layer(s)'), - QgsProcessing.TypeVectorPolygon + "INPUT_LAYER_LIST", + self.tr("Input layer(s)"), + QgsProcessing.TypeVectorPolygon, ) ) self.addParameter( QgsProcessingParameterNumber( - 'MAX_HOLE_SIZE', - self.tr('Tolerance'), - type=QgsProcessingParameterNumber.Double, - minValue=0) + "MAX_HOLE_SIZE", + self.tr("Tolerance"), + type=QgsProcessingParameterNumber.Double, + minValue=0, ) + ) self.addParameter( - QgsProcessingParameterFeatureSink( - self.OUTPUT, - self.tr('Flags') - ) + QgsProcessingParameterFeatureSink(self.OUTPUT, self.tr("Flags")) ) - def processAlgorithm(self, parameters, context, feedback): - feedback.setProgressText(self.tr('Searching holes smaller than tolerance')) - layerList = self.parameterAsLayerList(parameters,'INPUT_LAYER_LIST', context) - maxSize = self.parameterAsDouble (parameters,'MAX_HOLE_SIZE', context) + def processAlgorithm(self, parameters, context, feedback): + feedback.setProgressText(self.tr("Searching holes smaller than tolerance")) + layerList = self.parameterAsLayerList(parameters, "INPUT_LAYER_LIST", context) + maxSize = self.parameterAsDouble(parameters, "MAX_HOLE_SIZE", context) CRSstr = iface.mapCanvas().mapSettings().destinationCrs().authid() CRS = QgsCoordinateReferenceSystem(CRSstr) smallRings = [] listSize = len(layerList) - progressStep = 100/listSize if listSize else 0 + progressStep = 100 / listSize if listSize else 0 step = 0 - for step,layer in enumerate(layerList): + for step, layer in enumerate(layerList): if feedback.isCanceled(): return {self.OUTPUT: smallRings} for feature in layer.getFeatures(): @@ -89,35 +87,30 @@ def processAlgorithm(self, parameters, context, feedback): for ring in onlyrings: newRing = QgsGeometry.fromPolygonXY([ring]) print(newRing.area()) - if newRing.area() 0: return None - request = QgsFeatureRequest()\ - .setFilterExpression(f"AUTO in {tuple(idSet)}")\ - .setFlags(QgsFeatureRequest.NoGeometry)\ + request = ( + QgsFeatureRequest() + .setFilterExpression(f"AUTO in {tuple(idSet)}") + .setFlags(QgsFeatureRequest.NoGeometry) .setSubsetOfAttributes(fieldIdList) + ) f1, f2 = [i for i in localLyr.getFeatures(request)] differentFeats = any(f1[k] != f2[k] for k in fieldList) return geomWkb if not differentFeats else None - pool = concurrent.futures.ThreadPoolExecutor(max_workers=os.cpu_count()-1) + + pool = concurrent.futures.ThreadPoolExecutor(max_workers=os.cpu_count() - 1) futures = set() for current, (pointXY, idSet) in enumerate(initialAndEndPointDict.items()): @@ -210,7 +266,7 @@ def evaluate(pointXY, idSet): break futures.add(pool.submit(evaluate, pointXY, idSet)) multiStepFeedback.setProgress(current * stepSize) - + multiStepFeedback.setCurrentStep(1) for current, future in enumerate(concurrent.futures.as_completed(futures)): if multiStepFeedback.isCanceled(): @@ -220,10 +276,10 @@ def evaluate(pointXY, idSet): self.flagFeature( flagGeom=geomWkb, flagText=self.tr("Not merged lines with same attribute set"), - fromWkb=True + fromWkb=True, ) multiStepFeedback.setProgress(current * stepSize) - + def buildInitialAndEndPointDict(self, lyr, algRunner, context, feedback): pointDict = defaultdict(set) nSteps = 3 @@ -231,16 +287,12 @@ def buildInitialAndEndPointDict(self, lyr, algRunner, context, feedback): multiStepFeedback = QgsProcessingMultiStepFeedback(nSteps, feedback) multiStepFeedback.setCurrentStep(currentStep) boundaryLyr = algRunner.runBoundary( - inputLayer=lyr, - context=context, - feedback=multiStepFeedback + inputLayer=lyr, context=context, feedback=multiStepFeedback ) currentStep += 1 multiStepFeedback.setCurrentStep(currentStep) boundaryLyr = algRunner.runMultipartToSingleParts( - inputLayer=boundaryLyr, - context=context, - feedback=multiStepFeedback + inputLayer=boundaryLyr, context=context, feedback=multiStepFeedback ) currentStep += 1 @@ -248,7 +300,7 @@ def buildInitialAndEndPointDict(self, lyr, algRunner, context, feedback): featCount = boundaryLyr.featureCount() if featCount == 0: return pointDict - step = 100/featCount + step = 100 / featCount for current, feat in enumerate(boundaryLyr.getFeatures()): if multiStepFeedback.isCanceled(): break @@ -256,8 +308,7 @@ def buildInitialAndEndPointDict(self, lyr, algRunner, context, feedback): if geom is None or not geom.isGeosValid(): continue id = feat["AUTO"] - pointList = geom.asMultiPoint() if geom.isMultipart() else [ - geom.asPoint()] + pointList = geom.asMultiPoint() if geom.isMultipart() else [geom.asPoint()] for point in pointList: pointDict[point].add(id) multiStepFeedback.setProgress(current * step) diff --git a/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/identifyUnsharedVertexOnIntersectionsAlgorithm.py b/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/identifyUnsharedVertexOnIntersectionsAlgorithm.py index ecbd7badf..cebce8a38 100644 --- a/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/identifyUnsharedVertexOnIntersectionsAlgorithm.py +++ b/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/identifyUnsharedVertexOnIntersectionsAlgorithm.py @@ -23,28 +23,35 @@ from PyQt5.QtCore import QCoreApplication from DsgTools.core.GeometricTools.layerHandler import LayerHandler -from qgis.core import (QgsDataSourceUri, QgsFeature, QgsFeatureSink, - QgsProcessing, QgsProcessingAlgorithm, - QgsProcessingException, QgsProcessingMultiStepFeedback, - QgsProcessingOutputVectorLayer, - QgsProcessingParameterBoolean, - QgsProcessingParameterDistance, - QgsProcessingParameterFeatureSink, - QgsProcessingParameterFeatureSource, - QgsProcessingParameterField, - QgsProcessingParameterMultipleLayers, - QgsProcessingParameterVectorLayer, QgsWkbTypes) +from qgis.core import ( + QgsDataSourceUri, + QgsFeature, + QgsFeatureSink, + QgsProcessing, + QgsProcessingAlgorithm, + QgsProcessingException, + QgsProcessingMultiStepFeedback, + QgsProcessingOutputVectorLayer, + QgsProcessingParameterBoolean, + QgsProcessingParameterDistance, + QgsProcessingParameterFeatureSink, + QgsProcessingParameterFeatureSource, + QgsProcessingParameterField, + QgsProcessingParameterMultipleLayers, + QgsProcessingParameterVectorLayer, + QgsWkbTypes, +) from ...algRunner import AlgRunner from .validationAlgorithm import ValidationAlgorithm class IdentifyUnsharedVertexOnIntersectionsAlgorithm(ValidationAlgorithm): - FLAGS = 'FLAGS' - INPUT_POINTS = 'INPUT_POINTS' - INPUT_LINES = 'INPUT_LINES' - INPUT_POLYGONS = 'INPUT_POLYGONS' - SELECTED = 'SELECTED' + FLAGS = "FLAGS" + INPUT_POINTS = "INPUT_POINTS" + INPUT_LINES = "INPUT_LINES" + INPUT_POLYGONS = "INPUT_POLYGONS" + SELECTED = "SELECTED" def initAlgorithm(self, config): """ @@ -53,39 +60,37 @@ def initAlgorithm(self, config): self.addParameter( QgsProcessingParameterMultipleLayers( self.INPUT_POINTS, - self.tr('Point Layers'), + self.tr("Point Layers"), QgsProcessing.TypeVectorPoint, - optional=True + optional=True, ) ) self.addParameter( QgsProcessingParameterMultipleLayers( self.INPUT_LINES, - self.tr('Linestring Layers'), + self.tr("Linestring Layers"), QgsProcessing.TypeVectorLine, - optional=True + optional=True, ) ) self.addParameter( QgsProcessingParameterMultipleLayers( self.INPUT_POLYGONS, - self.tr('Polygon Layers'), + self.tr("Polygon Layers"), QgsProcessing.TypeVectorPolygon, - optional=True + optional=True, ) ) self.addParameter( QgsProcessingParameterBoolean( - self.SELECTED, - self.tr('Process only selected features') + self.SELECTED, self.tr("Process only selected features") ) ) self.addParameter( QgsProcessingParameterFeatureSink( - self.FLAGS, - self.tr('{0} Flags').format(self.displayName()) + self.FLAGS, self.tr("{0} Flags").format(self.displayName()) ) ) @@ -95,34 +100,22 @@ def processAlgorithm(self, parameters, context, feedback): """ layerHandler = LayerHandler() inputPointLyrList = self.parameterAsLayerList( - parameters, - self.INPUT_POINTS, - context + parameters, self.INPUT_POINTS, context ) inputLineLyrList = self.parameterAsLayerList( - parameters, - self.INPUT_LINES, - context + parameters, self.INPUT_LINES, context ) inputPolygonLyrList = self.parameterAsLayerList( - parameters, - self.INPUT_POLYGONS, - context + parameters, self.INPUT_POLYGONS, context ) if inputPointLyrList + inputLineLyrList + inputPolygonLyrList == []: - raise QgsProcessingException( - self.tr('Select at least one layer') - ) - onlySelected = self.parameterAsBool( - parameters, - self.SELECTED, - context - ) + raise QgsProcessingException(self.tr("Select at least one layer")) + onlySelected = self.parameterAsBool(parameters, self.SELECTED, context) self.prepareFlagSink( parameters, (inputPointLyrList + inputLineLyrList + inputPolygonLyrList)[0], QgsWkbTypes.Point, - context + context, ) # Compute the number of steps to display within the progress bar and # get features from source @@ -133,21 +126,16 @@ def processAlgorithm(self, parameters, context, feedback): inputLineLyrList, inputPolygonLyrList, onlySelected=onlySelected, - feedback=multiStepFeedback + feedback=multiStepFeedback, ) multiStepFeedback.setCurrentStep(1) - self.raiseFeaturesFlags( - usharedIntersectionSet, - multiStepFeedback - ) + self.raiseFeaturesFlags(usharedIntersectionSet, multiStepFeedback) return {self.FLAGS: self.flag_id} def raiseFeaturesFlags(self, usharedIntersectionSet, feedback): - size = 100/len(usharedIntersectionSet) if usharedIntersectionSet else 0 - flagText = self.tr( - 'Unshared vertex between the intersections of input layers.' - ) + size = 100 / len(usharedIntersectionSet) if usharedIntersectionSet else 0 + flagText = self.tr("Unshared vertex between the intersections of input layers.") for current, geomWkb in enumerate(usharedIntersectionSet): if feedback.isCanceled(): break @@ -162,21 +150,21 @@ def name(self): lowercase alphanumeric characters only and no spaces or other formatting characters. """ - return 'identifyunsharedvertexonintersectionsalgorithm' + return "identifyunsharedvertexonintersectionsalgorithm" def displayName(self): """ Returns the translated algorithm name, which should be used for any user-visible display of the algorithm name. """ - return self.tr('Identify Unshared Vertex on Intersections') + return self.tr("Identify Unshared Vertex on Intersections") def group(self): """ Returns the name of the group this algorithm belongs to. This string should be localised. """ - return self.tr('Quality Assurance Tools (Identification Processes)') + return self.tr("Quality Assurance Tools (Identification Processes)") def groupId(self): """ @@ -186,10 +174,12 @@ def groupId(self): contain lowercase alphanumeric characters only and no spaces or other formatting characters. """ - return 'DSGTools: Quality Assurance Tools (Identification Processes)' + return "DSGTools: Quality Assurance Tools (Identification Processes)" def tr(self, string): - return QCoreApplication.translate('IdentifyUnsharedVertexOnIntersectionsAlgorithm', string) + return QCoreApplication.translate( + "IdentifyUnsharedVertexOnIntersectionsAlgorithm", string + ) def createInstance(self): return IdentifyUnsharedVertexOnIntersectionsAlgorithm() diff --git a/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/identifyUnsharedVertexOnSharedEdgesAlgorithm.py b/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/identifyUnsharedVertexOnSharedEdgesAlgorithm.py index bb9cd2907..c36fe0711 100644 --- a/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/identifyUnsharedVertexOnSharedEdgesAlgorithm.py +++ b/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/identifyUnsharedVertexOnSharedEdgesAlgorithm.py @@ -23,28 +23,35 @@ from PyQt5.QtCore import QCoreApplication from DsgTools.core.GeometricTools.layerHandler import LayerHandler -from qgis.core import (QgsDataSourceUri, QgsFeature, QgsFeatureSink, - QgsProcessing, QgsProcessingAlgorithm, - QgsProcessingException, QgsProcessingMultiStepFeedback, - QgsProcessingOutputVectorLayer, - QgsProcessingParameterBoolean, - QgsProcessingParameterDistance, - QgsProcessingParameterFeatureSink, - QgsProcessingParameterFeatureSource, - QgsProcessingParameterField, - QgsProcessingParameterMultipleLayers, - QgsProcessingParameterVectorLayer, QgsWkbTypes) +from qgis.core import ( + QgsDataSourceUri, + QgsFeature, + QgsFeatureSink, + QgsProcessing, + QgsProcessingAlgorithm, + QgsProcessingException, + QgsProcessingMultiStepFeedback, + QgsProcessingOutputVectorLayer, + QgsProcessingParameterBoolean, + QgsProcessingParameterDistance, + QgsProcessingParameterFeatureSink, + QgsProcessingParameterFeatureSource, + QgsProcessingParameterField, + QgsProcessingParameterMultipleLayers, + QgsProcessingParameterVectorLayer, + QgsWkbTypes, +) from ...algRunner import AlgRunner from .validationAlgorithm import ValidationAlgorithm class IdentifyUnsharedVertexOnSharedEdgesAlgorithm(ValidationAlgorithm): - FLAGS = 'FLAGS' - INPUT_LINES = 'INPUT_LINES' - INPUT_POLYGONS = 'INPUT_POLYGONS' - SELECTED = 'SELECTED' - SEARCH_RADIUS = 'SEARCH_RADIUS' + FLAGS = "FLAGS" + INPUT_LINES = "INPUT_LINES" + INPUT_POLYGONS = "INPUT_POLYGONS" + SELECTED = "SELECTED" + SEARCH_RADIUS = "SEARCH_RADIUS" def initAlgorithm(self, config): """ @@ -53,39 +60,35 @@ def initAlgorithm(self, config): self.addParameter( QgsProcessingParameterMultipleLayers( self.INPUT_LINES, - self.tr('Linestring Layers'), + self.tr("Linestring Layers"), QgsProcessing.TypeVectorLine, - optional=True + optional=True, ) ) self.addParameter( QgsProcessingParameterMultipleLayers( self.INPUT_POLYGONS, - self.tr('Polygon Layers'), + self.tr("Polygon Layers"), QgsProcessing.TypeVectorPolygon, - optional=True + optional=True, ) ) self.addParameter( QgsProcessingParameterBoolean( - self.SELECTED, - self.tr('Process only selected features') + self.SELECTED, self.tr("Process only selected features") ) ) self.addParameter( QgsProcessingParameterDistance( - self.SEARCH_RADIUS, - self.tr('Search Radius'), - defaultValue=1.0 + self.SEARCH_RADIUS, self.tr("Search Radius"), defaultValue=1.0 ) ) self.addParameter( QgsProcessingParameterFeatureSink( - self.FLAGS, - self.tr('{0} Flags').format(self.displayName()) + self.FLAGS, self.tr("{0} Flags").format(self.displayName()) ) ) @@ -95,34 +98,20 @@ def processAlgorithm(self, parameters, context, feedback): """ layerHandler = LayerHandler() inputLineLyrList = self.parameterAsLayerList( - parameters, - self.INPUT_LINES, - context + parameters, self.INPUT_LINES, context ) inputPolygonLyrList = self.parameterAsLayerList( - parameters, - self.INPUT_POLYGONS, - context + parameters, self.INPUT_POLYGONS, context ) if inputLineLyrList + inputPolygonLyrList == []: - raise QgsProcessingException( - self.tr('Select at least one layer') - ) - onlySelected = self.parameterAsBool( - parameters, - self.SELECTED, - context - ) - searchRadius = self.parameterAsDouble( - parameters, - self.SEARCH_RADIUS, - context - ) + raise QgsProcessingException(self.tr("Select at least one layer")) + onlySelected = self.parameterAsBool(parameters, self.SELECTED, context) + searchRadius = self.parameterAsDouble(parameters, self.SEARCH_RADIUS, context) self.prepareFlagSink( parameters, (inputLineLyrList + inputPolygonLyrList)[0], QgsWkbTypes.Point, - context + context, ) # Compute the number of steps to display within the progress bar and # get features from source @@ -133,32 +122,24 @@ def processAlgorithm(self, parameters, context, feedback): inputPolygonLyrList, searchRadius, onlySelected=onlySelected, - feedback=multiStepFeedback + feedback=multiStepFeedback, ) multiStepFeedback.setCurrentStep(1) - self.raiseFeaturesFlags( - vertexNearEdgeFlagDict, - multiStepFeedback - ) + self.raiseFeaturesFlags(vertexNearEdgeFlagDict, multiStepFeedback) return {self.FLAGS: self.flag_id} def raiseFeaturesFlags(self, geomDict, feedback): - size = 100/len(geomDict) if geomDict else 0 + size = 100 / len(geomDict) if geomDict else 0 for current, (featid, vertexDict) in enumerate(geomDict.items()): if feedback.isCanceled(): break for vertexWkt, flagDict in vertexDict.items(): - edgeText = ', '.join( - [edge.asWkt() for edge in flagDict['edges']] - ) + edgeText = ", ".join([edge.asWkt() for edge in flagDict["edges"]]) flagText = self.tr( - 'Vertex {vertex_geom} is near edge(s) {edge_text}.' - ).format( - vertex_geom=vertexWkt, - edge_text=edgeText - ) - flagGeom = flagDict['flagGeom'] + "Vertex {vertex_geom} is near edge(s) {edge_text}." + ).format(vertex_geom=vertexWkt, edge_text=edgeText) + flagGeom = flagDict["flagGeom"] self.flagFeature(flagGeom, flagText) feedback.setProgress(size * current) @@ -170,21 +151,21 @@ def name(self): lowercase alphanumeric characters only and no spaces or other formatting characters. """ - return 'identifyunsharedvertexonsharededgesalgorithm' + return "identifyunsharedvertexonsharededgesalgorithm" def displayName(self): """ Returns the translated algorithm name, which should be used for any user-visible display of the algorithm name. """ - return self.tr('Identify Unshared Vertex on Shared Edges') + return self.tr("Identify Unshared Vertex on Shared Edges") def group(self): """ Returns the name of the group this algorithm belongs to. This string should be localised. """ - return self.tr('Quality Assurance Tools (Identification Processes)') + return self.tr("Quality Assurance Tools (Identification Processes)") def groupId(self): """ @@ -194,10 +175,12 @@ def groupId(self): contain lowercase alphanumeric characters only and no spaces or other formatting characters. """ - return 'DSGTools: Quality Assurance Tools (Identification Processes)' + return "DSGTools: Quality Assurance Tools (Identification Processes)" def tr(self, string): - return QCoreApplication.translate('IdentifyUnsharedVertexOnSharedEdgesAlgorithm', string) + return QCoreApplication.translate( + "IdentifyUnsharedVertexOnSharedEdgesAlgorithm", string + ) def createInstance(self): return IdentifyUnsharedVertexOnSharedEdgesAlgorithm() diff --git a/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/identifyVertexNearEdgesAlgorithm.py b/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/identifyVertexNearEdgesAlgorithm.py index 753ad7010..ba23ed93c 100644 --- a/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/identifyVertexNearEdgesAlgorithm.py +++ b/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/identifyVertexNearEdgesAlgorithm.py @@ -23,21 +23,33 @@ from PyQt5.QtCore import QCoreApplication from DsgTools.core.GeometricTools.layerHandler import LayerHandler -from qgis.core import (QgsDataSourceUri, QgsFeature, QgsFeatureSink, QgsProcessing, - QgsProcessingAlgorithm, QgsProcessingException, QgsProcessingMultiStepFeedback, - QgsProcessingOutputVectorLayer, QgsProcessingParameterBoolean, QgsProcessingParameterDistance, - QgsProcessingParameterFeatureSink, QgsProcessingParameterFeatureSource, - QgsProcessingParameterField, QgsProcessingParameterVectorLayer, QgsWkbTypes) +from qgis.core import ( + QgsDataSourceUri, + QgsFeature, + QgsFeatureSink, + QgsProcessing, + QgsProcessingAlgorithm, + QgsProcessingException, + QgsProcessingMultiStepFeedback, + QgsProcessingOutputVectorLayer, + QgsProcessingParameterBoolean, + QgsProcessingParameterDistance, + QgsProcessingParameterFeatureSink, + QgsProcessingParameterFeatureSource, + QgsProcessingParameterField, + QgsProcessingParameterVectorLayer, + QgsWkbTypes, +) from ...algRunner import AlgRunner from .validationAlgorithm import ValidationAlgorithm class IdentifyVertexNearEdgesAlgorithm(ValidationAlgorithm): - FLAGS = 'FLAGS' - INPUT = 'INPUT' - SELECTED = 'SELECTED' - SEARCH_RADIUS = 'SEARCH_RADIUS' + FLAGS = "FLAGS" + INPUT = "INPUT" + SELECTED = "SELECTED" + SEARCH_RADIUS = "SEARCH_RADIUS" def initAlgorithm(self, config): """ @@ -46,33 +58,26 @@ def initAlgorithm(self, config): self.addParameter( QgsProcessingParameterVectorLayer( self.INPUT, - self.tr('Input layer'), - [ - QgsProcessing.TypeVectorLine, - QgsProcessing.TypeVectorPolygon - ] + self.tr("Input layer"), + [QgsProcessing.TypeVectorLine, QgsProcessing.TypeVectorPolygon], ) ) self.addParameter( QgsProcessingParameterBoolean( - self.SELECTED, - self.tr('Process only selected features') + self.SELECTED, self.tr("Process only selected features") ) ) self.addParameter( QgsProcessingParameterDistance( - self.SEARCH_RADIUS, - self.tr('Search Radius'), - defaultValue = 1.0 + self.SEARCH_RADIUS, self.tr("Search Radius"), defaultValue=1.0 ) ) self.addParameter( QgsProcessingParameterFeatureSink( - self.FLAGS, - self.tr('{0} Flags').format(self.displayName()) + self.FLAGS, self.tr("{0} Flags").format(self.displayName()) ) ) @@ -81,26 +86,14 @@ def processAlgorithm(self, parameters, context, feedback): Here is where the processing itself takes place. """ layerHandler = LayerHandler() - inputLyr = self.parameterAsVectorLayer( - parameters, - self.INPUT, - context - ) + inputLyr = self.parameterAsVectorLayer(parameters, self.INPUT, context) if inputLyr is None: raise QgsProcessingException( self.invalidSourceError(parameters, self.INPUT) ) - onlySelected = self.parameterAsBool( - parameters, - self.SELECTED, - context - ) - searchRadius = self.parameterAsDouble( - parameters, - self.SEARCH_RADIUS, - context - ) - # output flag type is a polygon because the flag will be a circle with + onlySelected = self.parameterAsBool(parameters, self.SELECTED, context) + searchRadius = self.parameterAsDouble(parameters, self.SEARCH_RADIUS, context) + # output flag type is a polygon because the flag will be a circle with # radius tol and center as the vertex self.prepareFlagSink(parameters, inputLyr, QgsWkbTypes.Point, context) # Compute the number of steps to display within the progress bar and @@ -112,35 +105,29 @@ def processAlgorithm(self, parameters, context, feedback): searchRadius, onlySelected=onlySelected, feedback=multiStepFeedback, - context=context + context=context, ) multiStepFeedback.setCurrentStep(1) - self.raiseFeaturesFlags( - inputLyr, - vertexNearEdgeFlagDict, - multiStepFeedback - ) + self.raiseFeaturesFlags(inputLyr, vertexNearEdgeFlagDict, multiStepFeedback) return {self.FLAGS: self.flag_id} def raiseFeaturesFlags(self, inputLyr, geomDict, feedback): - size = 100/len(geomDict) if geomDict else 0 + size = 100 / len(geomDict) if geomDict else 0 for current, (featid, vertexDict) in enumerate(geomDict.items()): if feedback.isCanceled(): break for vertexWkt, flagDict in vertexDict.items(): - edgeText = ', '.join( - [edge.asWkt() for edge in flagDict['edges']] - ) + edgeText = ", ".join([edge.asWkt() for edge in flagDict["edges"]]) flagText = self.tr( - 'Vertex {vertex_geom} from feature {feat_id} layer {lyr_name} is near edge(s) {edge_text}.' - ).format( - lyr_name=inputLyr.name(), - vertex_geom=vertexWkt, - feat_id=featid, - edge_text=edgeText - ) - flagGeom = flagDict['flagGeom'] + "Vertex {vertex_geom} from feature {feat_id} layer {lyr_name} is near edge(s) {edge_text}." + ).format( + lyr_name=inputLyr.name(), + vertex_geom=vertexWkt, + feat_id=featid, + edge_text=edgeText, + ) + flagGeom = flagDict["flagGeom"] self.flagFeature(flagGeom, flagText) feedback.setProgress(size * current) @@ -152,21 +139,21 @@ def name(self): lowercase alphanumeric characters only and no spaces or other formatting characters. """ - return 'identifyvertexnearedges' + return "identifyvertexnearedges" def displayName(self): """ Returns the translated algorithm name, which should be used for any user-visible display of the algorithm name. """ - return self.tr('Identify Vertex Near Edges') + return self.tr("Identify Vertex Near Edges") def group(self): """ Returns the name of the group this algorithm belongs to. This string should be localised. """ - return self.tr('Quality Assurance Tools (Identification Processes)') + return self.tr("Quality Assurance Tools (Identification Processes)") def groupId(self): """ @@ -176,10 +163,10 @@ def groupId(self): contain lowercase alphanumeric characters only and no spaces or other formatting characters. """ - return 'DSGTools: Quality Assurance Tools (Identification Processes)' + return "DSGTools: Quality Assurance Tools (Identification Processes)" def tr(self, string): - return QCoreApplication.translate('IdentifyVertexNearEdgesAlgorithm', string) + return QCoreApplication.translate("IdentifyVertexNearEdgesAlgorithm", string) def createInstance(self): return IdentifyVertexNearEdgesAlgorithm() diff --git a/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/identifyWrongBuildingAnglesAlgorithm.py b/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/identifyWrongBuildingAnglesAlgorithm.py index 404f2e6de..693014d52 100644 --- a/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/identifyWrongBuildingAnglesAlgorithm.py +++ b/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/identifyWrongBuildingAnglesAlgorithm.py @@ -24,24 +24,31 @@ from PyQt5.QtCore import QCoreApplication from DsgTools.core.GeometricTools.geometryHandler import GeometryHandler -from qgis.core import (QgsDataSourceUri, QgsFeature, QgsFeatureSink, - QgsProcessing, QgsProcessingAlgorithm, - QgsProcessingOutputVectorLayer, - QgsProcessingParameterBoolean, - QgsProcessingParameterFeatureSink, - QgsProcessingParameterFeatureSource, - QgsProcessingParameterNumber, - QgsProcessingParameterVectorLayer, QgsWkbTypes, - QgsProcessingException) +from qgis.core import ( + QgsDataSourceUri, + QgsFeature, + QgsFeatureSink, + QgsProcessing, + QgsProcessingAlgorithm, + QgsProcessingOutputVectorLayer, + QgsProcessingParameterBoolean, + QgsProcessingParameterFeatureSink, + QgsProcessingParameterFeatureSource, + QgsProcessingParameterNumber, + QgsProcessingParameterVectorLayer, + QgsWkbTypes, + QgsProcessingException, +) from .validationAlgorithm import ValidationAlgorithm + class IdentifyWrongBuildingAnglesAlgorithm(ValidationAlgorithm): - FLAGS = 'FLAGS' - INPUT = 'INPUT' - TOLERANCE = 'TOLERANCE' - SELECTED = 'SELECTED' - IGNORE_CIRCLES = 'IGNORE_CIRCLES' + FLAGS = "FLAGS" + INPUT = "INPUT" + TOLERANCE = "TOLERANCE" + SELECTED = "SELECTED" + IGNORE_CIRCLES = "IGNORE_CIRCLES" def initAlgorithm(self, config): """ @@ -49,39 +56,35 @@ def initAlgorithm(self, config): """ self.addParameter( QgsProcessingParameterVectorLayer( - self.INPUT, - self.tr('Input layer'), - [QgsProcessing.TypeVectorPolygon] + self.INPUT, self.tr("Input layer"), [QgsProcessing.TypeVectorPolygon] ) ) self.addParameter( QgsProcessingParameterBoolean( - self.SELECTED, - self.tr('Process only selected features') + self.SELECTED, self.tr("Process only selected features") ) ) self.addParameter( QgsProcessingParameterNumber( self.TOLERANCE, - self.tr('Angular tolerance in decimal degrees'), + self.tr("Angular tolerance in decimal degrees"), minValue=0, defaultValue=0.1, - type=QgsProcessingParameterNumber.Double + type=QgsProcessingParameterNumber.Double, ) ) self.addParameter( QgsProcessingParameterBoolean( self.IGNORE_CIRCLES, - self.tr('Ignore circular geometries'), - defaultValue = False + self.tr("Ignore circular geometries"), + defaultValue=False, ) ) self.addParameter( QgsProcessingParameterFeatureSink( - self.FLAGS, - self.tr('{0} Flags').format(self.displayName()) + self.FLAGS, self.tr("{0} Flags").format(self.displayName()) ) ) @@ -92,14 +95,18 @@ def processAlgorithm(self, parameters, context, feedback): geometryHandler = GeometryHandler() inputLyr = self.parameterAsVectorLayer(parameters, self.INPUT, context) if inputLyr is None: - raise QgsProcessingException(self.invalidSourceError(parameters, self.INPUT)) + raise QgsProcessingException( + self.invalidSourceError(parameters, self.INPUT) + ) onlySelected = self.parameterAsBool(parameters, self.SELECTED, context) tol = self.parameterAsDouble(parameters, self.TOLERANCE, context) ignoreCircles = self.parameterAsBool(parameters, self.IGNORE_CIRCLES, context) self.prepareFlagSink(parameters, inputLyr, QgsWkbTypes.Point, context) # Compute the number of steps to display within the progress bar and # get features from source - featureList, total = self.getIteratorAndFeatureCount(inputLyr, onlySelected = onlySelected) + featureList, total = self.getIteratorAndFeatureCount( + inputLyr, onlySelected=onlySelected + ) for current, feat in enumerate(featureList): # Stop the algorithm if cancel button has been clicked @@ -110,12 +117,12 @@ def processAlgorithm(self, parameters, context, feedback): outOfBoundsList = geometryHandler.getInvalidBuildingAngle(feat, tol) if outOfBoundsList: for item in outOfBoundsList: - flagText = self.tr('Feature from layer {name} with id={id} has invalid building angle ({angle})').format( - name=inputLyr.name(), - id=item['feat_id'], - angle=item['angle'] - ) - self.flagFeature(item['geom'], flagText) + flagText = self.tr( + "Feature from layer {name} with id={id} has invalid building angle ({angle})" + ).format( + name=inputLyr.name(), id=item["feat_id"], angle=item["angle"] + ) + self.flagFeature(item["geom"], flagText) # Update the progress bar feedback.setProgress(int(current * total)) @@ -136,21 +143,21 @@ def name(self): lowercase alphanumeric characters only and no spaces or other formatting characters. """ - return 'identifywrongbuildinganglesalgorithm' + return "identifywrongbuildinganglesalgorithm" def displayName(self): """ Returns the translated algorithm name, which should be used for any user-visible display of the algorithm name. """ - return self.tr('Identify Wrong Building Angles') + return self.tr("Identify Wrong Building Angles") def group(self): """ Returns the name of the group this algorithm belongs to. This string should be localised. """ - return self.tr('Quality Assurance Tools (Identification Processes)') + return self.tr("Quality Assurance Tools (Identification Processes)") def groupId(self): """ @@ -160,10 +167,12 @@ def groupId(self): contain lowercase alphanumeric characters only and no spaces or other formatting characters. """ - return 'DSGTools: Quality Assurance Tools (Identification Processes)' + return "DSGTools: Quality Assurance Tools (Identification Processes)" def tr(self, string): - return QCoreApplication.translate('IdentifyWrongBuildingAnglesAlgorithm', string) + return QCoreApplication.translate( + "IdentifyWrongBuildingAnglesAlgorithm", string + ) def createInstance(self): return IdentifyWrongBuildingAnglesAlgorithm() diff --git a/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/identifyZAnglesBetweenFeaturesAlgorithm.py b/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/identifyZAnglesBetweenFeaturesAlgorithm.py index 4f0877ae1..f38aaad67 100644 --- a/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/identifyZAnglesBetweenFeaturesAlgorithm.py +++ b/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/identifyZAnglesBetweenFeaturesAlgorithm.py @@ -25,48 +25,56 @@ import os from PyQt5.QtCore import QCoreApplication, QVariant -from qgis.core import (QgsFeature, QgsFeatureRequest, QgsField, QgsFields, - QgsGeometry, QgsGeometryUtils, QgsPoint, QgsPointXY, - QgsProcessing, QgsProcessingParameterFeatureSink, - QgsProcessingParameterFeatureSource, - QgsProcessingParameterNumber, QgsProject, QgsWkbTypes, - QgsProcessingMultiStepFeedback) +from qgis.core import ( + QgsFeature, + QgsFeatureRequest, + QgsField, + QgsFields, + QgsGeometry, + QgsGeometryUtils, + QgsPoint, + QgsPointXY, + QgsProcessing, + QgsProcessingParameterFeatureSink, + QgsProcessingParameterFeatureSource, + QgsProcessingParameterNumber, + QgsProject, + QgsWkbTypes, + QgsProcessingMultiStepFeedback, +) from .validationAlgorithm import ValidationAlgorithm class identifyZAnglesBetweenFeaturesAlgorithm(ValidationAlgorithm): - INPUT = 'INPUT' - ANGLE = 'ANGLE' - OUTPUT = 'OUTPUT' + INPUT = "INPUT" + ANGLE = "ANGLE" + OUTPUT = "OUTPUT" def initAlgorithm(self, config=None): self.addParameter( QgsProcessingParameterFeatureSource( self.INPUT, - self.tr('Input'), + self.tr("Input"), [ QgsProcessing.TypeVectorLine, QgsProcessing.TypeVectorPolygon, - ] + ], ) ) self.addParameter( QgsProcessingParameterNumber( self.ANGLE, - self.tr('Minimum angle'), + self.tr("Minimum angle"), QgsProcessingParameterNumber.Double, defaultValue=300, minValue=270, - maxValue=360 + maxValue=360, ) ) self.addParameter( - QgsProcessingParameterFeatureSink( - self.OUTPUT, - self.tr('Flags') - ) + QgsProcessingParameterFeatureSink(self.OUTPUT, self.tr("Flags")) ) def processAlgorithm(self, parameters, context, feedback): @@ -76,33 +84,49 @@ def processAlgorithm(self, parameters, context, feedback): crs = QgsProject.instance().crs() self.fields = QgsFields() - self.fields.append(QgsField('source', QVariant.String)) + self.fields.append(QgsField("source", QVariant.String)) + + sink, dest_id = self.parameterAsSink( + parameters, self.OUTPUT, context, self.fields, QgsWkbTypes.LineString, crs + ) - sink, dest_id = self.parameterAsSink(parameters, self.OUTPUT, context, self.fields, - QgsWkbTypes.LineString, crs) - - nSteps = 2 if QgsWkbTypes.geometryType(inputSource.wkbType()) == QgsWkbTypes.LineGeometry else 1 - multiStepFeedback = feedback if nSteps == 1 else QgsProcessingMultiStepFeedback(nSteps, feedback) + nSteps = ( + 2 + if QgsWkbTypes.geometryType(inputSource.wkbType()) + == QgsWkbTypes.LineGeometry + else 1 + ) + multiStepFeedback = ( + feedback + if nSteps == 1 + else QgsProcessingMultiStepFeedback(nSteps, feedback) + ) currentStep = 0 - if QgsWkbTypes.geometryType(inputSource.wkbType()) == QgsWkbTypes.LineGeometry: + if QgsWkbTypes.geometryType(inputSource.wkbType()) == QgsWkbTypes.LineGeometry: multiStepFeedback.setProgressText(self.tr("Evaluating z within lines")) multiStepFeedback.setCurrentStep(currentStep) - featsToAnalyse.extend(self.caseBetweenLines(inputSource, angle, feedback=multiStepFeedback)) + featsToAnalyse.extend( + self.caseBetweenLines(inputSource, angle, feedback=multiStepFeedback) + ) currentStep += 1 - multiStepFeedback.setProgressText(self.tr("Evaluating z within features geometries")) + multiStepFeedback.setProgressText( + self.tr("Evaluating z within features geometries") + ) multiStepFeedback.setCurrentStep(currentStep) - featsToAnalyse.extend(self.caseInternLine(inputSource, angle, feedback=multiStepFeedback)) + featsToAnalyse.extend( + self.caseInternLine(inputSource, angle, feedback=multiStepFeedback) + ) currentStep += 1 else: multiStepFeedback.setProgressText(self.tr("Evaluating z within polygons")) - featsToAnalyse.extend(self.caseInternArea(inputSource, angle, feedback=multiStepFeedback)) + featsToAnalyse.extend( + self.caseInternArea(inputSource, angle, feedback=multiStepFeedback) + ) sink.addFeatures(featsToAnalyse) - return { - self.OUTPUT: dest_id - } + return {self.OUTPUT: dest_id} def caseInternLine(self, lines, angle, feedback=None): featsToAnalyse = [] @@ -118,11 +142,15 @@ def caseInternLine(self, lines, angle, feedback=None): v2 = next(vertices) if vertices.hasNext() else None v3 = next(vertices) if vertices.hasNext() else None for v4 in vertices: - newFeat = self.checkIntersectionAndCreateFeature4p(v1, v2, v3, v4, angle) if all((v1,v2,v3,v4)) else None + newFeat = ( + self.checkIntersectionAndCreateFeature4p(v1, v2, v3, v4, angle) + if all((v1, v2, v3, v4)) + else None + ) if newFeat: - newFeat.setAttribute('source',lines.sourceName()) + newFeat.setAttribute("source", lines.sourceName()) featsToAnalyse.append(newFeat) - v1,v2,v3 = v2,v3,v4 + v1, v2, v3 = v2, v3, v4 if feedback is not None: feedback.setProgress(current * total) return featsToAnalyse @@ -132,20 +160,28 @@ def caseInternArea(self, areas, angle, feedback=None): areaCount = areas.featureCount() if areaCount == 0: return featsToAnalyse - total = 100/areaCount + total = 100 / areaCount for current, feat in enumerate(areas.getFeatures()): if feedback is not None and feedback.isCanceled(): break geom = feat.geometry() - multiPolygons = geom.asMultiPolygon()[0] if geom.isMultipart() else geom.asPolygon() + multiPolygons = ( + geom.asMultiPolygon()[0] if geom.isMultipart() else geom.asPolygon() + ) for vertices in multiPolygons: - for i in range(len(vertices)-3): - v1, v2, v3, v4 = vertices[i:i+4] - newFeat = self.checkIntersectionAndCreateFeature4p(v1, v2, v3, v4, angle) if all((v1,v2,v3,v4)) else None + for i in range(len(vertices) - 3): + v1, v2, v3, v4 = vertices[i : i + 4] + newFeat = ( + self.checkIntersectionAndCreateFeature4p(v1, v2, v3, v4, angle) + if all((v1, v2, v3, v4)) + else None + ) if newFeat: - newFeat.setAttribute('source',areas.sourceName()) + newFeat.setAttribute("source", areas.sourceName()) featsToAnalyse.append(newFeat) - newFeat = self.checkIntersectionAndCreateFeature4p(vertices[-3], vertices[-2],vertices[-1], vertices[1], angle) + newFeat = self.checkIntersectionAndCreateFeature4p( + vertices[-3], vertices[-2], vertices[-1], vertices[1], angle + ) if newFeat: featsToAnalyse.append(newFeat) if feedback is not None: @@ -158,6 +194,7 @@ def caseBetweenLines(self, lines, angle, feedback=None): if lineCount == 0: return featsToAnalyse total = 100 / lineCount + def evaluateLine(feat1): featsToAnalyse = [] if feedback is not None and feedback.isCanceled(): @@ -170,36 +207,42 @@ def evaluateLine(feat1): gfeat2 = feat2.geometry() if gfeat1.intersects(gfeat2): if len(list(gfeat1.vertices())) > 2: - toAnalyse = self.checkIfIntersectionIsValid2g(gfeat1, gfeat2, angle) + toAnalyse = self.checkIfIntersectionIsValid2g( + gfeat1, gfeat2, angle + ) if isinstance(toAnalyse, tuple): toAnalyse = (x for x in toAnalyse if x) for feat in toAnalyse: - feat.setAttribute('source',lines.sourceName()) + feat.setAttribute("source", lines.sourceName()) featsToAnalyse.append(feat) elif toAnalyse: - toAnalyse.setAttribute('source',lines.sourceName()) + toAnalyse.setAttribute("source", lines.sourceName()) featsToAnalyse.append(toAnalyse) # Gets the case when the z angle is created by 3 feats (at least one has only two vertices) elif len(list(gfeat1.vertices())) == 2: - request2 = QgsFeatureRequest().setFilterRect(gfeat2.boundingBox()) + request2 = QgsFeatureRequest().setFilterRect( + gfeat2.boundingBox() + ) for k, feat3 in enumerate(lines.getFeatures(request2)): if any([(k > i), (k > j)]): continue gfeat3 = feat3.geometry() if not gfeat3.touches(gfeat1): - toAnalyse = self.checkIfIntersectionIsValid3g(gfeat1, gfeat2, gfeat3, angle) + toAnalyse = self.checkIfIntersectionIsValid3g( + gfeat1, gfeat2, gfeat3, angle + ) if isinstance(toAnalyse, tuple): toAnalyse = (x for x in toAnalyse if x) for feat in toAnalyse: - feat.setAttribute('source',lines.sourceName()) + feat.setAttribute("source", lines.sourceName()) featsToAnalyse.append(feat) elif toAnalyse: - toAnalyse.setAttribute('source',lines.sourceName()) + toAnalyse.setAttribute("source", lines.sourceName()) featsToAnalyse.append(toAnalyse) return featsToAnalyse - + futures = set() - pool = concurrent.futures.ThreadPoolExecutor(os.cpu_count()-1) + pool = concurrent.futures.ThreadPoolExecutor(os.cpu_count() - 1) multiStepFeedback = QgsProcessingMultiStepFeedback(2, feedback) multiStepFeedback.setCurrentStep(0) multiStepFeedback.pushInfo(self.tr("Submitting tasks to thread")) @@ -207,7 +250,9 @@ def evaluateLine(feat1): futures.add(pool.submit(evaluateLine, feat1)) multiStepFeedback.setCurrentStep(1) multiStepFeedback.pushInfo(self.tr("Evaluating tasks")) - concurrent.futures.wait(futures, timeout=None, return_when=concurrent.futures.ALL_COMPLETED) + concurrent.futures.wait( + futures, timeout=None, return_when=concurrent.futures.ALL_COMPLETED + ) for current, future in enumerate(concurrent.futures.as_completed(futures)): if feedback is not None and feedback.isCanceled(): break @@ -217,16 +262,22 @@ def evaluateLine(feat1): return featsToAnalyse def checkIntersectionAndCreateFeature4p(self, v1, v2, v3, v4, angle): - angle1 = QgsGeometryUtils.angleBetweenThreePoints(v1.x(), v1.y(), v2.x(), v2.y(), v3.x(), v3.y()) - angle2 = QgsGeometryUtils.angleBetweenThreePoints(v2.x(), v2.y(), v3.x(), v3.y(), v4.x(), v4.y()) + angle1 = QgsGeometryUtils.angleBetweenThreePoints( + v1.x(), v1.y(), v2.x(), v2.y(), v3.x(), v3.y() + ) + angle2 = QgsGeometryUtils.angleBetweenThreePoints( + v2.x(), v2.y(), v3.x(), v3.y(), v4.x(), v4.y() + ) angle1 = math.degrees(angle1) angle2 = math.degrees(angle2) - if (angle1 > angle and angle2 < 360 - angle) or (angle1 < 360 - angle and angle2 > angle): + if (angle1 > angle and angle2 < 360 - angle) or ( + angle1 < 360 - angle and angle2 > angle + ): newFeat = QgsFeature(self.fields) if isinstance(v1, QgsPoint): - newFeat.setGeometry(QgsGeometry.fromPolyline([v1,v2,v3,v4])) + newFeat.setGeometry(QgsGeometry.fromPolyline([v1, v2, v3, v4])) elif isinstance(v1, QgsPointXY): - newFeat.setGeometry(QgsGeometry.fromPolylineXY([v1,v2,v3,v4])) + newFeat.setGeometry(QgsGeometry.fromPolylineXY([v1, v2, v3, v4])) return newFeat def checkIfIntersectionIsValid2g(self, g1, g2, angle): @@ -235,42 +286,79 @@ def checkIfIntersectionIsValid2g(self, g1, g2, angle): return False intersection = intersection.asPoint() - _, g1VertexIdx, g1PreviousVertexIdx, g1NextVertexIdx, _ = g1.closestVertex(intersection) - _, g2VertexIdx, g2PreviousVertexIdx, g2NextVertexIdx, _ = g2.closestVertex(intersection) + _, g1VertexIdx, g1PreviousVertexIdx, g1NextVertexIdx, _ = g1.closestVertex( + intersection + ) + _, g2VertexIdx, g2PreviousVertexIdx, g2NextVertexIdx, _ = g2.closestVertex( + intersection + ) vg1 = list(g1.vertices()) vg2 = list(g2.vertices()) # Intersections between beginning / end of v1 and v2 if g1NextVertexIdx == g2PreviousVertexIdx == -1: - feat = self.checkIntersectionAndCreateFeature4p(vg1[g1PreviousVertexIdx-1], vg1[g1PreviousVertexIdx], vg1[g1VertexIdx], vg2[g2NextVertexIdx], angle) + feat = self.checkIntersectionAndCreateFeature4p( + vg1[g1PreviousVertexIdx - 1], + vg1[g1PreviousVertexIdx], + vg1[g1VertexIdx], + vg2[g2NextVertexIdx], + angle, + ) return feat elif g2NextVertexIdx == g1PreviousVertexIdx == -1: - feat = self.checkIntersectionAndCreateFeature4p(vg2[g2PreviousVertexIdx], vg2[g2VertexIdx], vg1[g1NextVertexIdx], vg1[g1NextVertexIdx+1], angle) + feat = self.checkIntersectionAndCreateFeature4p( + vg2[g2PreviousVertexIdx], + vg2[g2VertexIdx], + vg1[g1NextVertexIdx], + vg1[g1NextVertexIdx + 1], + angle, + ) return feat def checkIfIntersectionIsValid3g(self, g1, g2, g3, angle): inter12 = g1.intersection(g2) inter23 = g2.intersection(g3) - if any((inter12.wkbType() != QgsWkbTypes.Point, inter23.wkbType() != QgsWkbTypes.Point)): + if any( + ( + inter12.wkbType() != QgsWkbTypes.Point, + inter23.wkbType() != QgsWkbTypes.Point, + ) + ): return False inter12 = inter12.asPoint() inter23 = inter23.asPoint() - _, g1VertexIdx, g1PreviousVertexIdx, g1NextVertexIdx, _ = g1.closestVertex(inter12) - _, g3VertexIdx, g3PreviousVertexIdx, g3NextVertexIdx, _ = g3.closestVertex(inter23) + _, g1VertexIdx, g1PreviousVertexIdx, g1NextVertexIdx, _ = g1.closestVertex( + inter12 + ) + _, g3VertexIdx, g3PreviousVertexIdx, g3NextVertexIdx, _ = g3.closestVertex( + inter23 + ) vg1 = list(g1.vertices()) vg3 = list(g3.vertices()) # Intersections between beginning / end of v1 and v2 if g1NextVertexIdx == g3PreviousVertexIdx == -1: - feat = self.checkIntersectionAndCreateFeature4p(vg1[g1PreviousVertexIdx], vg1[g1VertexIdx], vg3[g3VertexIdx], vg3[g3NextVertexIdx], angle) + feat = self.checkIntersectionAndCreateFeature4p( + vg1[g1PreviousVertexIdx], + vg1[g1VertexIdx], + vg3[g3VertexIdx], + vg3[g3NextVertexIdx], + angle, + ) return feat elif g3NextVertexIdx == g1PreviousVertexIdx == -1: - feat = self.checkIntersectionAndCreateFeature4p(vg3[g3PreviousVertexIdx], vg3[g3VertexIdx], vg1[g1VertexIdx], vg1[g1NextVertexIdx], angle) + feat = self.checkIntersectionAndCreateFeature4p( + vg3[g3PreviousVertexIdx], + vg3[g3VertexIdx], + vg1[g1VertexIdx], + vg1[g1NextVertexIdx], + angle, + ) return feat def name(self): @@ -281,21 +369,21 @@ def name(self): lowercase alphanumeric characters only and no spaces or other formatting characters. """ - return 'identifyzanglesbetweenfeatures' + return "identifyzanglesbetweenfeatures" def displayName(self): """ Returns the translated algorithm name, which should be used for any user-visible display of the algorithm name. """ - return self.tr('Identify Z Angles Between Features') + return self.tr("Identify Z Angles Between Features") def group(self): """ Returns the name of the group this algorithm belongs to. This string should be localised. """ - return self.tr('Quality Assurance Tools (Identification Processes)') + return self.tr("Quality Assurance Tools (Identification Processes)") def groupId(self): """ @@ -305,10 +393,12 @@ def groupId(self): contain lowercase alphanumeric characters only and no spaces or other formatting characters. """ - return 'DSGTools: Quality Assurance Tools (Identification Processes)' + return "DSGTools: Quality Assurance Tools (Identification Processes)" def tr(self, string): - return QCoreApplication.translate('identifyZAnglesBetweenFeaturesAlgorithm', string) + return QCoreApplication.translate( + "identifyZAnglesBetweenFeaturesAlgorithm", string + ) def createInstance(self): return identifyZAnglesBetweenFeaturesAlgorithm() diff --git a/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/lineOnLineOverlayerAlgorithm.py b/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/lineOnLineOverlayerAlgorithm.py index 3518f607c..5bae5cb95 100644 --- a/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/lineOnLineOverlayerAlgorithm.py +++ b/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/lineOnLineOverlayerAlgorithm.py @@ -24,30 +24,38 @@ import processing from DsgTools.core.GeometricTools.layerHandler import LayerHandler -from qgis.core import (QgsDataSourceUri, QgsFeature, QgsFeatureSink, - QgsGeometry, QgsProcessing, QgsProcessingAlgorithm, - QgsProcessingMultiStepFeedback, - QgsProcessingOutputVectorLayer, - QgsProcessingParameterBoolean, - QgsProcessingParameterDistance, - QgsProcessingParameterEnum, - QgsProcessingParameterFeatureSink, - QgsProcessingParameterFeatureSource, - QgsProcessingParameterField, - QgsProcessingParameterMultipleLayers, - QgsProcessingParameterNumber, - QgsProcessingParameterVectorLayer, QgsProcessingUtils, - QgsSpatialIndex, QgsWkbTypes) +from qgis.core import ( + QgsDataSourceUri, + QgsFeature, + QgsFeatureSink, + QgsGeometry, + QgsProcessing, + QgsProcessingAlgorithm, + QgsProcessingMultiStepFeedback, + QgsProcessingOutputVectorLayer, + QgsProcessingParameterBoolean, + QgsProcessingParameterDistance, + QgsProcessingParameterEnum, + QgsProcessingParameterFeatureSink, + QgsProcessingParameterFeatureSource, + QgsProcessingParameterField, + QgsProcessingParameterMultipleLayers, + QgsProcessingParameterNumber, + QgsProcessingParameterVectorLayer, + QgsProcessingUtils, + QgsSpatialIndex, + QgsWkbTypes, +) from ...algRunner import AlgRunner from .validationAlgorithm import ValidationAlgorithm class LineOnLineOverlayerAlgorithm(ValidationAlgorithm): - INPUT = 'INPUT' - SELECTED = 'SELECTED' - TOLERANCE = 'TOLERANCE' - OUTPUT = 'OUTPUT' + INPUT = "INPUT" + SELECTED = "SELECTED" + TOLERANCE = "TOLERANCE" + OUTPUT = "OUTPUT" def initAlgorithm(self, config): """ @@ -55,30 +63,26 @@ def initAlgorithm(self, config): """ self.addParameter( QgsProcessingParameterVectorLayer( - self.INPUT, - self.tr('Input layer'), - [QgsProcessing.TypeVectorLine ] + self.INPUT, self.tr("Input layer"), [QgsProcessing.TypeVectorLine] ) ) self.addParameter( QgsProcessingParameterBoolean( - self.SELECTED, - self.tr('Process only selected features') + self.SELECTED, self.tr("Process only selected features") ) ) self.addParameter( QgsProcessingParameterDistance( - self.TOLERANCE, - self.tr('Snap radius'), - parentParameterName=self.INPUT, - minValue=-1.0, - defaultValue=1.0 + self.TOLERANCE, + self.tr("Snap radius"), + parentParameterName=self.INPUT, + minValue=-1.0, + defaultValue=1.0, ) ) self.addOutput( QgsProcessingOutputVectorLayer( - self.OUTPUT, - self.tr('Original layer with overlayed lines') + self.OUTPUT, self.tr("Original layer with overlayed lines") ) ) @@ -97,50 +101,47 @@ def processAlgorithm(self, parameters, context, feedback): if tol > 0: multiStepFeedback.pushInfo( - self.tr( - 'Identifying dangles on {layer}...' - ).format(layer=inputLyr.name())) + self.tr("Identifying dangles on {layer}...").format( + layer=inputLyr.name() + ) + ) dangleLyr = algRunner.runIdentifyDangles( inputLyr, tol, context, feedback=multiStepFeedback, - onlySelected=onlySelected - ) + onlySelected=onlySelected, + ) multiStepFeedback.setCurrentStep(1) - layerHandler.filterDangles( - dangleLyr, - tol, - feedback=multiStepFeedback - ) + layerHandler.filterDangles(dangleLyr, tol, feedback=multiStepFeedback) multiStepFeedback.setCurrentStep(2) multiStepFeedback.pushInfo( - self.tr( - 'Snapping layer {layer} to dangles...' - ).format(layer=inputLyr.name())) + self.tr("Snapping layer {layer} to dangles...").format( + layer=inputLyr.name() + ) + ) algRunner.runSnapLayerOnLayer( inputLyr, dangleLyr, tol, context, feedback=multiStepFeedback, - onlySelected=onlySelected - ) + onlySelected=onlySelected, + ) multiStepFeedback.setCurrentStep(3) multiStepFeedback.pushInfo( - self.tr( - 'Cleanning layer {layer}...' - ).format(layer=inputLyr.name())) + self.tr("Cleanning layer {layer}...").format(layer=inputLyr.name()) + ) algRunner.runDsgToolsClean( inputLyr, context, snap=tol, feedback=multiStepFeedback, - onlySelected=onlySelected - ) + onlySelected=onlySelected, + ) return {self.OUTPUT: inputLyr} @@ -152,21 +153,21 @@ def name(self): lowercase alphanumeric characters only and no spaces or other formatting characters. """ - return 'lineonlineoverlayer' + return "lineonlineoverlayer" def displayName(self): """ Returns the translated algorithm name, which should be used for any user-visible display of the algorithm name. """ - return self.tr('Line on line overlayer') + return self.tr("Line on line overlayer") def group(self): """ Returns the name of the group this algorithm belongs to. This string should be localised. """ - return self.tr('Quality Assurance Tools (Manipulation Processes)') + return self.tr("Quality Assurance Tools (Manipulation Processes)") def groupId(self): """ @@ -176,10 +177,10 @@ def groupId(self): contain lowercase alphanumeric characters only and no spaces or other formatting characters. """ - return 'DSGTools: Quality Assurance Tools (Manipulation Processes)' + return "DSGTools: Quality Assurance Tools (Manipulation Processes)" def tr(self, string): - return QCoreApplication.translate('LineOnLineOverlayerAlgorithm', string) + return QCoreApplication.translate("LineOnLineOverlayerAlgorithm", string) def createInstance(self): return LineOnLineOverlayerAlgorithm() diff --git a/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/mergeLinesAlgorithm.py b/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/mergeLinesAlgorithm.py index 1869bc0c5..7ddd37b46 100644 --- a/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/mergeLinesAlgorithm.py +++ b/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/mergeLinesAlgorithm.py @@ -24,29 +24,37 @@ import processing from DsgTools.core.GeometricTools.layerHandler import LayerHandler -from qgis.core import (QgsDataSourceUri, QgsFeature, QgsFeatureSink, - QgsGeometry, QgsProcessing, QgsProcessingAlgorithm, - QgsProcessingOutputVectorLayer, - QgsProcessingParameterBoolean, - QgsProcessingParameterEnum, - QgsProcessingParameterFeatureSink, - QgsProcessingParameterFeatureSource, - QgsProcessingParameterField, - QgsProcessingParameterMultipleLayers, - QgsProcessingParameterNumber, - QgsProcessingParameterVectorLayer, QgsProcessingUtils, - QgsSpatialIndex, QgsWkbTypes) +from qgis.core import ( + QgsDataSourceUri, + QgsFeature, + QgsFeatureSink, + QgsGeometry, + QgsProcessing, + QgsProcessingAlgorithm, + QgsProcessingOutputVectorLayer, + QgsProcessingParameterBoolean, + QgsProcessingParameterEnum, + QgsProcessingParameterFeatureSink, + QgsProcessingParameterFeatureSource, + QgsProcessingParameterField, + QgsProcessingParameterMultipleLayers, + QgsProcessingParameterNumber, + QgsProcessingParameterVectorLayer, + QgsProcessingUtils, + QgsSpatialIndex, + QgsWkbTypes, +) from .validationAlgorithm import ValidationAlgorithm class MergeLinesAlgorithm(ValidationAlgorithm): - INPUT = 'INPUT' - SELECTED = 'SELECTED' - ATTRIBUTE_BLACK_LIST = 'ATTRIBUTE_BLACK_LIST' - IGNORE_VIRTUAL_FIELDS = 'IGNORE_VIRTUAL_FIELDS' - IGNORE_PK_FIELDS = 'IGNORE_PK_FIELDS' - OUTPUT = 'OUTPUT' + INPUT = "INPUT" + SELECTED = "SELECTED" + ATTRIBUTE_BLACK_LIST = "ATTRIBUTE_BLACK_LIST" + IGNORE_VIRTUAL_FIELDS = "IGNORE_VIRTUAL_FIELDS" + IGNORE_PK_FIELDS = "IGNORE_PK_FIELDS" + OUTPUT = "OUTPUT" def initAlgorithm(self, config): """ @@ -54,46 +62,42 @@ def initAlgorithm(self, config): """ self.addParameter( QgsProcessingParameterVectorLayer( - self.INPUT, - self.tr('Input layer'), - [QgsProcessing.TypeVectorLine ] + self.INPUT, self.tr("Input layer"), [QgsProcessing.TypeVectorLine] ) ) self.addParameter( QgsProcessingParameterBoolean( - self.SELECTED, - self.tr('Process only selected features') + self.SELECTED, self.tr("Process only selected features") ) ) self.addParameter( QgsProcessingParameterField( - self.ATTRIBUTE_BLACK_LIST, - self.tr('Fields to ignore'), - None, - 'INPUT', + self.ATTRIBUTE_BLACK_LIST, + self.tr("Fields to ignore"), + None, + "INPUT", QgsProcessingParameterField.Any, allowMultiple=True, - optional = True + optional=True, ) ) self.addParameter( QgsProcessingParameterBoolean( self.IGNORE_VIRTUAL_FIELDS, - self.tr('Ignore virtual fields'), - defaultValue=True + self.tr("Ignore virtual fields"), + defaultValue=True, ) ) self.addParameter( QgsProcessingParameterBoolean( self.IGNORE_PK_FIELDS, - self.tr('Ignore primary key fields'), - defaultValue=True + self.tr("Ignore primary key fields"), + defaultValue=True, ) ) self.addOutput( QgsProcessingOutputVectorLayer( - self.OUTPUT, - self.tr('Original layer with merged lines') + self.OUTPUT, self.tr("Original layer with merged lines") ) ) @@ -102,31 +106,15 @@ def processAlgorithm(self, parameters, context, feedback): Here is where the processing itself takes place. """ layerHandler = LayerHandler() - inputLyr = self.parameterAsVectorLayer( - parameters, - self.INPUT, - context - ) - onlySelected = self.parameterAsBool( - parameters, - self.SELECTED, - context - ) + inputLyr = self.parameterAsVectorLayer(parameters, self.INPUT, context) + onlySelected = self.parameterAsBool(parameters, self.SELECTED, context) attributeBlackList = self.parameterAsFields( - parameters, - self.ATTRIBUTE_BLACK_LIST, - context - ) + parameters, self.ATTRIBUTE_BLACK_LIST, context + ) ignoreVirtual = self.parameterAsBool( - parameters, - self.IGNORE_VIRTUAL_FIELDS, - context - ) - ignorePK = self.parameterAsBool( - parameters, - self.IGNORE_PK_FIELDS, - context - ) + parameters, self.IGNORE_VIRTUAL_FIELDS, context + ) + ignorePK = self.parameterAsBool(parameters, self.IGNORE_PK_FIELDS, context) layerHandler.mergeLinesOnLayer( inputLyr, @@ -134,8 +122,8 @@ def processAlgorithm(self, parameters, context, feedback): onlySelected=onlySelected, ignoreVirtualFields=ignoreVirtual, attributeBlackList=attributeBlackList, - excludePrimaryKeys=ignorePK - ) + excludePrimaryKeys=ignorePK, + ) return {self.OUTPUT: inputLyr} @@ -147,21 +135,21 @@ def name(self): lowercase alphanumeric characters only and no spaces or other formatting characters. """ - return 'mergelineswithsameattributeset' + return "mergelineswithsameattributeset" def displayName(self): """ Returns the translated algorithm name, which should be used for any user-visible display of the algorithm name. """ - return self.tr('Merge lines with same attribute set') + return self.tr("Merge lines with same attribute set") def group(self): """ Returns the name of the group this algorithm belongs to. This string should be localised. """ - return self.tr('Quality Assurance Tools (Manipulation Processes)') + return self.tr("Quality Assurance Tools (Manipulation Processes)") def groupId(self): """ @@ -171,10 +159,10 @@ def groupId(self): contain lowercase alphanumeric characters only and no spaces or other formatting characters. """ - return 'DSGTools: Quality Assurance Tools (Manipulation Processes)' + return "DSGTools: Quality Assurance Tools (Manipulation Processes)" def tr(self, string): - return QCoreApplication.translate('MergeLinesAlgorithm', string) + return QCoreApplication.translate("MergeLinesAlgorithm", string) def createInstance(self): return MergeLinesAlgorithm() diff --git a/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/overlayElementsWithAreasAlgorithm.py b/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/overlayElementsWithAreasAlgorithm.py index 5e1087092..3b3e3725d 100644 --- a/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/overlayElementsWithAreasAlgorithm.py +++ b/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/overlayElementsWithAreasAlgorithm.py @@ -24,31 +24,41 @@ import processing from DsgTools.core.GeometricTools.layerHandler import LayerHandler -from qgis.core import (QgsDataSourceUri, QgsFeature, QgsFeatureSink, - QgsGeometry, QgsProcessing, QgsProcessingAlgorithm, - QgsProcessingException, QgsProcessingMultiStepFeedback, - QgsProcessingOutputVectorLayer, - QgsProcessingParameterBoolean, - QgsProcessingParameterDistance, - QgsProcessingParameterEnum, - QgsProcessingParameterFeatureSink, - QgsProcessingParameterFeatureSource, - QgsProcessingParameterMultipleLayers, - QgsProcessingParameterNumber, - QgsProcessingParameterVectorLayer, QgsProcessingUtils, - QgsProject, QgsSpatialIndex, QgsWkbTypes) +from qgis.core import ( + QgsDataSourceUri, + QgsFeature, + QgsFeatureSink, + QgsGeometry, + QgsProcessing, + QgsProcessingAlgorithm, + QgsProcessingException, + QgsProcessingMultiStepFeedback, + QgsProcessingOutputVectorLayer, + QgsProcessingParameterBoolean, + QgsProcessingParameterDistance, + QgsProcessingParameterEnum, + QgsProcessingParameterFeatureSink, + QgsProcessingParameterFeatureSource, + QgsProcessingParameterMultipleLayers, + QgsProcessingParameterNumber, + QgsProcessingParameterVectorLayer, + QgsProcessingUtils, + QgsProject, + QgsSpatialIndex, + QgsWkbTypes, +) from ...algRunner import AlgRunner from .validationAlgorithm import ValidationAlgorithm class OverlayElementsWithAreasAlgorithm(ValidationAlgorithm): - INPUT = 'INPUT' - SELECTED = 'SELECTED' - OVERLAY = 'OVERLAY' - SELECTED_OVERLAY = 'SELECTED_OVERLAY' - BEHAVIOR = 'BEHAVIOR' - OUTPUT = 'OUTPUT' + INPUT = "INPUT" + SELECTED = "SELECTED" + OVERLAY = "OVERLAY" + SELECTED_OVERLAY = "SELECTED_OVERLAY" + BEHAVIOR = "BEHAVIOR" + OUTPUT = "OUTPUT" RemoveOutside, RemoveInside, OverlayAndKeep = list(range(3)) def initAlgorithm(self, config): @@ -58,46 +68,42 @@ def initAlgorithm(self, config): self.addParameter( QgsProcessingParameterVectorLayer( self.INPUT, - self.tr('Input Layer'), - [QgsProcessing.TypeVectorAnyGeometry] + self.tr("Input Layer"), + [QgsProcessing.TypeVectorAnyGeometry], ) ) self.addParameter( QgsProcessingParameterBoolean( - self.SELECTED, - self.tr('Process only selected features') + self.SELECTED, self.tr("Process only selected features") ) ) self.addParameter( QgsProcessingParameterVectorLayer( self.OVERLAY, - self.tr('Polygon overlay Layer'), - [QgsProcessing.TypeVectorPolygon] + self.tr("Polygon overlay Layer"), + [QgsProcessing.TypeVectorPolygon], ) ) self.addParameter( QgsProcessingParameterBoolean( self.SELECTED_OVERLAY, - self.tr('Use only selected features from overlay layer') + self.tr("Use only selected features from overlay layer"), ) ) - self.modes = [self.tr('Remove outside elements'), - self.tr('Remove inside elements'), - self.tr('Overlay and Keep Elements') - ] + self.modes = [ + self.tr("Remove outside elements"), + self.tr("Remove inside elements"), + self.tr("Overlay and Keep Elements"), + ] self.addParameter( QgsProcessingParameterEnum( - self.BEHAVIOR, - self.tr('Behavior'), - options=self.modes, - defaultValue=0 + self.BEHAVIOR, self.tr("Behavior"), options=self.modes, defaultValue=0 ) ) self.addOutput( QgsProcessingOutputVectorLayer( - self.OUTPUT, - self.tr('Original layer with overlayed elements') + self.OUTPUT, self.tr("Original layer with overlayed elements") ) ) @@ -108,115 +114,93 @@ def processAlgorithm(self, parameters, context, feedback): layerHandler = LayerHandler() self.algRunner = AlgRunner() - inputLyr = self.parameterAsVectorLayer( - parameters, - self.INPUT, - context - ) + inputLyr = self.parameterAsVectorLayer(parameters, self.INPUT, context) if inputLyr is None: raise QgsProcessingException( - self.invalidSourceError( - parameters, - self.INPUT - ) - ) - overlayLyr = self.parameterAsVectorLayer( - parameters, - self.OVERLAY, - context + self.invalidSourceError(parameters, self.INPUT) ) + overlayLyr = self.parameterAsVectorLayer(parameters, self.OVERLAY, context) if overlayLyr is None: raise QgsProcessingException( - self.invalidSourceError( - parameters, - self.OVERLAY - ) - ) - onlySelected = self.parameterAsBool( - parameters, - self.SELECTED, - context + self.invalidSourceError(parameters, self.OVERLAY) ) + onlySelected = self.parameterAsBool(parameters, self.SELECTED, context) onlySelectedOverlay = self.parameterAsBool( - parameters, - self.SELECTED_OVERLAY, - context - ) - behavior = self.parameterAsEnum( - parameters, - self.BEHAVIOR, - context - ) + parameters, self.SELECTED_OVERLAY, context + ) + behavior = self.parameterAsEnum(parameters, self.BEHAVIOR, context) multiStepFeedback = QgsProcessingMultiStepFeedback(4, feedback) multiStepFeedback.setCurrentStep(0) - multiStepFeedback.pushInfo(self.tr('Populating temp layer...')) + multiStepFeedback.pushInfo(self.tr("Populating temp layer...")) auxLyr = layerHandler.createAndPopulateUnifiedVectorLayer( [inputLyr], geomType=inputLyr.wkbType(), onlySelected=onlySelected, - feedback=multiStepFeedback - ) + feedback=multiStepFeedback, + ) multiStepFeedback.setCurrentStep(1) if onlySelectedOverlay: overlayLyr = layerHandler.createAndPopulateUnifiedVectorLayer( [overlayLyr], geomType=overlayLyr.wkbType(), onlySelected=onlySelectedOverlay, - feedback=multiStepFeedback - ) + feedback=multiStepFeedback, + ) overlayLyr.startEditing() - overlayLyr.renameAttribute(0, 'fid') - overlayLyr.renameAttribute(1, 'cl') + overlayLyr.renameAttribute(0, "fid") + overlayLyr.renameAttribute(1, "cl") overlayLyr.commitChanges() + self.algRunner.runCreateSpatialIndex(overlayLyr, context=context) # 1- check method # 2- if overlay and keep, use clip and symetric difference # 3- if remove outside, use clip # 4- if remove inside, use symetric difference multiStepFeedback.setCurrentStep(2) - multiStepFeedback.pushInfo(self.tr('Running overlay...')) + multiStepFeedback.pushInfo(self.tr("Running overlay...")) outputLyr = self.runOverlay( - auxLyr, - overlayLyr, - behavior, - context, - multiStepFeedback - ) + auxLyr, overlayLyr, behavior, context, multiStepFeedback + ) multiStepFeedback.setCurrentStep(3) - multiStepFeedback.pushInfo(self.tr('Updating original layer...')) + multiStepFeedback.pushInfo(self.tr("Updating original layer...")) layerHandler.updateOriginalLayersFromUnifiedLayer( - [inputLyr], - outputLyr, - feedback=multiStepFeedback, - onlySelected=onlySelected - ) + [inputLyr], outputLyr, feedback=multiStepFeedback, onlySelected=onlySelected + ) + + return {self.OUTPUT: inputLyr} - return {self.OUTPUT : inputLyr} - def runOverlay(self, lyr, overlayLyr, behavior, context, feedback): nSteps = 2 if behavior == 2 else 1 localFeedback = QgsProcessingMultiStepFeedback(nSteps, feedback) localFeedback.setCurrentStep(0) # Intentional ifs not if else. - if behavior in [OverlayElementsWithAreasAlgorithm.RemoveOutside, OverlayElementsWithAreasAlgorithm.OverlayAndKeep]: - outputLyr = self.algRunner.runClip(lyr, overlayLyr, context, feedback=localFeedback) + if behavior in [ + OverlayElementsWithAreasAlgorithm.RemoveOutside, + OverlayElementsWithAreasAlgorithm.OverlayAndKeep, + ]: + outputLyr = self.algRunner.runClip( + lyr, overlayLyr, context, feedback=localFeedback + ) if behavior == OverlayElementsWithAreasAlgorithm.RemoveOutside: return outputLyr localFeedback.setCurrentStep(1) - if behavior in [OverlayElementsWithAreasAlgorithm.RemoveInside, OverlayElementsWithAreasAlgorithm.OverlayAndKeep]: - outputDiffLyr = self.algRunner.runSymDiff(lyr, overlayLyr, context, feedback=localFeedback) + if behavior in [ + OverlayElementsWithAreasAlgorithm.RemoveInside, + OverlayElementsWithAreasAlgorithm.OverlayAndKeep, + ]: + outputDiffLyr = self.algRunner.runSymDiff( + lyr, overlayLyr, context, feedback=localFeedback + ) if behavior == OverlayElementsWithAreasAlgorithm.RemoveInside: return outputDiffLyr if behavior == OverlayElementsWithAreasAlgorithm.OverlayAndKeep: - outsideFeats = [i for i in outputDiffLyr.getFeatures()] outputLyr.startEditing() - outputLyr.beginEditCommand('') - outputLyr.addFeatures(outsideFeats) + outputLyr.beginEditCommand("") + outputLyr.addFeatures(outputDiffLyr.getFeatures()) outputLyr.endEditCommand() outputLyr.commitChanges() return outputLyr - def name(self): """ Returns the algorithm name, used for identifying the algorithm. This @@ -225,21 +209,21 @@ def name(self): lowercase alphanumeric characters only and no spaces or other formatting characters. """ - return 'overlayelementswithareas' + return "overlayelementswithareas" def displayName(self): """ Returns the translated algorithm name, which should be used for any user-visible display of the algorithm name. """ - return self.tr('Overlay Elements With Areas') + return self.tr("Overlay Elements With Areas") def group(self): """ Returns the name of the group this algorithm belongs to. This string should be localised. """ - return self.tr('Quality Assurance Tools (Manipulation Processes)') + return self.tr("Quality Assurance Tools (Manipulation Processes)") def groupId(self): """ @@ -249,10 +233,10 @@ def groupId(self): contain lowercase alphanumeric characters only and no spaces or other formatting characters. """ - return 'DSGTools: Quality Assurance Tools (Manipulation Processes)' + return "DSGTools: Quality Assurance Tools (Manipulation Processes)" def tr(self, string): - return QCoreApplication.translate('OverlayElementsWithAreasAlgorithm', string) + return QCoreApplication.translate("OverlayElementsWithAreasAlgorithm", string) def createInstance(self): return OverlayElementsWithAreasAlgorithm() diff --git a/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/removeDuplicatedFeaturesAlgorithm.py b/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/removeDuplicatedFeaturesAlgorithm.py index 6ba4a5444..d1a3bc2c3 100644 --- a/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/removeDuplicatedFeaturesAlgorithm.py +++ b/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/removeDuplicatedFeaturesAlgorithm.py @@ -23,25 +23,32 @@ from PyQt5.QtCore import QCoreApplication from DsgTools.core.GeometricTools.layerHandler import LayerHandler -from qgis.core import (QgsDataSourceUri, QgsFeature, QgsFeatureSink, - QgsProcessing, QgsProcessingAlgorithm, - QgsProcessingException, QgsProcessingMultiStepFeedback, - QgsProcessingOutputVectorLayer, - QgsProcessingParameterBoolean, - QgsProcessingParameterFeatureSink, - QgsProcessingParameterFeatureSource, - QgsProcessingParameterField, - QgsProcessingParameterVectorLayer, QgsWkbTypes) +from qgis.core import ( + QgsDataSourceUri, + QgsFeature, + QgsFeatureSink, + QgsProcessing, + QgsProcessingAlgorithm, + QgsProcessingException, + QgsProcessingMultiStepFeedback, + QgsProcessingOutputVectorLayer, + QgsProcessingParameterBoolean, + QgsProcessingParameterFeatureSink, + QgsProcessingParameterFeatureSource, + QgsProcessingParameterField, + QgsProcessingParameterVectorLayer, + QgsWkbTypes, +) from .validationAlgorithm import ValidationAlgorithm class RemoveDuplicatedFeaturesAlgorithm(ValidationAlgorithm): - INPUT = 'INPUT' - SELECTED = 'SELECTED' - ATTRIBUTE_BLACK_LIST = 'ATTRIBUTE_BLACK_LIST' - IGNORE_VIRTUAL_FIELDS = 'IGNORE_VIRTUAL_FIELDS' - IGNORE_PK_FIELDS = 'IGNORE_PK_FIELDS' - OUTPUT = 'OUTPUT' + INPUT = "INPUT" + SELECTED = "SELECTED" + ATTRIBUTE_BLACK_LIST = "ATTRIBUTE_BLACK_LIST" + IGNORE_VIRTUAL_FIELDS = "IGNORE_VIRTUAL_FIELDS" + IGNORE_PK_FIELDS = "IGNORE_PK_FIELDS" + OUTPUT = "OUTPUT" def initAlgorithm(self, config): """ @@ -50,47 +57,45 @@ def initAlgorithm(self, config): self.addParameter( QgsProcessingParameterVectorLayer( self.INPUT, - self.tr('Input layer'), - [QgsProcessing.TypeVectorAnyGeometry ] + self.tr("Input layer"), + [QgsProcessing.TypeVectorAnyGeometry], ) ) self.addParameter( QgsProcessingParameterBoolean( - self.SELECTED, - self.tr('Process only selected features') + self.SELECTED, self.tr("Process only selected features") ) ) self.addParameter( QgsProcessingParameterField( - self.ATTRIBUTE_BLACK_LIST, - self.tr('Fields to ignore'), - None, - 'INPUT', + self.ATTRIBUTE_BLACK_LIST, + self.tr("Fields to ignore"), + None, + "INPUT", QgsProcessingParameterField.Any, allowMultiple=True, - optional = True + optional=True, ) ) self.addParameter( QgsProcessingParameterBoolean( self.IGNORE_VIRTUAL_FIELDS, - self.tr('Ignore virtual fields'), - defaultValue=True + self.tr("Ignore virtual fields"), + defaultValue=True, ) ) self.addParameter( QgsProcessingParameterBoolean( self.IGNORE_PK_FIELDS, - self.tr('Ignore primary key fields'), - defaultValue=True + self.tr("Ignore primary key fields"), + defaultValue=True, ) ) self.addOutput( QgsProcessingOutputVectorLayer( - self.OUTPUT, - self.tr('Original layer without duplicated features') + self.OUTPUT, self.tr("Original layer without duplicated features") ) ) @@ -103,27 +108,15 @@ def processAlgorithm(self, parameters, context, feedback): if inputLyr is None: raise QgsProcessingException( self.invalidSourceError(parameters, self.INPUT) - ) - onlySelected = self.parameterAsBool( - parameters, - self.SELECTED, - context ) + onlySelected = self.parameterAsBool(parameters, self.SELECTED, context) attributeBlackList = self.parameterAsFields( - parameters, - self.ATTRIBUTE_BLACK_LIST, - context - ) + parameters, self.ATTRIBUTE_BLACK_LIST, context + ) ignoreVirtual = self.parameterAsBool( - parameters, - self.IGNORE_VIRTUAL_FIELDS, - context - ) - ignorePK = self.parameterAsBool( - parameters, - self.IGNORE_PK_FIELDS, - context - ) + parameters, self.IGNORE_VIRTUAL_FIELDS, context + ) + ignorePK = self.parameterAsBool(parameters, self.IGNORE_PK_FIELDS, context) # Compute the number of steps to display within the progress bar and # get features from source multiStepFeedback = QgsProcessingMultiStepFeedback(2, feedback) @@ -134,19 +127,17 @@ def processAlgorithm(self, parameters, context, feedback): attributeBlackList=attributeBlackList, excludePrimaryKeys=ignorePK, ignoreVirtualFields=ignoreVirtual, - feedback=multiStepFeedback - ) + feedback=multiStepFeedback, + ) multiStepFeedback.setCurrentStep(1) self.deleteDuplicatedFeaturesFlags( - inputLyr, - duplicatedGeomDict, - multiStepFeedback - ) + inputLyr, duplicatedGeomDict, multiStepFeedback + ) return {self.OUTPUT: inputLyr} def deleteDuplicatedFeaturesFlags(self, inputLyr, duplicatedGeomDict, feedback): - size = 100/len(duplicatedGeomDict) if duplicatedGeomDict else 0 + size = 100 / len(duplicatedGeomDict) if duplicatedGeomDict else 0 deleteList = [] for current, (bboxKey, featList) in enumerate(duplicatedGeomDict.items()): if feedback.isCanceled(): @@ -155,7 +146,7 @@ def deleteDuplicatedFeaturesFlags(self, inputLyr, duplicatedGeomDict, feedback): deleteList += [feat.id() for feat in featList[1::]] feedback.setProgress(size * current) inputLyr.startEditing() - inputLyr.beginEditCommand('Deleting features') + inputLyr.beginEditCommand("Deleting features") inputLyr.deleteFeatures(deleteList) inputLyr.endEditCommand() @@ -167,21 +158,21 @@ def name(self): lowercase alphanumeric characters only and no spaces or other formatting characters. """ - return 'removeduplicatedfeatures' + return "removeduplicatedfeatures" def displayName(self): """ Returns the translated algorithm name, which should be used for any user-visible display of the algorithm name. """ - return self.tr('Remove Duplicated Features') + return self.tr("Remove Duplicated Features") def group(self): """ Returns the name of the group this algorithm belongs to. This string should be localised. """ - return self.tr('Quality Assurance Tools (Correction Processes)') + return self.tr("Quality Assurance Tools (Correction Processes)") def groupId(self): """ @@ -191,10 +182,10 @@ def groupId(self): contain lowercase alphanumeric characters only and no spaces or other formatting characters. """ - return 'DSGTools: Quality Assurance Tools (Correction Processes)' + return "DSGTools: Quality Assurance Tools (Correction Processes)" def tr(self, string): - return QCoreApplication.translate('RemoveDuplicatedFeaturesAlgorithm', string) + return QCoreApplication.translate("RemoveDuplicatedFeaturesAlgorithm", string) def createInstance(self): return RemoveDuplicatedFeaturesAlgorithm() diff --git a/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/removeDuplicatedGeometriesAlgorithm.py b/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/removeDuplicatedGeometriesAlgorithm.py index 42b42bf9a..b9fd6d56f 100644 --- a/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/removeDuplicatedGeometriesAlgorithm.py +++ b/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/removeDuplicatedGeometriesAlgorithm.py @@ -22,24 +22,31 @@ from PyQt5.QtCore import QCoreApplication -from qgis.core import (QgsDataSourceUri, QgsFeature, QgsFeatureSink, - QgsProcessing, QgsProcessingAlgorithm, - QgsProcessingException, QgsProcessingMultiStepFeedback, - QgsProcessingOutputVectorLayer, - QgsProcessingParameterBoolean, - QgsProcessingParameterFeatureSink, - QgsProcessingParameterFeatureSource, - QgsProcessingParameterVectorLayer, QgsWkbTypes) +from qgis.core import ( + QgsDataSourceUri, + QgsFeature, + QgsFeatureSink, + QgsProcessing, + QgsProcessingAlgorithm, + QgsProcessingException, + QgsProcessingMultiStepFeedback, + QgsProcessingOutputVectorLayer, + QgsProcessingParameterBoolean, + QgsProcessingParameterFeatureSink, + QgsProcessingParameterFeatureSource, + QgsProcessingParameterVectorLayer, + QgsWkbTypes, +) from ...algRunner import AlgRunner from .validationAlgorithm import ValidationAlgorithm class RemoveDuplicatedGeometriesAlgorithm(ValidationAlgorithm): - FLAGS = 'FLAGS' - INPUT = 'INPUT' - SELECTED = 'SELECTED' - OUTPUT = 'OUTPUT' + FLAGS = "FLAGS" + INPUT = "INPUT" + SELECTED = "SELECTED" + OUTPUT = "OUTPUT" def initAlgorithm(self, config): """ @@ -48,28 +55,25 @@ def initAlgorithm(self, config): self.addParameter( QgsProcessingParameterVectorLayer( self.INPUT, - self.tr('Input layer'), - [QgsProcessing.TypeVectorAnyGeometry ] + self.tr("Input layer"), + [QgsProcessing.TypeVectorAnyGeometry], ) ) self.addParameter( QgsProcessingParameterBoolean( - self.SELECTED, - self.tr('Process only selected features') + self.SELECTED, self.tr("Process only selected features") ) ) self.addParameter( QgsProcessingParameterFeatureSink( - self.FLAGS, - self.tr('{0} Flags').format(self.displayName()) + self.FLAGS, self.tr("{0} Flags").format(self.displayName()) ) ) self.addOutput( QgsProcessingOutputVectorLayer( - self.OUTPUT, - self.tr('Original layer without duplicated geometries') + self.OUTPUT, self.tr("Original layer without duplicated geometries") ) ) @@ -81,41 +85,33 @@ def processAlgorithm(self, parameters, context, feedback): inputLyr = self.parameterAsVectorLayer(parameters, self.INPUT, context) if inputLyr is None: raise QgsProcessingException( - self.invalidSourceError( - parameters, - self.INPUT - ) - ) - onlySelected = self.parameterAsBool( - parameters, - self.SELECTED, - context + self.invalidSourceError(parameters, self.INPUT) ) + onlySelected = self.parameterAsBool(parameters, self.SELECTED, context) multiStepFeedback = QgsProcessingMultiStepFeedback(2, feedback) multiStepFeedback.setCurrentStep(0) multiStepFeedback.pushInfo( - self.tr( - 'Identifying duplicated geometries in layer {0}...' - ).format(inputLyr.name())) - flagLyr = algRunner.runIdentifyDuplicatedGeometries( - inputLyr, - context, - feedback=multiStepFeedback, - onlySelected=onlySelected + self.tr("Identifying duplicated geometries in layer {0}...").format( + inputLyr.name() ) + ) + flagLyr = algRunner.runIdentifyDuplicatedGeometries( + inputLyr, context, feedback=multiStepFeedback, onlySelected=onlySelected + ) multiStepFeedback.setCurrentStep(1) multiStepFeedback.pushInfo( - self.tr( - 'Removing duplicated geometries in layer {0}...' - ).format(inputLyr.name())) + self.tr("Removing duplicated geometries in layer {0}...").format( + inputLyr.name() + ) + ) self.removeFeatures(inputLyr, flagLyr, multiStepFeedback) return {self.OUTPUT: inputLyr} - + def removeFeatures(self, inputLyr, flagLyr, feedback): featureList, total = self.getIteratorAndFeatureCount(flagLyr) - localTotal = 100/total if total else 0 + localTotal = 100 / total if total else 0 inputLyr.beginEditCommand("Removing duplicates") inputLyr.startEditing() removeSet = set() @@ -123,7 +119,16 @@ def removeFeatures(self, inputLyr, flagLyr, feedback): # Stop the algorithm if cancel button has been clicked if feedback.isCanceled(): break - removeSet = removeSet.union(set([i for i in map(int, feat['reason'].split('(')[-1].split(')')[0].split(','))][1::])) + removeSet = removeSet.union( + set( + [ + i + for i in map( + int, feat["reason"].split("(")[-1].split(")")[0].split(",") + ) + ][1::] + ) + ) feedback.setProgress(current * localTotal) inputLyr.deleteFeatures(list(removeSet)) inputLyr.endEditCommand() @@ -136,21 +141,21 @@ def name(self): lowercase alphanumeric characters only and no spaces or other formatting characters. """ - return 'removeduplicatedgeometries' + return "removeduplicatedgeometries" def displayName(self): """ Returns the translated algorithm name, which should be used for any user-visible display of the algorithm name. """ - return self.tr('Remove Duplicated Geometries') + return self.tr("Remove Duplicated Geometries") def group(self): """ Returns the name of the group this algorithm belongs to. This string should be localised. """ - return self.tr('Quality Assurance Tools (Correction Processes)') + return self.tr("Quality Assurance Tools (Correction Processes)") def groupId(self): """ @@ -160,10 +165,10 @@ def groupId(self): contain lowercase alphanumeric characters only and no spaces or other formatting characters. """ - return 'DSGTools: Quality Assurance Tools (Correction Processes)' + return "DSGTools: Quality Assurance Tools (Correction Processes)" def tr(self, string): - return QCoreApplication.translate('RemoveDuplicatedGeometriesAlgorithm', string) + return QCoreApplication.translate("RemoveDuplicatedGeometriesAlgorithm", string) def createInstance(self): return RemoveDuplicatedGeometriesAlgorithm() diff --git a/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/removeEmptyAndUpdateAlgorithm.py b/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/removeEmptyAndUpdateAlgorithm.py index 5e6b0d42c..ff5c18b8a 100644 --- a/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/removeEmptyAndUpdateAlgorithm.py +++ b/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/removeEmptyAndUpdateAlgorithm.py @@ -24,29 +24,38 @@ import processing from DsgTools.core.GeometricTools.layerHandler import LayerHandler -from qgis.core import (QgsDataSourceUri, QgsFeature, QgsFeatureSink, - QgsGeometry, QgsProcessing, QgsProcessingAlgorithm, - QgsProcessingException, QgsProcessingMultiStepFeedback, - QgsProcessingOutputVectorLayer, - QgsProcessingParameterBoolean, - QgsProcessingParameterDistance, - QgsProcessingParameterEnum, - QgsProcessingParameterFeatureSink, - QgsProcessingParameterFeatureSource, - QgsProcessingParameterField, - QgsProcessingParameterMultipleLayers, - QgsProcessingParameterNumber, - QgsProcessingParameterVectorLayer, QgsProcessingUtils, - QgsSpatialIndex, QgsWkbTypes) +from qgis.core import ( + QgsDataSourceUri, + QgsFeature, + QgsFeatureSink, + QgsGeometry, + QgsProcessing, + QgsProcessingAlgorithm, + QgsProcessingException, + QgsProcessingMultiStepFeedback, + QgsProcessingOutputVectorLayer, + QgsProcessingParameterBoolean, + QgsProcessingParameterDistance, + QgsProcessingParameterEnum, + QgsProcessingParameterFeatureSink, + QgsProcessingParameterFeatureSource, + QgsProcessingParameterField, + QgsProcessingParameterMultipleLayers, + QgsProcessingParameterNumber, + QgsProcessingParameterVectorLayer, + QgsProcessingUtils, + QgsSpatialIndex, + QgsWkbTypes, +) from ...algRunner import AlgRunner from .validationAlgorithm import ValidationAlgorithm class RemoveEmptyAndUpdateAlgorithm(ValidationAlgorithm): - INPUT = 'INPUT' - SELECTED = 'SELECTED' - OUTPUT = 'OUTPUT' + INPUT = "INPUT" + SELECTED = "SELECTED" + OUTPUT = "OUTPUT" def initAlgorithm(self, config): """ @@ -55,20 +64,18 @@ def initAlgorithm(self, config): self.addParameter( QgsProcessingParameterVectorLayer( self.INPUT, - self.tr('Input layer'), - [QgsProcessing.TypeVectorAnyGeometry ] + self.tr("Input layer"), + [QgsProcessing.TypeVectorAnyGeometry], ) ) self.addParameter( QgsProcessingParameterBoolean( - self.SELECTED, - self.tr('Process only selected features') + self.SELECTED, self.tr("Process only selected features") ) ) self.addOutput( QgsProcessingOutputVectorLayer( - self.OUTPUT, - self.tr('Original layer without empty geometries') + self.OUTPUT, self.tr("Original layer without empty geometries") ) ) @@ -81,44 +88,38 @@ def processAlgorithm(self, parameters, context, feedback): inputLyr = self.parameterAsVectorLayer(parameters, self.INPUT, context) if inputLyr is None: raise QgsProcessingException( - self.invalidSourceError( - parameters, - self.INPUT - ) - ) + self.invalidSourceError(parameters, self.INPUT) + ) onlySelected = self.parameterAsBool(parameters, self.SELECTED, context) multiStepFeedback = QgsProcessingMultiStepFeedback(3, feedback) multiStepFeedback.setCurrentStep(0) - multiStepFeedback.pushInfo( - self.tr('Populating temp layer...') - ) + multiStepFeedback.pushInfo(self.tr("Populating temp layer...")) auxLyr = layerHandler.createAndPopulateUnifiedVectorLayer( [inputLyr], geomType=inputLyr.wkbType(), onlySelected=onlySelected, - feedback=multiStepFeedback - ) + feedback=multiStepFeedback, + ) multiStepFeedback.setCurrentStep(1) multiStepFeedback.pushInfo( - self.tr( - 'Removing empty geometries from layer {input}...' - ).format(input=inputLyr.name())) - notNullLayer = algRunner.runRemoveNull( - auxLyr, - context, - feedback=multiStepFeedback + self.tr("Removing empty geometries from layer {input}...").format( + input=inputLyr.name() ) + ) + notNullLayer = algRunner.runRemoveNull( + auxLyr, context, feedback=multiStepFeedback + ) multiStepFeedback.setCurrentStep(2) - multiStepFeedback.pushInfo(self.tr('Updating original layer...')) + multiStepFeedback.pushInfo(self.tr("Updating original layer...")) layerHandler.updateOriginalLayersFromUnifiedLayer( [inputLyr], notNullLayer, feedback=multiStepFeedback, - onlySelected=onlySelected - ) + onlySelected=onlySelected, + ) return {self.OUTPUT: inputLyr} @@ -130,21 +131,21 @@ def name(self): lowercase alphanumeric characters only and no spaces or other formatting characters. """ - return 'removeemptyandupdate' + return "removeemptyandupdate" def displayName(self): """ Returns the translated algorithm name, which should be used for any user-visible display of the algorithm name. """ - return self.tr('Remove empty and update') + return self.tr("Remove empty and update") def group(self): """ Returns the name of the group this algorithm belongs to. This string should be localised. """ - return self.tr('Quality Assurance Tools (Manipulation Processes)') + return self.tr("Quality Assurance Tools (Manipulation Processes)") def groupId(self): """ @@ -154,10 +155,10 @@ def groupId(self): contain lowercase alphanumeric characters only and no spaces or other formatting characters. """ - return 'DSGTools: Quality Assurance Tools (Manipulation Processes)' + return "DSGTools: Quality Assurance Tools (Manipulation Processes)" def tr(self, string): - return QCoreApplication.translate('RemoveEmptyAndUpdateAlgorithm', string) + return QCoreApplication.translate("RemoveEmptyAndUpdateAlgorithm", string) def createInstance(self): return RemoveEmptyAndUpdateAlgorithm() diff --git a/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/removeSmallLinesAlgorithm.py b/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/removeSmallLinesAlgorithm.py index fb8943a8d..4be218610 100644 --- a/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/removeSmallLinesAlgorithm.py +++ b/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/removeSmallLinesAlgorithm.py @@ -21,27 +21,33 @@ """ from PyQt5.QtCore import QCoreApplication -from qgis.core import (QgsDataSourceUri, QgsFeature, QgsFeatureSink, - QgsProcessing, QgsProcessingAlgorithm, - QgsProcessingOutputVectorLayer, - QgsProcessingParameterBoolean, - QgsProcessingParameterFeatureSink, - QgsProcessingParameterFeatureSource, - QgsProcessingParameterNumber, - QgsProcessingParameterVectorLayer, QgsWkbTypes, - QgsProcessingMultiStepFeedback, - QgsProcessingException) +from qgis.core import ( + QgsDataSourceUri, + QgsFeature, + QgsFeatureSink, + QgsProcessing, + QgsProcessingAlgorithm, + QgsProcessingOutputVectorLayer, + QgsProcessingParameterBoolean, + QgsProcessingParameterFeatureSink, + QgsProcessingParameterFeatureSource, + QgsProcessingParameterNumber, + QgsProcessingParameterVectorLayer, + QgsWkbTypes, + QgsProcessingMultiStepFeedback, + QgsProcessingException, +) from ...algRunner import AlgRunner from .validationAlgorithm import ValidationAlgorithm class RemoveSmallLinesAlgorithm(ValidationAlgorithm): - FLAGS = 'FLAGS' - INPUT = 'INPUT' - OUTPUT = 'OUTPUT' - SELECTED = 'SELECTED' - TOLERANCE = 'TOLERANCE' + FLAGS = "FLAGS" + INPUT = "INPUT" + OUTPUT = "OUTPUT" + SELECTED = "SELECTED" + TOLERANCE = "TOLERANCE" def initAlgorithm(self, config): """ @@ -49,33 +55,29 @@ def initAlgorithm(self, config): """ self.addParameter( QgsProcessingParameterVectorLayer( - self.INPUT, - self.tr('Input layer'), - [QgsProcessing.TypeVectorLine ] + self.INPUT, self.tr("Input layer"), [QgsProcessing.TypeVectorLine] ) ) self.addParameter( QgsProcessingParameterBoolean( - self.SELECTED, - self.tr('Process only selected features') + self.SELECTED, self.tr("Process only selected features") ) ) self.addParameter( QgsProcessingParameterNumber( self.TOLERANCE, - self.tr('Line length tolerance'), + self.tr("Line length tolerance"), type=QgsProcessingParameterNumber.Double, minValue=0, - defaultValue=5 + defaultValue=5, ) ) self.addOutput( QgsProcessingOutputVectorLayer( - self.OUTPUT, - self.tr('Original layer without small lines') + self.OUTPUT, self.tr("Original layer without small lines") ) ) @@ -88,46 +90,43 @@ def processAlgorithm(self, parameters, context, feedback): if inputLyr is None: raise QgsProcessingException( self.invalidSourceError(parameters, self.INPUT) - ) + ) onlySelected = self.parameterAsBool(parameters, self.SELECTED, context) tol = self.parameterAsDouble(parameters, self.TOLERANCE, context) multiStepFeedback = QgsProcessingMultiStepFeedback(2, feedback) multiStepFeedback.setCurrentStep(0) multiStepFeedback.pushInfo( - self.tr( - 'Identifying small lines in layer {0}...' - ).format(inputLyr.name())) + self.tr("Identifying small lines in layer {0}...").format(inputLyr.name()) + ) flagLyr = algRunner.runIdentifySmallLines( inputLyr, tol, context, feedback=multiStepFeedback, - onlySelected=onlySelected - ) + onlySelected=onlySelected, + ) multiStepFeedback.setCurrentStep(1) multiStepFeedback.pushInfo( - self.tr( - 'Removing small lines from layer {0}...' - ).format(inputLyr.name())) + self.tr("Removing small lines from layer {0}...").format(inputLyr.name()) + ) self.removeFeatures(inputLyr, flagLyr, multiStepFeedback) return {self.OUTPUT: inputLyr} - - def removeFeatures(self, inputLyr, flagLyr, feedback, progressDelta = 100): + + def removeFeatures(self, inputLyr, flagLyr, feedback, progressDelta=100): featureList, total = self.getIteratorAndFeatureCount(flagLyr) currentProgress = feedback.progress() - localTotal = progressDelta/total if total else 0 + localTotal = progressDelta / total if total else 0 inputLyr.startEditing() idRemoveList = [] for current, feat in enumerate(featureList): # Stop the algorithm if cancel button has been clicked if feedback.isCanceled(): break - idRemoveList += [int(feat['reason'].split('=')[-1].split(' ')[0])] + idRemoveList += [int(feat["reason"].split("=")[-1].split(" ")[0])] feedback.setProgress(currentProgress + (current * localTotal)) inputLyr.deleteFeatures(idRemoveList) - def name(self): """ @@ -137,21 +136,21 @@ def name(self): lowercase alphanumeric characters only and no spaces or other formatting characters. """ - return 'removesmalllines' + return "removesmalllines" def displayName(self): """ Returns the translated algorithm name, which should be used for any user-visible display of the algorithm name. """ - return self.tr('Remove Small Lines') + return self.tr("Remove Small Lines") def group(self): """ Returns the name of the group this algorithm belongs to. This string should be localised. """ - return self.tr('Quality Assurance Tools (Correction Processes)') + return self.tr("Quality Assurance Tools (Correction Processes)") def groupId(self): """ @@ -161,10 +160,10 @@ def groupId(self): contain lowercase alphanumeric characters only and no spaces or other formatting characters. """ - return 'DSGTools: Quality Assurance Tools (Correction Processes)' + return "DSGTools: Quality Assurance Tools (Correction Processes)" def tr(self, string): - return QCoreApplication.translate('RemoveSmallLinesAlgorithm', string) + return QCoreApplication.translate("RemoveSmallLinesAlgorithm", string) def createInstance(self): return RemoveSmallLinesAlgorithm() diff --git a/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/removeSmallPolygonsAlgorithm.py b/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/removeSmallPolygonsAlgorithm.py index 3a5ca5d4d..7eb3fbac0 100644 --- a/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/removeSmallPolygonsAlgorithm.py +++ b/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/removeSmallPolygonsAlgorithm.py @@ -22,26 +22,33 @@ from PyQt5.QtCore import QCoreApplication -from qgis.core import (QgsDataSourceUri, QgsFeature, QgsFeatureSink, - QgsProcessing, QgsProcessingAlgorithm, - QgsProcessingException, QgsProcessingMultiStepFeedback, - QgsProcessingOutputVectorLayer, - QgsProcessingParameterBoolean, - QgsProcessingParameterFeatureSink, - QgsProcessingParameterFeatureSource, - QgsProcessingParameterNumber, - QgsProcessingParameterVectorLayer, QgsWkbTypes) +from qgis.core import ( + QgsDataSourceUri, + QgsFeature, + QgsFeatureSink, + QgsProcessing, + QgsProcessingAlgorithm, + QgsProcessingException, + QgsProcessingMultiStepFeedback, + QgsProcessingOutputVectorLayer, + QgsProcessingParameterBoolean, + QgsProcessingParameterFeatureSink, + QgsProcessingParameterFeatureSource, + QgsProcessingParameterNumber, + QgsProcessingParameterVectorLayer, + QgsWkbTypes, +) from ...algRunner import AlgRunner from .validationAlgorithm import ValidationAlgorithm class RemoveSmallPolygonsAlgorithm(ValidationAlgorithm): - FLAGS = 'FLAGS' - INPUT = 'INPUT' - SELECTED = 'SELECTED' - TOLERANCE = 'TOLERANCE' - OUTPUT = 'OUTPUT' + FLAGS = "FLAGS" + INPUT = "INPUT" + SELECTED = "SELECTED" + TOLERANCE = "TOLERANCE" + OUTPUT = "OUTPUT" def initAlgorithm(self, config): """ @@ -50,31 +57,26 @@ def initAlgorithm(self, config): self.addParameter( QgsProcessingParameterVectorLayer( self.INPUT, - self.tr('Input layer'), - [QgsProcessing.TypeVectorAnyGeometry ] + self.tr("Input layer"), + [QgsProcessing.TypeVectorAnyGeometry], ) ) self.addParameter( QgsProcessingParameterBoolean( - self.SELECTED, - self.tr('Process only selected features') + self.SELECTED, self.tr("Process only selected features") ) ) self.addParameter( QgsProcessingParameterNumber( - self.TOLERANCE, - self.tr('Area tolerance'), - minValue=0, - defaultValue=625 + self.TOLERANCE, self.tr("Area tolerance"), minValue=0, defaultValue=625 ) ) self.addOutput( QgsProcessingOutputVectorLayer( - self.OUTPUT, - self.tr('Original layer without small polygons') + self.OUTPUT, self.tr("Original layer without small polygons") ) ) @@ -86,32 +88,29 @@ def processAlgorithm(self, parameters, context, feedback): inputLyr = self.parameterAsVectorLayer(parameters, self.INPUT, context) if inputLyr is None: raise QgsProcessingException( - self.invalidSourceError( - parameters, - self.INPUT - ) - ) + self.invalidSourceError(parameters, self.INPUT) + ) onlySelected = self.parameterAsBool(parameters, self.SELECTED, context) tol = self.parameterAsDouble(parameters, self.TOLERANCE, context) multiStepFeedback = QgsProcessingMultiStepFeedback(2, feedback) multiStepFeedback.setCurrentStep(0) multiStepFeedback.pushInfo( - self.tr( - 'Identifying small polygons in layer {0}...' - ).format(inputLyr.name())) + self.tr("Identifying small polygons in layer {0}...").format( + inputLyr.name() + ) + ) flagLyr = algRunner.runIdentifySmallPolygons( inputLyr, tol, context, feedback=multiStepFeedback, - onlySelected=onlySelected - ) + onlySelected=onlySelected, + ) multiStepFeedback.setCurrentStep(1) multiStepFeedback.pushInfo( - self.tr( - 'Removing small polygons from layer {0}...' - ).format(inputLyr.name())) + self.tr("Removing small polygons from layer {0}...").format(inputLyr.name()) + ) self.removeFeatures(inputLyr, flagLyr, multiStepFeedback) return {self.OUTPUT: inputLyr} @@ -121,17 +120,16 @@ def removeFeatures(self, inputLyr, flagLyr, feedback): Parses features from flagLyr to get ids from inputLyr to remove. """ featureList, total = self.getIteratorAndFeatureCount(flagLyr) - localTotal = 100/total if total else 0 + localTotal = 100 / total if total else 0 inputLyr.startEditing() idRemoveList = [] for current, feat in enumerate(featureList): # Stop the algorithm if cancel button has been clicked if feedback.isCanceled(): break - idRemoveList += [int(feat['reason'].split('=')[-1].split(' ')[0])] + idRemoveList += [int(feat["reason"].split("=")[-1].split(" ")[0])] feedback.setProgress(current * localTotal) inputLyr.deleteFeatures(idRemoveList) - def name(self): """ @@ -141,21 +139,21 @@ def name(self): lowercase alphanumeric characters only and no spaces or other formatting characters. """ - return 'removesmallpolygons' + return "removesmallpolygons" def displayName(self): """ Returns the translated algorithm name, which should be used for any user-visible display of the algorithm name. """ - return self.tr('Remove Small Polygons') + return self.tr("Remove Small Polygons") def group(self): """ Returns the name of the group this algorithm belongs to. This string should be localised. """ - return self.tr('Quality Assurance Tools (Correction Processes)') + return self.tr("Quality Assurance Tools (Correction Processes)") def groupId(self): """ @@ -165,10 +163,10 @@ def groupId(self): contain lowercase alphanumeric characters only and no spaces or other formatting characters. """ - return 'DSGTools: Quality Assurance Tools (Correction Processes)' + return "DSGTools: Quality Assurance Tools (Correction Processes)" def tr(self, string): - return QCoreApplication.translate('RemoveSmallPolygonsAlgorithm', string) + return QCoreApplication.translate("RemoveSmallPolygonsAlgorithm", string) def createInstance(self): return RemoveSmallPolygonsAlgorithm() diff --git a/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/snapLayerOnLayerAndUpdateAlgorithm.py b/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/snapLayerOnLayerAndUpdateAlgorithm.py index 72db26c09..1752a69ae 100644 --- a/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/snapLayerOnLayerAndUpdateAlgorithm.py +++ b/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/snapLayerOnLayerAndUpdateAlgorithm.py @@ -25,33 +25,44 @@ import processing from DsgTools.core.GeometricTools.layerHandler import LayerHandler -from qgis.core import (QgsDataSourceUri, QgsFeature, QgsFeatureSink, - QgsGeometry, QgsProcessing, QgsProcessingAlgorithm, - QgsProcessingException, QgsProcessingMultiStepFeedback, - QgsProcessingOutputVectorLayer, - QgsProcessingParameterBoolean, - QgsProcessingParameterDistance, - QgsProcessingParameterEnum, - QgsProcessingParameterFeatureSink, - QgsProcessingParameterFeatureSource, - QgsProcessingParameterField, - QgsProcessingParameterMultipleLayers, - QgsProcessingParameterNumber, - QgsProcessingParameterVectorLayer, QgsProcessingUtils, - QgsSpatialIndex, QgsWkbTypes, QgsProject) +from qgis.core import ( + QgsDataSourceUri, + QgsFeature, + QgsFeatureSink, + QgsGeometry, + QgsProcessing, + QgsProcessingAlgorithm, + QgsProcessingException, + QgsProcessingMultiStepFeedback, + QgsProcessingOutputVectorLayer, + QgsProcessingParameterBoolean, + QgsProcessingParameterDistance, + QgsProcessingParameterEnum, + QgsProcessingParameterFeatureSink, + QgsProcessingParameterFeatureSource, + QgsProcessingParameterField, + QgsProcessingParameterMultipleLayers, + QgsProcessingParameterNumber, + QgsProcessingParameterVectorLayer, + QgsProcessingParameterFeatureSource, + QgsProcessingUtils, + QgsSpatialIndex, + QgsWkbTypes, + QgsProject, +) from ...algRunner import AlgRunner from .validationAlgorithm import ValidationAlgorithm class SnapLayerOnLayerAndUpdateAlgorithm(ValidationAlgorithm): - INPUT = 'INPUT' - SELECTED = 'SELECTED' - REFERENCE_LAYER = 'REFERENCE_LAYER' - BUILD_CACHE = 'BUILD_CACHE' - TOLERANCE = 'TOLERANCE' - BEHAVIOR = 'BEHAVIOR' - OUTPUT = 'OUTPUT' + INPUT = "INPUT" + SELECTED = "SELECTED" + REFERENCE_LAYER = "REFERENCE_LAYER" + BUILD_CACHE = "BUILD_CACHE" + TOLERANCE = "TOLERANCE" + BEHAVIOR = "BEHAVIOR" + OUTPUT = "OUTPUT" def initAlgorithm(self, config): """ @@ -60,59 +71,54 @@ def initAlgorithm(self, config): self.addParameter( QgsProcessingParameterVectorLayer( self.INPUT, - self.tr('Input layer'), - [QgsProcessing.TypeVectorAnyGeometry ] + self.tr("Input layer"), + [QgsProcessing.TypeVectorAnyGeometry], ) ) self.addParameter( QgsProcessingParameterBoolean( - self.SELECTED, - self.tr('Process only selected features') + self.SELECTED, self.tr("Process only selected features") ) ) self.addParameter( - QgsProcessingParameterVectorLayer( + QgsProcessingParameterFeatureSource( self.REFERENCE_LAYER, - self.tr('Reference layer'), - [QgsProcessing.TypeVectorAnyGeometry ] + self.tr("Reference layer"), + [QgsProcessing.TypeVectorAnyGeometry], ) ) - self.addParameter( - QgsProcessingParameterDistance( - self.TOLERANCE, - self.tr('Snap radius'), - parentParameterName=self.INPUT, - minValue=0, - defaultValue=1.0 - ) + param = QgsProcessingParameterDistance( + self.TOLERANCE, + self.tr("Search Radius"), + parentParameterName=self.INPUT, + defaultValue=1.0, ) - self.modes = [self.tr('Prefer aligning nodes, insert extra vertices where required'), - self.tr('Prefer closest point, insert extra vertices where required'), - self.tr('Prefer aligning nodes, don\'t insert new vertices'), - self.tr('Prefer closest point, don\'t insert new vertices'), - self.tr('Move end points only, prefer aligning nodes'), - self.tr('Move end points only, prefer closest point'), - self.tr('Snap end points to end points only')] + param.setMetadata({"widget_wrapper": {"decimals": 8}}) + self.addParameter(param) + self.modes = [ + self.tr("Prefer aligning nodes, insert extra vertices where required"), + self.tr("Prefer closest point, insert extra vertices where required"), + self.tr("Prefer aligning nodes, don't insert new vertices"), + self.tr("Prefer closest point, don't insert new vertices"), + self.tr("Move end points only, prefer aligning nodes"), + self.tr("Move end points only, prefer closest point"), + self.tr("Snap end points to end points only"), + ] self.addParameter( QgsProcessingParameterEnum( - self.BEHAVIOR, - self.tr('Behavior'), - options=self.modes, - defaultValue=0 + self.BEHAVIOR, self.tr("Behavior"), options=self.modes, defaultValue=0 ) ) self.addParameter( QgsProcessingParameterBoolean( - self.BUILD_CACHE, - self.tr('Build local cache of the reference layer') + self.BUILD_CACHE, self.tr("Build local cache of the reference layer") ) ) self.addOutput( QgsProcessingOutputVectorLayer( - self.OUTPUT, - self.tr('Original layer with snapped features') + self.OUTPUT, self.tr("Original layer with snapped features") ) ) @@ -125,47 +131,28 @@ def processAlgorithm(self, parameters, context, feedback): inputLyr = self.parameterAsVectorLayer(parameters, self.INPUT, context) if inputLyr is None: raise QgsProcessingException( - self.invalidSourceError( - parameters, - self.INPUT - ) - ) - onlySelected = self.parameterAsBool( - parameters, - self.SELECTED, - context - ) - refLyr = self.parameterAsVectorLayer( - parameters, - self.REFERENCE_LAYER, - context + self.invalidSourceError(parameters, self.INPUT) ) + onlySelected = self.parameterAsBool(parameters, self.SELECTED, context) + refLyr = self.parameterAsSource(parameters, self.REFERENCE_LAYER, context) if refLyr is None: raise QgsProcessingException( - self.invalidSourceError( - parameters, - self.REFERENCE_LAYER - ) - ) - tol = self.parameterAsDouble( - parameters, - self.TOLERANCE, - context - ) - behavior = self.parameterAsEnum( - parameters, - self.BEHAVIOR, - context + self.invalidSourceError(parameters, self.REFERENCE_LAYER) ) - buildLocalCache = self.parameterAsBool( - parameters, self.BUILD_CACHE, context - ) + tol = self.parameterAsDouble(parameters, self.TOLERANCE, context) + behavior = self.parameterAsEnum(parameters, self.BEHAVIOR, context) + buildLocalCache = self.parameterAsBool(parameters, self.BUILD_CACHE, context) nSteps = 6 if buildLocalCache else 4 currentStep = 0 multiStepFeedback = QgsProcessingMultiStepFeedback(nSteps, feedback) multiStepFeedback.setCurrentStep(currentStep) multiStepFeedback.setProgressText(self.tr("Creating aux structure...")) - auxLyr = layerHandler.createAndPopulateUnifiedVectorLayer([inputLyr], geomType=inputLyr.wkbType(), onlySelected = onlySelected, feedback=multiStepFeedback) + auxLyr = layerHandler.createAndPopulateUnifiedVectorLayer( + [inputLyr], + geomType=inputLyr.wkbType(), + onlySelected=onlySelected, + feedback=multiStepFeedback, + ) currentStep += 1 multiStepFeedback.setCurrentStep(currentStep) @@ -175,22 +162,24 @@ def processAlgorithm(self, parameters, context, feedback): if buildLocalCache: multiStepFeedback.setProgressText(self.tr("Building local cache...")) multiStepFeedback.setCurrentStep(currentStep) - refLyr = algRunner.runAddAutoIncrementalField(refLyr, context, multiStepFeedback) + refLyr = algRunner.runAddAutoIncrementalField( + refLyr, context, multiStepFeedback, is_child_algorithm=True + ) currentStep += 1 multiStepFeedback.setCurrentStep(currentStep) - algRunner.runCreateSpatialIndex(refLyr, context, multiStepFeedback) + algRunner.runCreateSpatialIndex(refLyr, context, multiStepFeedback, is_child_algorithm=True) currentStep += 1 multiStepFeedback.setCurrentStep(currentStep) multiStepFeedback.setProgressText(self.tr("Running snap...")) snapped = algRunner.runSnapGeometriesToLayer( inputLayer=auxLyr, - referenceLayer=refLyr, + referenceLayer=refLyr if buildLocalCache else parameters[self.REFERENCE_LAYER], tol=tol, behavior=behavior, context=context, - feedback=multiStepFeedback + feedback=multiStepFeedback, ) currentStep += 1 @@ -199,7 +188,9 @@ def processAlgorithm(self, parameters, context, feedback): multiStepFeedback.setCurrentStep(currentStep) multiStepFeedback.setProgressText(self.tr("Updating original layer...")) - layerHandler.updateOriginalLayersFromUnifiedLayer([inputLyr], snapped, feedback=multiStepFeedback, onlySelected=onlySelected) + layerHandler.updateOriginalLayersFromUnifiedLayer( + [inputLyr], snapped, feedback=multiStepFeedback, onlySelected=onlySelected + ) return {self.OUTPUT: inputLyr} def name(self): @@ -210,21 +201,21 @@ def name(self): lowercase alphanumeric characters only and no spaces or other formatting characters. """ - return 'snaplayeronlayer' + return "snaplayeronlayer" def displayName(self): """ Returns the translated algorithm name, which should be used for any user-visible display of the algorithm name. """ - return self.tr('Snap layer on layer') + return self.tr("Snap layer on layer") def group(self): """ Returns the name of the group this algorithm belongs to. This string should be localised. """ - return self.tr('Quality Assurance Tools (Manipulation Processes)') + return self.tr("Quality Assurance Tools (Manipulation Processes)") def groupId(self): """ @@ -234,10 +225,10 @@ def groupId(self): contain lowercase alphanumeric characters only and no spaces or other formatting characters. """ - return 'DSGTools: Quality Assurance Tools (Manipulation Processes)' + return "DSGTools: Quality Assurance Tools (Manipulation Processes)" def tr(self, string): - return QCoreApplication.translate('SnapLayerOnLayerAndUpdateAlgorithm', string) + return QCoreApplication.translate("SnapLayerOnLayerAndUpdateAlgorithm", string) def createInstance(self): return SnapLayerOnLayerAndUpdateAlgorithm() diff --git a/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/snapToGridAndUpdateAlgorithm.py b/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/snapToGridAndUpdateAlgorithm.py index ffec16599..76db5a7e3 100644 --- a/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/snapToGridAndUpdateAlgorithm.py +++ b/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/snapToGridAndUpdateAlgorithm.py @@ -24,30 +24,39 @@ import processing from DsgTools.core.GeometricTools.layerHandler import LayerHandler -from qgis.core import (QgsDataSourceUri, QgsFeature, QgsFeatureSink, - QgsGeometry, QgsProcessing, QgsProcessingAlgorithm, - QgsProcessingException, QgsProcessingMultiStepFeedback, - QgsProcessingOutputVectorLayer, - QgsProcessingParameterBoolean, - QgsProcessingParameterDistance, - QgsProcessingParameterEnum, - QgsProcessingParameterFeatureSink, - QgsProcessingParameterFeatureSource, - QgsProcessingParameterField, - QgsProcessingParameterMultipleLayers, - QgsProcessingParameterNumber, - QgsProcessingParameterVectorLayer, QgsProcessingUtils, - QgsSpatialIndex, QgsWkbTypes) +from qgis.core import ( + QgsDataSourceUri, + QgsFeature, + QgsFeatureSink, + QgsGeometry, + QgsProcessing, + QgsProcessingAlgorithm, + QgsProcessingException, + QgsProcessingMultiStepFeedback, + QgsProcessingOutputVectorLayer, + QgsProcessingParameterBoolean, + QgsProcessingParameterDistance, + QgsProcessingParameterEnum, + QgsProcessingParameterFeatureSink, + QgsProcessingParameterFeatureSource, + QgsProcessingParameterField, + QgsProcessingParameterMultipleLayers, + QgsProcessingParameterNumber, + QgsProcessingParameterVectorLayer, + QgsProcessingUtils, + QgsSpatialIndex, + QgsWkbTypes, +) from ...algRunner import AlgRunner from .validationAlgorithm import ValidationAlgorithm class SnapToGridAndUpdateAlgorithm(ValidationAlgorithm): - INPUT = 'INPUT' - SELECTED = 'SELECTED' - TOLERANCE = 'TOLERANCE' - OUTPUT = 'OUTPUT' + INPUT = "INPUT" + SELECTED = "SELECTED" + TOLERANCE = "TOLERANCE" + OUTPUT = "OUTPUT" def initAlgorithm(self, config): """ @@ -56,30 +65,27 @@ def initAlgorithm(self, config): self.addParameter( QgsProcessingParameterVectorLayer( self.INPUT, - self.tr('Input layer'), - [QgsProcessing.TypeVectorAnyGeometry] + self.tr("Input layer"), + [QgsProcessing.TypeVectorAnyGeometry], ) ) self.addParameter( QgsProcessingParameterBoolean( - self.SELECTED, - self.tr('Process only selected features') + self.SELECTED, self.tr("Process only selected features") ) ) - - self.addParameter( - QgsProcessingParameterDistance( - self.TOLERANCE, - self.tr('Tolerance'), - parentParameterName=self.INPUT, - minValue=0, - defaultValue=0.001 - ) + param = QgsProcessingParameterDistance( + self.TOLERANCE, + self.tr("Tolerance"), + parentParameterName=self.INPUT, + minValue=0, + defaultValue=1e-10, ) + param.setMetadata({'widget_wrapper':{'decimals': 12}}) + self.addParameter(param) self.addOutput( QgsProcessingOutputVectorLayer( - self.OUTPUT, - self.tr('Original layer with features snapped to grid') + self.OUTPUT, self.tr("Original layer with features snapped to grid") ) ) @@ -92,53 +98,39 @@ def processAlgorithm(self, parameters, context, feedback): inputLyr = self.parameterAsVectorLayer(parameters, self.INPUT, context) if inputLyr is None: raise QgsProcessingException( - self.invalidSourceError( - parameters, - self.INPUT - ) - ) - onlySelected = self.parameterAsBool( - parameters, - self.SELECTED, - context - ) - tol = self.parameterAsDouble( - parameters, - self.TOLERANCE, - context + self.invalidSourceError(parameters, self.INPUT) ) + onlySelected = self.parameterAsBool(parameters, self.SELECTED, context) + tol = self.parameterAsDouble(parameters, self.TOLERANCE, context) multiStepFeedback = QgsProcessingMultiStepFeedback(3, feedback) multiStepFeedback.setCurrentStep(0) - multiStepFeedback.pushInfo(self.tr('Populating temp layer...')) + multiStepFeedback.pushInfo(self.tr("Populating temp layer...")) auxLyr = layerHandler.createAndPopulateUnifiedVectorLayer( [inputLyr], geomType=inputLyr.wkbType(), onlySelected=onlySelected, - feedback=multiStepFeedback - ) + feedback=multiStepFeedback, + ) multiStepFeedback.setCurrentStep(1) multiStepFeedback.pushInfo( self.tr( - 'Snapping geometries from layer {input} to grid with size {tol}...' - ).format(input=inputLyr.name(), tol=tol) - ) + "Snapping geometries from layer {input} to grid with size {tol}..." + ).format(input=inputLyr.name(), tol=tol) + ) snappedLayer = algRunner.runSnapToGrid( - auxLyr, - tol, - context, - feedback=multiStepFeedback - ) + auxLyr, tol, context, feedback=multiStepFeedback + ) multiStepFeedback.setCurrentStep(2) - multiStepFeedback.pushInfo(self.tr('Updating original layer...')) + multiStepFeedback.pushInfo(self.tr("Updating original layer...")) layerHandler.updateOriginalLayersFromUnifiedLayer( [inputLyr], snappedLayer, feedback=multiStepFeedback, - onlySelected=onlySelected - ) + onlySelected=onlySelected, + ) return {self.OUTPUT: inputLyr} @@ -150,21 +142,21 @@ def name(self): lowercase alphanumeric characters only and no spaces or other formatting characters. """ - return 'snaptogridandupdate' + return "snaptogridandupdate" def displayName(self): """ Returns the translated algorithm name, which should be used for any user-visible display of the algorithm name. """ - return self.tr('Snap to grid and update') + return self.tr("Snap to grid and update") def group(self): """ Returns the name of the group this algorithm belongs to. This string should be localised. """ - return self.tr('Quality Assurance Tools (Manipulation Processes)') + return self.tr("Quality Assurance Tools (Manipulation Processes)") def groupId(self): """ @@ -174,10 +166,10 @@ def groupId(self): contain lowercase alphanumeric characters only and no spaces or other formatting characters. """ - return 'DSGTools: Quality Assurance Tools (Manipulation Processes)' + return "DSGTools: Quality Assurance Tools (Manipulation Processes)" def tr(self, string): - return QCoreApplication.translate('SnapToGridAndUpdateAlgorithm', string) + return QCoreApplication.translate("SnapToGridAndUpdateAlgorithm", string) def createInstance(self): return SnapToGridAndUpdateAlgorithm() diff --git a/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/spatialRulesCheckerAlgorithm.py b/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/spatialRulesCheckerAlgorithm.py index 8a2f8a200..55b72de29 100644 --- a/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/spatialRulesCheckerAlgorithm.py +++ b/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/spatialRulesCheckerAlgorithm.py @@ -25,47 +25,50 @@ import processing, os, requests from time import sleep from PyQt5.QtCore import QCoreApplication -from qgis.core import (QgsProcessing, - QgsFeatureSink, - QgsProcessingAlgorithm, - QgsProcessingParameterFeatureSource, - QgsProcessingParameterFeatureSink, - QgsFeature, - QgsDataSourceUri, - QgsProcessingOutputVectorLayer, - QgsProcessingParameterVectorLayer, - QgsWkbTypes, - QgsProcessingParameterBoolean, - QgsProcessingParameterEnum, - QgsProcessingParameterNumber, - QgsProcessingParameterMultipleLayers, - QgsProcessingUtils, - QgsSpatialIndex, - QgsGeometry, - QgsProcessingParameterField, - QgsProcessingMultiStepFeedback, - QgsProcessingParameterFile, - QgsProcessingParameterExpression, - QgsProcessingException, - QgsProcessingParameterString, - QgsProcessingParameterDefinition, - QgsProcessingParameterType) +from qgis.core import ( + QgsProcessing, + QgsFeatureSink, + QgsProcessingAlgorithm, + QgsProcessingParameterFeatureSource, + QgsProcessingParameterFeatureSink, + QgsFeature, + QgsDataSourceUri, + QgsProcessingOutputVectorLayer, + QgsProcessingParameterVectorLayer, + QgsWkbTypes, + QgsProcessingParameterBoolean, + QgsProcessingParameterEnum, + QgsProcessingParameterNumber, + QgsProcessingParameterMultipleLayers, + QgsProcessingUtils, + QgsSpatialIndex, + QgsGeometry, + QgsProcessingParameterField, + QgsProcessingMultiStepFeedback, + QgsProcessingParameterFile, + QgsProcessingParameterExpression, + QgsProcessingException, + QgsProcessingParameterString, + QgsProcessingParameterDefinition, + QgsProcessingParameterType, +) -class SpatialRulesCheckerAlgorithm(QgsProcessingAlgorithm): - RULES_SET = 'RULES_SET' +class SpatialRulesCheckerAlgorithm(QgsProcessingAlgorithm): + RULES_SET = "RULES_SET" def initAlgorithm(self, config): """ Parameter setting. """ spatialRulesSet = ParameterSpatialRulesSet( - self.RULES_SET, - description=self.tr('Spatial Rules Set') - ) - managerParameter.setMetadata({ - 'widget_wrapper' : 'DsgTools.gui.ProcessingUI.spatialRulesSetWrapper.SpatialRulesSetWrapper' - }) + self.RULES_SET, description=self.tr("Spatial Rules Set") + ) + managerParameter.setMetadata( + { + "widget_wrapper": "DsgTools.gui.ProcessingUI.spatialRulesSetWrapper.SpatialRulesSetWrapper" + } + ) self.addParameter(managerParameter) def parameterAsSpatialRulesSet(self, parameters, name, context): @@ -87,21 +90,21 @@ def name(self): lowercase alphanumeric characters only and no spaces or other formatting characters. """ - return 'spatialruleschecker' + return "spatialruleschecker" def displayName(self): """ Returns the translated algorithm name, which should be used for any user-visible display of the algorithm name. """ - return self.tr('Spatial Rules Checker') + return self.tr("Spatial Rules Checker") def group(self): """ Returns the name of the group this algorithm belongs to. This string should be localised. """ - return self.tr('Quality Assurance Tools (Identification Processes)') + return self.tr("Quality Assurance Tools (Identification Processes)") def groupId(self): """ @@ -111,16 +114,16 @@ def groupId(self): contain lowercase alphanumeric characters only and no spaces or other formatting characters. """ - return 'DSGTools: Quality Assurance Tools (Identification Processes)' + return "DSGTools: Quality Assurance Tools (Identification Processes)" def tr(self, string): - return QCoreApplication.translate('RunRemoteFMEAlgorithm', string) + return QCoreApplication.translate("RunRemoteFMEAlgorithm", string) def createInstance(self): return RunRemoteFMEAlgorithm() -class ParameterSpatialRulesSetType(QgsProcessingParameterType): +class ParameterSpatialRulesSetType(QgsProcessingParameterType): def __init__(self): super().__init__() @@ -128,20 +131,24 @@ def create(self, name): return ParameterSpatialRulesSet(name) def metadata(self): - return {'widget_wrapper': 'DsgTools.gui.ProcessingUI.spatialRulesSetWrapper.SpatialRulesSetWrapper'} + return { + "widget_wrapper": "DsgTools.gui.ProcessingUI.spatialRulesSetWrapper.SpatialRulesSetWrapper" + } def name(self): - return QCoreApplication.translate('Processing', 'Spatial Rules Set') + return QCoreApplication.translate("Processing", "Spatial Rules Set") def id(self): - return 'spatial_rules_set_type' + return "spatial_rules_set_type" def description(self): - return QCoreApplication.translate('Processing', 'Set of spatial rules. Used on Spatial Rules Checker.') + return QCoreApplication.translate( + "Processing", "Set of spatial rules. Used on Spatial Rules Checker." + ) -class ParameterSpatialRulesSet(QgsProcessingParameterDefinition): - def __init__(self, name, description=''): +class ParameterSpatialRulesSet(QgsProcessingParameterDefinition): + def __init__(self, name, description=""): super().__init__(name, description) def clone(self): @@ -153,7 +160,7 @@ def type(self): @staticmethod def typeName(): - return 'spatial_rules_set' + return "spatial_rules_set" def checkValueIsAcceptable(self, value, context=None): return True @@ -166,4 +173,4 @@ def asScriptCode(self): @classmethod def fromScriptCode(cls, name, description, isOptional, definition): - raise NotImplementedError() \ No newline at end of file + raise NotImplementedError() diff --git a/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/spellCheckerAlgorithm.py b/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/spellCheckerAlgorithm.py new file mode 100644 index 000000000..2f3e2540a --- /dev/null +++ b/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/spellCheckerAlgorithm.py @@ -0,0 +1,176 @@ +import re + +from PyQt5.QtCore import QCoreApplication +from qgis import core +from qgis.core import ( + QgsFeature, + QgsField, + QgsFields, + QgsProcessing, + QgsProcessingAlgorithm, + QgsProcessingParameterField, + QgsProcessingParameterFeatureSink, + QgsProcessingParameterVectorLayer, + QgsWkbTypes, + QgsProcessingException, +) +from qgis.PyQt.Qt import QVariant + +from ..LayerManagementAlgs.spellChecker.spellCheckerCtrl import SpellCheckerCtrl + + +class SpellCheckerAlgorithm(QgsProcessingAlgorithm): + + INPUT_LAYER = "INPUT_LAYER" + ATTRIBUTE_NAME = "ATTRIBUTE_NAME" + PRIMARY_KEY_FIELD = "PRIMARY_KEY_FIELD" + OUTPUT = "OUTPUT" + + def __init__(self): + super(SpellCheckerAlgorithm, self).__init__() + + def initAlgorithm(self, config): + self.addParameter( + QgsProcessingParameterVectorLayer( + self.INPUT_LAYER, + self.tr("Layer"), + [QgsProcessing.TypeVectorAnyGeometry], + ) + ) + + self.addParameter( + QgsProcessingParameterField( + self.ATTRIBUTE_NAME, + self.tr("Attribute name"), + type=QgsProcessingParameterField.String, + parentLayerParameterName=self.INPUT_LAYER, + allowMultiple=False, + defaultValue="nome", + ) + ) + + self.addParameter( + QgsProcessingParameterField( + self.PRIMARY_KEY_FIELD, + self.tr("Primary key field"), + type=QgsProcessingParameterField.Any, + parentLayerParameterName=self.INPUT_LAYER, + allowMultiple=False, + defaultValue="id", + ) + ) + + self.addParameter( + QgsProcessingParameterFeatureSink(self.OUTPUT, self.tr("Flags")) + ) + + def processAlgorithm(self, parameters, context, feedback): + layer = self.parameterAsVectorLayer(parameters, self.INPUT_LAYER, context) + attributeName = self.parameterAsFields( + parameters, self.ATTRIBUTE_NAME, context + )[0] + pkField = self.parameterAsFields(parameters, self.PRIMARY_KEY_FIELD, context)[0] + + try: + spellchecker = SpellCheckerCtrl("pt-BR") + except: + raise QgsProcessingException( + self.tr( + 'Error loading spellchecker files. Please go to the DSGTools menu and run "Download external data".' + ) + ) + + errorFieldName = "{}_erro".format(attributeName) + + layer.startEditing() + attributeIndex = self.getAttributeIndex(attributeName, layer) + if attributeIndex < 0: + return {self.OUTPUT: "Attribute index not found"} + fieldRelation = layer.fields().field(pkField) + auxLayer = core.QgsAuxiliaryStorage().createAuxiliaryLayer(fieldRelation, layer) + vdef = core.QgsPropertyDefinition( + errorFieldName, + core.QgsPropertyDefinition.DataType.DataTypeString, + "", + "", + "", + ) + auxLayer.addAuxiliaryField(vdef) + layer.setAuxiliaryLayer(auxLayer) + idx = layer.fields().indexOf("auxiliary_storage__{}".format(errorFieldName)) + layer.setFieldAlias(idx, errorFieldName) + auxFields = auxLayer.fields() + for feature in layer.getFeatures(): + if feedback.isCanceled(): + return {self.OUTPUT: ""} + attributeValue = feature[attributeIndex] + if not attributeValue: + continue + attributeValue = "".join( + e + for e in attributeValue + if not (e in [",", ";", "&", "."] or e.isdigit()) + ) + wordlist = re.split(" |/", attributeValue) + wordlist = [w for w in wordlist if not w in ["-"]] + wrongWords = [ + word for word in wordlist if not spellchecker.hasWord(word.lower()) + ] + if len(wrongWords) == 0: + continue + auxFeature = QgsFeature(auxFields) + auxFeature["ASPK"] = feature[pkField] + auxFeature["_{}".format(errorFieldName)] = ";".join(wrongWords) + auxLayer.addFeature(auxFeature) + returnMessage = "Field {} added/edited".format(errorFieldName) + return {self.OUTPUT: returnMessage} + + def getAttributeIndex(self, attributeName, layer): + if not layer.fields().indexOf(attributeName) < 0: + return layer.fields().indexOf(attributeName) + for attrName, attrAlias in list(layer.attributeAliases().items()): + if not (attributeName in [attrName, attrAlias]): + continue + if layer.fields().indexOf(attrName) < 0: + return layer.fields().indexOf(attrAlias) + return layer.fields().indexOf(attrName) + return -1 + + def getFlagWkbType(self): + return QgsWkbTypes.Point + + def getFlagFields(self): + sinkFields = QgsFields() + sinkFields.append(QgsField("erro", QVariant.String)) + sinkFields.append(QgsField("correcao", QVariant.String)) + sinkFields.append(QgsField("outras_opcoes", QVariant.String)) + return sinkFields + + def name(self): + return "spellchecker" + + def displayName(self): + return self.tr("Spell check") + + def group(self): + """ + Returns the name of the group this algorithm belongs to. This string + should be localised. + """ + return self.tr("Quality Assurance Tools (Identification Processes)") + + def groupId(self): + """ + Returns the unique ID of the group this algorithm belongs to. This + string should be fixed for the algorithm, and must not be localised. + The group id should be unique within each provider. Group id should + contain lowercase alphanumeric characters only and no spaces or other + formatting characters. + """ + return "DSGTools: Quality Assurance Tools (Identification Processes)" + + def tr(self, string): + return QCoreApplication.translate("SpellCheckerAlgorithm", string) + + def createInstance(self): + return SpellCheckerAlgorithm() diff --git a/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/streamOrder.py b/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/streamOrder.py new file mode 100644 index 000000000..ebc574412 --- /dev/null +++ b/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/streamOrder.py @@ -0,0 +1,177 @@ +# -*- coding: utf-8 -*- +""" +/*************************************************************************** + DsgTools + A QGIS plugin + Brazilian Army Cartographic Production Tools + ------------------- + begin : 2023-03-29 + git sha : $Format:%H$ + copyright : (C) 2023 by Philipe Borba - Cartographic Engineer @ Brazilian Army + email : borba.philipe@eb.mil.br + ***************************************************************************/ +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ +""" + +from DsgTools.core.DSGToolsProcessingAlgs.algRunner import AlgRunner +from qgis.PyQt.QtCore import (QCoreApplication, QVariant) +from qgis.core import (QgsProcessing, + QgsFeatureSink, + QgsProcessingAlgorithm, + QgsProcessingParameterFeatureSink, + QgsProcessingParameterVectorLayer, + QgsFeature, + QgsField, + QgsGeometry, + QgsPointXY, + QgsProcessingException, + QgsProcessingMultiStepFeedback, + QgsProcessingParameterFeatureSource, + QgsVectorLayerUtils, + ) +from DsgTools.core.GeometricTools import graphHandler + +class StreamOrder(QgsProcessingAlgorithm): + + INPUT = 'INPUT' + OUTPUT = 'OUTPUT' + + def initAlgorithm(self, config=None): + self.addParameter( + QgsProcessingParameterFeatureSource( + self.INPUT, + self.tr("Input network"), + [QgsProcessing.TypeVectorLine], + optional=False, + ) + ) + + self.addParameter( + QgsProcessingParameterFeatureSink( + self.OUTPUT, + self.tr('Output') + ) + ) + + def processAlgorithm(self, parameters, context, feedback): + + try: + import networkx as nx + except ImportError: + raise QgsProcessingException( + self.tr( + "This algorithm requires the Python networkx library. Please install this library and try again." + ) + ) + algRunner = AlgRunner() + networkLayer = self.parameterAsSource(parameters, self.INPUT, context) + fields = networkLayer.fields() + fields.append(QgsField('stream_order', QVariant.Int)) + (sink, sink_id) = self.parameterAsSink( + parameters, + self.OUTPUT, + context, + fields, + networkLayer.wkbType(), + networkLayer.sourceCrs(), + ) + multiStepFeedback = QgsProcessingMultiStepFeedback(6, feedback) + currentStep = 0 + multiStepFeedback.setCurrentStep(currentStep) + localCache = algRunner.runCreateFieldWithExpression( + inputLyr=parameters[self.INPUT], + expression="$id", + fieldName="featid", + fieldType=1, + context=context, + feedback=multiStepFeedback, + ) + currentStep += 1 + multiStepFeedback.setCurrentStep(currentStep) + algRunner.runCreateSpatialIndex( + inputLyr=localCache, context=context, feedback=multiStepFeedback + ) + currentStep += 1 + multiStepFeedback.setCurrentStep(currentStep) + nodesLayer = algRunner.runExtractSpecificVertices( + inputLyr=localCache, + vertices="0,-1", + context=context, + feedback=multiStepFeedback, + ) + currentStep += 1 + multiStepFeedback.setCurrentStep(currentStep) + ( + nodeDict, + nodeIdDict, + edgeDict, + hashDict, + networkBidirectionalGraph, + ) = graphHandler.buildAuxStructures( + nx, nodesLayer=nodesLayer, edgesLayer=localCache, feedback=multiStepFeedback, directed=True + ) + currentStep += 1 + multiStepFeedback.setCurrentStep(currentStep) + G_copy = graphHandler.evaluateStreamOrder(networkBidirectionalGraph, feedback=multiStepFeedback) + currentStep += 1 + multiStepFeedback.setCurrentStep(currentStep) + if len(G_copy.edges) == 0: + return {self.OUTPUT: sink_id} + stepSize = 100 / len(G_copy.edges) + for current, (n0, n1) in enumerate(G_copy.edges): + if multiStepFeedback.isCanceled(): + break + newFeat = QgsFeature(fields) + oldFeat = edgeDict[G_copy[n0][n1]["featid"]] + newFeat.setGeometry(oldFeat.geometry()) + for idx, attrValue in enumerate(oldFeat.attributes()): + newFeat.setAttribute(idx, attrValue) + newFeat["stream_order"] = G_copy[n0][n1]["stream_order"] + + sink.addFeature(newFeat) + multiStepFeedback.setProgress(current * stepSize) + return {self.OUTPUT: sink_id} + + def tr(self, string): + return QCoreApplication.translate('Processing', string) + + def createInstance(self): + return StreamOrder() + + def name(self): + return 'streamorder' + + def displayName(self): + """ + Returns the translated algorithm name, which should be used for any + user-visible display of the algorithm name. + """ + return self.tr("Stream Order") + + def group(self): + """ + Returns the name of the group this algorithm belongs to. This string + should be localised. + """ + return self.tr("Quality Assurance Tools (Network Processes)") + + def groupId(self): + """ + Returns the unique ID of the group this algorithm belongs to. This + string should be fixed for the algorithm, and must not be localised. + The group id should be unique within each provider. Group id should + contain lowercase alphanumeric characters only and no spaces or other + formatting characters. + """ + return "DSGTools: Quality Assurance Tools (Network Processes)" + + def shortHelpString(self): + return self.tr("O algoritmo orderna ou direciona fluxo, como linhas de drenagem ") + diff --git a/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/topologicalCleanAlgorithm.py b/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/topologicalCleanAlgorithm.py index f058d5efe..be155efb6 100644 --- a/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/topologicalCleanAlgorithm.py +++ b/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/topologicalCleanAlgorithm.py @@ -24,29 +24,39 @@ import processing from DsgTools.core.GeometricTools.layerHandler import LayerHandler -from qgis.core import (QgsDataSourceUri, QgsFeature, QgsFeatureSink, - QgsGeometry, QgsProcessing, QgsProcessingAlgorithm, - QgsProcessingException, QgsProcessingMultiStepFeedback, - QgsProcessingOutputVectorLayer, - QgsProcessingParameterBoolean, - QgsProcessingParameterEnum, - QgsProcessingParameterFeatureSink, - QgsProcessingParameterFeatureSource, - QgsProcessingParameterMultipleLayers, - QgsProcessingParameterNumber, - QgsProcessingParameterVectorLayer, QgsProcessingUtils, - QgsProject, QgsSpatialIndex, QgsWkbTypes) +from qgis.core import ( + QgsDataSourceUri, + QgsFeature, + QgsFeatureSink, + QgsGeometry, + QgsProcessing, + QgsProcessingAlgorithm, + QgsProcessingException, + QgsProcessingMultiStepFeedback, + QgsProcessingOutputVectorLayer, + QgsProcessingParameterBoolean, + QgsProcessingParameterEnum, + QgsProcessingParameterFeatureSink, + QgsProcessingParameterFeatureSource, + QgsProcessingParameterMultipleLayers, + QgsProcessingParameterNumber, + QgsProcessingParameterVectorLayer, + QgsProcessingUtils, + QgsProject, + QgsSpatialIndex, + QgsWkbTypes, +) from ...algRunner import AlgRunner from .validationAlgorithm import ValidationAlgorithm class TopologicalCleanAlgorithm(ValidationAlgorithm): - INPUTLAYERS = 'INPUTLAYERS' - SELECTED = 'SELECTED' - TOLERANCE = 'TOLERANCE' - MINAREA = 'MINAREA' - FLAGS = 'FLAGS' + INPUTLAYERS = "INPUTLAYERS" + SELECTED = "SELECTED" + TOLERANCE = "TOLERANCE" + MINAREA = "MINAREA" + FLAGS = "FLAGS" def initAlgorithm(self, config): """ @@ -55,38 +65,36 @@ def initAlgorithm(self, config): self.addParameter( QgsProcessingParameterMultipleLayers( self.INPUTLAYERS, - self.tr('Polygon Layers'), - QgsProcessing.TypeVectorPolygon + self.tr("Polygon Layers"), + QgsProcessing.TypeVectorPolygon, ) ) self.addParameter( QgsProcessingParameterBoolean( - self.SELECTED, - self.tr('Process only selected features') + self.SELECTED, self.tr("Process only selected features") ) ) self.addParameter( QgsProcessingParameterNumber( self.TOLERANCE, - self.tr('Snap radius'), + self.tr("Snap radius"), minValue=0, defaultValue=1, - type=QgsProcessingParameterNumber.Double + type=QgsProcessingParameterNumber.Double, ) ) self.addParameter( QgsProcessingParameterNumber( self.MINAREA, - self.tr('Minimum area'), + self.tr("Minimum area"), minValue=0, defaultValue=0.0001, - type=QgsProcessingParameterNumber.Double + type=QgsProcessingParameterNumber.Double, ) ) self.addParameter( QgsProcessingParameterFeatureSink( - self.FLAGS, - self.tr('{0} Flags').format(self.displayName()) + self.FLAGS, self.tr("{0} Flags").format(self.displayName()) ) ) @@ -100,11 +108,8 @@ def processAlgorithm(self, parameters, context, feedback): inputLyrList = self.parameterAsLayerList(parameters, self.INPUTLAYERS, context) if inputLyrList is None or inputLyrList == []: raise QgsProcessingException( - self.invalidSourceError( - parameters, - self.INPUTLAYERS - ) - ) + self.invalidSourceError(parameters, self.INPUTLAYERS) + ) for layer in inputLyrList: if layer.featureCount() > 0: geomType = next(layer.getFeatures()).geometry().wkbType() @@ -112,68 +117,44 @@ def processAlgorithm(self, parameters, context, feedback): else: raise QgsProcessingException( self.invalidSourceError(parameters, self.INPUTLAYERS), - self.tr("Provided layers have no features in it.") + self.tr("Provided layers have no features in it."), ) - onlySelected = self.parameterAsBool( - parameters, - self.SELECTED, - context - ) - snap = self.parameterAsDouble( - parameters, - self.TOLERANCE, - context - ) - minArea = self.parameterAsDouble( - parameters, - self.MINAREA, - context - ) - self.prepareFlagSink( - parameters, - inputLyrList[0], - geomType, - context - ) + onlySelected = self.parameterAsBool(parameters, self.SELECTED, context) + snap = self.parameterAsDouble(parameters, self.TOLERANCE, context) + minArea = self.parameterAsDouble(parameters, self.MINAREA, context) + self.prepareFlagSink(parameters, inputLyrList[0], geomType, context) multiStepFeedback = QgsProcessingMultiStepFeedback(3, feedback) multiStepFeedback.setCurrentStep(0) - multiStepFeedback.pushInfo(self.tr('Building unified layer...')) + multiStepFeedback.pushInfo(self.tr("Building unified layer...")) # in order to check the topology of all layers as a whole, all features # are handled as if they formed a single layer coverage = layerHandler.createAndPopulateUnifiedVectorLayer( inputLyrList, geomType=geomType, onlySelected=onlySelected, - feedback=multiStepFeedback + feedback=multiStepFeedback, ) multiStepFeedback.setCurrentStep(1) - multiStepFeedback.pushInfo(self.tr('Running clean on unified layer...')) + multiStepFeedback.pushInfo(self.tr("Running clean on unified layer...")) cleanedCoverage, error = algRunner.runClean( coverage, - [ - algRunner.RMSA, - algRunner.Break, - algRunner.RmDupl, - algRunner.RmDangle - ], + [algRunner.RMSA, algRunner.Break, algRunner.RmDupl, algRunner.RmDangle], context, returnError=True, snap=snap, minArea=minArea, - feedback=multiStepFeedback - ) + feedback=multiStepFeedback, + ) multiStepFeedback.setCurrentStep(2) - multiStepFeedback.pushInfo(self.tr('Updating original layer...')) + multiStepFeedback.pushInfo(self.tr("Updating original layer...")) layerHandler.updateOriginalLayersFromUnifiedLayer( - inputLyrList, - cleanedCoverage, - feedback=multiStepFeedback - ) + inputLyrList, cleanedCoverage, feedback=multiStepFeedback + ) self.flagCoverageIssues(cleanedCoverage, error, feedback) - return {self.INPUTLAYERS : inputLyrList, self.FLAGS : self.flagSink} + return {self.INPUTLAYERS: inputLyrList, self.FLAGS: self.flagSink} def flagCoverageIssues(self, cleanedCoverage, error, feedback): overlapDict = dict() @@ -191,22 +172,26 @@ def flagCoverageIssues(self, cleanedCoverage, error, feedback): if len(featList) > 1: txtList = [] for i in featList: - txtList += ['{0} (id={1})'.format(i['layer'], i['featid'])] - txt = ', '.join(txtList) + txtList += ["{0} (id={1})".format(i["layer"], i["featid"])] + txt = ", ".join(txtList) self.flagFeature( - featList[0].geometry(), self.tr('Features from {0} overlap').format(txt)) + featList[0].geometry(), + self.tr("Features from {0} overlap").format(txt), + ) elif len(featList) == 1: attrList = featList[0].attributes() - if attrList == len(attrList)*[None]: + if attrList == len(attrList) * [None]: self.flagFeature( - featList[0].geometry(), self.tr('Gap in coverage.')) + featList[0].geometry(), self.tr("Gap in coverage.") + ) if error: for feat in error.getFeatures(): if feedback.isCanceled(): break self.flagFeature( - feat.geometry(), self.tr('Clean error on unified layer.')) + feat.geometry(), self.tr("Clean error on unified layer.") + ) def name(self): """ @@ -216,21 +201,21 @@ def name(self): lowercase alphanumeric characters only and no spaces or other formatting characters. """ - return 'topologicalclean' + return "topologicalclean" def displayName(self): """ Returns the translated algorithm name, which should be used for any user-visible display of the algorithm name. """ - return self.tr('Topological Clean Polygons') + return self.tr("Topological Clean Polygons") def group(self): """ Returns the name of the group this algorithm belongs to. This string should be localised. """ - return self.tr('Quality Assurance Tools (Topological Processes)') + return self.tr("Quality Assurance Tools (Topological Processes)") def groupId(self): """ @@ -240,10 +225,10 @@ def groupId(self): contain lowercase alphanumeric characters only and no spaces or other formatting characters. """ - return 'DSGTools: Quality Assurance Tools (Topological Processes)' + return "DSGTools: Quality Assurance Tools (Topological Processes)" def tr(self, string): - return QCoreApplication.translate('TopologicalCleanAlgorithm', string) + return QCoreApplication.translate("TopologicalCleanAlgorithm", string) def createInstance(self): return TopologicalCleanAlgorithm() diff --git a/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/topologicalCleanLinesAlgorithm.py b/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/topologicalCleanLinesAlgorithm.py index 769934228..e5a612c5e 100644 --- a/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/topologicalCleanLinesAlgorithm.py +++ b/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/topologicalCleanLinesAlgorithm.py @@ -24,30 +24,38 @@ import processing from DsgTools.core.GeometricTools.layerHandler import LayerHandler -from qgis.core import (QgsDataSourceUri, QgsFeature, QgsFeatureSink, - QgsGeometry, QgsProcessing, QgsProcessingAlgorithm, - QgsProcessingMultiStepFeedback, - QgsProcessingOutputVectorLayer, - QgsProcessingParameterBoolean, - QgsProcessingParameterEnum, - QgsProcessingParameterFeatureSink, - QgsProcessingParameterFeatureSource, - QgsProcessingParameterMultipleLayers, - QgsProcessingParameterNumber, - QgsProcessingParameterVectorLayer, QgsProcessingUtils, - QgsProject, QgsSpatialIndex, QgsWkbTypes) +from qgis.core import ( + QgsDataSourceUri, + QgsFeature, + QgsFeatureSink, + QgsGeometry, + QgsProcessing, + QgsProcessingAlgorithm, + QgsProcessingMultiStepFeedback, + QgsProcessingOutputVectorLayer, + QgsProcessingParameterBoolean, + QgsProcessingParameterEnum, + QgsProcessingParameterFeatureSink, + QgsProcessingParameterFeatureSource, + QgsProcessingParameterMultipleLayers, + QgsProcessingParameterNumber, + QgsProcessingParameterVectorLayer, + QgsProcessingUtils, + QgsProject, + QgsSpatialIndex, + QgsWkbTypes, +) from ...algRunner import AlgRunner from .topologicalCleanAlgorithm import TopologicalCleanAlgorithm class TopologicalCleanLinesAlgorithm(TopologicalCleanAlgorithm): - INPUTLAYERS = 'INPUTLAYERS' - SELECTED = 'SELECTED' - TOLERANCE = 'TOLERANCE' - MINAREA = 'MINAREA' - FLAGS = 'FLAGS' - + INPUTLAYERS = "INPUTLAYERS" + SELECTED = "SELECTED" + TOLERANCE = "TOLERANCE" + MINAREA = "MINAREA" + FLAGS = "FLAGS" def initAlgorithm(self, config): """ @@ -56,39 +64,37 @@ def initAlgorithm(self, config): self.addParameter( QgsProcessingParameterMultipleLayers( self.INPUTLAYERS, - self.tr('Linestring Layers'), - QgsProcessing.TypeVectorLine + self.tr("Linestring Layers"), + QgsProcessing.TypeVectorLine, ) ) self.addParameter( QgsProcessingParameterBoolean( - self.SELECTED, - self.tr('Process only selected features') + self.SELECTED, self.tr("Process only selected features") ) ) self.addParameter( QgsProcessingParameterNumber( self.TOLERANCE, - self.tr('Snap radius'), + self.tr("Snap radius"), minValue=0, defaultValue=1, - type=QgsProcessingParameterNumber.Double + type=QgsProcessingParameterNumber.Double, ) ) self.addParameter( QgsProcessingParameterNumber( self.MINAREA, - self.tr('Minimum area'), + self.tr("Minimum area"), minValue=0, defaultValue=0.0001, - type=QgsProcessingParameterNumber.Double + type=QgsProcessingParameterNumber.Double, ) ) - + self.addParameter( QgsProcessingParameterFeatureSink( - self.FLAGS, - self.tr('{0} Flags').format(self.displayName()) + self.FLAGS, self.tr("{0} Flags").format(self.displayName()) ) ) @@ -100,21 +106,21 @@ def name(self): lowercase alphanumeric characters only and no spaces or other formatting characters. """ - return 'topologicalcleanlines' + return "topologicalcleanlines" def displayName(self): """ Returns the translated algorithm name, which should be used for any user-visible display of the algorithm name. """ - return self.tr('Topological Clean Linestrings') + return self.tr("Topological Clean Linestrings") def group(self): """ Returns the name of the group this algorithm belongs to. This string should be localised. """ - return self.tr('Quality Assurance Tools (Topological Processes)') + return self.tr("Quality Assurance Tools (Topological Processes)") def groupId(self): """ @@ -124,10 +130,10 @@ def groupId(self): contain lowercase alphanumeric characters only and no spaces or other formatting characters. """ - return 'DSGTools: Quality Assurance Tools (Topological Processes)' + return "DSGTools: Quality Assurance Tools (Topological Processes)" def tr(self, string): - return QCoreApplication.translate('TopologicalCleanLinesAlgorithm', string) + return QCoreApplication.translate("TopologicalCleanLinesAlgorithm", string) def createInstance(self): return TopologicalCleanLinesAlgorithm() diff --git a/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/topologicalDouglasAreaSimplificationAlgorithm.py b/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/topologicalDouglasAreaSimplificationAlgorithm.py index 5d56033a7..c0ef78af9 100644 --- a/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/topologicalDouglasAreaSimplificationAlgorithm.py +++ b/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/topologicalDouglasAreaSimplificationAlgorithm.py @@ -24,18 +24,27 @@ import processing from DsgTools.core.GeometricTools.layerHandler import LayerHandler -from qgis.core import (QgsDataSourceUri, QgsFeature, QgsFeatureSink, - QgsGeometry, QgsProcessing, QgsProcessingAlgorithm, - QgsProcessingMultiStepFeedback, - QgsProcessingOutputVectorLayer, - QgsProcessingParameterBoolean, - QgsProcessingParameterEnum, - QgsProcessingParameterFeatureSink, - QgsProcessingParameterFeatureSource, - QgsProcessingParameterMultipleLayers, - QgsProcessingParameterNumber, - QgsProcessingParameterVectorLayer, QgsProcessingUtils, - QgsProject, QgsSpatialIndex, QgsWkbTypes) +from qgis.core import ( + QgsDataSourceUri, + QgsFeature, + QgsFeatureSink, + QgsGeometry, + QgsProcessing, + QgsProcessingAlgorithm, + QgsProcessingMultiStepFeedback, + QgsProcessingOutputVectorLayer, + QgsProcessingParameterBoolean, + QgsProcessingParameterEnum, + QgsProcessingParameterFeatureSink, + QgsProcessingParameterFeatureSource, + QgsProcessingParameterMultipleLayers, + QgsProcessingParameterNumber, + QgsProcessingParameterVectorLayer, + QgsProcessingUtils, + QgsProject, + QgsSpatialIndex, + QgsWkbTypes, +) from ...algRunner import AlgRunner from .validationAlgorithm import ValidationAlgorithm @@ -46,12 +55,13 @@ class TopologicalDouglasPeuckerAreaSimplificationAlgorithm(ValidationAlgorithm): Implements a Douglas Peucker algorithm to simplify areas taking into consideration the topological behavior for boundaries between layers. """ - INPUTLAYERS = 'INPUTLAYERS' - SELECTED = 'SELECTED' - SNAP = 'SNAP' - DOUGLASPARAMETER = 'DOUGLASPARAMETER' - MINAREA = 'MINAREA' - FLAGS = 'FLAGS' + + INPUTLAYERS = "INPUTLAYERS" + SELECTED = "SELECTED" + SNAP = "SNAP" + DOUGLASPARAMETER = "DOUGLASPARAMETER" + MINAREA = "MINAREA" + FLAGS = "FLAGS" def initAlgorithm(self, config): """ @@ -60,47 +70,45 @@ def initAlgorithm(self, config): self.addParameter( QgsProcessingParameterMultipleLayers( self.INPUTLAYERS, - self.tr('Polygon Layers'), - QgsProcessing.TypeVectorPolygon + self.tr("Polygon Layers"), + QgsProcessing.TypeVectorPolygon, ) ) self.addParameter( QgsProcessingParameterBoolean( - self.SELECTED, - self.tr('Process only selected features') + self.SELECTED, self.tr("Process only selected features") ) ) self.addParameter( QgsProcessingParameterNumber( self.DOUGLASPARAMETER, - self.tr('Douglas Deucker threshold'), + self.tr("Douglas Deucker threshold"), minValue=0, defaultValue=2, - type=QgsProcessingParameterNumber.Double + type=QgsProcessingParameterNumber.Double, ) ) self.addParameter( QgsProcessingParameterNumber( self.SNAP, - self.tr('Snap radius'), + self.tr("Snap radius"), minValue=0, defaultValue=1, - type=QgsProcessingParameterNumber.Double + type=QgsProcessingParameterNumber.Double, ) ) self.addParameter( QgsProcessingParameterNumber( self.MINAREA, - self.tr('Minimum area'), + self.tr("Minimum area"), minValue=0, defaultValue=0.0001, - type=QgsProcessingParameterNumber.Double + type=QgsProcessingParameterNumber.Double, ) ) self.addParameter( QgsProcessingParameterFeatureSink( - self.FLAGS, - self.tr('{0} Flags').format(self.displayName()) + self.FLAGS, self.tr("{0} Flags").format(self.displayName()) ) ) @@ -111,32 +119,31 @@ def processAlgorithm(self, parameters, context, feedback): layerHandler = LayerHandler() algRunner = AlgRunner() - inputLyrList = self.parameterAsLayerList( - parameters, self.INPUTLAYERS, context) + inputLyrList = self.parameterAsLayerList(parameters, self.INPUTLAYERS, context) if inputLyrList is None or inputLyrList == []: - raise QgsProcessingException(self.invalidSourceError( - parameters, self.INPUTLAYERS)) + raise QgsProcessingException( + self.invalidSourceError(parameters, self.INPUTLAYERS) + ) onlySelected = self.parameterAsBool(parameters, self.SELECTED, context) snap = self.parameterAsDouble(parameters, self.SNAP, context) - threshold = self.parameterAsDouble( - parameters, self.DOUGLASPARAMETER, context) + threshold = self.parameterAsDouble(parameters, self.DOUGLASPARAMETER, context) minArea = self.parameterAsDouble(parameters, self.MINAREA, context) self.prepareFlagSink( - parameters, inputLyrList[0], QgsWkbTypes.MultiPolygon, context) + parameters, inputLyrList[0], QgsWkbTypes.MultiPolygon, context + ) multiStepFeedback = QgsProcessingMultiStepFeedback(3, feedback) multiStepFeedback.setCurrentStep(0) - multiStepFeedback.pushInfo(self.tr('Building unified layer...')) + multiStepFeedback.pushInfo(self.tr("Building unified layer...")) coverage = layerHandler.createAndPopulateUnifiedVectorLayer( inputLyrList, geomType=QgsWkbTypes.MultiPolygon, onlySelected=onlySelected, - feedback=multiStepFeedback + feedback=multiStepFeedback, ) multiStepFeedback.setCurrentStep(1) - multiStepFeedback.pushInfo( - self.tr('Running clean on unified layer...')) + multiStepFeedback.pushInfo(self.tr("Running clean on unified layer...")) simplifiedCoverage, error = algRunner.runDouglasSimplification( coverage, threshold, @@ -144,15 +151,17 @@ def processAlgorithm(self, parameters, context, feedback): returnError=True, snap=snap, minArea=minArea, - feedback=multiStepFeedback) + feedback=multiStepFeedback, + ) multiStepFeedback.setCurrentStep(2) - multiStepFeedback.pushInfo(self.tr('Updating original layer...')) + multiStepFeedback.pushInfo(self.tr("Updating original layer...")) layerHandler.updateOriginalLayersFromUnifiedLayer( inputLyrList, simplifiedCoverage, feedback=multiStepFeedback, - onlySelected=onlySelected) + onlySelected=onlySelected, + ) self.flagCoverageIssues(simplifiedCoverage, error, feedback) @@ -177,22 +186,24 @@ def flagCoverageIssues(self, cleanedCoverage, error, feedback): if len(featList) > 1: txtList = [] for i in featList: - txtList += ['{0} (id={1})'.format(i['layer'], i['featid'])] - txt = ', '.join(txtList) - self.flagFeature(featList[0].geometry(), self.tr( - 'Features from {0} overlap').format(txt)) + txtList += ["{0} (id={1})".format(i["layer"], i["featid"])] + txt = ", ".join(txtList) + self.flagFeature( + featList[0].geometry(), + self.tr("Features from {0} overlap").format(txt), + ) elif len(featList) == 1: attrList = featList[0].attributes() - if attrList == len(attrList)*[None]: + if attrList == len(attrList) * [None]: self.flagFeature( - featList[0].geometry(), self.tr('Gap in coverage.')) + featList[0].geometry(), self.tr("Gap in coverage.") + ) if error: for feat in error.getFeatures(): if feedback.isCanceled(): break - self.flagFeature(feat.geometry(), self.tr( - 'Clean error on coverage.')) + self.flagFeature(feat.geometry(), self.tr("Clean error on coverage.")) def name(self): """ @@ -202,21 +213,21 @@ def name(self): lowercase alphanumeric characters only and no spaces or other formatting characters. """ - return 'topologicaldouglaspeuckerareasimplification' + return "topologicaldouglaspeuckerareasimplification" def displayName(self): """ Returns the translated algorithm name, which should be used for any user-visible display of the algorithm name. """ - return self.tr('Topological Douglas Peucker Area Simplification') + return self.tr("Topological Douglas Peucker Area Simplification") def group(self): """ Returns the name of the group this algorithm belongs to. This string should be localised. """ - return self.tr('Quality Assurance Tools (Topological Processes)') + return self.tr("Quality Assurance Tools (Topological Processes)") def groupId(self): """ @@ -226,10 +237,12 @@ def groupId(self): contain lowercase alphanumeric characters only and no spaces or other formatting characters. """ - return 'DSGTools: Quality Assurance Tools (Topological Processes)' + return "DSGTools: Quality Assurance Tools (Topological Processes)" def tr(self, string): - return QCoreApplication.translate('TopologicalDouglasPeuckerAreaSimplificationAlgorithm', string) + return QCoreApplication.translate( + "TopologicalDouglasPeuckerAreaSimplificationAlgorithm", string + ) def createInstance(self): return TopologicalDouglasPeuckerAreaSimplificationAlgorithm() diff --git a/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/topologicalDouglasLineSimplificationAlgorithm.py b/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/topologicalDouglasLineSimplificationAlgorithm.py index fade94106..5a719c4ec 100644 --- a/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/topologicalDouglasLineSimplificationAlgorithm.py +++ b/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/topologicalDouglasLineSimplificationAlgorithm.py @@ -24,18 +24,27 @@ import processing from DsgTools.core.GeometricTools.layerHandler import LayerHandler -from qgis.core import (QgsDataSourceUri, QgsFeature, QgsFeatureSink, - QgsGeometry, QgsProcessing, QgsProcessingAlgorithm, - QgsProcessingMultiStepFeedback, - QgsProcessingOutputVectorLayer, - QgsProcessingParameterBoolean, - QgsProcessingParameterEnum, - QgsProcessingParameterFeatureSink, - QgsProcessingParameterFeatureSource, - QgsProcessingParameterMultipleLayers, - QgsProcessingParameterNumber, - QgsProcessingParameterVectorLayer, QgsProcessingUtils, - QgsProject, QgsSpatialIndex, QgsWkbTypes) +from qgis.core import ( + QgsDataSourceUri, + QgsFeature, + QgsFeatureSink, + QgsGeometry, + QgsProcessing, + QgsProcessingAlgorithm, + QgsProcessingMultiStepFeedback, + QgsProcessingOutputVectorLayer, + QgsProcessingParameterBoolean, + QgsProcessingParameterEnum, + QgsProcessingParameterFeatureSink, + QgsProcessingParameterFeatureSource, + QgsProcessingParameterMultipleLayers, + QgsProcessingParameterNumber, + QgsProcessingParameterVectorLayer, + QgsProcessingUtils, + QgsProject, + QgsSpatialIndex, + QgsWkbTypes, +) from ...algRunner import AlgRunner from .validationAlgorithm import ValidationAlgorithm @@ -46,11 +55,12 @@ class TopologicalDouglasPeuckerLineSimplificationAlgorithm(ValidationAlgorithm): Implements a Douglas Peucker algorithm to simplify lines taking into consideration the topological behavior for lines between layers. """ - INPUTLAYERS = 'INPUTLAYERS' - SELECTED = 'SELECTED' - SNAP = 'SNAP' - DOUGLASPARAMETER = 'DOUGLASPARAMETER' - FLAGS = 'FLAGS' + + INPUTLAYERS = "INPUTLAYERS" + SELECTED = "SELECTED" + SNAP = "SNAP" + DOUGLASPARAMETER = "DOUGLASPARAMETER" + FLAGS = "FLAGS" def initAlgorithm(self, config): """ @@ -59,38 +69,36 @@ def initAlgorithm(self, config): self.addParameter( QgsProcessingParameterMultipleLayers( self.INPUTLAYERS, - self.tr('Linestring Layers'), - QgsProcessing.TypeVectorLine + self.tr("Linestring Layers"), + QgsProcessing.TypeVectorLine, ) ) self.addParameter( QgsProcessingParameterBoolean( - self.SELECTED, - self.tr('Process only selected features') + self.SELECTED, self.tr("Process only selected features") ) ) self.addParameter( QgsProcessingParameterNumber( self.DOUGLASPARAMETER, - self.tr('Douglas Deucker threshold'), + self.tr("Douglas Deucker threshold"), minValue=0, defaultValue=2, - type=QgsProcessingParameterNumber.Double + type=QgsProcessingParameterNumber.Double, ) ) self.addParameter( QgsProcessingParameterNumber( self.SNAP, - self.tr('Snap radius'), + self.tr("Snap radius"), minValue=0, defaultValue=1, - type=QgsProcessingParameterNumber.Double + type=QgsProcessingParameterNumber.Double, ) ) self.addParameter( QgsProcessingParameterFeatureSink( - self.FLAGS, - self.tr('{0} Flags').format(self.displayName()) + self.FLAGS, self.tr("{0} Flags").format(self.displayName()) ) ) @@ -101,44 +109,48 @@ def processAlgorithm(self, parameters, context, feedback): layerHandler = LayerHandler() algRunner = AlgRunner() - inputLyrList = self.parameterAsLayerList(parameters, - self.INPUTLAYERS, context) + inputLyrList = self.parameterAsLayerList(parameters, self.INPUTLAYERS, context) if inputLyrList is None or inputLyrList == []: - raise QgsProcessingException(self.invalidSourceError( - parameters, self.INPUTLAYERS)) + raise QgsProcessingException( + self.invalidSourceError(parameters, self.INPUTLAYERS) + ) onlySelected = self.parameterAsBool(parameters, self.SELECTED, context) snap = self.parameterAsDouble(parameters, self.SNAP, context) - threshold = self.parameterAsDouble(parameters, - self.DOUGLASPARAMETER, context) - self.prepareFlagSink(parameters, inputLyrList[0], - QgsWkbTypes.MultiLineString, context) + threshold = self.parameterAsDouble(parameters, self.DOUGLASPARAMETER, context) + self.prepareFlagSink( + parameters, inputLyrList[0], QgsWkbTypes.MultiLineString, context + ) multiStepFeedback = QgsProcessingMultiStepFeedback(3, feedback) multiStepFeedback.setCurrentStep(0) - multiStepFeedback.pushInfo(self.tr('Building unified layer...')) + multiStepFeedback.pushInfo(self.tr("Building unified layer...")) coverage = layerHandler.createAndPopulateUnifiedVectorLayer( - inputLyrList, geomType=QgsWkbTypes.MultiLineString, - onlySelected=onlySelected, feedback=multiStepFeedback) + inputLyrList, + geomType=QgsWkbTypes.MultiLineString, + onlySelected=onlySelected, + feedback=multiStepFeedback, + ) multiStepFeedback.setCurrentStep(1) - multiStepFeedback.pushInfo( - self.tr('Running clean on unified layer...')) + multiStepFeedback.pushInfo(self.tr("Running clean on unified layer...")) simplifiedCoverage, error = algRunner.runDouglasSimplification( coverage, threshold, context, returnError=True, snap=snap, - feedback=multiStepFeedback) + feedback=multiStepFeedback, + ) multiStepFeedback.setCurrentStep(2) - multiStepFeedback.pushInfo(self.tr('Updating original layer...')) + multiStepFeedback.pushInfo(self.tr("Updating original layer...")) layerHandler.updateOriginalLayersFromUnifiedLayer( inputLyrList, simplifiedCoverage, feedback=multiStepFeedback, - onlySelected=onlySelected) + onlySelected=onlySelected, + ) self.flagCoverageIssues(simplifiedCoverage, error, feedback) @@ -163,22 +175,24 @@ def flagCoverageIssues(self, cleanedCoverage, error, feedback): if len(featList) > 1: txtList = [] for i in featList: - txtList += ['{0} (id={1})'.format(i['layer'], i['featid'])] - txt = ', '.join(txtList) - self.flagFeature(featList[0].geometry(), self.tr( - 'Features from {0} overlap').format(txt)) + txtList += ["{0} (id={1})".format(i["layer"], i["featid"])] + txt = ", ".join(txtList) + self.flagFeature( + featList[0].geometry(), + self.tr("Features from {0} overlap").format(txt), + ) elif len(featList) == 1: attrList = featList[0].attributes() - if attrList == len(attrList)*[None]: - self.flagFeature(featList[0].geometry(), self.tr( - 'Gap in coverage.')) + if attrList == len(attrList) * [None]: + self.flagFeature( + featList[0].geometry(), self.tr("Gap in coverage.") + ) if error: for feat in error.getFeatures(): if feedback.isCanceled(): break - self.flagFeature(feat.geometry(), self.tr( - 'Clean error on coverage.')) + self.flagFeature(feat.geometry(), self.tr("Clean error on coverage.")) def name(self): """ @@ -188,21 +202,21 @@ def name(self): lowercase alphanumeric characters only and no spaces or other formatting characters. """ - return 'topologicaldouglaspeuckerlinesimplification' + return "topologicaldouglaspeuckerlinesimplification" def displayName(self): """ Returns the translated algorithm name, which should be used for any user-visible display of the algorithm name. """ - return self.tr('Topological Douglas Peucker Line Simplification') + return self.tr("Topological Douglas Peucker Line Simplification") def group(self): """ Returns the name of the group this algorithm belongs to. This string should be localised. """ - return self.tr('Quality Assurance Tools (Topological Processes)') + return self.tr("Quality Assurance Tools (Topological Processes)") def groupId(self): """ @@ -212,14 +226,15 @@ def groupId(self): contain lowercase alphanumeric characters only and no spaces or other formatting characters. """ - return 'DSGTools: Quality Assurance Tools (Topological Processes)' + return "DSGTools: Quality Assurance Tools (Topological Processes)" def tr(self, string): """ Returns a translatable string with the self.tr() function. """ return QCoreApplication.translate( - 'TopologicalDouglasPeuckerLineSimplificationAlgorithm', string) + "TopologicalDouglasPeuckerLineSimplificationAlgorithm", string + ) def createInstance(self): """ diff --git a/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/topologicalLineConnectivityAdjustmentAlgorithm.py b/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/topologicalLineConnectivityAdjustmentAlgorithm.py index 31e348fd5..87b8d39c5 100644 --- a/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/topologicalLineConnectivityAdjustmentAlgorithm.py +++ b/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/topologicalLineConnectivityAdjustmentAlgorithm.py @@ -24,29 +24,37 @@ import processing from DsgTools.core.GeometricTools.layerHandler import LayerHandler -from qgis.core import (QgsDataSourceUri, QgsFeature, QgsFeatureSink, - QgsGeometry, QgsProcessing, QgsProcessingAlgorithm, - QgsProcessingMultiStepFeedback, - QgsProcessingOutputVectorLayer, - QgsProcessingParameterBoolean, - QgsProcessingParameterDistance, - QgsProcessingParameterEnum, - QgsProcessingParameterFeatureSink, - QgsProcessingParameterFeatureSource, - QgsProcessingParameterField, - QgsProcessingParameterMultipleLayers, - QgsProcessingParameterNumber, - QgsProcessingParameterVectorLayer, QgsProcessingUtils, - QgsSpatialIndex, QgsWkbTypes) +from qgis.core import ( + QgsDataSourceUri, + QgsFeature, + QgsFeatureSink, + QgsGeometry, + QgsProcessing, + QgsProcessingAlgorithm, + QgsProcessingMultiStepFeedback, + QgsProcessingOutputVectorLayer, + QgsProcessingParameterBoolean, + QgsProcessingParameterDistance, + QgsProcessingParameterEnum, + QgsProcessingParameterFeatureSink, + QgsProcessingParameterFeatureSource, + QgsProcessingParameterField, + QgsProcessingParameterMultipleLayers, + QgsProcessingParameterNumber, + QgsProcessingParameterVectorLayer, + QgsProcessingUtils, + QgsSpatialIndex, + QgsWkbTypes, +) from ...algRunner import AlgRunner from .validationAlgorithm import ValidationAlgorithm class TopologicalLineConnectivityAdjustment(ValidationAlgorithm): - INPUTLAYERS = 'INPUTLAYERS' - SELECTED = 'SELECTED' - TOLERANCE = 'TOLERANCE' + INPUTLAYERS = "INPUTLAYERS" + SELECTED = "SELECTED" + TOLERANCE = "TOLERANCE" def initAlgorithm(self, config): """ @@ -55,23 +63,22 @@ def initAlgorithm(self, config): self.addParameter( QgsProcessingParameterMultipleLayers( self.INPUTLAYERS, - self.tr('Linestring Layers'), - QgsProcessing.TypeVectorLine + self.tr("Linestring Layers"), + QgsProcessing.TypeVectorLine, ) ) self.addParameter( QgsProcessingParameterBoolean( - self.SELECTED, - self.tr('Process only selected features') + self.SELECTED, self.tr("Process only selected features") ) ) self.addParameter( QgsProcessingParameterDistance( self.TOLERANCE, - self.tr('Snap radius'), + self.tr("Snap radius"), parentParameterName=self.INPUTLAYERS, minValue=0, - defaultValue=1.0 + defaultValue=1.0, ) ) @@ -84,45 +91,59 @@ def processAlgorithm(self, parameters, context, feedback): inputLyrList = self.parameterAsLayerList(parameters, self.INPUTLAYERS, context) if inputLyrList is None or inputLyrList == []: raise QgsProcessingException( - self.invalidSourceError( - parameters, - self.INPUTLAYERS - ) - ) + self.invalidSourceError(parameters, self.INPUTLAYERS) + ) onlySelected = self.parameterAsBool(parameters, self.SELECTED, context) tol = self.parameterAsDouble(parameters, self.TOLERANCE, context) multiStepFeedback = QgsProcessingMultiStepFeedback(5, feedback) multiStepFeedback.setCurrentStep(0) - multiStepFeedback.pushInfo(self.tr('Building unified layer...')) + multiStepFeedback.pushInfo(self.tr("Building unified layer...")) coverage = layerHandler.createAndPopulateUnifiedVectorLayer( inputLyrList, geomType=QgsWkbTypes.MultiPolygon, onlySelected=onlySelected, - feedback=multiStepFeedback - ) - + feedback=multiStepFeedback, + ) multiStepFeedback.setCurrentStep(1) - multiStepFeedback.pushInfo(self.tr('Identifying dangles on {layer}...').format(layer=coverage.name())) - dangleLyr = algRunner.runIdentifyDangles(coverage, tol, context, feedback=multiStepFeedback, onlySelected=onlySelected) + multiStepFeedback.pushInfo( + self.tr("Identifying dangles on {layer}...").format(layer=coverage.name()) + ) + dangleLyr = algRunner.runIdentifyDangles( + coverage, + tol, + context, + feedback=multiStepFeedback, + onlySelected=onlySelected, + ) multiStepFeedback.setCurrentStep(2) layerHandler.filterDangles(dangleLyr, tol, feedback=multiStepFeedback) multiStepFeedback.setCurrentStep(3) - multiStepFeedback.pushInfo(self.tr('Snapping layer {layer} to dangles...').format(layer=coverage.name())) - algRunner.runSnapLayerOnLayer(coverage, dangleLyr, tol, context, feedback=multiStepFeedback, onlySelected=onlySelected, behavior=0) + multiStepFeedback.pushInfo( + self.tr("Snapping layer {layer} to dangles...").format( + layer=coverage.name() + ) + ) + algRunner.runSnapLayerOnLayer( + coverage, + dangleLyr, + tol, + context, + feedback=multiStepFeedback, + onlySelected=onlySelected, + behavior=0, + ) multiStepFeedback.setCurrentStep(4) - multiStepFeedback.pushInfo(self.tr('Updating original layers...')) + multiStepFeedback.pushInfo(self.tr("Updating original layers...")) layerHandler.updateOriginalLayersFromUnifiedLayer( - inputLyrList, - coverage, - feedback=multiStepFeedback - ) + inputLyrList, coverage, feedback=multiStepFeedback + ) - return {self.INPUTLAYERS : inputLyrList} + return {self.INPUTLAYERS: inputLyrList} def name(self): """ @@ -132,21 +153,21 @@ def name(self): lowercase alphanumeric characters only and no spaces or other formatting characters. """ - return 'topologicallineconnectivityadjustment' + return "topologicallineconnectivityadjustment" def displayName(self): """ Returns the translated algorithm name, which should be used for any user-visible display of the algorithm name. """ - return self.tr('Topological adjustment of the connectivity of lines') + return self.tr("Topological adjustment of the connectivity of lines") def group(self): """ Returns the name of the group this algorithm belongs to. This string should be localised. """ - return self.tr('Quality Assurance Tools (Network Processes)') + return self.tr("Quality Assurance Tools (Network Processes)") def groupId(self): """ @@ -156,10 +177,12 @@ def groupId(self): contain lowercase alphanumeric characters only and no spaces or other formatting characters. """ - return 'DSGTools: Quality Assurance Tools (Network Processes)' + return "DSGTools: Quality Assurance Tools (Network Processes)" def tr(self, string): - return QCoreApplication.translate('TopologicalLineConnectivityAdjustment', string) + return QCoreApplication.translate( + "TopologicalLineConnectivityAdjustment", string + ) def createInstance(self): return TopologicalLineConnectivityAdjustment() diff --git a/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/unbuildPolygonsAlgorithm.py b/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/unbuildPolygonsAlgorithm.py index 047134bc3..755d42615 100644 --- a/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/unbuildPolygonsAlgorithm.py +++ b/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/unbuildPolygonsAlgorithm.py @@ -23,30 +23,38 @@ from PyQt5.QtCore import QCoreApplication from DsgTools.core.GeometricTools.layerHandler import LayerHandler -from qgis.core import (QgsDataSourceUri, QgsFeature, QgsFeatureSink, - QgsProcessing, QgsProcessingAlgorithm, - QgsProcessingException, QgsProcessingMultiStepFeedback, - QgsProcessingOutputVectorLayer, - QgsProcessingParameterBoolean, - QgsProcessingParameterDistance, - QgsProcessingParameterFeatureSink, - QgsProcessingParameterFeatureSource, - QgsProcessingParameterField, - QgsProcessingParameterMultipleLayers, - QgsProcessingParameterVectorLayer, QgsWkbTypes, QgsFields) +from qgis.core import ( + QgsDataSourceUri, + QgsFeature, + QgsFeatureSink, + QgsProcessing, + QgsProcessingAlgorithm, + QgsProcessingException, + QgsProcessingMultiStepFeedback, + QgsProcessingOutputVectorLayer, + QgsProcessingParameterBoolean, + QgsProcessingParameterDistance, + QgsProcessingParameterFeatureSink, + QgsProcessingParameterFeatureSource, + QgsProcessingParameterField, + QgsProcessingParameterMultipleLayers, + QgsProcessingParameterVectorLayer, + QgsWkbTypes, + QgsFields, +) from ...algRunner import AlgRunner from .validationAlgorithm import ValidationAlgorithm class UnbuildPolygonsAlgorithm(ValidationAlgorithm): - INPUT_POLYGONS = 'INPUT_POLYGONS' - SELECTED = 'SELECTED' - CONSTRAINT_LINE_LAYERS = 'CONSTRAINT_LINE_LAYERS' - CONSTRAINT_POLYGON_LAYERS = 'CONSTRAINT_POLYGON_LAYERS' - GEOGRAPHIC_BOUNDARY = 'GEOGRAPHIC_BOUNDARY' - OUTPUT_CENTER_POINTS = 'OUTPUT_CENTER_POINTS' - OUTPUT_BOUNDARIES = 'OUTPUT_BOUNDARIES' + INPUT_POLYGONS = "INPUT_POLYGONS" + SELECTED = "SELECTED" + CONSTRAINT_LINE_LAYERS = "CONSTRAINT_LINE_LAYERS" + CONSTRAINT_POLYGON_LAYERS = "CONSTRAINT_POLYGON_LAYERS" + GEOGRAPHIC_BOUNDARY = "GEOGRAPHIC_BOUNDARY" + OUTPUT_CENTER_POINTS = "OUTPUT_CENTER_POINTS" + OUTPUT_BOUNDARIES = "OUTPUT_BOUNDARIES" def initAlgorithm(self, config): """ @@ -55,50 +63,47 @@ def initAlgorithm(self, config): self.addParameter( QgsProcessingParameterMultipleLayers( self.INPUT_POLYGONS, - self.tr('Polygon Layers'), - QgsProcessing.TypeVectorPolygon + self.tr("Polygon Layers"), + QgsProcessing.TypeVectorPolygon, ) ) self.addParameter( QgsProcessingParameterBoolean( - self.SELECTED, - self.tr('Process only selected features') + self.SELECTED, self.tr("Process only selected features") ) ) self.addParameter( QgsProcessingParameterMultipleLayers( self.CONSTRAINT_LINE_LAYERS, - self.tr('Line Constraint Layers'), + self.tr("Line Constraint Layers"), QgsProcessing.TypeVectorLine, - optional=True + optional=True, ) ) self.addParameter( QgsProcessingParameterMultipleLayers( self.CONSTRAINT_POLYGON_LAYERS, - self.tr('Polygon Constraint Layers'), + self.tr("Polygon Constraint Layers"), QgsProcessing.TypeVectorPolygon, - optional=True + optional=True, ) ) self.addParameter( QgsProcessingParameterVectorLayer( self.GEOGRAPHIC_BOUNDARY, - self.tr('Geographic Boundary'), + self.tr("Geographic Boundary"), [QgsProcessing.TypeVectorPolygon], - optional=True + optional=True, ) ) self.addParameter( QgsProcessingParameterFeatureSink( - self.OUTPUT_CENTER_POINTS, - self.tr('Output Center Points') + self.OUTPUT_CENTER_POINTS, self.tr("Output Center Points") ) ) self.addParameter( QgsProcessingParameterFeatureSink( - self.OUTPUT_BOUNDARIES, - self.tr('Output Boundaries') + self.OUTPUT_BOUNDARIES, self.tr("Output Boundaries") ) ) @@ -109,33 +114,21 @@ def processAlgorithm(self, parameters, context, feedback): layerHandler = LayerHandler() algRunner = AlgRunner() inputPolygonLyrList = self.parameterAsLayerList( - parameters, - self.INPUT_POLYGONS, - context + parameters, self.INPUT_POLYGONS, context ) constraintLineLyrList = self.parameterAsLayerList( - parameters, - self.CONSTRAINT_LINE_LAYERS, - context + parameters, self.CONSTRAINT_LINE_LAYERS, context ) constraintPolygonLyrList = self.parameterAsLayerList( - parameters, - self.CONSTRAINT_POLYGON_LAYERS, - context + parameters, self.CONSTRAINT_POLYGON_LAYERS, context ) if set(constraintPolygonLyrList).intersection(set(inputPolygonLyrList)): raise QgsProcessingException( - self.tr('Input polygon layers must not be in constraint polygon list.') + self.tr("Input polygon layers must not be in constraint polygon list.") ) - onlySelected = self.parameterAsBool( - parameters, - self.SELECTED, - context - ) + onlySelected = self.parameterAsBool(parameters, self.SELECTED, context) boundaryLyr = self.parameterAsLayer( - parameters, - self.GEOGRAPHIC_BOUNDARY, - context + parameters, self.GEOGRAPHIC_BOUNDARY, context ) # Compute the number of steps to display within the progress bar and # get features from source @@ -145,38 +138,30 @@ def processAlgorithm(self, parameters, context, feedback): # 3- Compute boundaries multiStepFeedback = QgsProcessingMultiStepFeedback(3, feedback) multiStepFeedback.setCurrentStep(0) - multiStepFeedback.pushInfo( - self.tr('Building single polygon layer') - ) + multiStepFeedback.pushInfo(self.tr("Building single polygon layer")) singlePolygonLayer = layerHandler.getMergedLayer( inputPolygonLyrList, onlySelected=onlySelected, feedback=multiStepFeedback, context=context, - algRunner=algRunner + algRunner=algRunner, ) multiStepFeedback.setCurrentStep(1) - ( - output_center_point_sink, - output_center_point_sink_id - ) = self.parameterAsSink( + (output_center_point_sink, output_center_point_sink_id) = self.parameterAsSink( parameters, self.OUTPUT_CENTER_POINTS, context, singlePolygonLayer.fields(), QgsWkbTypes.Point, - singlePolygonLayer.sourceCrs() + singlePolygonLayer.sourceCrs(), ) - ( - output_boundaries_sink, - output_boundaries_sink_id - ) = self.parameterAsSink( + (output_boundaries_sink, output_boundaries_sink_id) = self.parameterAsSink( parameters, self.OUTPUT_BOUNDARIES, context, QgsFields(), QgsWkbTypes.LineString, - singlePolygonLayer.sourceCrs() + singlePolygonLayer.sourceCrs(), ) layerHandler.getCentroidsAndBoundariesFromPolygons( singlePolygonLayer, @@ -186,12 +171,12 @@ def processAlgorithm(self, parameters, context, feedback): constraintPolygonLyrList=constraintPolygonLyrList, context=context, feedback=multiStepFeedback, - algRunner=algRunner + algRunner=algRunner, ) return { - self.OUTPUT_CENTER_POINTS : output_center_point_sink_id, - self.OUTPUT_BOUNDARIES : output_boundaries_sink_id + self.OUTPUT_CENTER_POINTS: output_center_point_sink_id, + self.OUTPUT_BOUNDARIES: output_boundaries_sink_id, } def name(self): @@ -202,21 +187,21 @@ def name(self): lowercase alphanumeric characters only and no spaces or other formatting characters. """ - return 'unbuildpolygonsalgorithm' + return "unbuildpolygonsalgorithm" def displayName(self): """ Returns the translated algorithm name, which should be used for any user-visible display of the algorithm name. """ - return self.tr('Unbuild Polygons') + return self.tr("Unbuild Polygons") def group(self): """ Returns the name of the group this algorithm belongs to. This string should be localised. """ - return self.tr('Quality Assurance Tools (Manipulation Processes)') + return self.tr("Quality Assurance Tools (Manipulation Processes)") def groupId(self): """ @@ -226,10 +211,10 @@ def groupId(self): contain lowercase alphanumeric characters only and no spaces or other formatting characters. """ - return 'DSGTools: Quality Assurance Tools (Manipulation Processes)' + return "DSGTools: Quality Assurance Tools (Manipulation Processes)" def tr(self, string): - return QCoreApplication.translate('UnbuildPolygonsAlgorithm', string) + return QCoreApplication.translate("UnbuildPolygonsAlgorithm", string) def createInstance(self): return UnbuildPolygonsAlgorithm() diff --git a/DsgTools/core/DSGToolsProcessingAlgs/Algs/OtherAlgs/unicodeFilterAlgorithm.py b/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/unicodeFilterAlgorithm.py similarity index 51% rename from DsgTools/core/DSGToolsProcessingAlgs/Algs/OtherAlgs/unicodeFilterAlgorithm.py rename to DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/unicodeFilterAlgorithm.py index c9b1765c3..f73cd09be 100644 --- a/DsgTools/core/DSGToolsProcessingAlgs/Algs/OtherAlgs/unicodeFilterAlgorithm.py +++ b/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/unicodeFilterAlgorithm.py @@ -1,65 +1,64 @@ # -*- coding: utf-8 -*- -from qgis.PyQt.QtCore import (QCoreApplication, QVariant) -from qgis.core import (QgsProcessing, - QgsFeatureSink, - QgsProcessingAlgorithm, - QgsProcessingParameterFeatureSink, - QgsCoordinateReferenceSystem, - QgsProcessingParameterMultipleLayers, - QgsFeatureRequest, - QgsFeature, - QgsProcessingParameterFile, - QgsProcessingParameterVectorLayer, - QgsField, - QgsFields, - QgsWkbTypes - ) +from qgis.PyQt.QtCore import QCoreApplication, QVariant +from qgis.core import ( + QgsProcessing, + QgsFeatureSink, + QgsProcessingAlgorithm, + QgsProcessingParameterFeatureSink, + QgsCoordinateReferenceSystem, + QgsProcessingParameterMultipleLayers, + QgsFeatureRequest, + QgsFeature, + QgsProcessingParameterFile, + QgsProcessingParameterVectorLayer, + QgsField, + QgsFields, + QgsWkbTypes, +) from qgis import processing from qgis.utils import iface import csv import concurrent.futures import os -class UnicodeFilterAlgorithm(QgsProcessingAlgorithm): - INPUT_LAYERS = 'INPUT_LAYER_LIST' - OUTPUT1 = 'OUTPUT1' - OUTPUT2 = 'OUTPUT2' - OUTPUT3 = 'OUTPUT3' +class UnicodeFilterAlgorithm(QgsProcessingAlgorithm): + + INPUT_LAYERS = "INPUT_LAYER_LIST" + OUTPUT1 = "OUTPUT1" + OUTPUT2 = "OUTPUT2" + OUTPUT3 = "OUTPUT3" def initAlgorithm(self, config=None): self.addParameter( QgsProcessingParameterMultipleLayers( - 'INPUT_LAYER_LIST', - self.tr('Selecionar camadas'), - QgsProcessing.TypeVectorAnyGeometry + "INPUT_LAYER_LIST", + self.tr("Selecionar camadas"), + QgsProcessing.TypeVectorAnyGeometry, ) ) self.addParameter( QgsProcessingParameterFeatureSink( - self.OUTPUT1, - self.tr('Flag - unicode não permitido (ponto)') + self.OUTPUT1, self.tr("Flag - unicode não permitido (ponto)") ) - ) + ) self.addParameter( QgsProcessingParameterFeatureSink( - self.OUTPUT2, - self.tr('Flag - unicode não permitido (linha)') + self.OUTPUT2, self.tr("Flag - unicode não permitido (linha)") ) - ) + ) self.addParameter( QgsProcessingParameterFeatureSink( - self.OUTPUT3, - self.tr('Flag - unicode não permitido (área)') + self.OUTPUT3, self.tr("Flag - unicode não permitido (área)") ) - ) + ) - def processAlgorithm(self, parameters, context, feedback): - feedback.setProgressText('Verificando unicodes...') - layerList = self.parameterAsLayerList(parameters,'INPUT_LAYER_LIST', context) + def processAlgorithm(self, parameters, context, feedback): + feedback.setProgressText("Verificando unicodes...") + layerList = self.parameterAsLayerList(parameters, "INPUT_LAYER_LIST", context) whitelist = self.getWhitelist(self.getCsvFilePath()) listSize = len(layerList) - progressStep = 100/listSize if listSize else 0 + progressStep = 100 / listSize if listSize else 0 step = 0 flags = {} @@ -68,7 +67,7 @@ def checkUnicode(layer): for feature in layer.getFeatures(): for attribute in feature.attributes(): for char in attribute: - if hex(ord(char))[2:].lower().rjust(4, '0') in whitelist: + if hex(ord(char))[2:].lower().rjust(4, "0") in whitelist: continue featuresNotApproved.append(feature) break @@ -80,21 +79,23 @@ def checkUnicode(layer): break flags[layer.geometryType()] += featuresNotApproved - pool = concurrent.futures.ThreadPoolExecutor(os.cpu_count()-1) + pool = concurrent.futures.ThreadPoolExecutor(os.cpu_count() - 1) futures = set() for step, layer in enumerate(layerList): - if not(layer.geometryType() in flags): + if not (layer.geometryType() in flags): flags[layer.geometryType()] = [] futures.add(pool.submit(checkUnicode, layer)) - concurrent.futures.wait(futures, timeout=None, return_when=concurrent.futures.ALL_COMPLETED) - - output = {self.OUTPUT1: '', self.OUTPUT2: '', self.OUTPUT3: ''} + concurrent.futures.wait( + futures, timeout=None, return_when=concurrent.futures.ALL_COMPLETED + ) + + output = {self.OUTPUT1: "", self.OUTPUT2: "", self.OUTPUT3: ""} for geometryType in flags: features = flags[geometryType] if len(features) == 0: continue if geometryType == QgsWkbTypes.PointGeometry: - out = self.OUTPUT1 + out = self.OUTPUT1 wkbType = QgsWkbTypes.MultiPoint elif geometryType == QgsWkbTypes.LineGeometry: out = self.OUTPUT2 @@ -104,67 +105,72 @@ def checkUnicode(layer): wkbType = QgsWkbTypes.MultiPolygon flagLayer = self.outLayer(parameters, context, out, features, wkbType) output[out] = flagLayer - + return output - + def outLayer(self, parameters, context, output, features, geomType): CRSstr = iface.mapCanvas().mapSettings().destinationCrs().authid() CRS = QgsCoordinateReferenceSystem(CRSstr) newField = QgsFields() - newField.append(QgsField('id', QVariant.Int)) - #newField.append(QgsField('nome_da_camada', QVariant.String)) + newField.append(QgsField("id", QVariant.Int)) + # newField.append(QgsField('nome_da_camada', QVariant.String)) (sink, newLayer) = self.parameterAsSink( - parameters, - output, - context, - newField, - geomType, - CRS + parameters, output, context, newField, geomType, CRS ) for idx, feature in enumerate(features): onlyfeature = feature[0] newFeat = QgsFeature() newFeat.setGeometry(feature.geometry()) newFeat.setFields(newField) - newFeat['id'] = idx + newFeat["id"] = idx sink.addFeature(newFeat, QgsFeatureSink.FastInsert) return newLayer def getWhitelist(self, csvFilePath): whitelist = [] - with open(csvFilePath, newline = '') as csvFile: - table = csv.reader(csvFile, delimiter = ',', quotechar='"') + with open(csvFilePath, newline="") as csvFile: + table = csv.reader(csvFile, delimiter=",", quotechar='"') for row in table: whitelist.append(row[0].lower()) return whitelist def getCsvFilePath(self): return os.path.join( - os.path.abspath(os.path.join( - os.path.dirname(__file__) - )), - 'data', - 'unicode-whitelist.csv' + os.path.abspath(os.path.join(os.path.dirname(__file__))), + "data", + "unicode-whitelist.csv", ) - + def tr(self, string): - return QCoreApplication.translate('Processing', string) + return QCoreApplication.translate("Processing", string) def createInstance(self): return UnicodeFilterAlgorithm() def name(self): - return 'unicodefilter' + return "unicodefilter" def displayName(self): - return self.tr('Identifica Feições que contém unicode não permitido') + return self.tr("Identify features with invalid unicode") def group(self): - return self.tr('Other Algorithms') + """ + Returns the name of the group this algorithm belongs to. This string + should be localised. + """ + return self.tr("Quality Assurance Tools (Identification Processes)") def groupId(self): - return 'DSGTools: Other Algorithms' + """ + Returns the unique ID of the group this algorithm belongs to. This + string should be fixed for the algorithm, and must not be localised. + The group id should be unique within each provider. Group id should + contain lowercase alphanumeric characters only and no spaces or other + formatting characters. + """ + return "DSGTools: Quality Assurance Tools (Identification Processes)" def shortHelpString(self): - return self.tr("O algoritmo identifica se existe algum atributo com um unicode que não está na whitelist") - + return self.tr( + "O algoritmo identifica se existe algum atributo com um unicode que não está na whitelist" + ) diff --git a/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/validationAlgorithm.py b/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/validationAlgorithm.py index b8aeac6e4..ddbb326f9 100644 --- a/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/validationAlgorithm.py +++ b/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/validationAlgorithm.py @@ -24,24 +24,32 @@ from qgis.core import QgsGeometry, QgsFeature, QgsField, QgsProcessingAlgorithm -from qgis.core import (QgsFeatureSink, - QgsProcessingAlgorithm, - QgsFeature, - QgsFields, - QgsProcessingException, - QgsProject) +from qgis.core import ( + QgsFeatureSink, + QgsProcessingAlgorithm, + QgsFeature, + QgsFields, + QgsProcessingException, + QgsProject, +) + class ValidationAlgorithm(QgsProcessingAlgorithm): """ Processing algorithm with handy stuff for other algs. """ - def getIteratorAndFeatureCount(self, lyr, onlySelected = False): + + def getIteratorAndFeatureCount(self, lyr, onlySelected=False): """ Gets the iterator and feature count from lyr. """ try: if onlySelected: - total = 100.0 / lyr.selectedFeatureCount() if lyr.selectedFeatureCount() else 0 + total = ( + 100.0 / lyr.selectedFeatureCount() + if lyr.selectedFeatureCount() + else 0 + ) iterator = lyr.getSelectedFeatures() else: total = 100.0 / lyr.featureCount() if lyr.featureCount() else 0 @@ -50,43 +58,45 @@ def getIteratorAndFeatureCount(self, lyr, onlySelected = False): except: return [], 0 - def prepareFlagSink(self, parameters, source, wkbType, context): + def prepareFlagSink(self, parameters, source, wkbType, context, addFeatId=False): (self.flagSink, self.flag_id) = self.prepareAndReturnFlagSink( - parameters, - source, - wkbType, - context, - self.FLAGS - ) - - def prepareAndReturnFlagSink(self, parameters, source, wkbType, context, UI_FIELD): - flagFields = self.getFlagFields() + parameters, source, wkbType, context, self.FLAGS, addFeatId=addFeatId + ) + + def prepareAndReturnFlagSink( + self, parameters, source, wkbType, context, UI_FIELD, addFeatId=False + ): + flagFields = self.getFlagFields(addFeatId=addFeatId) (flagSink, flag_id) = self.parameterAsSink( parameters, UI_FIELD, context, flagFields, wkbType, - source.sourceCrs() if source is not None else QgsProject.instance().crs() + source.sourceCrs() if source is not None else QgsProject.instance().crs(), ) if flagSink is None: raise QgsProcessingException(self.invalidSinkError(parameters, UI_FIELD)) return (flagSink, flag_id) - - def getFlagFields(self): + + def getFlagFields(self, addFeatId=False): fields = QgsFields() - fields.append(QgsField('reason',QVariant.String)) + fields.append(QgsField("reason", QVariant.String)) + if addFeatId: + fields.append(QgsField("featid", QVariant.String)) return fields - - def flagFeature(self, flagGeom, flagText, fromWkb=False, sink=None): + + def flagFeature(self, flagGeom, flagText, featid=None, fromWkb=False, sink=None): """ Creates and adds to flagSink a new flag with the reason. :param flagGeom: (QgsGeometry) geometry of the flag; :param flagText: (string) Text of the flag """ flagSink = self.flagSink if sink is None else sink - newFeat = QgsFeature(self.getFlagFields()) - newFeat['reason'] = flagText + newFeat = QgsFeature(self.getFlagFields(addFeatId=featid is not None)) + newFeat["reason"] = flagText + if featid is not None: + newFeat["featid"] = featid if fromWkb: geom = QgsGeometry() geom.fromWkb(flagGeom) @@ -94,13 +104,13 @@ def flagFeature(self, flagGeom, flagText, fromWkb=False, sink=None): else: newFeat.setGeometry(flagGeom) flagSink.addFeature(newFeat, QgsFeatureSink.FastInsert) - + def getFlagsFromOutput(self, output): - if 'FLAGS' not in output: + if "FLAGS" not in output: return [] - return [i for i in output['FLAGS'].getFeatures()] - + return [i for i in output["FLAGS"].getFeatures()] + def flagFeaturesFromProcessOutput(self, output): - if 'FLAGS' in output: - for feat in output['FLAGS'].getFeatures(): - self.flagSink.addFeature(feat, QgsFeatureSink.FastInsert) \ No newline at end of file + if "FLAGS" in output: + for feat in output["FLAGS"].getFeatures(): + self.flagSink.addFeature(feat, QgsFeatureSink.FastInsert) diff --git a/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/verifyCountourStackingAlgorithm.py b/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/verifyCountourStackingAlgorithm.py index cde38a4fa..3e03accfd 100644 --- a/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/verifyCountourStackingAlgorithm.py +++ b/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/verifyCountourStackingAlgorithm.py @@ -20,20 +20,21 @@ ***************************************************************************/ """ -from qgis.PyQt.QtCore import (QCoreApplication, QVariant) -from qgis.core import (QgsProcessing, - QgsFeatureSink, - QgsProcessingAlgorithm, - QgsProcessingParameterFeatureSink, - QgsProcessingParameterVectorLayer, - QgsProcessingParameterField, - QgsProcessingParameterNumber, - QgsFeature, - QgsField, - QgsProcessingFeatureSourceDefinition, - QgsFeatureRequest, - QgsProcessingParameterBoolean - ) +from qgis.PyQt.QtCore import QCoreApplication, QVariant +from qgis.core import ( + QgsProcessing, + QgsFeatureSink, + QgsProcessingAlgorithm, + QgsProcessingParameterFeatureSink, + QgsProcessingParameterVectorLayer, + QgsProcessingParameterField, + QgsProcessingParameterNumber, + QgsFeature, + QgsField, + QgsProcessingFeatureSourceDefinition, + QgsFeatureRequest, + QgsProcessingParameterBoolean, +) from qgis import processing from .validationAlgorithm import ValidationAlgorithm @@ -41,101 +42,119 @@ class VerifyCountourStackingAlgorihtm(ValidationAlgorithm): - INPUT_CONTOUR_LINES = 'INPUT_CONTOUR_LINES' - INPUT_LEVES_FIELD = 'INPUT_LEVES_FIELD' - INPUT_IS_DEPRESSION_FIELD = 'INPUT_IS_DEPRESSION_FIELD' - INPUT_LEVEL_GAP = 'INPUT_LEVEL_GAP' - OUTPUT = 'OUTPUT' - OUTPUT_NEW_LAYER = 'OUTPUT_NEW_LAYER' - RUNNING_INSIDE_MODEL = 'RUNNING_INSIDE_MODEL' + INPUT_CONTOUR_LINES = "INPUT_CONTOUR_LINES" + INPUT_LEVES_FIELD = "INPUT_LEVES_FIELD" + INPUT_IS_DEPRESSION_FIELD = "INPUT_IS_DEPRESSION_FIELD" + INPUT_LEVEL_GAP = "INPUT_LEVEL_GAP" + OUTPUT = "OUTPUT" + OUTPUT_NEW_LAYER = "OUTPUT_NEW_LAYER" + RUNNING_INSIDE_MODEL = "RUNNING_INSIDE_MODEL" + def initAlgorithm(self, config=None): self.addParameter( QgsProcessingParameterVectorLayer( - 'INPUT_COUNTOUR_LINES', - self.tr('Select'), - types=[QgsProcessing.TypeVectorLine] + "INPUT_COUNTOUR_LINES", + self.tr("Select"), + types=[QgsProcessing.TypeVectorLine], ) ) self.addParameter( QgsProcessingParameterField( - 'INPUT_LEVES_FIELD', - self.tr('Contour levels layer'), - type=QgsProcessingParameterField.Numeric, - parentLayerParameterName='INPUT_COUNTOUR_LINES', - allowMultiple=False, - defaultValue='cota') + "INPUT_LEVES_FIELD", + self.tr("Contour levels layer"), + type=QgsProcessingParameterField.Numeric, + parentLayerParameterName="INPUT_COUNTOUR_LINES", + allowMultiple=False, + defaultValue="cota", ) + ) self.addParameter( QgsProcessingParameterField( - 'INPUT_IS_DEPRESSION_FIELD', - self.tr('Attribute information about "depression"'), - type=QgsProcessingParameterField.Numeric, - parentLayerParameterName='INPUT_COUNTOUR_LINES', - allowMultiple=False, - defaultValue='depressao') + "INPUT_IS_DEPRESSION_FIELD", + self.tr('Attribute information about "depression"'), + type=QgsProcessingParameterField.Numeric, + parentLayerParameterName="INPUT_COUNTOUR_LINES", + allowMultiple=False, + defaultValue="depressao", ) + ) self.addParameter( QgsProcessingParameterNumber( - 'INPUT_LEVEL_GAP', - self.tr('Equidistance value'), - type=QgsProcessingParameterNumber.Double, - minValue=0) + "INPUT_LEVEL_GAP", + self.tr("Equidistance value"), + type=QgsProcessingParameterNumber.Double, + minValue=0, ) + ) self.addParameter( QgsProcessingParameterBoolean( self.RUNNING_INSIDE_MODEL, - self.tr('Process is running inside model'), + self.tr("Process is running inside model"), defaultValue=False, ) ) - + self.addParameter( - QgsProcessingParameterFeatureSink( - self.OUTPUT, - self.tr('Flags') - ) - ) + QgsProcessingParameterFeatureSink(self.OUTPUT, self.tr("Flags")) + ) def processAlgorithm(self, parameters, context, feedback): - countourLayer = self.parameterAsVectorLayer( parameters,'INPUT_COUNTOUR_LINES', context ) - levelsField = self.parameterAsFields( parameters,'INPUT_LEVES_FIELD', context )[0] - levelGap = self.parameterAsDouble (parameters,'INPUT_LEVEL_GAP', context) - isDepressionField = self.parameterAsFields (parameters,'INPUT_IS_DEPRESSION_FIELD', context)[0] - runningInsideModel = self.parameterAsBool(parameters, self.RUNNING_INSIDE_MODEL, context) - feedback.setProgressText('Verificando inconsistencias ') - step =1 - progressStep = 100/4 - countourLayerPolyHoles = self.lineToPolygons(countourLayer,context, feedback) - step +=1 - feedback.setProgress( step * progressStep ) + countourLayer = self.parameterAsVectorLayer( + parameters, "INPUT_COUNTOUR_LINES", context + ) + levelsField = self.parameterAsFields(parameters, "INPUT_LEVES_FIELD", context)[ + 0 + ] + levelGap = self.parameterAsDouble(parameters, "INPUT_LEVEL_GAP", context) + isDepressionField = self.parameterAsFields( + parameters, "INPUT_IS_DEPRESSION_FIELD", context + )[0] + runningInsideModel = self.parameterAsBool( + parameters, self.RUNNING_INSIDE_MODEL, context + ) + feedback.setProgressText("Verificando inconsistencias ") + step = 1 + progressStep = 100 / 4 + countourLayerPolyHoles = self.lineToPolygons(countourLayer, context, feedback) + step += 1 + feedback.setProgress(step * progressStep) countourLayerPoly = self.fillHoles(countourLayerPolyHoles, context, feedback) - step +=1 - feedback.setProgress( step * progressStep ) + step += 1 + feedback.setProgress(step * progressStep) outputPolygons = [] self.fillField(countourLayer, countourLayerPoly) - step +=1 - feedback.setProgress( step * progressStep ) - self.compareLevel(levelsField, levelGap, isDepressionField, countourLayerPoly, outputPolygons, feedback, step, progressStep) + step += 1 + feedback.setProgress(step * progressStep) + self.compareLevel( + levelsField, + levelGap, + isDepressionField, + countourLayerPoly, + outputPolygons, + feedback, + step, + progressStep, + ) if outputPolygons or runningInsideModel: newLayer = self.outLayer(parameters, context, outputPolygons, countourLayer) - else: - newLayer = self.tr('No flags') + else: + newLayer = self.tr("No flags") return {self.OUTPUT: newLayer} - def lineToPolygons(self, layer,context, feedback): + def lineToPolygons(self, layer, context, feedback): r = processing.run( - 'native:polygonize', - { 'INPUT' : QgsProcessingFeatureSourceDefinition( - layer.source() - ), - 'KEEP_FIELDS' : True, - 'OUTPUT' : 'TEMPORARY_OUTPUT' + "native:polygonize", + { + "INPUT": QgsProcessingFeatureSourceDefinition(layer.source()), + "KEEP_FIELDS": True, + "OUTPUT": "TEMPORARY_OUTPUT", }, - context = context, - feedback = feedback + context=context, + feedback=feedback, ) - return r['OUTPUT'] + return r["OUTPUT"] + def createFeaturesArray(self, originalLayer): arrayFeatures = [] features = originalLayer.getFeatures() @@ -144,17 +163,16 @@ def createFeaturesArray(self, originalLayer): arrayFeatures.append(feature) return arrayFeatures - + def fillHoles(self, layer, context, feedback): r = processing.run( - 'native:deleteholes', - { 'INPUT' : layer, - 'OUTPUT' : 'TEMPORARY_OUTPUT' - }, - context = context, - feedback = feedback + "native:deleteholes", + {"INPUT": layer, "OUTPUT": "TEMPORARY_OUTPUT"}, + context=context, + feedback=feedback, ) - return r['OUTPUT'] + return r["OUTPUT"] + def fillField(self, countourLayer, countourLayerPoly): countourLayerPoly.startEditing() pr = countourLayerPoly.dataProvider() @@ -166,33 +184,46 @@ def fillField(self, countourLayer, countourLayerPoly): if feature2.geometry().touches(feature1.geometry()): fv = {} for field in feature2.fields(): - fieldIdx = pr.fields().indexFromName( field.name()) + fieldIdx = pr.fields().indexFromName(field.name()) fv[fieldIdx] = feature2[field.name()] - - feature1[field.name()] = feature2[field.name()] + + feature1[field.name()] = feature2[field.name()] updateMap[feature1.id()] = fv - pr.changeAttributeValues( updateMap ) + pr.changeAttributeValues(updateMap) countourLayerPoly.commitChanges() return False - def compareLevel(self, levelsField, levelGap, isDepressionField, countourLayerPoly, outputPolygons, feedback, step, progressStep): + + def compareLevel( + self, + levelsField, + levelGap, + isDepressionField, + countourLayerPoly, + outputPolygons, + feedback, + step, + progressStep, + ): isDep = 1 - isNotDep = 0 + isNotDep = 0 auxstep = 0 AUXCOUNT = 0 auxProgressStep = countourLayerPoly.featureCount() for feature1 in countourLayerPoly.getFeatures(): AUXCOUNT += 1 - auxcount=0 - auxstep+=1 - feedback.setProgress( step*(1+(auxstep/auxProgressStep)) * progressStep ) + auxcount = 0 + auxstep += 1 + feedback.setProgress( + step * (1 + (auxstep / auxProgressStep)) * progressStep + ) toCompare = [] areaComp = [] skip = True AreaOfInterest = feature1.geometry().boundingBox() request = QgsFeatureRequest().setFilterRect(AreaOfInterest) for feature2 in countourLayerPoly.getFeatures(request): - auxcount+=1 - if str(feature1.geometry())==str(feature2.geometry()): + auxcount += 1 + if str(feature1.geometry()) == str(feature2.geometry()): continue if feature1.geometry().within(feature2.geometry()): toCompare.append(feature2) @@ -200,48 +231,61 @@ def compareLevel(self, levelsField, levelGap, isDepressionField, countourLayerPo skip = False if skip: continue - fToCompare = toCompare[areaComp.index(min(areaComp))] + fToCompare = toCompare[areaComp.index(min(areaComp))] if fToCompare[isDepressionField] == isNotDep: if feature1[isDepressionField] == isNotDep: - if not((feature1[levelsField] - fToCompare[levelsField])==levelGap): + if not ( + (feature1[levelsField] - fToCompare[levelsField]) == levelGap + ): outputPolygons.append([feature1, 1]) if feature1[isDepressionField] == isDep: - if not(feature1[levelsField] == fToCompare[levelsField]): + if not (feature1[levelsField] == fToCompare[levelsField]): outputPolygons.append([feature1, 3]) if fToCompare[isDepressionField] == isDep: if feature1[isDepressionField] == isDep: - if not((fToCompare[levelsField] - feature1[levelsField])==levelGap): + if not ( + (fToCompare[levelsField] - feature1[levelsField]) == levelGap + ): outputPolygons.append([feature1, 2]) if feature1[isDepressionField] == isNotDep: - if not(feature1[levelsField] == fToCompare[levelsField]): + if not (feature1[levelsField] == fToCompare[levelsField]): outputPolygons.append([feature1, 4]) return False + def outLayer(self, parameters, context, polygons, streamLayer): newFields = self.getFlagFields() - + (sink, newLayer) = self.parameterAsSink( parameters, self.OUTPUT, context, newFields, - 3, #polygon - streamLayer.sourceCrs() + 3, # polygon + streamLayer.sourceCrs(), ) dicterro = { - 1: self.tr('Extern and intern are normal, but elevation differences are not greater than one equidistance'), - 2: self.tr('Extern and intern are depressions, but elevation differences are not smaller than one equidistance'), - 3: self.tr('Extern is normal, intern is depression, but elevations are different'), - 4: self.tr('Extern is depression, intern is normal, but elevations are different') + 1: self.tr( + "Extern and intern are normal, but elevation differences are not greater than one equidistance" + ), + 2: self.tr( + "Extern and intern are depressions, but elevation differences are not smaller than one equidistance" + ), + 3: self.tr( + "Extern is normal, intern is depression, but elevations are different" + ), + 4: self.tr( + "Extern is depression, intern is normal, but elevations are different" + ), } for polygon in polygons: newFeat = QgsFeature() newFeat.setGeometry(polygon[0].geometry()) newFeat.setFields(newFields) - for field in range(len(polygon[0].fields())): + for field in range(len(polygon[0].fields())): newFeat.setAttribute((field), polygon[0].attribute((field))) - newFeat['reason'] = dicterro[polygon[1]] + newFeat["reason"] = dicterro[polygon[1]] sink.addFeature(newFeat, QgsFeatureSink.FastInsert) - + return newLayer def name(self): @@ -252,21 +296,21 @@ def name(self): lowercase alphanumeric characters only and no spaces or other formatting characters. """ - return 'verifycountourstacking' + return "verifycountourstacking" def displayName(self): """ Returns the translated algorithm name, which should be used for any user-visible display of the algorithm name. """ - return self.tr('Verifies the stacking of contour lines') + return self.tr("Verifies the stacking of contour lines") def group(self): """ Returns the name of the group this algorithm belongs to. This string should be localised. """ - return self.tr('Quality Assurance Tools (Identification Processes)') + return self.tr("Quality Assurance Tools (Identification Processes)") def groupId(self): """ @@ -276,10 +320,10 @@ def groupId(self): contain lowercase alphanumeric characters only and no spaces or other formatting characters. """ - return 'DSGTools: Quality Assurance Tools (Identification Processes)' + return "DSGTools: Quality Assurance Tools (Identification Processes)" def tr(self, string): - return QCoreApplication.translate('VerifyCountourStackingAlgorihtm', string) + return QCoreApplication.translate("VerifyCountourStackingAlgorihtm", string) def createInstance(self): return VerifyCountourStackingAlgorihtm() diff --git a/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/verifyNetworkDirectioningAlgorithm.py b/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/verifyNetworkDirectioningAlgorithm.py index edb799344..c3f13d0d7 100644 --- a/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/verifyNetworkDirectioningAlgorithm.py +++ b/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/verifyNetworkDirectioningAlgorithm.py @@ -25,20 +25,30 @@ import processing from DsgTools.core.GeometricTools.layerHandler import LayerHandler from DsgTools.core.GeometricTools.networkHandler import NetworkHandler -from qgis.core import (QgsDataSourceUri, QgsFeature, QgsFeatureSink, - QgsGeometry, QgsProcessing, QgsProcessingAlgorithm, - QgsProcessingException, QgsProcessingMultiStepFeedback, - QgsProcessingOutputVectorLayer, - QgsProcessingParameterBoolean, - QgsProcessingParameterDistance, - QgsProcessingParameterEnum, - QgsProcessingParameterFeatureSink, - QgsProcessingParameterFeatureSource, - QgsProcessingParameterField, - QgsProcessingParameterMultipleLayers, - QgsProcessingParameterNumber, - QgsProcessingParameterVectorLayer, QgsProcessingUtils, - QgsProject, QgsSpatialIndex, QgsWkbTypes) +from qgis.core import ( + QgsDataSourceUri, + QgsFeature, + QgsFeatureSink, + QgsGeometry, + QgsProcessing, + QgsProcessingAlgorithm, + QgsProcessingException, + QgsProcessingMultiStepFeedback, + QgsProcessingOutputVectorLayer, + QgsProcessingParameterBoolean, + QgsProcessingParameterDistance, + QgsProcessingParameterEnum, + QgsProcessingParameterFeatureSink, + QgsProcessingParameterFeatureSource, + QgsProcessingParameterField, + QgsProcessingParameterMultipleLayers, + QgsProcessingParameterNumber, + QgsProcessingParameterVectorLayer, + QgsProcessingUtils, + QgsProject, + QgsSpatialIndex, + QgsWkbTypes, +) from ....dsgEnums import DsgEnums from ...algRunner import AlgRunner @@ -46,21 +56,21 @@ class VerifyNetworkDirectioningAlgorithm(ValidationAlgorithm): - NETWORK_LAYER = 'NETWORK_LAYER' - ATTRIBUTE_BLACK_LIST = 'ATTRIBUTE_BLACK_LIST' - IGNORE_VIRTUAL_FIELDS = 'IGNORE_VIRTUAL_FIELDS' - IGNORE_PK_FIELDS = 'IGNORE_PK_FIELDS' - NODE_LAYER = 'NODE_LAYER' - SINK_LAYER = 'SINK_LAYER' - SPILLWAY_LAYER = 'SPILLWAY_LAYER' - REF_LAYER = 'REF_LAYER' - WATER_BODY_LAYERS = 'WATER_BODY_LAYERS' - MAX_CYCLES = 'MAX_CYCLES' - SEARCH_RADIUS = 'SEARCH_RADIUS' - SELECT_ALL_VALID = 'SELECT_ALL_VALID' - FLAGS = 'FLAGS' - LINE_FLAGS = 'LINE_FLAGS' - DITCH_LAYER = 'DITCH_LAYER' + NETWORK_LAYER = "NETWORK_LAYER" + ATTRIBUTE_BLACK_LIST = "ATTRIBUTE_BLACK_LIST" + IGNORE_VIRTUAL_FIELDS = "IGNORE_VIRTUAL_FIELDS" + IGNORE_PK_FIELDS = "IGNORE_PK_FIELDS" + NODE_LAYER = "NODE_LAYER" + SINK_LAYER = "SINK_LAYER" + SPILLWAY_LAYER = "SPILLWAY_LAYER" + REF_LAYER = "REF_LAYER" + WATER_BODY_LAYERS = "WATER_BODY_LAYERS" + MAX_CYCLES = "MAX_CYCLES" + SEARCH_RADIUS = "SEARCH_RADIUS" + SELECT_ALL_VALID = "SELECT_ALL_VALID" + FLAGS = "FLAGS" + LINE_FLAGS = "LINE_FLAGS" + DITCH_LAYER = "DITCH_LAYER" def initAlgorithm(self, config): """ @@ -69,115 +79,112 @@ def initAlgorithm(self, config): self.addParameter( QgsProcessingParameterVectorLayer( self.NETWORK_LAYER, - self.tr('Network layer'), - [QgsProcessing.TypeVectorLine] + self.tr("Network layer"), + [QgsProcessing.TypeVectorLine], ) ) self.addParameter( QgsProcessingParameterField( self.ATTRIBUTE_BLACK_LIST, - self.tr('Fields to ignore'), + self.tr("Fields to ignore"), None, - 'NETWORK_LAYER', + "NETWORK_LAYER", QgsProcessingParameterField.Any, allowMultiple=True, - optional = True + optional=True, ) ) self.addParameter( QgsProcessingParameterBoolean( self.IGNORE_VIRTUAL_FIELDS, - self.tr('Ignore virtual fields'), - defaultValue=True + self.tr("Ignore virtual fields"), + defaultValue=True, ) ) self.addParameter( QgsProcessingParameterBoolean( self.IGNORE_PK_FIELDS, - self.tr('Ignore primary key fields'), - defaultValue=True + self.tr("Ignore primary key fields"), + defaultValue=True, ) ) self.addParameter( QgsProcessingParameterVectorLayer( - self.NODE_LAYER, - self.tr('Node layer'), - [QgsProcessing.TypeVectorPoint] + self.NODE_LAYER, self.tr("Node layer"), [QgsProcessing.TypeVectorPoint] ) ) self.addParameter( QgsProcessingParameterVectorLayer( self.REF_LAYER, - self.tr('Reference layer'), - [QgsProcessing.TypeVectorPolygon] + self.tr("Reference layer"), + [QgsProcessing.TypeVectorPolygon], ) ) self.addParameter( QgsProcessingParameterVectorLayer( self.SINK_LAYER, - self.tr('Water sink layer'), + self.tr("Water sink layer"), [QgsProcessing.TypeVectorPoint], - optional=True + optional=True, ) ) self.addParameter( QgsProcessingParameterVectorLayer( self.SPILLWAY_LAYER, - self.tr('Spillway layer'), + self.tr("Spillway layer"), [QgsProcessing.TypeVectorPoint], - optional=True + optional=True, ) ) self.addParameter( QgsProcessingParameterMultipleLayers( self.WATER_BODY_LAYERS, - self.tr('Water body layers'), + self.tr("Water body layers"), QgsProcessing.TypeVectorPolygon, - optional=True + optional=True, ) ) self.addParameter( QgsProcessingParameterVectorLayer( self.DITCH_LAYER, - self.tr('Ditch layer'), + self.tr("Ditch layer"), [QgsProcessing.TypeVectorLine], - optional=True + optional=True, ) ) self.addParameter( QgsProcessingParameterNumber( self.MAX_CYCLES, - self.tr('Maximum cycles'), + self.tr("Maximum cycles"), minValue=1, defaultValue=2, - type=QgsProcessingParameterNumber.Integer + type=QgsProcessingParameterNumber.Integer, ) ) self.addParameter( QgsProcessingParameterNumber( self.SEARCH_RADIUS, - self.tr('Search radius'), + self.tr("Search radius"), minValue=0, defaultValue=1, - type=QgsProcessingParameterNumber.Double + type=QgsProcessingParameterNumber.Double, ) ) self.addParameter( QgsProcessingParameterBoolean( self.SELECT_ALL_VALID, - self.tr('Select all valid lines after the process') + self.tr("Select all valid lines after the process"), ) ) self.addParameter( QgsProcessingParameterFeatureSink( self.FLAGS, - self.tr('{0} network node errors').format(self.displayName()) + self.tr("{0} network node errors").format(self.displayName()), ) ) self.addParameter( QgsProcessingParameterFeatureSink( - self.LINE_FLAGS, - self.tr('{0} line errors').format(self.displayName()) + self.LINE_FLAGS, self.tr("{0} line errors").format(self.displayName()) ) ) @@ -185,19 +192,25 @@ def processAlgorithm(self, parameters, context, feedback): """ Here is where the processing itself takes place. """ - #get the network handler + # get the network handler layerHandler = LayerHandler() networkHandler = NetworkHandler() algRunner = AlgRunner() # get network layer networkLayer = self.parameterAsLayer(parameters, self.NETWORK_LAYER, context) if networkLayer is None: - raise QgsProcessingException(self.invalidSourceError(parameters, self.NETWORK_LAYER)) + raise QgsProcessingException( + self.invalidSourceError(parameters, self.NETWORK_LAYER) + ) # get network node layer networkNodeLayer = self.parameterAsLayer(parameters, self.NODE_LAYER, context) if networkLayer is None: - raise QgsProcessingException(self.invalidSourceError(parameters, self.NODE_LAYER)) - waterBodyClasses = self.parameterAsLayer(parameters, self.WATER_BODY_LAYERS, context) + raise QgsProcessingException( + self.invalidSourceError(parameters, self.NODE_LAYER) + ) + waterBodyClasses = self.parameterAsLayer( + parameters, self.WATER_BODY_LAYERS, context + ) networkNodeLayer.startEditing() # get water sink layer waterSinkLayer = self.parameterAsLayer(parameters, self.SINK_LAYER, context) @@ -206,15 +219,23 @@ def processAlgorithm(self, parameters, context, feedback): # get frame layer frameLayer = self.parameterAsLayer(parameters, self.REF_LAYER, context) if frameLayer is None: - raise QgsProcessingException(self.invalidSourceError(parameters, self.REF_LAYER)) + raise QgsProcessingException( + self.invalidSourceError(parameters, self.REF_LAYER) + ) # get ditch layer ditchLayer = self.parameterAsLayer(parameters, self.DITCH_LAYER, context) - attributeBlackList = self.parameterAsFields(parameters, self.ATTRIBUTE_BLACK_LIST, context) - ignoreVirtual = self.parameterAsBool(parameters, self.IGNORE_VIRTUAL_FIELDS, context) + attributeBlackList = self.parameterAsFields( + parameters, self.ATTRIBUTE_BLACK_LIST, context + ) + ignoreVirtual = self.parameterAsBool( + parameters, self.IGNORE_VIRTUAL_FIELDS, context + ) ignorePK = self.parameterAsBool(parameters, self.IGNORE_PK_FIELDS, context) multiStepFeedback = QgsProcessingMultiStepFeedback(3, feedback) multiStepFeedback.setCurrentStep(0) - frame = layerHandler.getFrameOutterBounds(frameLayer, algRunner, context, feedback=multiStepFeedback) + frame = layerHandler.getFrameOutterBounds( + frameLayer, algRunner, context, feedback=multiStepFeedback + ) # get search radius searchRadius = self.parameterAsDouble(parameters, self.SEARCH_RADIUS, context) selectValid = self.parameterAsBool(parameters, self.SELECT_ALL_VALID, context) @@ -233,40 +254,42 @@ def processAlgorithm(self, parameters, context, feedback): ditchLayer=ditchLayer, attributeBlackList=attributeBlackList, excludePrimaryKeys=ignorePK, - ignoreVirtualFields=ignoreVirtual + ignoreVirtualFields=ignoreVirtual, ) multiStepFeedback.setCurrentStep(1) - #these are counted as one set of operations - flag_line_sink_id = self.addFeaturesToFlagLineSink(featList, parameters, networkLayer, context) + # these are counted as one set of operations + flag_line_sink_id = self.addFeaturesToFlagLineSink( + featList, parameters, networkLayer, context + ) self.prepareFlagSink(parameters, networkLayer, QgsWkbTypes.Point, context) self.buildFlagList(nodeFlags, networkLayer, nodeIdDict, multiStepFeedback) - return {self.NETWORK_LAYER : networkLayer, self.FLAGS : self.flag_id, self.LINE_FLAGS : flag_line_sink_id} + return { + self.NETWORK_LAYER: networkLayer, + self.FLAGS: self.flag_id, + self.LINE_FLAGS: flag_line_sink_id, + } def addFeaturesToFlagLineSink(self, featList, parameters, source, context): """ Adds line flags raised by networkHandler to flag line sink. """ flag_line_sink, flag_line_sink_id = self.prepareAndReturnFlagSink( - parameters, - source, - QgsWkbTypes.LineString, - context, - self.LINE_FLAGS - ) + parameters, source, QgsWkbTypes.LineString, context, self.LINE_FLAGS + ) flag_line_sink.addFeatures(featList, QgsFeatureSink.FastInsert) return flag_line_sink_id - + def buildFlagList(self, nodeFlags, source, nodeIdDict, feedback): """ Builds record list from pointList to raise flags. - :param nodeFlags: (dict) dictionary containing invalid node + :param nodeFlags: (dict) dictionary containing invalid node and its reason ( { (QgsPoint) node : (str) reason } ) """ # prepare point flag sink countNodeNotInDb = 0 nodeNumber = len(nodeFlags) - size = 100/nodeNumber if nodeNumber else 0 + size = 100 / nodeNumber if nodeNumber else 0 for current, (node, reason) in enumerate(nodeFlags.items()): if feedback.isCanceled(): break @@ -276,17 +299,17 @@ def buildFlagList(self, nodeFlags, source, nodeIdDict, feedback): # if node is not previously classified on database, but then motivates a flag, it should appear on Flags list featid = -9999 countNodeNotInDb += 1 - flagText = 'Feature with id={id} from {lyrName} with problem: {msg}'.format( - id=featid, - lyrName=source.name(), - msg=reason + flagText = "Feature with id={id} from {lyrName} with problem: {msg}".format( + id=featid, lyrName=source.name(), msg=reason ) flagGeom = QgsGeometry.fromMultiPointXY([node]) self.flagFeature(flagGeom, flagText) feedback.setProgress(size * current) if countNodeNotInDb: # in case there are flagged nodes that are not loaded in DB, user is notified - msg = self.tr('There are {0} flagged nodes that were introduced to network. Node reclassification is indicated.').format(countNodeNotInDb) + msg = self.tr( + "There are {0} flagged nodes that were introduced to network. Node reclassification is indicated." + ).format(countNodeNotInDb) feedback.pushInfo(msg) def name(self): @@ -297,21 +320,21 @@ def name(self): lowercase alphanumeric characters only and no spaces or other formatting characters. """ - return 'verifynetworkdirectioning' + return "verifynetworkdirectioning" def displayName(self): """ Returns the translated algorithm name, which should be used for any user-visible display of the algorithm name. """ - return self.tr('Verify Drainage Network Directioning') + return self.tr("Verify Drainage Network Directioning") def group(self): """ Returns the name of the group this algorithm belongs to. This string should be localised. """ - return self.tr('Quality Assurance Tools (Network Processes)') + return self.tr("Quality Assurance Tools (Network Processes)") def groupId(self): """ @@ -321,10 +344,10 @@ def groupId(self): contain lowercase alphanumeric characters only and no spaces or other formatting characters. """ - return 'DSGTools: Quality Assurance Tools (Network Processes)' + return "DSGTools: Quality Assurance Tools (Network Processes)" def tr(self, string): - return QCoreApplication.translate('VerifyNetworkDirectioningAlgorithm', string) + return QCoreApplication.translate("VerifyNetworkDirectioningAlgorithm", string) def createInstance(self): return VerifyNetworkDirectioningAlgorithm() diff --git a/DsgTools/core/DSGToolsProcessingAlgs/Models/dsgToolsProcessingModel.py b/DsgTools/core/DSGToolsProcessingAlgs/Models/dsgToolsProcessingModel.py index 9836e9db6..5fecd2c77 100644 --- a/DsgTools/core/DSGToolsProcessingAlgs/Models/dsgToolsProcessingModel.py +++ b/DsgTools/core/DSGToolsProcessingAlgs/Models/dsgToolsProcessingModel.py @@ -23,39 +23,47 @@ import os, json from time import time, sleep -from qgis.core import (QgsTask, - QgsProject, - QgsMapLayer, - QgsLayerTreeLayer, - QgsProcessingFeedback, - QgsProcessingModelAlgorithm, - QgsVectorLayer, - QgsProcessingUtils) +from qgis.core import ( + QgsTask, + QgsProject, + QgsMapLayer, + QgsLayerTreeLayer, + QgsProcessingFeedback, + QgsProcessingModelAlgorithm, + QgsVectorLayer, + QgsProcessingUtils, +) from qgis.PyQt.QtCore import pyqtSignal, QCoreApplication from processing.tools import dataobjects import processing + class DsgToolsProcessingModel(QgsTask): """ Handles models and materializes QgsProcessingModels from a DSGTools default model parameter set. """ + # supported input model formats MODEL_TYPES = ["xml", "file", "model"] # xml: XML string # # file: path to a local file # # model: qgis resgistered model # modelFinished = pyqtSignal(QgsTask) - + # Appending status flags to the existing ones - n = max([ - QgsTask.Queued, - QgsTask.OnHold, - QgsTask.Running, - QgsTask.Complete, - QgsTask.Terminated - ]) - WarningFlags, HaltedOnFlags, HaltedOnPossibleFalsePositiveFlags = range(n + 1, n + 4) + n = max( + [ + QgsTask.Queued, + QgsTask.OnHold, + QgsTask.Running, + QgsTask.Complete, + QgsTask.Terminated, + ] + ) + WarningFlags, HaltedOnFlags, HaltedOnPossibleFalsePositiveFlags = range( + n + 1, n + 4 + ) del n def __init__(self, parameters, name, taskName=None, flags=None, feedback=None): @@ -70,11 +78,12 @@ def __init__(self, parameters, name, taskName=None, flags=None, feedback=None): """ super(DsgToolsProcessingModel, self).__init__( # "", QgsTask.CanCancel if flags is None else flags - taskName or QCoreApplication.translate( + taskName + or QCoreApplication.translate( "DsgToolsProcessingModel", - "DSGTools Quality Assurance Model: {0}".format(name) + "DSGTools Quality Assurance Model: {0}".format(name), ), - QgsTask.CanCancel if flags is None else flags + QgsTask.CanCancel if flags is None else flags, ) self._name = name self._param = {} if self.validateParameters(parameters) else parameters @@ -82,11 +91,11 @@ def __init__(self, parameters, name, taskName=None, flags=None, feedback=None): self.feedback = feedback or QgsProcessingFeedback() self.feedback.canceled.connect(self.cancel) self.output = { - "result" : dict(), - "status" : False, - "executionTime" : .0, - "errorMessage" : self.tr("Thread not started yet."), - "finishStatus" : "initial" + "result": dict(), + "status": False, + "executionTime": 0.0, + "errorMessage": self.tr("Thread not started yet."), + "finishStatus": "initial", } def setTitle(self, title): @@ -108,19 +117,20 @@ def validateParameters(self, parameters): if "flags" not in parameters or not parameters["flags"]: # this is a mandatory item, but it's has a default to be set if missing parameters["flags"] = { - "onFlagsRaised" : "halt", - "enableLocalFlags" : False, - "loadOutput" : False, + "onFlagsRaised": "halt", + "enableLocalFlags": False, + "loadOutput": False, } if "flagLayerNames" not in parameters["flags"]: parameters["flags"]["flagLayerNames"] = [] if "source" not in parameters or not parameters["source"]: return self.tr("Model source is not defined.") - if "type" not in parameters["source"] or \ - parameters["source"]["type"] not in self.MODEL_TYPES: + if ( + "type" not in parameters["source"] + or parameters["source"]["type"] not in self.MODEL_TYPES + ): return self.tr("Input model type is not supported (or missing).") - if "data" not in parameters["source"] or \ - not parameters["source"]["data"]: + if "data" not in parameters["source"] or not parameters["source"]["data"]: return self.tr("Input model source was not identified.") return "" @@ -144,8 +154,7 @@ def modelFromXml(xml): :return: (QgsProcessingModelAlgorithm) model as a processing algorithm. """ temp = os.path.join( - os.path.dirname(__file__), - "temp_model_{0}.model3".format(hash(time())) + os.path.dirname(__file__), "temp_model_{0}.model3".format(hash(time())) ) with open(temp, "w+", encoding="utf-8") as xmlFile: xmlFile.write(xml) @@ -166,12 +175,7 @@ def metadata(self): :return: (dict) metadata. """ if "metadata" not in self._param: - return { - "author" : "", - "version" : "", - "lastModified" : "", - "originalName" : "" - } + return {"author": "", "version": "", "lastModified": "", "originalName": ""} return self._param["metadata"] def author(self): @@ -214,9 +218,9 @@ def metadataText(self): """ if "metadata" not in self._param: return "" - return self.tr( - "Model {name} v{version} ({lastModified}) by {author}." - ).format(name=self.displayName(), **self.metadata()) + return self.tr("Model {name} v{version} ({lastModified}) by {author}.").format( + name=self.displayName(), **self.metadata() + ) def isValid(self): """ @@ -248,8 +252,11 @@ def displayName(self): """ if not self.isValid(): return "" - return self._param["displayName"] if "displayName" in self._param else \ - self.tr("DSGTools Validation Model ({0})").format(self.name()) + return ( + self._param["displayName"] + if "displayName" in self._param + else self.tr("DSGTools Validation Model ({0})").format(self.name()) + ) def name(self): """ @@ -266,11 +273,14 @@ def model(self): if not self.isValid(): return QgsProcessingModelAlgorithm() method = { - "xml" : DsgToolsProcessingModel.modelFromXml, - "file" : DsgToolsProcessingModel.modelFromFile + "xml": DsgToolsProcessingModel.modelFromXml, + "file": DsgToolsProcessingModel.modelFromFile, } - return method[self.source()](self.data()) if self.source() in method\ - else QgsProcessingModelAlgorithm() + return ( + method[self.source()](self.data()) + if self.source() in method + else QgsProcessingModelAlgorithm() + ) def flags(self): """ @@ -297,7 +307,7 @@ def loadOutput(self): :return: (str) model behaviour on Workflow. """ return self.flags()["loadOutput"] if self.flags() else False - + def flagLayerNames(self): """ Model behaviour when flags are raised. Tells which layers should be checked as flags. @@ -319,8 +329,8 @@ def childAlgorithms(self, model=None): :return: (list-of-str) list of all algorithms. """ return [ - alg.algorithm().displayName() \ - for alg in (model or self.model()).childAlgorithms().values() + alg.algorithm().displayName() + for alg in (model or self.model()).childAlgorithms().values() ] def modelParameters(self, model=None): @@ -328,9 +338,9 @@ def modelParameters(self, model=None): A list of parameters needed to be filled for the model to run. :param model: (QgsProcessingModelAlgorithm) model to have its parameters checked. - :return: (list-of-str) + :return: (list-of-str) """ - # IMPORTANT: this method seems to be causing QGIS to crash when called + # IMPORTANT: this method seems to be causing QGIS to crash when called # from command line. Error is "corrupted double-linked list / Aborted (core dumped)" # seems to be a QGIS mishandling, but should be lloked into deeper. # It works just fine running on plugin's thread - e.g. does not crash @@ -340,12 +350,11 @@ def modelParameters(self, model=None): if not self._param: return [] model = model or self.model() - return [ - param.name() \ - for param in model.parameterDefinitions() - ] + return [param.name() for param in model.parameterDefinitions()] - def addLayerToGroup(self, layer, groupname, subgroupname=None, clearGroupBeforeAdding=False): + def addLayerToGroup( + self, layer, groupname, subgroupname=None, clearGroupBeforeAdding=False + ): """ Adds a layer to a group into layer panel. :param layer: (QgsMapLayer) layer to be added to canvas. @@ -355,9 +364,12 @@ def addLayerToGroup(self, layer, groupname, subgroupname=None, clearGroupBeforeA subGroup = self.createGroups(groupname, subgroupname) if clearGroupBeforeAdding: self.clearGroup(subGroup) - layer = layer if isinstance(layer, QgsMapLayer) \ + layer = ( + layer + if isinstance(layer, QgsMapLayer) else QgsProcessingUtils.mapLayerFromString(layer) - QgsProject.instance().addMapLayer(layer, addToLegend = False) + ) + QgsProject.instance().addMapLayer(layer, addToLegend=False) subGroup.addLayer(layer) def createGroups(self, groupname, subgroupname): @@ -365,15 +377,14 @@ def createGroups(self, groupname, subgroupname): qaGroup = self.createGroup(groupname, root) subGroup = self.createGroup(subgroupname, qaGroup) return subGroup - + def createGroup(self, groupName, rootNode): groupNode = rootNode.findGroup(groupName) return groupNode if groupNode else rootNode.addGroup(groupName) - + def prepareGroup(self, model): subGroup = self.createGroups( - "DSGTools_QA_Toolbox", - self.model().model.displayName() + "DSGTools_QA_Toolbox", self.model().model.displayName() ) self.clearGroup(subGroup) @@ -396,13 +407,12 @@ def runModel(self, feedback=None): model = self.model() if self.isCanceled(): return {} - context = dataobjects.createContext( - feedback=feedback) + context = dataobjects.createContext(feedback=feedback) out = processing.run( model, - { param : "memory:" for param in self.modelParameters(model) }, + {param: "memory:" for param in self.modelParameters(model)}, feedback=feedback, - context=context + context=context, ) # not sure exactly when, but on 3.16 LTR output from model runs include # new items on it. these new items break our implementation =) @@ -420,14 +430,10 @@ def runModel(self, feedback=None): vl.setName(name.split(":", 2)[-1]) if vl.name() in flagLayerNames and vl.featureCount() == 0: continue - self.addLayerToGroup( - vl, - "DSGTools_QA_Toolbox", - model.displayName() - ) + self.addLayerToGroup(vl, "DSGTools_QA_Toolbox", model.displayName()) self.enableFeatureCount(vl) return out - + def enableFeatureCount(self, lyr): root = QgsProject.instance().layerTreeRoot() lyrNode = root.findLayer(lyr.id()) @@ -459,11 +465,7 @@ def run(self): start = time() try: if not self.feedback.isCanceled() or not self.isCanceled(): - self.output = { - "result": dict(), - "status" : True, - "errorMessage" : "" - } + self.output = {"result": dict(), "status": True, "errorMessage": ""} for paramName, vl in self.runModel(self.feedback).items(): baseName = paramName.rsplit(":", 1)[-1] name = baseName @@ -477,21 +479,25 @@ def run(self): self.output["result"][name] = vl except Exception as e: self.output = { - "result" : {}, - "status" : False, - "errorMessage" : self.tr("Model has failed:\n'{error}'")\ - .format(error=str(e)) + "result": {}, + "status": False, + "errorMessage": self.tr("Model has failed:\n'{error}'").format( + error=str(e) + ), } self.output["executionTime"] = time() - start return self.output["status"] - + def hasFlags(self): """ Iterates over the results and finds if there are flags. """ - for key, lyr in self.output['result'].items(): - if key in self._param['flags']['flagLayerNames'] \ - and isinstance(lyr, QgsMapLayer) and lyr.featureCount() > 0: + for key, lyr in self.output["result"].items(): + if ( + key in self._param["flags"]["flagLayerNames"] + and isinstance(lyr, QgsMapLayer) + and lyr.featureCount() > 0 + ): return True return False @@ -501,12 +507,12 @@ def finished(self, result): always called right after run is finished (read the docs on QgsTask). :param result: (bool) run returned valued. """ - if result and self.onFlagsRaised() == 'halt' and self.hasFlags(): + if result and self.onFlagsRaised() == "halt" and self.hasFlags(): self.cancel() self.feedback.cancel() - self.output["finishStatus"] = 'halt' + self.output["finishStatus"] = "halt" elif not result: - self.output["finishStatus"] = 'failed' + self.output["finishStatus"] = "failed" else: - self.output["finishStatus"] = 'finished' + self.output["finishStatus"] = "finished" self.modelFinished.emit(self) diff --git a/DsgTools/core/DSGToolsProcessingAlgs/Models/qualityAssuranceWorkflow.py b/DsgTools/core/DSGToolsProcessingAlgs/Models/qualityAssuranceWorkflow.py index 68d0ed6ef..7d4c4c584 100644 --- a/DsgTools/core/DSGToolsProcessingAlgs/Models/qualityAssuranceWorkflow.py +++ b/DsgTools/core/DSGToolsProcessingAlgs/Models/qualityAssuranceWorkflow.py @@ -25,18 +25,24 @@ from time import sleep, time from functools import partial -from qgis.core import (QgsApplication, - QgsProcessingFeedback, - QgsProcessingMultiStepFeedback) +from qgis.core import ( + QgsApplication, + QgsProcessingFeedback, + QgsProcessingMultiStepFeedback, +) from qgis.PyQt.QtCore import QObject, pyqtSignal -from DsgTools.core.DSGToolsProcessingAlgs.Models.dsgToolsProcessingModel import DsgToolsProcessingModel +from DsgTools.core.DSGToolsProcessingAlgs.Models.dsgToolsProcessingModel import ( + DsgToolsProcessingModel, +) + class QualityAssuranceWorkflow(QObject): """ Works as a multi-model runner. Understands all models' parameters as an output vector layer. """ + workflowFinished = pyqtSignal() haltedOnFlags = pyqtSignal(DsgToolsProcessingModel) modelStarted = pyqtSignal(DsgToolsProcessingModel) @@ -77,7 +83,7 @@ def validateParameters(self, parameters): if "models" not in parameters or not parameters["models"]: return self.tr("Workflow seems to have no models associated with it.") for modelName, modelParam in parameters["models"].items(): - model=DsgToolsProcessingModel(modelParam, modelName) + model = DsgToolsProcessingModel(modelParam, modelName) if not model.isValid(): return self.tr("Model {model} is invalid: '{reason}'.").format( model=modelName, reason=model.validateParameters(modelParam) @@ -135,8 +141,7 @@ def displayName(self): Friendly name for the workflow. :return: (str) display name. """ - return self._param["displayName"] if \ - "displayName" in self._param else "" + return self._param["displayName"] if "displayName" in self._param else "" def name(self): """ @@ -150,7 +155,7 @@ def models(self): Model parameters defined to run in this workflow. :return: (dict) models maps to valid and invalid models. """ - models = {"valid" : dict(), "invalid" : dict()} + models = {"valid": dict(), "invalid": dict()} self._multiStepFeedback = QgsProcessingMultiStepFeedback( len(self._param["models"]), self.feedback ) @@ -248,11 +253,9 @@ def asDict(self, withOutputDict=False): if withOutputDict: outputCopy = dict(self.output) for key, value in outputCopy.items(): - if 'result' in value: - outputCopy[key].pop('result') - outputDict.update( - {"output": outputCopy} - ) + if "result" in value: + outputCopy[key].pop("result") + outputDict.update({"output": outputCopy}) return outputDict def finished(self): @@ -275,8 +278,8 @@ def runOnMainThread(self): self.output[mName] = dict() try: self.output[mName]["result"] = { - k.split(":", 2)[-1] : v \ - for k, v in model.runModel(model.feedback).items() + k.split(":", 2)[-1]: v + for k, v in model.runModel(model.feedback).items() } self.output[mName]["status"] = True except Exception as e: @@ -352,9 +355,9 @@ def handleFlags(self, model): :param model: (DsgToolsProcessingModel) model to have its output handled. """ onFlagsMethod = { - "warn" : partial(self.raiseFlagWarning, model), - "halt" : partial(self.raiseFlagError, model), - "ignore" : partial(self.modelFinished.emit, model) + "warn": partial(self.raiseFlagWarning, model), + "halt": partial(self.raiseFlagError, model), + "ignore": partial(self.modelFinished.emit, model), }[model.onFlagsRaised()]() def run(self, firstModelName=None, cooldown=None): @@ -369,10 +372,12 @@ def run(self, firstModelName=None, cooldown=None): modelCount = len(self._executionOrder) if self.hasInvalidModel() or modelCount == 0: return None + def modelCompleted(model, step): self.output[model.name()] = model.output self._multiStepFeedback.setCurrentStep(step) self.handleFlags(model) + if firstModelName is not None: for idx, model in self._executionOrder.items(): if model.name() == firstModelName: @@ -391,16 +396,13 @@ def modelCompleted(model, step): currentModel.taskCompleted.connect( partial(modelCompleted, currentModel, idx + 1) ) - currentModel.begun.connect( - partial(self.modelStarted.emit, currentModel) - ) + currentModel.begun.connect(partial(self.modelStarted.emit, currentModel)) currentModel.taskTerminated.connect( partial(self.modelFailed.emit, currentModel) ) if idx != modelCount - 1: self._executionOrder[idx + 1].addSubTask( - currentModel, - subTaskDependency=currentModel.ParentDependsOnSubTask + currentModel, subTaskDependency=currentModel.ParentDependsOnSubTask ) else: # last model indicates workflow finish @@ -420,14 +422,16 @@ def lastModelName(self): modelCount = len(self._executionOrder) for idx, model in self._executionOrder.items(): modelName = self._executionOrder[idx].displayName() - if modelName not in self.output or \ - self.output[modelName]["finishStatus"] != "finished": + if ( + modelName not in self.output + or self.output[modelName]["finishStatus"] != "finished" + ): return modelName else: return None - + def getOutputStatusDict(self): return self.output - + def setOutputStatusDict(self, statusDict): self.output = statusDict diff --git a/DsgTools/core/DSGToolsProcessingAlgs/algRunner.py b/DsgTools/core/DSGToolsProcessingAlgs/algRunner.py index 26b53e038..99c43782a 100644 --- a/DsgTools/core/DSGToolsProcessingAlgs/algRunner.py +++ b/DsgTools/core/DSGToolsProcessingAlgs/algRunner.py @@ -23,39 +23,76 @@ import uuid import processing -from qgis.core import (Qgis, - QgsProcessingUtils, - QgsProcessingFeatureSourceDefinition) +from qgis.core import Qgis, QgsProcessingUtils, QgsProcessingFeatureSourceDefinition + class AlgRunner: - Break, Snap, RmDangle, ChDangle, RmBridge, ChBridge, RmDupl, RmDac, BPol, Prune, RmArea, RmLine, RMSA = range(13) + ( + Break, + Snap, + RmDangle, + ChDangle, + RmBridge, + ChBridge, + RmDupl, + RmDac, + BPol, + Prune, + RmArea, + RmLine, + RMSA, + ) = range(13) def generateGrassOutputAndError(self): - uuid_value = str(uuid.uuid4()).replace('-','') - output = QgsProcessingUtils.generateTempFilename('output_{uuid}.shp'.format(uuid=uuid_value)) - error = QgsProcessingUtils.generateTempFilename('error_{uuid}.shp'.format(uuid=uuid_value)) + uuid_value = str(uuid.uuid4()).replace("-", "") + output = QgsProcessingUtils.generateTempFilename( + "output_{uuid}.shp".format(uuid=uuid_value) + ) + error = QgsProcessingUtils.generateTempFilename( + "error_{uuid}.shp".format(uuid=uuid_value) + ) return output, error - - def getGrassReturn(self, outputDict, context, returnError = False): - lyr = QgsProcessingUtils.mapLayerFromString(outputDict['output'], context) + + def getGrassReturn(self, outputDict, context, returnError=False): + lyr = QgsProcessingUtils.mapLayerFromString(outputDict["output"], context) if returnError: - errorLyr = QgsProcessingUtils.mapLayerFromString(outputDict['error'], context) + errorLyr = QgsProcessingUtils.mapLayerFromString( + outputDict["error"], context + ) return lyr, errorLyr else: return lyr - def runDissolve(self, inputLyr, context, feedback=None, outputLyr=None, field=None): - outputLyr = 'memory:' if outputLyr is None else outputLyr + def runDissolve( + self, + inputLyr, + context, + feedback=None, + outputLyr=None, + field=None, + is_child_algorithm=False, + ): + outputLyr = "memory:" if outputLyr is None else outputLyr field = [] if field is None else field - parameters = { - 'INPUT' : inputLyr, - 'FIELD': field, - 'OUTPUT': outputLyr - } - output = processing.run('native:dissolve', parameters, context=context, feedback=feedback) - return output['OUTPUT'] - - def runGrassDissolve(self, inputLyr, context, feedback=None, column=None, outputLyr=None, onFinish=None): + parameters = {"INPUT": inputLyr, "FIELD": field, "OUTPUT": outputLyr} + output = processing.run( + "native:dissolve", + parameters, + context=context, + feedback=feedback, + is_child_algorithm=is_child_algorithm, + ) + return output["OUTPUT"] + + def runGrassDissolve( + self, + inputLyr, + context, + feedback=None, + column=None, + outputLyr=None, + onFinish=None, + ): """ Runs dissolve from GRASS algorithm provider. :param inputLyr: (QgsVectorLayer) layer to be dissolved. @@ -67,105 +104,167 @@ def runGrassDissolve(self, inputLyr, context, feedback=None, column=None, output :return: (QgsVectorLayer) dissolved (output) layer. """ parameters = { - 'GRASS_MIN_AREA_PARAMETER' : 0.0001, - 'GRASS_OUTPUT_TYPE_PARAMETER' : 0, - 'GRASS_REGION_PARAMETER' : None, - 'GRASS_SNAP_TOLERANCE_PARAMETER' : -1, - 'GRASS_VECTOR_DSCO' : '', - 'GRASS_VECTOR_EXPORT_NOCAT' : False, - 'GRASS_VECTOR_LCO' : '', - 'column' : column, - 'input' : inputLyr, - 'output' : outputLyr or QgsProcessingUtils.generateTempFilename('output.shp') + "GRASS_MIN_AREA_PARAMETER": 0.0001, + "GRASS_OUTPUT_TYPE_PARAMETER": 0, + "GRASS_REGION_PARAMETER": None, + "GRASS_SNAP_TOLERANCE_PARAMETER": -1, + "GRASS_VECTOR_DSCO": "", + "GRASS_VECTOR_EXPORT_NOCAT": False, + "GRASS_VECTOR_LCO": "", + "column": column, + "input": inputLyr, + "output": outputLyr + or QgsProcessingUtils.generateTempFilename("output.shp"), } - output = processing.run('grass7:v.dissolve', parameters, onFinish, feedback, context) + output = processing.run( + "grass7:v.dissolve", parameters, onFinish, feedback, context + ) return self.getGrassReturn(output, context) - def runDonutHoleExtractor(self, inputLyr, context, feedback=None, donuthole=None, outershell=None , selected=False): - donuthole = 'memory:' if donuthole is None else donuthole - outershell = 'memory:' if outershell is None else outershell + def runDonutHoleExtractor( + self, + inputLyr, + context, + feedback=None, + donuthole=None, + outershell=None, + selected=False, + ): + donuthole = "memory:" if donuthole is None else donuthole + outershell = "memory:" if outershell is None else outershell parameters = { - 'INPUT' : inputLyr, - 'SELECTED' : selected, - 'OUTERSHELL': outershell, - 'DONUTHOLE' : donuthole + "INPUT": inputLyr, + "SELECTED": selected, + "OUTERSHELL": outershell, + "DONUTHOLE": donuthole, } - output = processing.run('dsgtools:donutholeextractor', parameters, context=context, feedback=feedback) - return output['OUTERSHELL'], output['DONUTHOLE'] - - def runDeleteHoles(self, inputLyr, context, feedback=None, outputLyr=None, min_area=0): - outputLyr = 'memory:' if outputLyr is None else outputLyr - parameters = { - 'INPUT' : inputLyr, - 'MIN_AREA': min_area, - 'OUTPUT': outputLyr - } - output = processing.run('native:deleteholes', parameters, context=context, feedback=feedback) - return output['OUTPUT'] - - def runOverlay(self, lyrA, lyrB, context, atype=0, btype=0, feedback=None, snap=0, operator=0, minArea=1e-8): + output = processing.run( + "dsgtools:donutholeextractor", + parameters, + context=context, + feedback=feedback, + ) + return output["OUTERSHELL"], output["DONUTHOLE"] + + def runDeleteHoles( + self, inputLyr, context, feedback=None, outputLyr=None, min_area=0 + ): + outputLyr = "memory:" if outputLyr is None else outputLyr + parameters = {"INPUT": inputLyr, "MIN_AREA": min_area, "OUTPUT": outputLyr} + output = processing.run( + "native:deleteholes", parameters, context=context, feedback=feedback + ) + return output["OUTPUT"] + + def runOverlay( + self, + lyrA, + lyrB, + context, + atype=0, + btype=0, + feedback=None, + snap=0, + operator=0, + minArea=1e-8, + ): output, _ = self.generateGrassOutputAndError() parameters = { - 'ainput':lyrA, - 'atype':atype, - 'binput':lyrB, - 'btype':btype, - 'operator':operator, - 'snap':snap, - '-t':False, - 'output':output, - 'GRASS_REGION_PARAMETER':None, - 'GRASS_SNAP_TOLERANCE_PARAMETER':-1, - 'GRASS_MIN_AREA_PARAMETER':minArea, - 'GRASS_OUTPUT_TYPE_PARAMETER':0, - 'GRASS_VECTOR_DSCO':'', - 'GRASS_VECTOR_LCO':'' - } - outputDict = processing.run('grass7:v.overlay', parameters, context=context, feedback=feedback) + "ainput": lyrA, + "atype": atype, + "binput": lyrB, + "btype": btype, + "operator": operator, + "snap": snap, + "-t": False, + "output": output, + "GRASS_REGION_PARAMETER": None, + "GRASS_SNAP_TOLERANCE_PARAMETER": -1, + "GRASS_MIN_AREA_PARAMETER": minArea, + "GRASS_OUTPUT_TYPE_PARAMETER": 0, + "GRASS_VECTOR_DSCO": "", + "GRASS_VECTOR_LCO": "", + } + outputDict = processing.run( + "grass7:v.overlay", parameters, context=context, feedback=feedback + ) return self.getGrassReturn(outputDict, context) - - def runClean(self, inputLyr, toolList, context, feedback=None, typeList=None, returnError=False, useFollowup=False, snap=None, minArea=None): + + def runClean( + self, + inputLyr, + toolList, + context, + feedback=None, + typeList=None, + returnError=False, + useFollowup=False, + snap=None, + minArea=None, + ): snap = -1 if snap is None else snap minArea = 0.0001 if minArea is None else minArea - typeList = [0,1,2,3,4,5,6] if typeList is None else typeList + typeList = [0, 1, 2, 3, 4, 5, 6] if typeList is None else typeList output, error = self.generateGrassOutputAndError() parameters = { - 'input':inputLyr, - 'type':typeList, - 'tool':toolList, - '-b': False, - '-c': useFollowup, - 'output' : output, - 'error': error, - 'GRASS_REGION_PARAMETER': None, - 'GRASS_SNAP_TOLERANCE_PARAMETER': snap, - 'GRASS_MIN_AREA_PARAMETER': minArea, - 'GRASS_OUTPUT_TYPE_PARAMETER': 0, - 'GRASS_VECTOR_DSCO':'', - 'GRASS_VECTOR_LCO':'', - 'GRASS_VECTOR_EXPORT_NOCAT':False - } - outputDict = processing.run('grass7:v.clean', parameters, context=context, feedback=feedback) + "input": inputLyr, + "type": typeList, + "tool": toolList, + "-b": False, + "-c": useFollowup, + "output": output, + "error": error, + "GRASS_REGION_PARAMETER": None, + "GRASS_SNAP_TOLERANCE_PARAMETER": snap, + "GRASS_MIN_AREA_PARAMETER": minArea, + "GRASS_OUTPUT_TYPE_PARAMETER": 0, + "GRASS_VECTOR_DSCO": "", + "GRASS_VECTOR_LCO": "", + "GRASS_VECTOR_EXPORT_NOCAT": False, + } + outputDict = processing.run( + "grass7:v.clean", parameters, context=context, feedback=feedback + ) return self.getGrassReturn(outputDict, context, returnError=returnError) - - def runDsgToolsClean(self, inputLyr, context, feedback=None, onlySelected = False, snap=None, minArea=None, flags=None): + + def runDsgToolsClean( + self, + inputLyr, + context, + feedback=None, + onlySelected=False, + snap=None, + minArea=None, + flags=None, + ): snap = -1 if snap is None else snap minArea = 0.0001 if minArea is None else minArea - flags = 'memory:' if flags is None else flags + flags = "memory:" if flags is None else flags parameters = { - 'INPUT' : inputLyr, - 'SELECTED' : onlySelected, - 'TOLERANCE': snap, - 'MINAREA': minArea, - 'FLAGS' : flags + "INPUT": inputLyr, + "SELECTED": onlySelected, + "TOLERANCE": snap, + "MINAREA": minArea, + "FLAGS": flags, } - output = processing.run('dsgtools:cleangeometries', parameters, context=context, feedback=feedback) - return output['OUTPUT'] + output = processing.run( + "dsgtools:cleangeometries", parameters, context=context, feedback=feedback + ) + return output["OUTPUT"] - def runDouglasSimplification(self, inputLyr, threshold, context, - feedback=None, snap=None, minArea=None, - iterations=None, type=None, returnError=False, - flags=None): + def runDouglasSimplification( + self, + inputLyr, + threshold, + context, + feedback=None, + snap=None, + minArea=None, + iterations=None, + type=None, + returnError=False, + flags=None, + ): """ Runs simplify GRASS algorithm :param inputLyr: (QgsVectorLayer) layer, or layers, to be dissolved. @@ -184,374 +283,527 @@ def runDouglasSimplification(self, inputLyr, threshold, context, snap = -1 if snap is None else snap minArea = 0.0001 if minArea is None else minArea iterations = 1 if iterations is None else iterations - flags = 'memory:' if flags is None else flags + flags = "memory:" if flags is None else flags algType = [0, 1, 2] if type is None else type output, error = self.generateGrassOutputAndError() parameters = { - 'input': inputLyr, - 'type':algType, - 'cats':'', - 'where':'', - 'method':0, - 'threshold':threshold, - 'look_ahead':7, - 'reduction':50, - 'slide':0.5, - 'angle_thresh':3, - 'degree_thresh':0, - 'closeness_thresh':0, - 'betweeness_thresh':0, - 'alpha':1, - 'beta':1, - 'iterations':iterations, - '-t':False, - '-l':True, - 'output':output, - 'error':error, - 'GRASS_REGION_PARAMETER':None, - 'GRASS_SNAP_TOLERANCE_PARAMETER':snap, - 'GRASS_MIN_AREA_PARAMETER':minArea, - 'GRASS_OUTPUT_TYPE_PARAMETER':0, - 'GRASS_VECTOR_DSCO':'', - 'GRASS_VECTOR_LCO':''} - outputDict = processing.run("grass7:v.generalize", parameters, - context=context, feedback=feedback) + "input": inputLyr, + "type": algType, + "cats": "", + "where": "", + "method": 0, + "threshold": threshold, + "look_ahead": 7, + "reduction": 50, + "slide": 0.5, + "angle_thresh": 3, + "degree_thresh": 0, + "closeness_thresh": 0, + "betweeness_thresh": 0, + "alpha": 1, + "beta": 1, + "iterations": iterations, + "-t": False, + "-l": True, + "output": output, + "error": error, + "GRASS_REGION_PARAMETER": None, + "GRASS_SNAP_TOLERANCE_PARAMETER": snap, + "GRASS_MIN_AREA_PARAMETER": minArea, + "GRASS_OUTPUT_TYPE_PARAMETER": 0, + "GRASS_VECTOR_DSCO": "", + "GRASS_VECTOR_LCO": "", + } + outputDict = processing.run( + "grass7:v.generalize", parameters, context=context, feedback=feedback + ) return self.getGrassReturn(outputDict, context, returnError=returnError) - def runIdentifyDuplicatedGeometries(self, inputLyr, context, feedback=None, flagLyr=None, onlySelected=False): - flagLyr = 'memory:' if flagLyr is None else flagLyr - parameters = { - 'INPUT' : inputLyr, - 'SELECTED' : onlySelected, - 'FLAGS': flagLyr - } - output = processing.run('dsgtools:identifyduplicatedgeometries', parameters, context=context, feedback=feedback) - return output['FLAGS'] + def runIdentifyDuplicatedGeometries( + self, inputLyr, context, feedback=None, flagLyr=None, onlySelected=False + ): + flagLyr = "memory:" if flagLyr is None else flagLyr + parameters = {"INPUT": inputLyr, "SELECTED": onlySelected, "FLAGS": flagLyr} + output = processing.run( + "dsgtools:identifyduplicatedgeometries", + parameters, + context=context, + feedback=feedback, + ) + return output["FLAGS"] - def runIdentifyDuplicatedFeatures(self, inputLyr, context, onlySelected=False, attributeBlackList=None, excludePrimaryKeys=True, ignoreVirtualFields=True, feedback=None, flagLyr=None): - flagLyr = 'memory:' if flagLyr is None else flagLyr + def runIdentifyDuplicatedFeatures( + self, + inputLyr, + context, + onlySelected=False, + attributeBlackList=None, + excludePrimaryKeys=True, + ignoreVirtualFields=True, + feedback=None, + flagLyr=None, + ): + flagLyr = "memory:" if flagLyr is None else flagLyr attributeBlackList = [] if attributeBlackList is None else attributeBlackList parameters = { - 'INPUT' : inputLyr, - 'SELECTED' : onlySelected, - 'FLAGS': flagLyr, - 'ATTRIBUTE_BLACK_LIST' : attributeBlackList, - 'IGNORE_VIRTUAL_FIELDS' : ignoreVirtualFields, - 'IGNORE_PK_FIELDS' : excludePrimaryKeys + "INPUT": inputLyr, + "SELECTED": onlySelected, + "FLAGS": flagLyr, + "ATTRIBUTE_BLACK_LIST": attributeBlackList, + "IGNORE_VIRTUAL_FIELDS": ignoreVirtualFields, + "IGNORE_PK_FIELDS": excludePrimaryKeys, } - output = processing.run('dsgtools:identifyduplicatedfeatures', parameters, context=context, feedback=feedback) - return output['FLAGS'] + output = processing.run( + "dsgtools:identifyduplicatedfeatures", + parameters, + context=context, + feedback=feedback, + ) + return output["FLAGS"] - def runIdentifySmallLines(self, inputLyr, tol, context, feedback=None, flagLyr=None, onlySelected=False): - flagLyr = 'memory:' if flagLyr is None else flagLyr + def runIdentifySmallLines( + self, inputLyr, tol, context, feedback=None, flagLyr=None, onlySelected=False + ): + flagLyr = "memory:" if flagLyr is None else flagLyr parameters = { - 'INPUT' : inputLyr, - 'TOLERANCE' : tol, - 'SELECTED' : onlySelected, - 'FLAGS': flagLyr + "INPUT": inputLyr, + "TOLERANCE": tol, + "SELECTED": onlySelected, + "FLAGS": flagLyr, } - output = processing.run('dsgtools:identifysmalllines', parameters, context=context, feedback=feedback) - return output['FLAGS'] + output = processing.run( + "dsgtools:identifysmalllines", + parameters, + context=context, + feedback=feedback, + ) + return output["FLAGS"] - def runIdentifySmallPolygons(self, inputLyr, tol, context, feedback=None, flagLyr=None, onlySelected=False): - flagLyr = 'memory:' if flagLyr is None else flagLyr + def runIdentifySmallPolygons( + self, inputLyr, tol, context, feedback=None, flagLyr=None, onlySelected=False + ): + flagLyr = "memory:" if flagLyr is None else flagLyr parameters = { - 'INPUT' : inputLyr, - 'TOLERANCE' : tol, - 'SELECTED' : onlySelected, - 'FLAGS': flagLyr + "INPUT": inputLyr, + "TOLERANCE": tol, + "SELECTED": onlySelected, + "FLAGS": flagLyr, } - output = processing.run('dsgtools:identifysmallpolygons', parameters, context=context, feedback=feedback) - return output['FLAGS'] + output = processing.run( + "dsgtools:identifysmallpolygons", + parameters, + context=context, + feedback=feedback, + ) + return output["FLAGS"] - def runSnapGeometriesToLayer(self, inputLayer, referenceLayer, tol, context, feedback=None, behavior=None, outputLyr=None, is_child_algorithm=False): + def runSnapGeometriesToLayer( + self, + inputLayer, + referenceLayer, + tol, + context, + feedback=None, + behavior=None, + outputLyr=None, + is_child_algorithm=False, + ): behavior = 0 if behavior is None else behavior - outputLyr = 'memory:' if outputLyr is None else outputLyr + outputLyr = "memory:" if outputLyr is None else outputLyr parameters = { - 'INPUT' : inputLayer, - 'REFERENCE_LAYER' : referenceLayer, - 'TOLERANCE' : tol, - 'BEHAVIOR' : behavior, - 'OUTPUT' : outputLyr + "INPUT": inputLayer, + "REFERENCE_LAYER": referenceLayer, + "TOLERANCE": tol, + "BEHAVIOR": behavior, + "OUTPUT": outputLyr, } - output = processing.run('qgis:snapgeometries', parameters, context=context, feedback=feedback, is_child_algorithm=is_child_algorithm) - return output['OUTPUT'] + output = processing.run( + "qgis:snapgeometries", + parameters, + context=context, + feedback=feedback, + is_child_algorithm=is_child_algorithm, + ) + return output["OUTPUT"] - def runSnapLayerOnLayer(self, inputLayer, referenceLayer, tol, context, onlySelected=False, feedback=None, behavior=None, buildCache=False, is_child_algorithm=False): + def runSnapLayerOnLayer( + self, + inputLayer, + referenceLayer, + tol, + context, + onlySelected=False, + feedback=None, + behavior=None, + buildCache=False, + is_child_algorithm=False, + ): behavior = 0 if behavior is None else behavior parameters = { - 'INPUT' : inputLayer, - 'SELECTED' : onlySelected, - 'REFERENCE_LAYER' : referenceLayer, - 'TOLERANCE' : tol, - 'BEHAVIOR' : behavior, - 'BUILD_CACHE': buildCache, + "INPUT": inputLayer, + "SELECTED": onlySelected, + "REFERENCE_LAYER": referenceLayer, + "TOLERANCE": tol, + "BEHAVIOR": behavior, + "BUILD_CACHE": buildCache, } - output = processing.run('dsgtools:snaplayeronlayer', parameters, context=context, feedback=feedback, is_child_algorithm=is_child_algorithm) - return output['OUTPUT'] + output = processing.run( + "dsgtools:snaplayeronlayer", + parameters, + context=context, + feedback=feedback, + is_child_algorithm=is_child_algorithm, + ) + return output["OUTPUT"] def runIdentifyDangles( - self, inputLayer, searchRadius, context, feedback=None, onlySelected=False,\ - lineFilter = None, polygonFilter = None, ignoreDanglesOnUnsegmentedLines = False,\ - inputIsBoundaryLayer = False, geographicBoundsLyr = None, flagLyr=None, returnProcessingDict=False - ): - flagLyr = 'memory:' if flagLyr is None else flagLyr + self, + inputLayer, + searchRadius, + context, + feedback=None, + onlySelected=False, + lineFilter=None, + polygonFilter=None, + ignoreDanglesOnUnsegmentedLines=False, + inputIsBoundaryLayer=False, + geographicBoundsLyr=None, + flagLyr=None, + returnProcessingDict=False, + ): + flagLyr = "memory:" if flagLyr is None else flagLyr lineFilter = [] if lineFilter is None else lineFilter polygonFilter = [] if polygonFilter is None else polygonFilter parameters = { - 'INPUT' : inputLayer, - 'SELECTED' : onlySelected, - 'TOLERANCE' : searchRadius, - 'LINEFILTERLAYERS' : lineFilter, - 'POLYGONFILTERLAYERS' : polygonFilter, - 'IGNORE_DANGLES_ON_UNSEGMENTED_LINES' : ignoreDanglesOnUnsegmentedLines, - 'INPUT_IS_BOUDARY_LAYER' : inputIsBoundaryLayer, - 'GEOGRAPHIC_BOUNDARY': geographicBoundsLyr, - 'FLAGS' : flagLyr, + "INPUT": inputLayer, + "SELECTED": onlySelected, + "TOLERANCE": searchRadius, + "LINEFILTERLAYERS": lineFilter, + "POLYGONFILTERLAYERS": polygonFilter, + "IGNORE_DANGLES_ON_UNSEGMENTED_LINES": ignoreDanglesOnUnsegmentedLines, + "INPUT_IS_BOUDARY_LAYER": inputIsBoundaryLayer, + "GEOGRAPHIC_BOUNDARY": geographicBoundsLyr, + "FLAGS": flagLyr, } - output = processing.run('dsgtools:identifydangles', parameters, context=context, feedback=feedback) - return output if returnProcessingDict else output['FLAGS'] - + output = processing.run( + "dsgtools:identifydangles", parameters, context=context, feedback=feedback + ) + return output if returnProcessingDict else output["FLAGS"] + def runSnapToGrid(self, inputLayer, tol, context, feedback=None, outputLyr=None): - outputLyr = 'memory:' if outputLyr is None else outputLyr + outputLyr = "memory:" if outputLyr is None else outputLyr parameters = { - 'INPUT':inputLayer, - 'HSPACING':tol, - 'VSPACING':tol, - 'ZSPACING':0, - 'MSPACING':0, - 'OUTPUT':outputLyr + "INPUT": inputLayer, + "HSPACING": tol, + "VSPACING": tol, + "ZSPACING": 0, + "MSPACING": 0, + "OUTPUT": outputLyr, } - output = processing.run("native:snappointstogrid", parameters, context=context, feedback=feedback) - return output['OUTPUT'] - + output = processing.run( + "native:snappointstogrid", parameters, context=context, feedback=feedback + ) + return output["OUTPUT"] + def runRemoveNull(self, inputLayer, context, feedback=None, outputLyr=None): - outputLyr = 'memory:' if outputLyr is None else outputLyr - parameters = { - 'INPUT':inputLayer, - 'OUTPUT':outputLyr - } - output = processing.run("native:removenullgeometries", parameters, context=context, feedback=feedback) - return output['OUTPUT'] - - def runClip(self, inputLayer, overlayLayer, context, feedback=None, outputLyr=None): - outputLyr = 'memory:' if outputLyr is None else outputLyr - parameters = { - 'INPUT' : inputLayer, - 'OVERLAY' : overlayLayer, - 'OUTPUT' : outputLyr - } - output = processing.run("native:clip", parameters, context=context, feedback=feedback) - return output['OUTPUT'] - - def runSymDiff(self, inputLayer, overlayLayer, context, feedback=None, outputLyr=None): - outputLyr = 'memory:' if outputLyr is None else outputLyr - parameters = { - 'INPUT' : inputLayer, - 'OVERLAY' : overlayLayer, - 'OUTPUT' : outputLyr - } - output = processing.run("native:symmetricaldifference", parameters, context=context, feedback=feedback) - return output['OUTPUT'] - + outputLyr = "memory:" if outputLyr is None else outputLyr + parameters = {"INPUT": inputLayer, "OUTPUT": outputLyr} + output = processing.run( + "native:removenullgeometries", + parameters, + context=context, + feedback=feedback, + ) + return output["OUTPUT"] + + def runClip( + self, + inputLayer, + overlayLayer, + context, + feedback=None, + outputLyr=None, + is_child_algorithm=False, + ): + outputLyr = "memory:" if outputLyr is None else outputLyr + parameters = {"INPUT": inputLayer, "OVERLAY": overlayLayer, "OUTPUT": outputLyr} + output = processing.run( + "native:clip", + parameters, + context=context, + feedback=feedback, + is_child_algorithm=is_child_algorithm, + ) + return output["OUTPUT"] + + def runSymDiff( + self, inputLayer, overlayLayer, context, feedback=None, outputLyr=None + ): + outputLyr = "memory:" if outputLyr is None else outputLyr + parameters = {"INPUT": inputLayer, "OVERLAY": overlayLayer, "OUTPUT": outputLyr} + output = processing.run( + "native:symmetricaldifference", + parameters, + context=context, + feedback=feedback, + ) + return output["OUTPUT"] + def runBoundary(self, inputLayer, context, feedback=None, outputLyr=None): - outputLyr = 'memory:' if outputLyr is None else outputLyr - parameters = { - 'INPUT' : inputLayer, - 'OUTPUT' : outputLyr - } - output = processing.run("native:boundary", parameters, context=context, feedback=feedback) - return output['OUTPUT'] - - def runMultipartToSingleParts(self, inputLayer, context, feedback=None, outputLyr=None, is_child_algorithm=False): - outputLyr = 'memory:' if outputLyr is None else outputLyr - parameters = { - 'INPUT' : inputLayer, - 'OUTPUT' : outputLyr - } + outputLyr = "memory:" if outputLyr is None else outputLyr + parameters = {"INPUT": inputLayer, "OUTPUT": outputLyr} + output = processing.run( + "native:boundary", parameters, context=context, feedback=feedback + ) + return output["OUTPUT"] + + def runMultipartToSingleParts( + self, + inputLayer, + context, + feedback=None, + outputLyr=None, + is_child_algorithm=False, + ): + outputLyr = "memory:" if outputLyr is None else outputLyr + parameters = {"INPUT": inputLayer, "OUTPUT": outputLyr} output = processing.run( "native:multiparttosingleparts", parameters, context=context, feedback=feedback, - is_child_algorithm=is_child_algorithm + is_child_algorithm=is_child_algorithm, ) - return output['OUTPUT'] + return output["OUTPUT"] - def runBuffer(self, inputLayer, distance, context, dissolve=False, endCapStyle=None, joinStyle=None,\ - segments=None, mitterLimit=None, feedback=None, outputLyr=None): + def runBuffer( + self, + inputLayer, + distance, + context, + dissolve=False, + endCapStyle=None, + joinStyle=None, + segments=None, + mitterLimit=None, + feedback=None, + outputLyr=None, + is_child_algorithm=False, + ): endCapStyle = 0 if endCapStyle is None else endCapStyle joinStyle = 0 if joinStyle is None else joinStyle segments = 5 if segments is None else segments mitterLimit = 2 if mitterLimit is None else mitterLimit - outputLyr = 'memory:' if outputLyr is None else outputLyr + outputLyr = "memory:" if outputLyr is None else outputLyr parameters = { - 'INPUT' : inputLayer, - 'DISTANCE' : distance, - 'DISSOLVE' : dissolve, - 'END_CAP_STYLE' : endCapStyle, - 'JOIN_STYLE' : endCapStyle, - 'SEGMENTS' : segments, - 'MITER_LIMIT' : mitterLimit, - 'OUTPUT' : outputLyr + "INPUT": inputLayer, + "DISTANCE": distance, + "DISSOLVE": dissolve, + "END_CAP_STYLE": endCapStyle, + "JOIN_STYLE": endCapStyle, + "SEGMENTS": segments, + "MITER_LIMIT": mitterLimit, + "OUTPUT": outputLyr, } - output = processing.run("native:buffer", parameters, context=context, feedback=feedback) - return output['OUTPUT'] - - def runIntersection(self, inputLyr, context, inputFields=None, outputLyr=None, overlayLyr=None, overlayFields=None, feedback=None): - outputLyr = 'memory:' if outputLyr is None else outputLyr + output = processing.run( + "native:buffer", + parameters, + context=context, + feedback=feedback, + is_child_algorithm=is_child_algorithm, + ) + return output["OUTPUT"] + + def runIntersection( + self, + inputLyr, + context, + inputFields=None, + outputLyr=None, + overlayLyr=None, + overlayFields=None, + feedback=None, + ): + outputLyr = "memory:" if outputLyr is None else outputLyr inputFields = [] if inputFields is None else inputFields overlayFields = [] if overlayFields is None else overlayFields - parameters = { - 'INPUT' : inputLyr, - 'INPUT_FIELDS' : inputFields, - 'OUTPUT' : outputLyr, - 'OVERLAY' : overlayLyr, - 'OVERLAY_FIELDS' : overlayFields - } - output = processing.run("native:intersection", parameters, context=context, feedback=feedback) - return output['OUTPUT'] - - def runFilterExpression(self, inputLyr, expression, context, outputLyr=None, feedback=None): - outputLyr = 'memory:' if outputLyr is None else outputLyr - parameters = { - 'EXPRESSION' : expression, - 'INPUT' : inputLyr, - 'OUTPUT' : outputLyr - } - output = processing.run("native:extractbyexpression", parameters, context=context, feedback=feedback) - return output['OUTPUT'] - - def runRemoveDuplicatedFeatures(self, inputLyr, context, onlySelected=False, attributeBlackList=None, excludePrimaryKeys=True, ignoreVirtualFields=True, feedback=None, outputLyr=None): - outputLyr = 'memory:' if outputLyr is None else outputLyr - attributeBlackList = [] if attributeBlackList is None else attributeBlackList - parameters = { - 'INPUT' : inputLyr, - 'SELECTED' : onlySelected, - 'FLAGS': flagLyr, - 'ATTRIBUTE_BLACK_LIST' : attributeBlackList, - 'IGNORE_VIRTUAL_FIELDS' : ignoreVirtualFields, - 'IGNORE_PK_FIELDS' : excludePrimaryKeys, - 'OUTPUT' : outputLyr - } - output = processing.run('dsgtools:removeduplicatedfeatures', parameters, context=context, feedback=feedback) - return output['OUTPUT'] - - def runApplStylesFromDatabaseToLayers(self, inputList, context, styleName, feedback=None, outputLyr=None): - outputLyr = 'memory:' if outputLyr is None else outputLyr parameters = { - 'INPUT_LAYERS' : inputList, - 'STYLE_NAME' : styleName, - 'OUTPUT' : outputLyr + "INPUT": inputLyr, + "INPUT_FIELDS": inputFields, + "OUTPUT": outputLyr, + "OVERLAY": overlayLyr, + "OVERLAY_FIELDS": overlayFields, } - output = processing.run('dsgtools:applystylesfromdatabasetolayersalgorithm', parameters, context=context, feedback=feedback) - return output['OUTPUT'] - - def runMatchAndApplyQmlStylesToLayer(self, inputList, context, qmlFolder, feedback=None, outputLyr=None): - outputLyr = 'memory:' if outputLyr is None else outputLyr - parameters = { - 'INPUT_LAYERS' : inputList, - 'QML_FOLDER' : qmlFolder, - 'OUTPUT' : outputLyr - } - output = processing.run('dsgtools:matchandapplyqmlstylestolayersalgorithm', parameters, context=context, feedback=feedback) - return output['OUTPUT'] - - def runAddAutoIncrementalField(self, inputLyr, context, feedback=None, outputLyr=None, fieldName=None, start=1, sortAscending=True, sortNullsFirst=False, is_child_algorithm=False): - fieldName = 'featid' if fieldName is None else fieldName - outputLyr = 'memory:' if outputLyr is None else outputLyr + output = processing.run( + "native:intersection", parameters, context=context, feedback=feedback + ) + return output["OUTPUT"] + + def runFilterExpression( + self, inputLyr, expression, context, outputLyr=None, feedback=None + ): + outputLyr = "memory:" if outputLyr is None else outputLyr + parameters = {"EXPRESSION": expression, "INPUT": inputLyr, "OUTPUT": outputLyr} + output = processing.run( + "native:extractbyexpression", parameters, context=context, feedback=feedback + ) + return output["OUTPUT"] + + def runRemoveDuplicatedFeatures( + self, + inputLyr, + context, + onlySelected=False, + attributeBlackList=None, + excludePrimaryKeys=True, + ignoreVirtualFields=True, + feedback=None, + outputLyr=None, + ): + outputLyr = "memory:" if outputLyr is None else outputLyr + attributeBlackList = [] if attributeBlackList is None else attributeBlackList parameters = { - 'INPUT' : inputLyr, - 'FIELD_NAME' : fieldName, - 'START': start, - 'GROUP_FIELDS': [], - 'SORT_EXPRESSION': '', - 'SORT_ASCENDING': sortAscending, - 'SORT_NULLS_FIRST': sortNullsFirst, - 'OUTPUT': outputLyr, + "INPUT": inputLyr, + "SELECTED": onlySelected, + "FLAGS": flagLyr, + "ATTRIBUTE_BLACK_LIST": attributeBlackList, + "IGNORE_VIRTUAL_FIELDS": ignoreVirtualFields, + "IGNORE_PK_FIELDS": excludePrimaryKeys, + "OUTPUT": outputLyr, } output = processing.run( - 'native:addautoincrementalfield', + "dsgtools:removeduplicatedfeatures", parameters, context=context, feedback=feedback, - is_child_algorithm=is_child_algorithm ) - return output['OUTPUT'] - - def runPolygonsToLines(self, inputLyr, context, feedback=None, outputLyr=None, is_child_algorithm=False): - outputLyr = 'memory:' if outputLyr is None else outputLyr + return output["OUTPUT"] + + def runApplStylesFromDatabaseToLayers( + self, inputList, context, styleName, feedback=None, outputLyr=None + ): + outputLyr = "memory:" if outputLyr is None else outputLyr parameters = { - 'INPUT':inputLyr, - 'OUTPUT' : outputLyr + "INPUT_LAYERS": inputList, + "STYLE_NAME": styleName, + "OUTPUT": outputLyr, } output = processing.run( - 'native:polygonstolines' if Qgis.QGIS_VERSION_INT >= 30600 \ - else 'qgis:polygonstolines', + "dsgtools:applystylesfromdatabasetolayersalgorithm", parameters, context=context, feedback=feedback, - is_child_algorithm=is_child_algorithm ) - return output['OUTPUT'] + return output["OUTPUT"] - def runExtractVertices(self, inputLyr, context, feedback=None, outputLyr=None): - outputLyr = 'memory:' if outputLyr is None else outputLyr + def runMatchAndApplyQmlStylesToLayer( + self, inputList, context, qmlFolder, feedback=None, outputLyr=None + ): + outputLyr = "memory:" if outputLyr is None else outputLyr parameters = { - 'INPUT' : inputLyr, - 'OUTPUT' : outputLyr + "INPUT_LAYERS": inputList, + "QML_FOLDER": qmlFolder, + "OUTPUT": outputLyr, } output = processing.run( - 'native:extractvertices', + "dsgtools:matchandapplyqmlstylestolayersalgorithm", parameters, context=context, - feedback=feedback + feedback=feedback, ) - return output['OUTPUT'] - - def runExplodeLines(self, inputLyr, context, feedback=None, outputLyr=None, is_child_algorithm=False): - outputLyr = 'memory:' if outputLyr is None else outputLyr + return output["OUTPUT"] + + def runAddAutoIncrementalField( + self, + inputLyr, + context, + feedback=None, + outputLyr=None, + fieldName=None, + start=1, + sortAscending=True, + sortNullsFirst=False, + is_child_algorithm=False, + ): + fieldName = "featid" if fieldName is None else fieldName + outputLyr = "memory:" if outputLyr is None else outputLyr parameters = { - 'INPUT' : inputLyr, - 'OUTPUT' : outputLyr + "INPUT": inputLyr, + "FIELD_NAME": fieldName, + "START": start, + "GROUP_FIELDS": [], + "SORT_EXPRESSION": "", + "SORT_ASCENDING": sortAscending, + "SORT_NULLS_FIRST": sortNullsFirst, + "OUTPUT": outputLyr, } output = processing.run( - 'native:explodelines', + "native:addautoincrementalfield", parameters, context=context, feedback=feedback, - is_child_algorithm=is_child_algorithm + is_child_algorithm=is_child_algorithm, ) - return output['OUTPUT'] - - def runMergeVectorLayers(self, inputList, context, feedback=None, outputLyr=None, crs=None): - outputLyr = 'memory:' if outputLyr is None else outputLyr - parameters = { - 'LAYERS' : inputList, - 'CRS' : crs, - 'OUTPUT' : outputLyr - } + return output["OUTPUT"] + + def runPolygonsToLines( + self, inputLyr, context, feedback=None, outputLyr=None, is_child_algorithm=False + ): + outputLyr = "memory:" if outputLyr is None else outputLyr + parameters = {"INPUT": inputLyr, "OUTPUT": outputLyr} + output = processing.run( + "native:polygonstolines" + if Qgis.QGIS_VERSION_INT >= 30600 + else "qgis:polygonstolines", + parameters, + context=context, + feedback=feedback, + is_child_algorithm=is_child_algorithm, + ) + return output["OUTPUT"] + + def runExtractVertices(self, inputLyr, context, feedback=None, outputLyr=None): + outputLyr = "memory:" if outputLyr is None else outputLyr + parameters = {"INPUT": inputLyr, "OUTPUT": outputLyr} + output = processing.run( + "native:extractvertices", parameters, context=context, feedback=feedback + ) + return output["OUTPUT"] + + def runExplodeLines( + self, inputLyr, context, feedback=None, outputLyr=None, is_child_algorithm=False + ): + outputLyr = "memory:" if outputLyr is None else outputLyr + parameters = {"INPUT": inputLyr, "OUTPUT": outputLyr} output = processing.run( - 'native:mergevectorlayers', + "native:explodelines", parameters, context=context, - feedback=feedback + feedback=feedback, + is_child_algorithm=is_child_algorithm, ) - return output['OUTPUT'] - + return output["OUTPUT"] + + def runMergeVectorLayers( + self, inputList, context, feedback=None, outputLyr=None, crs=None + ): + outputLyr = "memory:" if outputLyr is None else outputLyr + parameters = {"LAYERS": inputList, "CRS": crs, "OUTPUT": outputLyr} + output = processing.run( + "native:mergevectorlayers", parameters, context=context, feedback=feedback + ) + return output["OUTPUT"] + def runSaveSelectedFeatures(self, inputLyr, context, feedback=None, outputLyr=None): - outputLyr = 'memory:' if outputLyr is None else outputLyr - parameters = { - 'LAYERS' : inputLyr, - 'OUTPUT' : outputLyr - } + outputLyr = "memory:" if outputLyr is None else outputLyr + parameters = {"INPUT": inputLyr, "OUTPUT": outputLyr} output = processing.run( "native:saveselectedfeatures", parameters, context=context, - feedback=feedback + feedback=feedback, ) - return output['OUTPUT'] + return output["OUTPUT"] def runReprojectLayer(self, layer, targetCrs, output=None, ctx=None, feedback=None): """ @@ -567,302 +819,375 @@ def runReprojectLayer(self, layer, targetCrs, output=None, ctx=None, feedback=No """ return processing.run( "native:reprojectlayer", - { - 'INPUT' : layer, - 'OUTPUT' : output or 'memory:', - 'TARGET_CRS' : targetCrs - }, + {"INPUT": layer, "OUTPUT": output or "memory:", "TARGET_CRS": targetCrs}, context=ctx, - feedback=feedback - )['OUTPUT'] + feedback=feedback, + )["OUTPUT"] - def runPointOnSurface(self, inputLyr, context, allParts=True, feedback=None, outputLyr=None, onlySelected=False): - outputLyr = 'memory:' if outputLyr is None else outputLyr - parameters = { - 'INPUT' : inputLyr, - 'ALL_PARTS' : allParts, - 'OUTPUT' : outputLyr - } + def runPointOnSurface( + self, + inputLyr, + context, + allParts=True, + feedback=None, + outputLyr=None, + onlySelected=False, + ): + outputLyr = "memory:" if outputLyr is None else outputLyr + parameters = {"INPUT": inputLyr, "ALL_PARTS": allParts, "OUTPUT": outputLyr} output = processing.run( - "native:pointonsurface", - parameters, - context=context, - feedback=feedback + "native:pointonsurface", parameters, context=context, feedback=feedback ) - return output['OUTPUT'] - - def runRemoveDuplicatedGeometries(self, inputLyr, context, feedback=None, outputLyr=None, onlySelected=False): - outputLyr = 'memory:' if outputLyr is None else outputLyr + return output["OUTPUT"] + + def runRemoveDuplicatedGeometries( + self, inputLyr, context, feedback=None, outputLyr=None, onlySelected=False + ): + outputLyr = "memory:" if outputLyr is None else outputLyr parameters = { - 'INPUT' : inputLyr, - 'SELECTED' : onlySelected, - 'FLAGS' : 'memory:', - 'OUTPUT' : outputLyr + "INPUT": inputLyr, + "SELECTED": onlySelected, + "FLAGS": "memory:", + "OUTPUT": outputLyr, } output = processing.run( "dsgtools:removeduplicatedgeometries", parameters, context=context, - feedback=feedback + feedback=feedback, ) - return output['OUTPUT'] - - def runPolygonize(self, inputLyr, context, keepFields=False, feedback=None, outputLyr=None, onlySelected=False): - outputLyr = 'memory:' if outputLyr is None else outputLyr - parameters = { - 'INPUT' : inputLyr, - 'KEEP_FIELDS' : keepFields, - 'OUTPUT' : outputLyr - } + return output["OUTPUT"] + + def runPolygonize( + self, + inputLyr, + context, + keepFields=False, + feedback=None, + outputLyr=None, + onlySelected=False, + ): + outputLyr = "memory:" if outputLyr is None else outputLyr + parameters = {"INPUT": inputLyr, "KEEP_FIELDS": keepFields, "OUTPUT": outputLyr} output = processing.run( - "qgis:polygonize", - parameters, - context=context, - feedback=feedback + "qgis:polygonize", parameters, context=context, feedback=feedback ) - return output['OUTPUT'] - - def runJoinAttributesByLocation(self, inputLyr, joinLyr, context, predicateList=None, joinFields=None,\ - method=None, discardNonMatching=True, feedback=None, outputLyr=None, unjoinnedLyr=None): + return output["OUTPUT"] + + def runJoinAttributesByLocation( + self, + inputLyr, + joinLyr, + context, + predicateList=None, + joinFields=None, + method=None, + discardNonMatching=True, + feedback=None, + outputLyr=None, + unjoinnedLyr=None, + ): predicateList = [0] if predicateList is None else predicateList joinFields = [] if joinFields is None else joinFields method = 0 if method is None else method - outputLyr = 'memory:' if outputLyr is None else outputLyr + outputLyr = "memory:" if outputLyr is None else outputLyr parameters = { - 'INPUT' : inputLyr, - 'JOIN' : joinLyr, - 'PREDICATE' : predicateList, - 'JOIN_FIELDS' : joinFields, - 'METHOD' : method, - 'DISCARD_NONMATCHING' : discardNonMatching, - 'PREFIX' : '', - 'OUTPUT' : outputLyr + "INPUT": inputLyr, + "JOIN": joinLyr, + "PREDICATE": predicateList, + "JOIN_FIELDS": joinFields, + "METHOD": method, + "DISCARD_NONMATCHING": discardNonMatching, + "PREFIX": "", + "OUTPUT": outputLyr, } output = processing.run( "qgis:joinattributesbylocation", parameters, context=context, - feedback=feedback + feedback=feedback, ) - return output['OUTPUT'] - - def runLineIntersections(self, inputLyr, intersectLyr, context, feedback=None, outputLyr=None): - outputLyr = 'memory:' if outputLyr is None else outputLyr + return output["OUTPUT"] + + def runLineIntersections( + self, inputLyr, intersectLyr, context, feedback=None, outputLyr=None + ): + outputLyr = "memory:" if outputLyr is None else outputLyr parameters = { - 'INPUT' : inputLyr, - 'INTERSECT' : intersectLyr, - 'INPUT_FIELDS' : [], - 'INTERSECT_FIELDS' : [], - 'OUTPUT' : outputLyr + "INPUT": inputLyr, + "INTERSECT": intersectLyr, + "INPUT_FIELDS": [], + "INTERSECT_FIELDS": [], + "OUTPUT": outputLyr, } output = processing.run( - "native:lineintersections", - parameters, - context=context, - feedback=feedback + "native:lineintersections", parameters, context=context, feedback=feedback ) - return output['OUTPUT'] + return output["OUTPUT"] - def runSplitLinesWithLines(self, inputLyr, linesLyr, context, feedback=None, onlySelected=False, outputLyr=None): - usedInput = inputLyr if not onlySelected else \ - QgsProcessingFeatureSourceDefinition(inputLyr.id(), True) - usedLines = linesLyr if not onlySelected else \ - QgsProcessingFeatureSourceDefinition(linesLyr.id(), True) - outputLyr = 'memory:' if outputLyr is None else outputLyr - parameters = { - 'INPUT' : usedInput, - 'LINES' : usedLines, - 'OUTPUT' : outputLyr - } + def runSplitLinesWithLines( + self, + inputLyr, + linesLyr, + context, + feedback=None, + onlySelected=False, + outputLyr=None, + ): + usedInput = ( + inputLyr + if not onlySelected + else QgsProcessingFeatureSourceDefinition(inputLyr.id(), True) + ) + usedLines = ( + linesLyr + if not onlySelected + else QgsProcessingFeatureSourceDefinition(linesLyr.id(), True) + ) + outputLyr = "memory:" if outputLyr is None else outputLyr + parameters = {"INPUT": usedInput, "LINES": usedLines, "OUTPUT": outputLyr} output = processing.run( - "native:splitwithlines", - parameters, - context=context, - feedback=feedback + "native:splitwithlines", parameters, context=context, feedback=feedback ) - return output['OUTPUT'] - - def runAggregate(self, inputLyr, context, groupBy=None, aggregates=None, \ - feedback=None, outputLyr=None, onlySelected=False): - groupBy = 'NULL' if groupBy is None else groupBy + return output["OUTPUT"] + + def runAggregate( + self, + inputLyr, + context, + groupBy=None, + aggregates=None, + feedback=None, + outputLyr=None, + onlySelected=False, + ): + groupBy = "NULL" if groupBy is None else groupBy aggregates = [] if aggregates is None else aggregates - outputLyr = 'memory:' if outputLyr is None else outputLyr + outputLyr = "memory:" if outputLyr is None else outputLyr parameters = { - 'INPUT' : inputLyr, - 'GROUP_BY' : groupBy, - 'AGGREGATES' : aggregates, - 'OUTPUT' : outputLyr + "INPUT": inputLyr, + "GROUP_BY": groupBy, + "AGGREGATES": aggregates, + "OUTPUT": outputLyr, } output = processing.run( - "qgis:aggregate", - parameters, - context=context, - feedback=feedback + "qgis:aggregate", parameters, context=context, feedback=feedback ) - return output['OUTPUT'] - + return output["OUTPUT"] + def runDeaggregate(self, inputLyr, context, feedback=None, onlySelected=False): - parameters = { - 'INPUT': inputLyr, - 'SELECTED': onlySelected - } + parameters = {"INPUT": inputLyr, "SELECTED": onlySelected} output = processing.run( "dsgtools:deaggregategeometries", parameters, context=context, - feedback=feedback + feedback=feedback, ) return output - def runCreateSpatialIndex(self, inputLyr, context, feedback=None, is_child_algorithm=False): + def runCreateSpatialIndex( + self, inputLyr, context, feedback=None, is_child_algorithm=False + ): processing.run( "native:createspatialindex", - {'INPUT':inputLyr}, + {"INPUT": inputLyr}, feedback=feedback, context=context, - is_child_algorithm=is_child_algorithm + is_child_algorithm=is_child_algorithm, ) return None - - def runExtractByLocation(self, inputLyr, intersectLyr, context, predicate=None, feedback=None, outputLyr=None, is_child_algorithm=False): + + def runExtractByLocation( + self, + inputLyr, + intersectLyr, + context, + predicate=None, + feedback=None, + outputLyr=None, + is_child_algorithm=False, + ): predicate = [0] if predicate is None else predicate - outputLyr = 'memory:' if outputLyr is None else outputLyr + outputLyr = "memory:" if outputLyr is None else outputLyr output = processing.run( "native:extractbylocation", { - 'INPUT': inputLyr, - 'INTERSECT': intersectLyr, - 'PREDICATE': predicate, - 'OUTPUT': outputLyr + "INPUT": inputLyr, + "INTERSECT": intersectLyr, + "PREDICATE": predicate, + "OUTPUT": outputLyr, }, context=context, feedback=feedback, - is_child_algorithm=is_child_algorithm + is_child_algorithm=is_child_algorithm, ) - return output['OUTPUT'] + return output["OUTPUT"] - def runCreateFieldWithExpression(self, inputLyr, expression, fieldName, context, fieldType=0, fieldLength=1000, fieldPrecision=0, feedback=None, outputLyr=None): - outputLyr = 'memory:' if outputLyr is None else outputLyr + def runCreateFieldWithExpression( + self, + inputLyr, + expression, + fieldName, + context, + fieldType=0, + fieldLength=1000, + fieldPrecision=0, + feedback=None, + outputLyr=None, + is_child_algorithm=False, + ): + outputLyr = "memory:" if outputLyr is None else outputLyr output = processing.run( "native:fieldcalculator", { - 'INPUT': inputLyr, - 'FIELD_NAME': fieldName, - 'FIELD_TYPE': fieldType, - 'FIELD_LENGTH': fieldLength, - 'FORMULA': expression, - 'OUTPUT': outputLyr, + "INPUT": inputLyr, + "FIELD_NAME": fieldName, + "FIELD_TYPE": fieldType, + "FIELD_LENGTH": fieldLength, + "FORMULA": expression, + "OUTPUT": outputLyr, }, context=context, - feedback=feedback + feedback=feedback, + is_child_algorithm=is_child_algorithm, ) - return output['OUTPUT'] + return output["OUTPUT"] def runStringCsvToLayerList(self, stringCSV, context, feedback=None): output = processing.run( "dsgtools:stringcsvtolayerlistalgorithm", - { - 'INPUTLAYERS': stringCSV, - 'OUTPUT': 'memory:' - }, + {"INPUTLAYERS": stringCSV, "OUTPUT": "memory:"}, context=context, - feedback=feedback + feedback=feedback, ) - return output['OUTPUT'] + return output["OUTPUT"] - def runClipRasterLayer(self, inputRaster, mask, context, feedback=None, outputRaster=None, noData=None): - outputRaster = 'TEMPORARY_OUTPUT' if outputRaster is None else outputRaster + def runClipRasterLayer( + self, inputRaster, mask, context, feedback=None, outputRaster=None, noData=None + ): + outputRaster = "TEMPORARY_OUTPUT" if outputRaster is None else outputRaster output = processing.run( "gdal:cliprasterbymasklayer", { - 'INPUT': inputRaster, - 'MASK': mask, - 'SOURCE_CRS': None, - 'TARGET_CRS': None, - 'TARGET_EXTENT': None, - 'NODATA': noData, - 'ALPHA_BAND': False, - 'CROP_TO_CUTLINE': True, - 'KEEP_RESOLUTION': False, - 'SET_RESOLUTION': False, - 'X_RESOLUTION': None, - 'Y_RESOLUTION': None, - 'MULTITHREADING': False, - 'OPTIONS': '', - 'DATA_TYPE': 0, - 'EXTRA': '', - 'OUTPUT': outputRaster + "INPUT": inputRaster, + "MASK": mask, + "SOURCE_CRS": None, + "TARGET_CRS": None, + "TARGET_EXTENT": None, + "NODATA": noData, + "ALPHA_BAND": False, + "CROP_TO_CUTLINE": True, + "KEEP_RESOLUTION": False, + "SET_RESOLUTION": False, + "X_RESOLUTION": None, + "Y_RESOLUTION": None, + "MULTITHREADING": False, + "OPTIONS": "", + "DATA_TYPE": 0, + "EXTRA": "", + "OUTPUT": outputRaster, }, # context=context, - feedback=feedback + feedback=feedback, ) - return output['OUTPUT'] + return output["OUTPUT"] - def runGrassMapCalcSimple(self, inputA, expression, context, feedback=None, inputB=None, inputC=None, inputD=None, inputE=None, inputF=None, outputRaster=None): - outputRaster = 'TEMPORARY_OUTPUT' if outputRaster is None else outputRaster + def runGrassMapCalcSimple( + self, + inputA, + expression, + context, + feedback=None, + inputB=None, + inputC=None, + inputD=None, + inputE=None, + inputF=None, + outputRaster=None, + ): + outputRaster = "TEMPORARY_OUTPUT" if outputRaster is None else outputRaster output = processing.run( "grass7:r.mapcalc.simple", { - 'a': inputA, - 'b': inputB, - 'c': inputC, - 'd': inputD, - 'e': inputE, - 'f': inputF, - 'expression': expression, - 'output': outputRaster, - 'GRASS_REGION_PARAMETER': None, - 'GRASS_REGION_CELLSIZE_PARAMETER': 0, - 'GRASS_RASTER_FORMAT_OPT': '', - 'GRASS_RASTER_FORMAT_META': '' + "a": inputA, + "b": inputB, + "c": inputC, + "d": inputD, + "e": inputE, + "f": inputF, + "expression": expression, + "output": outputRaster, + "GRASS_REGION_PARAMETER": None, + "GRASS_REGION_CELLSIZE_PARAMETER": 0, + "GRASS_RASTER_FORMAT_OPT": "", + "GRASS_RASTER_FORMAT_META": "", }, context=context, - feedback=feedback + feedback=feedback, ) - return output['output'] + return output["output"] - def runGrassReclass(self, inputRaster, expression, context, feedback=None, outputRaster=None): - outputRaster = 'TEMPORARY_OUTPUT' if outputRaster is None else outputRaster + def runGrassReclass( + self, inputRaster, expression, context, feedback=None, outputRaster=None + ): + outputRaster = "TEMPORARY_OUTPUT" if outputRaster is None else outputRaster output = processing.run( "grass7:r.reclass", { - 'input': inputRaster, - 'rules': '', - 'txtrules': expression, - 'output': outputRaster, - 'GRASS_REGION_PARAMETER': None, - 'GRASS_REGION_CELLSIZE_PARAMETER': 0, - 'GRASS_RASTER_FORMAT_OPT': '', - 'GRASS_RASTER_FORMAT_META': '' + "input": inputRaster, + "rules": "", + "txtrules": expression, + "output": outputRaster, + "GRASS_REGION_PARAMETER": None, + "GRASS_REGION_CELLSIZE_PARAMETER": 0, + "GRASS_RASTER_FORMAT_OPT": "", + "GRASS_RASTER_FORMAT_META": "", }, context=context, - feedback=feedback + feedback=feedback, ) - return output['output'] + return output["output"] - def runSieve(self, inputRaster, threshold, context, eightConectedness=False, feedback=None, outputRaster=None): - outputRaster = 'TEMPORARY_OUTPUT' if outputRaster is None else outputRaster + def runSieve( + self, + inputRaster, + threshold, + context, + eightConectedness=False, + feedback=None, + outputRaster=None, + ): + outputRaster = "TEMPORARY_OUTPUT" if outputRaster is None else outputRaster output = processing.run( "gdal:sieve", { - 'INPUT': inputRaster, - 'THRESHOLD': threshold, - 'EIGHT_CONNECTEDNESS': eightConectedness, - 'NO_MASK': False, - 'MASK_LAYER': None, - 'EXTRA': '', - 'OUTPUT': outputRaster + "INPUT": inputRaster, + "THRESHOLD": threshold, + "EIGHT_CONNECTEDNESS": eightConectedness, + "NO_MASK": False, + "MASK_LAYER": None, + "EXTRA": "", + "OUTPUT": outputRaster, }, context=context, - feedback=feedback + feedback=feedback, ) - return output['OUTPUT'] - + return output["OUTPUT"] - def runChaikenSmoothing(self, inputLyr, threshold, context, - feedback=None, snap=None, minArea=None, - iterations=None, type=None, returnError=False, - flags=None, is_child_algorithm=False): + def runChaikenSmoothing( + self, + inputLyr, + threshold, + context, + feedback=None, + snap=None, + minArea=None, + iterations=None, + type=None, + returnError=False, + flags=None, + is_child_algorithm=False, + ): """ Runs simplify GRASS algorithm :param inputLyr: (QgsVectorLayer) layer, or layers, to be dissolved. @@ -881,137 +1206,295 @@ def runChaikenSmoothing(self, inputLyr, threshold, context, snap = -1 if snap is None else snap minArea = 0.0001 if minArea is None else minArea iterations = 1 if iterations is None else iterations - flags = 'memory:' if flags is None else flags + flags = "memory:" if flags is None else flags algType = [0, 1, 2] if type is None else type output, error = self.generateGrassOutputAndError() parameters = { - 'input': inputLyr, - 'type':algType, - 'cats':'', - 'where':'', - 'method':8, - 'threshold':threshold, - 'look_ahead':7, - 'reduction':50, - 'slide':0.5, - 'angle_thresh':3, - 'degree_thresh':0, - 'closeness_thresh':0, - 'betweeness_thresh':0, - 'alpha':1, - 'beta':1, - 'iterations':iterations, - '-t':False, - '-l':True, - 'output':output, - 'error':error, - 'GRASS_REGION_PARAMETER':None, - 'GRASS_SNAP_TOLERANCE_PARAMETER':snap, - 'GRASS_MIN_AREA_PARAMETER':minArea, - 'GRASS_OUTPUT_TYPE_PARAMETER':0, - 'GRASS_VECTOR_DSCO':'', - 'GRASS_VECTOR_LCO':''} - outputDict = processing.run("grass7:v.generalize", parameters, - context=context, feedback=feedback, is_child_algorithm=is_child_algorithm) + "input": inputLyr, + "type": algType, + "cats": "", + "where": "", + "method": 8, + "threshold": threshold, + "look_ahead": 7, + "reduction": 50, + "slide": 0.5, + "angle_thresh": 3, + "degree_thresh": 0, + "closeness_thresh": 0, + "betweeness_thresh": 0, + "alpha": 1, + "beta": 1, + "iterations": iterations, + "-t": False, + "-l": True, + "output": output, + "error": error, + "GRASS_REGION_PARAMETER": None, + "GRASS_SNAP_TOLERANCE_PARAMETER": snap, + "GRASS_MIN_AREA_PARAMETER": minArea, + "GRASS_OUTPUT_TYPE_PARAMETER": 0, + "GRASS_VECTOR_DSCO": "", + "GRASS_VECTOR_LCO": "", + } + outputDict = processing.run( + "grass7:v.generalize", + parameters, + context=context, + feedback=feedback, + is_child_algorithm=is_child_algorithm, + ) return self.getGrassReturn(outputDict, context, returnError=returnError) - def runGdalPolygonize(self, inputRaster, context, band=1, field=None, eightConectedness=False, feedback=None, outputLyr=None, is_child_algorithm=False): - outputLyr = 'TEMPORARY_OUTPUT' if outputLyr is None else outputLyr - field = 'DN' if field is None else field + def runGdalPolygonize( + self, + inputRaster, + context, + band=1, + field=None, + eightConectedness=False, + feedback=None, + outputLyr=None, + is_child_algorithm=False, + ): + outputLyr = "TEMPORARY_OUTPUT" if outputLyr is None else outputLyr + field = "DN" if field is None else field output = processing.run( "gdal:polygonize", { - 'INPUT': inputRaster, - 'BAND': band, - 'FIELD': field, - 'EIGHT_CONNECTEDNESS': eightConectedness, - 'EXTRA': '', - 'OUTPUT': outputLyr + "INPUT": inputRaster, + "BAND": band, + "FIELD": field, + "EIGHT_CONNECTEDNESS": eightConectedness, + "EXTRA": "", + "OUTPUT": outputLyr, }, context=context, feedback=feedback, - is_child_algorithm=is_child_algorithm + is_child_algorithm=is_child_algorithm, ) - return output['OUTPUT'] - - def runExtractSpecificVertices(self, inputLyr, vertices, context, feedback=None, outputLyr=None): - outputLyr = 'TEMPORARY_OUTPUT' if outputLyr is None else outputLyr + return output["OUTPUT"] + + def runExtractSpecificVertices( + self, inputLyr, vertices, context, feedback=None, outputLyr=None + ): + outputLyr = "TEMPORARY_OUTPUT" if outputLyr is None else outputLyr output = processing.run( "native:extractspecificvertices", { - 'INPUT': inputLyr, - 'VERTICES': vertices, - 'OUTPUT': outputLyr, + "INPUT": inputLyr, + "VERTICES": vertices, + "OUTPUT": outputLyr, }, context=context, - feedback=feedback + feedback=feedback, ) - return output['OUTPUT'] - - def runCreateGrid(self, extent, crs, hSpacing, vSpacing, context, type=2, feedback=None, outputLyr=None, hOverlay=0, vOverlay=0): - outputLyr = 'memory:' if outputLyr is None else outputLyr + return output["OUTPUT"] + + def runCreateGrid( + self, + extent, + crs, + hSpacing, + vSpacing, + context, + type=2, + feedback=None, + outputLyr=None, + hOverlay=0, + vOverlay=0, + is_child_algorithm=False, + ): + outputLyr = "memory:" if outputLyr is None else outputLyr output = processing.run( "native:creategrid", { - 'TYPE': type, - 'EXTENT': extent, - 'HSPACING': hSpacing, - 'VSPACING': vSpacing, - 'HOVERLAY': hOverlay, - 'VOVERLAY': vOverlay, - 'CRS': crs, - 'OUTPUT': outputLyr + "TYPE": type, + "EXTENT": extent, + "HSPACING": hSpacing, + "VSPACING": vSpacing, + "HOVERLAY": hOverlay, + "VOVERLAY": vOverlay, + "CRS": crs, + "OUTPUT": outputLyr, }, context=context, - feedback=feedback + feedback=feedback, + is_child_algorithm=is_child_algorithm, ) - return output['OUTPUT'] + return output["OUTPUT"] - def runExtendLines(self, inputLyr, startDistance, endDistance, context, feedback=None, outputLyr=None): - outputLyr = 'memory:' if outputLyr is None else outputLyr + def runExtendLines( + self, + inputLyr, + startDistance, + endDistance, + context, + feedback=None, + outputLyr=None, + ): + outputLyr = "memory:" if outputLyr is None else outputLyr output = processing.run( "native:extendlines", { - 'INPUT': inputLyr, - 'START_DISTANCE': startDistance, - 'END_DISTANCE': endDistance, - 'OUTPUT': outputLyr, + "INPUT": inputLyr, + "START_DISTANCE": startDistance, + "END_DISTANCE": endDistance, + "OUTPUT": outputLyr, }, context=context, - feedback=feedback + feedback=feedback, ) - return output['OUTPUT'] + return output["OUTPUT"] - def runIdentifyUnsharedVertexOnIntersectionsAlgorithm(self, pointLayerList, lineLayerList, polygonLayerList, context, onlySelected=False, feedback=None, outputLyr=None, is_child_algorithm=False): - outputLyr = 'memory:' if outputLyr is None else outputLyr + def runIdentifyUnsharedVertexOnIntersectionsAlgorithm( + self, + pointLayerList, + lineLayerList, + polygonLayerList, + context, + onlySelected=False, + feedback=None, + outputLyr=None, + is_child_algorithm=False, + ): + outputLyr = "memory:" if outputLyr is None else outputLyr output = processing.run( "dsgtools:identifyunsharedvertexonintersectionsalgorithm", { - 'INPUT_POINTS': pointLayerList, - 'INPUT_LINES': lineLayerList, - 'INPUT_POLYGONS': polygonLayerList, - 'SELECTED': onlySelected, - 'FLAGS': outputLyr, + "INPUT_POINTS": pointLayerList, + "INPUT_LINES": lineLayerList, + "INPUT_POLYGONS": polygonLayerList, + "SELECTED": onlySelected, + "FLAGS": outputLyr, }, context=context, feedback=feedback, - is_child_algorithm=is_child_algorithm + is_child_algorithm=is_child_algorithm, ) - return output['FLAGS'] - - def runIdentifyUnsharedVertexOnSharedEdgesAlgorithm(self, lineLayerList, polygonLayerList, searchRadius, context, onlySelected=False, feedback=None, outputLyr=None, is_child_algorithm=False): - outputLyr = 'memory:' if outputLyr is None else outputLyr + return output["FLAGS"] + + def runIdentifyUnsharedVertexOnSharedEdgesAlgorithm( + self, + lineLayerList, + polygonLayerList, + searchRadius, + context, + onlySelected=False, + feedback=None, + outputLyr=None, + is_child_algorithm=False, + ): + outputLyr = "memory:" if outputLyr is None else outputLyr output = processing.run( "dsgtools:identifyunsharedvertexonsharededgesalgorithm", { - 'INPUT_LINES': lineLayerList, - 'INPUT_POLYGONS': polygonLayerList, - 'SELECTED': onlySelected, - 'SEARCH_RADIUS': searchRadius, - 'FLAGS': outputLyr, + "INPUT_LINES": lineLayerList, + "INPUT_POLYGONS": polygonLayerList, + "SELECTED": onlySelected, + "SEARCH_RADIUS": searchRadius, + "FLAGS": outputLyr, + }, + context=context, + feedback=feedback, + is_child_algorithm=is_child_algorithm, + ) + return output["FLAGS"] + + def runShortestLine( + self, + sourceLayer, + destinationLayer, + context, + method=0, + neighbors=1, + maxDistance=None, + feedback=None, + outputLyr=None, + is_child_algorithm=False, + ): + outputLyr = "memory:" if outputLyr is None else outputLyr + output = processing.run( + "native:shortestline", + { + "SOURCE": sourceLayer, + "DESTINATION": destinationLayer, + "METHOD": method, + "NEIGHBORS": neighbors, + "DISTANCE": maxDistance, + "OUTPUT": outputLyr, + }, + context=context, + feedback=feedback, + is_child_algorithm=is_child_algorithm, + ) + return output["OUTPUT"] + + def runRetainFields( + self, + inputLayer, + fields, + context, + feedback=None, + outputLyr=None, + is_child_algorithm=False, + ): + outputLyr = "memory:" if outputLyr is None else outputLyr + output = processing.run( + "native:retainfields", + {"INPUT": inputLayer, "FIELDS": fields, "OUTPUT": "TEMPORARY_OUTPUT"}, + context=context, + feedback=feedback, + is_child_algorithm=is_child_algorithm, + ) + return output["OUTPUT"] + + def runExtractByExtent( + self, + inputLayer, + extent, + context, + clip=True, + feedback=None, + outputLyr=None, + is_child_algorithm=False, + ): + outputLyr = "memory:" if outputLyr is None else outputLyr + output = processing.run( + "native:extractbyextent", + { + "INPUT": inputLayer, + "EXTENT": extent, + "CLIP": clip, + "OUTPUT": outputLyr, + }, + context=context, + feedback=feedback, + is_child_algorithm=is_child_algorithm, + ) + return output["OUTPUT"] + + def runSelectByLocation( + self, + inputLyr, + intersectLyr, + context, + predicate=None, + method=None, + feedback=None, + is_child_algorithm=False, + ): + predicate = [0] if predicate is None else predicate + method = [0] if method is None else method + processing.run( + "native:selectbylocation", + { + "INPUT": inputLyr, + "INTERSECT": intersectLyr, + "PREDICATE": predicate, + "METHOD": method, }, context=context, feedback=feedback, - is_child_algorithm=is_child_algorithm + is_child_algorithm=is_child_algorithm, ) - return output['FLAGS'] diff --git a/DsgTools/core/DSGToolsProcessingAlgs/dsgtoolsProcessingAlgorithmProvider.py b/DsgTools/core/DSGToolsProcessingAlgs/dsgtoolsProcessingAlgorithmProvider.py index 953c66d7f..d9bdeffc9 100644 --- a/DsgTools/core/DSGToolsProcessingAlgs/dsgtoolsProcessingAlgorithmProvider.py +++ b/DsgTools/core/DSGToolsProcessingAlgs/dsgtoolsProcessingAlgorithmProvider.py @@ -20,243 +20,399 @@ * * ***************************************************************************/ """ -from DsgTools.core.DSGToolsProcessingAlgs.Algs.EditingAlgs.createEditingGridAlgorithm import \ - CreateEditingGridAlgorithm -from DsgTools.core.DSGToolsProcessingAlgs.Algs.EnvironmentSetterAlgs.setFreeHandToolParametersAlgorithm import \ - SetFreeHandToolParametersAlgorithm -from DsgTools.core.DSGToolsProcessingAlgs.Algs.GeometricAlgs.buildTerrainSlicingFromContoursAlgorihtm import BuildTerrainSlicingFromContoursAlgorihtm -from DsgTools.core.DSGToolsProcessingAlgs.Algs.GeometricAlgs.donutHoleExtractorAlgorithm import \ - DonutHoleExtractorAlgorithm -from DsgTools.core.DSGToolsProcessingAlgs.Algs.LayerManagementAlgs.applyStylesFromDatabaseToLayersAlgorithm import \ - ApplyStylesFromDatabaseToLayersAlgorithm -from DsgTools.core.DSGToolsProcessingAlgs.Algs.LayerManagementAlgs.assignActionsToLayersAlgorithm import \ - AssignActionsToLayersAlgorithm -from DsgTools.core.DSGToolsProcessingAlgs.Algs.LayerManagementAlgs.assignAliasesToLayersAlgorithm import \ - AssignAliasesToLayersAlgorithm -from DsgTools.core.DSGToolsProcessingAlgs.Algs.LayerManagementAlgs.assignBoundingBoxFilterToLayersAlgorithm import \ - AssignBoundingBoxFilterToLayersAlgorithm -from DsgTools.core.DSGToolsProcessingAlgs.Algs.LayerManagementAlgs.assignConditionalStyleToLayersAlgorithm import \ - AssignConditionalStyleToLayersAlgorithm -from DsgTools.core.DSGToolsProcessingAlgs.Algs.LayerManagementAlgs.assignCustomFormAndFormatRulesToLayersAlgorithm import \ - AssignCustomFormAndFormatRulesToLayersAlgorithm -from DsgTools.core.DSGToolsProcessingAlgs.Algs.LayerManagementAlgs.assignDefaultFieldValueToLayersAlgorithm import \ - AssignDefaultFieldValueToLayersAlgorithm -from DsgTools.core.DSGToolsProcessingAlgs.Algs.LayerManagementAlgs.assignExpressionFieldToLayersAlgorithm import \ - AssignExpressionFieldToLayersAlgorithm -from DsgTools.core.DSGToolsProcessingAlgs.Algs.LayerManagementAlgs.assignFilterToLayersAlgorithm import \ - AssignFilterToLayersAlgorithm -from DsgTools.core.DSGToolsProcessingAlgs.Algs.LayerManagementAlgs.assignFormatRulesToLayersAlgorithm import \ - AssignFormatRulesToLayersAlgorithm -from DsgTools.core.DSGToolsProcessingAlgs.Algs.LayerManagementAlgs.detectNullGeometriesAlgorithm import \ - DetectNullGeometriesAlgorithm -from DsgTools.core.DSGToolsProcessingAlgs.Algs.LayerManagementAlgs.assignMeasureColumnToLayersAlgorithm import \ - AssignMeasureColumnToLayersAlgorithm -from DsgTools.core.DSGToolsProcessingAlgs.Algs.LayerManagementAlgs.lockAttributeEditingAlgorithm import \ - LockAttributeEditingAlgorithm -from DsgTools.core.DSGToolsProcessingAlgs.Algs.LayerManagementAlgs.assignValueMapToLayersAlgorithm import \ - AssignValueMapToLayersAlgorithm -from DsgTools.core.DSGToolsProcessingAlgs.Algs.LayerManagementAlgs.buildJoinsOnLayersAlgorithm import \ - BuildJoinsOnLayersAlgorithm -from DsgTools.core.DSGToolsProcessingAlgs.Algs.LayerManagementAlgs.groupLayersAlgorithm import \ - GroupLayersAlgorithm -from DsgTools.core.DSGToolsProcessingAlgs.Algs.LayerManagementAlgs.loadLayersFromPostgisAlgorithm import \ - LoadLayersFromPostgisAlgorithm -from DsgTools.core.DSGToolsProcessingAlgs.Algs.LayerManagementAlgs.loadNonSpatialLayersFromPostgreSQLAlgorithm import \ - LoadNonSpatialLayersFromPostgreSQLAlgorithm -from DsgTools.core.DSGToolsProcessingAlgs.Algs.LayerManagementAlgs.loadShapefileAlgorithm import \ - LoadShapefileAlgorithm -from DsgTools.core.DSGToolsProcessingAlgs.Algs.LayerManagementAlgs.matchAndApplyQmlStylesToLayersAlgorithm import \ - MatchAndApplyQmlStylesToLayersAlgorithm -from DsgTools.core.DSGToolsProcessingAlgs.Algs.LayerManagementAlgs.removeEmptyLayers import \ - RemoveEmptyLayers -from DsgTools.core.DSGToolsProcessingAlgs.Algs.LayerManagementAlgs.spellCheckerAlgorithm import \ - SpellCheckerAlgorithm -from DsgTools.core.DSGToolsProcessingAlgs.Algs.OtherAlgs.batchRunAlgorithm import \ - BatchRunAlgorithm -from DsgTools.core.DSGToolsProcessingAlgs.Algs.OtherAlgs.convertLayer2LayerAlgorithm import \ - ConvertLayer2LayerAlgorithm -from DsgTools.core.DSGToolsProcessingAlgs.Algs.OtherAlgs.createFrameAlgorithm import \ - CreateFrameAlgorithm -from DsgTools.core.DSGToolsProcessingAlgs.Algs.OtherAlgs.createFramesWithConstraintAlgorithm import \ - CreateFramesWithConstraintAlgorithm -from DsgTools.core.DSGToolsProcessingAlgs.Algs.ValidationAlgs.addUnsharedVertexOnIntersectionsAlgorithm import AddUnsharedVertexOnIntersectionsAlgorithm -from DsgTools.core.DSGToolsProcessingAlgs.Algs.ValidationAlgs.addUnsharedVertexOnSharedEdgesAlgorithm import AddUnsharedVertexOnSharedEdgesAlgorithm -from DsgTools.core.DSGToolsProcessingAlgs.Algs.ValidationAlgs.extendLinesToGeographicBoundsAlgorithm import ExtendLinesToGeographicBoundsAlgorithm -from .Algs.OtherAlgs.createReviewGridAlgorithm import CreateReviewGridAlgorithm -from DsgTools.core.DSGToolsProcessingAlgs.Algs.OtherAlgs.exportToMemoryLayer import \ - ExportToMemoryLayer -from DsgTools.core.DSGToolsProcessingAlgs.Algs.OtherAlgs.fileInventoryAlgorithm import \ - FileInventoryAlgorithm -from DsgTools.core.DSGToolsProcessingAlgs.Algs.OtherAlgs.pecCalculatorAlgorithm import \ - PecCalculatorAlgorithm -from DsgTools.core.DSGToolsProcessingAlgs.Algs.OtherAlgs.raiseFlagsAlgorithm import \ - RaiseFlagsAlgorithm -from DsgTools.core.DSGToolsProcessingAlgs.Algs.OtherAlgs.ruleStatisticsAlgorithm import \ - RuleStatisticsAlgorithm -from DsgTools.core.DSGToolsProcessingAlgs.Algs.OtherAlgs.runFMESAPAlgorithm import \ - RunFMESAPAlgorithm + +from DsgTools.core.DSGToolsProcessingAlgs.Algs.GeometricAlgs.extractByDE9IM import ( + ExtractByDE9IMAlgorithm, +) +from DsgTools.core.DSGToolsProcessingAlgs.Algs.GeometricAlgs.line2Multiline import ( + Line2Multiline, +) +from DsgTools.core.DSGToolsProcessingAlgs.Algs.GeometricAlgs.pointsInPolygonGridAlgorithm import ( + PointsInPolygonGridAlgorithm, +) +from DsgTools.core.DSGToolsProcessingAlgs.Algs.GeometricAlgs.selectByDE9IM import ( + SelectByDE9IMAlgorithm, +) +from DsgTools.core.DSGToolsProcessingAlgs.Algs.GeometricAlgs.splitPolygonsAlgorithm import ( + SplitPolygons, +) +from DsgTools.core.DSGToolsProcessingAlgs.Algs.GeometricAlgs.splitPolygonsByGrid import ( + SplitPolygonsByGrid, +) +from processing.core.ProcessingConfig import ProcessingConfig, Setting +from PyQt5.QtCore import QCoreApplication +from qgis.core import QgsApplication, QgsProcessingProvider +from qgis.PyQt.QtGui import QIcon + +from DsgTools.core.DSGToolsProcessingAlgs.Algs.EditingAlgs.createEditingGridAlgorithm import ( + CreateEditingGridAlgorithm, +) +from DsgTools.core.DSGToolsProcessingAlgs.Algs.EnvironmentSetterAlgs.setFreeHandToolParametersAlgorithm import ( + SetFreeHandToolParametersAlgorithm, +) +from DsgTools.core.DSGToolsProcessingAlgs.Algs.GeometricAlgs.donutHoleExtractorAlgorithm import ( + DonutHoleExtractorAlgorithm, +) +from DsgTools.core.DSGToolsProcessingAlgs.Algs.GeometricAlgs.reclassifyAdjecentPolygonsAlgorithm import ( + ReclassifyAdjacentPolygonsAlgorithm, +) +from DsgTools.core.DSGToolsProcessingAlgs.Algs.GeometricAlgs.smallHoleRemoverAlgorithm import ( + SmallHoleRemoverAlgorithm, +) +from DsgTools.core.DSGToolsProcessingAlgs.Algs.LayerManagementAlgs.applyStylesFromDatabaseToLayersAlgorithm import ( + ApplyStylesFromDatabaseToLayersAlgorithm, +) +from DsgTools.core.DSGToolsProcessingAlgs.Algs.LayerManagementAlgs.assignActionsToLayersAlgorithm import ( + AssignActionsToLayersAlgorithm, +) +from DsgTools.core.DSGToolsProcessingAlgs.Algs.LayerManagementAlgs.assignAliasesToLayersAlgorithm import ( + AssignAliasesToLayersAlgorithm, +) +from DsgTools.core.DSGToolsProcessingAlgs.Algs.LayerManagementAlgs.assignBoundingBoxFilterToLayersAlgorithm import ( + AssignBoundingBoxFilterToLayersAlgorithm, +) +from DsgTools.core.DSGToolsProcessingAlgs.Algs.LayerManagementAlgs.assignConditionalStyleToLayersAlgorithm import ( + AssignConditionalStyleToLayersAlgorithm, +) +from DsgTools.core.DSGToolsProcessingAlgs.Algs.LayerManagementAlgs.assignCustomFormAndFormatRulesToLayersAlgorithm import ( + AssignCustomFormAndFormatRulesToLayersAlgorithm, +) +from DsgTools.core.DSGToolsProcessingAlgs.Algs.LayerManagementAlgs.assignDefaultFieldValueToLayersAlgorithm import ( + AssignDefaultFieldValueToLayersAlgorithm, +) +from DsgTools.core.DSGToolsProcessingAlgs.Algs.LayerManagementAlgs.assignExpressionFieldToLayersAlgorithm import ( + AssignExpressionFieldToLayersAlgorithm, +) +from DsgTools.core.DSGToolsProcessingAlgs.Algs.LayerManagementAlgs.assignFilterToLayersAlgorithm import ( + AssignFilterToLayersAlgorithm, +) +from DsgTools.core.DSGToolsProcessingAlgs.Algs.LayerManagementAlgs.assignFormatRulesToLayersAlgorithm import ( + AssignFormatRulesToLayersAlgorithm, +) +from DsgTools.core.DSGToolsProcessingAlgs.Algs.LayerManagementAlgs.assignMeasureColumnToLayersAlgorithm import ( + AssignMeasureColumnToLayersAlgorithm, +) +from DsgTools.core.DSGToolsProcessingAlgs.Algs.LayerManagementAlgs.assignValueMapToLayersAlgorithm import ( + AssignValueMapToLayersAlgorithm, +) +from DsgTools.core.DSGToolsProcessingAlgs.Algs.LayerManagementAlgs.buildJoinsOnLayersAlgorithm import ( + BuildJoinsOnLayersAlgorithm, +) +from DsgTools.core.DSGToolsProcessingAlgs.Algs.LayerManagementAlgs.groupLayersAlgorithm import ( + GroupLayersAlgorithm, +) +from DsgTools.core.DSGToolsProcessingAlgs.Algs.LayerManagementAlgs.loadLayersFromPostgisAlgorithm import ( + LoadLayersFromPostgisAlgorithm, +) +from DsgTools.core.DSGToolsProcessingAlgs.Algs.LayerManagementAlgs.loadNonSpatialLayersFromPostgreSQLAlgorithm import ( + LoadNonSpatialLayersFromPostgreSQLAlgorithm, +) +from DsgTools.core.DSGToolsProcessingAlgs.Algs.LayerManagementAlgs.loadShapefileAlgorithm import ( + LoadShapefileAlgorithm, +) +from DsgTools.core.DSGToolsProcessingAlgs.Algs.LayerManagementAlgs.lockAttributeEditingAlgorithm import ( + LockAttributeEditingAlgorithm, +) +from DsgTools.core.DSGToolsProcessingAlgs.Algs.LayerManagementAlgs.matchAndApplyQmlStylesToLayersAlgorithm import ( + MatchAndApplyQmlStylesToLayersAlgorithm, +) +from DsgTools.core.DSGToolsProcessingAlgs.Algs.LayerManagementAlgs.removeEmptyLayers import ( + RemoveEmptyLayers, +) +from DsgTools.core.DSGToolsProcessingAlgs.Algs.LayerManagementAlgs.setRemoveDuplicateNodePropertyOnLayers import ( + SetRemoveDuplicateNodePropertyOnLayers, +) +from DsgTools.core.DSGToolsProcessingAlgs.Algs.OtherAlgs.batchRunAlgorithm import ( + BatchRunAlgorithm, +) +from DsgTools.core.DSGToolsProcessingAlgs.Algs.OtherAlgs.convertLayer2LayerAlgorithm import ( + ConvertLayer2LayerAlgorithm, +) +from DsgTools.core.DSGToolsProcessingAlgs.Algs.OtherAlgs.createFrameAlgorithm import ( + CreateFrameAlgorithm, +) +from DsgTools.core.DSGToolsProcessingAlgs.Algs.OtherAlgs.createFramesWithConstraintAlgorithm import ( + CreateFramesWithConstraintAlgorithm, +) +from DsgTools.core.DSGToolsProcessingAlgs.Algs.OtherAlgs.exportToMemoryLayer import ( + ExportToMemoryLayer, +) +from DsgTools.core.DSGToolsProcessingAlgs.Algs.OtherAlgs.fileInventoryAlgorithm import ( + FileInventoryAlgorithm, +) +from DsgTools.core.DSGToolsProcessingAlgs.Algs.OtherAlgs.filterLayerListByGeometryType import ( + FilterLayerListByGeometryType, +) +from DsgTools.core.DSGToolsProcessingAlgs.Algs.OtherAlgs.pecCalculatorAlgorithm import ( + PecCalculatorAlgorithm, +) +from DsgTools.core.DSGToolsProcessingAlgs.Algs.OtherAlgs.raiseFlagsAlgorithm import ( + RaiseFlagsAlgorithm, +) +from DsgTools.core.DSGToolsProcessingAlgs.Algs.OtherAlgs.ruleStatisticsAlgorithm import ( + RuleStatisticsAlgorithm, +) +from DsgTools.core.DSGToolsProcessingAlgs.Algs.OtherAlgs.runFMESAPAlgorithm import ( + RunFMESAPAlgorithm, +) from DsgTools.core.DSGToolsProcessingAlgs.Algs.OtherAlgs.runRemoteFMEAlgorithm import ( - ParameterFMEManagerType, RunRemoteFMEAlgorithm) -from DsgTools.core.DSGToolsProcessingAlgs.Algs.OtherAlgs.stringCsvToFirstLayerWithElementsAlgorithm import StringCsvToFirstLayerWithElementsAlgorithm -from DsgTools.core.DSGToolsProcessingAlgs.Algs.OtherAlgs.stringCsvToLayerListAlgorithm import \ - StringCsvToLayerListAlgorithm -from DsgTools.core.DSGToolsProcessingAlgs.Algs.OtherAlgs.unicodeFilterAlgorithm import \ - UnicodeFilterAlgorithm -# from DsgTools.core.DSGToolsProcessingAlgs.Algs.OtherAlgs.singleOutputUnitTestAlgorithm import \ -# SingleOutputUnitTestAlgorithm -from DsgTools.core.DSGToolsProcessingAlgs.Algs.OtherAlgs.updateOriginalLayerAlgorithm import \ - UpdateOriginalLayerAlgorithm -from DsgTools.core.DSGToolsProcessingAlgs.Algs.ValidationAlgs.adjustNetworkConnectivityAlgorithm import \ - AdjustNetworkConnectivityAlgorithm -from DsgTools.core.DSGToolsProcessingAlgs.Algs.ValidationAlgs.buildPolygonsFromCenterPointsAndBoundariesAlgorithm import \ - BuildPolygonsFromCenterPointsAndBoundariesAlgorithm -from DsgTools.core.DSGToolsProcessingAlgs.Algs.ValidationAlgs.cleanGeometriesAlgorithm import \ - CleanGeometriesAlgorithm -from DsgTools.core.DSGToolsProcessingAlgs.Algs.ValidationAlgs.createNetworkNodesAlgorithm import \ - CreateNetworkNodesAlgorithm -from DsgTools.core.DSGToolsProcessingAlgs.Algs.ValidationAlgs.deaggregateGeometriesAlgorithm import \ - DeaggregatorAlgorithm -from DsgTools.core.DSGToolsProcessingAlgs.Algs.ValidationAlgs.dissolvePolygonsWithSameAttributesAlgorithm import \ - DissolvePolygonsWithSameAttributesAlgorithm -from DsgTools.core.DSGToolsProcessingAlgs.Algs.ValidationAlgs.enforceAttributeRulesAlgorithm import \ - EnforceAttributeRulesAlgorithm + ParameterFMEManagerType, + RunRemoteFMEAlgorithm, +) +from DsgTools.core.DSGToolsProcessingAlgs.Algs.OtherAlgs.selectFeaturesOnCurrentCanvas import ( + SelectFeaturesOnCurrentCanvas, +) +from DsgTools.core.DSGToolsProcessingAlgs.Algs.OtherAlgs.stringCsvToFirstLayerWithElementsAlgorithm import ( + StringCsvToFirstLayerWithElementsAlgorithm, +) +from DsgTools.core.DSGToolsProcessingAlgs.Algs.OtherAlgs.stringCsvToLayerListAlgorithm import ( + StringCsvToLayerListAlgorithm, +) +from DsgTools.core.DSGToolsProcessingAlgs.Algs.OtherAlgs.updateOriginalLayerAlgorithm import ( + UpdateOriginalLayerAlgorithm, +) +from DsgTools.core.DSGToolsProcessingAlgs.Algs.ValidationAlgs.addUnsharedVertexOnIntersectionsAlgorithm import ( + AddUnsharedVertexOnIntersectionsAlgorithm, +) +from DsgTools.core.DSGToolsProcessingAlgs.Algs.ValidationAlgs.addUnsharedVertexOnSharedEdgesAlgorithm import ( + AddUnsharedVertexOnSharedEdgesAlgorithm, +) +from DsgTools.core.DSGToolsProcessingAlgs.Algs.ValidationAlgs.adjustNetworkConnectivityAlgorithm import ( + AdjustNetworkConnectivityAlgorithm, +) +from DsgTools.core.DSGToolsProcessingAlgs.Algs.ValidationAlgs.buildPolygonsFromCenterPointsAndBoundariesAlgorithm import ( + BuildPolygonsFromCenterPointsAndBoundariesAlgorithm, +) +from DsgTools.core.DSGToolsProcessingAlgs.Algs.ValidationAlgs.cleanGeometriesAlgorithm import ( + CleanGeometriesAlgorithm, +) +from DsgTools.core.DSGToolsProcessingAlgs.Algs.ValidationAlgs.createNetworkNodesAlgorithm import ( + CreateNetworkNodesAlgorithm, +) +from DsgTools.core.DSGToolsProcessingAlgs.Algs.ValidationAlgs.deaggregateGeometriesAlgorithm import ( + DeaggregatorAlgorithm, +) +from DsgTools.core.DSGToolsProcessingAlgs.Algs.ValidationAlgs.detectNullGeometriesAlgorithm import ( + DetectNullGeometriesAlgorithm, +) +from DsgTools.core.DSGToolsProcessingAlgs.Algs.ValidationAlgs.dissolvePolygonsWithSameAttributesAlgorithm import ( + DissolvePolygonsWithSameAttributesAlgorithm, +) +from DsgTools.core.DSGToolsProcessingAlgs.Algs.ValidationAlgs.enforceAttributeRulesAlgorithm import ( + EnforceAttributeRulesAlgorithm, +) from DsgTools.core.DSGToolsProcessingAlgs.Algs.ValidationAlgs.enforceSpatialRulesAlgorithm import ( - EnforceSpatialRulesAlgorithm, ParameterSpatialRulesSetType) + EnforceSpatialRulesAlgorithm, + ParameterSpatialRulesSetType, +) +from DsgTools.core.DSGToolsProcessingAlgs.Algs.ValidationAlgs.extendLinesToGeographicBoundsAlgorithm import ( + ExtendLinesToGeographicBoundsAlgorithm, +) from DsgTools.core.DSGToolsProcessingAlgs.Algs.ValidationAlgs.hierarchicalSnapLayerOnLayerAndUpdateAlgorithm import ( - HierarchicalSnapLayerOnLayerAndUpdateAlgorithm, ParameterSnapHierarchyType) -from DsgTools.core.DSGToolsProcessingAlgs.Algs.ValidationAlgs.identifyAndFixInvalidGeometriesAlgorithm import \ - IdentifyAndFixInvalidGeometriesAlgorithm -from DsgTools.core.DSGToolsProcessingAlgs.Algs.ValidationAlgs.identifyAnglesInInvalidRangeAlgorithm import \ - IdentifyAnglesInInvalidRangeAlgorithm -from DsgTools.core.DSGToolsProcessingAlgs.Algs.ValidationAlgs.identifyCountourStreamIntersectionAlgorithm import \ - IdentifyCountourStreamIntersectionAlgorithm -from DsgTools.core.DSGToolsProcessingAlgs.Algs.ValidationAlgs.identifyDanglesAlgorithm import \ - IdentifyDanglesAlgorithm -from DsgTools.core.DSGToolsProcessingAlgs.Algs.ValidationAlgs.identifyDrainageFlowIssuesWithOtherHydrographicClassesAlgorithm import IdentifyDrainageFlowIssuesWithHydrographyElementsAlgorithm -from DsgTools.core.DSGToolsProcessingAlgs.Algs.ValidationAlgs.identifyDrainageLoops import IdentifyDrainageLoops -from DsgTools.core.DSGToolsProcessingAlgs.Algs.ValidationAlgs.identifyNetworkConstructionIssuesAlgorithm import \ - IdentifyNetworkConstructionIssuesAlgorithm -from DsgTools.core.DSGToolsProcessingAlgs.Algs.ValidationAlgs.identifyDuplicatedFeaturesAlgorithm import \ - IdentifyDuplicatedFeaturesAlgorithm -from DsgTools.core.DSGToolsProcessingAlgs.Algs.ValidationAlgs.identifyDuplicatedGeometriesAlgorithm import \ - IdentifyDuplicatedGeometriesAlgorithm -from DsgTools.core.DSGToolsProcessingAlgs.Algs.ValidationAlgs.identifyDuplicatedLinesBetweenLayersAlgorithm import \ - IdentifyDuplicatedLinesBetweenLayersAlgorithm -from DsgTools.core.DSGToolsProcessingAlgs.Algs.ValidationAlgs.identifyDuplicatedPointsBetweenLayersAlgorithm import \ - IdentifyDuplicatedPointsBetweenLayersAlgorithm -from DsgTools.core.DSGToolsProcessingAlgs.Algs.ValidationAlgs.identifyDuplicatedPolygonsBetweenLayersAlgorithm import \ - IdentifyDuplicatedPolygonsBetweenLayersAlgorithm -from DsgTools.core.DSGToolsProcessingAlgs.Algs.ValidationAlgs.identifyDuplicatedVertexesAlgorithm import \ - IdentifyDuplicatedVertexesAlgorithm -from DsgTools.core.DSGToolsProcessingAlgs.Algs.ValidationAlgs.identifyGapsAlgorithm import \ - IdentifyGapsAlgorithm -from DsgTools.core.DSGToolsProcessingAlgs.Algs.ValidationAlgs.identifyGapsAndOverlapsInCoverageAlgorithm import \ - IdentifyGapsAndOverlapsInCoverageAlgorithm -from DsgTools.core.DSGToolsProcessingAlgs.Algs.ValidationAlgs.identifyGeometriesWithLargeVertexDensityAlgorithm import \ - IdentifyGeometriesWithLargeVertexDensityAlgorithm -from DsgTools.core.DSGToolsProcessingAlgs.Algs.ValidationAlgs.identifyInvalidUUIDsAlgorithm import \ - IdentifyInvalidUUIDsAlgorithm -from DsgTools.core.DSGToolsProcessingAlgs.Algs.ValidationAlgs.identifyMultiPartGeometriesAlgorithm import \ - IdentifyMultiPartGeometriesAlgorithm -from DsgTools.core.DSGToolsProcessingAlgs.Algs.ValidationAlgs.identifyUnmergedLinesWithSameAttributeSetAlgorithm import \ - IdentifyUnmergedLinesWithSameAttributeSetAlgorithm -from DsgTools.core.DSGToolsProcessingAlgs.Algs.ValidationAlgs.identifyOutOfBoundsAnglesAlgorithm import \ - IdentifyOutOfBoundsAnglesAlgorithm -from DsgTools.core.DSGToolsProcessingAlgs.Algs.ValidationAlgs.identifyOutOfBoundsAnglesInCoverageAlgorithm import \ - IdentifyOutOfBoundsAnglesInCoverageAlgorithm -from DsgTools.core.DSGToolsProcessingAlgs.Algs.ValidationAlgs.identifyOverlapsAlgorithm import \ - IdentifyOverlapsAlgorithm -from DsgTools.core.DSGToolsProcessingAlgs.Algs.ValidationAlgs.identifyPolygonSliverAlgorithm import \ - IdentifyPolygonSliverAlgorithm -from DsgTools.core.DSGToolsProcessingAlgs.Algs.ValidationAlgs.identifyPolygonUndershoots import \ - IdentifyPolygonUndershootsAlgorithm -from DsgTools.core.DSGToolsProcessingAlgs.Algs.ValidationAlgs.identifySmallFirstOrderDangle import \ - IdentifySmallFirstOrderDanglesAlgorithm -from DsgTools.core.DSGToolsProcessingAlgs.Algs.ValidationAlgs.identifySmallHolesAlgorithm import \ - IdentifySmallHolesAlgorithm -from DsgTools.core.DSGToolsProcessingAlgs.Algs.ValidationAlgs.identifySmallLinesAlgorithm import \ - IdentifySmallLinesAlgorithm -from DsgTools.core.DSGToolsProcessingAlgs.Algs.ValidationAlgs.identifySmallPolygonsAlgorithm import \ - IdentifySmallPolygonsAlgorithm + HierarchicalSnapLayerOnLayerAndUpdateAlgorithm, + ParameterSnapHierarchyType, +) +from DsgTools.core.DSGToolsProcessingAlgs.Algs.ValidationAlgs.identifyAndFixInvalidGeometriesAlgorithm import ( + IdentifyAndFixInvalidGeometriesAlgorithm, +) +from DsgTools.core.DSGToolsProcessingAlgs.Algs.ValidationAlgs.identifyAnglesInInvalidRangeAlgorithm import ( + IdentifyAnglesInInvalidRangeAlgorithm, +) +from DsgTools.core.DSGToolsProcessingAlgs.Algs.ValidationAlgs.identifyCountourStreamIntersectionAlgorithm import ( + IdentifyCountourStreamIntersectionAlgorithm, +) +from DsgTools.core.DSGToolsProcessingAlgs.Algs.ValidationAlgs.identifyDanglesAlgorithm import ( + IdentifyDanglesAlgorithm, +) +from DsgTools.core.DSGToolsProcessingAlgs.Algs.ValidationAlgs.identifyDrainageAngleIssues import ( + IdentifyDrainageAngleIssues, +) +from DsgTools.core.DSGToolsProcessingAlgs.Algs.ValidationAlgs.identifyDrainageFlowIssues import ( + IdentifyDrainageFlowIssues, +) +from DsgTools.core.DSGToolsProcessingAlgs.Algs.ValidationAlgs.identifyDrainageFlowIssuesWithOtherHydrographicClassesAlgorithm import ( + IdentifyDrainageFlowIssuesWithHydrographyElementsAlgorithm, +) +from DsgTools.core.DSGToolsProcessingAlgs.Algs.ValidationAlgs.identifyDrainageLoops import ( + IdentifyDrainageLoops, +) +from DsgTools.core.DSGToolsProcessingAlgs.Algs.ValidationAlgs.identifyDuplicatedFeaturesAlgorithm import ( + IdentifyDuplicatedFeaturesAlgorithm, +) +from DsgTools.core.DSGToolsProcessingAlgs.Algs.ValidationAlgs.identifyDuplicatedGeometriesAlgorithm import ( + IdentifyDuplicatedGeometriesAlgorithm, +) +from DsgTools.core.DSGToolsProcessingAlgs.Algs.ValidationAlgs.identifyDuplicatedLinesBetweenLayersAlgorithm import ( + IdentifyDuplicatedLinesBetweenLayersAlgorithm, +) +from DsgTools.core.DSGToolsProcessingAlgs.Algs.ValidationAlgs.identifyDuplicatedPointsBetweenLayersAlgorithm import ( + IdentifyDuplicatedPointsBetweenLayersAlgorithm, +) +from DsgTools.core.DSGToolsProcessingAlgs.Algs.ValidationAlgs.identifyDuplicatedPolygonsBetweenLayersAlgorithm import ( + IdentifyDuplicatedPolygonsBetweenLayersAlgorithm, +) +from DsgTools.core.DSGToolsProcessingAlgs.Algs.ValidationAlgs.identifyDuplicatedVertexesAlgorithm import ( + IdentifyDuplicatedVertexesAlgorithm, +) +from DsgTools.core.DSGToolsProcessingAlgs.Algs.ValidationAlgs.identifyGapsAlgorithm import ( + IdentifyGapsAlgorithm, +) +from DsgTools.core.DSGToolsProcessingAlgs.Algs.ValidationAlgs.identifyGapsAndOverlapsInCoverageAlgorithm import ( + IdentifyGapsAndOverlapsInCoverageAlgorithm, +) +from DsgTools.core.DSGToolsProcessingAlgs.Algs.ValidationAlgs.identifyGeometriesWithLargeVertexDensityAlgorithm import ( + IdentifyGeometriesWithLargeVertexDensityAlgorithm, +) +from DsgTools.core.DSGToolsProcessingAlgs.Algs.ValidationAlgs.identifyInvalidUUIDsAlgorithm import ( + IdentifyInvalidUUIDsAlgorithm, +) +from DsgTools.core.DSGToolsProcessingAlgs.Algs.ValidationAlgs.identifyMultiPartGeometriesAlgorithm import ( + IdentifyMultiPartGeometriesAlgorithm, +) +from DsgTools.core.DSGToolsProcessingAlgs.Algs.ValidationAlgs.identifyNetworkConstructionIssuesAlgorithm import ( + IdentifyNetworkConstructionIssuesAlgorithm, +) +from DsgTools.core.DSGToolsProcessingAlgs.Algs.ValidationAlgs.identifyOutOfBoundsAnglesAlgorithm import ( + IdentifyOutOfBoundsAnglesAlgorithm, +) +from DsgTools.core.DSGToolsProcessingAlgs.Algs.ValidationAlgs.identifyOutOfBoundsAnglesInCoverageAlgorithm import ( + IdentifyOutOfBoundsAnglesInCoverageAlgorithm, +) +from DsgTools.core.DSGToolsProcessingAlgs.Algs.ValidationAlgs.identifyOverlapsAlgorithm import ( + IdentifyOverlapsAlgorithm, +) +from DsgTools.core.DSGToolsProcessingAlgs.Algs.ValidationAlgs.identifyPolygonSliverAlgorithm import ( + IdentifyPolygonSliverAlgorithm, +) +from DsgTools.core.DSGToolsProcessingAlgs.Algs.ValidationAlgs.identifyPolygonUndershoots import ( + IdentifyPolygonUndershootsAlgorithm, +) +from DsgTools.core.DSGToolsProcessingAlgs.Algs.ValidationAlgs.identifySmallFirstOrderDangle import ( + IdentifySmallFirstOrderDanglesAlgorithm, +) +from DsgTools.core.DSGToolsProcessingAlgs.Algs.ValidationAlgs.identifySmallHolesAlgorithm import ( + IdentifySmallHolesAlgorithm, +) +from DsgTools.core.DSGToolsProcessingAlgs.Algs.ValidationAlgs.identifySmallLinesAlgorithm import ( + IdentifySmallLinesAlgorithm, +) +from DsgTools.core.DSGToolsProcessingAlgs.Algs.ValidationAlgs.identifySmallPolygonsAlgorithm import ( + IdentifySmallPolygonsAlgorithm, +) + # from DsgTools.core.DSGToolsProcessingAlgs.Algs.OtherAlgs.multipleOutputUnitTestAlgorithm import \ # MultipleOutputUnitTestAlgorithm -from DsgTools.core.DSGToolsProcessingAlgs.Algs.ValidationAlgs.identifyTerrainModelErrorsAlgorithm import \ - IdentifyTerrainModelErrorsAlgorithm -from DsgTools.core.DSGToolsProcessingAlgs.Algs.ValidationAlgs.identifyUnsharedVertexOnIntersectionsAlgorithm import \ - IdentifyUnsharedVertexOnIntersectionsAlgorithm -from DsgTools.core.DSGToolsProcessingAlgs.Algs.ValidationAlgs.identifyUnsharedVertexOnSharedEdgesAlgorithm import \ - IdentifyUnsharedVertexOnSharedEdgesAlgorithm -from DsgTools.core.DSGToolsProcessingAlgs.Algs.ValidationAlgs.identifyVertexNearEdgesAlgorithm import \ - IdentifyVertexNearEdgesAlgorithm +from DsgTools.core.DSGToolsProcessingAlgs.Algs.ValidationAlgs.identifyTerrainModelErrorsAlgorithm import ( + IdentifyTerrainModelErrorsAlgorithm, +) +from DsgTools.core.DSGToolsProcessingAlgs.Algs.ValidationAlgs.identifyUnmergedLinesWithSameAttributeSetAlgorithm import ( + IdentifyUnmergedLinesWithSameAttributeSetAlgorithm, +) +from DsgTools.core.DSGToolsProcessingAlgs.Algs.ValidationAlgs.identifyUnsharedVertexOnIntersectionsAlgorithm import ( + IdentifyUnsharedVertexOnIntersectionsAlgorithm, +) +from DsgTools.core.DSGToolsProcessingAlgs.Algs.ValidationAlgs.identifyUnsharedVertexOnSharedEdgesAlgorithm import ( + IdentifyUnsharedVertexOnSharedEdgesAlgorithm, +) +from DsgTools.core.DSGToolsProcessingAlgs.Algs.ValidationAlgs.identifyVertexNearEdgesAlgorithm import ( + IdentifyVertexNearEdgesAlgorithm, +) + # from DsgTools.core.DSGToolsProcessingAlgs.Algs.OtherAlgs.singleOutputUnitTestAlgorithm import SingleOutputUnitTestAlgorithm -from DsgTools.core.DSGToolsProcessingAlgs.Algs.ValidationAlgs.identifyWrongBuildingAnglesAlgorithm import \ - IdentifyWrongBuildingAnglesAlgorithm -from DsgTools.core.DSGToolsProcessingAlgs.Algs.ValidationAlgs.identifyZAnglesBetweenFeaturesAlgorithm import \ - identifyZAnglesBetweenFeaturesAlgorithm -from DsgTools.core.DSGToolsProcessingAlgs.Algs.ValidationAlgs.lineOnLineOverlayerAlgorithm import \ - LineOnLineOverlayerAlgorithm -from DsgTools.core.DSGToolsProcessingAlgs.Algs.ValidationAlgs.mergeLinesAlgorithm import \ - MergeLinesAlgorithm -from DsgTools.core.DSGToolsProcessingAlgs.Algs.ValidationAlgs.overlayElementsWithAreasAlgorithm import \ - OverlayElementsWithAreasAlgorithm -from DsgTools.core.DSGToolsProcessingAlgs.Algs.ValidationAlgs.removeDuplicatedFeaturesAlgorithm import \ - RemoveDuplicatedFeaturesAlgorithm -from DsgTools.core.DSGToolsProcessingAlgs.Algs.ValidationAlgs.removeDuplicatedGeometriesAlgorithm import \ - RemoveDuplicatedGeometriesAlgorithm -from DsgTools.core.DSGToolsProcessingAlgs.Algs.ValidationAlgs.removeEmptyAndUpdateAlgorithm import \ - RemoveEmptyAndUpdateAlgorithm -from DsgTools.core.DSGToolsProcessingAlgs.Algs.ValidationAlgs.removeSmallLinesAlgorithm import \ - RemoveSmallLinesAlgorithm -from DsgTools.core.DSGToolsProcessingAlgs.Algs.ValidationAlgs.removeSmallPolygonsAlgorithm import \ - RemoveSmallPolygonsAlgorithm -from DsgTools.core.DSGToolsProcessingAlgs.Algs.ValidationAlgs.snapLayerOnLayerAndUpdateAlgorithm import \ - SnapLayerOnLayerAndUpdateAlgorithm -from DsgTools.core.DSGToolsProcessingAlgs.Algs.ValidationAlgs.snapToGridAndUpdateAlgorithm import \ - SnapToGridAndUpdateAlgorithm -from DsgTools.core.DSGToolsProcessingAlgs.Algs.ValidationAlgs.topologicalCleanAlgorithm import \ - TopologicalCleanAlgorithm -from DsgTools.core.DSGToolsProcessingAlgs.Algs.ValidationAlgs.topologicalCleanLinesAlgorithm import \ - TopologicalCleanLinesAlgorithm -from DsgTools.core.DSGToolsProcessingAlgs.Algs.ValidationAlgs.topologicalDouglasAreaSimplificationAlgorithm import \ - TopologicalDouglasPeuckerAreaSimplificationAlgorithm -from DsgTools.core.DSGToolsProcessingAlgs.Algs.ValidationAlgs.topologicalDouglasLineSimplificationAlgorithm import \ - TopologicalDouglasPeuckerLineSimplificationAlgorithm -from DsgTools.core.DSGToolsProcessingAlgs.Algs.ValidationAlgs.topologicalLineConnectivityAdjustmentAlgorithm import \ - TopologicalLineConnectivityAdjustment -from DsgTools.core.DSGToolsProcessingAlgs.Algs.ValidationAlgs.unbuildPolygonsAlgorithm import \ - UnbuildPolygonsAlgorithm -from DsgTools.core.DSGToolsProcessingAlgs.Algs.ValidationAlgs.verifyCountourStackingAlgorithm import \ - VerifyCountourStackingAlgorihtm -from DsgTools.core.DSGToolsProcessingAlgs.Algs.ValidationAlgs.verifyNetworkDirectioningAlgorithm import \ - VerifyNetworkDirectioningAlgorithm -from DsgTools.core.DSGToolsProcessingAlgs.Algs.ValidationAlgs.identifyDrainageFlowIssues import \ - IdentifyDrainageFlowIssues -from DsgTools.core.DSGToolsProcessingAlgs.Algs.ValidationAlgs.identifyDrainageAngleIssues import \ - IdentifyDrainageAngleIssues -from DsgTools.core.DSGToolsProcessingAlgs.Algs.LayerManagementAlgs.setRemoveDuplicateNodePropertyOnLayers import \ - SetRemoveDuplicateNodePropertyOnLayers -from processing.core.ProcessingConfig import ProcessingConfig, Setting -from PyQt5.QtCore import QCoreApplication -from qgis.core import QgsApplication, QgsProcessingProvider -from qgis.PyQt.QtGui import QIcon +from DsgTools.core.DSGToolsProcessingAlgs.Algs.ValidationAlgs.identifyWrongBuildingAnglesAlgorithm import ( + IdentifyWrongBuildingAnglesAlgorithm, +) +from DsgTools.core.DSGToolsProcessingAlgs.Algs.ValidationAlgs.identifyZAnglesBetweenFeaturesAlgorithm import ( + identifyZAnglesBetweenFeaturesAlgorithm, +) +from DsgTools.core.DSGToolsProcessingAlgs.Algs.ValidationAlgs.lineOnLineOverlayerAlgorithm import ( + LineOnLineOverlayerAlgorithm, +) +from DsgTools.core.DSGToolsProcessingAlgs.Algs.ValidationAlgs.mergeLinesAlgorithm import ( + MergeLinesAlgorithm, +) +from DsgTools.core.DSGToolsProcessingAlgs.Algs.ValidationAlgs.overlayElementsWithAreasAlgorithm import ( + OverlayElementsWithAreasAlgorithm, +) +from DsgTools.core.DSGToolsProcessingAlgs.Algs.ValidationAlgs.removeDuplicatedFeaturesAlgorithm import ( + RemoveDuplicatedFeaturesAlgorithm, +) +from DsgTools.core.DSGToolsProcessingAlgs.Algs.ValidationAlgs.removeDuplicatedGeometriesAlgorithm import ( + RemoveDuplicatedGeometriesAlgorithm, +) +from DsgTools.core.DSGToolsProcessingAlgs.Algs.ValidationAlgs.removeEmptyAndUpdateAlgorithm import ( + RemoveEmptyAndUpdateAlgorithm, +) +from DsgTools.core.DSGToolsProcessingAlgs.Algs.ValidationAlgs.removeSmallLinesAlgorithm import ( + RemoveSmallLinesAlgorithm, +) +from DsgTools.core.DSGToolsProcessingAlgs.Algs.ValidationAlgs.removeSmallPolygonsAlgorithm import ( + RemoveSmallPolygonsAlgorithm, +) +from DsgTools.core.DSGToolsProcessingAlgs.Algs.ValidationAlgs.snapLayerOnLayerAndUpdateAlgorithm import ( + SnapLayerOnLayerAndUpdateAlgorithm, +) +from DsgTools.core.DSGToolsProcessingAlgs.Algs.ValidationAlgs.snapToGridAndUpdateAlgorithm import ( + SnapToGridAndUpdateAlgorithm, +) +from DsgTools.core.DSGToolsProcessingAlgs.Algs.ValidationAlgs.spellCheckerAlgorithm import ( + SpellCheckerAlgorithm, +) +from DsgTools.core.DSGToolsProcessingAlgs.Algs.ValidationAlgs.topologicalCleanAlgorithm import ( + TopologicalCleanAlgorithm, +) +from DsgTools.core.DSGToolsProcessingAlgs.Algs.ValidationAlgs.topologicalCleanLinesAlgorithm import ( + TopologicalCleanLinesAlgorithm, +) +from DsgTools.core.DSGToolsProcessingAlgs.Algs.ValidationAlgs.topologicalDouglasAreaSimplificationAlgorithm import ( + TopologicalDouglasPeuckerAreaSimplificationAlgorithm, +) +from DsgTools.core.DSGToolsProcessingAlgs.Algs.ValidationAlgs.topologicalDouglasLineSimplificationAlgorithm import ( + TopologicalDouglasPeuckerLineSimplificationAlgorithm, +) +from DsgTools.core.DSGToolsProcessingAlgs.Algs.ValidationAlgs.topologicalLineConnectivityAdjustmentAlgorithm import ( + TopologicalLineConnectivityAdjustment, +) +from DsgTools.core.DSGToolsProcessingAlgs.Algs.ValidationAlgs.unbuildPolygonsAlgorithm import ( + UnbuildPolygonsAlgorithm, +) +from DsgTools.core.DSGToolsProcessingAlgs.Algs.ValidationAlgs.unicodeFilterAlgorithm import ( + UnicodeFilterAlgorithm, +) +from DsgTools.core.DSGToolsProcessingAlgs.Algs.ValidationAlgs.verifyCountourStackingAlgorithm import ( + VerifyCountourStackingAlgorihtm, +) +from DsgTools.core.DSGToolsProcessingAlgs.Algs.ValidationAlgs.verifyNetworkDirectioningAlgorithm import ( + VerifyNetworkDirectioningAlgorithm, +) +from DsgTools.core.DSGToolsProcessingAlgs.Algs.ValidationAlgs.streamOrder import ( + StreamOrder, +) +from DsgTools.core.DSGToolsProcessingAlgs.Algs.OtherAlgs.createReviewGridAlgorithm import ( + CreateReviewGridAlgorithm, +) class DSGToolsProcessingAlgorithmProvider(QgsProcessingProvider): """ Constructor """ + snapHierarchyParameterName = QCoreApplication.translate( - 'Processing', 'Snap Hierarchy') + "Processing", "Snap Hierarchy" + ) fmeManagerParameterName = QCoreApplication.translate( - 'Processing', 'FME Manager Parameters') + "Processing", "FME Manager Parameters" + ) + def __init__(self): super(DSGToolsProcessingAlgorithmProvider, self).__init__() def getAlgList(self): algList = [ DeaggregatorAlgorithm(), - IdentifySmallPolygonsAlgorithm(), - IdentifySmallLinesAlgorithm(), + IdentifySmallPolygonsAlgorithm(), + IdentifySmallLinesAlgorithm(), IdentifyDuplicatedGeometriesAlgorithm(), IdentifyOutOfBoundsAnglesAlgorithm(), IdentifyOutOfBoundsAnglesInCoverageAlgorithm(), @@ -357,7 +513,6 @@ def getAlgList(self): StringCsvToFirstLayerWithElementsAlgorithm(), IdentifyDrainageFlowIssues(), IdentifyDrainageAngleIssues(), - BuildTerrainSlicingFromContoursAlgorihtm(), SetRemoveDuplicateNodePropertyOnLayers(), IdentifyDrainageLoops(), IdentifyDrainageFlowIssuesWithHydrographyElementsAlgorithm(), @@ -365,25 +520,39 @@ def getAlgList(self): ExtendLinesToGeographicBoundsAlgorithm(), AddUnsharedVertexOnIntersectionsAlgorithm(), AddUnsharedVertexOnSharedEdgesAlgorithm(), + SelectFeaturesOnCurrentCanvas(), + FilterLayerListByGeometryType(), + SmallHoleRemoverAlgorithm(), + ReclassifyAdjacentPolygonsAlgorithm(), + StreamOrder(), + PointsInPolygonGridAlgorithm(), + SplitPolygons(), + SplitPolygonsByGrid(), + SelectByDE9IMAlgorithm(), + ExtractByDE9IMAlgorithm(), + Line2Multiline(), ] return algList - def load(self): ProcessingConfig.settingIcons[self.name()] = self.icon() # Activate provider by default - ProcessingConfig.addSetting(Setting(self.name(), 'ACTIVATE_DSGTools', - 'Activate', True)) + ProcessingConfig.addSetting( + Setting(self.name(), "ACTIVATE_DSGTools", "Activate", True) + ) ProcessingConfig.readSettings() self.parameterTypeSnapHierarchy = ParameterSnapHierarchyType() QgsApplication.instance().processingRegistry().addParameterType( - self.parameterTypeSnapHierarchy) + self.parameterTypeSnapHierarchy + ) self.parameterTypeFMEManager = ParameterFMEManagerType() QgsApplication.instance().processingRegistry().addParameterType( - self.parameterTypeFMEManager) + self.parameterTypeFMEManager + ) self.parameterSpatialRulesSetType = ParameterSpatialRulesSetType() QgsApplication.instance().processingRegistry().addParameterType( - self.parameterSpatialRulesSetType) + self.parameterSpatialRulesSetType + ) self.refreshAlgorithms() return True @@ -391,22 +560,25 @@ def unload(self): """ Removes setting when the plugin is unloaded. """ - ProcessingConfig.removeSetting('ACTIVATE_DSGTools') + ProcessingConfig.removeSetting("ACTIVATE_DSGTools") QgsApplication.instance().processingRegistry().removeParameterType( - self.parameterTypeSnapHierarchy) + self.parameterTypeSnapHierarchy + ) QgsApplication.instance().processingRegistry().removeParameterType( - self.parameterTypeFMEManager) + self.parameterTypeFMEManager + ) QgsApplication.instance().processingRegistry().removeParameterType( - self.parameterSpatialRulesSetType) + self.parameterSpatialRulesSetType + ) def isActive(self): """ Returns True if the provider is activated. """ - return ProcessingConfig.getSetting('ACTIVATE_DSGTools') + return ProcessingConfig.getSetting("ACTIVATE_DSGTools") def setActive(self, active): - ProcessingConfig.setSettingValue('ACTIVATE_DSGTools', active) + ProcessingConfig.setSettingValue("ACTIVATE_DSGTools", active) def id(self): """ @@ -414,19 +586,19 @@ def id(self): It is also used to create the command line name of all the algorithms from this provider. """ - return 'dsgtools' + return "dsgtools" def name(self): """ This is the localised full name. """ - return 'DSGTools' + return "DSGTools" def icon(self): """ We return the default icon. """ - return QIcon(':/plugins/DsgTools/icons/dsg.png') + return QIcon(":/plugins/DsgTools/icons/dsg.png") def loadAlgorithms(self): """ diff --git a/DsgTools/core/DbModels/DomainMapping/edgv_213.json b/DsgTools/core/DbModels/DomainMapping/edgv_213.json index 2b065b103..1a771f5a8 100644 --- a/DsgTools/core/DbModels/DomainMapping/edgv_213.json +++ b/DsgTools/core/DbModels/DomainMapping/edgv_213.json @@ -4985,4 +4985,4 @@ "code" ] } -} \ No newline at end of file +} diff --git a/DsgTools/core/DbModels/DomainMapping/edgv_213_pro.json b/DsgTools/core/DbModels/DomainMapping/edgv_213_pro.json index 203f6aa75..13eb82413 100644 --- a/DsgTools/core/DbModels/DomainMapping/edgv_213_pro.json +++ b/DsgTools/core/DbModels/DomainMapping/edgv_213_pro.json @@ -1417,4 +1417,4 @@ "code" ] } -} \ No newline at end of file +} diff --git a/DsgTools/core/DbModels/DomainMapping/edgv_3.json b/DsgTools/core/DbModels/DomainMapping/edgv_3.json index c9189c9cf..8c2142984 100644 --- a/DsgTools/core/DbModels/DomainMapping/edgv_3.json +++ b/DsgTools/core/DbModels/DomainMapping/edgv_3.json @@ -6381,4 +6381,4 @@ "code" ] } -} \ No newline at end of file +} diff --git a/DsgTools/core/DbModels/PostGIS/213/edgv213.sql b/DsgTools/core/DbModels/PostGIS/213/edgv213.sql index d28d8af32..dd6645a2f 100644 --- a/DsgTools/core/DbModels/PostGIS/213/edgv213.sql +++ b/DsgTools/core/DbModels/PostGIS/213/edgv213.sql @@ -2548,8 +2548,8 @@ ALTER TABLE cb.adm_edif_pub_civil_a REFERENCES dominios.matconstr (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.adm_edif_pub_civil_a - ADD CONSTRAINT adm_edif_pub_civil_a_matconstr_check - CHECK (matconstr = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 4 :: SMALLINT, 5 :: SMALLINT, 97 :: SMALLINT, 99 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT adm_edif_pub_civil_a_matconstr_check + CHECK (matconstr = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 4 :: SMALLINT, 5 :: SMALLINT, 97 :: SMALLINT, 99 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.adm_edif_pub_civil_a ALTER COLUMN matconstr SET DEFAULT 999# ALTER TABLE cb.adm_edif_pub_civil_a ADD CONSTRAINT adm_edif_pub_civil_a_operacional_fk FOREIGN KEY (operacional) @@ -2561,8 +2561,8 @@ ALTER TABLE cb.adm_edif_pub_civil_a REFERENCES dominios.situacaofisica (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.adm_edif_pub_civil_a - ADD CONSTRAINT adm_edif_pub_civil_a_situacaofisica_check - CHECK (situacaofisica = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT adm_edif_pub_civil_a_situacaofisica_check + CHECK (situacaofisica = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.adm_edif_pub_civil_a ALTER COLUMN situacaofisica SET DEFAULT 999# ALTER TABLE cb.adm_edif_pub_civil_a ADD CONSTRAINT adm_edif_pub_civil_a_tipoedifcivil_fk FOREIGN KEY (tipoedifcivil) @@ -2599,8 +2599,8 @@ ALTER TABLE cb.adm_edif_pub_civil_p REFERENCES dominios.matconstr (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.adm_edif_pub_civil_p - ADD CONSTRAINT adm_edif_pub_civil_p_matconstr_check - CHECK (matconstr = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 4 :: SMALLINT, 5 :: SMALLINT, 97 :: SMALLINT, 99 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT adm_edif_pub_civil_p_matconstr_check + CHECK (matconstr = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 4 :: SMALLINT, 5 :: SMALLINT, 97 :: SMALLINT, 99 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.adm_edif_pub_civil_p ALTER COLUMN matconstr SET DEFAULT 999# ALTER TABLE cb.adm_edif_pub_civil_p ADD CONSTRAINT adm_edif_pub_civil_p_operacional_fk FOREIGN KEY (operacional) @@ -2612,8 +2612,8 @@ ALTER TABLE cb.adm_edif_pub_civil_p REFERENCES dominios.situacaofisica (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.adm_edif_pub_civil_p - ADD CONSTRAINT adm_edif_pub_civil_p_situacaofisica_check - CHECK (situacaofisica = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT adm_edif_pub_civil_p_situacaofisica_check + CHECK (situacaofisica = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.adm_edif_pub_civil_p ALTER COLUMN situacaofisica SET DEFAULT 999# ALTER TABLE cb.adm_edif_pub_civil_p ADD CONSTRAINT adm_edif_pub_civil_p_tipoedifcivil_fk FOREIGN KEY (tipoedifcivil) @@ -2650,8 +2650,8 @@ ALTER TABLE cb.adm_edif_pub_militar_a REFERENCES dominios.matconstr (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.adm_edif_pub_militar_a - ADD CONSTRAINT adm_edif_pub_militar_a_matconstr_check - CHECK (matconstr = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 4 :: SMALLINT, 5 :: SMALLINT, 97 :: SMALLINT, 99 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT adm_edif_pub_militar_a_matconstr_check + CHECK (matconstr = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 4 :: SMALLINT, 5 :: SMALLINT, 97 :: SMALLINT, 99 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.adm_edif_pub_militar_a ALTER COLUMN matconstr SET DEFAULT 999# ALTER TABLE cb.adm_edif_pub_militar_a ADD CONSTRAINT adm_edif_pub_militar_a_operacional_fk FOREIGN KEY (operacional) @@ -2663,8 +2663,8 @@ ALTER TABLE cb.adm_edif_pub_militar_a REFERENCES dominios.situacaofisica (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.adm_edif_pub_militar_a - ADD CONSTRAINT adm_edif_pub_militar_a_situacaofisica_check - CHECK (situacaofisica = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT adm_edif_pub_militar_a_situacaofisica_check + CHECK (situacaofisica = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.adm_edif_pub_militar_a ALTER COLUMN situacaofisica SET DEFAULT 999# ALTER TABLE cb.adm_edif_pub_militar_a ADD CONSTRAINT adm_edif_pub_militar_a_tipoedifmil_fk FOREIGN KEY (tipoedifmil) @@ -2701,8 +2701,8 @@ ALTER TABLE cb.adm_edif_pub_militar_p REFERENCES dominios.matconstr (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.adm_edif_pub_militar_p - ADD CONSTRAINT adm_edif_pub_militar_p_matconstr_check - CHECK (matconstr = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 4 :: SMALLINT, 5 :: SMALLINT, 97 :: SMALLINT, 99 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT adm_edif_pub_militar_p_matconstr_check + CHECK (matconstr = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 4 :: SMALLINT, 5 :: SMALLINT, 97 :: SMALLINT, 99 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.adm_edif_pub_militar_p ALTER COLUMN matconstr SET DEFAULT 999# ALTER TABLE cb.adm_edif_pub_militar_p ADD CONSTRAINT adm_edif_pub_militar_p_operacional_fk FOREIGN KEY (operacional) @@ -2714,8 +2714,8 @@ ALTER TABLE cb.adm_edif_pub_militar_p REFERENCES dominios.situacaofisica (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.adm_edif_pub_militar_p - ADD CONSTRAINT adm_edif_pub_militar_p_situacaofisica_check - CHECK (situacaofisica = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT adm_edif_pub_militar_p_situacaofisica_check + CHECK (situacaofisica = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.adm_edif_pub_militar_p ALTER COLUMN situacaofisica SET DEFAULT 999# ALTER TABLE cb.adm_edif_pub_militar_p ADD CONSTRAINT adm_edif_pub_militar_p_tipoedifmil_fk FOREIGN KEY (tipoedifmil) @@ -2755,8 +2755,8 @@ ALTER TABLE cb.adm_posto_fiscal_a REFERENCES dominios.situacaofisica (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.adm_posto_fiscal_a - ADD CONSTRAINT adm_posto_fiscal_a_situacaofisica_check - CHECK (situacaofisica = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT adm_posto_fiscal_a_situacaofisica_check + CHECK (situacaofisica = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.adm_posto_fiscal_a ALTER COLUMN situacaofisica SET DEFAULT 999# ALTER TABLE cb.adm_posto_fiscal_a ADD CONSTRAINT adm_posto_fiscal_a_tipopostofisc_fk FOREIGN KEY (tipopostofisc) @@ -2791,8 +2791,8 @@ ALTER TABLE cb.adm_posto_fiscal_p REFERENCES dominios.situacaofisica (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.adm_posto_fiscal_p - ADD CONSTRAINT adm_posto_fiscal_p_situacaofisica_check - CHECK (situacaofisica = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT adm_posto_fiscal_p_situacaofisica_check + CHECK (situacaofisica = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.adm_posto_fiscal_p ALTER COLUMN situacaofisica SET DEFAULT 999# ALTER TABLE cb.adm_posto_fiscal_p ADD CONSTRAINT adm_posto_fiscal_p_tipopostofisc_fk FOREIGN KEY (tipopostofisc) @@ -2827,8 +2827,8 @@ ALTER TABLE cb.adm_posto_pol_rod_a REFERENCES dominios.situacaofisica (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.adm_posto_pol_rod_a - ADD CONSTRAINT adm_posto_pol_rod_a_situacaofisica_check - CHECK (situacaofisica = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT adm_posto_pol_rod_a_situacaofisica_check + CHECK (situacaofisica = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.adm_posto_pol_rod_a ALTER COLUMN situacaofisica SET DEFAULT 999# ALTER TABLE cb.adm_posto_pol_rod_a ADD CONSTRAINT adm_posto_pol_rod_a_tipopostopol_fk FOREIGN KEY (tipopostopol) @@ -2863,8 +2863,8 @@ ALTER TABLE cb.adm_posto_pol_rod_p REFERENCES dominios.situacaofisica (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.adm_posto_pol_rod_p - ADD CONSTRAINT adm_posto_pol_rod_p_situacaofisica_check - CHECK (situacaofisica = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT adm_posto_pol_rod_p_situacaofisica_check + CHECK (situacaofisica = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.adm_posto_pol_rod_p ALTER COLUMN situacaofisica SET DEFAULT 999# ALTER TABLE cb.adm_posto_pol_rod_p ADD CONSTRAINT adm_posto_pol_rod_p_tipopostopol_fk FOREIGN KEY (tipopostopol) @@ -2973,16 +2973,16 @@ ALTER TABLE cb.asb_dep_abast_agua_a REFERENCES dominios.construcao (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.asb_dep_abast_agua_a - ADD CONSTRAINT asb_dep_abast_agua_a_construcao_check - CHECK (construcao = ANY(ARRAY[1 :: SMALLINT, 2 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT asb_dep_abast_agua_a_construcao_check + CHECK (construcao = ANY(ARRAY[1 :: SMALLINT, 2 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.asb_dep_abast_agua_a ALTER COLUMN construcao SET DEFAULT 999# ALTER TABLE cb.asb_dep_abast_agua_a ADD CONSTRAINT asb_dep_abast_agua_a_finalidade_fk FOREIGN KEY (finalidade) REFERENCES dominios.finalidade_asb (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.asb_dep_abast_agua_a - ADD CONSTRAINT asb_dep_abast_agua_a_finalidade_check - CHECK (finalidade = ANY(ARRAY[2 :: SMALLINT, 3 :: SMALLINT, 4 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT asb_dep_abast_agua_a_finalidade_check + CHECK (finalidade = ANY(ARRAY[2 :: SMALLINT, 3 :: SMALLINT, 4 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.asb_dep_abast_agua_a ALTER COLUMN finalidade SET DEFAULT 999# ALTER TABLE cb.asb_dep_abast_agua_a ADD CONSTRAINT asb_dep_abast_agua_a_geometriaaproximada_fk FOREIGN KEY (geometriaaproximada) @@ -2994,8 +2994,8 @@ ALTER TABLE cb.asb_dep_abast_agua_a REFERENCES dominios.matconstr (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.asb_dep_abast_agua_a - ADD CONSTRAINT asb_dep_abast_agua_a_matconstr_check - CHECK (matconstr = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 4 :: SMALLINT, 97 :: SMALLINT, 99 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT asb_dep_abast_agua_a_matconstr_check + CHECK (matconstr = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 4 :: SMALLINT, 97 :: SMALLINT, 99 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.asb_dep_abast_agua_a ALTER COLUMN matconstr SET DEFAULT 999# ALTER TABLE cb.asb_dep_abast_agua_a ADD CONSTRAINT asb_dep_abast_agua_a_operacional_fk FOREIGN KEY (operacional) @@ -3012,8 +3012,8 @@ ALTER TABLE cb.asb_dep_abast_agua_a REFERENCES dominios.situacaofisica (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.asb_dep_abast_agua_a - ADD CONSTRAINT asb_dep_abast_agua_a_situacaofisica_check - CHECK (situacaofisica = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT asb_dep_abast_agua_a_situacaofisica_check + CHECK (situacaofisica = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.asb_dep_abast_agua_a ALTER COLUMN situacaofisica SET DEFAULT 999# ALTER TABLE cb.asb_dep_abast_agua_a ADD CONSTRAINT asb_dep_abast_agua_a_tipodepabast_fk FOREIGN KEY (tipodepabast) @@ -3042,16 +3042,16 @@ ALTER TABLE cb.asb_dep_abast_agua_p REFERENCES dominios.construcao (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.asb_dep_abast_agua_p - ADD CONSTRAINT asb_dep_abast_agua_p_construcao_check - CHECK (construcao = ANY(ARRAY[1 :: SMALLINT, 2 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT asb_dep_abast_agua_p_construcao_check + CHECK (construcao = ANY(ARRAY[1 :: SMALLINT, 2 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.asb_dep_abast_agua_p ALTER COLUMN construcao SET DEFAULT 999# ALTER TABLE cb.asb_dep_abast_agua_p ADD CONSTRAINT asb_dep_abast_agua_p_finalidade_fk FOREIGN KEY (finalidade) REFERENCES dominios.finalidade_asb (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.asb_dep_abast_agua_p - ADD CONSTRAINT asb_dep_abast_agua_p_finalidade_check - CHECK (finalidade = ANY(ARRAY[2 :: SMALLINT, 3 :: SMALLINT, 4 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT asb_dep_abast_agua_p_finalidade_check + CHECK (finalidade = ANY(ARRAY[2 :: SMALLINT, 3 :: SMALLINT, 4 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.asb_dep_abast_agua_p ALTER COLUMN finalidade SET DEFAULT 999# ALTER TABLE cb.asb_dep_abast_agua_p ADD CONSTRAINT asb_dep_abast_agua_p_geometriaaproximada_fk FOREIGN KEY (geometriaaproximada) @@ -3063,8 +3063,8 @@ ALTER TABLE cb.asb_dep_abast_agua_p REFERENCES dominios.matconstr (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.asb_dep_abast_agua_p - ADD CONSTRAINT asb_dep_abast_agua_p_matconstr_check - CHECK (matconstr = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 4 :: SMALLINT, 97 :: SMALLINT, 99 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT asb_dep_abast_agua_p_matconstr_check + CHECK (matconstr = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 4 :: SMALLINT, 97 :: SMALLINT, 99 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.asb_dep_abast_agua_p ALTER COLUMN matconstr SET DEFAULT 999# ALTER TABLE cb.asb_dep_abast_agua_p ADD CONSTRAINT asb_dep_abast_agua_p_operacional_fk FOREIGN KEY (operacional) @@ -3081,8 +3081,8 @@ ALTER TABLE cb.asb_dep_abast_agua_p REFERENCES dominios.situacaofisica (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.asb_dep_abast_agua_p - ADD CONSTRAINT asb_dep_abast_agua_p_situacaofisica_check - CHECK (situacaofisica = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT asb_dep_abast_agua_p_situacaofisica_check + CHECK (situacaofisica = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.asb_dep_abast_agua_p ALTER COLUMN situacaofisica SET DEFAULT 999# ALTER TABLE cb.asb_dep_abast_agua_p ADD CONSTRAINT asb_dep_abast_agua_p_tipodepabast_fk FOREIGN KEY (tipodepabast) @@ -3117,8 +3117,8 @@ ALTER TABLE cb.asb_dep_saneamento_a REFERENCES dominios.finalidade_asb (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.asb_dep_saneamento_a - ADD CONSTRAINT asb_dep_saneamento_a_finalidade_check - CHECK (finalidade = ANY(ARRAY[0 :: SMALLINT, 2 :: SMALLINT, 8 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT asb_dep_saneamento_a_finalidade_check + CHECK (finalidade = ANY(ARRAY[0 :: SMALLINT, 2 :: SMALLINT, 8 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.asb_dep_saneamento_a ALTER COLUMN finalidade SET DEFAULT 999# ALTER TABLE cb.asb_dep_saneamento_a ADD CONSTRAINT asb_dep_saneamento_a_geometriaaproximada_fk FOREIGN KEY (geometriaaproximada) @@ -3130,8 +3130,8 @@ ALTER TABLE cb.asb_dep_saneamento_a REFERENCES dominios.matconstr (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.asb_dep_saneamento_a - ADD CONSTRAINT asb_dep_saneamento_a_matconstr_check - CHECK (matconstr = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 4 :: SMALLINT, 97 :: SMALLINT, 99 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT asb_dep_saneamento_a_matconstr_check + CHECK (matconstr = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 4 :: SMALLINT, 97 :: SMALLINT, 99 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.asb_dep_saneamento_a ALTER COLUMN matconstr SET DEFAULT 999# ALTER TABLE cb.asb_dep_saneamento_a ADD CONSTRAINT asb_dep_saneamento_a_operacional_fk FOREIGN KEY (operacional) @@ -3148,8 +3148,8 @@ ALTER TABLE cb.asb_dep_saneamento_a REFERENCES dominios.situacaofisica (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.asb_dep_saneamento_a - ADD CONSTRAINT asb_dep_saneamento_a_situacaofisica_check - CHECK (situacaofisica = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT asb_dep_saneamento_a_situacaofisica_check + CHECK (situacaofisica = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.asb_dep_saneamento_a ALTER COLUMN situacaofisica SET DEFAULT 999# ALTER TABLE cb.asb_dep_saneamento_a ADD CONSTRAINT asb_dep_saneamento_a_tipodepsaneam_fk FOREIGN KEY (tipodepsaneam) @@ -3189,8 +3189,8 @@ ALTER TABLE cb.asb_dep_saneamento_p REFERENCES dominios.finalidade_asb (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.asb_dep_saneamento_p - ADD CONSTRAINT asb_dep_saneamento_p_finalidade_check - CHECK (finalidade = ANY(ARRAY[0 :: SMALLINT, 2 :: SMALLINT, 8 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT asb_dep_saneamento_p_finalidade_check + CHECK (finalidade = ANY(ARRAY[0 :: SMALLINT, 2 :: SMALLINT, 8 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.asb_dep_saneamento_p ALTER COLUMN finalidade SET DEFAULT 999# ALTER TABLE cb.asb_dep_saneamento_p ADD CONSTRAINT asb_dep_saneamento_p_geometriaaproximada_fk FOREIGN KEY (geometriaaproximada) @@ -3202,8 +3202,8 @@ ALTER TABLE cb.asb_dep_saneamento_p REFERENCES dominios.matconstr (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.asb_dep_saneamento_p - ADD CONSTRAINT asb_dep_saneamento_p_matconstr_check - CHECK (matconstr = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 4 :: SMALLINT, 97 :: SMALLINT, 99 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT asb_dep_saneamento_p_matconstr_check + CHECK (matconstr = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 4 :: SMALLINT, 97 :: SMALLINT, 99 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.asb_dep_saneamento_p ALTER COLUMN matconstr SET DEFAULT 999# ALTER TABLE cb.asb_dep_saneamento_p ADD CONSTRAINT asb_dep_saneamento_p_operacional_fk FOREIGN KEY (operacional) @@ -3220,8 +3220,8 @@ ALTER TABLE cb.asb_dep_saneamento_p REFERENCES dominios.situacaofisica (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.asb_dep_saneamento_p - ADD CONSTRAINT asb_dep_saneamento_p_situacaofisica_check - CHECK (situacaofisica = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT asb_dep_saneamento_p_situacaofisica_check + CHECK (situacaofisica = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.asb_dep_saneamento_p ALTER COLUMN situacaofisica SET DEFAULT 999# ALTER TABLE cb.asb_dep_saneamento_p ADD CONSTRAINT asb_dep_saneamento_p_tipodepsaneam_fk FOREIGN KEY (tipodepsaneam) @@ -3296,8 +3296,8 @@ ALTER TABLE cb.asb_edif_abast_agua_a REFERENCES dominios.matconstr (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.asb_edif_abast_agua_a - ADD CONSTRAINT asb_edif_abast_agua_a_matconstr_check - CHECK (matconstr = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 4 :: SMALLINT, 5 :: SMALLINT, 97 :: SMALLINT, 99 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT asb_edif_abast_agua_a_matconstr_check + CHECK (matconstr = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 4 :: SMALLINT, 5 :: SMALLINT, 97 :: SMALLINT, 99 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.asb_edif_abast_agua_a ALTER COLUMN matconstr SET DEFAULT 999# ALTER TABLE cb.asb_edif_abast_agua_a ADD CONSTRAINT asb_edif_abast_agua_a_operacional_fk FOREIGN KEY (operacional) @@ -3338,8 +3338,8 @@ ALTER TABLE cb.asb_edif_abast_agua_p REFERENCES dominios.matconstr (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.asb_edif_abast_agua_p - ADD CONSTRAINT asb_edif_abast_agua_p_matconstr_check - CHECK (matconstr = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 4 :: SMALLINT, 5 :: SMALLINT, 97 :: SMALLINT, 99 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT asb_edif_abast_agua_p_matconstr_check + CHECK (matconstr = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 4 :: SMALLINT, 5 :: SMALLINT, 97 :: SMALLINT, 99 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.asb_edif_abast_agua_p ALTER COLUMN matconstr SET DEFAULT 999# ALTER TABLE cb.asb_edif_abast_agua_p ADD CONSTRAINT asb_edif_abast_agua_p_operacional_fk FOREIGN KEY (operacional) @@ -3380,8 +3380,8 @@ ALTER TABLE cb.asb_edif_saneamento_a REFERENCES dominios.matconstr (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.asb_edif_saneamento_a - ADD CONSTRAINT asb_edif_saneamento_a_matconstr_check - CHECK (matconstr = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 4 :: SMALLINT, 5 :: SMALLINT, 97 :: SMALLINT, 99 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT asb_edif_saneamento_a_matconstr_check + CHECK (matconstr = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 4 :: SMALLINT, 5 :: SMALLINT, 97 :: SMALLINT, 99 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.asb_edif_saneamento_a ALTER COLUMN matconstr SET DEFAULT 999# ALTER TABLE cb.asb_edif_saneamento_a ADD CONSTRAINT asb_edif_saneamento_a_operacional_fk FOREIGN KEY (operacional) @@ -3422,8 +3422,8 @@ ALTER TABLE cb.asb_edif_saneamento_p REFERENCES dominios.matconstr (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.asb_edif_saneamento_p - ADD CONSTRAINT asb_edif_saneamento_p_matconstr_check - CHECK (matconstr = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 4 :: SMALLINT, 5 :: SMALLINT, 97 :: SMALLINT, 99 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT asb_edif_saneamento_p_matconstr_check + CHECK (matconstr = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 4 :: SMALLINT, 5 :: SMALLINT, 97 :: SMALLINT, 99 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.asb_edif_saneamento_p ALTER COLUMN matconstr SET DEFAULT 999# ALTER TABLE cb.asb_edif_saneamento_p ADD CONSTRAINT asb_edif_saneamento_p_operacional_fk FOREIGN KEY (operacional) @@ -3528,8 +3528,8 @@ ALTER TABLE cb.eco_deposito_geral_a REFERENCES dominios.matconstr (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.eco_deposito_geral_a - ADD CONSTRAINT eco_deposito_geral_a_matconstr_check - CHECK (matconstr = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 4 :: SMALLINT, 5 :: SMALLINT, 97 :: SMALLINT, 99 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT eco_deposito_geral_a_matconstr_check + CHECK (matconstr = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 4 :: SMALLINT, 5 :: SMALLINT, 97 :: SMALLINT, 99 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.eco_deposito_geral_a ALTER COLUMN matconstr SET DEFAULT 999# ALTER TABLE cb.eco_deposito_geral_a ADD CONSTRAINT eco_deposito_geral_a_operacional_fk FOREIGN KEY (operacional) @@ -3541,8 +3541,8 @@ ALTER TABLE cb.eco_deposito_geral_a REFERENCES dominios.situacaofisica (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.eco_deposito_geral_a - ADD CONSTRAINT eco_deposito_geral_a_situacaofisica_check - CHECK (situacaofisica = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT eco_deposito_geral_a_situacaofisica_check + CHECK (situacaofisica = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.eco_deposito_geral_a ALTER COLUMN situacaofisica SET DEFAULT 999# ALTER TABLE cb.eco_deposito_geral_a ADD CONSTRAINT eco_deposito_geral_a_tipoconteudo_fk FOREIGN KEY (tipoconteudo) @@ -3564,8 +3564,8 @@ ALTER TABLE cb.eco_deposito_geral_a REFERENCES dominios.tipoprodutoresiduo (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.eco_deposito_geral_a - ADD CONSTRAINT eco_deposito_geral_a_tipoprodutoresiduo_check - CHECK (tipoprodutoresiduo = ANY(ARRAY[0 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 6 :: SMALLINT, 16 :: SMALLINT, 17 :: SMALLINT, 18 :: SMALLINT, 19 :: SMALLINT, 20 :: SMALLINT, 21 :: SMALLINT, 22 :: SMALLINT, 23 :: SMALLINT, 24 :: SMALLINT, 25 :: SMALLINT, 26 :: SMALLINT, 27 :: SMALLINT, 28 :: SMALLINT, 29 :: SMALLINT, 30 :: SMALLINT, 31 :: SMALLINT, 32 :: SMALLINT, 33 :: SMALLINT, 34 :: SMALLINT, 35 :: SMALLINT, 36 :: SMALLINT, 41 :: SMALLINT, 98 :: SMALLINT, 99 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT eco_deposito_geral_a_tipoprodutoresiduo_check + CHECK (tipoprodutoresiduo = ANY(ARRAY[0 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 6 :: SMALLINT, 16 :: SMALLINT, 17 :: SMALLINT, 18 :: SMALLINT, 19 :: SMALLINT, 20 :: SMALLINT, 21 :: SMALLINT, 22 :: SMALLINT, 23 :: SMALLINT, 24 :: SMALLINT, 25 :: SMALLINT, 26 :: SMALLINT, 27 :: SMALLINT, 28 :: SMALLINT, 29 :: SMALLINT, 30 :: SMALLINT, 31 :: SMALLINT, 32 :: SMALLINT, 33 :: SMALLINT, 34 :: SMALLINT, 35 :: SMALLINT, 36 :: SMALLINT, 41 :: SMALLINT, 98 :: SMALLINT, 99 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.eco_deposito_geral_a ALTER COLUMN tipoprodutoresiduo SET DEFAULT 999# ALTER TABLE cb.eco_deposito_geral_a ADD CONSTRAINT eco_deposito_geral_a_tratamento_fk FOREIGN KEY (tratamento) @@ -3607,8 +3607,8 @@ ALTER TABLE cb.eco_deposito_geral_p REFERENCES dominios.matconstr (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.eco_deposito_geral_p - ADD CONSTRAINT eco_deposito_geral_p_matconstr_check - CHECK (matconstr = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 4 :: SMALLINT, 5 :: SMALLINT, 97 :: SMALLINT, 99 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT eco_deposito_geral_p_matconstr_check + CHECK (matconstr = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 4 :: SMALLINT, 5 :: SMALLINT, 97 :: SMALLINT, 99 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.eco_deposito_geral_p ALTER COLUMN matconstr SET DEFAULT 999# ALTER TABLE cb.eco_deposito_geral_p ADD CONSTRAINT eco_deposito_geral_p_operacional_fk FOREIGN KEY (operacional) @@ -3620,8 +3620,8 @@ ALTER TABLE cb.eco_deposito_geral_p REFERENCES dominios.situacaofisica (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.eco_deposito_geral_p - ADD CONSTRAINT eco_deposito_geral_p_situacaofisica_check - CHECK (situacaofisica = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT eco_deposito_geral_p_situacaofisica_check + CHECK (situacaofisica = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.eco_deposito_geral_p ALTER COLUMN situacaofisica SET DEFAULT 999# ALTER TABLE cb.eco_deposito_geral_p ADD CONSTRAINT eco_deposito_geral_p_tipoconteudo_fk FOREIGN KEY (tipoconteudo) @@ -3643,8 +3643,8 @@ ALTER TABLE cb.eco_deposito_geral_p REFERENCES dominios.tipoprodutoresiduo (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.eco_deposito_geral_p - ADD CONSTRAINT eco_deposito_geral_p_tipoprodutoresiduo_check - CHECK (tipoprodutoresiduo = ANY(ARRAY[0 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 6 :: SMALLINT, 16 :: SMALLINT, 17 :: SMALLINT, 18 :: SMALLINT, 19 :: SMALLINT, 20 :: SMALLINT, 21 :: SMALLINT, 22 :: SMALLINT, 23 :: SMALLINT, 24 :: SMALLINT, 25 :: SMALLINT, 26 :: SMALLINT, 27 :: SMALLINT, 28 :: SMALLINT, 29 :: SMALLINT, 30 :: SMALLINT, 31 :: SMALLINT, 32 :: SMALLINT, 33 :: SMALLINT, 34 :: SMALLINT, 35 :: SMALLINT, 36 :: SMALLINT, 41 :: SMALLINT, 98 :: SMALLINT, 99 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT eco_deposito_geral_p_tipoprodutoresiduo_check + CHECK (tipoprodutoresiduo = ANY(ARRAY[0 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 6 :: SMALLINT, 16 :: SMALLINT, 17 :: SMALLINT, 18 :: SMALLINT, 19 :: SMALLINT, 20 :: SMALLINT, 21 :: SMALLINT, 22 :: SMALLINT, 23 :: SMALLINT, 24 :: SMALLINT, 25 :: SMALLINT, 26 :: SMALLINT, 27 :: SMALLINT, 28 :: SMALLINT, 29 :: SMALLINT, 30 :: SMALLINT, 31 :: SMALLINT, 32 :: SMALLINT, 33 :: SMALLINT, 34 :: SMALLINT, 35 :: SMALLINT, 36 :: SMALLINT, 41 :: SMALLINT, 98 :: SMALLINT, 99 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.eco_deposito_geral_p ALTER COLUMN tipoprodutoresiduo SET DEFAULT 999# ALTER TABLE cb.eco_deposito_geral_p ADD CONSTRAINT eco_deposito_geral_p_tratamento_fk FOREIGN KEY (tratamento) @@ -3719,8 +3719,8 @@ ALTER TABLE cb.eco_edif_agrop_ext_veg_pesca_a REFERENCES dominios.matconstr (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.eco_edif_agrop_ext_veg_pesca_a - ADD CONSTRAINT eco_edif_agrop_ext_veg_pesca_a_matconstr_check - CHECK (matconstr = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 3 :: SMALLINT, 4 :: SMALLINT, 5 :: SMALLINT, 99 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT eco_edif_agrop_ext_veg_pesca_a_matconstr_check + CHECK (matconstr = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 3 :: SMALLINT, 4 :: SMALLINT, 5 :: SMALLINT, 99 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.eco_edif_agrop_ext_veg_pesca_a ALTER COLUMN matconstr SET DEFAULT 999# ALTER TABLE cb.eco_edif_agrop_ext_veg_pesca_a ADD CONSTRAINT eco_edif_agrop_ext_veg_pesca_a_operacional_fk FOREIGN KEY (operacional) @@ -3732,8 +3732,8 @@ ALTER TABLE cb.eco_edif_agrop_ext_veg_pesca_a REFERENCES dominios.situacaofisica (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.eco_edif_agrop_ext_veg_pesca_a - ADD CONSTRAINT eco_edif_agrop_ext_veg_pesca_a_situacaofisica_check - CHECK (situacaofisica = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT eco_edif_agrop_ext_veg_pesca_a_situacaofisica_check + CHECK (situacaofisica = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.eco_edif_agrop_ext_veg_pesca_a ALTER COLUMN situacaofisica SET DEFAULT 999# ALTER TABLE cb.eco_edif_agrop_ext_veg_pesca_a ADD CONSTRAINT eco_edif_agrop_ext_veg_pesca_a_tipoedifagropec_fk FOREIGN KEY (tipoedifagropec) @@ -3764,8 +3764,8 @@ ALTER TABLE cb.eco_edif_agrop_ext_veg_pesca_p REFERENCES dominios.matconstr (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.eco_edif_agrop_ext_veg_pesca_p - ADD CONSTRAINT eco_edif_agrop_ext_veg_pesca_p_matconstr_check - CHECK (matconstr = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 3 :: SMALLINT, 4 :: SMALLINT, 5 :: SMALLINT, 99 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT eco_edif_agrop_ext_veg_pesca_p_matconstr_check + CHECK (matconstr = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 3 :: SMALLINT, 4 :: SMALLINT, 5 :: SMALLINT, 99 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.eco_edif_agrop_ext_veg_pesca_p ALTER COLUMN matconstr SET DEFAULT 999# ALTER TABLE cb.eco_edif_agrop_ext_veg_pesca_p ADD CONSTRAINT eco_edif_agrop_ext_veg_pesca_p_operacional_fk FOREIGN KEY (operacional) @@ -3777,8 +3777,8 @@ ALTER TABLE cb.eco_edif_agrop_ext_veg_pesca_p REFERENCES dominios.situacaofisica (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.eco_edif_agrop_ext_veg_pesca_p - ADD CONSTRAINT eco_edif_agrop_ext_veg_pesca_p_situacaofisica_check - CHECK (situacaofisica = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT eco_edif_agrop_ext_veg_pesca_p_situacaofisica_check + CHECK (situacaofisica = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.eco_edif_agrop_ext_veg_pesca_p ALTER COLUMN situacaofisica SET DEFAULT 999# ALTER TABLE cb.eco_edif_agrop_ext_veg_pesca_p ADD CONSTRAINT eco_edif_agrop_ext_veg_pesca_p_tipoedifagropec_fk FOREIGN KEY (tipoedifagropec) @@ -3815,8 +3815,8 @@ ALTER TABLE cb.eco_edif_comerc_serv_a REFERENCES dominios.matconstr (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.eco_edif_comerc_serv_a - ADD CONSTRAINT eco_edif_comerc_serv_a_matconstr_check - CHECK (matconstr = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 4 :: SMALLINT, 5 :: SMALLINT, 97 :: SMALLINT, 99 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT eco_edif_comerc_serv_a_matconstr_check + CHECK (matconstr = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 4 :: SMALLINT, 5 :: SMALLINT, 97 :: SMALLINT, 99 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.eco_edif_comerc_serv_a ALTER COLUMN matconstr SET DEFAULT 999# ALTER TABLE cb.eco_edif_comerc_serv_a ADD CONSTRAINT eco_edif_comerc_serv_a_operacional_fk FOREIGN KEY (operacional) @@ -3828,8 +3828,8 @@ ALTER TABLE cb.eco_edif_comerc_serv_a REFERENCES dominios.situacaofisica (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.eco_edif_comerc_serv_a - ADD CONSTRAINT eco_edif_comerc_serv_a_situacaofisica_check - CHECK (situacaofisica = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT eco_edif_comerc_serv_a_situacaofisica_check + CHECK (situacaofisica = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.eco_edif_comerc_serv_a ALTER COLUMN situacaofisica SET DEFAULT 999# ALTER TABLE cb.eco_edif_comerc_serv_a ADD CONSTRAINT eco_edif_comerc_serv_a_tipoedifcomercserv_fk FOREIGN KEY (tipoedifcomercserv) @@ -3866,8 +3866,8 @@ ALTER TABLE cb.eco_edif_comerc_serv_p REFERENCES dominios.matconstr (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.eco_edif_comerc_serv_p - ADD CONSTRAINT eco_edif_comerc_serv_p_matconstr_check - CHECK (matconstr = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 4 :: SMALLINT, 5 :: SMALLINT, 97 :: SMALLINT, 99 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT eco_edif_comerc_serv_p_matconstr_check + CHECK (matconstr = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 4 :: SMALLINT, 5 :: SMALLINT, 97 :: SMALLINT, 99 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.eco_edif_comerc_serv_p ALTER COLUMN matconstr SET DEFAULT 999# ALTER TABLE cb.eco_edif_comerc_serv_p ADD CONSTRAINT eco_edif_comerc_serv_p_operacional_fk FOREIGN KEY (operacional) @@ -3879,8 +3879,8 @@ ALTER TABLE cb.eco_edif_comerc_serv_p REFERENCES dominios.situacaofisica (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.eco_edif_comerc_serv_p - ADD CONSTRAINT eco_edif_comerc_serv_p_situacaofisica_check - CHECK (situacaofisica = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT eco_edif_comerc_serv_p_situacaofisica_check + CHECK (situacaofisica = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.eco_edif_comerc_serv_p ALTER COLUMN situacaofisica SET DEFAULT 999# ALTER TABLE cb.eco_edif_comerc_serv_p ADD CONSTRAINT eco_edif_comerc_serv_p_tipoedifcomercserv_fk FOREIGN KEY (tipoedifcomercserv) @@ -3911,8 +3911,8 @@ ALTER TABLE cb.eco_edif_ext_mineral_a REFERENCES dominios.matconstr (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.eco_edif_ext_mineral_a - ADD CONSTRAINT eco_edif_ext_mineral_a_matconstr_check - CHECK (matconstr = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 4 :: SMALLINT, 5 :: SMALLINT, 97 :: SMALLINT, 99 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT eco_edif_ext_mineral_a_matconstr_check + CHECK (matconstr = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 4 :: SMALLINT, 5 :: SMALLINT, 97 :: SMALLINT, 99 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.eco_edif_ext_mineral_a ALTER COLUMN matconstr SET DEFAULT 999# ALTER TABLE cb.eco_edif_ext_mineral_a ADD CONSTRAINT eco_edif_ext_mineral_a_operacional_fk FOREIGN KEY (operacional) @@ -3924,16 +3924,16 @@ ALTER TABLE cb.eco_edif_ext_mineral_a REFERENCES dominios.situacaofisica (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.eco_edif_ext_mineral_a - ADD CONSTRAINT eco_edif_ext_mineral_a_situacaofisica_check - CHECK (situacaofisica = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT eco_edif_ext_mineral_a_situacaofisica_check + CHECK (situacaofisica = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.eco_edif_ext_mineral_a ALTER COLUMN situacaofisica SET DEFAULT 999# ALTER TABLE cb.eco_edif_ext_mineral_a ADD CONSTRAINT eco_edif_ext_mineral_a_tipodivisaocnae_fk FOREIGN KEY (tipodivisaocnae) REFERENCES dominios.tipodivisaocnae (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.eco_edif_ext_mineral_a - ADD CONSTRAINT eco_edif_ext_mineral_a_tipodivisaocnae_check - CHECK (tipodivisaocnae = ANY(ARRAY[0 :: SMALLINT, 10 :: SMALLINT, 11 :: SMALLINT, 13 :: SMALLINT, 14 :: SMALLINT, 99 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT eco_edif_ext_mineral_a_tipodivisaocnae_check + CHECK (tipodivisaocnae = ANY(ARRAY[0 :: SMALLINT, 10 :: SMALLINT, 11 :: SMALLINT, 13 :: SMALLINT, 14 :: SMALLINT, 99 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.eco_edif_ext_mineral_a ALTER COLUMN tipodivisaocnae SET DEFAULT 999# CREATE TABLE cb.eco_edif_ext_mineral_p( id serial NOT NULL, @@ -3959,8 +3959,8 @@ ALTER TABLE cb.eco_edif_ext_mineral_p REFERENCES dominios.matconstr (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.eco_edif_ext_mineral_p - ADD CONSTRAINT eco_edif_ext_mineral_p_matconstr_check - CHECK (matconstr = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 4 :: SMALLINT, 5 :: SMALLINT, 97 :: SMALLINT, 99 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT eco_edif_ext_mineral_p_matconstr_check + CHECK (matconstr = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 4 :: SMALLINT, 5 :: SMALLINT, 97 :: SMALLINT, 99 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.eco_edif_ext_mineral_p ALTER COLUMN matconstr SET DEFAULT 999# ALTER TABLE cb.eco_edif_ext_mineral_p ADD CONSTRAINT eco_edif_ext_mineral_p_operacional_fk FOREIGN KEY (operacional) @@ -3972,16 +3972,16 @@ ALTER TABLE cb.eco_edif_ext_mineral_p REFERENCES dominios.situacaofisica (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.eco_edif_ext_mineral_p - ADD CONSTRAINT eco_edif_ext_mineral_p_situacaofisica_check - CHECK (situacaofisica = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT eco_edif_ext_mineral_p_situacaofisica_check + CHECK (situacaofisica = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.eco_edif_ext_mineral_p ALTER COLUMN situacaofisica SET DEFAULT 999# ALTER TABLE cb.eco_edif_ext_mineral_p ADD CONSTRAINT eco_edif_ext_mineral_p_tipodivisaocnae_fk FOREIGN KEY (tipodivisaocnae) REFERENCES dominios.tipodivisaocnae (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.eco_edif_ext_mineral_p - ADD CONSTRAINT eco_edif_ext_mineral_p_tipodivisaocnae_check - CHECK (tipodivisaocnae = ANY(ARRAY[0 :: SMALLINT, 10 :: SMALLINT, 11 :: SMALLINT, 13 :: SMALLINT, 14 :: SMALLINT, 99 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT eco_edif_ext_mineral_p_tipodivisaocnae_check + CHECK (tipodivisaocnae = ANY(ARRAY[0 :: SMALLINT, 10 :: SMALLINT, 11 :: SMALLINT, 13 :: SMALLINT, 14 :: SMALLINT, 99 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.eco_edif_ext_mineral_p ALTER COLUMN tipodivisaocnae SET DEFAULT 999# CREATE TABLE cb.eco_edif_industrial_a( id serial NOT NULL, @@ -4013,8 +4013,8 @@ ALTER TABLE cb.eco_edif_industrial_a REFERENCES dominios.matconstr (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.eco_edif_industrial_a - ADD CONSTRAINT eco_edif_industrial_a_matconstr_check - CHECK (matconstr = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 4 :: SMALLINT, 5 :: SMALLINT, 97 :: SMALLINT, 99 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT eco_edif_industrial_a_matconstr_check + CHECK (matconstr = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 4 :: SMALLINT, 5 :: SMALLINT, 97 :: SMALLINT, 99 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.eco_edif_industrial_a ALTER COLUMN matconstr SET DEFAULT 999# ALTER TABLE cb.eco_edif_industrial_a ADD CONSTRAINT eco_edif_industrial_a_operacional_fk FOREIGN KEY (operacional) @@ -4026,16 +4026,16 @@ ALTER TABLE cb.eco_edif_industrial_a REFERENCES dominios.situacaofisica (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.eco_edif_industrial_a - ADD CONSTRAINT eco_edif_industrial_a_situacaofisica_check - CHECK (situacaofisica = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT eco_edif_industrial_a_situacaofisica_check + CHECK (situacaofisica = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.eco_edif_industrial_a ALTER COLUMN situacaofisica SET DEFAULT 999# ALTER TABLE cb.eco_edif_industrial_a ADD CONSTRAINT eco_edif_industrial_a_tipodivisaocnae_fk FOREIGN KEY (tipodivisaocnae) REFERENCES dominios.tipodivisaocnae (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.eco_edif_industrial_a - ADD CONSTRAINT eco_edif_industrial_a_tipodivisaocnae_check - CHECK (tipodivisaocnae = ANY(ARRAY[0 :: SMALLINT, 15 :: SMALLINT, 16 :: SMALLINT, 17 :: SMALLINT, 18 :: SMALLINT, 19 :: SMALLINT, 20 :: SMALLINT, 21 :: SMALLINT, 22 :: SMALLINT, 23 :: SMALLINT, 24 :: SMALLINT, 25 :: SMALLINT, 26 :: SMALLINT, 27 :: SMALLINT, 28 :: SMALLINT, 29 :: SMALLINT, 30 :: SMALLINT, 31 :: SMALLINT, 32 :: SMALLINT, 33 :: SMALLINT, 34 :: SMALLINT, 35 :: SMALLINT, 36 :: SMALLINT, 37 :: SMALLINT, 45 :: SMALLINT, 99 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT eco_edif_industrial_a_tipodivisaocnae_check + CHECK (tipodivisaocnae = ANY(ARRAY[0 :: SMALLINT, 15 :: SMALLINT, 16 :: SMALLINT, 17 :: SMALLINT, 18 :: SMALLINT, 19 :: SMALLINT, 20 :: SMALLINT, 21 :: SMALLINT, 22 :: SMALLINT, 23 :: SMALLINT, 24 :: SMALLINT, 25 :: SMALLINT, 26 :: SMALLINT, 27 :: SMALLINT, 28 :: SMALLINT, 29 :: SMALLINT, 30 :: SMALLINT, 31 :: SMALLINT, 32 :: SMALLINT, 33 :: SMALLINT, 34 :: SMALLINT, 35 :: SMALLINT, 36 :: SMALLINT, 37 :: SMALLINT, 45 :: SMALLINT, 99 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.eco_edif_industrial_a ALTER COLUMN tipodivisaocnae SET DEFAULT 999# CREATE TABLE cb.eco_edif_industrial_p( id serial NOT NULL, @@ -4067,8 +4067,8 @@ ALTER TABLE cb.eco_edif_industrial_p REFERENCES dominios.matconstr (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.eco_edif_industrial_p - ADD CONSTRAINT eco_edif_industrial_p_matconstr_check - CHECK (matconstr = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 4 :: SMALLINT, 5 :: SMALLINT, 97 :: SMALLINT, 99 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT eco_edif_industrial_p_matconstr_check + CHECK (matconstr = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 4 :: SMALLINT, 5 :: SMALLINT, 97 :: SMALLINT, 99 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.eco_edif_industrial_p ALTER COLUMN matconstr SET DEFAULT 999# ALTER TABLE cb.eco_edif_industrial_p ADD CONSTRAINT eco_edif_industrial_p_operacional_fk FOREIGN KEY (operacional) @@ -4080,16 +4080,16 @@ ALTER TABLE cb.eco_edif_industrial_p REFERENCES dominios.situacaofisica (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.eco_edif_industrial_p - ADD CONSTRAINT eco_edif_industrial_p_situacaofisica_check - CHECK (situacaofisica = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT eco_edif_industrial_p_situacaofisica_check + CHECK (situacaofisica = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.eco_edif_industrial_p ALTER COLUMN situacaofisica SET DEFAULT 999# ALTER TABLE cb.eco_edif_industrial_p ADD CONSTRAINT eco_edif_industrial_p_tipodivisaocnae_fk FOREIGN KEY (tipodivisaocnae) REFERENCES dominios.tipodivisaocnae (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.eco_edif_industrial_p - ADD CONSTRAINT eco_edif_industrial_p_tipodivisaocnae_check - CHECK (tipodivisaocnae = ANY(ARRAY[0 :: SMALLINT, 15 :: SMALLINT, 16 :: SMALLINT, 17 :: SMALLINT, 18 :: SMALLINT, 19 :: SMALLINT, 20 :: SMALLINT, 21 :: SMALLINT, 22 :: SMALLINT, 23 :: SMALLINT, 24 :: SMALLINT, 25 :: SMALLINT, 26 :: SMALLINT, 27 :: SMALLINT, 28 :: SMALLINT, 29 :: SMALLINT, 30 :: SMALLINT, 31 :: SMALLINT, 32 :: SMALLINT, 33 :: SMALLINT, 34 :: SMALLINT, 35 :: SMALLINT, 36 :: SMALLINT, 37 :: SMALLINT, 45 :: SMALLINT, 99 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT eco_edif_industrial_p_tipodivisaocnae_check + CHECK (tipodivisaocnae = ANY(ARRAY[0 :: SMALLINT, 15 :: SMALLINT, 16 :: SMALLINT, 17 :: SMALLINT, 18 :: SMALLINT, 19 :: SMALLINT, 20 :: SMALLINT, 21 :: SMALLINT, 22 :: SMALLINT, 23 :: SMALLINT, 24 :: SMALLINT, 25 :: SMALLINT, 26 :: SMALLINT, 27 :: SMALLINT, 28 :: SMALLINT, 29 :: SMALLINT, 30 :: SMALLINT, 31 :: SMALLINT, 32 :: SMALLINT, 33 :: SMALLINT, 34 :: SMALLINT, 35 :: SMALLINT, 36 :: SMALLINT, 37 :: SMALLINT, 45 :: SMALLINT, 99 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.eco_edif_industrial_p ALTER COLUMN tipodivisaocnae SET DEFAULT 999# CREATE TABLE cb.eco_equip_agropec_a( id serial NOT NULL, @@ -4115,8 +4115,8 @@ ALTER TABLE cb.eco_equip_agropec_a REFERENCES dominios.matconstr (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.eco_equip_agropec_a - ADD CONSTRAINT eco_equip_agropec_a_matconstr_check - CHECK (matconstr = ANY(ARRAY[0 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 99 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT eco_equip_agropec_a_matconstr_check + CHECK (matconstr = ANY(ARRAY[0 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 99 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.eco_equip_agropec_a ALTER COLUMN matconstr SET DEFAULT 999# ALTER TABLE cb.eco_equip_agropec_a ADD CONSTRAINT eco_equip_agropec_a_operacional_fk FOREIGN KEY (operacional) @@ -4128,8 +4128,8 @@ ALTER TABLE cb.eco_equip_agropec_a REFERENCES dominios.situacaofisica (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.eco_equip_agropec_a - ADD CONSTRAINT eco_equip_agropec_a_situacaofisica_check - CHECK (situacaofisica = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT eco_equip_agropec_a_situacaofisica_check + CHECK (situacaofisica = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.eco_equip_agropec_a ALTER COLUMN situacaofisica SET DEFAULT 999# ALTER TABLE cb.eco_equip_agropec_a ADD CONSTRAINT eco_equip_agropec_a_tipoequipagropec_fk FOREIGN KEY (tipoequipagropec) @@ -4160,8 +4160,8 @@ ALTER TABLE cb.eco_equip_agropec_l REFERENCES dominios.matconstr (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.eco_equip_agropec_l - ADD CONSTRAINT eco_equip_agropec_l_matconstr_check - CHECK (matconstr = ANY(ARRAY[0 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 99 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT eco_equip_agropec_l_matconstr_check + CHECK (matconstr = ANY(ARRAY[0 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 99 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.eco_equip_agropec_l ALTER COLUMN matconstr SET DEFAULT 999# ALTER TABLE cb.eco_equip_agropec_l ADD CONSTRAINT eco_equip_agropec_l_operacional_fk FOREIGN KEY (operacional) @@ -4173,8 +4173,8 @@ ALTER TABLE cb.eco_equip_agropec_l REFERENCES dominios.situacaofisica (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.eco_equip_agropec_l - ADD CONSTRAINT eco_equip_agropec_l_situacaofisica_check - CHECK (situacaofisica = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT eco_equip_agropec_l_situacaofisica_check + CHECK (situacaofisica = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.eco_equip_agropec_l ALTER COLUMN situacaofisica SET DEFAULT 999# ALTER TABLE cb.eco_equip_agropec_l ADD CONSTRAINT eco_equip_agropec_l_tipoequipagropec_fk FOREIGN KEY (tipoequipagropec) @@ -4205,8 +4205,8 @@ ALTER TABLE cb.eco_equip_agropec_p REFERENCES dominios.matconstr (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.eco_equip_agropec_p - ADD CONSTRAINT eco_equip_agropec_p_matconstr_check - CHECK (matconstr = ANY(ARRAY[0 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 99 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT eco_equip_agropec_p_matconstr_check + CHECK (matconstr = ANY(ARRAY[0 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 99 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.eco_equip_agropec_p ALTER COLUMN matconstr SET DEFAULT 999# ALTER TABLE cb.eco_equip_agropec_p ADD CONSTRAINT eco_equip_agropec_p_operacional_fk FOREIGN KEY (operacional) @@ -4218,8 +4218,8 @@ ALTER TABLE cb.eco_equip_agropec_p REFERENCES dominios.situacaofisica (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.eco_equip_agropec_p - ADD CONSTRAINT eco_equip_agropec_p_situacaofisica_check - CHECK (situacaofisica = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT eco_equip_agropec_p_situacaofisica_check + CHECK (situacaofisica = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.eco_equip_agropec_p ALTER COLUMN situacaofisica SET DEFAULT 999# ALTER TABLE cb.eco_equip_agropec_p ADD CONSTRAINT eco_equip_agropec_p_tipoequipagropec_fk FOREIGN KEY (tipoequipagropec) @@ -4275,8 +4275,8 @@ ALTER TABLE cb.eco_ext_mineral_a REFERENCES dominios.situacaofisica (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.eco_ext_mineral_a - ADD CONSTRAINT eco_ext_mineral_a_situacaofisica_check - CHECK (situacaofisica = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT eco_ext_mineral_a_situacaofisica_check + CHECK (situacaofisica = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.eco_ext_mineral_a ALTER COLUMN situacaofisica SET DEFAULT 999# ALTER TABLE cb.eco_ext_mineral_a ADD CONSTRAINT eco_ext_mineral_a_tipoextmin_fk FOREIGN KEY (tipoextmin) @@ -4293,16 +4293,16 @@ ALTER TABLE cb.eco_ext_mineral_a REFERENCES dominios.tipoprodutoresiduo (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.eco_ext_mineral_a - ADD CONSTRAINT eco_ext_mineral_a_tipoprodutoresiduo_check - CHECK (tipoprodutoresiduo = ANY(ARRAY[0 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 18 :: SMALLINT, 22 :: SMALLINT, 23 :: SMALLINT, 24 :: SMALLINT, 25 :: SMALLINT, 26 :: SMALLINT, 27 :: SMALLINT, 32 :: SMALLINT, 33 :: SMALLINT, 34 :: SMALLINT, 35 :: SMALLINT, 37 :: SMALLINT, 38 :: SMALLINT, 39 :: SMALLINT, 40 :: SMALLINT, 42 :: SMALLINT, 43 :: SMALLINT, 98 :: SMALLINT, 99 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT eco_ext_mineral_a_tipoprodutoresiduo_check + CHECK (tipoprodutoresiduo = ANY(ARRAY[0 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 18 :: SMALLINT, 22 :: SMALLINT, 23 :: SMALLINT, 24 :: SMALLINT, 25 :: SMALLINT, 26 :: SMALLINT, 27 :: SMALLINT, 32 :: SMALLINT, 33 :: SMALLINT, 34 :: SMALLINT, 35 :: SMALLINT, 37 :: SMALLINT, 38 :: SMALLINT, 39 :: SMALLINT, 40 :: SMALLINT, 42 :: SMALLINT, 43 :: SMALLINT, 98 :: SMALLINT, 99 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.eco_ext_mineral_a ALTER COLUMN tipoprodutoresiduo SET DEFAULT 999# ALTER TABLE cb.eco_ext_mineral_a ADD CONSTRAINT eco_ext_mineral_a_tiposecaocnae_fk FOREIGN KEY (tiposecaocnae) REFERENCES dominios.tiposecaocnae (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.eco_ext_mineral_a - ADD CONSTRAINT eco_ext_mineral_a_tiposecaocnae_check - CHECK (tiposecaocnae = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 99 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT eco_ext_mineral_a_tiposecaocnae_check + CHECK (tiposecaocnae = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 99 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.eco_ext_mineral_a ALTER COLUMN tiposecaocnae SET DEFAULT 999# CREATE TABLE cb.eco_ext_mineral_p( id serial NOT NULL, @@ -4353,8 +4353,8 @@ ALTER TABLE cb.eco_ext_mineral_p REFERENCES dominios.situacaofisica (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.eco_ext_mineral_p - ADD CONSTRAINT eco_ext_mineral_p_situacaofisica_check - CHECK (situacaofisica = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT eco_ext_mineral_p_situacaofisica_check + CHECK (situacaofisica = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.eco_ext_mineral_p ALTER COLUMN situacaofisica SET DEFAULT 999# ALTER TABLE cb.eco_ext_mineral_p ADD CONSTRAINT eco_ext_mineral_p_tipoextmin_fk FOREIGN KEY (tipoextmin) @@ -4371,16 +4371,16 @@ ALTER TABLE cb.eco_ext_mineral_p REFERENCES dominios.tipoprodutoresiduo (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.eco_ext_mineral_p - ADD CONSTRAINT eco_ext_mineral_p_tipoprodutoresiduo_check - CHECK (tipoprodutoresiduo = ANY(ARRAY[0 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 18 :: SMALLINT, 22 :: SMALLINT, 23 :: SMALLINT, 24 :: SMALLINT, 25 :: SMALLINT, 26 :: SMALLINT, 27 :: SMALLINT, 32 :: SMALLINT, 33 :: SMALLINT, 34 :: SMALLINT, 35 :: SMALLINT, 37 :: SMALLINT, 38 :: SMALLINT, 39 :: SMALLINT, 40 :: SMALLINT, 42 :: SMALLINT, 43 :: SMALLINT, 98 :: SMALLINT, 99 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT eco_ext_mineral_p_tipoprodutoresiduo_check + CHECK (tipoprodutoresiduo = ANY(ARRAY[0 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 18 :: SMALLINT, 22 :: SMALLINT, 23 :: SMALLINT, 24 :: SMALLINT, 25 :: SMALLINT, 26 :: SMALLINT, 27 :: SMALLINT, 32 :: SMALLINT, 33 :: SMALLINT, 34 :: SMALLINT, 35 :: SMALLINT, 37 :: SMALLINT, 38 :: SMALLINT, 39 :: SMALLINT, 40 :: SMALLINT, 42 :: SMALLINT, 43 :: SMALLINT, 98 :: SMALLINT, 99 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.eco_ext_mineral_p ALTER COLUMN tipoprodutoresiduo SET DEFAULT 999# ALTER TABLE cb.eco_ext_mineral_p ADD CONSTRAINT eco_ext_mineral_p_tiposecaocnae_fk FOREIGN KEY (tiposecaocnae) REFERENCES dominios.tiposecaocnae (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.eco_ext_mineral_p - ADD CONSTRAINT eco_ext_mineral_p_tiposecaocnae_check - CHECK (tiposecaocnae = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 99 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT eco_ext_mineral_p_tiposecaocnae_check + CHECK (tiposecaocnae = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 99 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.eco_ext_mineral_p ALTER COLUMN tiposecaocnae SET DEFAULT 999# CREATE TABLE cb.eco_plataforma_a( id serial NOT NULL, @@ -4503,8 +4503,8 @@ ALTER TABLE cb.edu_arquibancada_a REFERENCES dominios.situacaofisica (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.edu_arquibancada_a - ADD CONSTRAINT edu_arquibancada_a_situacaofisica_check - CHECK (situacaofisica = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT edu_arquibancada_a_situacaofisica_check + CHECK (situacaofisica = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.edu_arquibancada_a ALTER COLUMN situacaofisica SET DEFAULT 999# CREATE TABLE cb.edu_arquibancada_p( id serial NOT NULL, @@ -4533,8 +4533,8 @@ ALTER TABLE cb.edu_arquibancada_p REFERENCES dominios.situacaofisica (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.edu_arquibancada_p - ADD CONSTRAINT edu_arquibancada_p_situacaofisica_check - CHECK (situacaofisica = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT edu_arquibancada_p_situacaofisica_check + CHECK (situacaofisica = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.edu_arquibancada_p ALTER COLUMN situacaofisica SET DEFAULT 999# CREATE TABLE cb.edu_campo_quadra_a( id serial NOT NULL, @@ -4564,8 +4564,8 @@ ALTER TABLE cb.edu_campo_quadra_a REFERENCES dominios.situacaofisica (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.edu_campo_quadra_a - ADD CONSTRAINT edu_campo_quadra_a_situacaofisica_check - CHECK (situacaofisica = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT edu_campo_quadra_a_situacaofisica_check + CHECK (situacaofisica = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.edu_campo_quadra_a ALTER COLUMN situacaofisica SET DEFAULT 999# ALTER TABLE cb.edu_campo_quadra_a ADD CONSTRAINT edu_campo_quadra_a_tipocampoquadra_fk FOREIGN KEY (tipocampoquadra) @@ -4600,8 +4600,8 @@ ALTER TABLE cb.edu_campo_quadra_p REFERENCES dominios.situacaofisica (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.edu_campo_quadra_p - ADD CONSTRAINT edu_campo_quadra_p_situacaofisica_check - CHECK (situacaofisica = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT edu_campo_quadra_p_situacaofisica_check + CHECK (situacaofisica = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.edu_campo_quadra_p ALTER COLUMN situacaofisica SET DEFAULT 999# ALTER TABLE cb.edu_campo_quadra_p ADD CONSTRAINT edu_campo_quadra_p_tipocampoquadra_fk FOREIGN KEY (tipocampoquadra) @@ -4635,8 +4635,8 @@ ALTER TABLE cb.edu_coreto_tribuna_a REFERENCES dominios.situacaofisica (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.edu_coreto_tribuna_a - ADD CONSTRAINT edu_coreto_tribuna_a_situacaofisica_check - CHECK (situacaofisica = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT edu_coreto_tribuna_a_situacaofisica_check + CHECK (situacaofisica = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.edu_coreto_tribuna_a ALTER COLUMN situacaofisica SET DEFAULT 999# CREATE TABLE cb.edu_coreto_tribuna_p( id serial NOT NULL, @@ -4665,8 +4665,8 @@ ALTER TABLE cb.edu_coreto_tribuna_p REFERENCES dominios.situacaofisica (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.edu_coreto_tribuna_p - ADD CONSTRAINT edu_coreto_tribuna_p_situacaofisica_check - CHECK (situacaofisica = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT edu_coreto_tribuna_p_situacaofisica_check + CHECK (situacaofisica = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.edu_coreto_tribuna_p ALTER COLUMN situacaofisica SET DEFAULT 999# CREATE TABLE cb.edu_descontinuidade_geometrica_a( id serial NOT NULL, @@ -4731,8 +4731,8 @@ ALTER TABLE cb.edu_edif_const_lazer_a REFERENCES dominios.matconstr (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.edu_edif_const_lazer_a - ADD CONSTRAINT edu_edif_const_lazer_a_matconstr_check - CHECK (matconstr = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 4 :: SMALLINT, 5 :: SMALLINT, 97 :: SMALLINT, 99 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT edu_edif_const_lazer_a_matconstr_check + CHECK (matconstr = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 4 :: SMALLINT, 5 :: SMALLINT, 97 :: SMALLINT, 99 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.edu_edif_const_lazer_a ALTER COLUMN matconstr SET DEFAULT 999# ALTER TABLE cb.edu_edif_const_lazer_a ADD CONSTRAINT edu_edif_const_lazer_a_operacional_fk FOREIGN KEY (operacional) @@ -4744,8 +4744,8 @@ ALTER TABLE cb.edu_edif_const_lazer_a REFERENCES dominios.situacaofisica (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.edu_edif_const_lazer_a - ADD CONSTRAINT edu_edif_const_lazer_a_situacaofisica_check - CHECK (situacaofisica = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT edu_edif_const_lazer_a_situacaofisica_check + CHECK (situacaofisica = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.edu_edif_const_lazer_a ALTER COLUMN situacaofisica SET DEFAULT 999# ALTER TABLE cb.edu_edif_const_lazer_a ADD CONSTRAINT edu_edif_const_lazer_a_tipoediflazer_fk FOREIGN KEY (tipoediflazer) @@ -4776,8 +4776,8 @@ ALTER TABLE cb.edu_edif_const_lazer_p REFERENCES dominios.matconstr (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.edu_edif_const_lazer_p - ADD CONSTRAINT edu_edif_const_lazer_p_matconstr_check - CHECK (matconstr = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 4 :: SMALLINT, 5 :: SMALLINT, 97 :: SMALLINT, 99 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT edu_edif_const_lazer_p_matconstr_check + CHECK (matconstr = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 4 :: SMALLINT, 5 :: SMALLINT, 97 :: SMALLINT, 99 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.edu_edif_const_lazer_p ALTER COLUMN matconstr SET DEFAULT 999# ALTER TABLE cb.edu_edif_const_lazer_p ADD CONSTRAINT edu_edif_const_lazer_p_operacional_fk FOREIGN KEY (operacional) @@ -4789,8 +4789,8 @@ ALTER TABLE cb.edu_edif_const_lazer_p REFERENCES dominios.situacaofisica (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.edu_edif_const_lazer_p - ADD CONSTRAINT edu_edif_const_lazer_p_situacaofisica_check - CHECK (situacaofisica = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT edu_edif_const_lazer_p_situacaofisica_check + CHECK (situacaofisica = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.edu_edif_const_lazer_p ALTER COLUMN situacaofisica SET DEFAULT 999# ALTER TABLE cb.edu_edif_const_lazer_p ADD CONSTRAINT edu_edif_const_lazer_p_tipoediflazer_fk FOREIGN KEY (tipoediflazer) @@ -4822,8 +4822,8 @@ ALTER TABLE cb.edu_edif_const_turistica_a REFERENCES dominios.matconstr (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.edu_edif_const_turistica_a - ADD CONSTRAINT edu_edif_const_turistica_a_matconstr_check - CHECK (matconstr = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 4 :: SMALLINT, 5 :: SMALLINT, 97 :: SMALLINT, 99 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT edu_edif_const_turistica_a_matconstr_check + CHECK (matconstr = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 4 :: SMALLINT, 5 :: SMALLINT, 97 :: SMALLINT, 99 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.edu_edif_const_turistica_a ALTER COLUMN matconstr SET DEFAULT 999# ALTER TABLE cb.edu_edif_const_turistica_a ADD CONSTRAINT edu_edif_const_turistica_a_operacional_fk FOREIGN KEY (operacional) @@ -4840,8 +4840,8 @@ ALTER TABLE cb.edu_edif_const_turistica_a REFERENCES dominios.situacaofisica (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.edu_edif_const_turistica_a - ADD CONSTRAINT edu_edif_const_turistica_a_situacaofisica_check - CHECK (situacaofisica = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT edu_edif_const_turistica_a_situacaofisica_check + CHECK (situacaofisica = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.edu_edif_const_turistica_a ALTER COLUMN situacaofisica SET DEFAULT 999# ALTER TABLE cb.edu_edif_const_turistica_a ADD CONSTRAINT edu_edif_const_turistica_a_tipoedifturist_fk FOREIGN KEY (tipoedifturist) @@ -4873,8 +4873,8 @@ ALTER TABLE cb.edu_edif_const_turistica_p REFERENCES dominios.matconstr (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.edu_edif_const_turistica_p - ADD CONSTRAINT edu_edif_const_turistica_p_matconstr_check - CHECK (matconstr = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 4 :: SMALLINT, 5 :: SMALLINT, 97 :: SMALLINT, 99 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT edu_edif_const_turistica_p_matconstr_check + CHECK (matconstr = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 4 :: SMALLINT, 5 :: SMALLINT, 97 :: SMALLINT, 99 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.edu_edif_const_turistica_p ALTER COLUMN matconstr SET DEFAULT 999# ALTER TABLE cb.edu_edif_const_turistica_p ADD CONSTRAINT edu_edif_const_turistica_p_operacional_fk FOREIGN KEY (operacional) @@ -4891,8 +4891,8 @@ ALTER TABLE cb.edu_edif_const_turistica_p REFERENCES dominios.situacaofisica (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.edu_edif_const_turistica_p - ADD CONSTRAINT edu_edif_const_turistica_p_situacaofisica_check - CHECK (situacaofisica = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT edu_edif_const_turistica_p_situacaofisica_check + CHECK (situacaofisica = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.edu_edif_const_turistica_p ALTER COLUMN situacaofisica SET DEFAULT 999# ALTER TABLE cb.edu_edif_const_turistica_p ADD CONSTRAINT edu_edif_const_turistica_p_tipoedifturist_fk FOREIGN KEY (tipoedifturist) @@ -4923,8 +4923,8 @@ ALTER TABLE cb.edu_edif_ensino_a REFERENCES dominios.matconstr (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.edu_edif_ensino_a - ADD CONSTRAINT edu_edif_ensino_a_matconstr_check - CHECK (matconstr = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 4 :: SMALLINT, 5 :: SMALLINT, 97 :: SMALLINT, 99 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT edu_edif_ensino_a_matconstr_check + CHECK (matconstr = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 4 :: SMALLINT, 5 :: SMALLINT, 97 :: SMALLINT, 99 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.edu_edif_ensino_a ALTER COLUMN matconstr SET DEFAULT 999# ALTER TABLE cb.edu_edif_ensino_a ADD CONSTRAINT edu_edif_ensino_a_operacional_fk FOREIGN KEY (operacional) @@ -4936,16 +4936,16 @@ ALTER TABLE cb.edu_edif_ensino_a REFERENCES dominios.situacaofisica (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.edu_edif_ensino_a - ADD CONSTRAINT edu_edif_ensino_a_situacaofisica_check - CHECK (situacaofisica = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT edu_edif_ensino_a_situacaofisica_check + CHECK (situacaofisica = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.edu_edif_ensino_a ALTER COLUMN situacaofisica SET DEFAULT 999# ALTER TABLE cb.edu_edif_ensino_a ADD CONSTRAINT edu_edif_ensino_a_tipoclassecnae_fk FOREIGN KEY (tipoclassecnae) REFERENCES dominios.tipoclassecnae (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.edu_edif_ensino_a - ADD CONSTRAINT edu_edif_ensino_a_tipoclassecnae_check - CHECK (tipoclassecnae = ANY(ARRAY[0 :: SMALLINT, 16 :: SMALLINT, 17 :: SMALLINT, 18 :: SMALLINT, 19 :: SMALLINT, 20 :: SMALLINT, 21 :: SMALLINT, 22 :: SMALLINT, 23 :: SMALLINT, 24 :: SMALLINT, 25 :: SMALLINT, 98 :: SMALLINT, 99 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT edu_edif_ensino_a_tipoclassecnae_check + CHECK (tipoclassecnae = ANY(ARRAY[0 :: SMALLINT, 16 :: SMALLINT, 17 :: SMALLINT, 18 :: SMALLINT, 19 :: SMALLINT, 20 :: SMALLINT, 21 :: SMALLINT, 22 :: SMALLINT, 23 :: SMALLINT, 24 :: SMALLINT, 25 :: SMALLINT, 98 :: SMALLINT, 99 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.edu_edif_ensino_a ALTER COLUMN tipoclassecnae SET DEFAULT 999# CREATE TABLE cb.edu_edif_ensino_p( id serial NOT NULL, @@ -4971,8 +4971,8 @@ ALTER TABLE cb.edu_edif_ensino_p REFERENCES dominios.matconstr (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.edu_edif_ensino_p - ADD CONSTRAINT edu_edif_ensino_p_matconstr_check - CHECK (matconstr = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 4 :: SMALLINT, 5 :: SMALLINT, 97 :: SMALLINT, 99 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT edu_edif_ensino_p_matconstr_check + CHECK (matconstr = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 4 :: SMALLINT, 5 :: SMALLINT, 97 :: SMALLINT, 99 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.edu_edif_ensino_p ALTER COLUMN matconstr SET DEFAULT 999# ALTER TABLE cb.edu_edif_ensino_p ADD CONSTRAINT edu_edif_ensino_p_operacional_fk FOREIGN KEY (operacional) @@ -4984,16 +4984,16 @@ ALTER TABLE cb.edu_edif_ensino_p REFERENCES dominios.situacaofisica (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.edu_edif_ensino_p - ADD CONSTRAINT edu_edif_ensino_p_situacaofisica_check - CHECK (situacaofisica = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT edu_edif_ensino_p_situacaofisica_check + CHECK (situacaofisica = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.edu_edif_ensino_p ALTER COLUMN situacaofisica SET DEFAULT 999# ALTER TABLE cb.edu_edif_ensino_p ADD CONSTRAINT edu_edif_ensino_p_tipoclassecnae_fk FOREIGN KEY (tipoclassecnae) REFERENCES dominios.tipoclassecnae (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.edu_edif_ensino_p - ADD CONSTRAINT edu_edif_ensino_p_tipoclassecnae_check - CHECK (tipoclassecnae = ANY(ARRAY[0 :: SMALLINT, 16 :: SMALLINT, 17 :: SMALLINT, 18 :: SMALLINT, 19 :: SMALLINT, 20 :: SMALLINT, 21 :: SMALLINT, 22 :: SMALLINT, 23 :: SMALLINT, 24 :: SMALLINT, 25 :: SMALLINT, 98 :: SMALLINT, 99 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT edu_edif_ensino_p_tipoclassecnae_check + CHECK (tipoclassecnae = ANY(ARRAY[0 :: SMALLINT, 16 :: SMALLINT, 17 :: SMALLINT, 18 :: SMALLINT, 19 :: SMALLINT, 20 :: SMALLINT, 21 :: SMALLINT, 22 :: SMALLINT, 23 :: SMALLINT, 24 :: SMALLINT, 25 :: SMALLINT, 98 :: SMALLINT, 99 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.edu_edif_ensino_p ALTER COLUMN tipoclassecnae SET DEFAULT 999# CREATE TABLE cb.edu_edif_religiosa_a( id serial NOT NULL, @@ -5026,8 +5026,8 @@ ALTER TABLE cb.edu_edif_religiosa_a REFERENCES dominios.matconstr (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.edu_edif_religiosa_a - ADD CONSTRAINT edu_edif_religiosa_a_matconstr_check - CHECK (matconstr = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 4 :: SMALLINT, 5 :: SMALLINT, 97 :: SMALLINT, 99 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT edu_edif_religiosa_a_matconstr_check + CHECK (matconstr = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 4 :: SMALLINT, 5 :: SMALLINT, 97 :: SMALLINT, 99 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.edu_edif_religiosa_a ALTER COLUMN matconstr SET DEFAULT 999# ALTER TABLE cb.edu_edif_religiosa_a ADD CONSTRAINT edu_edif_religiosa_a_operacional_fk FOREIGN KEY (operacional) @@ -5039,8 +5039,8 @@ ALTER TABLE cb.edu_edif_religiosa_a REFERENCES dominios.situacaofisica (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.edu_edif_religiosa_a - ADD CONSTRAINT edu_edif_religiosa_a_situacaofisica_check - CHECK (situacaofisica = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT edu_edif_religiosa_a_situacaofisica_check + CHECK (situacaofisica = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.edu_edif_religiosa_a ALTER COLUMN situacaofisica SET DEFAULT 999# ALTER TABLE cb.edu_edif_religiosa_a ADD CONSTRAINT edu_edif_religiosa_a_tipoedifrelig_fk FOREIGN KEY (tipoedifrelig) @@ -5078,8 +5078,8 @@ ALTER TABLE cb.edu_edif_religiosa_p REFERENCES dominios.matconstr (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.edu_edif_religiosa_p - ADD CONSTRAINT edu_edif_religiosa_p_matconstr_check - CHECK (matconstr = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 4 :: SMALLINT, 5 :: SMALLINT, 97 :: SMALLINT, 99 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT edu_edif_religiosa_p_matconstr_check + CHECK (matconstr = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 4 :: SMALLINT, 5 :: SMALLINT, 97 :: SMALLINT, 99 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.edu_edif_religiosa_p ALTER COLUMN matconstr SET DEFAULT 999# ALTER TABLE cb.edu_edif_religiosa_p ADD CONSTRAINT edu_edif_religiosa_p_operacional_fk FOREIGN KEY (operacional) @@ -5091,8 +5091,8 @@ ALTER TABLE cb.edu_edif_religiosa_p REFERENCES dominios.situacaofisica (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.edu_edif_religiosa_p - ADD CONSTRAINT edu_edif_religiosa_p_situacaofisica_check - CHECK (situacaofisica = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT edu_edif_religiosa_p_situacaofisica_check + CHECK (situacaofisica = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.edu_edif_religiosa_p ALTER COLUMN situacaofisica SET DEFAULT 999# ALTER TABLE cb.edu_edif_religiosa_p ADD CONSTRAINT edu_edif_religiosa_p_tipoedifrelig_fk FOREIGN KEY (tipoedifrelig) @@ -5126,8 +5126,8 @@ ALTER TABLE cb.edu_piscina_a REFERENCES dominios.situacaofisica (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.edu_piscina_a - ADD CONSTRAINT edu_piscina_a_situacaofisica_check - CHECK (situacaofisica = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT edu_piscina_a_situacaofisica_check + CHECK (situacaofisica = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.edu_piscina_a ALTER COLUMN situacaofisica SET DEFAULT 999# CREATE TABLE cb.edu_pista_competicao_l( id serial NOT NULL, @@ -5157,16 +5157,16 @@ ALTER TABLE cb.edu_pista_competicao_l REFERENCES dominios.situacaofisica (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.edu_pista_competicao_l - ADD CONSTRAINT edu_pista_competicao_l_situacaofisica_check - CHECK (situacaofisica = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT edu_pista_competicao_l_situacaofisica_check + CHECK (situacaofisica = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.edu_pista_competicao_l ALTER COLUMN situacaofisica SET DEFAULT 999# ALTER TABLE cb.edu_pista_competicao_l ADD CONSTRAINT edu_pista_competicao_l_tipopista_fk FOREIGN KEY (tipopista) REFERENCES dominios.tipopista (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.edu_pista_competicao_l - ADD CONSTRAINT edu_pista_competicao_l_tipopista_check - CHECK (tipopista = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 4 :: SMALLINT, 5 :: SMALLINT, 98 :: SMALLINT, 99 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT edu_pista_competicao_l_tipopista_check + CHECK (tipopista = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 4 :: SMALLINT, 5 :: SMALLINT, 98 :: SMALLINT, 99 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.edu_pista_competicao_l ALTER COLUMN tipopista SET DEFAULT 999# CREATE TABLE cb.edu_ruina_a( id serial NOT NULL, @@ -5309,8 +5309,8 @@ ALTER TABLE cb.enc_edif_comunic_a REFERENCES dominios.matconstr (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.enc_edif_comunic_a - ADD CONSTRAINT enc_edif_comunic_a_matconstr_check - CHECK (matconstr = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 4 :: SMALLINT, 5 :: SMALLINT, 97 :: SMALLINT, 99 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT enc_edif_comunic_a_matconstr_check + CHECK (matconstr = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 4 :: SMALLINT, 5 :: SMALLINT, 97 :: SMALLINT, 99 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.enc_edif_comunic_a ALTER COLUMN matconstr SET DEFAULT 999# ALTER TABLE cb.enc_edif_comunic_a ADD CONSTRAINT enc_edif_comunic_a_modalidade_fk FOREIGN KEY (modalidade) @@ -5327,8 +5327,8 @@ ALTER TABLE cb.enc_edif_comunic_a REFERENCES dominios.situacaofisica (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.enc_edif_comunic_a - ADD CONSTRAINT enc_edif_comunic_a_situacaofisica_check - CHECK (situacaofisica = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT enc_edif_comunic_a_situacaofisica_check + CHECK (situacaofisica = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.enc_edif_comunic_a ALTER COLUMN situacaofisica SET DEFAULT 999# ALTER TABLE cb.enc_edif_comunic_a ADD CONSTRAINT enc_edif_comunic_a_tipoedifcomunic_fk FOREIGN KEY (tipoedifcomunic) @@ -5360,8 +5360,8 @@ ALTER TABLE cb.enc_edif_comunic_p REFERENCES dominios.matconstr (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.enc_edif_comunic_p - ADD CONSTRAINT enc_edif_comunic_p_matconstr_check - CHECK (matconstr = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 4 :: SMALLINT, 5 :: SMALLINT, 97 :: SMALLINT, 99 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT enc_edif_comunic_p_matconstr_check + CHECK (matconstr = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 4 :: SMALLINT, 5 :: SMALLINT, 97 :: SMALLINT, 99 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.enc_edif_comunic_p ALTER COLUMN matconstr SET DEFAULT 999# ALTER TABLE cb.enc_edif_comunic_p ADD CONSTRAINT enc_edif_comunic_p_modalidade_fk FOREIGN KEY (modalidade) @@ -5378,8 +5378,8 @@ ALTER TABLE cb.enc_edif_comunic_p REFERENCES dominios.situacaofisica (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.enc_edif_comunic_p - ADD CONSTRAINT enc_edif_comunic_p_situacaofisica_check - CHECK (situacaofisica = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT enc_edif_comunic_p_situacaofisica_check + CHECK (situacaofisica = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.enc_edif_comunic_p ALTER COLUMN situacaofisica SET DEFAULT 999# ALTER TABLE cb.enc_edif_comunic_p ADD CONSTRAINT enc_edif_comunic_p_tipoedifcomunic_fk FOREIGN KEY (tipoedifcomunic) @@ -5410,8 +5410,8 @@ ALTER TABLE cb.enc_edif_energia_a REFERENCES dominios.matconstr (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.enc_edif_energia_a - ADD CONSTRAINT enc_edif_energia_a_matconstr_check - CHECK (matconstr = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 4 :: SMALLINT, 5 :: SMALLINT, 99 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT enc_edif_energia_a_matconstr_check + CHECK (matconstr = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 4 :: SMALLINT, 5 :: SMALLINT, 99 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.enc_edif_energia_a ALTER COLUMN matconstr SET DEFAULT 999# ALTER TABLE cb.enc_edif_energia_a ADD CONSTRAINT enc_edif_energia_a_operacional_fk FOREIGN KEY (operacional) @@ -5423,8 +5423,8 @@ ALTER TABLE cb.enc_edif_energia_a REFERENCES dominios.situacaofisica (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.enc_edif_energia_a - ADD CONSTRAINT enc_edif_energia_a_situacaofisica_check - CHECK (situacaofisica = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT enc_edif_energia_a_situacaofisica_check + CHECK (situacaofisica = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.enc_edif_energia_a ALTER COLUMN situacaofisica SET DEFAULT 999# ALTER TABLE cb.enc_edif_energia_a ADD CONSTRAINT enc_edif_energia_a_tipoedifenergia_fk FOREIGN KEY (tipoedifenergia) @@ -5455,8 +5455,8 @@ ALTER TABLE cb.enc_edif_energia_p REFERENCES dominios.matconstr (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.enc_edif_energia_p - ADD CONSTRAINT enc_edif_energia_p_matconstr_check - CHECK (matconstr = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 4 :: SMALLINT, 5 :: SMALLINT, 99 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT enc_edif_energia_p_matconstr_check + CHECK (matconstr = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 4 :: SMALLINT, 5 :: SMALLINT, 99 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.enc_edif_energia_p ALTER COLUMN matconstr SET DEFAULT 999# ALTER TABLE cb.enc_edif_energia_p ADD CONSTRAINT enc_edif_energia_p_operacional_fk FOREIGN KEY (operacional) @@ -5468,8 +5468,8 @@ ALTER TABLE cb.enc_edif_energia_p REFERENCES dominios.situacaofisica (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.enc_edif_energia_p - ADD CONSTRAINT enc_edif_energia_p_situacaofisica_check - CHECK (situacaofisica = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT enc_edif_energia_p_situacaofisica_check + CHECK (situacaofisica = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.enc_edif_energia_p ALTER COLUMN situacaofisica SET DEFAULT 999# ALTER TABLE cb.enc_edif_energia_p ADD CONSTRAINT enc_edif_energia_p_tipoedifenergia_fk FOREIGN KEY (tipoedifenergia) @@ -5513,8 +5513,8 @@ ALTER TABLE cb.enc_est_gerad_energia_eletr_a REFERENCES dominios.situacaofisica (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.enc_est_gerad_energia_eletr_a - ADD CONSTRAINT enc_est_gerad_energia_eletr_a_situacaofisica_check - CHECK (situacaofisica = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT enc_est_gerad_energia_eletr_a_situacaofisica_check + CHECK (situacaofisica = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.enc_est_gerad_energia_eletr_a ALTER COLUMN situacaofisica SET DEFAULT 999# ALTER TABLE cb.enc_est_gerad_energia_eletr_a ADD CONSTRAINT enc_est_gerad_energia_eletr_a_tipoestgerad_fk FOREIGN KEY (tipoestgerad) @@ -5558,8 +5558,8 @@ ALTER TABLE cb.enc_est_gerad_energia_eletr_l REFERENCES dominios.situacaofisica (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.enc_est_gerad_energia_eletr_l - ADD CONSTRAINT enc_est_gerad_energia_eletr_l_situacaofisica_check - CHECK (situacaofisica = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT enc_est_gerad_energia_eletr_l_situacaofisica_check + CHECK (situacaofisica = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.enc_est_gerad_energia_eletr_l ALTER COLUMN situacaofisica SET DEFAULT 999# ALTER TABLE cb.enc_est_gerad_energia_eletr_l ADD CONSTRAINT enc_est_gerad_energia_eletr_l_tipoestgerad_fk FOREIGN KEY (tipoestgerad) @@ -5603,8 +5603,8 @@ ALTER TABLE cb.enc_est_gerad_energia_eletr_p REFERENCES dominios.situacaofisica (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.enc_est_gerad_energia_eletr_p - ADD CONSTRAINT enc_est_gerad_energia_eletr_p_situacaofisica_check - CHECK (situacaofisica = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT enc_est_gerad_energia_eletr_p_situacaofisica_check + CHECK (situacaofisica = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.enc_est_gerad_energia_eletr_p ALTER COLUMN situacaofisica SET DEFAULT 999# ALTER TABLE cb.enc_est_gerad_energia_eletr_p ADD CONSTRAINT enc_est_gerad_energia_eletr_p_tipoestgerad_fk FOREIGN KEY (tipoestgerad) @@ -5678,8 +5678,8 @@ ALTER TABLE cb.enc_hidreletrica_a REFERENCES dominios.situacaofisica (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.enc_hidreletrica_a - ADD CONSTRAINT enc_hidreletrica_a_situacaofisica_check - CHECK (situacaofisica = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT enc_hidreletrica_a_situacaofisica_check + CHECK (situacaofisica = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.enc_hidreletrica_a ALTER COLUMN situacaofisica SET DEFAULT 999# CREATE TABLE cb.enc_hidreletrica_l( id serial NOT NULL, @@ -5718,8 +5718,8 @@ ALTER TABLE cb.enc_hidreletrica_l REFERENCES dominios.situacaofisica (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.enc_hidreletrica_l - ADD CONSTRAINT enc_hidreletrica_l_situacaofisica_check - CHECK (situacaofisica = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT enc_hidreletrica_l_situacaofisica_check + CHECK (situacaofisica = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.enc_hidreletrica_l ALTER COLUMN situacaofisica SET DEFAULT 999# CREATE TABLE cb.enc_hidreletrica_p( id serial NOT NULL, @@ -5758,8 +5758,8 @@ ALTER TABLE cb.enc_hidreletrica_p REFERENCES dominios.situacaofisica (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.enc_hidreletrica_p - ADD CONSTRAINT enc_hidreletrica_p_situacaofisica_check - CHECK (situacaofisica = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT enc_hidreletrica_p_situacaofisica_check + CHECK (situacaofisica = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.enc_hidreletrica_p ALTER COLUMN situacaofisica SET DEFAULT 999# CREATE TABLE cb.enc_ponto_trecho_energia_p( id serial NOT NULL, @@ -5830,8 +5830,8 @@ ALTER TABLE cb.enc_termeletrica_a REFERENCES dominios.situacaofisica (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.enc_termeletrica_a - ADD CONSTRAINT enc_termeletrica_a_situacaofisica_check - CHECK (situacaofisica = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT enc_termeletrica_a_situacaofisica_check + CHECK (situacaofisica = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.enc_termeletrica_a ALTER COLUMN situacaofisica SET DEFAULT 999# ALTER TABLE cb.enc_termeletrica_a ADD CONSTRAINT enc_termeletrica_a_tipocombustivel_fk FOREIGN KEY (tipocombustivel) @@ -5893,8 +5893,8 @@ ALTER TABLE cb.enc_termeletrica_p REFERENCES dominios.situacaofisica (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.enc_termeletrica_p - ADD CONSTRAINT enc_termeletrica_p_situacaofisica_check - CHECK (situacaofisica = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT enc_termeletrica_p_situacaofisica_check + CHECK (situacaofisica = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.enc_termeletrica_p ALTER COLUMN situacaofisica SET DEFAULT 999# ALTER TABLE cb.enc_termeletrica_p ADD CONSTRAINT enc_termeletrica_p_tipocombustivel_fk FOREIGN KEY (tipocombustivel) @@ -5946,8 +5946,8 @@ ALTER TABLE cb.enc_torre_comunic_p REFERENCES dominios.situacaofisica (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.enc_torre_comunic_p - ADD CONSTRAINT enc_torre_comunic_p_situacaofisica_check - CHECK (situacaofisica = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT enc_torre_comunic_p_situacaofisica_check + CHECK (situacaofisica = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.enc_torre_comunic_p ALTER COLUMN situacaofisica SET DEFAULT 999# CREATE TABLE cb.enc_torre_energia_p( id serial NOT NULL, @@ -5985,8 +5985,8 @@ ALTER TABLE cb.enc_torre_energia_p REFERENCES dominios.situacaofisica (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.enc_torre_energia_p - ADD CONSTRAINT enc_torre_energia_p_situacaofisica_check - CHECK (situacaofisica = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT enc_torre_energia_p_situacaofisica_check + CHECK (situacaofisica = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.enc_torre_energia_p ALTER COLUMN situacaofisica SET DEFAULT 999# ALTER TABLE cb.enc_torre_energia_p ADD CONSTRAINT enc_torre_energia_p_tipotorre_fk FOREIGN KEY (tipotorre) @@ -6024,8 +6024,8 @@ ALTER TABLE cb.enc_trecho_comunic_l REFERENCES dominios.matconstr (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.enc_trecho_comunic_l - ADD CONSTRAINT enc_trecho_comunic_l_matconstr_check - CHECK (matconstr = ANY(ARRAY[0 :: SMALLINT, 25 :: SMALLINT, 26 :: SMALLINT, 99 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT enc_trecho_comunic_l_matconstr_check + CHECK (matconstr = ANY(ARRAY[0 :: SMALLINT, 25 :: SMALLINT, 26 :: SMALLINT, 99 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.enc_trecho_comunic_l ALTER COLUMN matconstr SET DEFAULT 999# ALTER TABLE cb.enc_trecho_comunic_l ADD CONSTRAINT enc_trecho_comunic_l_operacional_fk FOREIGN KEY (operacional) @@ -6037,16 +6037,16 @@ ALTER TABLE cb.enc_trecho_comunic_l REFERENCES dominios.posicaorelativa (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.enc_trecho_comunic_l - ADD CONSTRAINT enc_trecho_comunic_l_posicaorelativa_check - CHECK (posicaorelativa = ANY(ARRAY[2 :: SMALLINT, 3 :: SMALLINT, 4 :: SMALLINT, 5 :: SMALLINT, 6 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT enc_trecho_comunic_l_posicaorelativa_check + CHECK (posicaorelativa = ANY(ARRAY[2 :: SMALLINT, 3 :: SMALLINT, 4 :: SMALLINT, 5 :: SMALLINT, 6 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.enc_trecho_comunic_l ALTER COLUMN posicaorelativa SET DEFAULT 999# ALTER TABLE cb.enc_trecho_comunic_l ADD CONSTRAINT enc_trecho_comunic_l_situacaofisica_fk FOREIGN KEY (situacaofisica) REFERENCES dominios.situacaofisica (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.enc_trecho_comunic_l - ADD CONSTRAINT enc_trecho_comunic_l_situacaofisica_check - CHECK (situacaofisica = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT enc_trecho_comunic_l_situacaofisica_check + CHECK (situacaofisica = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.enc_trecho_comunic_l ALTER COLUMN situacaofisica SET DEFAULT 999# ALTER TABLE cb.enc_trecho_comunic_l ADD CONSTRAINT enc_trecho_comunic_l_tipotrechocomunic_fk FOREIGN KEY (tipotrechocomunic) @@ -6095,16 +6095,16 @@ ALTER TABLE cb.enc_trecho_energia_l REFERENCES dominios.posicaorelativa (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.enc_trecho_energia_l - ADD CONSTRAINT enc_trecho_energia_l_posicaorelativa_check - CHECK (posicaorelativa = ANY(ARRAY[2 :: SMALLINT, 3 :: SMALLINT, 4 :: SMALLINT, 5 :: SMALLINT, 6 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT enc_trecho_energia_l_posicaorelativa_check + CHECK (posicaorelativa = ANY(ARRAY[2 :: SMALLINT, 3 :: SMALLINT, 4 :: SMALLINT, 5 :: SMALLINT, 6 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.enc_trecho_energia_l ALTER COLUMN posicaorelativa SET DEFAULT 999# ALTER TABLE cb.enc_trecho_energia_l ADD CONSTRAINT enc_trecho_energia_l_situacaofisica_fk FOREIGN KEY (situacaofisica) REFERENCES dominios.situacaofisica (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.enc_trecho_energia_l - ADD CONSTRAINT enc_trecho_energia_l_situacaofisica_check - CHECK (situacaofisica = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT enc_trecho_energia_l_situacaofisica_check + CHECK (situacaofisica = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.enc_trecho_energia_l ALTER COLUMN situacaofisica SET DEFAULT 999# CREATE TABLE cb.enc_zona_linhas_energia_com_a( id serial NOT NULL, @@ -6182,8 +6182,8 @@ ALTER TABLE cb.hid_banco_areia_a REFERENCES dominios.materialpredominante (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.hid_banco_areia_a - ADD CONSTRAINT hid_banco_areia_a_materialpredominante_check - CHECK (materialpredominante = ANY(ARRAY[0 :: SMALLINT, 12 :: SMALLINT, 18 :: SMALLINT, 19 :: SMALLINT, 24 :: SMALLINT, 98 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT hid_banco_areia_a_materialpredominante_check + CHECK (materialpredominante = ANY(ARRAY[0 :: SMALLINT, 12 :: SMALLINT, 18 :: SMALLINT, 19 :: SMALLINT, 24 :: SMALLINT, 98 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.hid_banco_areia_a ALTER COLUMN materialpredominante SET DEFAULT 999# ALTER TABLE cb.hid_banco_areia_a ADD CONSTRAINT hid_banco_areia_a_situacaoemagua_fk FOREIGN KEY (situacaoemagua) @@ -6218,8 +6218,8 @@ ALTER TABLE cb.hid_banco_areia_l REFERENCES dominios.materialpredominante (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.hid_banco_areia_l - ADD CONSTRAINT hid_banco_areia_l_materialpredominante_check - CHECK (materialpredominante = ANY(ARRAY[0 :: SMALLINT, 12 :: SMALLINT, 18 :: SMALLINT, 19 :: SMALLINT, 24 :: SMALLINT, 98 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT hid_banco_areia_l_materialpredominante_check + CHECK (materialpredominante = ANY(ARRAY[0 :: SMALLINT, 12 :: SMALLINT, 18 :: SMALLINT, 19 :: SMALLINT, 24 :: SMALLINT, 98 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.hid_banco_areia_l ALTER COLUMN materialpredominante SET DEFAULT 999# ALTER TABLE cb.hid_banco_areia_l ADD CONSTRAINT hid_banco_areia_l_situacaoemagua_fk FOREIGN KEY (situacaoemagua) @@ -6255,8 +6255,8 @@ ALTER TABLE cb.hid_barragem_a REFERENCES dominios.matconstr (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.hid_barragem_a - ADD CONSTRAINT hid_barragem_a_matconstr_check - CHECK (matconstr = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 4 :: SMALLINT, 23 :: SMALLINT, 99 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT hid_barragem_a_matconstr_check + CHECK (matconstr = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 4 :: SMALLINT, 23 :: SMALLINT, 99 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.hid_barragem_a ALTER COLUMN matconstr SET DEFAULT 999# ALTER TABLE cb.hid_barragem_a ADD CONSTRAINT hid_barragem_a_operacional_fk FOREIGN KEY (operacional) @@ -6297,8 +6297,8 @@ ALTER TABLE cb.hid_barragem_l REFERENCES dominios.matconstr (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.hid_barragem_l - ADD CONSTRAINT hid_barragem_l_matconstr_check - CHECK (matconstr = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 4 :: SMALLINT, 23 :: SMALLINT, 99 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT hid_barragem_l_matconstr_check + CHECK (matconstr = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 4 :: SMALLINT, 23 :: SMALLINT, 99 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.hid_barragem_l ALTER COLUMN matconstr SET DEFAULT 999# ALTER TABLE cb.hid_barragem_l ADD CONSTRAINT hid_barragem_l_operacional_fk FOREIGN KEY (operacional) @@ -6339,8 +6339,8 @@ ALTER TABLE cb.hid_barragem_p REFERENCES dominios.matconstr (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.hid_barragem_p - ADD CONSTRAINT hid_barragem_p_matconstr_check - CHECK (matconstr = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 4 :: SMALLINT, 23 :: SMALLINT, 99 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT hid_barragem_p_matconstr_check + CHECK (matconstr = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 4 :: SMALLINT, 23 :: SMALLINT, 99 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.hid_barragem_p ALTER COLUMN matconstr SET DEFAULT 999# ALTER TABLE cb.hid_barragem_p ADD CONSTRAINT hid_barragem_p_operacional_fk FOREIGN KEY (operacional) @@ -6538,8 +6538,8 @@ ALTER TABLE cb.hid_fonte_dagua_p REFERENCES dominios.regime (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.hid_fonte_dagua_p - ADD CONSTRAINT hid_fonte_dagua_p_regime_check - CHECK (regime = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 3 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT hid_fonte_dagua_p_regime_check + CHECK (regime = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 3 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.hid_fonte_dagua_p ALTER COLUMN regime SET DEFAULT 999# ALTER TABLE cb.hid_fonte_dagua_p ADD CONSTRAINT hid_fonte_dagua_p_tipofontedagua_fk FOREIGN KEY (tipofontedagua) @@ -6676,8 +6676,8 @@ ALTER TABLE cb.hid_limite_massa_dagua_l REFERENCES dominios.materialpredominante (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.hid_limite_massa_dagua_l - ADD CONSTRAINT hid_limite_massa_dagua_l_materialpredominante_check - CHECK (materialpredominante = ANY(ARRAY[0 :: SMALLINT, 4 :: SMALLINT, 12 :: SMALLINT, 13 :: SMALLINT, 14 :: SMALLINT, 15 :: SMALLINT, 16 :: SMALLINT, 18 :: SMALLINT, 19 :: SMALLINT, 20 :: SMALLINT, 21 :: SMALLINT, 50 :: SMALLINT, 97 :: SMALLINT, 98 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT hid_limite_massa_dagua_l_materialpredominante_check + CHECK (materialpredominante = ANY(ARRAY[0 :: SMALLINT, 4 :: SMALLINT, 12 :: SMALLINT, 13 :: SMALLINT, 14 :: SMALLINT, 15 :: SMALLINT, 16 :: SMALLINT, 18 :: SMALLINT, 19 :: SMALLINT, 20 :: SMALLINT, 21 :: SMALLINT, 50 :: SMALLINT, 97 :: SMALLINT, 98 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.hid_limite_massa_dagua_l ALTER COLUMN materialpredominante SET DEFAULT 999# ALTER TABLE cb.hid_limite_massa_dagua_l ADD CONSTRAINT hid_limite_massa_dagua_l_tipolimmassa_fk FOREIGN KEY (tipolimmassa) @@ -6707,8 +6707,8 @@ ALTER TABLE cb.hid_massa_dagua_a REFERENCES dominios.regime (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.hid_massa_dagua_a - ADD CONSTRAINT hid_massa_dagua_a_regime_check - CHECK (regime = ANY(ARRAY[1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 4 :: SMALLINT, 5 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT hid_massa_dagua_a_regime_check + CHECK (regime = ANY(ARRAY[1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 4 :: SMALLINT, 5 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.hid_massa_dagua_a ALTER COLUMN regime SET DEFAULT 999# ALTER TABLE cb.hid_massa_dagua_a ADD CONSTRAINT hid_massa_dagua_a_salinidade_fk FOREIGN KEY (salinidade) @@ -6747,8 +6747,8 @@ ALTER TABLE cb.hid_natureza_fundo_a REFERENCES dominios.materialpredominante (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.hid_natureza_fundo_a - ADD CONSTRAINT hid_natureza_fundo_a_materialpredominante_check - CHECK (materialpredominante = ANY(ARRAY[0 :: SMALLINT, 4 :: SMALLINT, 12 :: SMALLINT, 13 :: SMALLINT, 14 :: SMALLINT, 15 :: SMALLINT, 16 :: SMALLINT, 18 :: SMALLINT, 19 :: SMALLINT, 20 :: SMALLINT, 21 :: SMALLINT, 22 :: SMALLINT, 50 :: SMALLINT, 98 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT hid_natureza_fundo_a_materialpredominante_check + CHECK (materialpredominante = ANY(ARRAY[0 :: SMALLINT, 4 :: SMALLINT, 12 :: SMALLINT, 13 :: SMALLINT, 14 :: SMALLINT, 15 :: SMALLINT, 16 :: SMALLINT, 18 :: SMALLINT, 19 :: SMALLINT, 20 :: SMALLINT, 21 :: SMALLINT, 22 :: SMALLINT, 50 :: SMALLINT, 98 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.hid_natureza_fundo_a ALTER COLUMN materialpredominante SET DEFAULT 999# CREATE TABLE cb.hid_natureza_fundo_l( id serial NOT NULL, @@ -6777,8 +6777,8 @@ ALTER TABLE cb.hid_natureza_fundo_l REFERENCES dominios.materialpredominante (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.hid_natureza_fundo_l - ADD CONSTRAINT hid_natureza_fundo_l_materialpredominante_check - CHECK (materialpredominante = ANY(ARRAY[0 :: SMALLINT, 4 :: SMALLINT, 12 :: SMALLINT, 13 :: SMALLINT, 14 :: SMALLINT, 15 :: SMALLINT, 16 :: SMALLINT, 18 :: SMALLINT, 19 :: SMALLINT, 20 :: SMALLINT, 21 :: SMALLINT, 22 :: SMALLINT, 50 :: SMALLINT, 98 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT hid_natureza_fundo_l_materialpredominante_check + CHECK (materialpredominante = ANY(ARRAY[0 :: SMALLINT, 4 :: SMALLINT, 12 :: SMALLINT, 13 :: SMALLINT, 14 :: SMALLINT, 15 :: SMALLINT, 16 :: SMALLINT, 18 :: SMALLINT, 19 :: SMALLINT, 20 :: SMALLINT, 21 :: SMALLINT, 22 :: SMALLINT, 50 :: SMALLINT, 98 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.hid_natureza_fundo_l ALTER COLUMN materialpredominante SET DEFAULT 999# CREATE TABLE cb.hid_natureza_fundo_p( id serial NOT NULL, @@ -6807,8 +6807,8 @@ ALTER TABLE cb.hid_natureza_fundo_p REFERENCES dominios.materialpredominante (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.hid_natureza_fundo_p - ADD CONSTRAINT hid_natureza_fundo_p_materialpredominante_check - CHECK (materialpredominante = ANY(ARRAY[0 :: SMALLINT, 4 :: SMALLINT, 12 :: SMALLINT, 13 :: SMALLINT, 14 :: SMALLINT, 15 :: SMALLINT, 16 :: SMALLINT, 18 :: SMALLINT, 19 :: SMALLINT, 20 :: SMALLINT, 21 :: SMALLINT, 22 :: SMALLINT, 50 :: SMALLINT, 98 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT hid_natureza_fundo_p_materialpredominante_check + CHECK (materialpredominante = ANY(ARRAY[0 :: SMALLINT, 4 :: SMALLINT, 12 :: SMALLINT, 13 :: SMALLINT, 14 :: SMALLINT, 15 :: SMALLINT, 16 :: SMALLINT, 18 :: SMALLINT, 19 :: SMALLINT, 20 :: SMALLINT, 21 :: SMALLINT, 22 :: SMALLINT, 50 :: SMALLINT, 98 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.hid_natureza_fundo_p ALTER COLUMN materialpredominante SET DEFAULT 999# CREATE TABLE cb.hid_ponto_drenagem_p( id serial NOT NULL, @@ -6875,8 +6875,8 @@ ALTER TABLE cb.hid_quebramar_molhe_a REFERENCES dominios.matconstr (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.hid_quebramar_molhe_a - ADD CONSTRAINT hid_quebramar_molhe_a_matconstr_check - CHECK (matconstr = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 4 :: SMALLINT, 99 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT hid_quebramar_molhe_a_matconstr_check + CHECK (matconstr = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 4 :: SMALLINT, 99 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.hid_quebramar_molhe_a ALTER COLUMN matconstr SET DEFAULT 999# ALTER TABLE cb.hid_quebramar_molhe_a ADD CONSTRAINT hid_quebramar_molhe_a_operacional_fk FOREIGN KEY (operacional) @@ -6923,8 +6923,8 @@ ALTER TABLE cb.hid_quebramar_molhe_l REFERENCES dominios.matconstr (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.hid_quebramar_molhe_l - ADD CONSTRAINT hid_quebramar_molhe_l_matconstr_check - CHECK (matconstr = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 4 :: SMALLINT, 99 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT hid_quebramar_molhe_l_matconstr_check + CHECK (matconstr = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 4 :: SMALLINT, 99 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.hid_quebramar_molhe_l ALTER COLUMN matconstr SET DEFAULT 999# ALTER TABLE cb.hid_quebramar_molhe_l ADD CONSTRAINT hid_quebramar_molhe_l_operacional_fk FOREIGN KEY (operacional) @@ -7277,8 +7277,8 @@ ALTER TABLE cb.hid_trecho_drenagem_l REFERENCES dominios.regime (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.hid_trecho_drenagem_l - ADD CONSTRAINT hid_trecho_drenagem_l_regime_check - CHECK (regime = ANY(ARRAY[1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 4 :: SMALLINT, 5 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT hid_trecho_drenagem_l_regime_check + CHECK (regime = ANY(ARRAY[1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 4 :: SMALLINT, 5 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.hid_trecho_drenagem_l ALTER COLUMN regime SET DEFAULT 999# CREATE TABLE cb.hid_trecho_massa_dagua_a( id serial NOT NULL, @@ -7303,8 +7303,8 @@ ALTER TABLE cb.hid_trecho_massa_dagua_a REFERENCES dominios.regime (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.hid_trecho_massa_dagua_a - ADD CONSTRAINT hid_trecho_massa_dagua_a_regime_check - CHECK (regime = ANY(ARRAY[1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 4 :: SMALLINT, 5 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT hid_trecho_massa_dagua_a_regime_check + CHECK (regime = ANY(ARRAY[1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 4 :: SMALLINT, 5 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.hid_trecho_massa_dagua_a ALTER COLUMN regime SET DEFAULT 999# ALTER TABLE cb.hid_trecho_massa_dagua_a ADD CONSTRAINT hid_trecho_massa_dagua_a_salinidade_fk FOREIGN KEY (salinidade) @@ -7465,8 +7465,8 @@ ALTER TABLE cb.lim_delimitacao_fisica_l REFERENCES dominios.matconstr (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.lim_delimitacao_fisica_l - ADD CONSTRAINT lim_delimitacao_fisica_l_matconstr_check - CHECK (matconstr = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 4 :: SMALLINT, 5 :: SMALLINT, 6 :: SMALLINT, 7 :: SMALLINT, 8 :: SMALLINT, 99 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT lim_delimitacao_fisica_l_matconstr_check + CHECK (matconstr = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 4 :: SMALLINT, 5 :: SMALLINT, 6 :: SMALLINT, 7 :: SMALLINT, 8 :: SMALLINT, 99 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.lim_delimitacao_fisica_l ALTER COLUMN matconstr SET DEFAULT 999# ALTER TABLE cb.lim_delimitacao_fisica_l ADD CONSTRAINT lim_delimitacao_fisica_l_tipodelimfis_fk FOREIGN KEY (tipodelimfis) @@ -7767,8 +7767,8 @@ ALTER TABLE cb.lim_outras_unid_protegidas_a REFERENCES dominios.administracao (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.lim_outras_unid_protegidas_a - ADD CONSTRAINT lim_outras_unid_protegidas_a_administracao_check - CHECK (administracao = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT lim_outras_unid_protegidas_a_administracao_check + CHECK (administracao = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.lim_outras_unid_protegidas_a ALTER COLUMN administracao SET DEFAULT 999# ALTER TABLE cb.lim_outras_unid_protegidas_a ADD CONSTRAINT lim_outras_unid_protegidas_a_geometriaaproximada_fk FOREIGN KEY (geometriaaproximada) @@ -7801,8 +7801,8 @@ ALTER TABLE cb.lim_outras_unid_protegidas_p REFERENCES dominios.administracao (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.lim_outras_unid_protegidas_p - ADD CONSTRAINT lim_outras_unid_protegidas_p_administracao_check - CHECK (administracao = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT lim_outras_unid_protegidas_p_administracao_check + CHECK (administracao = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.lim_outras_unid_protegidas_p ALTER COLUMN administracao SET DEFAULT 999# ALTER TABLE cb.lim_outras_unid_protegidas_p ADD CONSTRAINT lim_outras_unid_protegidas_p_geometriaaproximada_fk FOREIGN KEY (geometriaaproximada) @@ -7998,8 +7998,8 @@ ALTER TABLE cb.lim_unidade_conserv_nao_snuc_a REFERENCES dominios.administracao (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.lim_unidade_conserv_nao_snuc_a - ADD CONSTRAINT lim_unidade_conserv_nao_snuc_a_administracao_check - CHECK (administracao = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT lim_unidade_conserv_nao_snuc_a_administracao_check + CHECK (administracao = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.lim_unidade_conserv_nao_snuc_a ALTER COLUMN administracao SET DEFAULT 999# ALTER TABLE cb.lim_unidade_conserv_nao_snuc_a ADD CONSTRAINT lim_unidade_conserv_nao_snuc_a_geometriaaproximada_fk FOREIGN KEY (geometriaaproximada) @@ -8027,8 +8027,8 @@ ALTER TABLE cb.lim_unidade_conserv_nao_snuc_p REFERENCES dominios.administracao (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.lim_unidade_conserv_nao_snuc_p - ADD CONSTRAINT lim_unidade_conserv_nao_snuc_p_administracao_check - CHECK (administracao = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT lim_unidade_conserv_nao_snuc_p_administracao_check + CHECK (administracao = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.lim_unidade_conserv_nao_snuc_p ALTER COLUMN administracao SET DEFAULT 999# ALTER TABLE cb.lim_unidade_conserv_nao_snuc_p ADD CONSTRAINT lim_unidade_conserv_nao_snuc_p_geometriaaproximada_fk FOREIGN KEY (geometriaaproximada) @@ -8073,8 +8073,8 @@ ALTER TABLE cb.lim_unidade_protecao_integral_a REFERENCES dominios.administracao (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.lim_unidade_protecao_integral_a - ADD CONSTRAINT lim_unidade_protecao_integral_a_administracao_check - CHECK (administracao = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT lim_unidade_protecao_integral_a_administracao_check + CHECK (administracao = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.lim_unidade_protecao_integral_a ALTER COLUMN administracao SET DEFAULT 999# ALTER TABLE cb.lim_unidade_protecao_integral_a ADD CONSTRAINT lim_unidade_protecao_integral_a_geometriaaproximada_fk FOREIGN KEY (geometriaaproximada) @@ -8107,8 +8107,8 @@ ALTER TABLE cb.lim_unidade_protecao_integral_p REFERENCES dominios.administracao (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.lim_unidade_protecao_integral_p - ADD CONSTRAINT lim_unidade_protecao_integral_p_administracao_check - CHECK (administracao = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT lim_unidade_protecao_integral_p_administracao_check + CHECK (administracao = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.lim_unidade_protecao_integral_p ALTER COLUMN administracao SET DEFAULT 999# ALTER TABLE cb.lim_unidade_protecao_integral_p ADD CONSTRAINT lim_unidade_protecao_integral_p_geometriaaproximada_fk FOREIGN KEY (geometriaaproximada) @@ -8141,8 +8141,8 @@ ALTER TABLE cb.lim_unidade_uso_sustentavel_a REFERENCES dominios.administracao (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.lim_unidade_uso_sustentavel_a - ADD CONSTRAINT lim_unidade_uso_sustentavel_a_administracao_check - CHECK (administracao = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT lim_unidade_uso_sustentavel_a_administracao_check + CHECK (administracao = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.lim_unidade_uso_sustentavel_a ALTER COLUMN administracao SET DEFAULT 999# ALTER TABLE cb.lim_unidade_uso_sustentavel_a ADD CONSTRAINT lim_unidade_uso_sustentavel_a_geometriaaproximada_fk FOREIGN KEY (geometriaaproximada) @@ -8175,8 +8175,8 @@ ALTER TABLE cb.lim_unidade_uso_sustentavel_p REFERENCES dominios.administracao (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.lim_unidade_uso_sustentavel_p - ADD CONSTRAINT lim_unidade_uso_sustentavel_p_administracao_check - CHECK (administracao = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT lim_unidade_uso_sustentavel_p_administracao_check + CHECK (administracao = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.lim_unidade_uso_sustentavel_p ALTER COLUMN administracao SET DEFAULT 999# ALTER TABLE cb.lim_unidade_uso_sustentavel_p ADD CONSTRAINT lim_unidade_uso_sustentavel_p_geometriaaproximada_fk FOREIGN KEY (geometriaaproximada) @@ -8385,8 +8385,8 @@ ALTER TABLE cb.loc_edif_habitacional_a REFERENCES dominios.matconstr (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.loc_edif_habitacional_a - ADD CONSTRAINT loc_edif_habitacional_a_matconstr_check - CHECK (matconstr = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 4 :: SMALLINT, 5 :: SMALLINT, 97 :: SMALLINT, 99 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT loc_edif_habitacional_a_matconstr_check + CHECK (matconstr = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 4 :: SMALLINT, 5 :: SMALLINT, 97 :: SMALLINT, 99 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.loc_edif_habitacional_a ALTER COLUMN matconstr SET DEFAULT 999# ALTER TABLE cb.loc_edif_habitacional_a ADD CONSTRAINT loc_edif_habitacional_a_operacional_fk FOREIGN KEY (operacional) @@ -8398,8 +8398,8 @@ ALTER TABLE cb.loc_edif_habitacional_a REFERENCES dominios.situacaofisica (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.loc_edif_habitacional_a - ADD CONSTRAINT loc_edif_habitacional_a_situacaofisica_check - CHECK (situacaofisica = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT loc_edif_habitacional_a_situacaofisica_check + CHECK (situacaofisica = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.loc_edif_habitacional_a ALTER COLUMN situacaofisica SET DEFAULT 999# CREATE TABLE cb.loc_edif_habitacional_p( id serial NOT NULL, @@ -8424,8 +8424,8 @@ ALTER TABLE cb.loc_edif_habitacional_p REFERENCES dominios.matconstr (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.loc_edif_habitacional_p - ADD CONSTRAINT loc_edif_habitacional_p_matconstr_check - CHECK (matconstr = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 4 :: SMALLINT, 5 :: SMALLINT, 97 :: SMALLINT, 99 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT loc_edif_habitacional_p_matconstr_check + CHECK (matconstr = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 4 :: SMALLINT, 5 :: SMALLINT, 97 :: SMALLINT, 99 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.loc_edif_habitacional_p ALTER COLUMN matconstr SET DEFAULT 999# ALTER TABLE cb.loc_edif_habitacional_p ADD CONSTRAINT loc_edif_habitacional_p_operacional_fk FOREIGN KEY (operacional) @@ -8437,8 +8437,8 @@ ALTER TABLE cb.loc_edif_habitacional_p REFERENCES dominios.situacaofisica (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.loc_edif_habitacional_p - ADD CONSTRAINT loc_edif_habitacional_p_situacaofisica_check - CHECK (situacaofisica = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT loc_edif_habitacional_p_situacaofisica_check + CHECK (situacaofisica = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.loc_edif_habitacional_p ALTER COLUMN situacaofisica SET DEFAULT 999# CREATE TABLE cb.loc_edificacao_a( id serial NOT NULL, @@ -8463,8 +8463,8 @@ ALTER TABLE cb.loc_edificacao_a REFERENCES dominios.matconstr (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.loc_edificacao_a - ADD CONSTRAINT loc_edificacao_a_matconstr_check - CHECK (matconstr = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 4 :: SMALLINT, 5 :: SMALLINT, 97 :: SMALLINT, 99 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT loc_edificacao_a_matconstr_check + CHECK (matconstr = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 4 :: SMALLINT, 5 :: SMALLINT, 97 :: SMALLINT, 99 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.loc_edificacao_a ALTER COLUMN matconstr SET DEFAULT 999# ALTER TABLE cb.loc_edificacao_a ADD CONSTRAINT loc_edificacao_a_operacional_fk FOREIGN KEY (operacional) @@ -8476,8 +8476,8 @@ ALTER TABLE cb.loc_edificacao_a REFERENCES dominios.situacaofisica (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.loc_edificacao_a - ADD CONSTRAINT loc_edificacao_a_situacaofisica_check - CHECK (situacaofisica = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT loc_edificacao_a_situacaofisica_check + CHECK (situacaofisica = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.loc_edificacao_a ALTER COLUMN situacaofisica SET DEFAULT 999# CREATE TABLE cb.loc_edificacao_p( id serial NOT NULL, @@ -8502,8 +8502,8 @@ ALTER TABLE cb.loc_edificacao_p REFERENCES dominios.matconstr (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.loc_edificacao_p - ADD CONSTRAINT loc_edificacao_p_matconstr_check - CHECK (matconstr = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 4 :: SMALLINT, 5 :: SMALLINT, 97 :: SMALLINT, 99 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT loc_edificacao_p_matconstr_check + CHECK (matconstr = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 4 :: SMALLINT, 5 :: SMALLINT, 97 :: SMALLINT, 99 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.loc_edificacao_p ALTER COLUMN matconstr SET DEFAULT 999# ALTER TABLE cb.loc_edificacao_p ADD CONSTRAINT loc_edificacao_p_operacional_fk FOREIGN KEY (operacional) @@ -8515,8 +8515,8 @@ ALTER TABLE cb.loc_edificacao_p REFERENCES dominios.situacaofisica (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.loc_edificacao_p - ADD CONSTRAINT loc_edificacao_p_situacaofisica_check - CHECK (situacaofisica = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT loc_edificacao_p_situacaofisica_check + CHECK (situacaofisica = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.loc_edificacao_p ALTER COLUMN situacaofisica SET DEFAULT 999# CREATE TABLE cb.loc_hab_indigena_a( id serial NOT NULL, @@ -8680,8 +8680,8 @@ ALTER TABLE cb.pto_edif_constr_est_med_fen_a REFERENCES dominios.matconstr (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.pto_edif_constr_est_med_fen_a - ADD CONSTRAINT pto_edif_constr_est_med_fen_a_matconstr_check - CHECK (matconstr = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 4 :: SMALLINT, 5 :: SMALLINT, 97 :: SMALLINT, 99 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT pto_edif_constr_est_med_fen_a_matconstr_check + CHECK (matconstr = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 4 :: SMALLINT, 5 :: SMALLINT, 97 :: SMALLINT, 99 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.pto_edif_constr_est_med_fen_a ALTER COLUMN matconstr SET DEFAULT 999# ALTER TABLE cb.pto_edif_constr_est_med_fen_a ADD CONSTRAINT pto_edif_constr_est_med_fen_a_operacional_fk FOREIGN KEY (operacional) @@ -8693,8 +8693,8 @@ ALTER TABLE cb.pto_edif_constr_est_med_fen_a REFERENCES dominios.situacaofisica (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.pto_edif_constr_est_med_fen_a - ADD CONSTRAINT pto_edif_constr_est_med_fen_a_situacaofisica_check - CHECK (situacaofisica = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT pto_edif_constr_est_med_fen_a_situacaofisica_check + CHECK (situacaofisica = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.pto_edif_constr_est_med_fen_a ALTER COLUMN situacaofisica SET DEFAULT 999# CREATE TABLE cb.pto_edif_constr_est_med_fen_p( id serial NOT NULL, @@ -8719,8 +8719,8 @@ ALTER TABLE cb.pto_edif_constr_est_med_fen_p REFERENCES dominios.matconstr (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.pto_edif_constr_est_med_fen_p - ADD CONSTRAINT pto_edif_constr_est_med_fen_p_matconstr_check - CHECK (matconstr = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 4 :: SMALLINT, 5 :: SMALLINT, 97 :: SMALLINT, 99 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT pto_edif_constr_est_med_fen_p_matconstr_check + CHECK (matconstr = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 4 :: SMALLINT, 5 :: SMALLINT, 97 :: SMALLINT, 99 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.pto_edif_constr_est_med_fen_p ALTER COLUMN matconstr SET DEFAULT 999# ALTER TABLE cb.pto_edif_constr_est_med_fen_p ADD CONSTRAINT pto_edif_constr_est_med_fen_p_operacional_fk FOREIGN KEY (operacional) @@ -8732,8 +8732,8 @@ ALTER TABLE cb.pto_edif_constr_est_med_fen_p REFERENCES dominios.situacaofisica (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.pto_edif_constr_est_med_fen_p - ADD CONSTRAINT pto_edif_constr_est_med_fen_p_situacaofisica_check - CHECK (situacaofisica = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT pto_edif_constr_est_med_fen_p_situacaofisica_check + CHECK (situacaofisica = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.pto_edif_constr_est_med_fen_p ALTER COLUMN situacaofisica SET DEFAULT 999# CREATE TABLE cb.pto_pto_controle_p( id serial NOT NULL, @@ -8788,8 +8788,8 @@ ALTER TABLE cb.pto_pto_controle_p REFERENCES dominios.tiporef (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.pto_pto_controle_p - ADD CONSTRAINT pto_pto_controle_p_tiporef_check - CHECK (tiporef = ANY(ARRAY[1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT pto_pto_controle_p_tiporef_check + CHECK (tiporef = ANY(ARRAY[1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.pto_pto_controle_p ALTER COLUMN tiporef SET DEFAULT 999# CREATE TABLE cb.pto_pto_est_med_fenomenos_p( id serial NOT NULL, @@ -9356,8 +9356,8 @@ ALTER TABLE cb.sau_edif_saude_a REFERENCES dominios.matconstr (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.sau_edif_saude_a - ADD CONSTRAINT sau_edif_saude_a_matconstr_check - CHECK (matconstr = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 4 :: SMALLINT, 5 :: SMALLINT, 97 :: SMALLINT, 99 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT sau_edif_saude_a_matconstr_check + CHECK (matconstr = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 4 :: SMALLINT, 5 :: SMALLINT, 97 :: SMALLINT, 99 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.sau_edif_saude_a ALTER COLUMN matconstr SET DEFAULT 999# ALTER TABLE cb.sau_edif_saude_a ADD CONSTRAINT sau_edif_saude_a_nivelatencao_fk FOREIGN KEY (nivelatencao) @@ -9374,16 +9374,16 @@ ALTER TABLE cb.sau_edif_saude_a REFERENCES dominios.situacaofisica (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.sau_edif_saude_a - ADD CONSTRAINT sau_edif_saude_a_situacaofisica_check - CHECK (situacaofisica = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT sau_edif_saude_a_situacaofisica_check + CHECK (situacaofisica = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.sau_edif_saude_a ALTER COLUMN situacaofisica SET DEFAULT 999# ALTER TABLE cb.sau_edif_saude_a ADD CONSTRAINT sau_edif_saude_a_tipoclassecnae_fk FOREIGN KEY (tipoclassecnae) REFERENCES dominios.tipoclassecnae (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.sau_edif_saude_a - ADD CONSTRAINT sau_edif_saude_a_tipoclassecnae_check - CHECK (tipoclassecnae = ANY(ARRAY[0 :: SMALLINT, 26 :: SMALLINT, 27 :: SMALLINT, 28 :: SMALLINT, 29 :: SMALLINT, 30 :: SMALLINT, 31 :: SMALLINT, 98 :: SMALLINT, 99 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT sau_edif_saude_a_tipoclassecnae_check + CHECK (tipoclassecnae = ANY(ARRAY[0 :: SMALLINT, 26 :: SMALLINT, 27 :: SMALLINT, 28 :: SMALLINT, 29 :: SMALLINT, 30 :: SMALLINT, 31 :: SMALLINT, 98 :: SMALLINT, 99 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.sau_edif_saude_a ALTER COLUMN tipoclassecnae SET DEFAULT 999# CREATE TABLE cb.sau_edif_saude_p( id serial NOT NULL, @@ -9410,8 +9410,8 @@ ALTER TABLE cb.sau_edif_saude_p REFERENCES dominios.matconstr (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.sau_edif_saude_p - ADD CONSTRAINT sau_edif_saude_p_matconstr_check - CHECK (matconstr = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 4 :: SMALLINT, 5 :: SMALLINT, 97 :: SMALLINT, 99 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT sau_edif_saude_p_matconstr_check + CHECK (matconstr = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 4 :: SMALLINT, 5 :: SMALLINT, 97 :: SMALLINT, 99 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.sau_edif_saude_p ALTER COLUMN matconstr SET DEFAULT 999# ALTER TABLE cb.sau_edif_saude_p ADD CONSTRAINT sau_edif_saude_p_nivelatencao_fk FOREIGN KEY (nivelatencao) @@ -9428,16 +9428,16 @@ ALTER TABLE cb.sau_edif_saude_p REFERENCES dominios.situacaofisica (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.sau_edif_saude_p - ADD CONSTRAINT sau_edif_saude_p_situacaofisica_check - CHECK (situacaofisica = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT sau_edif_saude_p_situacaofisica_check + CHECK (situacaofisica = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.sau_edif_saude_p ALTER COLUMN situacaofisica SET DEFAULT 999# ALTER TABLE cb.sau_edif_saude_p ADD CONSTRAINT sau_edif_saude_p_tipoclassecnae_fk FOREIGN KEY (tipoclassecnae) REFERENCES dominios.tipoclassecnae (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.sau_edif_saude_p - ADD CONSTRAINT sau_edif_saude_p_tipoclassecnae_check - CHECK (tipoclassecnae = ANY(ARRAY[0 :: SMALLINT, 26 :: SMALLINT, 27 :: SMALLINT, 28 :: SMALLINT, 29 :: SMALLINT, 30 :: SMALLINT, 31 :: SMALLINT, 98 :: SMALLINT, 99 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT sau_edif_saude_p_tipoclassecnae_check + CHECK (tipoclassecnae = ANY(ARRAY[0 :: SMALLINT, 26 :: SMALLINT, 27 :: SMALLINT, 28 :: SMALLINT, 29 :: SMALLINT, 30 :: SMALLINT, 31 :: SMALLINT, 98 :: SMALLINT, 99 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.sau_edif_saude_p ALTER COLUMN tipoclassecnae SET DEFAULT 999# CREATE TABLE cb.sau_edif_servico_social_a( id serial NOT NULL, @@ -9463,8 +9463,8 @@ ALTER TABLE cb.sau_edif_servico_social_a REFERENCES dominios.matconstr (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.sau_edif_servico_social_a - ADD CONSTRAINT sau_edif_servico_social_a_matconstr_check - CHECK (matconstr = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 4 :: SMALLINT, 5 :: SMALLINT, 97 :: SMALLINT, 99 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT sau_edif_servico_social_a_matconstr_check + CHECK (matconstr = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 4 :: SMALLINT, 5 :: SMALLINT, 97 :: SMALLINT, 99 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.sau_edif_servico_social_a ALTER COLUMN matconstr SET DEFAULT 999# ALTER TABLE cb.sau_edif_servico_social_a ADD CONSTRAINT sau_edif_servico_social_a_operacional_fk FOREIGN KEY (operacional) @@ -9476,16 +9476,16 @@ ALTER TABLE cb.sau_edif_servico_social_a REFERENCES dominios.situacaofisica (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.sau_edif_servico_social_a - ADD CONSTRAINT sau_edif_servico_social_a_situacaofisica_check - CHECK (situacaofisica = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT sau_edif_servico_social_a_situacaofisica_check + CHECK (situacaofisica = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.sau_edif_servico_social_a ALTER COLUMN situacaofisica SET DEFAULT 999# ALTER TABLE cb.sau_edif_servico_social_a ADD CONSTRAINT sau_edif_servico_social_a_tipoclassecnae_fk FOREIGN KEY (tipoclassecnae) REFERENCES dominios.tipoclassecnae (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.sau_edif_servico_social_a - ADD CONSTRAINT sau_edif_servico_social_a_tipoclassecnae_check - CHECK (tipoclassecnae = ANY(ARRAY[0 :: SMALLINT, 32 :: SMALLINT, 33 :: SMALLINT, 98 :: SMALLINT, 99 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT sau_edif_servico_social_a_tipoclassecnae_check + CHECK (tipoclassecnae = ANY(ARRAY[0 :: SMALLINT, 32 :: SMALLINT, 33 :: SMALLINT, 98 :: SMALLINT, 99 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.sau_edif_servico_social_a ALTER COLUMN tipoclassecnae SET DEFAULT 999# CREATE TABLE cb.sau_edif_servico_social_p( id serial NOT NULL, @@ -9511,8 +9511,8 @@ ALTER TABLE cb.sau_edif_servico_social_p REFERENCES dominios.matconstr (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.sau_edif_servico_social_p - ADD CONSTRAINT sau_edif_servico_social_p_matconstr_check - CHECK (matconstr = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 4 :: SMALLINT, 5 :: SMALLINT, 97 :: SMALLINT, 99 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT sau_edif_servico_social_p_matconstr_check + CHECK (matconstr = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 4 :: SMALLINT, 5 :: SMALLINT, 97 :: SMALLINT, 99 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.sau_edif_servico_social_p ALTER COLUMN matconstr SET DEFAULT 999# ALTER TABLE cb.sau_edif_servico_social_p ADD CONSTRAINT sau_edif_servico_social_p_operacional_fk FOREIGN KEY (operacional) @@ -9524,16 +9524,16 @@ ALTER TABLE cb.sau_edif_servico_social_p REFERENCES dominios.situacaofisica (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.sau_edif_servico_social_p - ADD CONSTRAINT sau_edif_servico_social_p_situacaofisica_check - CHECK (situacaofisica = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT sau_edif_servico_social_p_situacaofisica_check + CHECK (situacaofisica = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.sau_edif_servico_social_p ALTER COLUMN situacaofisica SET DEFAULT 999# ALTER TABLE cb.sau_edif_servico_social_p ADD CONSTRAINT sau_edif_servico_social_p_tipoclassecnae_fk FOREIGN KEY (tipoclassecnae) REFERENCES dominios.tipoclassecnae (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.sau_edif_servico_social_p - ADD CONSTRAINT sau_edif_servico_social_p_tipoclassecnae_check - CHECK (tipoclassecnae = ANY(ARRAY[0 :: SMALLINT, 32 :: SMALLINT, 33 :: SMALLINT, 98 :: SMALLINT, 99 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT sau_edif_servico_social_p_tipoclassecnae_check + CHECK (tipoclassecnae = ANY(ARRAY[0 :: SMALLINT, 32 :: SMALLINT, 33 :: SMALLINT, 98 :: SMALLINT, 99 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.sau_edif_servico_social_p ALTER COLUMN tipoclassecnae SET DEFAULT 999# CREATE TABLE cb.tra_area_duto_a( id serial NOT NULL, @@ -9627,8 +9627,8 @@ ALTER TABLE cb.tra_atracadouro_a REFERENCES dominios.administracao (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.tra_atracadouro_a - ADD CONSTRAINT tra_atracadouro_a_administracao_check - CHECK (administracao = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 6 :: SMALLINT, 7 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT tra_atracadouro_a_administracao_check + CHECK (administracao = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 6 :: SMALLINT, 7 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.tra_atracadouro_a ALTER COLUMN administracao SET DEFAULT 999# ALTER TABLE cb.tra_atracadouro_a ADD CONSTRAINT tra_atracadouro_a_geometriaaproximada_fk FOREIGN KEY (geometriaaproximada) @@ -9640,8 +9640,8 @@ ALTER TABLE cb.tra_atracadouro_a REFERENCES dominios.matconstr (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.tra_atracadouro_a - ADD CONSTRAINT tra_atracadouro_a_matconstr_check - CHECK (matconstr = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 4 :: SMALLINT, 5 :: SMALLINT, 99 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT tra_atracadouro_a_matconstr_check + CHECK (matconstr = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 4 :: SMALLINT, 5 :: SMALLINT, 99 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.tra_atracadouro_a ALTER COLUMN matconstr SET DEFAULT 999# ALTER TABLE cb.tra_atracadouro_a ADD CONSTRAINT tra_atracadouro_a_operacional_fk FOREIGN KEY (operacional) @@ -9678,8 +9678,8 @@ ALTER TABLE cb.tra_atracadouro_l REFERENCES dominios.administracao (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.tra_atracadouro_l - ADD CONSTRAINT tra_atracadouro_l_administracao_check - CHECK (administracao = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 6 :: SMALLINT, 7 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT tra_atracadouro_l_administracao_check + CHECK (administracao = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 6 :: SMALLINT, 7 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.tra_atracadouro_l ALTER COLUMN administracao SET DEFAULT 999# ALTER TABLE cb.tra_atracadouro_l ADD CONSTRAINT tra_atracadouro_l_geometriaaproximada_fk FOREIGN KEY (geometriaaproximada) @@ -9691,8 +9691,8 @@ ALTER TABLE cb.tra_atracadouro_l REFERENCES dominios.matconstr (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.tra_atracadouro_l - ADD CONSTRAINT tra_atracadouro_l_matconstr_check - CHECK (matconstr = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 4 :: SMALLINT, 5 :: SMALLINT, 99 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT tra_atracadouro_l_matconstr_check + CHECK (matconstr = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 4 :: SMALLINT, 5 :: SMALLINT, 99 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.tra_atracadouro_l ALTER COLUMN matconstr SET DEFAULT 999# ALTER TABLE cb.tra_atracadouro_l ADD CONSTRAINT tra_atracadouro_l_operacional_fk FOREIGN KEY (operacional) @@ -9729,8 +9729,8 @@ ALTER TABLE cb.tra_atracadouro_p REFERENCES dominios.administracao (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.tra_atracadouro_p - ADD CONSTRAINT tra_atracadouro_p_administracao_check - CHECK (administracao = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 6 :: SMALLINT, 7 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT tra_atracadouro_p_administracao_check + CHECK (administracao = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 6 :: SMALLINT, 7 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.tra_atracadouro_p ALTER COLUMN administracao SET DEFAULT 999# ALTER TABLE cb.tra_atracadouro_p ADD CONSTRAINT tra_atracadouro_p_geometriaaproximada_fk FOREIGN KEY (geometriaaproximada) @@ -9742,8 +9742,8 @@ ALTER TABLE cb.tra_atracadouro_p REFERENCES dominios.matconstr (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.tra_atracadouro_p - ADD CONSTRAINT tra_atracadouro_p_matconstr_check - CHECK (matconstr = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 4 :: SMALLINT, 5 :: SMALLINT, 99 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT tra_atracadouro_p_matconstr_check + CHECK (matconstr = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 4 :: SMALLINT, 5 :: SMALLINT, 99 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.tra_atracadouro_p ALTER COLUMN matconstr SET DEFAULT 999# ALTER TABLE cb.tra_atracadouro_p ADD CONSTRAINT tra_atracadouro_p_operacional_fk FOREIGN KEY (operacional) @@ -9789,8 +9789,8 @@ ALTER TABLE cb.tra_caminho_aereo_l REFERENCES dominios.situacaofisica (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.tra_caminho_aereo_l - ADD CONSTRAINT tra_caminho_aereo_l_situacaofisica_check - CHECK (situacaofisica = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT tra_caminho_aereo_l_situacaofisica_check + CHECK (situacaofisica = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.tra_caminho_aereo_l ALTER COLUMN situacaofisica SET DEFAULT 999# ALTER TABLE cb.tra_caminho_aereo_l ADD CONSTRAINT tra_caminho_aereo_l_tipocaminhoaereo_fk FOREIGN KEY (tipocaminhoaereo) @@ -9822,8 +9822,8 @@ ALTER TABLE cb.tra_ciclovia_l REFERENCES dominios.administracao (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.tra_ciclovia_l - ADD CONSTRAINT tra_ciclovia_l_administracao_check - CHECK (administracao = ANY(ARRAY[0 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 4 :: SMALLINT, 6 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT tra_ciclovia_l_administracao_check + CHECK (administracao = ANY(ARRAY[0 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 4 :: SMALLINT, 6 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.tra_ciclovia_l ALTER COLUMN administracao SET DEFAULT 999# ALTER TABLE cb.tra_ciclovia_l ADD CONSTRAINT tra_ciclovia_l_geometriaaproximada_fk FOREIGN KEY (geometriaaproximada) @@ -9879,16 +9879,16 @@ ALTER TABLE cb.tra_condutor_hidrico_l REFERENCES dominios.matconstr (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.tra_condutor_hidrico_l - ADD CONSTRAINT tra_condutor_hidrico_l_matconstr_check - CHECK (matconstr = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 4 :: SMALLINT, 99 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT tra_condutor_hidrico_l_matconstr_check + CHECK (matconstr = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 4 :: SMALLINT, 99 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.tra_condutor_hidrico_l ALTER COLUMN matconstr SET DEFAULT 999# ALTER TABLE cb.tra_condutor_hidrico_l ADD CONSTRAINT tra_condutor_hidrico_l_mattransp_fk FOREIGN KEY (mattransp) REFERENCES dominios.mattransp (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.tra_condutor_hidrico_l - ADD CONSTRAINT tra_condutor_hidrico_l_mattransp_check - CHECK (mattransp = ANY(ARRAY[1 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT tra_condutor_hidrico_l_mattransp_check + CHECK (mattransp = ANY(ARRAY[1 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.tra_condutor_hidrico_l ALTER COLUMN mattransp SET DEFAULT 999# ALTER TABLE cb.tra_condutor_hidrico_l ADD CONSTRAINT tra_condutor_hidrico_l_operacional_fk FOREIGN KEY (operacional) @@ -9905,8 +9905,8 @@ ALTER TABLE cb.tra_condutor_hidrico_l REFERENCES dominios.setor (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.tra_condutor_hidrico_l - ADD CONSTRAINT tra_condutor_hidrico_l_setor_check - CHECK (setor = ANY(ARRAY[1 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT tra_condutor_hidrico_l_setor_check + CHECK (setor = ANY(ARRAY[1 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.tra_condutor_hidrico_l ALTER COLUMN setor SET DEFAULT 999# ALTER TABLE cb.tra_condutor_hidrico_l ADD CONSTRAINT tra_condutor_hidrico_l_situacaoespacial_fk FOREIGN KEY (situacaoespacial) @@ -9918,8 +9918,8 @@ ALTER TABLE cb.tra_condutor_hidrico_l REFERENCES dominios.situacaofisica (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.tra_condutor_hidrico_l - ADD CONSTRAINT tra_condutor_hidrico_l_situacaofisica_check - CHECK (situacaofisica = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT tra_condutor_hidrico_l_situacaofisica_check + CHECK (situacaofisica = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.tra_condutor_hidrico_l ALTER COLUMN situacaofisica SET DEFAULT 999# ALTER TABLE cb.tra_condutor_hidrico_l ADD CONSTRAINT tra_condutor_hidrico_l_tipocondutor_fk FOREIGN KEY (tipocondutor) @@ -10046,8 +10046,8 @@ ALTER TABLE cb.tra_eclusa_a REFERENCES dominios.matconstr (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.tra_eclusa_a - ADD CONSTRAINT tra_eclusa_a_matconstr_check - CHECK (matconstr = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 99 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT tra_eclusa_a_matconstr_check + CHECK (matconstr = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 99 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.tra_eclusa_a ALTER COLUMN matconstr SET DEFAULT 999# ALTER TABLE cb.tra_eclusa_a ADD CONSTRAINT tra_eclusa_a_operacional_fk FOREIGN KEY (operacional) @@ -10059,8 +10059,8 @@ ALTER TABLE cb.tra_eclusa_a REFERENCES dominios.situacaofisica (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.tra_eclusa_a - ADD CONSTRAINT tra_eclusa_a_situacaofisica_check - CHECK (situacaofisica = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT tra_eclusa_a_situacaofisica_check + CHECK (situacaofisica = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.tra_eclusa_a ALTER COLUMN situacaofisica SET DEFAULT 999# CREATE TABLE cb.tra_eclusa_l( id serial NOT NULL, @@ -10089,8 +10089,8 @@ ALTER TABLE cb.tra_eclusa_l REFERENCES dominios.matconstr (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.tra_eclusa_l - ADD CONSTRAINT tra_eclusa_l_matconstr_check - CHECK (matconstr = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 99 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT tra_eclusa_l_matconstr_check + CHECK (matconstr = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 99 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.tra_eclusa_l ALTER COLUMN matconstr SET DEFAULT 999# ALTER TABLE cb.tra_eclusa_l ADD CONSTRAINT tra_eclusa_l_operacional_fk FOREIGN KEY (operacional) @@ -10102,8 +10102,8 @@ ALTER TABLE cb.tra_eclusa_l REFERENCES dominios.situacaofisica (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.tra_eclusa_l - ADD CONSTRAINT tra_eclusa_l_situacaofisica_check - CHECK (situacaofisica = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT tra_eclusa_l_situacaofisica_check + CHECK (situacaofisica = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.tra_eclusa_l ALTER COLUMN situacaofisica SET DEFAULT 999# CREATE TABLE cb.tra_eclusa_p( id serial NOT NULL, @@ -10132,8 +10132,8 @@ ALTER TABLE cb.tra_eclusa_p REFERENCES dominios.matconstr (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.tra_eclusa_p - ADD CONSTRAINT tra_eclusa_p_matconstr_check - CHECK (matconstr = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 99 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT tra_eclusa_p_matconstr_check + CHECK (matconstr = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 99 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.tra_eclusa_p ALTER COLUMN matconstr SET DEFAULT 999# ALTER TABLE cb.tra_eclusa_p ADD CONSTRAINT tra_eclusa_p_operacional_fk FOREIGN KEY (operacional) @@ -10145,8 +10145,8 @@ ALTER TABLE cb.tra_eclusa_p REFERENCES dominios.situacaofisica (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.tra_eclusa_p - ADD CONSTRAINT tra_eclusa_p_situacaofisica_check - CHECK (situacaofisica = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT tra_eclusa_p_situacaofisica_check + CHECK (situacaofisica = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.tra_eclusa_p ALTER COLUMN situacaofisica SET DEFAULT 999# CREATE TABLE cb.tra_edif_constr_aeroportuaria_a( id serial NOT NULL, @@ -10168,8 +10168,8 @@ ALTER TABLE cb.tra_edif_constr_aeroportuaria_a REFERENCES dominios.administracao (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.tra_edif_constr_aeroportuaria_a - ADD CONSTRAINT tra_edif_constr_aeroportuaria_a_administracao_check - CHECK (administracao = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 6 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT tra_edif_constr_aeroportuaria_a_administracao_check + CHECK (administracao = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 6 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.tra_edif_constr_aeroportuaria_a ALTER COLUMN administracao SET DEFAULT 999# ALTER TABLE cb.tra_edif_constr_aeroportuaria_a ADD CONSTRAINT tra_edif_constr_aeroportuaria_a_geometriaaproximada_fk FOREIGN KEY (geometriaaproximada) @@ -10181,8 +10181,8 @@ ALTER TABLE cb.tra_edif_constr_aeroportuaria_a REFERENCES dominios.matconstr (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.tra_edif_constr_aeroportuaria_a - ADD CONSTRAINT tra_edif_constr_aeroportuaria_a_matconstr_check - CHECK (matconstr = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 99 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT tra_edif_constr_aeroportuaria_a_matconstr_check + CHECK (matconstr = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 99 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.tra_edif_constr_aeroportuaria_a ALTER COLUMN matconstr SET DEFAULT 999# ALTER TABLE cb.tra_edif_constr_aeroportuaria_a ADD CONSTRAINT tra_edif_constr_aeroportuaria_a_operacional_fk FOREIGN KEY (operacional) @@ -10219,8 +10219,8 @@ ALTER TABLE cb.tra_edif_constr_aeroportuaria_p REFERENCES dominios.administracao (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.tra_edif_constr_aeroportuaria_p - ADD CONSTRAINT tra_edif_constr_aeroportuaria_p_administracao_check - CHECK (administracao = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 6 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT tra_edif_constr_aeroportuaria_p_administracao_check + CHECK (administracao = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 6 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.tra_edif_constr_aeroportuaria_p ALTER COLUMN administracao SET DEFAULT 999# ALTER TABLE cb.tra_edif_constr_aeroportuaria_p ADD CONSTRAINT tra_edif_constr_aeroportuaria_p_geometriaaproximada_fk FOREIGN KEY (geometriaaproximada) @@ -10232,8 +10232,8 @@ ALTER TABLE cb.tra_edif_constr_aeroportuaria_p REFERENCES dominios.matconstr (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.tra_edif_constr_aeroportuaria_p - ADD CONSTRAINT tra_edif_constr_aeroportuaria_p_matconstr_check - CHECK (matconstr = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 99 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT tra_edif_constr_aeroportuaria_p_matconstr_check + CHECK (matconstr = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 99 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.tra_edif_constr_aeroportuaria_p ALTER COLUMN matconstr SET DEFAULT 999# ALTER TABLE cb.tra_edif_constr_aeroportuaria_p ADD CONSTRAINT tra_edif_constr_aeroportuaria_p_operacional_fk FOREIGN KEY (operacional) @@ -10270,8 +10270,8 @@ ALTER TABLE cb.tra_edif_constr_portuaria_a REFERENCES dominios.administracao (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.tra_edif_constr_portuaria_a - ADD CONSTRAINT tra_edif_constr_portuaria_a_administracao_check - CHECK (administracao = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 6 :: SMALLINT, 7 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT tra_edif_constr_portuaria_a_administracao_check + CHECK (administracao = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 6 :: SMALLINT, 7 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.tra_edif_constr_portuaria_a ALTER COLUMN administracao SET DEFAULT 999# ALTER TABLE cb.tra_edif_constr_portuaria_a ADD CONSTRAINT tra_edif_constr_portuaria_a_geometriaaproximada_fk FOREIGN KEY (geometriaaproximada) @@ -10283,8 +10283,8 @@ ALTER TABLE cb.tra_edif_constr_portuaria_a REFERENCES dominios.matconstr (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.tra_edif_constr_portuaria_a - ADD CONSTRAINT tra_edif_constr_portuaria_a_matconstr_check - CHECK (matconstr = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 99 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT tra_edif_constr_portuaria_a_matconstr_check + CHECK (matconstr = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 99 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.tra_edif_constr_portuaria_a ALTER COLUMN matconstr SET DEFAULT 999# ALTER TABLE cb.tra_edif_constr_portuaria_a ADD CONSTRAINT tra_edif_constr_portuaria_a_operacional_fk FOREIGN KEY (operacional) @@ -10321,8 +10321,8 @@ ALTER TABLE cb.tra_edif_constr_portuaria_p REFERENCES dominios.administracao (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.tra_edif_constr_portuaria_p - ADD CONSTRAINT tra_edif_constr_portuaria_p_administracao_check - CHECK (administracao = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 6 :: SMALLINT, 7 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT tra_edif_constr_portuaria_p_administracao_check + CHECK (administracao = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 6 :: SMALLINT, 7 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.tra_edif_constr_portuaria_p ALTER COLUMN administracao SET DEFAULT 999# ALTER TABLE cb.tra_edif_constr_portuaria_p ADD CONSTRAINT tra_edif_constr_portuaria_p_geometriaaproximada_fk FOREIGN KEY (geometriaaproximada) @@ -10334,8 +10334,8 @@ ALTER TABLE cb.tra_edif_constr_portuaria_p REFERENCES dominios.matconstr (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.tra_edif_constr_portuaria_p - ADD CONSTRAINT tra_edif_constr_portuaria_p_matconstr_check - CHECK (matconstr = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 99 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT tra_edif_constr_portuaria_p_matconstr_check + CHECK (matconstr = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 99 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.tra_edif_constr_portuaria_p ALTER COLUMN matconstr SET DEFAULT 999# ALTER TABLE cb.tra_edif_constr_portuaria_p ADD CONSTRAINT tra_edif_constr_portuaria_p_operacional_fk FOREIGN KEY (operacional) @@ -10373,8 +10373,8 @@ ALTER TABLE cb.tra_edif_metro_ferroviaria_a REFERENCES dominios.administracao (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.tra_edif_metro_ferroviaria_a - ADD CONSTRAINT tra_edif_metro_ferroviaria_a_administracao_check - CHECK (administracao = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 6 :: SMALLINT, 7 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT tra_edif_metro_ferroviaria_a_administracao_check + CHECK (administracao = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 6 :: SMALLINT, 7 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.tra_edif_metro_ferroviaria_a ALTER COLUMN administracao SET DEFAULT 999# ALTER TABLE cb.tra_edif_metro_ferroviaria_a ADD CONSTRAINT tra_edif_metro_ferroviaria_a_funcaoedifmetroferrov_fk FOREIGN KEY (funcaoedifmetroferrov) @@ -10391,8 +10391,8 @@ ALTER TABLE cb.tra_edif_metro_ferroviaria_a REFERENCES dominios.matconstr (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.tra_edif_metro_ferroviaria_a - ADD CONSTRAINT tra_edif_metro_ferroviaria_a_matconstr_check - CHECK (matconstr = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 99 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT tra_edif_metro_ferroviaria_a_matconstr_check + CHECK (matconstr = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 99 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.tra_edif_metro_ferroviaria_a ALTER COLUMN matconstr SET DEFAULT 999# ALTER TABLE cb.tra_edif_metro_ferroviaria_a ADD CONSTRAINT tra_edif_metro_ferroviaria_a_multimodal_fk FOREIGN KEY (multimodal) @@ -10430,8 +10430,8 @@ ALTER TABLE cb.tra_edif_metro_ferroviaria_p REFERENCES dominios.administracao (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.tra_edif_metro_ferroviaria_p - ADD CONSTRAINT tra_edif_metro_ferroviaria_p_administracao_check - CHECK (administracao = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 6 :: SMALLINT, 7 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT tra_edif_metro_ferroviaria_p_administracao_check + CHECK (administracao = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 6 :: SMALLINT, 7 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.tra_edif_metro_ferroviaria_p ALTER COLUMN administracao SET DEFAULT 999# ALTER TABLE cb.tra_edif_metro_ferroviaria_p ADD CONSTRAINT tra_edif_metro_ferroviaria_p_funcaoedifmetroferrov_fk FOREIGN KEY (funcaoedifmetroferrov) @@ -10448,8 +10448,8 @@ ALTER TABLE cb.tra_edif_metro_ferroviaria_p REFERENCES dominios.matconstr (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.tra_edif_metro_ferroviaria_p - ADD CONSTRAINT tra_edif_metro_ferroviaria_p_matconstr_check - CHECK (matconstr = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 99 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT tra_edif_metro_ferroviaria_p_matconstr_check + CHECK (matconstr = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 99 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.tra_edif_metro_ferroviaria_p ALTER COLUMN matconstr SET DEFAULT 999# ALTER TABLE cb.tra_edif_metro_ferroviaria_p ADD CONSTRAINT tra_edif_metro_ferroviaria_p_multimodal_fk FOREIGN KEY (multimodal) @@ -10486,8 +10486,8 @@ ALTER TABLE cb.tra_edif_rodoviaria_a REFERENCES dominios.administracao (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.tra_edif_rodoviaria_a - ADD CONSTRAINT tra_edif_rodoviaria_a_administracao_check - CHECK (administracao = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 6 :: SMALLINT, 7 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT tra_edif_rodoviaria_a_administracao_check + CHECK (administracao = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 6 :: SMALLINT, 7 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.tra_edif_rodoviaria_a ALTER COLUMN administracao SET DEFAULT 999# ALTER TABLE cb.tra_edif_rodoviaria_a ADD CONSTRAINT tra_edif_rodoviaria_a_geometriaaproximada_fk FOREIGN KEY (geometriaaproximada) @@ -10499,8 +10499,8 @@ ALTER TABLE cb.tra_edif_rodoviaria_a REFERENCES dominios.matconstr (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.tra_edif_rodoviaria_a - ADD CONSTRAINT tra_edif_rodoviaria_a_matconstr_check - CHECK (matconstr = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 99 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT tra_edif_rodoviaria_a_matconstr_check + CHECK (matconstr = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 99 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.tra_edif_rodoviaria_a ALTER COLUMN matconstr SET DEFAULT 999# ALTER TABLE cb.tra_edif_rodoviaria_a ADD CONSTRAINT tra_edif_rodoviaria_a_operacional_fk FOREIGN KEY (operacional) @@ -10512,8 +10512,8 @@ ALTER TABLE cb.tra_edif_rodoviaria_a REFERENCES dominios.situacaofisica (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.tra_edif_rodoviaria_a - ADD CONSTRAINT tra_edif_rodoviaria_a_situacaofisica_check - CHECK (situacaofisica = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT tra_edif_rodoviaria_a_situacaofisica_check + CHECK (situacaofisica = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.tra_edif_rodoviaria_a ALTER COLUMN situacaofisica SET DEFAULT 999# ALTER TABLE cb.tra_edif_rodoviaria_a ADD CONSTRAINT tra_edif_rodoviaria_a_tipoedifrod_fk FOREIGN KEY (tipoedifrod) @@ -10540,8 +10540,8 @@ ALTER TABLE cb.tra_edif_rodoviaria_p REFERENCES dominios.administracao (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.tra_edif_rodoviaria_p - ADD CONSTRAINT tra_edif_rodoviaria_p_administracao_check - CHECK (administracao = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 6 :: SMALLINT, 7 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT tra_edif_rodoviaria_p_administracao_check + CHECK (administracao = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 6 :: SMALLINT, 7 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.tra_edif_rodoviaria_p ALTER COLUMN administracao SET DEFAULT 999# ALTER TABLE cb.tra_edif_rodoviaria_p ADD CONSTRAINT tra_edif_rodoviaria_p_geometriaaproximada_fk FOREIGN KEY (geometriaaproximada) @@ -10553,8 +10553,8 @@ ALTER TABLE cb.tra_edif_rodoviaria_p REFERENCES dominios.matconstr (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.tra_edif_rodoviaria_p - ADD CONSTRAINT tra_edif_rodoviaria_p_matconstr_check - CHECK (matconstr = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 99 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT tra_edif_rodoviaria_p_matconstr_check + CHECK (matconstr = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 99 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.tra_edif_rodoviaria_p ALTER COLUMN matconstr SET DEFAULT 999# ALTER TABLE cb.tra_edif_rodoviaria_p ADD CONSTRAINT tra_edif_rodoviaria_p_operacional_fk FOREIGN KEY (operacional) @@ -10566,8 +10566,8 @@ ALTER TABLE cb.tra_edif_rodoviaria_p REFERENCES dominios.situacaofisica (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.tra_edif_rodoviaria_p - ADD CONSTRAINT tra_edif_rodoviaria_p_situacaofisica_check - CHECK (situacaofisica = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT tra_edif_rodoviaria_p_situacaofisica_check + CHECK (situacaofisica = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.tra_edif_rodoviaria_p ALTER COLUMN situacaofisica SET DEFAULT 999# ALTER TABLE cb.tra_edif_rodoviaria_p ADD CONSTRAINT tra_edif_rodoviaria_p_tipoedifrod_fk FOREIGN KEY (tipoedifrod) @@ -10627,8 +10627,8 @@ ALTER TABLE cb.tra_fundeadouro_a REFERENCES dominios.administracao (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.tra_fundeadouro_a - ADD CONSTRAINT tra_fundeadouro_a_administracao_check - CHECK (administracao = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 6 :: SMALLINT, 7 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT tra_fundeadouro_a_administracao_check + CHECK (administracao = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 6 :: SMALLINT, 7 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.tra_fundeadouro_a ALTER COLUMN administracao SET DEFAULT 999# ALTER TABLE cb.tra_fundeadouro_a ADD CONSTRAINT tra_fundeadouro_a_destinacaofundeadouro_fk FOREIGN KEY (destinacaofundeadouro) @@ -10657,8 +10657,8 @@ ALTER TABLE cb.tra_fundeadouro_l REFERENCES dominios.administracao (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.tra_fundeadouro_l - ADD CONSTRAINT tra_fundeadouro_l_administracao_check - CHECK (administracao = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 6 :: SMALLINT, 7 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT tra_fundeadouro_l_administracao_check + CHECK (administracao = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 6 :: SMALLINT, 7 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.tra_fundeadouro_l ALTER COLUMN administracao SET DEFAULT 999# ALTER TABLE cb.tra_fundeadouro_l ADD CONSTRAINT tra_fundeadouro_l_destinacaofundeadouro_fk FOREIGN KEY (destinacaofundeadouro) @@ -10687,8 +10687,8 @@ ALTER TABLE cb.tra_fundeadouro_p REFERENCES dominios.administracao (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.tra_fundeadouro_p - ADD CONSTRAINT tra_fundeadouro_p_administracao_check - CHECK (administracao = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 6 :: SMALLINT, 7 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT tra_fundeadouro_p_administracao_check + CHECK (administracao = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 6 :: SMALLINT, 7 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.tra_fundeadouro_p ALTER COLUMN administracao SET DEFAULT 999# ALTER TABLE cb.tra_fundeadouro_p ADD CONSTRAINT tra_fundeadouro_p_destinacaofundeadouro_fk FOREIGN KEY (destinacaofundeadouro) @@ -10778,8 +10778,8 @@ ALTER TABLE cb.tra_galeria_bueiro_l REFERENCES dominios.matconstr (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.tra_galeria_bueiro_l - ADD CONSTRAINT tra_galeria_bueiro_l_matconstr_check - CHECK (matconstr = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 4 :: SMALLINT, 99 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT tra_galeria_bueiro_l_matconstr_check + CHECK (matconstr = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 4 :: SMALLINT, 99 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.tra_galeria_bueiro_l ALTER COLUMN matconstr SET DEFAULT 999# ALTER TABLE cb.tra_galeria_bueiro_l ADD CONSTRAINT tra_galeria_bueiro_l_operacional_fk FOREIGN KEY (operacional) @@ -10791,8 +10791,8 @@ ALTER TABLE cb.tra_galeria_bueiro_l REFERENCES dominios.situacaofisica (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.tra_galeria_bueiro_l - ADD CONSTRAINT tra_galeria_bueiro_l_situacaofisica_check - CHECK (situacaofisica = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT tra_galeria_bueiro_l_situacaofisica_check + CHECK (situacaofisica = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.tra_galeria_bueiro_l ALTER COLUMN situacaofisica SET DEFAULT 999# CREATE TABLE cb.tra_galeria_bueiro_p( id serial NOT NULL, @@ -10818,8 +10818,8 @@ ALTER TABLE cb.tra_galeria_bueiro_p REFERENCES dominios.matconstr (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.tra_galeria_bueiro_p - ADD CONSTRAINT tra_galeria_bueiro_p_matconstr_check - CHECK (matconstr = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 4 :: SMALLINT, 99 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT tra_galeria_bueiro_p_matconstr_check + CHECK (matconstr = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 4 :: SMALLINT, 99 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.tra_galeria_bueiro_p ALTER COLUMN matconstr SET DEFAULT 999# ALTER TABLE cb.tra_galeria_bueiro_p ADD CONSTRAINT tra_galeria_bueiro_p_operacional_fk FOREIGN KEY (operacional) @@ -10831,8 +10831,8 @@ ALTER TABLE cb.tra_galeria_bueiro_p REFERENCES dominios.situacaofisica (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.tra_galeria_bueiro_p - ADD CONSTRAINT tra_galeria_bueiro_p_situacaofisica_check - CHECK (situacaofisica = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT tra_galeria_bueiro_p_situacaofisica_check + CHECK (situacaofisica = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.tra_galeria_bueiro_p ALTER COLUMN situacaofisica SET DEFAULT 999# CREATE TABLE cb.tra_girador_ferroviario_p( id serial NOT NULL, @@ -10852,8 +10852,8 @@ ALTER TABLE cb.tra_girador_ferroviario_p REFERENCES dominios.administracao (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.tra_girador_ferroviario_p - ADD CONSTRAINT tra_girador_ferroviario_p_administracao_check - CHECK (administracao = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 6 :: SMALLINT, 7 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT tra_girador_ferroviario_p_administracao_check + CHECK (administracao = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 6 :: SMALLINT, 7 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.tra_girador_ferroviario_p ALTER COLUMN administracao SET DEFAULT 999# ALTER TABLE cb.tra_girador_ferroviario_p ADD CONSTRAINT tra_girador_ferroviario_p_geometriaaproximada_fk FOREIGN KEY (geometriaaproximada) @@ -11059,16 +11059,16 @@ ALTER TABLE cb.tra_passag_elevada_viaduto_l REFERENCES dominios.matconstr (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.tra_passag_elevada_viaduto_l - ADD CONSTRAINT tra_passag_elevada_viaduto_l_matconstr_check - CHECK (matconstr = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 99 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT tra_passag_elevada_viaduto_l_matconstr_check + CHECK (matconstr = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 99 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.tra_passag_elevada_viaduto_l ALTER COLUMN matconstr SET DEFAULT 999# ALTER TABLE cb.tra_passag_elevada_viaduto_l ADD CONSTRAINT tra_passag_elevada_viaduto_l_modaluso_fk FOREIGN KEY (modaluso) REFERENCES dominios.modaluso (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.tra_passag_elevada_viaduto_l - ADD CONSTRAINT tra_passag_elevada_viaduto_l_modaluso_check - CHECK (modaluso = ANY(ARRAY[4 :: SMALLINT, 5 :: SMALLINT, 8 :: SMALLINT, 9 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT tra_passag_elevada_viaduto_l_modaluso_check + CHECK (modaluso = ANY(ARRAY[4 :: SMALLINT, 5 :: SMALLINT, 8 :: SMALLINT, 9 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.tra_passag_elevada_viaduto_l ALTER COLUMN modaluso SET DEFAULT 999# ALTER TABLE cb.tra_passag_elevada_viaduto_l ADD CONSTRAINT tra_passag_elevada_viaduto_l_operacional_fk FOREIGN KEY (operacional) @@ -11125,16 +11125,16 @@ ALTER TABLE cb.tra_passag_elevada_viaduto_p REFERENCES dominios.matconstr (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.tra_passag_elevada_viaduto_p - ADD CONSTRAINT tra_passag_elevada_viaduto_p_matconstr_check - CHECK (matconstr = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 99 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT tra_passag_elevada_viaduto_p_matconstr_check + CHECK (matconstr = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 99 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.tra_passag_elevada_viaduto_p ALTER COLUMN matconstr SET DEFAULT 999# ALTER TABLE cb.tra_passag_elevada_viaduto_p ADD CONSTRAINT tra_passag_elevada_viaduto_p_modaluso_fk FOREIGN KEY (modaluso) REFERENCES dominios.modaluso (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.tra_passag_elevada_viaduto_p - ADD CONSTRAINT tra_passag_elevada_viaduto_p_modaluso_check - CHECK (modaluso = ANY(ARRAY[4 :: SMALLINT, 5 :: SMALLINT, 8 :: SMALLINT, 9 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT tra_passag_elevada_viaduto_p_modaluso_check + CHECK (modaluso = ANY(ARRAY[4 :: SMALLINT, 5 :: SMALLINT, 8 :: SMALLINT, 9 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.tra_passag_elevada_viaduto_p ALTER COLUMN modaluso SET DEFAULT 999# ALTER TABLE cb.tra_passag_elevada_viaduto_p ADD CONSTRAINT tra_passag_elevada_viaduto_p_operacional_fk FOREIGN KEY (operacional) @@ -11190,8 +11190,8 @@ ALTER TABLE cb.tra_patio_a REFERENCES dominios.administracao (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.tra_patio_a - ADD CONSTRAINT tra_patio_a_administracao_check - CHECK (administracao = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 6 :: SMALLINT, 7 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT tra_patio_a_administracao_check + CHECK (administracao = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 6 :: SMALLINT, 7 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.tra_patio_a ALTER COLUMN administracao SET DEFAULT 999# ALTER TABLE cb.tra_patio_a ADD CONSTRAINT tra_patio_a_geometriaaproximada_fk FOREIGN KEY (geometriaaproximada) @@ -11203,8 +11203,8 @@ ALTER TABLE cb.tra_patio_a REFERENCES dominios.modaluso (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.tra_patio_a - ADD CONSTRAINT tra_patio_a_modaluso_check - CHECK (modaluso = ANY(ARRAY[4 :: SMALLINT, 5 :: SMALLINT, 6 :: SMALLINT, 9 :: SMALLINT, 14 :: SMALLINT, 98 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT tra_patio_a_modaluso_check + CHECK (modaluso = ANY(ARRAY[4 :: SMALLINT, 5 :: SMALLINT, 6 :: SMALLINT, 9 :: SMALLINT, 14 :: SMALLINT, 98 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.tra_patio_a ALTER COLUMN modaluso SET DEFAULT 999# ALTER TABLE cb.tra_patio_a ADD CONSTRAINT tra_patio_a_operacional_fk FOREIGN KEY (operacional) @@ -11235,8 +11235,8 @@ ALTER TABLE cb.tra_patio_p REFERENCES dominios.administracao (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.tra_patio_p - ADD CONSTRAINT tra_patio_p_administracao_check - CHECK (administracao = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 6 :: SMALLINT, 7 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT tra_patio_p_administracao_check + CHECK (administracao = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 6 :: SMALLINT, 7 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.tra_patio_p ALTER COLUMN administracao SET DEFAULT 999# ALTER TABLE cb.tra_patio_p ADD CONSTRAINT tra_patio_p_geometriaaproximada_fk FOREIGN KEY (geometriaaproximada) @@ -11248,8 +11248,8 @@ ALTER TABLE cb.tra_patio_p REFERENCES dominios.modaluso (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.tra_patio_p - ADD CONSTRAINT tra_patio_p_modaluso_check - CHECK (modaluso = ANY(ARRAY[4 :: SMALLINT, 5 :: SMALLINT, 6 :: SMALLINT, 9 :: SMALLINT, 14 :: SMALLINT, 98 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT tra_patio_p_modaluso_check + CHECK (modaluso = ANY(ARRAY[4 :: SMALLINT, 5 :: SMALLINT, 6 :: SMALLINT, 9 :: SMALLINT, 14 :: SMALLINT, 98 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.tra_patio_p ALTER COLUMN modaluso SET DEFAULT 999# ALTER TABLE cb.tra_patio_p ADD CONSTRAINT tra_patio_p_operacional_fk FOREIGN KEY (operacional) @@ -11309,8 +11309,8 @@ ALTER TABLE cb.tra_pista_ponto_pouso_a REFERENCES dominios.tipopista (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.tra_pista_ponto_pouso_a - ADD CONSTRAINT tra_pista_ponto_pouso_a_tipopista_check - CHECK (tipopista = ANY(ARRAY[9 :: SMALLINT, 10 :: SMALLINT, 11 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT tra_pista_ponto_pouso_a_tipopista_check + CHECK (tipopista = ANY(ARRAY[9 :: SMALLINT, 10 :: SMALLINT, 11 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.tra_pista_ponto_pouso_a ALTER COLUMN tipopista SET DEFAULT 999# ALTER TABLE cb.tra_pista_ponto_pouso_a ADD CONSTRAINT tra_pista_ponto_pouso_a_usopista_fk FOREIGN KEY (usopista) @@ -11365,8 +11365,8 @@ ALTER TABLE cb.tra_pista_ponto_pouso_l REFERENCES dominios.tipopista (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.tra_pista_ponto_pouso_l - ADD CONSTRAINT tra_pista_ponto_pouso_l_tipopista_check - CHECK (tipopista = ANY(ARRAY[9 :: SMALLINT, 10 :: SMALLINT, 11 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT tra_pista_ponto_pouso_l_tipopista_check + CHECK (tipopista = ANY(ARRAY[9 :: SMALLINT, 10 :: SMALLINT, 11 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.tra_pista_ponto_pouso_l ALTER COLUMN tipopista SET DEFAULT 999# ALTER TABLE cb.tra_pista_ponto_pouso_l ADD CONSTRAINT tra_pista_ponto_pouso_l_usopista_fk FOREIGN KEY (usopista) @@ -11421,8 +11421,8 @@ ALTER TABLE cb.tra_pista_ponto_pouso_p REFERENCES dominios.tipopista (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.tra_pista_ponto_pouso_p - ADD CONSTRAINT tra_pista_ponto_pouso_p_tipopista_check - CHECK (tipopista = ANY(ARRAY[9 :: SMALLINT, 10 :: SMALLINT, 11 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT tra_pista_ponto_pouso_p_tipopista_check + CHECK (tipopista = ANY(ARRAY[9 :: SMALLINT, 10 :: SMALLINT, 11 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.tra_pista_ponto_pouso_p ALTER COLUMN tipopista SET DEFAULT 999# ALTER TABLE cb.tra_pista_ponto_pouso_p ADD CONSTRAINT tra_pista_ponto_pouso_p_usopista_fk FOREIGN KEY (usopista) @@ -11462,16 +11462,16 @@ ALTER TABLE cb.tra_ponte_l REFERENCES dominios.matconstr (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.tra_ponte_l - ADD CONSTRAINT tra_ponte_l_matconstr_check - CHECK (matconstr = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 99 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT tra_ponte_l_matconstr_check + CHECK (matconstr = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 99 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.tra_ponte_l ALTER COLUMN matconstr SET DEFAULT 999# ALTER TABLE cb.tra_ponte_l ADD CONSTRAINT tra_ponte_l_modaluso_fk FOREIGN KEY (modaluso) REFERENCES dominios.modaluso (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.tra_ponte_l - ADD CONSTRAINT tra_ponte_l_modaluso_check - CHECK (modaluso = ANY(ARRAY[4 :: SMALLINT, 5 :: SMALLINT, 8 :: SMALLINT, 9 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT tra_ponte_l_modaluso_check + CHECK (modaluso = ANY(ARRAY[4 :: SMALLINT, 5 :: SMALLINT, 8 :: SMALLINT, 9 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.tra_ponte_l ALTER COLUMN modaluso SET DEFAULT 999# ALTER TABLE cb.tra_ponte_l ADD CONSTRAINT tra_ponte_l_operacional_fk FOREIGN KEY (operacional) @@ -11526,16 +11526,16 @@ ALTER TABLE cb.tra_ponte_p REFERENCES dominios.matconstr (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.tra_ponte_p - ADD CONSTRAINT tra_ponte_p_matconstr_check - CHECK (matconstr = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 99 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT tra_ponte_p_matconstr_check + CHECK (matconstr = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 99 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.tra_ponte_p ALTER COLUMN matconstr SET DEFAULT 999# ALTER TABLE cb.tra_ponte_p ADD CONSTRAINT tra_ponte_p_modaluso_fk FOREIGN KEY (modaluso) REFERENCES dominios.modaluso (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.tra_ponte_p - ADD CONSTRAINT tra_ponte_p_modaluso_check - CHECK (modaluso = ANY(ARRAY[4 :: SMALLINT, 5 :: SMALLINT, 8 :: SMALLINT, 9 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT tra_ponte_p_modaluso_check + CHECK (modaluso = ANY(ARRAY[4 :: SMALLINT, 5 :: SMALLINT, 8 :: SMALLINT, 9 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.tra_ponte_p ALTER COLUMN modaluso SET DEFAULT 999# ALTER TABLE cb.tra_ponte_p ADD CONSTRAINT tra_ponte_p_operacional_fk FOREIGN KEY (operacional) @@ -11633,8 +11633,8 @@ ALTER TABLE cb.tra_posto_combustivel_a REFERENCES dominios.administracao (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.tra_posto_combustivel_a - ADD CONSTRAINT tra_posto_combustivel_a_administracao_check - CHECK (administracao = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 6 :: SMALLINT, 7 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT tra_posto_combustivel_a_administracao_check + CHECK (administracao = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 6 :: SMALLINT, 7 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.tra_posto_combustivel_a ALTER COLUMN administracao SET DEFAULT 999# ALTER TABLE cb.tra_posto_combustivel_a ADD CONSTRAINT tra_posto_combustivel_a_geometriaaproximada_fk FOREIGN KEY (geometriaaproximada) @@ -11646,8 +11646,8 @@ ALTER TABLE cb.tra_posto_combustivel_a REFERENCES dominios.matconstr (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.tra_posto_combustivel_a - ADD CONSTRAINT tra_posto_combustivel_a_matconstr_check - CHECK (matconstr = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 99 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT tra_posto_combustivel_a_matconstr_check + CHECK (matconstr = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 99 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.tra_posto_combustivel_a ALTER COLUMN matconstr SET DEFAULT 999# ALTER TABLE cb.tra_posto_combustivel_a ADD CONSTRAINT tra_posto_combustivel_a_operacional_fk FOREIGN KEY (operacional) @@ -11659,8 +11659,8 @@ ALTER TABLE cb.tra_posto_combustivel_a REFERENCES dominios.situacaofisica (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.tra_posto_combustivel_a - ADD CONSTRAINT tra_posto_combustivel_a_situacaofisica_check - CHECK (situacaofisica = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT tra_posto_combustivel_a_situacaofisica_check + CHECK (situacaofisica = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.tra_posto_combustivel_a ALTER COLUMN situacaofisica SET DEFAULT 999# CREATE TABLE cb.tra_posto_combustivel_p( id serial NOT NULL, @@ -11681,8 +11681,8 @@ ALTER TABLE cb.tra_posto_combustivel_p REFERENCES dominios.administracao (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.tra_posto_combustivel_p - ADD CONSTRAINT tra_posto_combustivel_p_administracao_check - CHECK (administracao = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 6 :: SMALLINT, 7 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT tra_posto_combustivel_p_administracao_check + CHECK (administracao = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 6 :: SMALLINT, 7 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.tra_posto_combustivel_p ALTER COLUMN administracao SET DEFAULT 999# ALTER TABLE cb.tra_posto_combustivel_p ADD CONSTRAINT tra_posto_combustivel_p_geometriaaproximada_fk FOREIGN KEY (geometriaaproximada) @@ -11694,8 +11694,8 @@ ALTER TABLE cb.tra_posto_combustivel_p REFERENCES dominios.matconstr (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.tra_posto_combustivel_p - ADD CONSTRAINT tra_posto_combustivel_p_matconstr_check - CHECK (matconstr = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 99 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT tra_posto_combustivel_p_matconstr_check + CHECK (matconstr = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 99 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.tra_posto_combustivel_p ALTER COLUMN matconstr SET DEFAULT 999# ALTER TABLE cb.tra_posto_combustivel_p ADD CONSTRAINT tra_posto_combustivel_p_operacional_fk FOREIGN KEY (operacional) @@ -11707,8 +11707,8 @@ ALTER TABLE cb.tra_posto_combustivel_p REFERENCES dominios.situacaofisica (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.tra_posto_combustivel_p - ADD CONSTRAINT tra_posto_combustivel_p_situacaofisica_check - CHECK (situacaofisica = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT tra_posto_combustivel_p_situacaofisica_check + CHECK (situacaofisica = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.tra_posto_combustivel_p ALTER COLUMN situacaofisica SET DEFAULT 999# CREATE TABLE cb.tra_sinalizacao_p( id serial NOT NULL, @@ -11811,8 +11811,8 @@ ALTER TABLE cb.tra_travessia_pedestre_l REFERENCES dominios.matconstr (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.tra_travessia_pedestre_l - ADD CONSTRAINT tra_travessia_pedestre_l_matconstr_check - CHECK (matconstr = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 99 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT tra_travessia_pedestre_l_matconstr_check + CHECK (matconstr = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 99 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.tra_travessia_pedestre_l ALTER COLUMN matconstr SET DEFAULT 999# ALTER TABLE cb.tra_travessia_pedestre_l ADD CONSTRAINT tra_travessia_pedestre_l_operacional_fk FOREIGN KEY (operacional) @@ -11824,8 +11824,8 @@ ALTER TABLE cb.tra_travessia_pedestre_l REFERENCES dominios.situacaofisica (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.tra_travessia_pedestre_l - ADD CONSTRAINT tra_travessia_pedestre_l_situacaofisica_check - CHECK (situacaofisica = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT tra_travessia_pedestre_l_situacaofisica_check + CHECK (situacaofisica = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.tra_travessia_pedestre_l ALTER COLUMN situacaofisica SET DEFAULT 999# ALTER TABLE cb.tra_travessia_pedestre_l ADD CONSTRAINT tra_travessia_pedestre_l_tipotravessiaped_fk FOREIGN KEY (tipotravessiaped) @@ -11858,8 +11858,8 @@ ALTER TABLE cb.tra_travessia_pedestre_p REFERENCES dominios.matconstr (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.tra_travessia_pedestre_p - ADD CONSTRAINT tra_travessia_pedestre_p_matconstr_check - CHECK (matconstr = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 99 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT tra_travessia_pedestre_p_matconstr_check + CHECK (matconstr = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 99 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.tra_travessia_pedestre_p ALTER COLUMN matconstr SET DEFAULT 999# ALTER TABLE cb.tra_travessia_pedestre_p ADD CONSTRAINT tra_travessia_pedestre_p_operacional_fk FOREIGN KEY (operacional) @@ -11871,8 +11871,8 @@ ALTER TABLE cb.tra_travessia_pedestre_p REFERENCES dominios.situacaofisica (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.tra_travessia_pedestre_p - ADD CONSTRAINT tra_travessia_pedestre_p_situacaofisica_check - CHECK (situacaofisica = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT tra_travessia_pedestre_p_situacaofisica_check + CHECK (situacaofisica = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.tra_travessia_pedestre_p ALTER COLUMN situacaofisica SET DEFAULT 999# ALTER TABLE cb.tra_travessia_pedestre_p ADD CONSTRAINT tra_travessia_pedestre_p_tipotravessiaped_fk FOREIGN KEY (tipotravessiaped) @@ -11908,8 +11908,8 @@ ALTER TABLE cb.tra_trecho_duto_l REFERENCES dominios.matconstr (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.tra_trecho_duto_l - ADD CONSTRAINT tra_trecho_duto_l_matconstr_check - CHECK (matconstr = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 4 :: SMALLINT, 99 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT tra_trecho_duto_l_matconstr_check + CHECK (matconstr = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 4 :: SMALLINT, 99 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.tra_trecho_duto_l ALTER COLUMN matconstr SET DEFAULT 999# ALTER TABLE cb.tra_trecho_duto_l ADD CONSTRAINT tra_trecho_duto_l_mattransp_fk FOREIGN KEY (mattransp) @@ -11941,8 +11941,8 @@ ALTER TABLE cb.tra_trecho_duto_l REFERENCES dominios.situacaofisica (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.tra_trecho_duto_l - ADD CONSTRAINT tra_trecho_duto_l_situacaofisica_check - CHECK (situacaofisica = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT tra_trecho_duto_l_situacaofisica_check + CHECK (situacaofisica = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.tra_trecho_duto_l ALTER COLUMN situacaofisica SET DEFAULT 999# ALTER TABLE cb.tra_trecho_duto_l ADD CONSTRAINT tra_trecho_duto_l_tipotrechoduto_fk FOREIGN KEY (tipotrechoduto) @@ -11977,8 +11977,8 @@ ALTER TABLE cb.tra_trecho_ferroviario_l REFERENCES dominios.administracao (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.tra_trecho_ferroviario_l - ADD CONSTRAINT tra_trecho_ferroviario_l_administracao_check - CHECK (administracao = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 6 :: SMALLINT, 7 :: SMALLINT, 97 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT tra_trecho_ferroviario_l_administracao_check + CHECK (administracao = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 6 :: SMALLINT, 7 :: SMALLINT, 97 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.tra_trecho_ferroviario_l ALTER COLUMN administracao SET DEFAULT 999# ALTER TABLE cb.tra_trecho_ferroviario_l ADD CONSTRAINT tra_trecho_ferroviario_l_bitola_fk FOREIGN KEY (bitola) @@ -12005,8 +12005,8 @@ ALTER TABLE cb.tra_trecho_ferroviario_l REFERENCES dominios.jurisdicao (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.tra_trecho_ferroviario_l - ADD CONSTRAINT tra_trecho_ferroviario_l_jurisdicao_check - CHECK (jurisdicao = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 6 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT tra_trecho_ferroviario_l_jurisdicao_check + CHECK (jurisdicao = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 6 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.tra_trecho_ferroviario_l ALTER COLUMN jurisdicao SET DEFAULT 999# ALTER TABLE cb.tra_trecho_ferroviario_l ADD CONSTRAINT tra_trecho_ferroviario_l_nrlinhas_fk FOREIGN KEY (nrlinhas) @@ -12023,8 +12023,8 @@ ALTER TABLE cb.tra_trecho_ferroviario_l REFERENCES dominios.posicaorelativa (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.tra_trecho_ferroviario_l - ADD CONSTRAINT tra_trecho_ferroviario_l_posicaorelativa_check - CHECK (posicaorelativa = ANY(ARRAY[0 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 6 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT tra_trecho_ferroviario_l_posicaorelativa_check + CHECK (posicaorelativa = ANY(ARRAY[0 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 6 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.tra_trecho_ferroviario_l ALTER COLUMN posicaorelativa SET DEFAULT 999# ALTER TABLE cb.tra_trecho_ferroviario_l ADD CONSTRAINT tra_trecho_ferroviario_l_situacaofisica_fk FOREIGN KEY (situacaofisica) @@ -12066,8 +12066,8 @@ ALTER TABLE cb.tra_trecho_hidroviario_l REFERENCES dominios.regime (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.tra_trecho_hidroviario_l - ADD CONSTRAINT tra_trecho_hidroviario_l_regime_check - CHECK (regime = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 6 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT tra_trecho_hidroviario_l_regime_check + CHECK (regime = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 6 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.tra_trecho_hidroviario_l ALTER COLUMN regime SET DEFAULT 999# ALTER TABLE cb.tra_trecho_hidroviario_l ADD CONSTRAINT tra_trecho_hidroviario_l_situacaofisica_fk FOREIGN KEY (situacaofisica) @@ -12100,8 +12100,8 @@ ALTER TABLE cb.tra_trecho_rodoviario_l REFERENCES dominios.administracao (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.tra_trecho_rodoviario_l - ADD CONSTRAINT tra_trecho_rodoviario_l_administracao_check - CHECK (administracao = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 6 :: SMALLINT, 7 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT tra_trecho_rodoviario_l_administracao_check + CHECK (administracao = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 6 :: SMALLINT, 7 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.tra_trecho_rodoviario_l ALTER COLUMN administracao SET DEFAULT 999# ALTER TABLE cb.tra_trecho_rodoviario_l ADD CONSTRAINT tra_trecho_rodoviario_l_canteirodivisorio_fk FOREIGN KEY (canteirodivisorio) @@ -12118,8 +12118,8 @@ ALTER TABLE cb.tra_trecho_rodoviario_l REFERENCES dominios.jurisdicao (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.tra_trecho_rodoviario_l - ADD CONSTRAINT tra_trecho_rodoviario_l_jurisdicao_check - CHECK (jurisdicao = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 8 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT tra_trecho_rodoviario_l_jurisdicao_check + CHECK (jurisdicao = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 8 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.tra_trecho_rodoviario_l ALTER COLUMN jurisdicao SET DEFAULT 999# ALTER TABLE cb.tra_trecho_rodoviario_l ADD CONSTRAINT tra_trecho_rodoviario_l_operacional_fk FOREIGN KEY (operacional) @@ -12192,16 +12192,16 @@ ALTER TABLE cb.tra_tunel_l REFERENCES dominios.matconstr (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.tra_tunel_l - ADD CONSTRAINT tra_tunel_l_matconstr_check - CHECK (matconstr = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 99 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT tra_tunel_l_matconstr_check + CHECK (matconstr = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 99 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.tra_tunel_l ALTER COLUMN matconstr SET DEFAULT 999# ALTER TABLE cb.tra_tunel_l ADD CONSTRAINT tra_tunel_l_modaluso_fk FOREIGN KEY (modaluso) REFERENCES dominios.modaluso (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.tra_tunel_l - ADD CONSTRAINT tra_tunel_l_modaluso_check - CHECK (modaluso = ANY(ARRAY[4 :: SMALLINT, 5 :: SMALLINT, 6 :: SMALLINT, 7 :: SMALLINT, 8 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT tra_tunel_l_modaluso_check + CHECK (modaluso = ANY(ARRAY[4 :: SMALLINT, 5 :: SMALLINT, 6 :: SMALLINT, 7 :: SMALLINT, 8 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.tra_tunel_l ALTER COLUMN modaluso SET DEFAULT 999# ALTER TABLE cb.tra_tunel_l ADD CONSTRAINT tra_tunel_l_operacional_fk FOREIGN KEY (operacional) @@ -12254,16 +12254,16 @@ ALTER TABLE cb.tra_tunel_p REFERENCES dominios.matconstr (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.tra_tunel_p - ADD CONSTRAINT tra_tunel_p_matconstr_check - CHECK (matconstr = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 99 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT tra_tunel_p_matconstr_check + CHECK (matconstr = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 99 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.tra_tunel_p ALTER COLUMN matconstr SET DEFAULT 999# ALTER TABLE cb.tra_tunel_p ADD CONSTRAINT tra_tunel_p_modaluso_fk FOREIGN KEY (modaluso) REFERENCES dominios.modaluso (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.tra_tunel_p - ADD CONSTRAINT tra_tunel_p_modaluso_check - CHECK (modaluso = ANY(ARRAY[4 :: SMALLINT, 5 :: SMALLINT, 6 :: SMALLINT, 7 :: SMALLINT, 8 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT tra_tunel_p_modaluso_check + CHECK (modaluso = ANY(ARRAY[4 :: SMALLINT, 5 :: SMALLINT, 6 :: SMALLINT, 7 :: SMALLINT, 8 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.tra_tunel_p ALTER COLUMN modaluso SET DEFAULT 999# ALTER TABLE cb.tra_tunel_p ADD CONSTRAINT tra_tunel_p_operacional_fk FOREIGN KEY (operacional) @@ -12310,8 +12310,8 @@ ALTER TABLE cb.veg_brejo_pantano_a REFERENCES dominios.classificacaoporte (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.veg_brejo_pantano_a - ADD CONSTRAINT veg_brejo_pantano_a_classificacaoporte_check - CHECK (classificacaoporte = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 98 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT veg_brejo_pantano_a_classificacaoporte_check + CHECK (classificacaoporte = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 98 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.veg_brejo_pantano_a ALTER COLUMN classificacaoporte SET DEFAULT 999# ALTER TABLE cb.veg_brejo_pantano_a ADD CONSTRAINT veg_brejo_pantano_a_denso_fk FOREIGN KEY (denso) @@ -12352,8 +12352,8 @@ ALTER TABLE cb.veg_caatinga_a REFERENCES dominios.classificacaoporte (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.veg_caatinga_a - ADD CONSTRAINT veg_caatinga_a_classificacaoporte_check - CHECK (classificacaoporte = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 98 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT veg_caatinga_a_classificacaoporte_check + CHECK (classificacaoporte = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 98 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.veg_caatinga_a ALTER COLUMN classificacaoporte SET DEFAULT 999# ALTER TABLE cb.veg_caatinga_a ADD CONSTRAINT veg_caatinga_a_denso_fk FOREIGN KEY (denso) @@ -12389,8 +12389,8 @@ ALTER TABLE cb.veg_campinarana_a REFERENCES dominios.classificacaoporte (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.veg_campinarana_a - ADD CONSTRAINT veg_campinarana_a_classificacaoporte_check - CHECK (classificacaoporte = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 98 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT veg_campinarana_a_classificacaoporte_check + CHECK (classificacaoporte = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 98 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.veg_campinarana_a ALTER COLUMN classificacaoporte SET DEFAULT 999# ALTER TABLE cb.veg_campinarana_a ADD CONSTRAINT veg_campinarana_a_denso_fk FOREIGN KEY (denso) @@ -12454,8 +12454,8 @@ ALTER TABLE cb.veg_cerrado_cerradao_a REFERENCES dominios.classificacaoporte (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.veg_cerrado_cerradao_a - ADD CONSTRAINT veg_cerrado_cerradao_a_classificacaoporte_check - CHECK (classificacaoporte = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 98 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT veg_cerrado_cerradao_a_classificacaoporte_check + CHECK (classificacaoporte = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 98 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.veg_cerrado_cerradao_a ALTER COLUMN classificacaoporte SET DEFAULT 999# ALTER TABLE cb.veg_cerrado_cerradao_a ADD CONSTRAINT veg_cerrado_cerradao_a_denso_fk FOREIGN KEY (denso) @@ -12570,8 +12570,8 @@ ALTER TABLE cb.veg_floresta_a REFERENCES dominios.classificacaoporte (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.veg_floresta_a - ADD CONSTRAINT veg_floresta_a_classificacaoporte_check - CHECK (classificacaoporte = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 98 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT veg_floresta_a_classificacaoporte_check + CHECK (classificacaoporte = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 98 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.veg_floresta_a ALTER COLUMN classificacaoporte SET DEFAULT 999# ALTER TABLE cb.veg_floresta_a ADD CONSTRAINT veg_floresta_a_denso_fk FOREIGN KEY (denso) @@ -12613,8 +12613,8 @@ ALTER TABLE cb.veg_macega_chavascal_a REFERENCES dominios.classificacaoporte (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.veg_macega_chavascal_a - ADD CONSTRAINT veg_macega_chavascal_a_classificacaoporte_check - CHECK (classificacaoporte = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 98 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT veg_macega_chavascal_a_classificacaoporte_check + CHECK (classificacaoporte = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 98 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.veg_macega_chavascal_a ALTER COLUMN classificacaoporte SET DEFAULT 999# ALTER TABLE cb.veg_macega_chavascal_a ADD CONSTRAINT veg_macega_chavascal_a_denso_fk FOREIGN KEY (denso) @@ -12655,8 +12655,8 @@ ALTER TABLE cb.veg_mangue_a REFERENCES dominios.classificacaoporte (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.veg_mangue_a - ADD CONSTRAINT veg_mangue_a_classificacaoporte_check - CHECK (classificacaoporte = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 98 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT veg_mangue_a_classificacaoporte_check + CHECK (classificacaoporte = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 98 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.veg_mangue_a ALTER COLUMN classificacaoporte SET DEFAULT 999# ALTER TABLE cb.veg_mangue_a ADD CONSTRAINT veg_mangue_a_denso_fk FOREIGN KEY (denso) @@ -12692,8 +12692,8 @@ ALTER TABLE cb.veg_veg_area_contato_a REFERENCES dominios.classificacaoporte (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.veg_veg_area_contato_a - ADD CONSTRAINT veg_veg_area_contato_a_classificacaoporte_check - CHECK (classificacaoporte = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 98 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT veg_veg_area_contato_a_classificacaoporte_check + CHECK (classificacaoporte = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 98 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.veg_veg_area_contato_a ALTER COLUMN classificacaoporte SET DEFAULT 999# ALTER TABLE cb.veg_veg_area_contato_a ADD CONSTRAINT veg_veg_area_contato_a_denso_fk FOREIGN KEY (denso) @@ -12783,8 +12783,8 @@ ALTER TABLE cb.veg_veg_restinga_a REFERENCES dominios.classificacaoporte (code) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE cb.veg_veg_restinga_a - ADD CONSTRAINT veg_veg_restinga_a_classificacaoporte_check - CHECK (classificacaoporte = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 98 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT veg_veg_restinga_a_classificacaoporte_check + CHECK (classificacaoporte = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 98 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE cb.veg_veg_restinga_a ALTER COLUMN classificacaoporte SET DEFAULT 999# ALTER TABLE cb.veg_veg_restinga_a ADD CONSTRAINT veg_veg_restinga_a_denso_fk FOREIGN KEY (denso) @@ -12833,4 +12833,4 @@ CREATE TABLE cb.aux_moldura_a( CONSTRAINT aux_moldura_a_pk PRIMARY KEY (id) WITH (FILLFACTOR = 80) )# -CREATE INDEX aux_moldura_a_geom ON cb.aux_moldura_a USING gist (geom)# \ No newline at end of file +CREATE INDEX aux_moldura_a_geom ON cb.aux_moldura_a USING gist (geom)# diff --git a/DsgTools/core/DbModels/PostGIS/213/triggers.sql b/DsgTools/core/DbModels/PostGIS/213/triggers.sql index eaede9eec..303054c78 100644 --- a/DsgTools/core/DbModels/PostGIS/213/triggers.sql +++ b/DsgTools/core/DbModels/PostGIS/213/triggers.sql @@ -13,14 +13,14 @@ $BODY$ querytext1 := 'INSERT INTO ' || quote_ident(TG_TABLE_SCHEMA) || '.' || quote_ident(TG_TABLE_NAME) || '('; querytext2 := 'geom) SELECT '; - FOR r IN SELECT (each(hstore(NEW))).* + FOR r IN SELECT (each(hstore(NEW))).* LOOP IF r.key <> 'geom' AND r.key <> 'id' THEN querytext1 := querytext1 || quote_ident(r.key) || ','; IF r.value <> '' THEN querytext2 := querytext2 || quote_literal(r.value) || ','; ELSE - querytext2 := querytext2 || 'NULL' || ','; + querytext2 := querytext2 || 'NULL' || ','; END IF; END IF; END LOOP; @@ -141,4 +141,4 @@ GRANT ALL ON ALL SEQUENCES IN SCHEMA edgv TO public# GRANT USAGE ON SCHEMA dominios TO public# GRANT SELECT, INSERT, UPDATE, DELETE ON ALL TABLES IN SCHEMA dominios TO public# -GRANT ALL ON ALL SEQUENCES IN SCHEMA dominios TO public# \ No newline at end of file +GRANT ALL ON ALL SEQUENCES IN SCHEMA dominios TO public# diff --git a/DsgTools/core/DbModels/PostGIS/213/views_213.sql b/DsgTools/core/DbModels/PostGIS/213/views_213.sql index dde3bfb38..f7ef30288 100644 --- a/DsgTools/core/DbModels/PostGIS/213/views_213.sql +++ b/DsgTools/core/DbModels/PostGIS/213/views_213.sql @@ -1,19 +1,19 @@ DROP SCHEMA IF EXISTS views CASCADE# CREATE SCHEMA views# DROP VIEW IF EXISTS views.edu_descontinuidade_geometrica_l# -CREATE [VIEW] views.edu_descontinuidade_geometrica_l as +CREATE [VIEW] views.edu_descontinuidade_geometrica_l as SELECT id as id, dominio_geometriaaproximada.code_name as geometriaaproximada, dominio_motivodescontinuidade.code_name as motivodescontinuidade, geom as geom [FROM] - cb.edu_descontinuidade_geometrica_l - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = edu_descontinuidade_geometrica_l.geometriaaproximada + cb.edu_descontinuidade_geometrica_l + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = edu_descontinuidade_geometrica_l.geometriaaproximada left join dominios.motivodescontinuidade as dominio_motivodescontinuidade on dominio_motivodescontinuidade.code = edu_descontinuidade_geometrica_l.motivodescontinuidade # DROP VIEW IF EXISTS views.pto_pto_geod_topo_controle_p# -CREATE [VIEW] views.pto_pto_geod_topo_controle_p as +CREATE [VIEW] views.pto_pto_geod_topo_controle_p as SELECT id as id, nomeabrev as nomeabrev, @@ -31,14 +31,14 @@ CREATE [VIEW] views.pto_pto_geod_topo_controle_p as obs as obs, geom as geom [FROM] - cb.pto_pto_geod_topo_controle_p - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = pto_pto_geod_topo_controle_p.geometriaaproximada - left join dominios.tiporef as dominio_tiporef on dominio_tiporef.code = pto_pto_geod_topo_controle_p.tiporef - left join dominios.sistemageodesico as dominio_sistemageodesico on dominio_sistemageodesico.code = pto_pto_geod_topo_controle_p.sistemageodesico + cb.pto_pto_geod_topo_controle_p + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = pto_pto_geod_topo_controle_p.geometriaaproximada + left join dominios.tiporef as dominio_tiporef on dominio_tiporef.code = pto_pto_geod_topo_controle_p.tiporef + left join dominios.sistemageodesico as dominio_sistemageodesico on dominio_sistemageodesico.code = pto_pto_geod_topo_controle_p.sistemageodesico left join dominios.referencialaltim as dominio_referencialaltim on dominio_referencialaltim.code = pto_pto_geod_topo_controle_p.referencialaltim # DROP VIEW IF EXISTS views.edu_edif_religiosa_a# -CREATE [VIEW] views.edu_edif_religiosa_a as +CREATE [VIEW] views.edu_edif_religiosa_a as SELECT id as id, nome as nome, @@ -53,16 +53,16 @@ CREATE [VIEW] views.edu_edif_religiosa_a as religiao as religiao, id_org_religiosa as id_org_religiosa [FROM] - cb.edu_edif_religiosa_a - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = edu_edif_religiosa_a.geometriaaproximada - left join dominios.operacional as dominio_operacional on dominio_operacional.code = edu_edif_religiosa_a.operacional - left join dominios.situacaofisica as dominio_situacaofisica on dominio_situacaofisica.code = edu_edif_religiosa_a.situacaofisica - left join dominios.matconstr as dominio_matconstr on dominio_matconstr.code = edu_edif_religiosa_a.matconstr - left join dominios.tipoedifrelig as dominio_tipoedifrelig on dominio_tipoedifrelig.code = edu_edif_religiosa_a.tipoedifrelig + cb.edu_edif_religiosa_a + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = edu_edif_religiosa_a.geometriaaproximada + left join dominios.operacional as dominio_operacional on dominio_operacional.code = edu_edif_religiosa_a.operacional + left join dominios.situacaofisica as dominio_situacaofisica on dominio_situacaofisica.code = edu_edif_religiosa_a.situacaofisica + left join dominios.matconstr as dominio_matconstr on dominio_matconstr.code = edu_edif_religiosa_a.matconstr + left join dominios.tipoedifrelig as dominio_tipoedifrelig on dominio_tipoedifrelig.code = edu_edif_religiosa_a.tipoedifrelig left join dominios.ensino as dominio_ensino on dominio_ensino.code = edu_edif_religiosa_a.ensino # DROP VIEW IF EXISTS views.lim_terra_publica_p# -CREATE [VIEW] views.lim_terra_publica_p as +CREATE [VIEW] views.lim_terra_publica_p as SELECT id as id, nome as nome, @@ -71,22 +71,22 @@ CREATE [VIEW] views.lim_terra_publica_p as geom as geom, classificacao as classificacao [FROM] - cb.lim_terra_publica_p + cb.lim_terra_publica_p left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = lim_terra_publica_p.geometriaaproximada # DROP VIEW IF EXISTS views.asb_area_saneamento_a# -CREATE [VIEW] views.asb_area_saneamento_a as +CREATE [VIEW] views.asb_area_saneamento_a as SELECT id as id, dominio_geometriaaproximada.code_name as geometriaaproximada, id_complexo_saneamento as id_complexo_saneamento, geom as geom [FROM] - cb.asb_area_saneamento_a + cb.asb_area_saneamento_a left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = asb_area_saneamento_a.geometriaaproximada # DROP VIEW IF EXISTS views.eco_edif_comerc_serv_p# -CREATE [VIEW] views.eco_edif_comerc_serv_p as +CREATE [VIEW] views.eco_edif_comerc_serv_p as SELECT id as id, nome as nome, @@ -100,16 +100,16 @@ CREATE [VIEW] views.eco_edif_comerc_serv_p as dominio_finalidade.code_name as finalidade, id_org_comerc_serv as id_org_comerc_serv [FROM] - cb.eco_edif_comerc_serv_p - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = eco_edif_comerc_serv_p.geometriaaproximada - left join dominios.operacional as dominio_operacional on dominio_operacional.code = eco_edif_comerc_serv_p.operacional - left join dominios.situacaofisica as dominio_situacaofisica on dominio_situacaofisica.code = eco_edif_comerc_serv_p.situacaofisica - left join dominios.matconstr as dominio_matconstr on dominio_matconstr.code = eco_edif_comerc_serv_p.matconstr - left join dominios.tipoedifcomercserv as dominio_tipoedifcomercserv on dominio_tipoedifcomercserv.code = eco_edif_comerc_serv_p.tipoedifcomercserv + cb.eco_edif_comerc_serv_p + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = eco_edif_comerc_serv_p.geometriaaproximada + left join dominios.operacional as dominio_operacional on dominio_operacional.code = eco_edif_comerc_serv_p.operacional + left join dominios.situacaofisica as dominio_situacaofisica on dominio_situacaofisica.code = eco_edif_comerc_serv_p.situacaofisica + left join dominios.matconstr as dominio_matconstr on dominio_matconstr.code = eco_edif_comerc_serv_p.matconstr + left join dominios.tipoedifcomercserv as dominio_tipoedifcomercserv on dominio_tipoedifcomercserv.code = eco_edif_comerc_serv_p.tipoedifcomercserv left join dominios.finalidade_eco as dominio_finalidade on dominio_finalidade.code = eco_edif_comerc_serv_p.finalidade # DROP VIEW IF EXISTS views.pto_edif_constr_est_med_fen_a# -CREATE [VIEW] views.pto_edif_constr_est_med_fen_a as +CREATE [VIEW] views.pto_edif_constr_est_med_fen_a as SELECT id as id, nome as nome, @@ -120,14 +120,14 @@ CREATE [VIEW] views.pto_edif_constr_est_med_fen_a as dominio_matconstr.code_name as matconstr, geom as geom [FROM] - cb.pto_edif_constr_est_med_fen_a - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = pto_edif_constr_est_med_fen_a.geometriaaproximada - left join dominios.operacional as dominio_operacional on dominio_operacional.code = pto_edif_constr_est_med_fen_a.operacional - left join dominios.situacaofisica as dominio_situacaofisica on dominio_situacaofisica.code = pto_edif_constr_est_med_fen_a.situacaofisica + cb.pto_edif_constr_est_med_fen_a + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = pto_edif_constr_est_med_fen_a.geometriaaproximada + left join dominios.operacional as dominio_operacional on dominio_operacional.code = pto_edif_constr_est_med_fen_a.operacional + left join dominios.situacaofisica as dominio_situacaofisica on dominio_situacaofisica.code = pto_edif_constr_est_med_fen_a.situacaofisica left join dominios.matconstr as dominio_matconstr on dominio_matconstr.code = pto_edif_constr_est_med_fen_a.matconstr # DROP VIEW IF EXISTS views.tra_trecho_duto_l# -CREATE [VIEW] views.tra_trecho_duto_l as +CREATE [VIEW] views.tra_trecho_duto_l as SELECT id as id, nome as nome, @@ -145,42 +145,42 @@ CREATE [VIEW] views.tra_trecho_duto_l as id_duto as id_duto, geom as geom [FROM] - cb.tra_trecho_duto_l - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = tra_trecho_duto_l.geometriaaproximada - left join dominios.tipotrechoduto as dominio_tipotrechoduto on dominio_tipotrechoduto.code = tra_trecho_duto_l.tipotrechoduto - left join dominios.mattransp as dominio_mattransp on dominio_mattransp.code = tra_trecho_duto_l.mattransp - left join dominios.setor as dominio_setor on dominio_setor.code = tra_trecho_duto_l.setor - left join dominios.posicaorelativa as dominio_posicaorelativa on dominio_posicaorelativa.code = tra_trecho_duto_l.posicaorelativa - left join dominios.matconstr as dominio_matconstr on dominio_matconstr.code = tra_trecho_duto_l.matconstr - left join dominios.situacaoespacial as dominio_situacaoespacial on dominio_situacaoespacial.code = tra_trecho_duto_l.situacaoespacial - left join dominios.operacional as dominio_operacional on dominio_operacional.code = tra_trecho_duto_l.operacional + cb.tra_trecho_duto_l + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = tra_trecho_duto_l.geometriaaproximada + left join dominios.tipotrechoduto as dominio_tipotrechoduto on dominio_tipotrechoduto.code = tra_trecho_duto_l.tipotrechoduto + left join dominios.mattransp as dominio_mattransp on dominio_mattransp.code = tra_trecho_duto_l.mattransp + left join dominios.setor as dominio_setor on dominio_setor.code = tra_trecho_duto_l.setor + left join dominios.posicaorelativa as dominio_posicaorelativa on dominio_posicaorelativa.code = tra_trecho_duto_l.posicaorelativa + left join dominios.matconstr as dominio_matconstr on dominio_matconstr.code = tra_trecho_duto_l.matconstr + left join dominios.situacaoespacial as dominio_situacaoespacial on dominio_situacaoespacial.code = tra_trecho_duto_l.situacaoespacial + left join dominios.operacional as dominio_operacional on dominio_operacional.code = tra_trecho_duto_l.operacional left join dominios.situacaofisica as dominio_situacaofisica on dominio_situacaofisica.code = tra_trecho_duto_l.situacaofisica # DROP VIEW IF EXISTS views.edu_descontinuidade_geometrica_a# -CREATE [VIEW] views.edu_descontinuidade_geometrica_a as +CREATE [VIEW] views.edu_descontinuidade_geometrica_a as SELECT id as id, dominio_geometriaaproximada.code_name as geometriaaproximada, dominio_motivodescontinuidade.code_name as motivodescontinuidade, geom as geom [FROM] - cb.edu_descontinuidade_geometrica_a - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = edu_descontinuidade_geometrica_a.geometriaaproximada + cb.edu_descontinuidade_geometrica_a + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = edu_descontinuidade_geometrica_a.geometriaaproximada left join dominios.motivodescontinuidade as dominio_motivodescontinuidade on dominio_motivodescontinuidade.code = edu_descontinuidade_geometrica_a.motivodescontinuidade # DROP VIEW IF EXISTS views.adm_area_pub_civil_a# -CREATE [VIEW] views.adm_area_pub_civil_a as +CREATE [VIEW] views.adm_area_pub_civil_a as SELECT id as id, dominio_geometriaaproximada.code_name as geometriaaproximada, geom as geom, id_org_pub_civil as id_org_pub_civil [FROM] - cb.adm_area_pub_civil_a + cb.adm_area_pub_civil_a left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = adm_area_pub_civil_a.geometriaaproximada # DROP VIEW IF EXISTS views.rel_pico_p# -CREATE [VIEW] views.rel_pico_p as +CREATE [VIEW] views.rel_pico_p as SELECT id as id, nome as nome, @@ -189,12 +189,12 @@ CREATE [VIEW] views.rel_pico_p as dominio_tipoelemnat.code_name as tipoelemnat, geom as geom [FROM] - cb.rel_pico_p - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = rel_pico_p.geometriaaproximada + cb.rel_pico_p + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = rel_pico_p.geometriaaproximada left join dominios.tipoelemnat as dominio_tipoelemnat on dominio_tipoelemnat.code = rel_pico_p.tipoelemnat # DROP VIEW IF EXISTS views.lim_terra_publica_a# -CREATE [VIEW] views.lim_terra_publica_a as +CREATE [VIEW] views.lim_terra_publica_a as SELECT id as id, nome as nome, @@ -203,11 +203,11 @@ CREATE [VIEW] views.lim_terra_publica_a as geom as geom, classificacao as classificacao [FROM] - cb.lim_terra_publica_a + cb.lim_terra_publica_a left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = lim_terra_publica_a.geometriaaproximada # DROP VIEW IF EXISTS views.pto_edif_constr_est_med_fen_p# -CREATE [VIEW] views.pto_edif_constr_est_med_fen_p as +CREATE [VIEW] views.pto_edif_constr_est_med_fen_p as SELECT id as id, nome as nome, @@ -218,14 +218,14 @@ CREATE [VIEW] views.pto_edif_constr_est_med_fen_p as dominio_matconstr.code_name as matconstr, geom as geom [FROM] - cb.pto_edif_constr_est_med_fen_p - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = pto_edif_constr_est_med_fen_p.geometriaaproximada - left join dominios.operacional as dominio_operacional on dominio_operacional.code = pto_edif_constr_est_med_fen_p.operacional - left join dominios.situacaofisica as dominio_situacaofisica on dominio_situacaofisica.code = pto_edif_constr_est_med_fen_p.situacaofisica + cb.pto_edif_constr_est_med_fen_p + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = pto_edif_constr_est_med_fen_p.geometriaaproximada + left join dominios.operacional as dominio_operacional on dominio_operacional.code = pto_edif_constr_est_med_fen_p.operacional + left join dominios.situacaofisica as dominio_situacaofisica on dominio_situacaofisica.code = pto_edif_constr_est_med_fen_p.situacaofisica left join dominios.matconstr as dominio_matconstr on dominio_matconstr.code = pto_edif_constr_est_med_fen_p.matconstr # DROP VIEW IF EXISTS views.eco_edif_comerc_serv_a# -CREATE [VIEW] views.eco_edif_comerc_serv_a as +CREATE [VIEW] views.eco_edif_comerc_serv_a as SELECT id as id, nome as nome, @@ -239,28 +239,28 @@ CREATE [VIEW] views.eco_edif_comerc_serv_a as dominio_finalidade.code_name as finalidade, id_org_comerc_serv as id_org_comerc_serv [FROM] - cb.eco_edif_comerc_serv_a - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = eco_edif_comerc_serv_a.geometriaaproximada - left join dominios.operacional as dominio_operacional on dominio_operacional.code = eco_edif_comerc_serv_a.operacional - left join dominios.situacaofisica as dominio_situacaofisica on dominio_situacaofisica.code = eco_edif_comerc_serv_a.situacaofisica - left join dominios.matconstr as dominio_matconstr on dominio_matconstr.code = eco_edif_comerc_serv_a.matconstr - left join dominios.tipoedifcomercserv as dominio_tipoedifcomercserv on dominio_tipoedifcomercserv.code = eco_edif_comerc_serv_a.tipoedifcomercserv + cb.eco_edif_comerc_serv_a + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = eco_edif_comerc_serv_a.geometriaaproximada + left join dominios.operacional as dominio_operacional on dominio_operacional.code = eco_edif_comerc_serv_a.operacional + left join dominios.situacaofisica as dominio_situacaofisica on dominio_situacaofisica.code = eco_edif_comerc_serv_a.situacaofisica + left join dominios.matconstr as dominio_matconstr on dominio_matconstr.code = eco_edif_comerc_serv_a.matconstr + left join dominios.tipoedifcomercserv as dominio_tipoedifcomercserv on dominio_tipoedifcomercserv.code = eco_edif_comerc_serv_a.tipoedifcomercserv left join dominios.finalidade_eco as dominio_finalidade on dominio_finalidade.code = eco_edif_comerc_serv_a.finalidade # DROP VIEW IF EXISTS views.edu_descontinuidade_geometrica_p# -CREATE [VIEW] views.edu_descontinuidade_geometrica_p as +CREATE [VIEW] views.edu_descontinuidade_geometrica_p as SELECT id as id, dominio_geometriaaproximada.code_name as geometriaaproximada, dominio_motivodescontinuidade.code_name as motivodescontinuidade, geom as geom [FROM] - cb.edu_descontinuidade_geometrica_p - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = edu_descontinuidade_geometrica_p.geometriaaproximada + cb.edu_descontinuidade_geometrica_p + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = edu_descontinuidade_geometrica_p.geometriaaproximada left join dominios.motivodescontinuidade as dominio_motivodescontinuidade on dominio_motivodescontinuidade.code = edu_descontinuidade_geometrica_p.motivodescontinuidade # DROP VIEW IF EXISTS views.eco_edif_ext_mineral_p# -CREATE [VIEW] views.eco_edif_ext_mineral_p as +CREATE [VIEW] views.eco_edif_ext_mineral_p as SELECT id as id, nome as nome, @@ -273,15 +273,15 @@ CREATE [VIEW] views.eco_edif_ext_mineral_p as dominio_tipodivisaocnae.code_name as tipodivisaocnae, id_org_ext_mineral as id_org_ext_mineral [FROM] - cb.eco_edif_ext_mineral_p - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = eco_edif_ext_mineral_p.geometriaaproximada - left join dominios.operacional as dominio_operacional on dominio_operacional.code = eco_edif_ext_mineral_p.operacional - left join dominios.situacaofisica as dominio_situacaofisica on dominio_situacaofisica.code = eco_edif_ext_mineral_p.situacaofisica - left join dominios.matconstr as dominio_matconstr on dominio_matconstr.code = eco_edif_ext_mineral_p.matconstr + cb.eco_edif_ext_mineral_p + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = eco_edif_ext_mineral_p.geometriaaproximada + left join dominios.operacional as dominio_operacional on dominio_operacional.code = eco_edif_ext_mineral_p.operacional + left join dominios.situacaofisica as dominio_situacaofisica on dominio_situacaofisica.code = eco_edif_ext_mineral_p.situacaofisica + left join dominios.matconstr as dominio_matconstr on dominio_matconstr.code = eco_edif_ext_mineral_p.matconstr left join dominios.tipodivisaocnae as dominio_tipodivisaocnae on dominio_tipodivisaocnae.code = eco_edif_ext_mineral_p.tipodivisaocnae # DROP VIEW IF EXISTS views.loc_area_edificada_a# -CREATE [VIEW] views.loc_area_edificada_a as +CREATE [VIEW] views.loc_area_edificada_a as SELECT id as id, nome as nome, @@ -289,11 +289,11 @@ CREATE [VIEW] views.loc_area_edificada_a as dominio_geometriaaproximada.code_name as geometriaaproximada, geom as geom [FROM] - cb.loc_area_edificada_a + cb.loc_area_edificada_a left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = loc_area_edificada_a.geometriaaproximada # DROP VIEW IF EXISTS views.tra_eclusa_l# -CREATE [VIEW] views.tra_eclusa_l as +CREATE [VIEW] views.tra_eclusa_l as SELECT id as id, nome as nome, @@ -308,25 +308,25 @@ CREATE [VIEW] views.tra_eclusa_l as dominio_situacaofisica.code_name as situacaofisica, geom as geom [FROM] - cb.tra_eclusa_l - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = tra_eclusa_l.geometriaaproximada - left join dominios.matconstr as dominio_matconstr on dominio_matconstr.code = tra_eclusa_l.matconstr - left join dominios.operacional as dominio_operacional on dominio_operacional.code = tra_eclusa_l.operacional + cb.tra_eclusa_l + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = tra_eclusa_l.geometriaaproximada + left join dominios.matconstr as dominio_matconstr on dominio_matconstr.code = tra_eclusa_l.matconstr + left join dominios.operacional as dominio_operacional on dominio_operacional.code = tra_eclusa_l.operacional left join dominios.situacaofisica as dominio_situacaofisica on dominio_situacaofisica.code = tra_eclusa_l.situacaofisica # DROP VIEW IF EXISTS views.adm_area_pub_militar_a# -CREATE [VIEW] views.adm_area_pub_militar_a as +CREATE [VIEW] views.adm_area_pub_militar_a as SELECT id as id, dominio_geometriaaproximada.code_name as geometriaaproximada, geom as geom, id_org_pub_militar as id_org_pub_militar [FROM] - cb.adm_area_pub_militar_a + cb.adm_area_pub_militar_a left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = adm_area_pub_militar_a.geometriaaproximada # DROP VIEW IF EXISTS views.hid_barragem_p# -CREATE [VIEW] views.hid_barragem_p as +CREATE [VIEW] views.hid_barragem_p as SELECT id as id, nome as nome, @@ -339,15 +339,15 @@ CREATE [VIEW] views.hid_barragem_p as id_complexo_gerad_energ_eletr as id_complexo_gerad_energ_eletr, geom as geom [FROM] - cb.hid_barragem_p - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = hid_barragem_p.geometriaaproximada - left join dominios.matconstr as dominio_matconstr on dominio_matconstr.code = hid_barragem_p.matconstr - left join dominios.usoprincipal as dominio_usoprincipal on dominio_usoprincipal.code = hid_barragem_p.usoprincipal - left join dominios.operacional as dominio_operacional on dominio_operacional.code = hid_barragem_p.operacional + cb.hid_barragem_p + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = hid_barragem_p.geometriaaproximada + left join dominios.matconstr as dominio_matconstr on dominio_matconstr.code = hid_barragem_p.matconstr + left join dominios.usoprincipal as dominio_usoprincipal on dominio_usoprincipal.code = hid_barragem_p.usoprincipal + left join dominios.operacional as dominio_operacional on dominio_operacional.code = hid_barragem_p.operacional left join dominios.situacaofisica as dominio_situacaofisica on dominio_situacaofisica.code = hid_barragem_p.situacaofisica # DROP VIEW IF EXISTS views.lim_bairro_a# -CREATE [VIEW] views.lim_bairro_a as +CREATE [VIEW] views.lim_bairro_a as SELECT id as id, nome as nome, @@ -356,11 +356,11 @@ CREATE [VIEW] views.lim_bairro_a as geom as geom, anodereferencia as anodereferencia [FROM] - cb.lim_bairro_a + cb.lim_bairro_a left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = lim_bairro_a.geometriaaproximada # DROP VIEW IF EXISTS views.asb_dep_saneamento_p# -CREATE [VIEW] views.asb_dep_saneamento_p as +CREATE [VIEW] views.asb_dep_saneamento_p as SELECT id as id, nome as nome, @@ -377,31 +377,31 @@ CREATE [VIEW] views.asb_dep_saneamento_p as id_complexo_saneamento as id_complexo_saneamento, geom as geom [FROM] - cb.asb_dep_saneamento_p - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = asb_dep_saneamento_p.geometriaaproximada - left join dominios.tipodepsaneam as dominio_tipodepsaneam on dominio_tipodepsaneam.code = asb_dep_saneamento_p.tipodepsaneam - left join dominios.construcao as dominio_construcao on dominio_construcao.code = asb_dep_saneamento_p.construcao - left join dominios.matconstr as dominio_matconstr on dominio_matconstr.code = asb_dep_saneamento_p.matconstr - left join dominios.finalidade_asb as dominio_finalidade on dominio_finalidade.code = asb_dep_saneamento_p.finalidade - left join dominios.operacional as dominio_operacional on dominio_operacional.code = asb_dep_saneamento_p.operacional - left join dominios.situacaofisica as dominio_situacaofisica on dominio_situacaofisica.code = asb_dep_saneamento_p.situacaofisica - left join dominios.residuo as dominio_residuo on dominio_residuo.code = asb_dep_saneamento_p.residuo + cb.asb_dep_saneamento_p + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = asb_dep_saneamento_p.geometriaaproximada + left join dominios.tipodepsaneam as dominio_tipodepsaneam on dominio_tipodepsaneam.code = asb_dep_saneamento_p.tipodepsaneam + left join dominios.construcao as dominio_construcao on dominio_construcao.code = asb_dep_saneamento_p.construcao + left join dominios.matconstr as dominio_matconstr on dominio_matconstr.code = asb_dep_saneamento_p.matconstr + left join dominios.finalidade_asb as dominio_finalidade on dominio_finalidade.code = asb_dep_saneamento_p.finalidade + left join dominios.operacional as dominio_operacional on dominio_operacional.code = asb_dep_saneamento_p.operacional + left join dominios.situacaofisica as dominio_situacaofisica on dominio_situacaofisica.code = asb_dep_saneamento_p.situacaofisica + left join dominios.residuo as dominio_residuo on dominio_residuo.code = asb_dep_saneamento_p.residuo left join dominios.tiporesiduo as dominio_tiporesiduo on dominio_tiporesiduo.code = asb_dep_saneamento_p.tiporesiduo # DROP VIEW IF EXISTS views.eco_descontinuidade_geometrica_p# -CREATE [VIEW] views.eco_descontinuidade_geometrica_p as +CREATE [VIEW] views.eco_descontinuidade_geometrica_p as SELECT id as id, dominio_geometriaaproximada.code_name as geometriaaproximada, dominio_motivodescontinuidade.code_name as motivodescontinuidade, geom as geom [FROM] - cb.eco_descontinuidade_geometrica_p - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = eco_descontinuidade_geometrica_p.geometriaaproximada + cb.eco_descontinuidade_geometrica_p + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = eco_descontinuidade_geometrica_p.geometriaaproximada left join dominios.motivodescontinuidade as dominio_motivodescontinuidade on dominio_motivodescontinuidade.code = eco_descontinuidade_geometrica_p.motivodescontinuidade # DROP VIEW IF EXISTS views.edu_campo_quadra_p# -CREATE [VIEW] views.edu_campo_quadra_p as +CREATE [VIEW] views.edu_campo_quadra_p as SELECT id as id, nome as nome, @@ -413,14 +413,14 @@ CREATE [VIEW] views.edu_campo_quadra_p as id_complexo_lazer as id_complexo_lazer, geom as geom [FROM] - cb.edu_campo_quadra_p - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = edu_campo_quadra_p.geometriaaproximada - left join dominios.operacional as dominio_operacional on dominio_operacional.code = edu_campo_quadra_p.operacional - left join dominios.situacaofisica as dominio_situacaofisica on dominio_situacaofisica.code = edu_campo_quadra_p.situacaofisica + cb.edu_campo_quadra_p + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = edu_campo_quadra_p.geometriaaproximada + left join dominios.operacional as dominio_operacional on dominio_operacional.code = edu_campo_quadra_p.operacional + left join dominios.situacaofisica as dominio_situacaofisica on dominio_situacaofisica.code = edu_campo_quadra_p.situacaofisica left join dominios.tipocampoquadra as dominio_tipocampoquadra on dominio_tipocampoquadra.code = edu_campo_quadra_p.tipocampoquadra # DROP VIEW IF EXISTS views.rel_elemento_fisiog_natural_a# -CREATE [VIEW] views.rel_elemento_fisiog_natural_a as +CREATE [VIEW] views.rel_elemento_fisiog_natural_a as SELECT id as id, nome as nome, @@ -429,12 +429,12 @@ CREATE [VIEW] views.rel_elemento_fisiog_natural_a as dominio_tipoelemnat.code_name as tipoelemnat, geom as geom [FROM] - cb.rel_elemento_fisiog_natural_a - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = rel_elemento_fisiog_natural_a.geometriaaproximada + cb.rel_elemento_fisiog_natural_a + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = rel_elemento_fisiog_natural_a.geometriaaproximada left join dominios.tipoelemnat as dominio_tipoelemnat on dominio_tipoelemnat.code = rel_elemento_fisiog_natural_a.tipoelemnat # DROP VIEW IF EXISTS views.tra_atracadouro_a# -CREATE [VIEW] views.tra_atracadouro_a as +CREATE [VIEW] views.tra_atracadouro_a as SELECT id as id, nome as nome, @@ -448,28 +448,28 @@ CREATE [VIEW] views.tra_atracadouro_a as id_complexo_portuario as id_complexo_portuario, geom as geom [FROM] - cb.tra_atracadouro_a - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = tra_atracadouro_a.geometriaaproximada - left join dominios.tipoatracad as dominio_tipoatracad on dominio_tipoatracad.code = tra_atracadouro_a.tipoatracad - left join dominios.administracao as dominio_administracao on dominio_administracao.code = tra_atracadouro_a.administracao - left join dominios.matconstr as dominio_matconstr on dominio_matconstr.code = tra_atracadouro_a.matconstr - left join dominios.operacional as dominio_operacional on dominio_operacional.code = tra_atracadouro_a.operacional + cb.tra_atracadouro_a + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = tra_atracadouro_a.geometriaaproximada + left join dominios.tipoatracad as dominio_tipoatracad on dominio_tipoatracad.code = tra_atracadouro_a.tipoatracad + left join dominios.administracao as dominio_administracao on dominio_administracao.code = tra_atracadouro_a.administracao + left join dominios.matconstr as dominio_matconstr on dominio_matconstr.code = tra_atracadouro_a.matconstr + left join dominios.operacional as dominio_operacional on dominio_operacional.code = tra_atracadouro_a.operacional left join dominios.situacaofisica as dominio_situacaofisica on dominio_situacaofisica.code = tra_atracadouro_a.situacaofisica # DROP VIEW IF EXISTS views.lim_descontinuidade_geometrica_a# -CREATE [VIEW] views.lim_descontinuidade_geometrica_a as +CREATE [VIEW] views.lim_descontinuidade_geometrica_a as SELECT id as id, dominio_geometriaaproximada.code_name as geometriaaproximada, dominio_motivodescontinuidade.code_name as motivodescontinuidade, geom as geom [FROM] - cb.lim_descontinuidade_geometrica_a - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = lim_descontinuidade_geometrica_a.geometriaaproximada + cb.lim_descontinuidade_geometrica_a + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = lim_descontinuidade_geometrica_a.geometriaaproximada left join dominios.motivodescontinuidade as dominio_motivodescontinuidade on dominio_motivodescontinuidade.code = lim_descontinuidade_geometrica_a.motivodescontinuidade # DROP VIEW IF EXISTS views.eco_edif_ext_mineral_a# -CREATE [VIEW] views.eco_edif_ext_mineral_a as +CREATE [VIEW] views.eco_edif_ext_mineral_a as SELECT id as id, nome as nome, @@ -482,15 +482,15 @@ CREATE [VIEW] views.eco_edif_ext_mineral_a as dominio_tipodivisaocnae.code_name as tipodivisaocnae, id_org_ext_mineral as id_org_ext_mineral [FROM] - cb.eco_edif_ext_mineral_a - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = eco_edif_ext_mineral_a.geometriaaproximada - left join dominios.operacional as dominio_operacional on dominio_operacional.code = eco_edif_ext_mineral_a.operacional - left join dominios.situacaofisica as dominio_situacaofisica on dominio_situacaofisica.code = eco_edif_ext_mineral_a.situacaofisica - left join dominios.matconstr as dominio_matconstr on dominio_matconstr.code = eco_edif_ext_mineral_a.matconstr + cb.eco_edif_ext_mineral_a + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = eco_edif_ext_mineral_a.geometriaaproximada + left join dominios.operacional as dominio_operacional on dominio_operacional.code = eco_edif_ext_mineral_a.operacional + left join dominios.situacaofisica as dominio_situacaofisica on dominio_situacaofisica.code = eco_edif_ext_mineral_a.situacaofisica + left join dominios.matconstr as dominio_matconstr on dominio_matconstr.code = eco_edif_ext_mineral_a.matconstr left join dominios.tipodivisaocnae as dominio_tipodivisaocnae on dominio_tipodivisaocnae.code = eco_edif_ext_mineral_a.tipodivisaocnae # DROP VIEW IF EXISTS views.hid_ponto_inicio_drenagem_p# -CREATE [VIEW] views.hid_ponto_inicio_drenagem_p as +CREATE [VIEW] views.hid_ponto_inicio_drenagem_p as SELECT id as id, nome as nome, @@ -500,25 +500,25 @@ CREATE [VIEW] views.hid_ponto_inicio_drenagem_p as geom as geom, dominio_nascente.code_name as nascente [FROM] - cb.hid_ponto_inicio_drenagem_p - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = hid_ponto_inicio_drenagem_p.geometriaaproximada - left join dominios.relacionado_hid as dominio_relacionado on dominio_relacionado.code = hid_ponto_inicio_drenagem_p.relacionado + cb.hid_ponto_inicio_drenagem_p + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = hid_ponto_inicio_drenagem_p.geometriaaproximada + left join dominios.relacionado_hid as dominio_relacionado on dominio_relacionado.code = hid_ponto_inicio_drenagem_p.relacionado left join dominios.nascente as dominio_nascente on dominio_nascente.code = hid_ponto_inicio_drenagem_p.nascente # DROP VIEW IF EXISTS views.eco_descontinuidade_geometrica_l# -CREATE [VIEW] views.eco_descontinuidade_geometrica_l as +CREATE [VIEW] views.eco_descontinuidade_geometrica_l as SELECT id as id, dominio_geometriaaproximada.code_name as geometriaaproximada, dominio_motivodescontinuidade.code_name as motivodescontinuidade, geom as geom [FROM] - cb.eco_descontinuidade_geometrica_l - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = eco_descontinuidade_geometrica_l.geometriaaproximada + cb.eco_descontinuidade_geometrica_l + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = eco_descontinuidade_geometrica_l.geometriaaproximada left join dominios.motivodescontinuidade as dominio_motivodescontinuidade on dominio_motivodescontinuidade.code = eco_descontinuidade_geometrica_l.motivodescontinuidade # DROP VIEW IF EXISTS views.tra_caminho_aereo_l# -CREATE [VIEW] views.tra_caminho_aereo_l as +CREATE [VIEW] views.tra_caminho_aereo_l as SELECT id as id, nome as nome, @@ -532,27 +532,27 @@ CREATE [VIEW] views.tra_caminho_aereo_l as id_org_ext_mineral as id_org_ext_mineral, id_complexo_lazer as id_complexo_lazer [FROM] - cb.tra_caminho_aereo_l - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = tra_caminho_aereo_l.geometriaaproximada - left join dominios.tipocaminhoaereo as dominio_tipocaminhoaereo on dominio_tipocaminhoaereo.code = tra_caminho_aereo_l.tipocaminhoaereo - left join dominios.tipousocaminhoaer as dominio_tipousocaminhoaer on dominio_tipousocaminhoaer.code = tra_caminho_aereo_l.tipousocaminhoaer - left join dominios.operacional as dominio_operacional on dominio_operacional.code = tra_caminho_aereo_l.operacional + cb.tra_caminho_aereo_l + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = tra_caminho_aereo_l.geometriaaproximada + left join dominios.tipocaminhoaereo as dominio_tipocaminhoaereo on dominio_tipocaminhoaereo.code = tra_caminho_aereo_l.tipocaminhoaereo + left join dominios.tipousocaminhoaer as dominio_tipousocaminhoaer on dominio_tipousocaminhoaer.code = tra_caminho_aereo_l.tipousocaminhoaer + left join dominios.operacional as dominio_operacional on dominio_operacional.code = tra_caminho_aereo_l.operacional left join dominios.situacaofisica as dominio_situacaofisica on dominio_situacaofisica.code = tra_caminho_aereo_l.situacaofisica # DROP VIEW IF EXISTS views.eco_descontinuidade_geometrica_a# -CREATE [VIEW] views.eco_descontinuidade_geometrica_a as +CREATE [VIEW] views.eco_descontinuidade_geometrica_a as SELECT id as id, dominio_geometriaaproximada.code_name as geometriaaproximada, dominio_motivodescontinuidade.code_name as motivodescontinuidade, geom as geom [FROM] - cb.eco_descontinuidade_geometrica_a - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = eco_descontinuidade_geometrica_a.geometriaaproximada + cb.eco_descontinuidade_geometrica_a + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = eco_descontinuidade_geometrica_a.geometriaaproximada left join dominios.motivodescontinuidade as dominio_motivodescontinuidade on dominio_motivodescontinuidade.code = eco_descontinuidade_geometrica_a.motivodescontinuidade # DROP VIEW IF EXISTS views.edu_campo_quadra_a# -CREATE [VIEW] views.edu_campo_quadra_a as +CREATE [VIEW] views.edu_campo_quadra_a as SELECT id as id, nome as nome, @@ -564,14 +564,14 @@ CREATE [VIEW] views.edu_campo_quadra_a as id_complexo_lazer as id_complexo_lazer, geom as geom [FROM] - cb.edu_campo_quadra_a - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = edu_campo_quadra_a.geometriaaproximada - left join dominios.operacional as dominio_operacional on dominio_operacional.code = edu_campo_quadra_a.operacional - left join dominios.situacaofisica as dominio_situacaofisica on dominio_situacaofisica.code = edu_campo_quadra_a.situacaofisica + cb.edu_campo_quadra_a + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = edu_campo_quadra_a.geometriaaproximada + left join dominios.operacional as dominio_operacional on dominio_operacional.code = edu_campo_quadra_a.operacional + left join dominios.situacaofisica as dominio_situacaofisica on dominio_situacaofisica.code = edu_campo_quadra_a.situacaofisica left join dominios.tipocampoquadra as dominio_tipocampoquadra on dominio_tipocampoquadra.code = edu_campo_quadra_a.tipocampoquadra # DROP VIEW IF EXISTS views.lim_distrito_a# -CREATE [VIEW] views.lim_distrito_a as +CREATE [VIEW] views.lim_distrito_a as SELECT id as id, nome as nome, @@ -581,11 +581,11 @@ CREATE [VIEW] views.lim_distrito_a as geocodigo as geocodigo, anodereferencia as anodereferencia [FROM] - cb.lim_distrito_a + cb.lim_distrito_a left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = lim_distrito_a.geometriaaproximada # DROP VIEW IF EXISTS views.tra_passag_elevada_viaduto_p# -CREATE [VIEW] views.tra_passag_elevada_viaduto_p as +CREATE [VIEW] views.tra_passag_elevada_viaduto_p as SELECT id as id, nome as nome, @@ -608,17 +608,17 @@ CREATE [VIEW] views.tra_passag_elevada_viaduto_p as largura as largura, geom as geom [FROM] - cb.tra_passag_elevada_viaduto_p - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = tra_passag_elevada_viaduto_p.geometriaaproximada - left join dominios.tipopassagviad as dominio_tipopassagviad on dominio_tipopassagviad.code = tra_passag_elevada_viaduto_p.tipopassagviad - left join dominios.modaluso as dominio_modaluso on dominio_modaluso.code = tra_passag_elevada_viaduto_p.modaluso - left join dominios.matconstr as dominio_matconstr on dominio_matconstr.code = tra_passag_elevada_viaduto_p.matconstr - left join dominios.operacional as dominio_operacional on dominio_operacional.code = tra_passag_elevada_viaduto_p.operacional - left join dominios.situacaofisica as dominio_situacaofisica on dominio_situacaofisica.code = tra_passag_elevada_viaduto_p.situacaofisica + cb.tra_passag_elevada_viaduto_p + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = tra_passag_elevada_viaduto_p.geometriaaproximada + left join dominios.tipopassagviad as dominio_tipopassagviad on dominio_tipopassagviad.code = tra_passag_elevada_viaduto_p.tipopassagviad + left join dominios.modaluso as dominio_modaluso on dominio_modaluso.code = tra_passag_elevada_viaduto_p.modaluso + left join dominios.matconstr as dominio_matconstr on dominio_matconstr.code = tra_passag_elevada_viaduto_p.matconstr + left join dominios.operacional as dominio_operacional on dominio_operacional.code = tra_passag_elevada_viaduto_p.operacional + left join dominios.situacaofisica as dominio_situacaofisica on dominio_situacaofisica.code = tra_passag_elevada_viaduto_p.situacaofisica left join dominios.posicaopista as dominio_posicaopista on dominio_posicaopista.code = tra_passag_elevada_viaduto_p.posicaopista # DROP VIEW IF EXISTS views.rel_elemento_fisiog_natural_p# -CREATE [VIEW] views.rel_elemento_fisiog_natural_p as +CREATE [VIEW] views.rel_elemento_fisiog_natural_p as SELECT id as id, nome as nome, @@ -627,12 +627,12 @@ CREATE [VIEW] views.rel_elemento_fisiog_natural_p as dominio_tipoelemnat.code_name as tipoelemnat, geom as geom [FROM] - cb.rel_elemento_fisiog_natural_p - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = rel_elemento_fisiog_natural_p.geometriaaproximada + cb.rel_elemento_fisiog_natural_p + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = rel_elemento_fisiog_natural_p.geometriaaproximada left join dominios.tipoelemnat as dominio_tipoelemnat on dominio_tipoelemnat.code = rel_elemento_fisiog_natural_p.tipoelemnat # DROP VIEW IF EXISTS views.tra_eclusa_p# -CREATE [VIEW] views.tra_eclusa_p as +CREATE [VIEW] views.tra_eclusa_p as SELECT id as id, nome as nome, @@ -647,14 +647,14 @@ CREATE [VIEW] views.tra_eclusa_p as dominio_situacaofisica.code_name as situacaofisica, geom as geom [FROM] - cb.tra_eclusa_p - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = tra_eclusa_p.geometriaaproximada - left join dominios.matconstr as dominio_matconstr on dominio_matconstr.code = tra_eclusa_p.matconstr - left join dominios.operacional as dominio_operacional on dominio_operacional.code = tra_eclusa_p.operacional + cb.tra_eclusa_p + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = tra_eclusa_p.geometriaaproximada + left join dominios.matconstr as dominio_matconstr on dominio_matconstr.code = tra_eclusa_p.matconstr + left join dominios.operacional as dominio_operacional on dominio_operacional.code = tra_eclusa_p.operacional left join dominios.situacaofisica as dominio_situacaofisica on dominio_situacaofisica.code = tra_eclusa_p.situacaofisica # DROP VIEW IF EXISTS views.tra_atracadouro_p# -CREATE [VIEW] views.tra_atracadouro_p as +CREATE [VIEW] views.tra_atracadouro_p as SELECT id as id, nome as nome, @@ -668,16 +668,16 @@ CREATE [VIEW] views.tra_atracadouro_p as id_complexo_portuario as id_complexo_portuario, geom as geom [FROM] - cb.tra_atracadouro_p - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = tra_atracadouro_p.geometriaaproximada - left join dominios.tipoatracad as dominio_tipoatracad on dominio_tipoatracad.code = tra_atracadouro_p.tipoatracad - left join dominios.administracao as dominio_administracao on dominio_administracao.code = tra_atracadouro_p.administracao - left join dominios.matconstr as dominio_matconstr on dominio_matconstr.code = tra_atracadouro_p.matconstr - left join dominios.operacional as dominio_operacional on dominio_operacional.code = tra_atracadouro_p.operacional + cb.tra_atracadouro_p + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = tra_atracadouro_p.geometriaaproximada + left join dominios.tipoatracad as dominio_tipoatracad on dominio_tipoatracad.code = tra_atracadouro_p.tipoatracad + left join dominios.administracao as dominio_administracao on dominio_administracao.code = tra_atracadouro_p.administracao + left join dominios.matconstr as dominio_matconstr on dominio_matconstr.code = tra_atracadouro_p.matconstr + left join dominios.operacional as dominio_operacional on dominio_operacional.code = tra_atracadouro_p.operacional left join dominios.situacaofisica as dominio_situacaofisica on dominio_situacaofisica.code = tra_atracadouro_p.situacaofisica # DROP VIEW IF EXISTS views.enc_torre_comunic_p# -CREATE [VIEW] views.enc_torre_comunic_p as +CREATE [VIEW] views.enc_torre_comunic_p as SELECT id as id, nome as nome, @@ -691,15 +691,15 @@ CREATE [VIEW] views.enc_torre_comunic_p as id_complexo_comunicacao as id_complexo_comunicacao, geom as geom [FROM] - cb.enc_torre_comunic_p - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = enc_torre_comunic_p.geometriaaproximada - left join dominios.operacional as dominio_operacional on dominio_operacional.code = enc_torre_comunic_p.operacional - left join dominios.situacaofisica as dominio_situacaofisica on dominio_situacaofisica.code = enc_torre_comunic_p.situacaofisica - left join dominios.posicaoreledific as dominio_posicaoreledific on dominio_posicaoreledific.code = enc_torre_comunic_p.posicaoreledific + cb.enc_torre_comunic_p + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = enc_torre_comunic_p.geometriaaproximada + left join dominios.operacional as dominio_operacional on dominio_operacional.code = enc_torre_comunic_p.operacional + left join dominios.situacaofisica as dominio_situacaofisica on dominio_situacaofisica.code = enc_torre_comunic_p.situacaofisica + left join dominios.posicaoreledific as dominio_posicaoreledific on dominio_posicaoreledific.code = enc_torre_comunic_p.posicaoreledific left join dominios.ovgd as dominio_ovgd on dominio_ovgd.code = enc_torre_comunic_p.ovgd # DROP VIEW IF EXISTS views.loc_hab_indigena_p# -CREATE [VIEW] views.loc_hab_indigena_p as +CREATE [VIEW] views.loc_hab_indigena_p as SELECT id as id, nome as nome, @@ -710,13 +710,13 @@ CREATE [VIEW] views.loc_hab_indigena_p as id_aldeia_indigena as id_aldeia_indigena, geom as geom [FROM] - cb.loc_hab_indigena_p - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = loc_hab_indigena_p.geometriaaproximada - left join dominios.coletiva as dominio_coletiva on dominio_coletiva.code = loc_hab_indigena_p.coletiva + cb.loc_hab_indigena_p + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = loc_hab_indigena_p.geometriaaproximada + left join dominios.coletiva as dominio_coletiva on dominio_coletiva.code = loc_hab_indigena_p.coletiva left join dominios.isolada as dominio_isolada on dominio_isolada.code = loc_hab_indigena_p.isolada # DROP VIEW IF EXISTS views.edu_edif_const_turistica_a# -CREATE [VIEW] views.edu_edif_const_turistica_a as +CREATE [VIEW] views.edu_edif_const_turistica_a as SELECT id as id, nome as nome, @@ -730,16 +730,16 @@ CREATE [VIEW] views.edu_edif_const_turistica_a as dominio_ovgd.code_name as ovgd, id_complexo_lazer as id_complexo_lazer [FROM] - cb.edu_edif_const_turistica_a - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = edu_edif_const_turistica_a.geometriaaproximada - left join dominios.operacional as dominio_operacional on dominio_operacional.code = edu_edif_const_turistica_a.operacional - left join dominios.situacaofisica as dominio_situacaofisica on dominio_situacaofisica.code = edu_edif_const_turistica_a.situacaofisica - left join dominios.matconstr as dominio_matconstr on dominio_matconstr.code = edu_edif_const_turistica_a.matconstr - left join dominios.tipoedifturist as dominio_tipoedifturist on dominio_tipoedifturist.code = edu_edif_const_turistica_a.tipoedifturist + cb.edu_edif_const_turistica_a + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = edu_edif_const_turistica_a.geometriaaproximada + left join dominios.operacional as dominio_operacional on dominio_operacional.code = edu_edif_const_turistica_a.operacional + left join dominios.situacaofisica as dominio_situacaofisica on dominio_situacaofisica.code = edu_edif_const_turistica_a.situacaofisica + left join dominios.matconstr as dominio_matconstr on dominio_matconstr.code = edu_edif_const_turistica_a.matconstr + left join dominios.tipoedifturist as dominio_tipoedifturist on dominio_tipoedifturist.code = edu_edif_const_turistica_a.tipoedifturist left join dominios.ovgd as dominio_ovgd on dominio_ovgd.code = edu_edif_const_turistica_a.ovgd # DROP VIEW IF EXISTS views.rel_terreno_exposto_a# -CREATE [VIEW] views.rel_terreno_exposto_a as +CREATE [VIEW] views.rel_terreno_exposto_a as SELECT id as id, dominio_geometriaaproximada.code_name as geometriaaproximada, @@ -747,13 +747,13 @@ CREATE [VIEW] views.rel_terreno_exposto_a as dominio_causaexposicao.code_name as causaexposicao, geom as geom [FROM] - cb.rel_terreno_exposto_a - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = rel_terreno_exposto_a.geometriaaproximada - left join dominios.tipoterrexp as dominio_tipoterrexp on dominio_tipoterrexp.code = rel_terreno_exposto_a.tipoterrexp + cb.rel_terreno_exposto_a + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = rel_terreno_exposto_a.geometriaaproximada + left join dominios.tipoterrexp as dominio_tipoterrexp on dominio_tipoterrexp.code = rel_terreno_exposto_a.tipoterrexp left join dominios.causaexposicao as dominio_causaexposicao on dominio_causaexposicao.code = rel_terreno_exposto_a.causaexposicao # DROP VIEW IF EXISTS views.adm_posto_pol_rod_p# -CREATE [VIEW] views.adm_posto_pol_rod_p as +CREATE [VIEW] views.adm_posto_pol_rod_p as SELECT id as id, nome as nome, @@ -766,14 +766,14 @@ CREATE [VIEW] views.adm_posto_pol_rod_p as id_org_pub_civil as id_org_pub_civil, geom as geom [FROM] - cb.adm_posto_pol_rod_p - left join dominios.tipopostopol as dominio_tipopostopol on dominio_tipopostopol.code = adm_posto_pol_rod_p.tipopostopol - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = adm_posto_pol_rod_p.geometriaaproximada - left join dominios.operacional as dominio_operacional on dominio_operacional.code = adm_posto_pol_rod_p.operacional + cb.adm_posto_pol_rod_p + left join dominios.tipopostopol as dominio_tipopostopol on dominio_tipopostopol.code = adm_posto_pol_rod_p.tipopostopol + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = adm_posto_pol_rod_p.geometriaaproximada + left join dominios.operacional as dominio_operacional on dominio_operacional.code = adm_posto_pol_rod_p.operacional left join dominios.situacaofisica as dominio_situacaofisica on dominio_situacaofisica.code = adm_posto_pol_rod_p.situacaofisica # DROP VIEW IF EXISTS views.enc_edif_comunic_p# -CREATE [VIEW] views.enc_edif_comunic_p as +CREATE [VIEW] views.enc_edif_comunic_p as SELECT id as id, nome as nome, @@ -787,16 +787,16 @@ CREATE [VIEW] views.enc_edif_comunic_p as dominio_tipoedifcomunic.code_name as tipoedifcomunic, id_complexo_comunicacao as id_complexo_comunicacao [FROM] - cb.enc_edif_comunic_p - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = enc_edif_comunic_p.geometriaaproximada - left join dominios.operacional as dominio_operacional on dominio_operacional.code = enc_edif_comunic_p.operacional - left join dominios.situacaofisica as dominio_situacaofisica on dominio_situacaofisica.code = enc_edif_comunic_p.situacaofisica - left join dominios.matconstr as dominio_matconstr on dominio_matconstr.code = enc_edif_comunic_p.matconstr - left join dominios.modalidade as dominio_modalidade on dominio_modalidade.code = enc_edif_comunic_p.modalidade + cb.enc_edif_comunic_p + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = enc_edif_comunic_p.geometriaaproximada + left join dominios.operacional as dominio_operacional on dominio_operacional.code = enc_edif_comunic_p.operacional + left join dominios.situacaofisica as dominio_situacaofisica on dominio_situacaofisica.code = enc_edif_comunic_p.situacaofisica + left join dominios.matconstr as dominio_matconstr on dominio_matconstr.code = enc_edif_comunic_p.matconstr + left join dominios.modalidade as dominio_modalidade on dominio_modalidade.code = enc_edif_comunic_p.modalidade left join dominios.tipoedifcomunic as dominio_tipoedifcomunic on dominio_tipoedifcomunic.code = enc_edif_comunic_p.tipoedifcomunic # DROP VIEW IF EXISTS views.tra_girador_ferroviario_p# -CREATE [VIEW] views.tra_girador_ferroviario_p as +CREATE [VIEW] views.tra_girador_ferroviario_p as SELECT id as id, nome as nome, @@ -808,14 +808,14 @@ CREATE [VIEW] views.tra_girador_ferroviario_p as geom as geom, id_estrut_apoio as id_estrut_apoio [FROM] - cb.tra_girador_ferroviario_p - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = tra_girador_ferroviario_p.geometriaaproximada - left join dominios.administracao as dominio_administracao on dominio_administracao.code = tra_girador_ferroviario_p.administracao - left join dominios.operacional as dominio_operacional on dominio_operacional.code = tra_girador_ferroviario_p.operacional + cb.tra_girador_ferroviario_p + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = tra_girador_ferroviario_p.geometriaaproximada + left join dominios.administracao as dominio_administracao on dominio_administracao.code = tra_girador_ferroviario_p.administracao + left join dominios.operacional as dominio_operacional on dominio_operacional.code = tra_girador_ferroviario_p.operacional left join dominios.situacaofisica as dominio_situacaofisica on dominio_situacaofisica.code = tra_girador_ferroviario_p.situacaofisica # DROP VIEW IF EXISTS views.hid_sumidouro_vertedouro_p# -CREATE [VIEW] views.hid_sumidouro_vertedouro_p as +CREATE [VIEW] views.hid_sumidouro_vertedouro_p as SELECT id as id, nome as nome, @@ -825,25 +825,25 @@ CREATE [VIEW] views.hid_sumidouro_vertedouro_p as dominio_causa.code_name as causa, geom as geom [FROM] - cb.hid_sumidouro_vertedouro_p - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = hid_sumidouro_vertedouro_p.geometriaaproximada - left join dominios.tiposumvert as dominio_tiposumvert on dominio_tiposumvert.code = hid_sumidouro_vertedouro_p.tiposumvert + cb.hid_sumidouro_vertedouro_p + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = hid_sumidouro_vertedouro_p.geometriaaproximada + left join dominios.tiposumvert as dominio_tiposumvert on dominio_tiposumvert.code = hid_sumidouro_vertedouro_p.tiposumvert left join dominios.causa as dominio_causa on dominio_causa.code = hid_sumidouro_vertedouro_p.causa # DROP VIEW IF EXISTS views.tra_descontinuidade_geometrica_p# -CREATE [VIEW] views.tra_descontinuidade_geometrica_p as +CREATE [VIEW] views.tra_descontinuidade_geometrica_p as SELECT id as id, dominio_geometriaaproximada.code_name as geometriaaproximada, dominio_motivodescontinuidade.code_name as motivodescontinuidade, geom as geom [FROM] - cb.tra_descontinuidade_geometrica_p - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = tra_descontinuidade_geometrica_p.geometriaaproximada + cb.tra_descontinuidade_geometrica_p + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = tra_descontinuidade_geometrica_p.geometriaaproximada left join dominios.motivodescontinuidade as dominio_motivodescontinuidade on dominio_motivodescontinuidade.code = tra_descontinuidade_geometrica_p.motivodescontinuidade # DROP VIEW IF EXISTS views.lim_limite_politico_adm_l# -CREATE [VIEW] views.lim_limite_politico_adm_l as +CREATE [VIEW] views.lim_limite_politico_adm_l as SELECT id as id, nome as nome, @@ -855,13 +855,13 @@ CREATE [VIEW] views.lim_limite_politico_adm_l as dominio_tipolimpol.code_name as tipolimpol, obssituacao as obssituacao [FROM] - cb.lim_limite_politico_adm_l - left join dominios.coincidecomdentrode_lim as dominio_coincidecomdentrode on dominio_coincidecomdentrode.code = lim_limite_politico_adm_l.coincidecomdentrode - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = lim_limite_politico_adm_l.geometriaaproximada + cb.lim_limite_politico_adm_l + left join dominios.coincidecomdentrode_lim as dominio_coincidecomdentrode on dominio_coincidecomdentrode.code = lim_limite_politico_adm_l.coincidecomdentrode + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = lim_limite_politico_adm_l.geometriaaproximada left join dominios.tipolimpol as dominio_tipolimpol on dominio_tipolimpol.code = lim_limite_politico_adm_l.tipolimpol # DROP VIEW IF EXISTS views.tra_trilha_picada_l# -CREATE [VIEW] views.tra_trilha_picada_l as +CREATE [VIEW] views.tra_trilha_picada_l as SELECT id as id, nome as nome, @@ -869,11 +869,11 @@ CREATE [VIEW] views.tra_trilha_picada_l as dominio_geometriaaproximada.code_name as geometriaaproximada, geom as geom [FROM] - cb.tra_trilha_picada_l + cb.tra_trilha_picada_l left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = tra_trilha_picada_l.geometriaaproximada # DROP VIEW IF EXISTS views.tra_travessia_p# -CREATE [VIEW] views.tra_travessia_p as +CREATE [VIEW] views.tra_travessia_p as SELECT id as id, nome as nome, @@ -882,12 +882,12 @@ CREATE [VIEW] views.tra_travessia_p as dominio_tipotravessia.code_name as tipotravessia, geom as geom [FROM] - cb.tra_travessia_p - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = tra_travessia_p.geometriaaproximada + cb.tra_travessia_p + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = tra_travessia_p.geometriaaproximada left join dominios.tipotravessia as dominio_tipotravessia on dominio_tipotravessia.code = tra_travessia_p.tipotravessia # DROP VIEW IF EXISTS views.lim_terra_indigena_p# -CREATE [VIEW] views.lim_terra_indigena_p as +CREATE [VIEW] views.lim_terra_indigena_p as SELECT id as id, nome as nome, @@ -901,12 +901,12 @@ CREATE [VIEW] views.lim_terra_indigena_p as perimetrooficial as perimetrooficial, geom as geom [FROM] - cb.lim_terra_indigena_p - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = lim_terra_indigena_p.geometriaaproximada + cb.lim_terra_indigena_p + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = lim_terra_indigena_p.geometriaaproximada left join dominios.situacaojuridica as dominio_situacaojuridica on dominio_situacaojuridica.code = lim_terra_indigena_p.situacaojuridica # DROP VIEW IF EXISTS views.edu_piscina_a# -CREATE [VIEW] views.edu_piscina_a as +CREATE [VIEW] views.edu_piscina_a as SELECT id as id, nome as nome, @@ -917,13 +917,13 @@ CREATE [VIEW] views.edu_piscina_a as id_complexo_lazer as id_complexo_lazer, geom as geom [FROM] - cb.edu_piscina_a - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = edu_piscina_a.geometriaaproximada - left join dominios.operacional as dominio_operacional on dominio_operacional.code = edu_piscina_a.operacional + cb.edu_piscina_a + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = edu_piscina_a.geometriaaproximada + left join dominios.operacional as dominio_operacional on dominio_operacional.code = edu_piscina_a.operacional left join dominios.situacaofisica as dominio_situacaofisica on dominio_situacaofisica.code = edu_piscina_a.situacaofisica # DROP VIEW IF EXISTS views.loc_hab_indigena_a# -CREATE [VIEW] views.loc_hab_indigena_a as +CREATE [VIEW] views.loc_hab_indigena_a as SELECT id as id, nome as nome, @@ -934,24 +934,24 @@ CREATE [VIEW] views.loc_hab_indigena_a as id_aldeia_indigena as id_aldeia_indigena, geom as geom [FROM] - cb.loc_hab_indigena_a - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = loc_hab_indigena_a.geometriaaproximada - left join dominios.coletiva as dominio_coletiva on dominio_coletiva.code = loc_hab_indigena_a.coletiva + cb.loc_hab_indigena_a + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = loc_hab_indigena_a.geometriaaproximada + left join dominios.coletiva as dominio_coletiva on dominio_coletiva.code = loc_hab_indigena_a.coletiva left join dominios.isolada as dominio_isolada on dominio_isolada.code = loc_hab_indigena_a.isolada # DROP VIEW IF EXISTS views.pto_area_est_med_fenom_a# -CREATE [VIEW] views.pto_area_est_med_fenom_a as +CREATE [VIEW] views.pto_area_est_med_fenom_a as SELECT id as id, dominio_geometriaaproximada.code_name as geometriaaproximada, id_est_med_fenomenos as id_est_med_fenomenos, geom as geom [FROM] - cb.pto_area_est_med_fenom_a + cb.pto_area_est_med_fenom_a left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = pto_area_est_med_fenom_a.geometriaaproximada # DROP VIEW IF EXISTS views.edu_edif_const_turistica_p# -CREATE [VIEW] views.edu_edif_const_turistica_p as +CREATE [VIEW] views.edu_edif_const_turistica_p as SELECT id as id, nome as nome, @@ -965,16 +965,16 @@ CREATE [VIEW] views.edu_edif_const_turistica_p as dominio_ovgd.code_name as ovgd, id_complexo_lazer as id_complexo_lazer [FROM] - cb.edu_edif_const_turistica_p - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = edu_edif_const_turistica_p.geometriaaproximada - left join dominios.operacional as dominio_operacional on dominio_operacional.code = edu_edif_const_turistica_p.operacional - left join dominios.situacaofisica as dominio_situacaofisica on dominio_situacaofisica.code = edu_edif_const_turistica_p.situacaofisica - left join dominios.matconstr as dominio_matconstr on dominio_matconstr.code = edu_edif_const_turistica_p.matconstr - left join dominios.tipoedifturist as dominio_tipoedifturist on dominio_tipoedifturist.code = edu_edif_const_turistica_p.tipoedifturist + cb.edu_edif_const_turistica_p + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = edu_edif_const_turistica_p.geometriaaproximada + left join dominios.operacional as dominio_operacional on dominio_operacional.code = edu_edif_const_turistica_p.operacional + left join dominios.situacaofisica as dominio_situacaofisica on dominio_situacaofisica.code = edu_edif_const_turistica_p.situacaofisica + left join dominios.matconstr as dominio_matconstr on dominio_matconstr.code = edu_edif_const_turistica_p.matconstr + left join dominios.tipoedifturist as dominio_tipoedifturist on dominio_tipoedifturist.code = edu_edif_const_turistica_p.tipoedifturist left join dominios.ovgd as dominio_ovgd on dominio_ovgd.code = edu_edif_const_turistica_p.ovgd # DROP VIEW IF EXISTS views.enc_edif_comunic_a# -CREATE [VIEW] views.enc_edif_comunic_a as +CREATE [VIEW] views.enc_edif_comunic_a as SELECT id as id, nome as nome, @@ -988,16 +988,16 @@ CREATE [VIEW] views.enc_edif_comunic_a as dominio_tipoedifcomunic.code_name as tipoedifcomunic, id_complexo_comunicacao as id_complexo_comunicacao [FROM] - cb.enc_edif_comunic_a - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = enc_edif_comunic_a.geometriaaproximada - left join dominios.operacional as dominio_operacional on dominio_operacional.code = enc_edif_comunic_a.operacional - left join dominios.situacaofisica as dominio_situacaofisica on dominio_situacaofisica.code = enc_edif_comunic_a.situacaofisica - left join dominios.matconstr as dominio_matconstr on dominio_matconstr.code = enc_edif_comunic_a.matconstr - left join dominios.modalidade as dominio_modalidade on dominio_modalidade.code = enc_edif_comunic_a.modalidade + cb.enc_edif_comunic_a + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = enc_edif_comunic_a.geometriaaproximada + left join dominios.operacional as dominio_operacional on dominio_operacional.code = enc_edif_comunic_a.operacional + left join dominios.situacaofisica as dominio_situacaofisica on dominio_situacaofisica.code = enc_edif_comunic_a.situacaofisica + left join dominios.matconstr as dominio_matconstr on dominio_matconstr.code = enc_edif_comunic_a.matconstr + left join dominios.modalidade as dominio_modalidade on dominio_modalidade.code = enc_edif_comunic_a.modalidade left join dominios.tipoedifcomunic as dominio_tipoedifcomunic on dominio_tipoedifcomunic.code = enc_edif_comunic_a.tipoedifcomunic # DROP VIEW IF EXISTS views.adm_posto_pol_rod_a# -CREATE [VIEW] views.adm_posto_pol_rod_a as +CREATE [VIEW] views.adm_posto_pol_rod_a as SELECT id as id, nome as nome, @@ -1010,38 +1010,38 @@ CREATE [VIEW] views.adm_posto_pol_rod_a as id_org_pub_civil as id_org_pub_civil, geom as geom [FROM] - cb.adm_posto_pol_rod_a - left join dominios.tipopostopol as dominio_tipopostopol on dominio_tipopostopol.code = adm_posto_pol_rod_a.tipopostopol - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = adm_posto_pol_rod_a.geometriaaproximada - left join dominios.operacional as dominio_operacional on dominio_operacional.code = adm_posto_pol_rod_a.operacional + cb.adm_posto_pol_rod_a + left join dominios.tipopostopol as dominio_tipopostopol on dominio_tipopostopol.code = adm_posto_pol_rod_a.tipopostopol + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = adm_posto_pol_rod_a.geometriaaproximada + left join dominios.operacional as dominio_operacional on dominio_operacional.code = adm_posto_pol_rod_a.operacional left join dominios.situacaofisica as dominio_situacaofisica on dominio_situacaofisica.code = adm_posto_pol_rod_a.situacaofisica # DROP VIEW IF EXISTS views.tra_ponto_duto_p# -CREATE [VIEW] views.tra_ponto_duto_p as +CREATE [VIEW] views.tra_ponto_duto_p as SELECT id as id, geom as geom, dominio_geometriaaproximada.code_name as geometriaaproximada, dominio_relacionado.code_name as relacionado [FROM] - cb.tra_ponto_duto_p - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = tra_ponto_duto_p.geometriaaproximada + cb.tra_ponto_duto_p + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = tra_ponto_duto_p.geometriaaproximada left join dominios.relacionado_dut as dominio_relacionado on dominio_relacionado.code = tra_ponto_duto_p.relacionado # DROP VIEW IF EXISTS views.tra_descontinuidade_geometrica_a# -CREATE [VIEW] views.tra_descontinuidade_geometrica_a as +CREATE [VIEW] views.tra_descontinuidade_geometrica_a as SELECT id as id, dominio_geometriaaproximada.code_name as geometriaaproximada, dominio_motivodescontinuidade.code_name as motivodescontinuidade, geom as geom [FROM] - cb.tra_descontinuidade_geometrica_a - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = tra_descontinuidade_geometrica_a.geometriaaproximada + cb.tra_descontinuidade_geometrica_a + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = tra_descontinuidade_geometrica_a.geometriaaproximada left join dominios.motivodescontinuidade as dominio_motivodescontinuidade on dominio_motivodescontinuidade.code = tra_descontinuidade_geometrica_a.motivodescontinuidade # DROP VIEW IF EXISTS views.eco_deposito_geral_a# -CREATE [VIEW] views.eco_deposito_geral_a as +CREATE [VIEW] views.eco_deposito_geral_a as SELECT id as id, nome as nome, @@ -1065,20 +1065,20 @@ CREATE [VIEW] views.eco_deposito_geral_a as id_org_industrial as id_org_industrial, geom as geom [FROM] - cb.eco_deposito_geral_a - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = eco_deposito_geral_a.geometriaaproximada - left join dominios.operacional as dominio_operacional on dominio_operacional.code = eco_deposito_geral_a.operacional - left join dominios.situacaofisica as dominio_situacaofisica on dominio_situacaofisica.code = eco_deposito_geral_a.situacaofisica - left join dominios.tipodepgeral as dominio_tipodepgeral on dominio_tipodepgeral.code = eco_deposito_geral_a.tipodepgeral - left join dominios.matconstr as dominio_matconstr on dominio_matconstr.code = eco_deposito_geral_a.matconstr - left join dominios.tipoexposicao as dominio_tipoexposicao on dominio_tipoexposicao.code = eco_deposito_geral_a.tipoexposicao - left join dominios.tipoprodutoresiduo as dominio_tipoprodutoresiduo on dominio_tipoprodutoresiduo.code = eco_deposito_geral_a.tipoprodutoresiduo - left join dominios.tipoconteudo as dominio_tipoconteudo on dominio_tipoconteudo.code = eco_deposito_geral_a.tipoconteudo - left join dominios.unidadevolume as dominio_unidadevolume on dominio_unidadevolume.code = eco_deposito_geral_a.unidadevolume + cb.eco_deposito_geral_a + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = eco_deposito_geral_a.geometriaaproximada + left join dominios.operacional as dominio_operacional on dominio_operacional.code = eco_deposito_geral_a.operacional + left join dominios.situacaofisica as dominio_situacaofisica on dominio_situacaofisica.code = eco_deposito_geral_a.situacaofisica + left join dominios.tipodepgeral as dominio_tipodepgeral on dominio_tipodepgeral.code = eco_deposito_geral_a.tipodepgeral + left join dominios.matconstr as dominio_matconstr on dominio_matconstr.code = eco_deposito_geral_a.matconstr + left join dominios.tipoexposicao as dominio_tipoexposicao on dominio_tipoexposicao.code = eco_deposito_geral_a.tipoexposicao + left join dominios.tipoprodutoresiduo as dominio_tipoprodutoresiduo on dominio_tipoprodutoresiduo.code = eco_deposito_geral_a.tipoprodutoresiduo + left join dominios.tipoconteudo as dominio_tipoconteudo on dominio_tipoconteudo.code = eco_deposito_geral_a.tipoconteudo + left join dominios.unidadevolume as dominio_unidadevolume on dominio_unidadevolume.code = eco_deposito_geral_a.unidadevolume left join dominios.tratamento as dominio_tratamento on dominio_tratamento.code = eco_deposito_geral_a.tratamento # DROP VIEW IF EXISTS views.lim_regiao_administrativa_a# -CREATE [VIEW] views.lim_regiao_administrativa_a as +CREATE [VIEW] views.lim_regiao_administrativa_a as SELECT id as id, nome as nome, @@ -1087,11 +1087,11 @@ CREATE [VIEW] views.lim_regiao_administrativa_a as geom as geom, anodereferencia as anodereferencia [FROM] - cb.lim_regiao_administrativa_a + cb.lim_regiao_administrativa_a left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = lim_regiao_administrativa_a.geometriaaproximada # DROP VIEW IF EXISTS views.lim_terra_indigena_a# -CREATE [VIEW] views.lim_terra_indigena_a as +CREATE [VIEW] views.lim_terra_indigena_a as SELECT id as id, nome as nome, @@ -1105,12 +1105,12 @@ CREATE [VIEW] views.lim_terra_indigena_a as perimetrooficial as perimetrooficial, geom as geom [FROM] - cb.lim_terra_indigena_a - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = lim_terra_indigena_a.geometriaaproximada + cb.lim_terra_indigena_a + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = lim_terra_indigena_a.geometriaaproximada left join dominios.situacaojuridica as dominio_situacaojuridica on dominio_situacaojuridica.code = lim_terra_indigena_a.situacaojuridica # DROP VIEW IF EXISTS views.tra_edif_rodoviaria_p# -CREATE [VIEW] views.tra_edif_rodoviaria_p as +CREATE [VIEW] views.tra_edif_rodoviaria_p as SELECT id as id, nome as nome, @@ -1124,28 +1124,28 @@ CREATE [VIEW] views.tra_edif_rodoviaria_p as dominio_administracao.code_name as administracao, id_estrut_apoio as id_estrut_apoio [FROM] - cb.tra_edif_rodoviaria_p - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = tra_edif_rodoviaria_p.geometriaaproximada - left join dominios.operacional as dominio_operacional on dominio_operacional.code = tra_edif_rodoviaria_p.operacional - left join dominios.situacaofisica as dominio_situacaofisica on dominio_situacaofisica.code = tra_edif_rodoviaria_p.situacaofisica - left join dominios.matconstr as dominio_matconstr on dominio_matconstr.code = tra_edif_rodoviaria_p.matconstr - left join dominios.tipoedifrod as dominio_tipoedifrod on dominio_tipoedifrod.code = tra_edif_rodoviaria_p.tipoedifrod + cb.tra_edif_rodoviaria_p + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = tra_edif_rodoviaria_p.geometriaaproximada + left join dominios.operacional as dominio_operacional on dominio_operacional.code = tra_edif_rodoviaria_p.operacional + left join dominios.situacaofisica as dominio_situacaofisica on dominio_situacaofisica.code = tra_edif_rodoviaria_p.situacaofisica + left join dominios.matconstr as dominio_matconstr on dominio_matconstr.code = tra_edif_rodoviaria_p.matconstr + left join dominios.tipoedifrod as dominio_tipoedifrod on dominio_tipoedifrod.code = tra_edif_rodoviaria_p.tipoedifrod left join dominios.administracao as dominio_administracao on dominio_administracao.code = tra_edif_rodoviaria_p.administracao # DROP VIEW IF EXISTS views.enc_descontinuidade_geometrica_p# -CREATE [VIEW] views.enc_descontinuidade_geometrica_p as +CREATE [VIEW] views.enc_descontinuidade_geometrica_p as SELECT id as id, dominio_geometriaaproximada.code_name as geometriaaproximada, dominio_motivodescontinuidade.code_name as motivodescontinuidade, geom as geom [FROM] - cb.enc_descontinuidade_geometrica_p - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = enc_descontinuidade_geometrica_p.geometriaaproximada + cb.enc_descontinuidade_geometrica_p + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = enc_descontinuidade_geometrica_p.geometriaaproximada left join dominios.motivodescontinuidade as dominio_motivodescontinuidade on dominio_motivodescontinuidade.code = enc_descontinuidade_geometrica_p.motivodescontinuidade # DROP VIEW IF EXISTS views.hid_banco_areia_a# -CREATE [VIEW] views.hid_banco_areia_a as +CREATE [VIEW] views.hid_banco_areia_a as SELECT id as id, nome as nome, @@ -1156,25 +1156,25 @@ CREATE [VIEW] views.hid_banco_areia_a as dominio_materialpredominante.code_name as materialpredominante, geom as geom [FROM] - cb.hid_banco_areia_a - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = hid_banco_areia_a.geometriaaproximada - left join dominios.tipobanco as dominio_tipobanco on dominio_tipobanco.code = hid_banco_areia_a.tipobanco - left join dominios.situacaoemagua as dominio_situacaoemagua on dominio_situacaoemagua.code = hid_banco_areia_a.situacaoemagua + cb.hid_banco_areia_a + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = hid_banco_areia_a.geometriaaproximada + left join dominios.tipobanco as dominio_tipobanco on dominio_tipobanco.code = hid_banco_areia_a.tipobanco + left join dominios.situacaoemagua as dominio_situacaoemagua on dominio_situacaoemagua.code = hid_banco_areia_a.situacaoemagua left join dominios.materialpredominante as dominio_materialpredominante on dominio_materialpredominante.code = hid_banco_areia_a.materialpredominante # DROP VIEW IF EXISTS views.asb_area_abast_agua_a# -CREATE [VIEW] views.asb_area_abast_agua_a as +CREATE [VIEW] views.asb_area_abast_agua_a as SELECT id as id, dominio_geometriaaproximada.code_name as geometriaaproximada, geom as geom, id_complexo_abast_agua as id_complexo_abast_agua [FROM] - cb.asb_area_abast_agua_a + cb.asb_area_abast_agua_a left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = asb_area_abast_agua_a.geometriaaproximada # DROP VIEW IF EXISTS views.tra_condutor_hidrico_l# -CREATE [VIEW] views.tra_condutor_hidrico_l as +CREATE [VIEW] views.tra_condutor_hidrico_l as SELECT id as id, nome as nome, @@ -1194,20 +1194,20 @@ CREATE [VIEW] views.tra_condutor_hidrico_l as dominio_tipocondutor.code_name as tipocondutor, id_complexo_gerad_energ_eletr as id_complexo_gerad_energ_eletr [FROM] - cb.tra_condutor_hidrico_l - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = tra_condutor_hidrico_l.geometriaaproximada - left join dominios.tipotrechoduto as dominio_tipotrechoduto on dominio_tipotrechoduto.code = tra_condutor_hidrico_l.tipotrechoduto - left join dominios.mattransp as dominio_mattransp on dominio_mattransp.code = tra_condutor_hidrico_l.mattransp - left join dominios.setor as dominio_setor on dominio_setor.code = tra_condutor_hidrico_l.setor - left join dominios.posicaorelativa as dominio_posicaorelativa on dominio_posicaorelativa.code = tra_condutor_hidrico_l.posicaorelativa - left join dominios.matconstr as dominio_matconstr on dominio_matconstr.code = tra_condutor_hidrico_l.matconstr - left join dominios.situacaoespacial as dominio_situacaoespacial on dominio_situacaoespacial.code = tra_condutor_hidrico_l.situacaoespacial - left join dominios.operacional as dominio_operacional on dominio_operacional.code = tra_condutor_hidrico_l.operacional - left join dominios.situacaofisica as dominio_situacaofisica on dominio_situacaofisica.code = tra_condutor_hidrico_l.situacaofisica + cb.tra_condutor_hidrico_l + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = tra_condutor_hidrico_l.geometriaaproximada + left join dominios.tipotrechoduto as dominio_tipotrechoduto on dominio_tipotrechoduto.code = tra_condutor_hidrico_l.tipotrechoduto + left join dominios.mattransp as dominio_mattransp on dominio_mattransp.code = tra_condutor_hidrico_l.mattransp + left join dominios.setor as dominio_setor on dominio_setor.code = tra_condutor_hidrico_l.setor + left join dominios.posicaorelativa as dominio_posicaorelativa on dominio_posicaorelativa.code = tra_condutor_hidrico_l.posicaorelativa + left join dominios.matconstr as dominio_matconstr on dominio_matconstr.code = tra_condutor_hidrico_l.matconstr + left join dominios.situacaoespacial as dominio_situacaoespacial on dominio_situacaoespacial.code = tra_condutor_hidrico_l.situacaoespacial + left join dominios.operacional as dominio_operacional on dominio_operacional.code = tra_condutor_hidrico_l.operacional + left join dominios.situacaofisica as dominio_situacaofisica on dominio_situacaofisica.code = tra_condutor_hidrico_l.situacaofisica left join dominios.tipocondutor as dominio_tipocondutor on dominio_tipocondutor.code = tra_condutor_hidrico_l.tipocondutor # DROP VIEW IF EXISTS views.asb_cemiterio_p# -CREATE [VIEW] views.asb_cemiterio_p as +CREATE [VIEW] views.asb_cemiterio_p as SELECT id as id, nome as nome, @@ -1217,13 +1217,13 @@ CREATE [VIEW] views.asb_cemiterio_p as dominio_denominacaoassociada.code_name as denominacaoassociada, geom as geom [FROM] - cb.asb_cemiterio_p - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = asb_cemiterio_p.geometriaaproximada - left join dominios.tipocemiterio as dominio_tipocemiterio on dominio_tipocemiterio.code = asb_cemiterio_p.tipocemiterio + cb.asb_cemiterio_p + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = asb_cemiterio_p.geometriaaproximada + left join dominios.tipocemiterio as dominio_tipocemiterio on dominio_tipocemiterio.code = asb_cemiterio_p.tipocemiterio left join dominios.denominacaoassociada as dominio_denominacaoassociada on dominio_denominacaoassociada.code = asb_cemiterio_p.denominacaoassociada # DROP VIEW IF EXISTS views.lim_outras_unid_protegidas_a# -CREATE [VIEW] views.lim_outras_unid_protegidas_a as +CREATE [VIEW] views.lim_outras_unid_protegidas_a as SELECT id as id, nome as nome, @@ -1237,61 +1237,61 @@ CREATE [VIEW] views.lim_outras_unid_protegidas_a as areaoficial as areaoficial, dominio_administracao.code_name as administracao [FROM] - cb.lim_outras_unid_protegidas_a - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = lim_outras_unid_protegidas_a.geometriaaproximada - left join dominios.tipooutunidprot as dominio_tipooutunidprot on dominio_tipooutunidprot.code = lim_outras_unid_protegidas_a.tipooutunidprot + cb.lim_outras_unid_protegidas_a + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = lim_outras_unid_protegidas_a.geometriaaproximada + left join dominios.tipooutunidprot as dominio_tipooutunidprot on dominio_tipooutunidprot.code = lim_outras_unid_protegidas_a.tipooutunidprot left join dominios.administracao as dominio_administracao on dominio_administracao.code = lim_outras_unid_protegidas_a.administracao # DROP VIEW IF EXISTS views.tra_ponto_hidroviario_p# -CREATE [VIEW] views.tra_ponto_hidroviario_p as +CREATE [VIEW] views.tra_ponto_hidroviario_p as SELECT id as id, dominio_geometriaaproximada.code_name as geometriaaproximada, dominio_relacionado.code_name as relacionado, geom as geom [FROM] - cb.tra_ponto_hidroviario_p - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = tra_ponto_hidroviario_p.geometriaaproximada + cb.tra_ponto_hidroviario_p + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = tra_ponto_hidroviario_p.geometriaaproximada left join dominios.relacionado_hdr as dominio_relacionado on dominio_relacionado.code = tra_ponto_hidroviario_p.relacionado # DROP VIEW IF EXISTS views.loc_descontinuidade_geometrica_l# -CREATE [VIEW] views.loc_descontinuidade_geometrica_l as +CREATE [VIEW] views.loc_descontinuidade_geometrica_l as SELECT id as id, dominio_geometriaaproximada.code_name as geometriaaproximada, dominio_motivodescontinuidade.code_name as motivodescontinuidade, geom as geom [FROM] - cb.loc_descontinuidade_geometrica_l - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = loc_descontinuidade_geometrica_l.geometriaaproximada + cb.loc_descontinuidade_geometrica_l + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = loc_descontinuidade_geometrica_l.geometriaaproximada left join dominios.motivodescontinuidade as dominio_motivodescontinuidade on dominio_motivodescontinuidade.code = loc_descontinuidade_geometrica_l.motivodescontinuidade # DROP VIEW IF EXISTS views.loc_descontinuidade_geometrica_a# -CREATE [VIEW] views.loc_descontinuidade_geometrica_a as +CREATE [VIEW] views.loc_descontinuidade_geometrica_a as SELECT id as id, dominio_geometriaaproximada.code_name as geometriaaproximada, dominio_motivodescontinuidade.code_name as motivodescontinuidade, geom as geom [FROM] - cb.loc_descontinuidade_geometrica_a - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = loc_descontinuidade_geometrica_a.geometriaaproximada + cb.loc_descontinuidade_geometrica_a + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = loc_descontinuidade_geometrica_a.geometriaaproximada left join dominios.motivodescontinuidade as dominio_motivodescontinuidade on dominio_motivodescontinuidade.code = loc_descontinuidade_geometrica_a.motivodescontinuidade # DROP VIEW IF EXISTS views.sau_descontinuidade_geometrica_p# -CREATE [VIEW] views.sau_descontinuidade_geometrica_p as +CREATE [VIEW] views.sau_descontinuidade_geometrica_p as SELECT id as id, dominio_geometriaaproximada.code_name as geometriaaproximada, dominio_motivodescontinuidade.code_name as motivodescontinuidade, geom as geom [FROM] - cb.sau_descontinuidade_geometrica_p - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = sau_descontinuidade_geometrica_p.geometriaaproximada + cb.sau_descontinuidade_geometrica_p + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = sau_descontinuidade_geometrica_p.geometriaaproximada left join dominios.motivodescontinuidade as dominio_motivodescontinuidade on dominio_motivodescontinuidade.code = sau_descontinuidade_geometrica_p.motivodescontinuidade # DROP VIEW IF EXISTS views.edu_coreto_tribuna_p# -CREATE [VIEW] views.edu_coreto_tribuna_p as +CREATE [VIEW] views.edu_coreto_tribuna_p as SELECT id as id, nome as nome, @@ -1302,13 +1302,13 @@ CREATE [VIEW] views.edu_coreto_tribuna_p as id_complexo_lazer as id_complexo_lazer, geom as geom [FROM] - cb.edu_coreto_tribuna_p - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = edu_coreto_tribuna_p.geometriaaproximada - left join dominios.operacional as dominio_operacional on dominio_operacional.code = edu_coreto_tribuna_p.operacional + cb.edu_coreto_tribuna_p + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = edu_coreto_tribuna_p.geometriaaproximada + left join dominios.operacional as dominio_operacional on dominio_operacional.code = edu_coreto_tribuna_p.operacional left join dominios.situacaofisica as dominio_situacaofisica on dominio_situacaofisica.code = edu_coreto_tribuna_p.situacaofisica # DROP VIEW IF EXISTS views.hid_banco_areia_l# -CREATE [VIEW] views.hid_banco_areia_l as +CREATE [VIEW] views.hid_banco_areia_l as SELECT id as id, nome as nome, @@ -1319,14 +1319,14 @@ CREATE [VIEW] views.hid_banco_areia_l as dominio_materialpredominante.code_name as materialpredominante, geom as geom [FROM] - cb.hid_banco_areia_l - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = hid_banco_areia_l.geometriaaproximada - left join dominios.tipobanco as dominio_tipobanco on dominio_tipobanco.code = hid_banco_areia_l.tipobanco - left join dominios.situacaoemagua as dominio_situacaoemagua on dominio_situacaoemagua.code = hid_banco_areia_l.situacaoemagua + cb.hid_banco_areia_l + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = hid_banco_areia_l.geometriaaproximada + left join dominios.tipobanco as dominio_tipobanco on dominio_tipobanco.code = hid_banco_areia_l.tipobanco + left join dominios.situacaoemagua as dominio_situacaoemagua on dominio_situacaoemagua.code = hid_banco_areia_l.situacaoemagua left join dominios.materialpredominante as dominio_materialpredominante on dominio_materialpredominante.code = hid_banco_areia_l.materialpredominante # DROP VIEW IF EXISTS views.hid_foz_maritima_p# -CREATE [VIEW] views.hid_foz_maritima_p as +CREATE [VIEW] views.hid_foz_maritima_p as SELECT id as id, nome as nome, @@ -1334,11 +1334,11 @@ CREATE [VIEW] views.hid_foz_maritima_p as dominio_geometriaaproximada.code_name as geometriaaproximada, geom as geom [FROM] - cb.hid_foz_maritima_p + cb.hid_foz_maritima_p left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = hid_foz_maritima_p.geometriaaproximada # DROP VIEW IF EXISTS views.tra_edif_rodoviaria_a# -CREATE [VIEW] views.tra_edif_rodoviaria_a as +CREATE [VIEW] views.tra_edif_rodoviaria_a as SELECT id as id, nome as nome, @@ -1352,16 +1352,16 @@ CREATE [VIEW] views.tra_edif_rodoviaria_a as dominio_administracao.code_name as administracao, id_estrut_apoio as id_estrut_apoio [FROM] - cb.tra_edif_rodoviaria_a - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = tra_edif_rodoviaria_a.geometriaaproximada - left join dominios.operacional as dominio_operacional on dominio_operacional.code = tra_edif_rodoviaria_a.operacional - left join dominios.situacaofisica as dominio_situacaofisica on dominio_situacaofisica.code = tra_edif_rodoviaria_a.situacaofisica - left join dominios.matconstr as dominio_matconstr on dominio_matconstr.code = tra_edif_rodoviaria_a.matconstr - left join dominios.tipoedifrod as dominio_tipoedifrod on dominio_tipoedifrod.code = tra_edif_rodoviaria_a.tipoedifrod + cb.tra_edif_rodoviaria_a + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = tra_edif_rodoviaria_a.geometriaaproximada + left join dominios.operacional as dominio_operacional on dominio_operacional.code = tra_edif_rodoviaria_a.operacional + left join dominios.situacaofisica as dominio_situacaofisica on dominio_situacaofisica.code = tra_edif_rodoviaria_a.situacaofisica + left join dominios.matconstr as dominio_matconstr on dominio_matconstr.code = tra_edif_rodoviaria_a.matconstr + left join dominios.tipoedifrod as dominio_tipoedifrod on dominio_tipoedifrod.code = tra_edif_rodoviaria_a.tipoedifrod left join dominios.administracao as dominio_administracao on dominio_administracao.code = tra_edif_rodoviaria_a.administracao # DROP VIEW IF EXISTS views.hid_terreno_suj_inundacao_a# -CREATE [VIEW] views.hid_terreno_suj_inundacao_a as +CREATE [VIEW] views.hid_terreno_suj_inundacao_a as SELECT id as id, nome as nome, @@ -1370,11 +1370,11 @@ CREATE [VIEW] views.hid_terreno_suj_inundacao_a as periodicidadeinunda as periodicidadeinunda, geom as geom [FROM] - cb.hid_terreno_suj_inundacao_a + cb.hid_terreno_suj_inundacao_a left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = hid_terreno_suj_inundacao_a.geometriaaproximada # DROP VIEW IF EXISTS views.hid_foz_maritima_l# -CREATE [VIEW] views.hid_foz_maritima_l as +CREATE [VIEW] views.hid_foz_maritima_l as SELECT id as id, nome as nome, @@ -1382,11 +1382,11 @@ CREATE [VIEW] views.hid_foz_maritima_l as dominio_geometriaaproximada.code_name as geometriaaproximada, geom as geom [FROM] - cb.hid_foz_maritima_l + cb.hid_foz_maritima_l left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = hid_foz_maritima_l.geometriaaproximada # DROP VIEW IF EXISTS views.veg_veg_restinga_a# -CREATE [VIEW] views.veg_veg_restinga_a as +CREATE [VIEW] views.veg_veg_restinga_a as SELECT id as id, nome as nome, @@ -1398,14 +1398,14 @@ CREATE [VIEW] views.veg_veg_restinga_a as alturamediaindividuos as alturamediaindividuos, dominio_classificacaoporte.code_name as classificacaoporte [FROM] - cb.veg_veg_restinga_a - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = veg_veg_restinga_a.geometriaaproximada - left join dominios.denso as dominio_denso on dominio_denso.code = veg_veg_restinga_a.denso - left join dominios.antropizada as dominio_antropizada on dominio_antropizada.code = veg_veg_restinga_a.antropizada + cb.veg_veg_restinga_a + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = veg_veg_restinga_a.geometriaaproximada + left join dominios.denso as dominio_denso on dominio_denso.code = veg_veg_restinga_a.denso + left join dominios.antropizada as dominio_antropizada on dominio_antropizada.code = veg_veg_restinga_a.antropizada left join dominios.classificacaoporte as dominio_classificacaoporte on dominio_classificacaoporte.code = veg_veg_restinga_a.classificacaoporte # DROP VIEW IF EXISTS views.lim_outras_unid_protegidas_p# -CREATE [VIEW] views.lim_outras_unid_protegidas_p as +CREATE [VIEW] views.lim_outras_unid_protegidas_p as SELECT id as id, nome as nome, @@ -1419,13 +1419,13 @@ CREATE [VIEW] views.lim_outras_unid_protegidas_p as areaoficial as areaoficial, dominio_administracao.code_name as administracao [FROM] - cb.lim_outras_unid_protegidas_p - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = lim_outras_unid_protegidas_p.geometriaaproximada - left join dominios.tipooutunidprot as dominio_tipooutunidprot on dominio_tipooutunidprot.code = lim_outras_unid_protegidas_p.tipooutunidprot + cb.lim_outras_unid_protegidas_p + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = lim_outras_unid_protegidas_p.geometriaaproximada + left join dominios.tipooutunidprot as dominio_tipooutunidprot on dominio_tipooutunidprot.code = lim_outras_unid_protegidas_p.tipooutunidprot left join dominios.administracao as dominio_administracao on dominio_administracao.code = lim_outras_unid_protegidas_p.administracao # DROP VIEW IF EXISTS views.asb_cemiterio_a# -CREATE [VIEW] views.asb_cemiterio_a as +CREATE [VIEW] views.asb_cemiterio_a as SELECT id as id, nome as nome, @@ -1435,13 +1435,13 @@ CREATE [VIEW] views.asb_cemiterio_a as dominio_denominacaoassociada.code_name as denominacaoassociada, geom as geom [FROM] - cb.asb_cemiterio_a - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = asb_cemiterio_a.geometriaaproximada - left join dominios.tipocemiterio as dominio_tipocemiterio on dominio_tipocemiterio.code = asb_cemiterio_a.tipocemiterio + cb.asb_cemiterio_a + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = asb_cemiterio_a.geometriaaproximada + left join dominios.tipocemiterio as dominio_tipocemiterio on dominio_tipocemiterio.code = asb_cemiterio_a.tipocemiterio left join dominios.denominacaoassociada as dominio_denominacaoassociada on dominio_denominacaoassociada.code = asb_cemiterio_a.denominacaoassociada # DROP VIEW IF EXISTS views.enc_edif_energia_p# -CREATE [VIEW] views.enc_edif_energia_p as +CREATE [VIEW] views.enc_edif_energia_p as SELECT id as id, nome as nome, @@ -1455,15 +1455,15 @@ CREATE [VIEW] views.enc_edif_energia_p as id_complexo_gerad_energ_eletr as id_complexo_gerad_energ_eletr, id_subestacao_ener_eletr as id_subestacao_ener_eletr [FROM] - cb.enc_edif_energia_p - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = enc_edif_energia_p.geometriaaproximada - left join dominios.operacional as dominio_operacional on dominio_operacional.code = enc_edif_energia_p.operacional - left join dominios.situacaofisica as dominio_situacaofisica on dominio_situacaofisica.code = enc_edif_energia_p.situacaofisica - left join dominios.matconstr as dominio_matconstr on dominio_matconstr.code = enc_edif_energia_p.matconstr + cb.enc_edif_energia_p + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = enc_edif_energia_p.geometriaaproximada + left join dominios.operacional as dominio_operacional on dominio_operacional.code = enc_edif_energia_p.operacional + left join dominios.situacaofisica as dominio_situacaofisica on dominio_situacaofisica.code = enc_edif_energia_p.situacaofisica + left join dominios.matconstr as dominio_matconstr on dominio_matconstr.code = enc_edif_energia_p.matconstr left join dominios.tipoedifenergia as dominio_tipoedifenergia on dominio_tipoedifenergia.code = enc_edif_energia_p.tipoedifenergia # DROP VIEW IF EXISTS views.tra_posto_combustivel_p# -CREATE [VIEW] views.tra_posto_combustivel_p as +CREATE [VIEW] views.tra_posto_combustivel_p as SELECT id as id, nome as nome, @@ -1476,15 +1476,15 @@ CREATE [VIEW] views.tra_posto_combustivel_p as id_estrut_transporte as id_estrut_transporte, geom as geom [FROM] - cb.tra_posto_combustivel_p - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = tra_posto_combustivel_p.geometriaaproximada - left join dominios.administracao as dominio_administracao on dominio_administracao.code = tra_posto_combustivel_p.administracao - left join dominios.operacional as dominio_operacional on dominio_operacional.code = tra_posto_combustivel_p.operacional - left join dominios.situacaofisica as dominio_situacaofisica on dominio_situacaofisica.code = tra_posto_combustivel_p.situacaofisica + cb.tra_posto_combustivel_p + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = tra_posto_combustivel_p.geometriaaproximada + left join dominios.administracao as dominio_administracao on dominio_administracao.code = tra_posto_combustivel_p.administracao + left join dominios.operacional as dominio_operacional on dominio_operacional.code = tra_posto_combustivel_p.operacional + left join dominios.situacaofisica as dominio_situacaofisica on dominio_situacaofisica.code = tra_posto_combustivel_p.situacaofisica left join dominios.matconstr as dominio_matconstr on dominio_matconstr.code = tra_posto_combustivel_p.matconstr # DROP VIEW IF EXISTS views.pto_pto_est_med_fenomenos_p# -CREATE [VIEW] views.pto_pto_est_med_fenomenos_p as +CREATE [VIEW] views.pto_pto_est_med_fenomenos_p as SELECT id as id, nome as nome, @@ -1495,12 +1495,12 @@ CREATE [VIEW] views.pto_pto_est_med_fenomenos_p as id_est_med_fenomenos as id_est_med_fenomenos, geom as geom [FROM] - cb.pto_pto_est_med_fenomenos_p - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = pto_pto_est_med_fenomenos_p.geometriaaproximada + cb.pto_pto_est_med_fenomenos_p + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = pto_pto_est_med_fenomenos_p.geometriaaproximada left join dominios.tipoptoestmed as dominio_tipoptoestmed on dominio_tipoptoestmed.code = pto_pto_est_med_fenomenos_p.tipoptoestmed # DROP VIEW IF EXISTS views.hid_comporta_p# -CREATE [VIEW] views.hid_comporta_p as +CREATE [VIEW] views.hid_comporta_p as SELECT id as id, nome as nome, @@ -1510,13 +1510,13 @@ CREATE [VIEW] views.hid_comporta_p as dominio_situacaofisica.code_name as situacaofisica, geom as geom [FROM] - cb.hid_comporta_p - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = hid_comporta_p.geometriaaproximada - left join dominios.operacional as dominio_operacional on dominio_operacional.code = hid_comporta_p.operacional + cb.hid_comporta_p + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = hid_comporta_p.geometriaaproximada + left join dominios.operacional as dominio_operacional on dominio_operacional.code = hid_comporta_p.operacional left join dominios.situacaofisica as dominio_situacaofisica on dominio_situacaofisica.code = hid_comporta_p.situacaofisica # DROP VIEW IF EXISTS views.hid_corredeira_p# -CREATE [VIEW] views.hid_corredeira_p as +CREATE [VIEW] views.hid_corredeira_p as SELECT id as id, nome as nome, @@ -1524,11 +1524,11 @@ CREATE [VIEW] views.hid_corredeira_p as dominio_geometriaaproximada.code_name as geometriaaproximada, geom as geom [FROM] - cb.hid_corredeira_p + cb.hid_corredeira_p left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = hid_corredeira_p.geometriaaproximada # DROP VIEW IF EXISTS views.tra_faixa_seguranca_a# -CREATE [VIEW] views.tra_faixa_seguranca_a as +CREATE [VIEW] views.tra_faixa_seguranca_a as SELECT id as id, dominio_geometriaaproximada.code_name as geometriaaproximada, @@ -1536,11 +1536,11 @@ CREATE [VIEW] views.tra_faixa_seguranca_a as extensao as extensao, geom as geom [FROM] - cb.tra_faixa_seguranca_a + cb.tra_faixa_seguranca_a left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = tra_faixa_seguranca_a.geometriaaproximada # DROP VIEW IF EXISTS views.edu_edif_ensino_a# -CREATE [VIEW] views.edu_edif_ensino_a as +CREATE [VIEW] views.edu_edif_ensino_a as SELECT id as id, nome as nome, @@ -1553,27 +1553,27 @@ CREATE [VIEW] views.edu_edif_ensino_a as dominio_tipoclassecnae.code_name as tipoclassecnae, id_org_ensino as id_org_ensino [FROM] - cb.edu_edif_ensino_a - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = edu_edif_ensino_a.geometriaaproximada - left join dominios.operacional as dominio_operacional on dominio_operacional.code = edu_edif_ensino_a.operacional - left join dominios.situacaofisica as dominio_situacaofisica on dominio_situacaofisica.code = edu_edif_ensino_a.situacaofisica - left join dominios.matconstr as dominio_matconstr on dominio_matconstr.code = edu_edif_ensino_a.matconstr + cb.edu_edif_ensino_a + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = edu_edif_ensino_a.geometriaaproximada + left join dominios.operacional as dominio_operacional on dominio_operacional.code = edu_edif_ensino_a.operacional + left join dominios.situacaofisica as dominio_situacaofisica on dominio_situacaofisica.code = edu_edif_ensino_a.situacaofisica + left join dominios.matconstr as dominio_matconstr on dominio_matconstr.code = edu_edif_ensino_a.matconstr left join dominios.tipoclassecnae as dominio_tipoclassecnae on dominio_tipoclassecnae.code = edu_edif_ensino_a.tipoclassecnae # DROP VIEW IF EXISTS views.veg_descontinuidade_geometrica_p# -CREATE [VIEW] views.veg_descontinuidade_geometrica_p as +CREATE [VIEW] views.veg_descontinuidade_geometrica_p as SELECT id as id, dominio_geometriaaproximada.code_name as geometriaaproximada, dominio_motivodescontinuidade.code_name as motivodescontinuidade, geom as geom [FROM] - cb.veg_descontinuidade_geometrica_p - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = veg_descontinuidade_geometrica_p.geometriaaproximada + cb.veg_descontinuidade_geometrica_p + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = veg_descontinuidade_geometrica_p.geometriaaproximada left join dominios.motivodescontinuidade as dominio_motivodescontinuidade on dominio_motivodescontinuidade.code = veg_descontinuidade_geometrica_p.motivodescontinuidade # DROP VIEW IF EXISTS views.lim_area_uso_comunitario_p# -CREATE [VIEW] views.lim_area_uso_comunitario_p as +CREATE [VIEW] views.lim_area_uso_comunitario_p as SELECT id as id, nome as nome, @@ -1582,12 +1582,12 @@ CREATE [VIEW] views.lim_area_uso_comunitario_p as geom as geom, dominio_tipoareausocomun.code_name as tipoareausocomun [FROM] - cb.lim_area_uso_comunitario_p - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = lim_area_uso_comunitario_p.geometriaaproximada + cb.lim_area_uso_comunitario_p + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = lim_area_uso_comunitario_p.geometriaaproximada left join dominios.tipoareausocomun as dominio_tipoareausocomun on dominio_tipoareausocomun.code = lim_area_uso_comunitario_p.tipoareausocomun # DROP VIEW IF EXISTS views.tra_ciclovia_l# -CREATE [VIEW] views.tra_ciclovia_l as +CREATE [VIEW] views.tra_ciclovia_l as SELECT id as id, nome as nome, @@ -1600,16 +1600,16 @@ CREATE [VIEW] views.tra_ciclovia_l as dominio_trafego.code_name as trafego, geom as geom [FROM] - cb.tra_ciclovia_l - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = tra_ciclovia_l.geometriaaproximada - left join dominios.administracao as dominio_administracao on dominio_administracao.code = tra_ciclovia_l.administracao - left join dominios.revestimento as dominio_revestimento on dominio_revestimento.code = tra_ciclovia_l.revestimento - left join dominios.operacional as dominio_operacional on dominio_operacional.code = tra_ciclovia_l.operacional - left join dominios.situacaofisica as dominio_situacaofisica on dominio_situacaofisica.code = tra_ciclovia_l.situacaofisica + cb.tra_ciclovia_l + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = tra_ciclovia_l.geometriaaproximada + left join dominios.administracao as dominio_administracao on dominio_administracao.code = tra_ciclovia_l.administracao + left join dominios.revestimento as dominio_revestimento on dominio_revestimento.code = tra_ciclovia_l.revestimento + left join dominios.operacional as dominio_operacional on dominio_operacional.code = tra_ciclovia_l.operacional + left join dominios.situacaofisica as dominio_situacaofisica on dominio_situacaofisica.code = tra_ciclovia_l.situacaofisica left join dominios.trafego as dominio_trafego on dominio_trafego.code = tra_ciclovia_l.trafego # DROP VIEW IF EXISTS views.enc_hidreletrica_p# -CREATE [VIEW] views.enc_hidreletrica_p as +CREATE [VIEW] views.enc_hidreletrica_p as SELECT id as id, nome as nome, @@ -1626,15 +1626,15 @@ CREATE [VIEW] views.enc_hidreletrica_p as geom as geom, codigohidreletrica as codigohidreletrica [FROM] - cb.enc_hidreletrica_p - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = enc_hidreletrica_p.geometriaaproximada - left join dominios.tipoestgerad as dominio_tipoestgerad on dominio_tipoestgerad.code = enc_hidreletrica_p.tipoestgerad - left join dominios.operacional as dominio_operacional on dominio_operacional.code = enc_hidreletrica_p.operacional - left join dominios.situacaofisica as dominio_situacaofisica on dominio_situacaofisica.code = enc_hidreletrica_p.situacaofisica + cb.enc_hidreletrica_p + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = enc_hidreletrica_p.geometriaaproximada + left join dominios.tipoestgerad as dominio_tipoestgerad on dominio_tipoestgerad.code = enc_hidreletrica_p.tipoestgerad + left join dominios.operacional as dominio_operacional on dominio_operacional.code = enc_hidreletrica_p.operacional + left join dominios.situacaofisica as dominio_situacaofisica on dominio_situacaofisica.code = enc_hidreletrica_p.situacaofisica left join dominios.destenergelet as dominio_destenergelet on dominio_destenergelet.code = enc_hidreletrica_p.destenergelet # DROP VIEW IF EXISTS views.hid_corredeira_a# -CREATE [VIEW] views.hid_corredeira_a as +CREATE [VIEW] views.hid_corredeira_a as SELECT id as id, nome as nome, @@ -1642,11 +1642,11 @@ CREATE [VIEW] views.hid_corredeira_a as dominio_geometriaaproximada.code_name as geometriaaproximada, geom as geom [FROM] - cb.hid_corredeira_a + cb.hid_corredeira_a left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = hid_corredeira_a.geometriaaproximada # DROP VIEW IF EXISTS views.edu_coreto_tribuna_a# -CREATE [VIEW] views.edu_coreto_tribuna_a as +CREATE [VIEW] views.edu_coreto_tribuna_a as SELECT id as id, nome as nome, @@ -1657,13 +1657,13 @@ CREATE [VIEW] views.edu_coreto_tribuna_a as id_complexo_lazer as id_complexo_lazer, geom as geom [FROM] - cb.edu_coreto_tribuna_a - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = edu_coreto_tribuna_a.geometriaaproximada - left join dominios.operacional as dominio_operacional on dominio_operacional.code = edu_coreto_tribuna_a.operacional + cb.edu_coreto_tribuna_a + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = edu_coreto_tribuna_a.geometriaaproximada + left join dominios.operacional as dominio_operacional on dominio_operacional.code = edu_coreto_tribuna_a.operacional left join dominios.situacaofisica as dominio_situacaofisica on dominio_situacaofisica.code = edu_coreto_tribuna_a.situacaofisica # DROP VIEW IF EXISTS views.edu_edif_ensino_p# -CREATE [VIEW] views.edu_edif_ensino_p as +CREATE [VIEW] views.edu_edif_ensino_p as SELECT id as id, nome as nome, @@ -1676,15 +1676,15 @@ CREATE [VIEW] views.edu_edif_ensino_p as dominio_tipoclassecnae.code_name as tipoclassecnae, id_org_ensino as id_org_ensino [FROM] - cb.edu_edif_ensino_p - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = edu_edif_ensino_p.geometriaaproximada - left join dominios.operacional as dominio_operacional on dominio_operacional.code = edu_edif_ensino_p.operacional - left join dominios.situacaofisica as dominio_situacaofisica on dominio_situacaofisica.code = edu_edif_ensino_p.situacaofisica - left join dominios.matconstr as dominio_matconstr on dominio_matconstr.code = edu_edif_ensino_p.matconstr + cb.edu_edif_ensino_p + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = edu_edif_ensino_p.geometriaaproximada + left join dominios.operacional as dominio_operacional on dominio_operacional.code = edu_edif_ensino_p.operacional + left join dominios.situacaofisica as dominio_situacaofisica on dominio_situacaofisica.code = edu_edif_ensino_p.situacaofisica + left join dominios.matconstr as dominio_matconstr on dominio_matconstr.code = edu_edif_ensino_p.matconstr left join dominios.tipoclassecnae as dominio_tipoclassecnae on dominio_tipoclassecnae.code = edu_edif_ensino_p.tipoclassecnae # DROP VIEW IF EXISTS views.tra_posto_combustivel_a# -CREATE [VIEW] views.tra_posto_combustivel_a as +CREATE [VIEW] views.tra_posto_combustivel_a as SELECT id as id, nome as nome, @@ -1697,39 +1697,39 @@ CREATE [VIEW] views.tra_posto_combustivel_a as id_estrut_transporte as id_estrut_transporte, geom as geom [FROM] - cb.tra_posto_combustivel_a - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = tra_posto_combustivel_a.geometriaaproximada - left join dominios.administracao as dominio_administracao on dominio_administracao.code = tra_posto_combustivel_a.administracao - left join dominios.operacional as dominio_operacional on dominio_operacional.code = tra_posto_combustivel_a.operacional - left join dominios.situacaofisica as dominio_situacaofisica on dominio_situacaofisica.code = tra_posto_combustivel_a.situacaofisica + cb.tra_posto_combustivel_a + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = tra_posto_combustivel_a.geometriaaproximada + left join dominios.administracao as dominio_administracao on dominio_administracao.code = tra_posto_combustivel_a.administracao + left join dominios.operacional as dominio_operacional on dominio_operacional.code = tra_posto_combustivel_a.operacional + left join dominios.situacaofisica as dominio_situacaofisica on dominio_situacaofisica.code = tra_posto_combustivel_a.situacaofisica left join dominios.matconstr as dominio_matconstr on dominio_matconstr.code = tra_posto_combustivel_a.matconstr # DROP VIEW IF EXISTS views.enc_ponto_trecho_energia_p# -CREATE [VIEW] views.enc_ponto_trecho_energia_p as +CREATE [VIEW] views.enc_ponto_trecho_energia_p as SELECT id as id, dominio_geometriaaproximada.code_name as geometriaaproximada, dominio_tipoptoenergia.code_name as tipoptoenergia, geom as geom [FROM] - cb.enc_ponto_trecho_energia_p - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = enc_ponto_trecho_energia_p.geometriaaproximada + cb.enc_ponto_trecho_energia_p + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = enc_ponto_trecho_energia_p.geometriaaproximada left join dominios.tipoptoenergia as dominio_tipoptoenergia on dominio_tipoptoenergia.code = enc_ponto_trecho_energia_p.tipoptoenergia # DROP VIEW IF EXISTS views.hid_descontinuidade_geometrica_l# -CREATE [VIEW] views.hid_descontinuidade_geometrica_l as +CREATE [VIEW] views.hid_descontinuidade_geometrica_l as SELECT id as id, dominio_geometriaaproximada.code_name as geometriaaproximada, dominio_motivodescontinuidade.code_name as motivodescontinuidade, geom as geom [FROM] - cb.hid_descontinuidade_geometrica_l - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = hid_descontinuidade_geometrica_l.geometriaaproximada + cb.hid_descontinuidade_geometrica_l + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = hid_descontinuidade_geometrica_l.geometriaaproximada left join dominios.motivodescontinuidade as dominio_motivodescontinuidade on dominio_motivodescontinuidade.code = hid_descontinuidade_geometrica_l.motivodescontinuidade # DROP VIEW IF EXISTS views.hid_trecho_massa_dagua_a# -CREATE [VIEW] views.hid_trecho_massa_dagua_a as +CREATE [VIEW] views.hid_trecho_massa_dagua_a as SELECT id as id, nome as nome, @@ -1740,25 +1740,25 @@ CREATE [VIEW] views.hid_trecho_massa_dagua_a as id_trecho_curso_dagua as id_trecho_curso_dagua, geom as geom [FROM] - cb.hid_trecho_massa_dagua_a - left join dominios.tipotrechomassa as dominio_tipotrechomassa on dominio_tipotrechomassa.code = hid_trecho_massa_dagua_a.tipotrechomassa - left join dominios.regime as dominio_regime on dominio_regime.code = hid_trecho_massa_dagua_a.regime + cb.hid_trecho_massa_dagua_a + left join dominios.tipotrechomassa as dominio_tipotrechomassa on dominio_tipotrechomassa.code = hid_trecho_massa_dagua_a.tipotrechomassa + left join dominios.regime as dominio_regime on dominio_regime.code = hid_trecho_massa_dagua_a.regime left join dominios.salinidade as dominio_salinidade on dominio_salinidade.code = hid_trecho_massa_dagua_a.salinidade # DROP VIEW IF EXISTS views.veg_descontinuidade_geometrica_l# -CREATE [VIEW] views.veg_descontinuidade_geometrica_l as +CREATE [VIEW] views.veg_descontinuidade_geometrica_l as SELECT id as id, dominio_geometriaaproximada.code_name as geometriaaproximada, dominio_motivodescontinuidade.code_name as motivodescontinuidade, geom as geom [FROM] - cb.veg_descontinuidade_geometrica_l - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = veg_descontinuidade_geometrica_l.geometriaaproximada + cb.veg_descontinuidade_geometrica_l + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = veg_descontinuidade_geometrica_l.geometriaaproximada left join dominios.motivodescontinuidade as dominio_motivodescontinuidade on dominio_motivodescontinuidade.code = veg_descontinuidade_geometrica_l.motivodescontinuidade # DROP VIEW IF EXISTS views.enc_edif_energia_a# -CREATE [VIEW] views.enc_edif_energia_a as +CREATE [VIEW] views.enc_edif_energia_a as SELECT id as id, nome as nome, @@ -1772,15 +1772,15 @@ CREATE [VIEW] views.enc_edif_energia_a as id_complexo_gerad_energ_eletr as id_complexo_gerad_energ_eletr, id_subestacao_ener_eletr as id_subestacao_ener_eletr [FROM] - cb.enc_edif_energia_a - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = enc_edif_energia_a.geometriaaproximada - left join dominios.operacional as dominio_operacional on dominio_operacional.code = enc_edif_energia_a.operacional - left join dominios.situacaofisica as dominio_situacaofisica on dominio_situacaofisica.code = enc_edif_energia_a.situacaofisica - left join dominios.matconstr as dominio_matconstr on dominio_matconstr.code = enc_edif_energia_a.matconstr + cb.enc_edif_energia_a + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = enc_edif_energia_a.geometriaaproximada + left join dominios.operacional as dominio_operacional on dominio_operacional.code = enc_edif_energia_a.operacional + left join dominios.situacaofisica as dominio_situacaofisica on dominio_situacaofisica.code = enc_edif_energia_a.situacaofisica + left join dominios.matconstr as dominio_matconstr on dominio_matconstr.code = enc_edif_energia_a.matconstr left join dominios.tipoedifenergia as dominio_tipoedifenergia on dominio_tipoedifenergia.code = enc_edif_energia_a.tipoedifenergia # DROP VIEW IF EXISTS views.hid_comporta_l# -CREATE [VIEW] views.hid_comporta_l as +CREATE [VIEW] views.hid_comporta_l as SELECT id as id, nome as nome, @@ -1790,13 +1790,13 @@ CREATE [VIEW] views.hid_comporta_l as dominio_situacaofisica.code_name as situacaofisica, geom as geom [FROM] - cb.hid_comporta_l - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = hid_comporta_l.geometriaaproximada - left join dominios.operacional as dominio_operacional on dominio_operacional.code = hid_comporta_l.operacional + cb.hid_comporta_l + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = hid_comporta_l.geometriaaproximada + left join dominios.operacional as dominio_operacional on dominio_operacional.code = hid_comporta_l.operacional left join dominios.situacaofisica as dominio_situacaofisica on dominio_situacaofisica.code = hid_comporta_l.situacaofisica # DROP VIEW IF EXISTS views.hid_corredeira_l# -CREATE [VIEW] views.hid_corredeira_l as +CREATE [VIEW] views.hid_corredeira_l as SELECT id as id, nome as nome, @@ -1804,23 +1804,23 @@ CREATE [VIEW] views.hid_corredeira_l as dominio_geometriaaproximada.code_name as geometriaaproximada, geom as geom [FROM] - cb.hid_corredeira_l + cb.hid_corredeira_l left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = hid_corredeira_l.geometriaaproximada # DROP VIEW IF EXISTS views.adm_descontinuidade_geometrica_p# -CREATE [VIEW] views.adm_descontinuidade_geometrica_p as +CREATE [VIEW] views.adm_descontinuidade_geometrica_p as SELECT id as id, dominio_geometriaaproximada.code_name as geometriaaproximada, dominio_motivodescontinuidade.code_name as motivodescontinuidade, geom as geom [FROM] - cb.adm_descontinuidade_geometrica_p - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = adm_descontinuidade_geometrica_p.geometriaaproximada + cb.adm_descontinuidade_geometrica_p + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = adm_descontinuidade_geometrica_p.geometriaaproximada left join dominios.motivodescontinuidade as dominio_motivodescontinuidade on dominio_motivodescontinuidade.code = adm_descontinuidade_geometrica_p.motivodescontinuidade # DROP VIEW IF EXISTS views.lim_area_desenv_controle_a# -CREATE [VIEW] views.lim_area_desenv_controle_a as +CREATE [VIEW] views.lim_area_desenv_controle_a as SELECT id as id, nome as nome, @@ -1829,11 +1829,11 @@ CREATE [VIEW] views.lim_area_desenv_controle_a as geom as geom, classificacao as classificacao [FROM] - cb.lim_area_desenv_controle_a + cb.lim_area_desenv_controle_a left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = lim_area_desenv_controle_a.geometriaaproximada # DROP VIEW IF EXISTS views.tra_sinalizacao_p# -CREATE [VIEW] views.tra_sinalizacao_p as +CREATE [VIEW] views.tra_sinalizacao_p as SELECT id as id, nome as nome, @@ -1844,14 +1844,14 @@ CREATE [VIEW] views.tra_sinalizacao_p as dominio_situacaofisica.code_name as situacaofisica, geom as geom [FROM] - cb.tra_sinalizacao_p - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = tra_sinalizacao_p.geometriaaproximada - left join dominios.tiposinal as dominio_tiposinal on dominio_tiposinal.code = tra_sinalizacao_p.tiposinal - left join dominios.operacional as dominio_operacional on dominio_operacional.code = tra_sinalizacao_p.operacional + cb.tra_sinalizacao_p + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = tra_sinalizacao_p.geometriaaproximada + left join dominios.tiposinal as dominio_tiposinal on dominio_tiposinal.code = tra_sinalizacao_p.tiposinal + left join dominios.operacional as dominio_operacional on dominio_operacional.code = tra_sinalizacao_p.operacional left join dominios.situacaofisica as dominio_situacaofisica on dominio_situacaofisica.code = tra_sinalizacao_p.situacaofisica # DROP VIEW IF EXISTS views.lim_limite_intra_munic_adm_l# -CREATE [VIEW] views.lim_limite_intra_munic_adm_l as +CREATE [VIEW] views.lim_limite_intra_munic_adm_l as SELECT id as id, nome as nome, @@ -1863,24 +1863,24 @@ CREATE [VIEW] views.lim_limite_intra_munic_adm_l as dominio_tipolimintramun.code_name as tipolimintramun, obssituacao as obssituacao [FROM] - cb.lim_limite_intra_munic_adm_l - left join dominios.coincidecomdentrode_lim as dominio_coincidecomdentrode on dominio_coincidecomdentrode.code = lim_limite_intra_munic_adm_l.coincidecomdentrode - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = lim_limite_intra_munic_adm_l.geometriaaproximada + cb.lim_limite_intra_munic_adm_l + left join dominios.coincidecomdentrode_lim as dominio_coincidecomdentrode on dominio_coincidecomdentrode.code = lim_limite_intra_munic_adm_l.coincidecomdentrode + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = lim_limite_intra_munic_adm_l.geometriaaproximada left join dominios.tipolimintramun as dominio_tipolimintramun on dominio_tipolimintramun.code = lim_limite_intra_munic_adm_l.tipolimintramun # DROP VIEW IF EXISTS views.edu_area_ensino_a# -CREATE [VIEW] views.edu_area_ensino_a as +CREATE [VIEW] views.edu_area_ensino_a as SELECT id as id, dominio_geometriaaproximada.code_name as geometriaaproximada, geom as geom, id_org_ensino as id_org_ensino [FROM] - cb.edu_area_ensino_a + cb.edu_area_ensino_a left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = edu_area_ensino_a.geometriaaproximada # DROP VIEW IF EXISTS views.adm_posto_fiscal_a# -CREATE [VIEW] views.adm_posto_fiscal_a as +CREATE [VIEW] views.adm_posto_fiscal_a as SELECT id as id, nome as nome, @@ -1892,14 +1892,14 @@ CREATE [VIEW] views.adm_posto_fiscal_a as id_org_pub_civil as id_org_pub_civil, geom as geom [FROM] - cb.adm_posto_fiscal_a - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = adm_posto_fiscal_a.geometriaaproximada - left join dominios.operacional as dominio_operacional on dominio_operacional.code = adm_posto_fiscal_a.operacional - left join dominios.situacaofisica as dominio_situacaofisica on dominio_situacaofisica.code = adm_posto_fiscal_a.situacaofisica + cb.adm_posto_fiscal_a + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = adm_posto_fiscal_a.geometriaaproximada + left join dominios.operacional as dominio_operacional on dominio_operacional.code = adm_posto_fiscal_a.operacional + left join dominios.situacaofisica as dominio_situacaofisica on dominio_situacaofisica.code = adm_posto_fiscal_a.situacaofisica left join dominios.tipopostofisc as dominio_tipopostofisc on dominio_tipopostofisc.code = adm_posto_fiscal_a.tipopostofisc # DROP VIEW IF EXISTS views.rel_dolina_p# -CREATE [VIEW] views.rel_dolina_p as +CREATE [VIEW] views.rel_dolina_p as SELECT id as id, nome as nome, @@ -1908,12 +1908,12 @@ CREATE [VIEW] views.rel_dolina_p as dominio_tipoelemnat.code_name as tipoelemnat, geom as geom [FROM] - cb.rel_dolina_p - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = rel_dolina_p.geometriaaproximada + cb.rel_dolina_p + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = rel_dolina_p.geometriaaproximada left join dominios.tipoelemnat as dominio_tipoelemnat on dominio_tipoelemnat.code = rel_dolina_p.tipoelemnat # DROP VIEW IF EXISTS views.tra_travessia_pedestre_l# -CREATE [VIEW] views.tra_travessia_pedestre_l as +CREATE [VIEW] views.tra_travessia_pedestre_l as SELECT id as id, nome as nome, @@ -1927,15 +1927,15 @@ CREATE [VIEW] views.tra_travessia_pedestre_l as extensao as extensao, geom as geom [FROM] - cb.tra_travessia_pedestre_l - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = tra_travessia_pedestre_l.geometriaaproximada - left join dominios.tipotravessiaped as dominio_tipotravessiaped on dominio_tipotravessiaped.code = tra_travessia_pedestre_l.tipotravessiaped - left join dominios.matconstr as dominio_matconstr on dominio_matconstr.code = tra_travessia_pedestre_l.matconstr - left join dominios.operacional as dominio_operacional on dominio_operacional.code = tra_travessia_pedestre_l.operacional + cb.tra_travessia_pedestre_l + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = tra_travessia_pedestre_l.geometriaaproximada + left join dominios.tipotravessiaped as dominio_tipotravessiaped on dominio_tipotravessiaped.code = tra_travessia_pedestre_l.tipotravessiaped + left join dominios.matconstr as dominio_matconstr on dominio_matconstr.code = tra_travessia_pedestre_l.matconstr + left join dominios.operacional as dominio_operacional on dominio_operacional.code = tra_travessia_pedestre_l.operacional left join dominios.situacaofisica as dominio_situacaofisica on dominio_situacaofisica.code = tra_travessia_pedestre_l.situacaofisica # DROP VIEW IF EXISTS views.hid_trecho_drenagem_l# -CREATE [VIEW] views.hid_trecho_drenagem_l as +CREATE [VIEW] views.hid_trecho_drenagem_l as SELECT id as id, nome as nome, @@ -1954,17 +1954,17 @@ CREATE [VIEW] views.hid_trecho_drenagem_l as id_trecho_curso_dagua as id_trecho_curso_dagua, geom as geom [FROM] - cb.hid_trecho_drenagem_l - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = hid_trecho_drenagem_l.geometriaaproximada - left join dominios.coincidecomdentrode_hid as dominio_coincidecomdentrode on dominio_coincidecomdentrode.code = hid_trecho_drenagem_l.coincidecomdentrode - left join dominios.dentrodepoligono as dominio_dentrodepoligono on dominio_dentrodepoligono.code = hid_trecho_drenagem_l.dentrodepoligono - left join dominios.compartilhado as dominio_compartilhado on dominio_compartilhado.code = hid_trecho_drenagem_l.compartilhado - left join dominios.eixoprincipal as dominio_eixoprincipal on dominio_eixoprincipal.code = hid_trecho_drenagem_l.eixoprincipal - left join dominios.navegabilidade as dominio_navegabilidade on dominio_navegabilidade.code = hid_trecho_drenagem_l.navegabilidade + cb.hid_trecho_drenagem_l + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = hid_trecho_drenagem_l.geometriaaproximada + left join dominios.coincidecomdentrode_hid as dominio_coincidecomdentrode on dominio_coincidecomdentrode.code = hid_trecho_drenagem_l.coincidecomdentrode + left join dominios.dentrodepoligono as dominio_dentrodepoligono on dominio_dentrodepoligono.code = hid_trecho_drenagem_l.dentrodepoligono + left join dominios.compartilhado as dominio_compartilhado on dominio_compartilhado.code = hid_trecho_drenagem_l.compartilhado + left join dominios.eixoprincipal as dominio_eixoprincipal on dominio_eixoprincipal.code = hid_trecho_drenagem_l.eixoprincipal + left join dominios.navegabilidade as dominio_navegabilidade on dominio_navegabilidade.code = hid_trecho_drenagem_l.navegabilidade left join dominios.regime as dominio_regime on dominio_regime.code = hid_trecho_drenagem_l.regime # DROP VIEW IF EXISTS views.lim_unidade_conserv_nao_snuc_a# -CREATE [VIEW] views.lim_unidade_conserv_nao_snuc_a as +CREATE [VIEW] views.lim_unidade_conserv_nao_snuc_a as SELECT id as id, nome as nome, @@ -1978,12 +1978,12 @@ CREATE [VIEW] views.lim_unidade_conserv_nao_snuc_a as sigla as sigla, areaoficial as areaoficial [FROM] - cb.lim_unidade_conserv_nao_snuc_a - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = lim_unidade_conserv_nao_snuc_a.geometriaaproximada + cb.lim_unidade_conserv_nao_snuc_a + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = lim_unidade_conserv_nao_snuc_a.geometriaaproximada left join dominios.administracao as dominio_administracao on dominio_administracao.code = lim_unidade_conserv_nao_snuc_a.administracao # DROP VIEW IF EXISTS views.lim_area_especial_a# -CREATE [VIEW] views.lim_area_especial_a as +CREATE [VIEW] views.lim_area_especial_a as SELECT id as id, nome as nome, @@ -1991,23 +1991,23 @@ CREATE [VIEW] views.lim_area_especial_a as dominio_geometriaaproximada.code_name as geometriaaproximada, geom as geom [FROM] - cb.lim_area_especial_a + cb.lim_area_especial_a left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = lim_area_especial_a.geometriaaproximada # DROP VIEW IF EXISTS views.adm_descontinuidade_geometrica_a# -CREATE [VIEW] views.adm_descontinuidade_geometrica_a as +CREATE [VIEW] views.adm_descontinuidade_geometrica_a as SELECT id as id, dominio_geometriaaproximada.code_name as geometriaaproximada, dominio_motivodescontinuidade.code_name as motivodescontinuidade, geom as geom [FROM] - cb.adm_descontinuidade_geometrica_a - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = adm_descontinuidade_geometrica_a.geometriaaproximada + cb.adm_descontinuidade_geometrica_a + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = adm_descontinuidade_geometrica_a.geometriaaproximada left join dominios.motivodescontinuidade as dominio_motivodescontinuidade on dominio_motivodescontinuidade.code = adm_descontinuidade_geometrica_a.motivodescontinuidade # DROP VIEW IF EXISTS views.loc_edif_habitacional_a# -CREATE [VIEW] views.loc_edif_habitacional_a as +CREATE [VIEW] views.loc_edif_habitacional_a as SELECT id as id, nome as nome, @@ -2019,14 +2019,14 @@ CREATE [VIEW] views.loc_edif_habitacional_a as geom as geom, id_complexo_habitacional as id_complexo_habitacional [FROM] - cb.loc_edif_habitacional_a - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = loc_edif_habitacional_a.geometriaaproximada - left join dominios.operacional as dominio_operacional on dominio_operacional.code = loc_edif_habitacional_a.operacional - left join dominios.situacaofisica as dominio_situacaofisica on dominio_situacaofisica.code = loc_edif_habitacional_a.situacaofisica + cb.loc_edif_habitacional_a + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = loc_edif_habitacional_a.geometriaaproximada + left join dominios.operacional as dominio_operacional on dominio_operacional.code = loc_edif_habitacional_a.operacional + left join dominios.situacaofisica as dominio_situacaofisica on dominio_situacaofisica.code = loc_edif_habitacional_a.situacaofisica left join dominios.matconstr as dominio_matconstr on dominio_matconstr.code = loc_edif_habitacional_a.matconstr # DROP VIEW IF EXISTS views.loc_aglom_rural_de_ext_urbana_p# -CREATE [VIEW] views.loc_aglom_rural_de_ext_urbana_p as +CREATE [VIEW] views.loc_aglom_rural_de_ext_urbana_p as SELECT id as id, nome as nome, @@ -2040,11 +2040,11 @@ CREATE [VIEW] views.loc_aglom_rural_de_ext_urbana_p as longitude_gms as longitude_gms, geom as geom [FROM] - cb.loc_aglom_rural_de_ext_urbana_p + cb.loc_aglom_rural_de_ext_urbana_p left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = loc_aglom_rural_de_ext_urbana_p.geometriaaproximada # DROP VIEW IF EXISTS views.adm_posto_fiscal_p# -CREATE [VIEW] views.adm_posto_fiscal_p as +CREATE [VIEW] views.adm_posto_fiscal_p as SELECT id as id, nome as nome, @@ -2056,14 +2056,14 @@ CREATE [VIEW] views.adm_posto_fiscal_p as id_org_pub_civil as id_org_pub_civil, geom as geom [FROM] - cb.adm_posto_fiscal_p - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = adm_posto_fiscal_p.geometriaaproximada - left join dominios.operacional as dominio_operacional on dominio_operacional.code = adm_posto_fiscal_p.operacional - left join dominios.situacaofisica as dominio_situacaofisica on dominio_situacaofisica.code = adm_posto_fiscal_p.situacaofisica + cb.adm_posto_fiscal_p + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = adm_posto_fiscal_p.geometriaaproximada + left join dominios.operacional as dominio_operacional on dominio_operacional.code = adm_posto_fiscal_p.operacional + left join dominios.situacaofisica as dominio_situacaofisica on dominio_situacaofisica.code = adm_posto_fiscal_p.situacaofisica left join dominios.tipopostofisc as dominio_tipopostofisc on dominio_tipopostofisc.code = adm_posto_fiscal_p.tipopostofisc # DROP VIEW IF EXISTS views.tra_passagem_nivel_p# -CREATE [VIEW] views.tra_passagem_nivel_p as +CREATE [VIEW] views.tra_passagem_nivel_p as SELECT id as id, nome as nome, @@ -2071,11 +2071,11 @@ CREATE [VIEW] views.tra_passagem_nivel_p as dominio_geometriaaproximada.code_name as geometriaaproximada, geom as geom [FROM] - cb.tra_passagem_nivel_p + cb.tra_passagem_nivel_p left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = tra_passagem_nivel_p.geometriaaproximada # DROP VIEW IF EXISTS views.tra_edif_constr_portuaria_p# -CREATE [VIEW] views.tra_edif_constr_portuaria_p as +CREATE [VIEW] views.tra_edif_constr_portuaria_p as SELECT id as id, nome as nome, @@ -2089,16 +2089,16 @@ CREATE [VIEW] views.tra_edif_constr_portuaria_p as dominio_administracao.code_name as administracao, id_complexo_portuario as id_complexo_portuario [FROM] - cb.tra_edif_constr_portuaria_p - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = tra_edif_constr_portuaria_p.geometriaaproximada - left join dominios.operacional as dominio_operacional on dominio_operacional.code = tra_edif_constr_portuaria_p.operacional - left join dominios.situacaofisica as dominio_situacaofisica on dominio_situacaofisica.code = tra_edif_constr_portuaria_p.situacaofisica - left join dominios.matconstr as dominio_matconstr on dominio_matconstr.code = tra_edif_constr_portuaria_p.matconstr - left join dominios.tipoedifport as dominio_tipoedifport on dominio_tipoedifport.code = tra_edif_constr_portuaria_p.tipoedifport + cb.tra_edif_constr_portuaria_p + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = tra_edif_constr_portuaria_p.geometriaaproximada + left join dominios.operacional as dominio_operacional on dominio_operacional.code = tra_edif_constr_portuaria_p.operacional + left join dominios.situacaofisica as dominio_situacaofisica on dominio_situacaofisica.code = tra_edif_constr_portuaria_p.situacaofisica + left join dominios.matconstr as dominio_matconstr on dominio_matconstr.code = tra_edif_constr_portuaria_p.matconstr + left join dominios.tipoedifport as dominio_tipoedifport on dominio_tipoedifport.code = tra_edif_constr_portuaria_p.tipoedifport left join dominios.administracao as dominio_administracao on dominio_administracao.code = tra_edif_constr_portuaria_p.administracao # DROP VIEW IF EXISTS views.edu_edif_religiosa_p# -CREATE [VIEW] views.edu_edif_religiosa_p as +CREATE [VIEW] views.edu_edif_religiosa_p as SELECT id as id, nome as nome, @@ -2113,16 +2113,16 @@ CREATE [VIEW] views.edu_edif_religiosa_p as religiao as religiao, id_org_religiosa as id_org_religiosa [FROM] - cb.edu_edif_religiosa_p - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = edu_edif_religiosa_p.geometriaaproximada - left join dominios.operacional as dominio_operacional on dominio_operacional.code = edu_edif_religiosa_p.operacional - left join dominios.situacaofisica as dominio_situacaofisica on dominio_situacaofisica.code = edu_edif_religiosa_p.situacaofisica - left join dominios.matconstr as dominio_matconstr on dominio_matconstr.code = edu_edif_religiosa_p.matconstr - left join dominios.tipoedifrelig as dominio_tipoedifrelig on dominio_tipoedifrelig.code = edu_edif_religiosa_p.tipoedifrelig + cb.edu_edif_religiosa_p + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = edu_edif_religiosa_p.geometriaaproximada + left join dominios.operacional as dominio_operacional on dominio_operacional.code = edu_edif_religiosa_p.operacional + left join dominios.situacaofisica as dominio_situacaofisica on dominio_situacaofisica.code = edu_edif_religiosa_p.situacaofisica + left join dominios.matconstr as dominio_matconstr on dominio_matconstr.code = edu_edif_religiosa_p.matconstr + left join dominios.tipoedifrelig as dominio_tipoedifrelig on dominio_tipoedifrelig.code = edu_edif_religiosa_p.tipoedifrelig left join dominios.ensino as dominio_ensino on dominio_ensino.code = edu_edif_religiosa_p.ensino # DROP VIEW IF EXISTS views.hid_massa_dagua_a# -CREATE [VIEW] views.hid_massa_dagua_a as +CREATE [VIEW] views.hid_massa_dagua_a as SELECT id as id, nome as nome, @@ -2133,14 +2133,14 @@ CREATE [VIEW] views.hid_massa_dagua_a as dominio_salinidade.code_name as salinidade, geom as geom [FROM] - cb.hid_massa_dagua_a - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = hid_massa_dagua_a.geometriaaproximada - left join dominios.tipomassadagua as dominio_tipomassadagua on dominio_tipomassadagua.code = hid_massa_dagua_a.tipomassadagua - left join dominios.regime as dominio_regime on dominio_regime.code = hid_massa_dagua_a.regime + cb.hid_massa_dagua_a + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = hid_massa_dagua_a.geometriaaproximada + left join dominios.tipomassadagua as dominio_tipomassadagua on dominio_tipomassadagua.code = hid_massa_dagua_a.tipomassadagua + left join dominios.regime as dominio_regime on dominio_regime.code = hid_massa_dagua_a.regime left join dominios.salinidade as dominio_salinidade on dominio_salinidade.code = hid_massa_dagua_a.salinidade # DROP VIEW IF EXISTS views.lim_unidade_conserv_nao_snuc_p# -CREATE [VIEW] views.lim_unidade_conserv_nao_snuc_p as +CREATE [VIEW] views.lim_unidade_conserv_nao_snuc_p as SELECT id as id, nome as nome, @@ -2154,12 +2154,12 @@ CREATE [VIEW] views.lim_unidade_conserv_nao_snuc_p as sigla as sigla, areaoficial as areaoficial [FROM] - cb.lim_unidade_conserv_nao_snuc_p - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = lim_unidade_conserv_nao_snuc_p.geometriaaproximada + cb.lim_unidade_conserv_nao_snuc_p + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = lim_unidade_conserv_nao_snuc_p.geometriaaproximada left join dominios.administracao as dominio_administracao on dominio_administracao.code = lim_unidade_conserv_nao_snuc_p.administracao # DROP VIEW IF EXISTS views.enc_trecho_comunic_l# -CREATE [VIEW] views.enc_trecho_comunic_l as +CREATE [VIEW] views.enc_trecho_comunic_l as SELECT id as id, nome as nome, @@ -2174,17 +2174,17 @@ CREATE [VIEW] views.enc_trecho_comunic_l as id_org_comerc_serv as id_org_comerc_serv, geom as geom [FROM] - cb.enc_trecho_comunic_l - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = enc_trecho_comunic_l.geometriaaproximada - left join dominios.tipotrechocomunic as dominio_tipotrechocomunic on dominio_tipotrechocomunic.code = enc_trecho_comunic_l.tipotrechocomunic - left join dominios.posicaorelativa as dominio_posicaorelativa on dominio_posicaorelativa.code = enc_trecho_comunic_l.posicaorelativa - left join dominios.matconstr as dominio_matconstr on dominio_matconstr.code = enc_trecho_comunic_l.matconstr - left join dominios.operacional as dominio_operacional on dominio_operacional.code = enc_trecho_comunic_l.operacional - left join dominios.situacaofisica as dominio_situacaofisica on dominio_situacaofisica.code = enc_trecho_comunic_l.situacaofisica + cb.enc_trecho_comunic_l + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = enc_trecho_comunic_l.geometriaaproximada + left join dominios.tipotrechocomunic as dominio_tipotrechocomunic on dominio_tipotrechocomunic.code = enc_trecho_comunic_l.tipotrechocomunic + left join dominios.posicaorelativa as dominio_posicaorelativa on dominio_posicaorelativa.code = enc_trecho_comunic_l.posicaorelativa + left join dominios.matconstr as dominio_matconstr on dominio_matconstr.code = enc_trecho_comunic_l.matconstr + left join dominios.operacional as dominio_operacional on dominio_operacional.code = enc_trecho_comunic_l.operacional + left join dominios.situacaofisica as dominio_situacaofisica on dominio_situacaofisica.code = enc_trecho_comunic_l.situacaofisica left join dominios.emduto as dominio_emduto on dominio_emduto.code = enc_trecho_comunic_l.emduto # DROP VIEW IF EXISTS views.lim_unidade_uso_sustentavel_a# -CREATE [VIEW] views.lim_unidade_uso_sustentavel_a as +CREATE [VIEW] views.lim_unidade_uso_sustentavel_a as SELECT id as id, nome as nome, @@ -2198,13 +2198,13 @@ CREATE [VIEW] views.lim_unidade_uso_sustentavel_a as dominio_administracao.code_name as administracao, dominio_tipounidusosust.code_name as tipounidusosust [FROM] - cb.lim_unidade_uso_sustentavel_a - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = lim_unidade_uso_sustentavel_a.geometriaaproximada - left join dominios.administracao as dominio_administracao on dominio_administracao.code = lim_unidade_uso_sustentavel_a.administracao + cb.lim_unidade_uso_sustentavel_a + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = lim_unidade_uso_sustentavel_a.geometriaaproximada + left join dominios.administracao as dominio_administracao on dominio_administracao.code = lim_unidade_uso_sustentavel_a.administracao left join dominios.tipounidusosust as dominio_tipounidusosust on dominio_tipounidusosust.code = lim_unidade_uso_sustentavel_a.tipounidusosust # DROP VIEW IF EXISTS views.tra_travessia_l# -CREATE [VIEW] views.tra_travessia_l as +CREATE [VIEW] views.tra_travessia_l as SELECT id as id, nome as nome, @@ -2213,24 +2213,24 @@ CREATE [VIEW] views.tra_travessia_l as dominio_tipotravessia.code_name as tipotravessia, geom as geom [FROM] - cb.tra_travessia_l - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = tra_travessia_l.geometriaaproximada + cb.tra_travessia_l + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = tra_travessia_l.geometriaaproximada left join dominios.tipotravessia as dominio_tipotravessia on dominio_tipotravessia.code = tra_travessia_l.tipotravessia # DROP VIEW IF EXISTS views.loc_descontinuidade_geometrica_p# -CREATE [VIEW] views.loc_descontinuidade_geometrica_p as +CREATE [VIEW] views.loc_descontinuidade_geometrica_p as SELECT id as id, dominio_geometriaaproximada.code_name as geometriaaproximada, dominio_motivodescontinuidade.code_name as motivodescontinuidade, geom as geom [FROM] - cb.loc_descontinuidade_geometrica_p - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = loc_descontinuidade_geometrica_p.geometriaaproximada + cb.loc_descontinuidade_geometrica_p + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = loc_descontinuidade_geometrica_p.geometriaaproximada left join dominios.motivodescontinuidade as dominio_motivodescontinuidade on dominio_motivodescontinuidade.code = loc_descontinuidade_geometrica_p.motivodescontinuidade # DROP VIEW IF EXISTS views.rel_elemento_fisiog_natural_l# -CREATE [VIEW] views.rel_elemento_fisiog_natural_l as +CREATE [VIEW] views.rel_elemento_fisiog_natural_l as SELECT id as id, nome as nome, @@ -2239,12 +2239,12 @@ CREATE [VIEW] views.rel_elemento_fisiog_natural_l as dominio_tipoelemnat.code_name as tipoelemnat, geom as geom [FROM] - cb.rel_elemento_fisiog_natural_l - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = rel_elemento_fisiog_natural_l.geometriaaproximada + cb.rel_elemento_fisiog_natural_l + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = rel_elemento_fisiog_natural_l.geometriaaproximada left join dominios.tipoelemnat as dominio_tipoelemnat on dominio_tipoelemnat.code = rel_elemento_fisiog_natural_l.tipoelemnat # DROP VIEW IF EXISTS views.eco_ext_mineral_a# -CREATE [VIEW] views.eco_ext_mineral_a as +CREATE [VIEW] views.eco_ext_mineral_a as SELECT id as id, nome as nome, @@ -2262,20 +2262,20 @@ CREATE [VIEW] views.eco_ext_mineral_a as id_org_ext_mineral as id_org_ext_mineral, geom as geom [FROM] - cb.eco_ext_mineral_a - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = eco_ext_mineral_a.geometriaaproximada - left join dominios.tiposecaocnae as dominio_tiposecaocnae on dominio_tiposecaocnae.code = eco_ext_mineral_a.tiposecaocnae - left join dominios.operacional as dominio_operacional on dominio_operacional.code = eco_ext_mineral_a.operacional - left join dominios.situacaofisica as dominio_situacaofisica on dominio_situacaofisica.code = eco_ext_mineral_a.situacaofisica - left join dominios.tipoextmin as dominio_tipoextmin on dominio_tipoextmin.code = eco_ext_mineral_a.tipoextmin - left join dominios.tipoprodutoresiduo as dominio_tipoprodutoresiduo on dominio_tipoprodutoresiduo.code = eco_ext_mineral_a.tipoprodutoresiduo - left join dominios.tipopocomina as dominio_tipopocomina on dominio_tipopocomina.code = eco_ext_mineral_a.tipopocomina - left join dominios.procextracao as dominio_procextracao on dominio_procextracao.code = eco_ext_mineral_a.procextracao - left join dominios.formaextracao as dominio_formaextracao on dominio_formaextracao.code = eco_ext_mineral_a.formaextracao + cb.eco_ext_mineral_a + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = eco_ext_mineral_a.geometriaaproximada + left join dominios.tiposecaocnae as dominio_tiposecaocnae on dominio_tiposecaocnae.code = eco_ext_mineral_a.tiposecaocnae + left join dominios.operacional as dominio_operacional on dominio_operacional.code = eco_ext_mineral_a.operacional + left join dominios.situacaofisica as dominio_situacaofisica on dominio_situacaofisica.code = eco_ext_mineral_a.situacaofisica + left join dominios.tipoextmin as dominio_tipoextmin on dominio_tipoextmin.code = eco_ext_mineral_a.tipoextmin + left join dominios.tipoprodutoresiduo as dominio_tipoprodutoresiduo on dominio_tipoprodutoresiduo.code = eco_ext_mineral_a.tipoprodutoresiduo + left join dominios.tipopocomina as dominio_tipopocomina on dominio_tipopocomina.code = eco_ext_mineral_a.tipopocomina + left join dominios.procextracao as dominio_procextracao on dominio_procextracao.code = eco_ext_mineral_a.procextracao + left join dominios.formaextracao as dominio_formaextracao on dominio_formaextracao.code = eco_ext_mineral_a.formaextracao left join dominios.atividade as dominio_atividade on dominio_atividade.code = eco_ext_mineral_a.atividade # DROP VIEW IF EXISTS views.sau_edif_servico_social_p# -CREATE [VIEW] views.sau_edif_servico_social_p as +CREATE [VIEW] views.sau_edif_servico_social_p as SELECT id as id, nome as nome, @@ -2288,15 +2288,15 @@ CREATE [VIEW] views.sau_edif_servico_social_p as dominio_tipoclassecnae.code_name as tipoclassecnae, id_org_servico_social as id_org_servico_social [FROM] - cb.sau_edif_servico_social_p - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = sau_edif_servico_social_p.geometriaaproximada - left join dominios.operacional as dominio_operacional on dominio_operacional.code = sau_edif_servico_social_p.operacional - left join dominios.situacaofisica as dominio_situacaofisica on dominio_situacaofisica.code = sau_edif_servico_social_p.situacaofisica - left join dominios.matconstr as dominio_matconstr on dominio_matconstr.code = sau_edif_servico_social_p.matconstr + cb.sau_edif_servico_social_p + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = sau_edif_servico_social_p.geometriaaproximada + left join dominios.operacional as dominio_operacional on dominio_operacional.code = sau_edif_servico_social_p.operacional + left join dominios.situacaofisica as dominio_situacaofisica on dominio_situacaofisica.code = sau_edif_servico_social_p.situacaofisica + left join dominios.matconstr as dominio_matconstr on dominio_matconstr.code = sau_edif_servico_social_p.matconstr left join dominios.tipoclassecnae as dominio_tipoclassecnae on dominio_tipoclassecnae.code = sau_edif_servico_social_p.tipoclassecnae # DROP VIEW IF EXISTS views.enc_zona_linhas_energia_com_a# -CREATE [VIEW] views.enc_zona_linhas_energia_com_a as +CREATE [VIEW] views.enc_zona_linhas_energia_com_a as SELECT id as id, nome as nome, @@ -2304,23 +2304,23 @@ CREATE [VIEW] views.enc_zona_linhas_energia_com_a as dominio_geometriaaproximada.code_name as geometriaaproximada, geom as geom [FROM] - cb.enc_zona_linhas_energia_com_a + cb.enc_zona_linhas_energia_com_a left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = enc_zona_linhas_energia_com_a.geometriaaproximada # DROP VIEW IF EXISTS views.tra_ponto_rodoviario_p# -CREATE [VIEW] views.tra_ponto_rodoviario_p as +CREATE [VIEW] views.tra_ponto_rodoviario_p as SELECT id as id, dominio_geometriaaproximada.code_name as geometriaaproximada, dominio_relacionado.code_name as relacionado, geom as geom [FROM] - cb.tra_ponto_rodoviario_p - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = tra_ponto_rodoviario_p.geometriaaproximada + cb.tra_ponto_rodoviario_p + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = tra_ponto_rodoviario_p.geometriaaproximada left join dominios.relacionado_rod as dominio_relacionado on dominio_relacionado.code = tra_ponto_rodoviario_p.relacionado # DROP VIEW IF EXISTS views.lim_unidade_uso_sustentavel_p# -CREATE [VIEW] views.lim_unidade_uso_sustentavel_p as +CREATE [VIEW] views.lim_unidade_uso_sustentavel_p as SELECT id as id, nome as nome, @@ -2334,25 +2334,25 @@ CREATE [VIEW] views.lim_unidade_uso_sustentavel_p as dominio_administracao.code_name as administracao, dominio_tipounidusosust.code_name as tipounidusosust [FROM] - cb.lim_unidade_uso_sustentavel_p - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = lim_unidade_uso_sustentavel_p.geometriaaproximada - left join dominios.administracao as dominio_administracao on dominio_administracao.code = lim_unidade_uso_sustentavel_p.administracao + cb.lim_unidade_uso_sustentavel_p + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = lim_unidade_uso_sustentavel_p.geometriaaproximada + left join dominios.administracao as dominio_administracao on dominio_administracao.code = lim_unidade_uso_sustentavel_p.administracao left join dominios.tipounidusosust as dominio_tipounidusosust on dominio_tipounidusosust.code = lim_unidade_uso_sustentavel_p.tipounidusosust # DROP VIEW IF EXISTS views.aux_descontinuidade_geometrica_l# -CREATE [VIEW] views.aux_descontinuidade_geometrica_l as +CREATE [VIEW] views.aux_descontinuidade_geometrica_l as SELECT id as id, dominio_geometriaaproximada.code_name as geometriaaproximada, dominio_motivodescontinuidade.code_name as motivodescontinuidade, geom as geom [FROM] - cb.aux_descontinuidade_geometrica_l - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = aux_descontinuidade_geometrica_l.geometriaaproximada + cb.aux_descontinuidade_geometrica_l + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = aux_descontinuidade_geometrica_l.geometriaaproximada left join dominios.motivodescontinuidade as dominio_motivodescontinuidade on dominio_motivodescontinuidade.code = aux_descontinuidade_geometrica_l.motivodescontinuidade # DROP VIEW IF EXISTS views.tra_atracadouro_l# -CREATE [VIEW] views.tra_atracadouro_l as +CREATE [VIEW] views.tra_atracadouro_l as SELECT id as id, nome as nome, @@ -2366,28 +2366,28 @@ CREATE [VIEW] views.tra_atracadouro_l as id_complexo_portuario as id_complexo_portuario, geom as geom [FROM] - cb.tra_atracadouro_l - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = tra_atracadouro_l.geometriaaproximada - left join dominios.tipoatracad as dominio_tipoatracad on dominio_tipoatracad.code = tra_atracadouro_l.tipoatracad - left join dominios.administracao as dominio_administracao on dominio_administracao.code = tra_atracadouro_l.administracao - left join dominios.matconstr as dominio_matconstr on dominio_matconstr.code = tra_atracadouro_l.matconstr - left join dominios.operacional as dominio_operacional on dominio_operacional.code = tra_atracadouro_l.operacional + cb.tra_atracadouro_l + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = tra_atracadouro_l.geometriaaproximada + left join dominios.tipoatracad as dominio_tipoatracad on dominio_tipoatracad.code = tra_atracadouro_l.tipoatracad + left join dominios.administracao as dominio_administracao on dominio_administracao.code = tra_atracadouro_l.administracao + left join dominios.matconstr as dominio_matconstr on dominio_matconstr.code = tra_atracadouro_l.matconstr + left join dominios.operacional as dominio_operacional on dominio_operacional.code = tra_atracadouro_l.operacional left join dominios.situacaofisica as dominio_situacaofisica on dominio_situacaofisica.code = tra_atracadouro_l.situacaofisica # DROP VIEW IF EXISTS views.aux_descontinuidade_geometrica_p# -CREATE [VIEW] views.aux_descontinuidade_geometrica_p as +CREATE [VIEW] views.aux_descontinuidade_geometrica_p as SELECT id as id, dominio_geometriaaproximada.code_name as geometriaaproximada, dominio_motivodescontinuidade.code_name as motivodescontinuidade, geom as geom [FROM] - cb.aux_descontinuidade_geometrica_p - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = aux_descontinuidade_geometrica_p.geometriaaproximada + cb.aux_descontinuidade_geometrica_p + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = aux_descontinuidade_geometrica_p.geometriaaproximada left join dominios.motivodescontinuidade as dominio_motivodescontinuidade on dominio_motivodescontinuidade.code = aux_descontinuidade_geometrica_p.motivodescontinuidade # DROP VIEW IF EXISTS views.edu_arquibancada_a# -CREATE [VIEW] views.edu_arquibancada_a as +CREATE [VIEW] views.edu_arquibancada_a as SELECT id as id, nome as nome, @@ -2398,24 +2398,24 @@ CREATE [VIEW] views.edu_arquibancada_a as id_complexo_lazer as id_complexo_lazer, geom as geom [FROM] - cb.edu_arquibancada_a - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = edu_arquibancada_a.geometriaaproximada - left join dominios.operacional as dominio_operacional on dominio_operacional.code = edu_arquibancada_a.operacional + cb.edu_arquibancada_a + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = edu_arquibancada_a.geometriaaproximada + left join dominios.operacional as dominio_operacional on dominio_operacional.code = edu_arquibancada_a.operacional left join dominios.situacaofisica as dominio_situacaofisica on dominio_situacaofisica.code = edu_arquibancada_a.situacaofisica # DROP VIEW IF EXISTS views.tra_area_estrut_transporte_a# -CREATE [VIEW] views.tra_area_estrut_transporte_a as +CREATE [VIEW] views.tra_area_estrut_transporte_a as SELECT id as id, dominio_geometriaaproximada.code_name as geometriaaproximada, id_estrut_transporte as id_estrut_transporte, geom as geom [FROM] - cb.tra_area_estrut_transporte_a + cb.tra_area_estrut_transporte_a left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = tra_area_estrut_transporte_a.geometriaaproximada # DROP VIEW IF EXISTS views.loc_cidade_p# -CREATE [VIEW] views.loc_cidade_p as +CREATE [VIEW] views.loc_cidade_p as SELECT id as id, nome as nome, @@ -2429,11 +2429,11 @@ CREATE [VIEW] views.loc_cidade_p as longitude_gms as longitude_gms, geom as geom [FROM] - cb.loc_cidade_p + cb.loc_cidade_p left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = loc_cidade_p.geometriaaproximada # DROP VIEW IF EXISTS views.eco_equip_agropec_a# -CREATE [VIEW] views.eco_equip_agropec_a as +CREATE [VIEW] views.eco_equip_agropec_a as SELECT id as id, nome as nome, @@ -2446,15 +2446,15 @@ CREATE [VIEW] views.eco_equip_agropec_a as id_org_agropec_ext_veg_pesca as id_org_agropec_ext_veg_pesca, geom as geom [FROM] - cb.eco_equip_agropec_a - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = eco_equip_agropec_a.geometriaaproximada - left join dominios.operacional as dominio_operacional on dominio_operacional.code = eco_equip_agropec_a.operacional - left join dominios.situacaofisica as dominio_situacaofisica on dominio_situacaofisica.code = eco_equip_agropec_a.situacaofisica - left join dominios.tipoequipagropec as dominio_tipoequipagropec on dominio_tipoequipagropec.code = eco_equip_agropec_a.tipoequipagropec + cb.eco_equip_agropec_a + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = eco_equip_agropec_a.geometriaaproximada + left join dominios.operacional as dominio_operacional on dominio_operacional.code = eco_equip_agropec_a.operacional + left join dominios.situacaofisica as dominio_situacaofisica on dominio_situacaofisica.code = eco_equip_agropec_a.situacaofisica + left join dominios.tipoequipagropec as dominio_tipoequipagropec on dominio_tipoequipagropec.code = eco_equip_agropec_a.tipoequipagropec left join dominios.matconstr as dominio_matconstr on dominio_matconstr.code = eco_equip_agropec_a.matconstr # DROP VIEW IF EXISTS views.hid_area_umida_a# -CREATE [VIEW] views.hid_area_umida_a as +CREATE [VIEW] views.hid_area_umida_a as SELECT id as id, nome as nome, @@ -2463,24 +2463,24 @@ CREATE [VIEW] views.hid_area_umida_a as dominio_tipoareaumida.code_name as tipoareaumida, geom as geom [FROM] - cb.hid_area_umida_a - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = hid_area_umida_a.geometriaaproximada + cb.hid_area_umida_a + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = hid_area_umida_a.geometriaaproximada left join dominios.tipoareaumida as dominio_tipoareaumida on dominio_tipoareaumida.code = hid_area_umida_a.tipoareaumida # DROP VIEW IF EXISTS views.aux_descontinuidade_geometrica_a# -CREATE [VIEW] views.aux_descontinuidade_geometrica_a as +CREATE [VIEW] views.aux_descontinuidade_geometrica_a as SELECT id as id, dominio_geometriaaproximada.code_name as geometriaaproximada, dominio_motivodescontinuidade.code_name as motivodescontinuidade, geom as geom [FROM] - cb.aux_descontinuidade_geometrica_a - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = aux_descontinuidade_geometrica_a.geometriaaproximada + cb.aux_descontinuidade_geometrica_a + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = aux_descontinuidade_geometrica_a.geometriaaproximada left join dominios.motivodescontinuidade as dominio_motivodescontinuidade on dominio_motivodescontinuidade.code = aux_descontinuidade_geometrica_a.motivodescontinuidade # DROP VIEW IF EXISTS views.lim_unidade_protecao_integral_p# -CREATE [VIEW] views.lim_unidade_protecao_integral_p as +CREATE [VIEW] views.lim_unidade_protecao_integral_p as SELECT id as id, nome as nome, @@ -2494,24 +2494,24 @@ CREATE [VIEW] views.lim_unidade_protecao_integral_p as dominio_tipounidprotinteg.code_name as tipounidprotinteg, sigla as sigla [FROM] - cb.lim_unidade_protecao_integral_p - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = lim_unidade_protecao_integral_p.geometriaaproximada - left join dominios.administracao as dominio_administracao on dominio_administracao.code = lim_unidade_protecao_integral_p.administracao + cb.lim_unidade_protecao_integral_p + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = lim_unidade_protecao_integral_p.geometriaaproximada + left join dominios.administracao as dominio_administracao on dominio_administracao.code = lim_unidade_protecao_integral_p.administracao left join dominios.tipounidprotinteg as dominio_tipounidprotinteg on dominio_tipounidprotinteg.code = lim_unidade_protecao_integral_p.tipounidprotinteg # DROP VIEW IF EXISTS views.enc_area_comunicacao_a# -CREATE [VIEW] views.enc_area_comunicacao_a as +CREATE [VIEW] views.enc_area_comunicacao_a as SELECT id as id, dominio_geometriaaproximada.code_name as geometriaaproximada, geom as geom, id_complexo_comunicacao as id_complexo_comunicacao [FROM] - cb.enc_area_comunicacao_a + cb.enc_area_comunicacao_a left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = enc_area_comunicacao_a.geometriaaproximada # DROP VIEW IF EXISTS views.eco_plataforma_a# -CREATE [VIEW] views.eco_plataforma_a as +CREATE [VIEW] views.eco_plataforma_a as SELECT id as id, nome as nome, @@ -2520,12 +2520,12 @@ CREATE [VIEW] views.eco_plataforma_a as dominio_tipoplataforma.code_name as tipoplataforma, geom as geom [FROM] - cb.eco_plataforma_a - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = eco_plataforma_a.geometriaaproximada + cb.eco_plataforma_a + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = eco_plataforma_a.geometriaaproximada left join dominios.tipoplataforma as dominio_tipoplataforma on dominio_tipoplataforma.code = eco_plataforma_a.tipoplataforma # DROP VIEW IF EXISTS views.enc_termeletrica_a# -CREATE [VIEW] views.enc_termeletrica_a as +CREATE [VIEW] views.enc_termeletrica_a as SELECT id as id, nome as nome, @@ -2545,19 +2545,19 @@ CREATE [VIEW] views.enc_termeletrica_a as dominio_tipomaqtermica.code_name as tipomaqtermica, dominio_geracao.code_name as geracao [FROM] - cb.enc_termeletrica_a - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = enc_termeletrica_a.geometriaaproximada - left join dominios.tipoestgerad as dominio_tipoestgerad on dominio_tipoestgerad.code = enc_termeletrica_a.tipoestgerad - left join dominios.operacional as dominio_operacional on dominio_operacional.code = enc_termeletrica_a.operacional - left join dominios.situacaofisica as dominio_situacaofisica on dominio_situacaofisica.code = enc_termeletrica_a.situacaofisica - left join dominios.destenergelet as dominio_destenergelet on dominio_destenergelet.code = enc_termeletrica_a.destenergelet - left join dominios.tipocombustivel as dominio_tipocombustivel on dominio_tipocombustivel.code = enc_termeletrica_a.tipocombustivel - left join dominios.combrenovavel as dominio_combrenovavel on dominio_combrenovavel.code = enc_termeletrica_a.combrenovavel - left join dominios.tipomaqtermica as dominio_tipomaqtermica on dominio_tipomaqtermica.code = enc_termeletrica_a.tipomaqtermica + cb.enc_termeletrica_a + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = enc_termeletrica_a.geometriaaproximada + left join dominios.tipoestgerad as dominio_tipoestgerad on dominio_tipoestgerad.code = enc_termeletrica_a.tipoestgerad + left join dominios.operacional as dominio_operacional on dominio_operacional.code = enc_termeletrica_a.operacional + left join dominios.situacaofisica as dominio_situacaofisica on dominio_situacaofisica.code = enc_termeletrica_a.situacaofisica + left join dominios.destenergelet as dominio_destenergelet on dominio_destenergelet.code = enc_termeletrica_a.destenergelet + left join dominios.tipocombustivel as dominio_tipocombustivel on dominio_tipocombustivel.code = enc_termeletrica_a.tipocombustivel + left join dominios.combrenovavel as dominio_combrenovavel on dominio_combrenovavel.code = enc_termeletrica_a.combrenovavel + left join dominios.tipomaqtermica as dominio_tipomaqtermica on dominio_tipomaqtermica.code = enc_termeletrica_a.tipomaqtermica left join dominios.geracao as dominio_geracao on dominio_geracao.code = enc_termeletrica_a.geracao # DROP VIEW IF EXISTS views.lim_sub_distrito_a# -CREATE [VIEW] views.lim_sub_distrito_a as +CREATE [VIEW] views.lim_sub_distrito_a as SELECT id as id, nome as nome, @@ -2567,33 +2567,33 @@ CREATE [VIEW] views.lim_sub_distrito_a as geocodigo as geocodigo, anodereferencia as anodereferencia [FROM] - cb.lim_sub_distrito_a + cb.lim_sub_distrito_a left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = lim_sub_distrito_a.geometriaaproximada # DROP VIEW IF EXISTS views.loc_nome_local_p# -CREATE [VIEW] views.loc_nome_local_p as +CREATE [VIEW] views.loc_nome_local_p as SELECT id as id, nome as nome, dominio_geometriaaproximada.code_name as geometriaaproximada, geom as geom [FROM] - cb.loc_nome_local_p + cb.loc_nome_local_p left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = loc_nome_local_p.geometriaaproximada # DROP VIEW IF EXISTS views.eco_area_ext_mineral_a# -CREATE [VIEW] views.eco_area_ext_mineral_a as +CREATE [VIEW] views.eco_area_ext_mineral_a as SELECT id as id, geom as geom, dominio_geometriaaproximada.code_name as geometriaaproximada, id_org_ext_mineral as id_org_ext_mineral [FROM] - cb.eco_area_ext_mineral_a + cb.eco_area_ext_mineral_a left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = eco_area_ext_mineral_a.geometriaaproximada # DROP VIEW IF EXISTS views.lim_unidade_protecao_integral_a# -CREATE [VIEW] views.lim_unidade_protecao_integral_a as +CREATE [VIEW] views.lim_unidade_protecao_integral_a as SELECT id as id, nome as nome, @@ -2607,13 +2607,13 @@ CREATE [VIEW] views.lim_unidade_protecao_integral_a as anocriacao as anocriacao, sigla as sigla [FROM] - cb.lim_unidade_protecao_integral_a - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = lim_unidade_protecao_integral_a.geometriaaproximada - left join dominios.tipounidprotinteg as dominio_tipounidprotinteg on dominio_tipounidprotinteg.code = lim_unidade_protecao_integral_a.tipounidprotinteg + cb.lim_unidade_protecao_integral_a + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = lim_unidade_protecao_integral_a.geometriaaproximada + left join dominios.tipounidprotinteg as dominio_tipounidprotinteg on dominio_tipounidprotinteg.code = lim_unidade_protecao_integral_a.tipounidprotinteg left join dominios.administracao as dominio_administracao on dominio_administracao.code = lim_unidade_protecao_integral_a.administracao # DROP VIEW IF EXISTS views.eco_plataforma_p# -CREATE [VIEW] views.eco_plataforma_p as +CREATE [VIEW] views.eco_plataforma_p as SELECT id as id, nome as nome, @@ -2622,12 +2622,12 @@ CREATE [VIEW] views.eco_plataforma_p as dominio_tipoplataforma.code_name as tipoplataforma, geom as geom [FROM] - cb.eco_plataforma_p - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = eco_plataforma_p.geometriaaproximada + cb.eco_plataforma_p + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = eco_plataforma_p.geometriaaproximada left join dominios.tipoplataforma as dominio_tipoplataforma on dominio_tipoplataforma.code = eco_plataforma_p.tipoplataforma # DROP VIEW IF EXISTS views.hid_foz_maritima_a# -CREATE [VIEW] views.hid_foz_maritima_a as +CREATE [VIEW] views.hid_foz_maritima_a as SELECT id as id, nome as nome, @@ -2635,11 +2635,11 @@ CREATE [VIEW] views.hid_foz_maritima_a as dominio_geometriaaproximada.code_name as geometriaaproximada, geom as geom [FROM] - cb.hid_foz_maritima_a + cb.hid_foz_maritima_a left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = hid_foz_maritima_a.geometriaaproximada # DROP VIEW IF EXISTS views.enc_termeletrica_p# -CREATE [VIEW] views.enc_termeletrica_p as +CREATE [VIEW] views.enc_termeletrica_p as SELECT id as id, nome as nome, @@ -2659,19 +2659,19 @@ CREATE [VIEW] views.enc_termeletrica_p as dominio_tipomaqtermica.code_name as tipomaqtermica, dominio_geracao.code_name as geracao [FROM] - cb.enc_termeletrica_p - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = enc_termeletrica_p.geometriaaproximada - left join dominios.tipoestgerad as dominio_tipoestgerad on dominio_tipoestgerad.code = enc_termeletrica_p.tipoestgerad - left join dominios.operacional as dominio_operacional on dominio_operacional.code = enc_termeletrica_p.operacional - left join dominios.situacaofisica as dominio_situacaofisica on dominio_situacaofisica.code = enc_termeletrica_p.situacaofisica - left join dominios.destenergelet as dominio_destenergelet on dominio_destenergelet.code = enc_termeletrica_p.destenergelet - left join dominios.tipocombustivel as dominio_tipocombustivel on dominio_tipocombustivel.code = enc_termeletrica_p.tipocombustivel - left join dominios.combrenovavel as dominio_combrenovavel on dominio_combrenovavel.code = enc_termeletrica_p.combrenovavel - left join dominios.tipomaqtermica as dominio_tipomaqtermica on dominio_tipomaqtermica.code = enc_termeletrica_p.tipomaqtermica + cb.enc_termeletrica_p + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = enc_termeletrica_p.geometriaaproximada + left join dominios.tipoestgerad as dominio_tipoestgerad on dominio_tipoestgerad.code = enc_termeletrica_p.tipoestgerad + left join dominios.operacional as dominio_operacional on dominio_operacional.code = enc_termeletrica_p.operacional + left join dominios.situacaofisica as dominio_situacaofisica on dominio_situacaofisica.code = enc_termeletrica_p.situacaofisica + left join dominios.destenergelet as dominio_destenergelet on dominio_destenergelet.code = enc_termeletrica_p.destenergelet + left join dominios.tipocombustivel as dominio_tipocombustivel on dominio_tipocombustivel.code = enc_termeletrica_p.tipocombustivel + left join dominios.combrenovavel as dominio_combrenovavel on dominio_combrenovavel.code = enc_termeletrica_p.combrenovavel + left join dominios.tipomaqtermica as dominio_tipomaqtermica on dominio_tipomaqtermica.code = enc_termeletrica_p.tipomaqtermica left join dominios.geracao as dominio_geracao on dominio_geracao.code = enc_termeletrica_p.geracao # DROP VIEW IF EXISTS views.enc_torre_energia_p# -CREATE [VIEW] views.enc_torre_energia_p as +CREATE [VIEW] views.enc_torre_energia_p as SELECT id as id, nome as nome, @@ -2685,15 +2685,15 @@ CREATE [VIEW] views.enc_torre_energia_p as arranjofases as arranjofases, geom as geom [FROM] - cb.enc_torre_energia_p - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = enc_torre_energia_p.geometriaaproximada - left join dominios.operacional as dominio_operacional on dominio_operacional.code = enc_torre_energia_p.operacional - left join dominios.situacaofisica as dominio_situacaofisica on dominio_situacaofisica.code = enc_torre_energia_p.situacaofisica - left join dominios.ovgd as dominio_ovgd on dominio_ovgd.code = enc_torre_energia_p.ovgd + cb.enc_torre_energia_p + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = enc_torre_energia_p.geometriaaproximada + left join dominios.operacional as dominio_operacional on dominio_operacional.code = enc_torre_energia_p.operacional + left join dominios.situacaofisica as dominio_situacaofisica on dominio_situacaofisica.code = enc_torre_energia_p.situacaofisica + left join dominios.ovgd as dominio_ovgd on dominio_ovgd.code = enc_torre_energia_p.ovgd left join dominios.tipotorre as dominio_tipotorre on dominio_tipotorre.code = enc_torre_energia_p.tipotorre # DROP VIEW IF EXISTS views.hid_natureza_fundo_p# -CREATE [VIEW] views.hid_natureza_fundo_p as +CREATE [VIEW] views.hid_natureza_fundo_p as SELECT id as id, nome as nome, @@ -2703,13 +2703,13 @@ CREATE [VIEW] views.hid_natureza_fundo_p as dominio_espessalgas.code_name as espessalgas, geom as geom [FROM] - cb.hid_natureza_fundo_p - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = hid_natureza_fundo_p.geometriaaproximada - left join dominios.materialpredominante as dominio_materialpredominante on dominio_materialpredominante.code = hid_natureza_fundo_p.materialpredominante + cb.hid_natureza_fundo_p + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = hid_natureza_fundo_p.geometriaaproximada + left join dominios.materialpredominante as dominio_materialpredominante on dominio_materialpredominante.code = hid_natureza_fundo_p.materialpredominante left join dominios.espessalgas as dominio_espessalgas on dominio_espessalgas.code = hid_natureza_fundo_p.espessalgas # DROP VIEW IF EXISTS views.hid_bacia_hidrografica_a# -CREATE [VIEW] views.hid_bacia_hidrografica_a as +CREATE [VIEW] views.hid_bacia_hidrografica_a as SELECT id as id, nome as nome, @@ -2719,11 +2719,11 @@ CREATE [VIEW] views.hid_bacia_hidrografica_a as nivelotto as nivelotto, geom as geom [FROM] - cb.hid_bacia_hidrografica_a + cb.hid_bacia_hidrografica_a left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = hid_bacia_hidrografica_a.geometriaaproximada # DROP VIEW IF EXISTS views.edu_edif_const_lazer_a# -CREATE [VIEW] views.edu_edif_const_lazer_a as +CREATE [VIEW] views.edu_edif_const_lazer_a as SELECT id as id, nome as nome, @@ -2736,15 +2736,15 @@ CREATE [VIEW] views.edu_edif_const_lazer_a as dominio_tipoediflazer.code_name as tipoediflazer, id_complexo_lazer as id_complexo_lazer [FROM] - cb.edu_edif_const_lazer_a - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = edu_edif_const_lazer_a.geometriaaproximada - left join dominios.operacional as dominio_operacional on dominio_operacional.code = edu_edif_const_lazer_a.operacional - left join dominios.situacaofisica as dominio_situacaofisica on dominio_situacaofisica.code = edu_edif_const_lazer_a.situacaofisica - left join dominios.matconstr as dominio_matconstr on dominio_matconstr.code = edu_edif_const_lazer_a.matconstr + cb.edu_edif_const_lazer_a + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = edu_edif_const_lazer_a.geometriaaproximada + left join dominios.operacional as dominio_operacional on dominio_operacional.code = edu_edif_const_lazer_a.operacional + left join dominios.situacaofisica as dominio_situacaofisica on dominio_situacaofisica.code = edu_edif_const_lazer_a.situacaofisica + left join dominios.matconstr as dominio_matconstr on dominio_matconstr.code = edu_edif_const_lazer_a.matconstr left join dominios.tipoediflazer as dominio_tipoediflazer on dominio_tipoediflazer.code = edu_edif_const_lazer_a.tipoediflazer # DROP VIEW IF EXISTS views.enc_hidreletrica_l# -CREATE [VIEW] views.enc_hidreletrica_l as +CREATE [VIEW] views.enc_hidreletrica_l as SELECT id as id, nome as nome, @@ -2761,38 +2761,38 @@ CREATE [VIEW] views.enc_hidreletrica_l as geom as geom, codigohidreletrica as codigohidreletrica [FROM] - cb.enc_hidreletrica_l - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = enc_hidreletrica_l.geometriaaproximada - left join dominios.tipoestgerad as dominio_tipoestgerad on dominio_tipoestgerad.code = enc_hidreletrica_l.tipoestgerad - left join dominios.operacional as dominio_operacional on dominio_operacional.code = enc_hidreletrica_l.operacional - left join dominios.situacaofisica as dominio_situacaofisica on dominio_situacaofisica.code = enc_hidreletrica_l.situacaofisica + cb.enc_hidreletrica_l + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = enc_hidreletrica_l.geometriaaproximada + left join dominios.tipoestgerad as dominio_tipoestgerad on dominio_tipoestgerad.code = enc_hidreletrica_l.tipoestgerad + left join dominios.operacional as dominio_operacional on dominio_operacional.code = enc_hidreletrica_l.operacional + left join dominios.situacaofisica as dominio_situacaofisica on dominio_situacaofisica.code = enc_hidreletrica_l.situacaofisica left join dominios.destenergelet as dominio_destenergelet on dominio_destenergelet.code = enc_hidreletrica_l.destenergelet # DROP VIEW IF EXISTS views.hid_descontinuidade_geometrica_p# -CREATE [VIEW] views.hid_descontinuidade_geometrica_p as +CREATE [VIEW] views.hid_descontinuidade_geometrica_p as SELECT id as id, dominio_geometriaaproximada.code_name as geometriaaproximada, dominio_motivodescontinuidade.code_name as motivodescontinuidade, geom as geom [FROM] - cb.hid_descontinuidade_geometrica_p - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = hid_descontinuidade_geometrica_p.geometriaaproximada + cb.hid_descontinuidade_geometrica_p + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = hid_descontinuidade_geometrica_p.geometriaaproximada left join dominios.motivodescontinuidade as dominio_motivodescontinuidade on dominio_motivodescontinuidade.code = hid_descontinuidade_geometrica_p.motivodescontinuidade # DROP VIEW IF EXISTS views.eco_area_comerc_serv_a# -CREATE [VIEW] views.eco_area_comerc_serv_a as +CREATE [VIEW] views.eco_area_comerc_serv_a as SELECT id as id, dominio_geometriaaproximada.code_name as geometriaaproximada, geom as geom, id_org_comerc_serv as id_org_comerc_serv [FROM] - cb.eco_area_comerc_serv_a + cb.eco_area_comerc_serv_a left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = eco_area_comerc_serv_a.geometriaaproximada # DROP VIEW IF EXISTS views.tra_patio_p# -CREATE [VIEW] views.tra_patio_p as +CREATE [VIEW] views.tra_patio_p as SELECT id as id, nome as nome, @@ -2811,27 +2811,27 @@ CREATE [VIEW] views.tra_patio_p as id_complexo_lazer as id_complexo_lazer, geom as geom [FROM] - cb.tra_patio_p - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = tra_patio_p.geometriaaproximada - left join dominios.modaluso as dominio_modaluso on dominio_modaluso.code = tra_patio_p.modaluso - left join dominios.administracao as dominio_administracao on dominio_administracao.code = tra_patio_p.administracao - left join dominios.operacional as dominio_operacional on dominio_operacional.code = tra_patio_p.operacional + cb.tra_patio_p + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = tra_patio_p.geometriaaproximada + left join dominios.modaluso as dominio_modaluso on dominio_modaluso.code = tra_patio_p.modaluso + left join dominios.administracao as dominio_administracao on dominio_administracao.code = tra_patio_p.administracao + left join dominios.operacional as dominio_operacional on dominio_operacional.code = tra_patio_p.operacional left join dominios.situacaofisica as dominio_situacaofisica on dominio_situacaofisica.code = tra_patio_p.situacaofisica # DROP VIEW IF EXISTS views.sau_descontinuidade_geometrica_a# -CREATE [VIEW] views.sau_descontinuidade_geometrica_a as +CREATE [VIEW] views.sau_descontinuidade_geometrica_a as SELECT id as id, dominio_geometriaaproximada.code_name as geometriaaproximada, dominio_motivodescontinuidade.code_name as motivodescontinuidade, geom as geom [FROM] - cb.sau_descontinuidade_geometrica_a - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = sau_descontinuidade_geometrica_a.geometriaaproximada + cb.sau_descontinuidade_geometrica_a + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = sau_descontinuidade_geometrica_a.geometriaaproximada left join dominios.motivodescontinuidade as dominio_motivodescontinuidade on dominio_motivodescontinuidade.code = sau_descontinuidade_geometrica_a.motivodescontinuidade # DROP VIEW IF EXISTS views.enc_hidreletrica_a# -CREATE [VIEW] views.enc_hidreletrica_a as +CREATE [VIEW] views.enc_hidreletrica_a as SELECT id as id, nome as nome, @@ -2848,15 +2848,15 @@ CREATE [VIEW] views.enc_hidreletrica_a as geom as geom, codigohidreletrica as codigohidreletrica [FROM] - cb.enc_hidreletrica_a - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = enc_hidreletrica_a.geometriaaproximada - left join dominios.tipoestgerad as dominio_tipoestgerad on dominio_tipoestgerad.code = enc_hidreletrica_a.tipoestgerad - left join dominios.operacional as dominio_operacional on dominio_operacional.code = enc_hidreletrica_a.operacional - left join dominios.situacaofisica as dominio_situacaofisica on dominio_situacaofisica.code = enc_hidreletrica_a.situacaofisica + cb.enc_hidreletrica_a + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = enc_hidreletrica_a.geometriaaproximada + left join dominios.tipoestgerad as dominio_tipoestgerad on dominio_tipoestgerad.code = enc_hidreletrica_a.tipoestgerad + left join dominios.operacional as dominio_operacional on dominio_operacional.code = enc_hidreletrica_a.operacional + left join dominios.situacaofisica as dominio_situacaofisica on dominio_situacaofisica.code = enc_hidreletrica_a.situacaofisica left join dominios.destenergelet as dominio_destenergelet on dominio_destenergelet.code = enc_hidreletrica_a.destenergelet # DROP VIEW IF EXISTS views.loc_aglomerado_rural_p# -CREATE [VIEW] views.loc_aglomerado_rural_p as +CREATE [VIEW] views.loc_aglomerado_rural_p as SELECT id as id, nome as nome, @@ -2870,11 +2870,11 @@ CREATE [VIEW] views.loc_aglomerado_rural_p as longitude_gms as longitude_gms, geom as geom [FROM] - cb.loc_aglomerado_rural_p + cb.loc_aglomerado_rural_p left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = loc_aglomerado_rural_p.geometriaaproximada # DROP VIEW IF EXISTS views.tra_edif_constr_aeroportuaria_p# -CREATE [VIEW] views.tra_edif_constr_aeroportuaria_p as +CREATE [VIEW] views.tra_edif_constr_aeroportuaria_p as SELECT id as id, nome as nome, @@ -2888,16 +2888,16 @@ CREATE [VIEW] views.tra_edif_constr_aeroportuaria_p as dominio_administracao.code_name as administracao, id_complexo_aeroportuario as id_complexo_aeroportuario [FROM] - cb.tra_edif_constr_aeroportuaria_p - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = tra_edif_constr_aeroportuaria_p.geometriaaproximada - left join dominios.operacional as dominio_operacional on dominio_operacional.code = tra_edif_constr_aeroportuaria_p.operacional - left join dominios.situacaofisica as dominio_situacaofisica on dominio_situacaofisica.code = tra_edif_constr_aeroportuaria_p.situacaofisica - left join dominios.matconstr as dominio_matconstr on dominio_matconstr.code = tra_edif_constr_aeroportuaria_p.matconstr - left join dominios.tipoedifaero as dominio_tipoedifaero on dominio_tipoedifaero.code = tra_edif_constr_aeroportuaria_p.tipoedifaero + cb.tra_edif_constr_aeroportuaria_p + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = tra_edif_constr_aeroportuaria_p.geometriaaproximada + left join dominios.operacional as dominio_operacional on dominio_operacional.code = tra_edif_constr_aeroportuaria_p.operacional + left join dominios.situacaofisica as dominio_situacaofisica on dominio_situacaofisica.code = tra_edif_constr_aeroportuaria_p.situacaofisica + left join dominios.matconstr as dominio_matconstr on dominio_matconstr.code = tra_edif_constr_aeroportuaria_p.matconstr + left join dominios.tipoedifaero as dominio_tipoedifaero on dominio_tipoedifaero.code = tra_edif_constr_aeroportuaria_p.tipoedifaero left join dominios.administracao as dominio_administracao on dominio_administracao.code = tra_edif_constr_aeroportuaria_p.administracao # DROP VIEW IF EXISTS views.rel_dolina_a# -CREATE [VIEW] views.rel_dolina_a as +CREATE [VIEW] views.rel_dolina_a as SELECT id as id, nome as nome, @@ -2906,12 +2906,12 @@ CREATE [VIEW] views.rel_dolina_a as dominio_tipoelemnat.code_name as tipoelemnat, geom as geom [FROM] - cb.rel_dolina_a - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = rel_dolina_a.geometriaaproximada + cb.rel_dolina_a + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = rel_dolina_a.geometriaaproximada left join dominios.tipoelemnat as dominio_tipoelemnat on dominio_tipoelemnat.code = rel_dolina_a.tipoelemnat # DROP VIEW IF EXISTS views.hid_confluencia_p# -CREATE [VIEW] views.hid_confluencia_p as +CREATE [VIEW] views.hid_confluencia_p as SELECT id as id, nome as nome, @@ -2920,12 +2920,12 @@ CREATE [VIEW] views.hid_confluencia_p as dominio_relacionado.code_name as relacionado, geom as geom [FROM] - cb.hid_confluencia_p - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = hid_confluencia_p.geometriaaproximada + cb.hid_confluencia_p + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = hid_confluencia_p.geometriaaproximada left join dominios.relacionado_hid as dominio_relacionado on dominio_relacionado.code = hid_confluencia_p.relacionado # DROP VIEW IF EXISTS views.tra_pista_ponto_pouso_l# -CREATE [VIEW] views.tra_pista_ponto_pouso_l as +CREATE [VIEW] views.tra_pista_ponto_pouso_l as SELECT id as id, nome as nome, @@ -2942,17 +2942,17 @@ CREATE [VIEW] views.tra_pista_ponto_pouso_l as id_complexo_aeroportuario as id_complexo_aeroportuario, geom as geom [FROM] - cb.tra_pista_ponto_pouso_l - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = tra_pista_ponto_pouso_l.geometriaaproximada - left join dominios.tipopista as dominio_tipopista on dominio_tipopista.code = tra_pista_ponto_pouso_l.tipopista - left join dominios.revestimento as dominio_revestimento on dominio_revestimento.code = tra_pista_ponto_pouso_l.revestimento - left join dominios.usopista as dominio_usopista on dominio_usopista.code = tra_pista_ponto_pouso_l.usopista - left join dominios.homologacao as dominio_homologacao on dominio_homologacao.code = tra_pista_ponto_pouso_l.homologacao - left join dominios.operacional as dominio_operacional on dominio_operacional.code = tra_pista_ponto_pouso_l.operacional + cb.tra_pista_ponto_pouso_l + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = tra_pista_ponto_pouso_l.geometriaaproximada + left join dominios.tipopista as dominio_tipopista on dominio_tipopista.code = tra_pista_ponto_pouso_l.tipopista + left join dominios.revestimento as dominio_revestimento on dominio_revestimento.code = tra_pista_ponto_pouso_l.revestimento + left join dominios.usopista as dominio_usopista on dominio_usopista.code = tra_pista_ponto_pouso_l.usopista + left join dominios.homologacao as dominio_homologacao on dominio_homologacao.code = tra_pista_ponto_pouso_l.homologacao + left join dominios.operacional as dominio_operacional on dominio_operacional.code = tra_pista_ponto_pouso_l.operacional left join dominios.situacaofisica as dominio_situacaofisica on dominio_situacaofisica.code = tra_pista_ponto_pouso_l.situacaofisica # DROP VIEW IF EXISTS views.tra_passag_elevada_viaduto_l# -CREATE [VIEW] views.tra_passag_elevada_viaduto_l as +CREATE [VIEW] views.tra_passag_elevada_viaduto_l as SELECT id as id, nome as nome, @@ -2975,17 +2975,17 @@ CREATE [VIEW] views.tra_passag_elevada_viaduto_l as largura as largura, geom as geom [FROM] - cb.tra_passag_elevada_viaduto_l - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = tra_passag_elevada_viaduto_l.geometriaaproximada - left join dominios.tipopassagviad as dominio_tipopassagviad on dominio_tipopassagviad.code = tra_passag_elevada_viaduto_l.tipopassagviad - left join dominios.modaluso as dominio_modaluso on dominio_modaluso.code = tra_passag_elevada_viaduto_l.modaluso - left join dominios.matconstr as dominio_matconstr on dominio_matconstr.code = tra_passag_elevada_viaduto_l.matconstr - left join dominios.operacional as dominio_operacional on dominio_operacional.code = tra_passag_elevada_viaduto_l.operacional - left join dominios.situacaofisica as dominio_situacaofisica on dominio_situacaofisica.code = tra_passag_elevada_viaduto_l.situacaofisica + cb.tra_passag_elevada_viaduto_l + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = tra_passag_elevada_viaduto_l.geometriaaproximada + left join dominios.tipopassagviad as dominio_tipopassagviad on dominio_tipopassagviad.code = tra_passag_elevada_viaduto_l.tipopassagviad + left join dominios.modaluso as dominio_modaluso on dominio_modaluso.code = tra_passag_elevada_viaduto_l.modaluso + left join dominios.matconstr as dominio_matconstr on dominio_matconstr.code = tra_passag_elevada_viaduto_l.matconstr + left join dominios.operacional as dominio_operacional on dominio_operacional.code = tra_passag_elevada_viaduto_l.operacional + left join dominios.situacaofisica as dominio_situacaofisica on dominio_situacaofisica.code = tra_passag_elevada_viaduto_l.situacaofisica left join dominios.posicaopista as dominio_posicaopista on dominio_posicaopista.code = tra_passag_elevada_viaduto_l.posicaopista # DROP VIEW IF EXISTS views.hid_natureza_fundo_a# -CREATE [VIEW] views.hid_natureza_fundo_a as +CREATE [VIEW] views.hid_natureza_fundo_a as SELECT id as id, nome as nome, @@ -2995,13 +2995,13 @@ CREATE [VIEW] views.hid_natureza_fundo_a as dominio_espessalgas.code_name as espessalgas, geom as geom [FROM] - cb.hid_natureza_fundo_a - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = hid_natureza_fundo_a.geometriaaproximada - left join dominios.materialpredominante as dominio_materialpredominante on dominio_materialpredominante.code = hid_natureza_fundo_a.materialpredominante + cb.hid_natureza_fundo_a + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = hid_natureza_fundo_a.geometriaaproximada + left join dominios.materialpredominante as dominio_materialpredominante on dominio_materialpredominante.code = hid_natureza_fundo_a.materialpredominante left join dominios.espessalgas as dominio_espessalgas on dominio_espessalgas.code = hid_natureza_fundo_a.espessalgas # DROP VIEW IF EXISTS views.tra_eclusa_a# -CREATE [VIEW] views.tra_eclusa_a as +CREATE [VIEW] views.tra_eclusa_a as SELECT id as id, nome as nome, @@ -3016,14 +3016,14 @@ CREATE [VIEW] views.tra_eclusa_a as dominio_situacaofisica.code_name as situacaofisica, geom as geom [FROM] - cb.tra_eclusa_a - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = tra_eclusa_a.geometriaaproximada - left join dominios.matconstr as dominio_matconstr on dominio_matconstr.code = tra_eclusa_a.matconstr - left join dominios.operacional as dominio_operacional on dominio_operacional.code = tra_eclusa_a.operacional + cb.tra_eclusa_a + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = tra_eclusa_a.geometriaaproximada + left join dominios.matconstr as dominio_matconstr on dominio_matconstr.code = tra_eclusa_a.matconstr + left join dominios.operacional as dominio_operacional on dominio_operacional.code = tra_eclusa_a.operacional left join dominios.situacaofisica as dominio_situacaofisica on dominio_situacaofisica.code = tra_eclusa_a.situacaofisica # DROP VIEW IF EXISTS views.sau_edif_saude_a# -CREATE [VIEW] views.sau_edif_saude_a as +CREATE [VIEW] views.sau_edif_saude_a as SELECT id as id, nome as nome, @@ -3037,16 +3037,16 @@ CREATE [VIEW] views.sau_edif_saude_a as dominio_nivelatencao.code_name as nivelatencao, id_org_saude as id_org_saude [FROM] - cb.sau_edif_saude_a - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = sau_edif_saude_a.geometriaaproximada - left join dominios.operacional as dominio_operacional on dominio_operacional.code = sau_edif_saude_a.operacional - left join dominios.situacaofisica as dominio_situacaofisica on dominio_situacaofisica.code = sau_edif_saude_a.situacaofisica - left join dominios.matconstr as dominio_matconstr on dominio_matconstr.code = sau_edif_saude_a.matconstr - left join dominios.tipoclassecnae as dominio_tipoclassecnae on dominio_tipoclassecnae.code = sau_edif_saude_a.tipoclassecnae + cb.sau_edif_saude_a + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = sau_edif_saude_a.geometriaaproximada + left join dominios.operacional as dominio_operacional on dominio_operacional.code = sau_edif_saude_a.operacional + left join dominios.situacaofisica as dominio_situacaofisica on dominio_situacaofisica.code = sau_edif_saude_a.situacaofisica + left join dominios.matconstr as dominio_matconstr on dominio_matconstr.code = sau_edif_saude_a.matconstr + left join dominios.tipoclassecnae as dominio_tipoclassecnae on dominio_tipoclassecnae.code = sau_edif_saude_a.tipoclassecnae left join dominios.nivelatencao as dominio_nivelatencao on dominio_nivelatencao.code = sau_edif_saude_a.nivelatencao # DROP VIEW IF EXISTS views.veg_campo_a# -CREATE [VIEW] views.veg_campo_a as +CREATE [VIEW] views.veg_campo_a as SELECT id as id, nome as nome, @@ -3056,13 +3056,13 @@ CREATE [VIEW] views.veg_campo_a as dominio_ocorrenciaem.code_name as ocorrenciaem, geom as geom [FROM] - cb.veg_campo_a - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = veg_campo_a.geometriaaproximada - left join dominios.tipocampo as dominio_tipocampo on dominio_tipocampo.code = veg_campo_a.tipocampo + cb.veg_campo_a + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = veg_campo_a.geometriaaproximada + left join dominios.tipocampo as dominio_tipocampo on dominio_tipocampo.code = veg_campo_a.tipocampo left join dominios.ocorrenciaem as dominio_ocorrenciaem on dominio_ocorrenciaem.code = veg_campo_a.ocorrenciaem # DROP VIEW IF EXISTS views.loc_vila_p# -CREATE [VIEW] views.loc_vila_p as +CREATE [VIEW] views.loc_vila_p as SELECT id as id, nome as nome, @@ -3076,11 +3076,11 @@ CREATE [VIEW] views.loc_vila_p as longitude_gms as longitude_gms, geom as geom [FROM] - cb.loc_vila_p + cb.loc_vila_p left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = loc_vila_p.geometriaaproximada # DROP VIEW IF EXISTS views.hid_fonte_dagua_p# -CREATE [VIEW] views.hid_fonte_dagua_p as +CREATE [VIEW] views.hid_fonte_dagua_p as SELECT id as id, nome as nome, @@ -3091,14 +3091,14 @@ CREATE [VIEW] views.hid_fonte_dagua_p as dominio_regime.code_name as regime, geom as geom [FROM] - cb.hid_fonte_dagua_p - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = hid_fonte_dagua_p.geometriaaproximada - left join dominios.tipofontedagua as dominio_tipofontedagua on dominio_tipofontedagua.code = hid_fonte_dagua_p.tipofontedagua - left join dominios.qualidagua as dominio_qualidagua on dominio_qualidagua.code = hid_fonte_dagua_p.qualidagua + cb.hid_fonte_dagua_p + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = hid_fonte_dagua_p.geometriaaproximada + left join dominios.tipofontedagua as dominio_tipofontedagua on dominio_tipofontedagua.code = hid_fonte_dagua_p.tipofontedagua + left join dominios.qualidagua as dominio_qualidagua on dominio_qualidagua.code = hid_fonte_dagua_p.qualidagua left join dominios.regime as dominio_regime on dominio_regime.code = hid_fonte_dagua_p.regime # DROP VIEW IF EXISTS views.loc_capital_p# -CREATE [VIEW] views.loc_capital_p as +CREATE [VIEW] views.loc_capital_p as SELECT id as id, nome as nome, @@ -3113,12 +3113,12 @@ CREATE [VIEW] views.loc_capital_p as geom as geom, dominio_tipocapital.code_name as tipocapital [FROM] - cb.loc_capital_p - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = loc_capital_p.geometriaaproximada + cb.loc_capital_p + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = loc_capital_p.geometriaaproximada left join dominios.tipocapital as dominio_tipocapital on dominio_tipocapital.code = loc_capital_p.tipocapital # DROP VIEW IF EXISTS views.hid_natureza_fundo_l# -CREATE [VIEW] views.hid_natureza_fundo_l as +CREATE [VIEW] views.hid_natureza_fundo_l as SELECT id as id, nome as nome, @@ -3128,13 +3128,13 @@ CREATE [VIEW] views.hid_natureza_fundo_l as dominio_espessalgas.code_name as espessalgas, geom as geom [FROM] - cb.hid_natureza_fundo_l - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = hid_natureza_fundo_l.geometriaaproximada - left join dominios.materialpredominante as dominio_materialpredominante on dominio_materialpredominante.code = hid_natureza_fundo_l.materialpredominante + cb.hid_natureza_fundo_l + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = hid_natureza_fundo_l.geometriaaproximada + left join dominios.materialpredominante as dominio_materialpredominante on dominio_materialpredominante.code = hid_natureza_fundo_l.materialpredominante left join dominios.espessalgas as dominio_espessalgas on dominio_espessalgas.code = hid_natureza_fundo_l.espessalgas # DROP VIEW IF EXISTS views.lim_area_politico_adm_a# -CREATE [VIEW] views.lim_area_politico_adm_a as +CREATE [VIEW] views.lim_area_politico_adm_a as SELECT id as id, nome as nome, @@ -3142,11 +3142,11 @@ CREATE [VIEW] views.lim_area_politico_adm_a as dominio_geometriaaproximada.code_name as geometriaaproximada, geom as geom [FROM] - cb.lim_area_politico_adm_a + cb.lim_area_politico_adm_a left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = lim_area_politico_adm_a.geometriaaproximada # DROP VIEW IF EXISTS views.eco_deposito_geral_p# -CREATE [VIEW] views.eco_deposito_geral_p as +CREATE [VIEW] views.eco_deposito_geral_p as SELECT id as id, nome as nome, @@ -3170,31 +3170,31 @@ CREATE [VIEW] views.eco_deposito_geral_p as id_org_industrial as id_org_industrial, geom as geom [FROM] - cb.eco_deposito_geral_p - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = eco_deposito_geral_p.geometriaaproximada - left join dominios.operacional as dominio_operacional on dominio_operacional.code = eco_deposito_geral_p.operacional - left join dominios.situacaofisica as dominio_situacaofisica on dominio_situacaofisica.code = eco_deposito_geral_p.situacaofisica - left join dominios.tipodepgeral as dominio_tipodepgeral on dominio_tipodepgeral.code = eco_deposito_geral_p.tipodepgeral - left join dominios.matconstr as dominio_matconstr on dominio_matconstr.code = eco_deposito_geral_p.matconstr - left join dominios.tipoexposicao as dominio_tipoexposicao on dominio_tipoexposicao.code = eco_deposito_geral_p.tipoexposicao - left join dominios.tipoprodutoresiduo as dominio_tipoprodutoresiduo on dominio_tipoprodutoresiduo.code = eco_deposito_geral_p.tipoprodutoresiduo - left join dominios.tipoconteudo as dominio_tipoconteudo on dominio_tipoconteudo.code = eco_deposito_geral_p.tipoconteudo - left join dominios.unidadevolume as dominio_unidadevolume on dominio_unidadevolume.code = eco_deposito_geral_p.unidadevolume + cb.eco_deposito_geral_p + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = eco_deposito_geral_p.geometriaaproximada + left join dominios.operacional as dominio_operacional on dominio_operacional.code = eco_deposito_geral_p.operacional + left join dominios.situacaofisica as dominio_situacaofisica on dominio_situacaofisica.code = eco_deposito_geral_p.situacaofisica + left join dominios.tipodepgeral as dominio_tipodepgeral on dominio_tipodepgeral.code = eco_deposito_geral_p.tipodepgeral + left join dominios.matconstr as dominio_matconstr on dominio_matconstr.code = eco_deposito_geral_p.matconstr + left join dominios.tipoexposicao as dominio_tipoexposicao on dominio_tipoexposicao.code = eco_deposito_geral_p.tipoexposicao + left join dominios.tipoprodutoresiduo as dominio_tipoprodutoresiduo on dominio_tipoprodutoresiduo.code = eco_deposito_geral_p.tipoprodutoresiduo + left join dominios.tipoconteudo as dominio_tipoconteudo on dominio_tipoconteudo.code = eco_deposito_geral_p.tipoconteudo + left join dominios.unidadevolume as dominio_unidadevolume on dominio_unidadevolume.code = eco_deposito_geral_p.unidadevolume left join dominios.tratamento as dominio_tratamento on dominio_tratamento.code = eco_deposito_geral_p.tratamento # DROP VIEW IF EXISTS views.sau_area_servico_social_a# -CREATE [VIEW] views.sau_area_servico_social_a as +CREATE [VIEW] views.sau_area_servico_social_a as SELECT id as id, dominio_geometriaaproximada.code_name as geometriaaproximada, id_org_servico_social as id_org_servico_social, geom as geom [FROM] - cb.sau_area_servico_social_a + cb.sau_area_servico_social_a left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = sau_area_servico_social_a.geometriaaproximada # DROP VIEW IF EXISTS views.edu_ruina_a# -CREATE [VIEW] views.edu_ruina_a as +CREATE [VIEW] views.edu_ruina_a as SELECT id as id, nome as nome, @@ -3203,11 +3203,11 @@ CREATE [VIEW] views.edu_ruina_a as id_complexo_lazer as id_complexo_lazer, geom as geom [FROM] - cb.edu_ruina_a + cb.edu_ruina_a left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = edu_ruina_a.geometriaaproximada # DROP VIEW IF EXISTS views.edu_pista_competicao_l# -CREATE [VIEW] views.edu_pista_competicao_l as +CREATE [VIEW] views.edu_pista_competicao_l as SELECT id as id, nome as nome, @@ -3219,14 +3219,14 @@ CREATE [VIEW] views.edu_pista_competicao_l as id_complexo_lazer as id_complexo_lazer, geom as geom [FROM] - cb.edu_pista_competicao_l - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = edu_pista_competicao_l.geometriaaproximada - left join dominios.operacional as dominio_operacional on dominio_operacional.code = edu_pista_competicao_l.operacional - left join dominios.situacaofisica as dominio_situacaofisica on dominio_situacaofisica.code = edu_pista_competicao_l.situacaofisica + cb.edu_pista_competicao_l + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = edu_pista_competicao_l.geometriaaproximada + left join dominios.operacional as dominio_operacional on dominio_operacional.code = edu_pista_competicao_l.operacional + left join dominios.situacaofisica as dominio_situacaofisica on dominio_situacaofisica.code = edu_pista_competicao_l.situacaofisica left join dominios.tipopista as dominio_tipopista on dominio_tipopista.code = edu_pista_competicao_l.tipopista # DROP VIEW IF EXISTS views.rel_duna_p# -CREATE [VIEW] views.rel_duna_p as +CREATE [VIEW] views.rel_duna_p as SELECT id as id, nome as nome, @@ -3236,25 +3236,25 @@ CREATE [VIEW] views.rel_duna_p as geom as geom, dominio_fixa.code_name as fixa [FROM] - cb.rel_duna_p - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = rel_duna_p.geometriaaproximada - left join dominios.tipoelemnat as dominio_tipoelemnat on dominio_tipoelemnat.code = rel_duna_p.tipoelemnat + cb.rel_duna_p + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = rel_duna_p.geometriaaproximada + left join dominios.tipoelemnat as dominio_tipoelemnat on dominio_tipoelemnat.code = rel_duna_p.tipoelemnat left join dominios.fixa as dominio_fixa on dominio_fixa.code = rel_duna_p.fixa # DROP VIEW IF EXISTS views.asb_descontinuidade_geometrica_p# -CREATE [VIEW] views.asb_descontinuidade_geometrica_p as +CREATE [VIEW] views.asb_descontinuidade_geometrica_p as SELECT id as id, dominio_geometriaaproximada.code_name as geometriaaproximada, dominio_motivodescontinuidade.code_name as motivodescontinuidade, geom as geom [FROM] - cb.asb_descontinuidade_geometrica_p - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = asb_descontinuidade_geometrica_p.geometriaaproximada + cb.asb_descontinuidade_geometrica_p + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = asb_descontinuidade_geometrica_p.geometriaaproximada left join dominios.motivodescontinuidade as dominio_motivodescontinuidade on dominio_motivodescontinuidade.code = asb_descontinuidade_geometrica_p.motivodescontinuidade # DROP VIEW IF EXISTS views.tra_entroncamento_p# -CREATE [VIEW] views.tra_entroncamento_p as +CREATE [VIEW] views.tra_entroncamento_p as SELECT id as id, nome as nome, @@ -3263,12 +3263,12 @@ CREATE [VIEW] views.tra_entroncamento_p as dominio_tipoentroncamento.code_name as tipoentroncamento, geom as geom [FROM] - cb.tra_entroncamento_p - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = tra_entroncamento_p.geometriaaproximada + cb.tra_entroncamento_p + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = tra_entroncamento_p.geometriaaproximada left join dominios.tipoentroncamento as dominio_tipoentroncamento on dominio_tipoentroncamento.code = tra_entroncamento_p.tipoentroncamento # DROP VIEW IF EXISTS views.eco_edif_industrial_a# -CREATE [VIEW] views.eco_edif_industrial_a as +CREATE [VIEW] views.eco_edif_industrial_a as SELECT id as id, nome as nome, @@ -3282,16 +3282,16 @@ CREATE [VIEW] views.eco_edif_industrial_a as dominio_tipodivisaocnae.code_name as tipodivisaocnae, id_org_industrial as id_org_industrial [FROM] - cb.eco_edif_industrial_a - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = eco_edif_industrial_a.geometriaaproximada - left join dominios.operacional as dominio_operacional on dominio_operacional.code = eco_edif_industrial_a.operacional - left join dominios.situacaofisica as dominio_situacaofisica on dominio_situacaofisica.code = eco_edif_industrial_a.situacaofisica - left join dominios.matconstr as dominio_matconstr on dominio_matconstr.code = eco_edif_industrial_a.matconstr - left join dominios.chamine as dominio_chamine on dominio_chamine.code = eco_edif_industrial_a.chamine + cb.eco_edif_industrial_a + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = eco_edif_industrial_a.geometriaaproximada + left join dominios.operacional as dominio_operacional on dominio_operacional.code = eco_edif_industrial_a.operacional + left join dominios.situacaofisica as dominio_situacaofisica on dominio_situacaofisica.code = eco_edif_industrial_a.situacaofisica + left join dominios.matconstr as dominio_matconstr on dominio_matconstr.code = eco_edif_industrial_a.matconstr + left join dominios.chamine as dominio_chamine on dominio_chamine.code = eco_edif_industrial_a.chamine left join dominios.tipodivisaocnae as dominio_tipodivisaocnae on dominio_tipodivisaocnae.code = eco_edif_industrial_a.tipodivisaocnae # DROP VIEW IF EXISTS views.hid_ilha_p# -CREATE [VIEW] views.hid_ilha_p as +CREATE [VIEW] views.hid_ilha_p as SELECT id as id, nome as nome, @@ -3301,13 +3301,13 @@ CREATE [VIEW] views.hid_ilha_p as geom as geom, dominio_tipoilha.code_name as tipoilha [FROM] - cb.hid_ilha_p - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = hid_ilha_p.geometriaaproximada - left join dominios.tipoelemnat as dominio_tipoelemnat on dominio_tipoelemnat.code = hid_ilha_p.tipoelemnat + cb.hid_ilha_p + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = hid_ilha_p.geometriaaproximada + left join dominios.tipoelemnat as dominio_tipoelemnat on dominio_tipoelemnat.code = hid_ilha_p.tipoelemnat left join dominios.tipoilha as dominio_tipoilha on dominio_tipoilha.code = hid_ilha_p.tipoilha # DROP VIEW IF EXISTS views.edu_ruina_p# -CREATE [VIEW] views.edu_ruina_p as +CREATE [VIEW] views.edu_ruina_p as SELECT id as id, nome as nome, @@ -3316,22 +3316,22 @@ CREATE [VIEW] views.edu_ruina_p as id_complexo_lazer as id_complexo_lazer, geom as geom [FROM] - cb.edu_ruina_p + cb.edu_ruina_p left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = edu_ruina_p.geometriaaproximada # DROP VIEW IF EXISTS views.eco_area_industrial_a# -CREATE [VIEW] views.eco_area_industrial_a as +CREATE [VIEW] views.eco_area_industrial_a as SELECT id as id, dominio_geometriaaproximada.code_name as geometriaaproximada, id_org_industrial as id_org_industrial, geom as geom [FROM] - cb.eco_area_industrial_a + cb.eco_area_industrial_a left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = eco_area_industrial_a.geometriaaproximada # DROP VIEW IF EXISTS views.lim_marco_de_limite_p# -CREATE [VIEW] views.lim_marco_de_limite_p as +CREATE [VIEW] views.lim_marco_de_limite_p as SELECT id as id, nome as nome, @@ -3350,14 +3350,14 @@ CREATE [VIEW] views.lim_marco_de_limite_p as orgresp as orgresp, geom as geom [FROM] - cb.lim_marco_de_limite_p - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = lim_marco_de_limite_p.geometriaaproximada - left join dominios.tipomarcolim as dominio_tipomarcolim on dominio_tipomarcolim.code = lim_marco_de_limite_p.tipomarcolim - left join dominios.sistemageodesico as dominio_sistemageodesico on dominio_sistemageodesico.code = lim_marco_de_limite_p.sistemageodesico + cb.lim_marco_de_limite_p + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = lim_marco_de_limite_p.geometriaaproximada + left join dominios.tipomarcolim as dominio_tipomarcolim on dominio_tipomarcolim.code = lim_marco_de_limite_p.tipomarcolim + left join dominios.sistemageodesico as dominio_sistemageodesico on dominio_sistemageodesico.code = lim_marco_de_limite_p.sistemageodesico left join dominios.referencialaltim as dominio_referencialaltim on dominio_referencialaltim.code = lim_marco_de_limite_p.referencialaltim # DROP VIEW IF EXISTS views.hid_ilha_l# -CREATE [VIEW] views.hid_ilha_l as +CREATE [VIEW] views.hid_ilha_l as SELECT id as id, nome as nome, @@ -3367,13 +3367,13 @@ CREATE [VIEW] views.hid_ilha_l as geom as geom, dominio_tipoilha.code_name as tipoilha [FROM] - cb.hid_ilha_l - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = hid_ilha_l.geometriaaproximada - left join dominios.tipoelemnat as dominio_tipoelemnat on dominio_tipoelemnat.code = hid_ilha_l.tipoelemnat + cb.hid_ilha_l + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = hid_ilha_l.geometriaaproximada + left join dominios.tipoelemnat as dominio_tipoelemnat on dominio_tipoelemnat.code = hid_ilha_l.tipoelemnat left join dominios.tipoilha as dominio_tipoilha on dominio_tipoilha.code = hid_ilha_l.tipoilha # DROP VIEW IF EXISTS views.rel_duna_a# -CREATE [VIEW] views.rel_duna_a as +CREATE [VIEW] views.rel_duna_a as SELECT id as id, nome as nome, @@ -3383,13 +3383,13 @@ CREATE [VIEW] views.rel_duna_a as geom as geom, dominio_fixa.code_name as fixa [FROM] - cb.rel_duna_a - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = rel_duna_a.geometriaaproximada - left join dominios.tipoelemnat as dominio_tipoelemnat on dominio_tipoelemnat.code = rel_duna_a.tipoelemnat + cb.rel_duna_a + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = rel_duna_a.geometriaaproximada + left join dominios.tipoelemnat as dominio_tipoelemnat on dominio_tipoelemnat.code = rel_duna_a.tipoelemnat left join dominios.fixa as dominio_fixa on dominio_fixa.code = rel_duna_a.fixa # DROP VIEW IF EXISTS views.lim_limite_area_especial_l# -CREATE [VIEW] views.lim_limite_area_especial_l as +CREATE [VIEW] views.lim_limite_area_especial_l as SELECT id as id, nome as nome, @@ -3401,25 +3401,25 @@ CREATE [VIEW] views.lim_limite_area_especial_l as dominio_tipolimareaesp.code_name as tipolimareaesp, obssituacao as obssituacao [FROM] - cb.lim_limite_area_especial_l - left join dominios.coincidecomdentrode_lim as dominio_coincidecomdentrode on dominio_coincidecomdentrode.code = lim_limite_area_especial_l.coincidecomdentrode - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = lim_limite_area_especial_l.geometriaaproximada + cb.lim_limite_area_especial_l + left join dominios.coincidecomdentrode_lim as dominio_coincidecomdentrode on dominio_coincidecomdentrode.code = lim_limite_area_especial_l.coincidecomdentrode + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = lim_limite_area_especial_l.geometriaaproximada left join dominios.tipolimareaesp as dominio_tipolimareaesp on dominio_tipolimareaesp.code = lim_limite_area_especial_l.tipolimareaesp # DROP VIEW IF EXISTS views.asb_descontinuidade_geometrica_a# -CREATE [VIEW] views.asb_descontinuidade_geometrica_a as +CREATE [VIEW] views.asb_descontinuidade_geometrica_a as SELECT id as id, dominio_geometriaaproximada.code_name as geometriaaproximada, dominio_motivodescontinuidade.code_name as motivodescontinuidade, geom as geom [FROM] - cb.asb_descontinuidade_geometrica_a - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = asb_descontinuidade_geometrica_a.geometriaaproximada + cb.asb_descontinuidade_geometrica_a + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = asb_descontinuidade_geometrica_a.geometriaaproximada left join dominios.motivodescontinuidade as dominio_motivodescontinuidade on dominio_motivodescontinuidade.code = asb_descontinuidade_geometrica_a.motivodescontinuidade # DROP VIEW IF EXISTS views.tra_funicular_l# -CREATE [VIEW] views.tra_funicular_l as +CREATE [VIEW] views.tra_funicular_l as SELECT id as id, nome as nome, @@ -3431,13 +3431,13 @@ CREATE [VIEW] views.tra_funicular_l as id_complexo_lazer as id_complexo_lazer, geom as geom [FROM] - cb.tra_funicular_l - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = tra_funicular_l.geometriaaproximada - left join dominios.operacional as dominio_operacional on dominio_operacional.code = tra_funicular_l.operacional + cb.tra_funicular_l + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = tra_funicular_l.geometriaaproximada + left join dominios.operacional as dominio_operacional on dominio_operacional.code = tra_funicular_l.operacional left join dominios.situacaofisica as dominio_situacaofisica on dominio_situacaofisica.code = tra_funicular_l.situacaofisica # DROP VIEW IF EXISTS views.eco_edif_industrial_p# -CREATE [VIEW] views.eco_edif_industrial_p as +CREATE [VIEW] views.eco_edif_industrial_p as SELECT id as id, nome as nome, @@ -3451,16 +3451,16 @@ CREATE [VIEW] views.eco_edif_industrial_p as dominio_tipodivisaocnae.code_name as tipodivisaocnae, id_org_industrial as id_org_industrial [FROM] - cb.eco_edif_industrial_p - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = eco_edif_industrial_p.geometriaaproximada - left join dominios.operacional as dominio_operacional on dominio_operacional.code = eco_edif_industrial_p.operacional - left join dominios.situacaofisica as dominio_situacaofisica on dominio_situacaofisica.code = eco_edif_industrial_p.situacaofisica - left join dominios.matconstr as dominio_matconstr on dominio_matconstr.code = eco_edif_industrial_p.matconstr - left join dominios.chamine as dominio_chamine on dominio_chamine.code = eco_edif_industrial_p.chamine + cb.eco_edif_industrial_p + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = eco_edif_industrial_p.geometriaaproximada + left join dominios.operacional as dominio_operacional on dominio_operacional.code = eco_edif_industrial_p.operacional + left join dominios.situacaofisica as dominio_situacaofisica on dominio_situacaofisica.code = eco_edif_industrial_p.situacaofisica + left join dominios.matconstr as dominio_matconstr on dominio_matconstr.code = eco_edif_industrial_p.matconstr + left join dominios.chamine as dominio_chamine on dominio_chamine.code = eco_edif_industrial_p.chamine left join dominios.tipodivisaocnae as dominio_tipodivisaocnae on dominio_tipodivisaocnae.code = eco_edif_industrial_p.tipodivisaocnae # DROP VIEW IF EXISTS views.rel_rocha_p# -CREATE [VIEW] views.rel_rocha_p as +CREATE [VIEW] views.rel_rocha_p as SELECT id as id, nome as nome, @@ -3470,24 +3470,24 @@ CREATE [VIEW] views.rel_rocha_p as geom as geom, dominio_tiporocha.code_name as tiporocha [FROM] - cb.rel_rocha_p - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = rel_rocha_p.geometriaaproximada - left join dominios.tipoelemnat as dominio_tipoelemnat on dominio_tipoelemnat.code = rel_rocha_p.tipoelemnat + cb.rel_rocha_p + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = rel_rocha_p.geometriaaproximada + left join dominios.tipoelemnat as dominio_tipoelemnat on dominio_tipoelemnat.code = rel_rocha_p.tipoelemnat left join dominios.tiporocha as dominio_tiporocha on dominio_tiporocha.code = rel_rocha_p.tiporocha # DROP VIEW IF EXISTS views.edu_area_religiosa_a# -CREATE [VIEW] views.edu_area_religiosa_a as +CREATE [VIEW] views.edu_area_religiosa_a as SELECT id as id, dominio_geometriaaproximada.code_name as geometriaaproximada, geom as geom, id_org_religiosa as id_org_religiosa [FROM] - cb.edu_area_religiosa_a + cb.edu_area_religiosa_a left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = edu_area_religiosa_a.geometriaaproximada # DROP VIEW IF EXISTS views.tra_ponte_p# -CREATE [VIEW] views.tra_ponte_p as +CREATE [VIEW] views.tra_ponte_p as SELECT id as id, nome as nome, @@ -3508,17 +3508,17 @@ CREATE [VIEW] views.tra_ponte_p as extensao as extensao, geom as geom [FROM] - cb.tra_ponte_p - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = tra_ponte_p.geometriaaproximada - left join dominios.tipoponte as dominio_tipoponte on dominio_tipoponte.code = tra_ponte_p.tipoponte - left join dominios.modaluso as dominio_modaluso on dominio_modaluso.code = tra_ponte_p.modaluso - left join dominios.matconstr as dominio_matconstr on dominio_matconstr.code = tra_ponte_p.matconstr - left join dominios.operacional as dominio_operacional on dominio_operacional.code = tra_ponte_p.operacional - left join dominios.situacaofisica as dominio_situacaofisica on dominio_situacaofisica.code = tra_ponte_p.situacaofisica + cb.tra_ponte_p + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = tra_ponte_p.geometriaaproximada + left join dominios.tipoponte as dominio_tipoponte on dominio_tipoponte.code = tra_ponte_p.tipoponte + left join dominios.modaluso as dominio_modaluso on dominio_modaluso.code = tra_ponte_p.modaluso + left join dominios.matconstr as dominio_matconstr on dominio_matconstr.code = tra_ponte_p.matconstr + left join dominios.operacional as dominio_operacional on dominio_operacional.code = tra_ponte_p.operacional + left join dominios.situacaofisica as dominio_situacaofisica on dominio_situacaofisica.code = tra_ponte_p.situacaofisica left join dominios.posicaopista as dominio_posicaopista on dominio_posicaopista.code = tra_ponte_p.posicaopista # DROP VIEW IF EXISTS views.hid_ilha_a# -CREATE [VIEW] views.hid_ilha_a as +CREATE [VIEW] views.hid_ilha_a as SELECT id as id, nome as nome, @@ -3528,13 +3528,13 @@ CREATE [VIEW] views.hid_ilha_a as geom as geom, dominio_tipoilha.code_name as tipoilha [FROM] - cb.hid_ilha_a - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = hid_ilha_a.geometriaaproximada - left join dominios.tipoelemnat as dominio_tipoelemnat on dominio_tipoelemnat.code = hid_ilha_a.tipoelemnat + cb.hid_ilha_a + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = hid_ilha_a.geometriaaproximada + left join dominios.tipoelemnat as dominio_tipoelemnat on dominio_tipoelemnat.code = hid_ilha_a.tipoelemnat left join dominios.tipoilha as dominio_tipoilha on dominio_tipoilha.code = hid_ilha_a.tipoilha # DROP VIEW IF EXISTS views.tra_arruamento_l# -CREATE [VIEW] views.tra_arruamento_l as +CREATE [VIEW] views.tra_arruamento_l as SELECT id as id, nome as nome, @@ -3548,28 +3548,28 @@ CREATE [VIEW] views.tra_arruamento_l as dominio_canteirodivisorio.code_name as canteirodivisorio, geom as geom [FROM] - cb.tra_arruamento_l - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = tra_arruamento_l.geometriaaproximada - left join dominios.revestimento as dominio_revestimento on dominio_revestimento.code = tra_arruamento_l.revestimento - left join dominios.operacional as dominio_operacional on dominio_operacional.code = tra_arruamento_l.operacional - left join dominios.situacaofisica as dominio_situacaofisica on dominio_situacaofisica.code = tra_arruamento_l.situacaofisica - left join dominios.trafego as dominio_trafego on dominio_trafego.code = tra_arruamento_l.trafego + cb.tra_arruamento_l + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = tra_arruamento_l.geometriaaproximada + left join dominios.revestimento as dominio_revestimento on dominio_revestimento.code = tra_arruamento_l.revestimento + left join dominios.operacional as dominio_operacional on dominio_operacional.code = tra_arruamento_l.operacional + left join dominios.situacaofisica as dominio_situacaofisica on dominio_situacaofisica.code = tra_arruamento_l.situacaofisica + left join dominios.trafego as dominio_trafego on dominio_trafego.code = tra_arruamento_l.trafego left join dominios.canteirodivisorio as dominio_canteirodivisorio on dominio_canteirodivisorio.code = tra_arruamento_l.canteirodivisorio # DROP VIEW IF EXISTS views.pto_descontinuidade_geometrica_p# -CREATE [VIEW] views.pto_descontinuidade_geometrica_p as +CREATE [VIEW] views.pto_descontinuidade_geometrica_p as SELECT id as id, dominio_geometriaaproximada.code_name as geometriaaproximada, dominio_motivodescontinuidade.code_name as motivodescontinuidade, geom as geom [FROM] - cb.pto_descontinuidade_geometrica_p - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = pto_descontinuidade_geometrica_p.geometriaaproximada + cb.pto_descontinuidade_geometrica_p + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = pto_descontinuidade_geometrica_p.geometriaaproximada left join dominios.motivodescontinuidade as dominio_motivodescontinuidade on dominio_motivodescontinuidade.code = pto_descontinuidade_geometrica_p.motivodescontinuidade # DROP VIEW IF EXISTS views.hid_rocha_em_agua_a# -CREATE [VIEW] views.hid_rocha_em_agua_a as +CREATE [VIEW] views.hid_rocha_em_agua_a as SELECT id as id, nome as nome, @@ -3578,11 +3578,11 @@ CREATE [VIEW] views.hid_rocha_em_agua_a as alturalamina as alturalamina, geom as geom [FROM] - cb.hid_rocha_em_agua_a + cb.hid_rocha_em_agua_a left join dominios.situacaoemagua as dominio_situacaoemagua on dominio_situacaoemagua.code = hid_rocha_em_agua_a.situacaoemagua # DROP VIEW IF EXISTS views.tra_local_critico_p# -CREATE [VIEW] views.tra_local_critico_p as +CREATE [VIEW] views.tra_local_critico_p as SELECT id as id, nome as nome, @@ -3591,12 +3591,12 @@ CREATE [VIEW] views.tra_local_critico_p as dominio_tipolocalcrit.code_name as tipolocalcrit, geom as geom [FROM] - cb.tra_local_critico_p - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = tra_local_critico_p.geometriaaproximada + cb.tra_local_critico_p + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = tra_local_critico_p.geometriaaproximada left join dominios.tipolocalcrit as dominio_tipolocalcrit on dominio_tipolocalcrit.code = tra_local_critico_p.tipolocalcrit # DROP VIEW IF EXISTS views.hid_recife_a# -CREATE [VIEW] views.hid_recife_a as +CREATE [VIEW] views.hid_recife_a as SELECT id as id, nome as nome, @@ -3607,14 +3607,14 @@ CREATE [VIEW] views.hid_recife_a as dominio_situacaocosta.code_name as situacaocosta, geom as geom [FROM] - cb.hid_recife_a - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = hid_recife_a.geometriaaproximada - left join dominios.tiporecife as dominio_tiporecife on dominio_tiporecife.code = hid_recife_a.tiporecife - left join dominios.situamare as dominio_situamare on dominio_situamare.code = hid_recife_a.situamare + cb.hid_recife_a + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = hid_recife_a.geometriaaproximada + left join dominios.tiporecife as dominio_tiporecife on dominio_tiporecife.code = hid_recife_a.tiporecife + left join dominios.situamare as dominio_situamare on dominio_situamare.code = hid_recife_a.situamare left join dominios.situacaocosta as dominio_situacaocosta on dominio_situacaocosta.code = hid_recife_a.situacaocosta # DROP VIEW IF EXISTS views.hid_recife_l# -CREATE [VIEW] views.hid_recife_l as +CREATE [VIEW] views.hid_recife_l as SELECT id as id, nome as nome, @@ -3625,14 +3625,14 @@ CREATE [VIEW] views.hid_recife_l as dominio_situacaocosta.code_name as situacaocosta, geom as geom [FROM] - cb.hid_recife_l - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = hid_recife_l.geometriaaproximada - left join dominios.tiporecife as dominio_tiporecife on dominio_tiporecife.code = hid_recife_l.tiporecife - left join dominios.situamare as dominio_situamare on dominio_situamare.code = hid_recife_l.situamare + cb.hid_recife_l + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = hid_recife_l.geometriaaproximada + left join dominios.tiporecife as dominio_tiporecife on dominio_tiporecife.code = hid_recife_l.tiporecife + left join dominios.situamare as dominio_situamare on dominio_situamare.code = hid_recife_l.situamare left join dominios.situacaocosta as dominio_situacaocosta on dominio_situacaocosta.code = hid_recife_l.situacaocosta # DROP VIEW IF EXISTS views.veg_cerrado_cerradao_a# -CREATE [VIEW] views.veg_cerrado_cerradao_a as +CREATE [VIEW] views.veg_cerrado_cerradao_a as SELECT id as id, nome as nome, @@ -3644,15 +3644,15 @@ CREATE [VIEW] views.veg_cerrado_cerradao_a as dominio_tipocerr.code_name as tipocerr, dominio_classificacaoporte.code_name as classificacaoporte [FROM] - cb.veg_cerrado_cerradao_a - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = veg_cerrado_cerradao_a.geometriaaproximada - left join dominios.denso as dominio_denso on dominio_denso.code = veg_cerrado_cerradao_a.denso - left join dominios.antropizada as dominio_antropizada on dominio_antropizada.code = veg_cerrado_cerradao_a.antropizada - left join dominios.tipocerr as dominio_tipocerr on dominio_tipocerr.code = veg_cerrado_cerradao_a.tipocerr + cb.veg_cerrado_cerradao_a + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = veg_cerrado_cerradao_a.geometriaaproximada + left join dominios.denso as dominio_denso on dominio_denso.code = veg_cerrado_cerradao_a.denso + left join dominios.antropizada as dominio_antropizada on dominio_antropizada.code = veg_cerrado_cerradao_a.antropizada + left join dominios.tipocerr as dominio_tipocerr on dominio_tipocerr.code = veg_cerrado_cerradao_a.tipocerr left join dominios.classificacaoporte as dominio_classificacaoporte on dominio_classificacaoporte.code = veg_cerrado_cerradao_a.classificacaoporte # DROP VIEW IF EXISTS views.loc_area_habitacional_a# -CREATE [VIEW] views.loc_area_habitacional_a as +CREATE [VIEW] views.loc_area_habitacional_a as SELECT id as id, nome as nome, @@ -3661,35 +3661,35 @@ CREATE [VIEW] views.loc_area_habitacional_a as id_complexo_habitacional as id_complexo_habitacional, geom as geom [FROM] - cb.loc_area_habitacional_a + cb.loc_area_habitacional_a left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = loc_area_habitacional_a.geometriaaproximada # DROP VIEW IF EXISTS views.tra_descontinuidade_geometrica_l# -CREATE [VIEW] views.tra_descontinuidade_geometrica_l as +CREATE [VIEW] views.tra_descontinuidade_geometrica_l as SELECT id as id, dominio_geometriaaproximada.code_name as geometriaaproximada, dominio_motivodescontinuidade.code_name as motivodescontinuidade, geom as geom [FROM] - cb.tra_descontinuidade_geometrica_l - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = tra_descontinuidade_geometrica_l.geometriaaproximada + cb.tra_descontinuidade_geometrica_l + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = tra_descontinuidade_geometrica_l.geometriaaproximada left join dominios.motivodescontinuidade as dominio_motivodescontinuidade on dominio_motivodescontinuidade.code = tra_descontinuidade_geometrica_l.motivodescontinuidade # DROP VIEW IF EXISTS views.pto_descontinuidade_geometrica_a# -CREATE [VIEW] views.pto_descontinuidade_geometrica_a as +CREATE [VIEW] views.pto_descontinuidade_geometrica_a as SELECT id as id, dominio_geometriaaproximada.code_name as geometriaaproximada, dominio_motivodescontinuidade.code_name as motivodescontinuidade, geom as geom [FROM] - cb.pto_descontinuidade_geometrica_a - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = pto_descontinuidade_geometrica_a.geometriaaproximada + cb.pto_descontinuidade_geometrica_a + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = pto_descontinuidade_geometrica_a.geometriaaproximada left join dominios.motivodescontinuidade as dominio_motivodescontinuidade on dominio_motivodescontinuidade.code = pto_descontinuidade_geometrica_a.motivodescontinuidade # DROP VIEW IF EXISTS views.hid_barragem_l# -CREATE [VIEW] views.hid_barragem_l as +CREATE [VIEW] views.hid_barragem_l as SELECT id as id, nome as nome, @@ -3702,15 +3702,15 @@ CREATE [VIEW] views.hid_barragem_l as id_complexo_gerad_energ_eletr as id_complexo_gerad_energ_eletr, geom as geom [FROM] - cb.hid_barragem_l - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = hid_barragem_l.geometriaaproximada - left join dominios.matconstr as dominio_matconstr on dominio_matconstr.code = hid_barragem_l.matconstr - left join dominios.usoprincipal as dominio_usoprincipal on dominio_usoprincipal.code = hid_barragem_l.usoprincipal - left join dominios.operacional as dominio_operacional on dominio_operacional.code = hid_barragem_l.operacional + cb.hid_barragem_l + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = hid_barragem_l.geometriaaproximada + left join dominios.matconstr as dominio_matconstr on dominio_matconstr.code = hid_barragem_l.matconstr + left join dominios.usoprincipal as dominio_usoprincipal on dominio_usoprincipal.code = hid_barragem_l.usoprincipal + left join dominios.operacional as dominio_operacional on dominio_operacional.code = hid_barragem_l.operacional left join dominios.situacaofisica as dominio_situacaofisica on dominio_situacaofisica.code = hid_barragem_l.situacaofisica # DROP VIEW IF EXISTS views.tra_local_critico_a# -CREATE [VIEW] views.tra_local_critico_a as +CREATE [VIEW] views.tra_local_critico_a as SELECT id as id, nome as nome, @@ -3719,12 +3719,12 @@ CREATE [VIEW] views.tra_local_critico_a as dominio_tipolocalcrit.code_name as tipolocalcrit, geom as geom [FROM] - cb.tra_local_critico_a - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = tra_local_critico_a.geometriaaproximada + cb.tra_local_critico_a + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = tra_local_critico_a.geometriaaproximada left join dominios.tipolocalcrit as dominio_tipolocalcrit on dominio_tipolocalcrit.code = tra_local_critico_a.tipolocalcrit # DROP VIEW IF EXISTS views.hid_rocha_em_agua_p# -CREATE [VIEW] views.hid_rocha_em_agua_p as +CREATE [VIEW] views.hid_rocha_em_agua_p as SELECT id as id, nome as nome, @@ -3733,11 +3733,11 @@ CREATE [VIEW] views.hid_rocha_em_agua_p as alturalamina as alturalamina, geom as geom [FROM] - cb.hid_rocha_em_agua_p + cb.hid_rocha_em_agua_p left join dominios.situacaoemagua as dominio_situacaoemagua on dominio_situacaoemagua.code = hid_rocha_em_agua_p.situacaoemagua # DROP VIEW IF EXISTS views.tra_funicular_p# -CREATE [VIEW] views.tra_funicular_p as +CREATE [VIEW] views.tra_funicular_p as SELECT id as id, nome as nome, @@ -3749,13 +3749,13 @@ CREATE [VIEW] views.tra_funicular_p as id_complexo_lazer as id_complexo_lazer, geom as geom [FROM] - cb.tra_funicular_p - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = tra_funicular_p.geometriaaproximada - left join dominios.operacional as dominio_operacional on dominio_operacional.code = tra_funicular_p.operacional + cb.tra_funicular_p + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = tra_funicular_p.geometriaaproximada + left join dominios.operacional as dominio_operacional on dominio_operacional.code = tra_funicular_p.operacional left join dominios.situacaofisica as dominio_situacaofisica on dominio_situacaofisica.code = tra_funicular_p.situacaofisica # DROP VIEW IF EXISTS views.hid_recife_p# -CREATE [VIEW] views.hid_recife_p as +CREATE [VIEW] views.hid_recife_p as SELECT id as id, nome as nome, @@ -3766,14 +3766,14 @@ CREATE [VIEW] views.hid_recife_p as dominio_situacaocosta.code_name as situacaocosta, geom as geom [FROM] - cb.hid_recife_p - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = hid_recife_p.geometriaaproximada - left join dominios.tiporecife as dominio_tiporecife on dominio_tiporecife.code = hid_recife_p.tiporecife - left join dominios.situamare as dominio_situamare on dominio_situamare.code = hid_recife_p.situamare + cb.hid_recife_p + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = hid_recife_p.geometriaaproximada + left join dominios.tiporecife as dominio_tiporecife on dominio_tiporecife.code = hid_recife_p.tiporecife + left join dominios.situamare as dominio_situamare on dominio_situamare.code = hid_recife_p.situamare left join dominios.situacaocosta as dominio_situacaocosta on dominio_situacaocosta.code = hid_recife_p.situacaocosta # DROP VIEW IF EXISTS views.veg_macega_chavascal_a# -CREATE [VIEW] views.veg_macega_chavascal_a as +CREATE [VIEW] views.veg_macega_chavascal_a as SELECT id as id, nome as nome, @@ -3786,15 +3786,15 @@ CREATE [VIEW] views.veg_macega_chavascal_a as alturamediaindividuos as alturamediaindividuos, dominio_classificacaoporte.code_name as classificacaoporte [FROM] - cb.veg_macega_chavascal_a - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = veg_macega_chavascal_a.geometriaaproximada - left join dominios.denso as dominio_denso on dominio_denso.code = veg_macega_chavascal_a.denso - left join dominios.antropizada as dominio_antropizada on dominio_antropizada.code = veg_macega_chavascal_a.antropizada - left join dominios.tipomacchav as dominio_tipomacchav on dominio_tipomacchav.code = veg_macega_chavascal_a.tipomacchav + cb.veg_macega_chavascal_a + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = veg_macega_chavascal_a.geometriaaproximada + left join dominios.denso as dominio_denso on dominio_denso.code = veg_macega_chavascal_a.denso + left join dominios.antropizada as dominio_antropizada on dominio_antropizada.code = veg_macega_chavascal_a.antropizada + left join dominios.tipomacchav as dominio_tipomacchav on dominio_tipomacchav.code = veg_macega_chavascal_a.tipomacchav left join dominios.classificacaoporte as dominio_classificacaoporte on dominio_classificacaoporte.code = veg_macega_chavascal_a.classificacaoporte # DROP VIEW IF EXISTS views.lim_area_desenv_controle_p# -CREATE [VIEW] views.lim_area_desenv_controle_p as +CREATE [VIEW] views.lim_area_desenv_controle_p as SELECT id as id, nome as nome, @@ -3803,23 +3803,23 @@ CREATE [VIEW] views.lim_area_desenv_controle_p as geom as geom, classificacao as classificacao [FROM] - cb.lim_area_desenv_controle_p + cb.lim_area_desenv_controle_p left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = lim_area_desenv_controle_p.geometriaaproximada # DROP VIEW IF EXISTS views.asb_descontinuidade_geometrica_l# -CREATE [VIEW] views.asb_descontinuidade_geometrica_l as +CREATE [VIEW] views.asb_descontinuidade_geometrica_l as SELECT id as id, dominio_geometriaaproximada.code_name as geometriaaproximada, dominio_motivodescontinuidade.code_name as motivodescontinuidade, geom as geom [FROM] - cb.asb_descontinuidade_geometrica_l - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = asb_descontinuidade_geometrica_l.geometriaaproximada + cb.asb_descontinuidade_geometrica_l + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = asb_descontinuidade_geometrica_l.geometriaaproximada left join dominios.motivodescontinuidade as dominio_motivodescontinuidade on dominio_motivodescontinuidade.code = asb_descontinuidade_geometrica_l.motivodescontinuidade # DROP VIEW IF EXISTS views.tra_tunel_p# -CREATE [VIEW] views.tra_tunel_p as +CREATE [VIEW] views.tra_tunel_p as SELECT id as id, nome as nome, @@ -3837,17 +3837,17 @@ CREATE [VIEW] views.tra_tunel_p as extensao as extensao, geom as geom [FROM] - cb.tra_tunel_p - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = tra_tunel_p.geometriaaproximada - left join dominios.tipotunel as dominio_tipotunel on dominio_tipotunel.code = tra_tunel_p.tipotunel - left join dominios.modaluso as dominio_modaluso on dominio_modaluso.code = tra_tunel_p.modaluso - left join dominios.matconstr as dominio_matconstr on dominio_matconstr.code = tra_tunel_p.matconstr - left join dominios.operacional as dominio_operacional on dominio_operacional.code = tra_tunel_p.operacional - left join dominios.situacaofisica as dominio_situacaofisica on dominio_situacaofisica.code = tra_tunel_p.situacaofisica + cb.tra_tunel_p + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = tra_tunel_p.geometriaaproximada + left join dominios.tipotunel as dominio_tipotunel on dominio_tipotunel.code = tra_tunel_p.tipotunel + left join dominios.modaluso as dominio_modaluso on dominio_modaluso.code = tra_tunel_p.modaluso + left join dominios.matconstr as dominio_matconstr on dominio_matconstr.code = tra_tunel_p.matconstr + left join dominios.operacional as dominio_operacional on dominio_operacional.code = tra_tunel_p.operacional + left join dominios.situacaofisica as dominio_situacaofisica on dominio_situacaofisica.code = tra_tunel_p.situacaofisica left join dominios.posicaopista as dominio_posicaopista on dominio_posicaopista.code = tra_tunel_p.posicaopista # DROP VIEW IF EXISTS views.loc_aglomerado_rural_isolado_p# -CREATE [VIEW] views.loc_aglomerado_rural_isolado_p as +CREATE [VIEW] views.loc_aglomerado_rural_isolado_p as SELECT id as id, nome as nome, @@ -3862,12 +3862,12 @@ CREATE [VIEW] views.loc_aglomerado_rural_isolado_p as geom as geom, dominio_tipoaglomrurisol.code_name as tipoaglomrurisol [FROM] - cb.loc_aglomerado_rural_isolado_p - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = loc_aglomerado_rural_isolado_p.geometriaaproximada + cb.loc_aglomerado_rural_isolado_p + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = loc_aglomerado_rural_isolado_p.geometriaaproximada left join dominios.tipoaglomrurisol as dominio_tipoaglomrurisol on dominio_tipoaglomrurisol.code = loc_aglomerado_rural_isolado_p.tipoaglomrurisol # DROP VIEW IF EXISTS views.tra_obstaculo_navegacao_p# -CREATE [VIEW] views.tra_obstaculo_navegacao_p as +CREATE [VIEW] views.tra_obstaculo_navegacao_p as SELECT id as id, nome as nome, @@ -3877,13 +3877,13 @@ CREATE [VIEW] views.tra_obstaculo_navegacao_p as dominio_situacaoemagua.code_name as situacaoemagua, geom as geom [FROM] - cb.tra_obstaculo_navegacao_p - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = tra_obstaculo_navegacao_p.geometriaaproximada - left join dominios.tipoobst as dominio_tipoobst on dominio_tipoobst.code = tra_obstaculo_navegacao_p.tipoobst + cb.tra_obstaculo_navegacao_p + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = tra_obstaculo_navegacao_p.geometriaaproximada + left join dominios.tipoobst as dominio_tipoobst on dominio_tipoobst.code = tra_obstaculo_navegacao_p.tipoobst left join dominios.situacaoemagua as dominio_situacaoemagua on dominio_situacaoemagua.code = tra_obstaculo_navegacao_p.situacaoemagua # DROP VIEW IF EXISTS views.loc_area_urbana_isolada_a# -CREATE [VIEW] views.loc_area_urbana_isolada_a as +CREATE [VIEW] views.loc_area_urbana_isolada_a as SELECT id as id, dominio_geometriaaproximada.code_name as geometriaaproximada, @@ -3892,12 +3892,12 @@ CREATE [VIEW] views.loc_area_urbana_isolada_a as dominio_tipoassociado.code_name as tipoassociado, geom as geom [FROM] - cb.loc_area_urbana_isolada_a - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = loc_area_urbana_isolada_a.geometriaaproximada + cb.loc_area_urbana_isolada_a + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = loc_area_urbana_isolada_a.geometriaaproximada left join dominios.tipoassociado as dominio_tipoassociado on dominio_tipoassociado.code = loc_area_urbana_isolada_a.tipoassociado # DROP VIEW IF EXISTS views.enc_grupo_transformadores_p# -CREATE [VIEW] views.enc_grupo_transformadores_p as +CREATE [VIEW] views.enc_grupo_transformadores_p as SELECT id as id, nome as nome, @@ -3906,11 +3906,11 @@ CREATE [VIEW] views.enc_grupo_transformadores_p as id_subestacao_ener_eletr as id_subestacao_ener_eletr, geom as geom [FROM] - cb.enc_grupo_transformadores_p + cb.enc_grupo_transformadores_p left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = enc_grupo_transformadores_p.geometriaaproximada # DROP VIEW IF EXISTS views.lim_pais_a# -CREATE [VIEW] views.lim_pais_a as +CREATE [VIEW] views.lim_pais_a as SELECT id as id, nome as nome, @@ -3920,11 +3920,11 @@ CREATE [VIEW] views.lim_pais_a as sigla as sigla, codiso3166 as codiso3166 [FROM] - cb.lim_pais_a + cb.lim_pais_a left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = lim_pais_a.geometriaaproximada # DROP VIEW IF EXISTS views.asb_edif_saneamento_p# -CREATE [VIEW] views.asb_edif_saneamento_p as +CREATE [VIEW] views.asb_edif_saneamento_p as SELECT id as id, nome as nome, @@ -3937,15 +3937,15 @@ CREATE [VIEW] views.asb_edif_saneamento_p as dominio_tipoedifsaneam.code_name as tipoedifsaneam, id_complexo_saneamento as id_complexo_saneamento [FROM] - cb.asb_edif_saneamento_p - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = asb_edif_saneamento_p.geometriaaproximada - left join dominios.operacional as dominio_operacional on dominio_operacional.code = asb_edif_saneamento_p.operacional - left join dominios.situacaofisica as dominio_situacaofisica on dominio_situacaofisica.code = asb_edif_saneamento_p.situacaofisica - left join dominios.matconstr as dominio_matconstr on dominio_matconstr.code = asb_edif_saneamento_p.matconstr + cb.asb_edif_saneamento_p + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = asb_edif_saneamento_p.geometriaaproximada + left join dominios.operacional as dominio_operacional on dominio_operacional.code = asb_edif_saneamento_p.operacional + left join dominios.situacaofisica as dominio_situacaofisica on dominio_situacaofisica.code = asb_edif_saneamento_p.situacaofisica + left join dominios.matconstr as dominio_matconstr on dominio_matconstr.code = asb_edif_saneamento_p.matconstr left join dominios.tipoedifsaneam as dominio_tipoedifsaneam on dominio_tipoedifsaneam.code = asb_edif_saneamento_p.tipoedifsaneam # DROP VIEW IF EXISTS views.pto_pto_ref_geod_topo_p# -CREATE [VIEW] views.pto_pto_ref_geod_topo_p as +CREATE [VIEW] views.pto_pto_ref_geod_topo_p as SELECT id as id, nomeabrev as nomeabrev, @@ -3970,19 +3970,19 @@ CREATE [VIEW] views.pto_pto_ref_geod_topo_p as dominio_situacaomarco.code_name as situacaomarco, datavisita as datavisita [FROM] - cb.pto_pto_ref_geod_topo_p - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = pto_pto_ref_geod_topo_p.geometriaaproximada - left join dominios.tiporef as dominio_tiporef on dominio_tiporef.code = pto_pto_ref_geod_topo_p.tiporef - left join dominios.sistemageodesico as dominio_sistemageodesico on dominio_sistemageodesico.code = pto_pto_ref_geod_topo_p.sistemageodesico - left join dominios.referencialaltim as dominio_referencialaltim on dominio_referencialaltim.code = pto_pto_ref_geod_topo_p.referencialaltim - left join dominios.proximidade as dominio_proximidade on dominio_proximidade.code = pto_pto_ref_geod_topo_p.proximidade - left join dominios.tipoptorefgeodtopo as dominio_tipoptorefgeodtopo on dominio_tipoptorefgeodtopo.code = pto_pto_ref_geod_topo_p.tipoptorefgeodtopo - left join dominios.rede as dominio_rede on dominio_rede.code = pto_pto_ref_geod_topo_p.rede - left join dominios.referencialgrav as dominio_referencialgrav on dominio_referencialgrav.code = pto_pto_ref_geod_topo_p.referencialgrav + cb.pto_pto_ref_geod_topo_p + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = pto_pto_ref_geod_topo_p.geometriaaproximada + left join dominios.tiporef as dominio_tiporef on dominio_tiporef.code = pto_pto_ref_geod_topo_p.tiporef + left join dominios.sistemageodesico as dominio_sistemageodesico on dominio_sistemageodesico.code = pto_pto_ref_geod_topo_p.sistemageodesico + left join dominios.referencialaltim as dominio_referencialaltim on dominio_referencialaltim.code = pto_pto_ref_geod_topo_p.referencialaltim + left join dominios.proximidade as dominio_proximidade on dominio_proximidade.code = pto_pto_ref_geod_topo_p.proximidade + left join dominios.tipoptorefgeodtopo as dominio_tipoptorefgeodtopo on dominio_tipoptorefgeodtopo.code = pto_pto_ref_geod_topo_p.tipoptorefgeodtopo + left join dominios.rede as dominio_rede on dominio_rede.code = pto_pto_ref_geod_topo_p.rede + left join dominios.referencialgrav as dominio_referencialgrav on dominio_referencialgrav.code = pto_pto_ref_geod_topo_p.referencialgrav left join dominios.situacaomarco as dominio_situacaomarco on dominio_situacaomarco.code = pto_pto_ref_geod_topo_p.situacaomarco # DROP VIEW IF EXISTS views.rel_curva_batimetrica_l# -CREATE [VIEW] views.rel_curva_batimetrica_l as +CREATE [VIEW] views.rel_curva_batimetrica_l as SELECT id as id, profundidade as profundidade, @@ -3991,7 +3991,7 @@ CREATE [VIEW] views.rel_curva_batimetrica_l as cb.rel_curva_batimetrica_l # DROP VIEW IF EXISTS views.veg_floresta_a# -CREATE [VIEW] views.veg_floresta_a as +CREATE [VIEW] views.veg_floresta_a as SELECT id as id, nome as nome, @@ -4005,16 +4005,16 @@ CREATE [VIEW] views.veg_floresta_a as alturamediaindividuos as alturamediaindividuos, dominio_classificacaoporte.code_name as classificacaoporte [FROM] - cb.veg_floresta_a - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = veg_floresta_a.geometriaaproximada - left join dominios.denso as dominio_denso on dominio_denso.code = veg_floresta_a.denso - left join dominios.antropizada as dominio_antropizada on dominio_antropizada.code = veg_floresta_a.antropizada - left join dominios.especiepredominante as dominio_especiepredominante on dominio_especiepredominante.code = veg_floresta_a.especiepredominante - left join dominios.caracteristicafloresta as dominio_caracteristicafloresta on dominio_caracteristicafloresta.code = veg_floresta_a.caracteristicafloresta + cb.veg_floresta_a + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = veg_floresta_a.geometriaaproximada + left join dominios.denso as dominio_denso on dominio_denso.code = veg_floresta_a.denso + left join dominios.antropizada as dominio_antropizada on dominio_antropizada.code = veg_floresta_a.antropizada + left join dominios.especiepredominante as dominio_especiepredominante on dominio_especiepredominante.code = veg_floresta_a.especiepredominante + left join dominios.caracteristicafloresta as dominio_caracteristicafloresta on dominio_caracteristicafloresta.code = veg_floresta_a.caracteristicafloresta left join dominios.classificacaoporte as dominio_classificacaoporte on dominio_classificacaoporte.code = veg_floresta_a.classificacaoporte # DROP VIEW IF EXISTS views.lim_outros_limites_oficiais_l# -CREATE [VIEW] views.lim_outros_limites_oficiais_l as +CREATE [VIEW] views.lim_outros_limites_oficiais_l as SELECT id as id, nome as nome, @@ -4026,13 +4026,13 @@ CREATE [VIEW] views.lim_outros_limites_oficiais_l as dominio_tipooutlimofic.code_name as tipooutlimofic, obssituacao as obssituacao [FROM] - cb.lim_outros_limites_oficiais_l - left join dominios.coincidecomdentrode_lim as dominio_coincidecomdentrode on dominio_coincidecomdentrode.code = lim_outros_limites_oficiais_l.coincidecomdentrode - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = lim_outros_limites_oficiais_l.geometriaaproximada + cb.lim_outros_limites_oficiais_l + left join dominios.coincidecomdentrode_lim as dominio_coincidecomdentrode on dominio_coincidecomdentrode.code = lim_outros_limites_oficiais_l.coincidecomdentrode + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = lim_outros_limites_oficiais_l.geometriaaproximada left join dominios.tipooutlimofic as dominio_tipooutlimofic on dominio_tipooutlimofic.code = lim_outros_limites_oficiais_l.tipooutlimofic # DROP VIEW IF EXISTS views.adm_edif_pub_militar_a# -CREATE [VIEW] views.adm_edif_pub_militar_a as +CREATE [VIEW] views.adm_edif_pub_militar_a as SELECT id as id, nome as nome, @@ -4046,16 +4046,16 @@ CREATE [VIEW] views.adm_edif_pub_militar_a as dominio_tipousoedif.code_name as tipousoedif, id_org_pub_militar as id_org_pub_militar [FROM] - cb.adm_edif_pub_militar_a - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = adm_edif_pub_militar_a.geometriaaproximada - left join dominios.operacional as dominio_operacional on dominio_operacional.code = adm_edif_pub_militar_a.operacional - left join dominios.situacaofisica as dominio_situacaofisica on dominio_situacaofisica.code = adm_edif_pub_militar_a.situacaofisica - left join dominios.matconstr as dominio_matconstr on dominio_matconstr.code = adm_edif_pub_militar_a.matconstr - left join dominios.tipoedifmil as dominio_tipoedifmil on dominio_tipoedifmil.code = adm_edif_pub_militar_a.tipoedifmil + cb.adm_edif_pub_militar_a + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = adm_edif_pub_militar_a.geometriaaproximada + left join dominios.operacional as dominio_operacional on dominio_operacional.code = adm_edif_pub_militar_a.operacional + left join dominios.situacaofisica as dominio_situacaofisica on dominio_situacaofisica.code = adm_edif_pub_militar_a.situacaofisica + left join dominios.matconstr as dominio_matconstr on dominio_matconstr.code = adm_edif_pub_militar_a.matconstr + left join dominios.tipoedifmil as dominio_tipoedifmil on dominio_tipoedifmil.code = adm_edif_pub_militar_a.tipoedifmil left join dominios.tipousoedif as dominio_tipousoedif on dominio_tipousoedif.code = adm_edif_pub_militar_a.tipousoedif # DROP VIEW IF EXISTS views.eco_area_agrop_ext_veg_pesca_a# -CREATE [VIEW] views.eco_area_agrop_ext_veg_pesca_a as +CREATE [VIEW] views.eco_area_agrop_ext_veg_pesca_a as SELECT id as id, dominio_geometriaaproximada.code_name as geometriaaproximada, @@ -4063,12 +4063,12 @@ CREATE [VIEW] views.eco_area_agrop_ext_veg_pesca_a as id_org_agropec_ext_veg_pesca as id_org_agropec_ext_veg_pesca, geom as geom [FROM] - cb.eco_area_agrop_ext_veg_pesca_a - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = eco_area_agrop_ext_veg_pesca_a.geometriaaproximada + cb.eco_area_agrop_ext_veg_pesca_a + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = eco_area_agrop_ext_veg_pesca_a.geometriaaproximada left join dominios.destinadoa as dominio_destinadoa on dominio_destinadoa.code = eco_area_agrop_ext_veg_pesca_a.destinadoa # DROP VIEW IF EXISTS views.rel_ponto_cotado_batimetrico_p# -CREATE [VIEW] views.rel_ponto_cotado_batimetrico_p as +CREATE [VIEW] views.rel_ponto_cotado_batimetrico_p as SELECT id as id, profundidade as profundidade, @@ -4077,7 +4077,7 @@ CREATE [VIEW] views.rel_ponto_cotado_batimetrico_p as cb.rel_ponto_cotado_batimetrico_p # DROP VIEW IF EXISTS views.tra_obstaculo_navegacao_a# -CREATE [VIEW] views.tra_obstaculo_navegacao_a as +CREATE [VIEW] views.tra_obstaculo_navegacao_a as SELECT id as id, nome as nome, @@ -4087,13 +4087,13 @@ CREATE [VIEW] views.tra_obstaculo_navegacao_a as dominio_situacaoemagua.code_name as situacaoemagua, geom as geom [FROM] - cb.tra_obstaculo_navegacao_a - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = tra_obstaculo_navegacao_a.geometriaaproximada - left join dominios.tipoobst as dominio_tipoobst on dominio_tipoobst.code = tra_obstaculo_navegacao_a.tipoobst + cb.tra_obstaculo_navegacao_a + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = tra_obstaculo_navegacao_a.geometriaaproximada + left join dominios.tipoobst as dominio_tipoobst on dominio_tipoobst.code = tra_obstaculo_navegacao_a.tipoobst left join dominios.situacaoemagua as dominio_situacaoemagua on dominio_situacaoemagua.code = tra_obstaculo_navegacao_a.situacaoemagua # DROP VIEW IF EXISTS views.enc_grupo_transformadores_a# -CREATE [VIEW] views.enc_grupo_transformadores_a as +CREATE [VIEW] views.enc_grupo_transformadores_a as SELECT id as id, nome as nome, @@ -4102,23 +4102,23 @@ CREATE [VIEW] views.enc_grupo_transformadores_a as id_subestacao_ener_eletr as id_subestacao_ener_eletr, geom as geom [FROM] - cb.enc_grupo_transformadores_a + cb.enc_grupo_transformadores_a left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = enc_grupo_transformadores_a.geometriaaproximada # DROP VIEW IF EXISTS views.lim_descontinuidade_geometrica_p# -CREATE [VIEW] views.lim_descontinuidade_geometrica_p as +CREATE [VIEW] views.lim_descontinuidade_geometrica_p as SELECT id as id, dominio_geometriaaproximada.code_name as geometriaaproximada, dominio_motivodescontinuidade.code_name as motivodescontinuidade, geom as geom [FROM] - cb.lim_descontinuidade_geometrica_p - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = lim_descontinuidade_geometrica_p.geometriaaproximada + cb.lim_descontinuidade_geometrica_p + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = lim_descontinuidade_geometrica_p.geometriaaproximada left join dominios.motivodescontinuidade as dominio_motivodescontinuidade on dominio_motivodescontinuidade.code = lim_descontinuidade_geometrica_p.motivodescontinuidade # DROP VIEW IF EXISTS views.veg_estepe_a# -CREATE [VIEW] views.veg_estepe_a as +CREATE [VIEW] views.veg_estepe_a as SELECT id as id, nome as nome, @@ -4129,13 +4129,13 @@ CREATE [VIEW] views.veg_estepe_a as geom as geom, alturamediaindividuos as alturamediaindividuos [FROM] - cb.veg_estepe_a - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = veg_estepe_a.geometriaaproximada - left join dominios.denso as dominio_denso on dominio_denso.code = veg_estepe_a.denso + cb.veg_estepe_a + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = veg_estepe_a.geometriaaproximada + left join dominios.denso as dominio_denso on dominio_denso.code = veg_estepe_a.denso left join dominios.antropizada as dominio_antropizada on dominio_antropizada.code = veg_estepe_a.antropizada # DROP VIEW IF EXISTS views.tra_obstaculo_navegacao_l# -CREATE [VIEW] views.tra_obstaculo_navegacao_l as +CREATE [VIEW] views.tra_obstaculo_navegacao_l as SELECT id as id, nome as nome, @@ -4145,13 +4145,13 @@ CREATE [VIEW] views.tra_obstaculo_navegacao_l as dominio_situacaoemagua.code_name as situacaoemagua, geom as geom [FROM] - cb.tra_obstaculo_navegacao_l - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = tra_obstaculo_navegacao_l.geometriaaproximada - left join dominios.tipoobst as dominio_tipoobst on dominio_tipoobst.code = tra_obstaculo_navegacao_l.tipoobst + cb.tra_obstaculo_navegacao_l + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = tra_obstaculo_navegacao_l.geometriaaproximada + left join dominios.tipoobst as dominio_tipoobst on dominio_tipoobst.code = tra_obstaculo_navegacao_l.tipoobst left join dominios.situacaoemagua as dominio_situacaoemagua on dominio_situacaoemagua.code = tra_obstaculo_navegacao_l.situacaoemagua # DROP VIEW IF EXISTS views.lim_limite_operacional_l# -CREATE [VIEW] views.lim_limite_operacional_l as +CREATE [VIEW] views.lim_limite_operacional_l as SELECT id as id, nome as nome, @@ -4163,13 +4163,13 @@ CREATE [VIEW] views.lim_limite_operacional_l as dominio_tipolimoper.code_name as tipolimoper, obssituacao as obssituacao [FROM] - cb.lim_limite_operacional_l - left join dominios.coincidecomdentrode_lim as dominio_coincidecomdentrode on dominio_coincidecomdentrode.code = lim_limite_operacional_l.coincidecomdentrode - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = lim_limite_operacional_l.geometriaaproximada + cb.lim_limite_operacional_l + left join dominios.coincidecomdentrode_lim as dominio_coincidecomdentrode on dominio_coincidecomdentrode.code = lim_limite_operacional_l.coincidecomdentrode + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = lim_limite_operacional_l.geometriaaproximada left join dominios.tipolimoper as dominio_tipolimoper on dominio_tipolimoper.code = lim_limite_operacional_l.tipolimoper # DROP VIEW IF EXISTS views.adm_edif_pub_militar_p# -CREATE [VIEW] views.adm_edif_pub_militar_p as +CREATE [VIEW] views.adm_edif_pub_militar_p as SELECT id as id, nome as nome, @@ -4183,16 +4183,16 @@ CREATE [VIEW] views.adm_edif_pub_militar_p as dominio_tipoedifmil.code_name as tipoedifmil, id_org_pub_militar as id_org_pub_militar [FROM] - cb.adm_edif_pub_militar_p - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = adm_edif_pub_militar_p.geometriaaproximada - left join dominios.operacional as dominio_operacional on dominio_operacional.code = adm_edif_pub_militar_p.operacional - left join dominios.situacaofisica as dominio_situacaofisica on dominio_situacaofisica.code = adm_edif_pub_militar_p.situacaofisica - left join dominios.matconstr as dominio_matconstr on dominio_matconstr.code = adm_edif_pub_militar_p.matconstr - left join dominios.tipousoedif as dominio_tipousoedif on dominio_tipousoedif.code = adm_edif_pub_militar_p.tipousoedif + cb.adm_edif_pub_militar_p + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = adm_edif_pub_militar_p.geometriaaproximada + left join dominios.operacional as dominio_operacional on dominio_operacional.code = adm_edif_pub_militar_p.operacional + left join dominios.situacaofisica as dominio_situacaofisica on dominio_situacaofisica.code = adm_edif_pub_militar_p.situacaofisica + left join dominios.matconstr as dominio_matconstr on dominio_matconstr.code = adm_edif_pub_militar_p.matconstr + left join dominios.tipousoedif as dominio_tipousoedif on dominio_tipousoedif.code = adm_edif_pub_militar_p.tipousoedif left join dominios.tipoedifmil as dominio_tipoedifmil on dominio_tipoedifmil.code = adm_edif_pub_militar_p.tipoedifmil # DROP VIEW IF EXISTS views.asb_edif_saneamento_a# -CREATE [VIEW] views.asb_edif_saneamento_a as +CREATE [VIEW] views.asb_edif_saneamento_a as SELECT id as id, nome as nome, @@ -4205,15 +4205,15 @@ CREATE [VIEW] views.asb_edif_saneamento_a as dominio_tipoedifsaneam.code_name as tipoedifsaneam, id_complexo_saneamento as id_complexo_saneamento [FROM] - cb.asb_edif_saneamento_a - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = asb_edif_saneamento_a.geometriaaproximada - left join dominios.operacional as dominio_operacional on dominio_operacional.code = asb_edif_saneamento_a.operacional - left join dominios.situacaofisica as dominio_situacaofisica on dominio_situacaofisica.code = asb_edif_saneamento_a.situacaofisica - left join dominios.matconstr as dominio_matconstr on dominio_matconstr.code = asb_edif_saneamento_a.matconstr + cb.asb_edif_saneamento_a + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = asb_edif_saneamento_a.geometriaaproximada + left join dominios.operacional as dominio_operacional on dominio_operacional.code = asb_edif_saneamento_a.operacional + left join dominios.situacaofisica as dominio_situacaofisica on dominio_situacaofisica.code = asb_edif_saneamento_a.situacaofisica + left join dominios.matconstr as dominio_matconstr on dominio_matconstr.code = asb_edif_saneamento_a.matconstr left join dominios.tipoedifsaneam as dominio_tipoedifsaneam on dominio_tipoedifsaneam.code = asb_edif_saneamento_a.tipoedifsaneam # DROP VIEW IF EXISTS views.tra_patio_a# -CREATE [VIEW] views.tra_patio_a as +CREATE [VIEW] views.tra_patio_a as SELECT id as id, nome as nome, @@ -4232,15 +4232,15 @@ CREATE [VIEW] views.tra_patio_a as id_complexo_lazer as id_complexo_lazer, geom as geom [FROM] - cb.tra_patio_a - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = tra_patio_a.geometriaaproximada - left join dominios.modaluso as dominio_modaluso on dominio_modaluso.code = tra_patio_a.modaluso - left join dominios.administracao as dominio_administracao on dominio_administracao.code = tra_patio_a.administracao - left join dominios.operacional as dominio_operacional on dominio_operacional.code = tra_patio_a.operacional + cb.tra_patio_a + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = tra_patio_a.geometriaaproximada + left join dominios.modaluso as dominio_modaluso on dominio_modaluso.code = tra_patio_a.modaluso + left join dominios.administracao as dominio_administracao on dominio_administracao.code = tra_patio_a.administracao + left join dominios.operacional as dominio_operacional on dominio_operacional.code = tra_patio_a.operacional left join dominios.situacaofisica as dominio_situacaofisica on dominio_situacaofisica.code = tra_patio_a.situacaofisica # DROP VIEW IF EXISTS views.enc_trecho_energia_l# -CREATE [VIEW] views.enc_trecho_energia_l as +CREATE [VIEW] views.enc_trecho_energia_l as SELECT id as id, nome as nome, @@ -4256,16 +4256,16 @@ CREATE [VIEW] views.enc_trecho_energia_l as id_org_comerc_serv as id_org_comerc_serv, geom as geom [FROM] - cb.enc_trecho_energia_l - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = enc_trecho_energia_l.geometriaaproximada - left join dominios.especie as dominio_especie on dominio_especie.code = enc_trecho_energia_l.especie - left join dominios.posicaorelativa as dominio_posicaorelativa on dominio_posicaorelativa.code = enc_trecho_energia_l.posicaorelativa - left join dominios.operacional as dominio_operacional on dominio_operacional.code = enc_trecho_energia_l.operacional - left join dominios.situacaofisica as dominio_situacaofisica on dominio_situacaofisica.code = enc_trecho_energia_l.situacaofisica + cb.enc_trecho_energia_l + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = enc_trecho_energia_l.geometriaaproximada + left join dominios.especie as dominio_especie on dominio_especie.code = enc_trecho_energia_l.especie + left join dominios.posicaorelativa as dominio_posicaorelativa on dominio_posicaorelativa.code = enc_trecho_energia_l.posicaorelativa + left join dominios.operacional as dominio_operacional on dominio_operacional.code = enc_trecho_energia_l.operacional + left join dominios.situacaofisica as dominio_situacaofisica on dominio_situacaofisica.code = enc_trecho_energia_l.situacaofisica left join dominios.emduto as dominio_emduto on dominio_emduto.code = enc_trecho_energia_l.emduto # DROP VIEW IF EXISTS views.tra_ponte_l# -CREATE [VIEW] views.tra_ponte_l as +CREATE [VIEW] views.tra_ponte_l as SELECT id as id, nome as nome, @@ -4286,17 +4286,17 @@ CREATE [VIEW] views.tra_ponte_l as extensao as extensao, geom as geom [FROM] - cb.tra_ponte_l - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = tra_ponte_l.geometriaaproximada - left join dominios.tipoponte as dominio_tipoponte on dominio_tipoponte.code = tra_ponte_l.tipoponte - left join dominios.modaluso as dominio_modaluso on dominio_modaluso.code = tra_ponte_l.modaluso - left join dominios.matconstr as dominio_matconstr on dominio_matconstr.code = tra_ponte_l.matconstr - left join dominios.operacional as dominio_operacional on dominio_operacional.code = tra_ponte_l.operacional - left join dominios.situacaofisica as dominio_situacaofisica on dominio_situacaofisica.code = tra_ponte_l.situacaofisica + cb.tra_ponte_l + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = tra_ponte_l.geometriaaproximada + left join dominios.tipoponte as dominio_tipoponte on dominio_tipoponte.code = tra_ponte_l.tipoponte + left join dominios.modaluso as dominio_modaluso on dominio_modaluso.code = tra_ponte_l.modaluso + left join dominios.matconstr as dominio_matconstr on dominio_matconstr.code = tra_ponte_l.matconstr + left join dominios.operacional as dominio_operacional on dominio_operacional.code = tra_ponte_l.operacional + left join dominios.situacaofisica as dominio_situacaofisica on dominio_situacaofisica.code = tra_ponte_l.situacaofisica left join dominios.posicaopista as dominio_posicaopista on dominio_posicaopista.code = tra_ponte_l.posicaopista # DROP VIEW IF EXISTS views.tra_edif_metro_ferroviaria_p# -CREATE [VIEW] views.tra_edif_metro_ferroviaria_p as +CREATE [VIEW] views.tra_edif_metro_ferroviaria_p as SELECT id as id, nome as nome, @@ -4311,17 +4311,17 @@ CREATE [VIEW] views.tra_edif_metro_ferroviaria_p as dominio_administracao.code_name as administracao, id_estrut_apoio as id_estrut_apoio [FROM] - cb.tra_edif_metro_ferroviaria_p - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = tra_edif_metro_ferroviaria_p.geometriaaproximada - left join dominios.operacional as dominio_operacional on dominio_operacional.code = tra_edif_metro_ferroviaria_p.operacional - left join dominios.situacaofisica as dominio_situacaofisica on dominio_situacaofisica.code = tra_edif_metro_ferroviaria_p.situacaofisica - left join dominios.matconstr as dominio_matconstr on dominio_matconstr.code = tra_edif_metro_ferroviaria_p.matconstr - left join dominios.funcaoedifmetroferrov as dominio_funcaoedifmetroferrov on dominio_funcaoedifmetroferrov.code = tra_edif_metro_ferroviaria_p.funcaoedifmetroferrov - left join dominios.multimodal as dominio_multimodal on dominio_multimodal.code = tra_edif_metro_ferroviaria_p.multimodal + cb.tra_edif_metro_ferroviaria_p + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = tra_edif_metro_ferroviaria_p.geometriaaproximada + left join dominios.operacional as dominio_operacional on dominio_operacional.code = tra_edif_metro_ferroviaria_p.operacional + left join dominios.situacaofisica as dominio_situacaofisica on dominio_situacaofisica.code = tra_edif_metro_ferroviaria_p.situacaofisica + left join dominios.matconstr as dominio_matconstr on dominio_matconstr.code = tra_edif_metro_ferroviaria_p.matconstr + left join dominios.funcaoedifmetroferrov as dominio_funcaoedifmetroferrov on dominio_funcaoedifmetroferrov.code = tra_edif_metro_ferroviaria_p.funcaoedifmetroferrov + left join dominios.multimodal as dominio_multimodal on dominio_multimodal.code = tra_edif_metro_ferroviaria_p.multimodal left join dominios.administracao as dominio_administracao on dominio_administracao.code = tra_edif_metro_ferroviaria_p.administracao # DROP VIEW IF EXISTS views.tra_trecho_hidroviario_l# -CREATE [VIEW] views.tra_trecho_hidroviario_l as +CREATE [VIEW] views.tra_trecho_hidroviario_l as SELECT id as id, nome as nome, @@ -4335,14 +4335,14 @@ CREATE [VIEW] views.tra_trecho_hidroviario_l as geom as geom, id_hidrovia as id_hidrovia [FROM] - cb.tra_trecho_hidroviario_l - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = tra_trecho_hidroviario_l.geometriaaproximada - left join dominios.operacional as dominio_operacional on dominio_operacional.code = tra_trecho_hidroviario_l.operacional - left join dominios.situacaofisica as dominio_situacaofisica on dominio_situacaofisica.code = tra_trecho_hidroviario_l.situacaofisica + cb.tra_trecho_hidroviario_l + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = tra_trecho_hidroviario_l.geometriaaproximada + left join dominios.operacional as dominio_operacional on dominio_operacional.code = tra_trecho_hidroviario_l.operacional + left join dominios.situacaofisica as dominio_situacaofisica on dominio_situacaofisica.code = tra_trecho_hidroviario_l.situacaofisica left join dominios.regime as dominio_regime on dominio_regime.code = tra_trecho_hidroviario_l.regime # DROP VIEW IF EXISTS views.adm_edif_pub_civil_p# -CREATE [VIEW] views.adm_edif_pub_civil_p as +CREATE [VIEW] views.adm_edif_pub_civil_p as SELECT id as id, nome as nome, @@ -4356,27 +4356,27 @@ CREATE [VIEW] views.adm_edif_pub_civil_p as dominio_tipousoedif.code_name as tipousoedif, id_org_pub_civil as id_org_pub_civil [FROM] - cb.adm_edif_pub_civil_p - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = adm_edif_pub_civil_p.geometriaaproximada - left join dominios.operacional as dominio_operacional on dominio_operacional.code = adm_edif_pub_civil_p.operacional - left join dominios.situacaofisica as dominio_situacaofisica on dominio_situacaofisica.code = adm_edif_pub_civil_p.situacaofisica - left join dominios.matconstr as dominio_matconstr on dominio_matconstr.code = adm_edif_pub_civil_p.matconstr - left join dominios.tipoedifcivil as dominio_tipoedifcivil on dominio_tipoedifcivil.code = adm_edif_pub_civil_p.tipoedifcivil + cb.adm_edif_pub_civil_p + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = adm_edif_pub_civil_p.geometriaaproximada + left join dominios.operacional as dominio_operacional on dominio_operacional.code = adm_edif_pub_civil_p.operacional + left join dominios.situacaofisica as dominio_situacaofisica on dominio_situacaofisica.code = adm_edif_pub_civil_p.situacaofisica + left join dominios.matconstr as dominio_matconstr on dominio_matconstr.code = adm_edif_pub_civil_p.matconstr + left join dominios.tipoedifcivil as dominio_tipoedifcivil on dominio_tipoedifcivil.code = adm_edif_pub_civil_p.tipoedifcivil left join dominios.tipousoedif as dominio_tipousoedif on dominio_tipousoedif.code = adm_edif_pub_civil_p.tipousoedif # DROP VIEW IF EXISTS views.sau_area_saude_a# -CREATE [VIEW] views.sau_area_saude_a as +CREATE [VIEW] views.sau_area_saude_a as SELECT id as id, dominio_geometriaaproximada.code_name as geometriaaproximada, id_org_saude as id_org_saude, geom as geom [FROM] - cb.sau_area_saude_a + cb.sau_area_saude_a left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = sau_area_saude_a.geometriaaproximada # DROP VIEW IF EXISTS views.asb_dep_abast_agua_p# -CREATE [VIEW] views.asb_dep_abast_agua_p as +CREATE [VIEW] views.asb_dep_abast_agua_p as SELECT id as id, nome as nome, @@ -4396,18 +4396,18 @@ CREATE [VIEW] views.asb_dep_abast_agua_p as id_org_industrial as id_org_industrial, geom as geom [FROM] - cb.asb_dep_abast_agua_p - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = asb_dep_abast_agua_p.geometriaaproximada - left join dominios.tipodepabast as dominio_tipodepabast on dominio_tipodepabast.code = asb_dep_abast_agua_p.tipodepabast - left join dominios.situacaoagua as dominio_situacaoagua on dominio_situacaoagua.code = asb_dep_abast_agua_p.situacaoagua - left join dominios.construcao as dominio_construcao on dominio_construcao.code = asb_dep_abast_agua_p.construcao - left join dominios.matconstr as dominio_matconstr on dominio_matconstr.code = asb_dep_abast_agua_p.matconstr - left join dominios.finalidade_asb as dominio_finalidade on dominio_finalidade.code = asb_dep_abast_agua_p.finalidade - left join dominios.situacaofisica as dominio_situacaofisica on dominio_situacaofisica.code = asb_dep_abast_agua_p.situacaofisica + cb.asb_dep_abast_agua_p + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = asb_dep_abast_agua_p.geometriaaproximada + left join dominios.tipodepabast as dominio_tipodepabast on dominio_tipodepabast.code = asb_dep_abast_agua_p.tipodepabast + left join dominios.situacaoagua as dominio_situacaoagua on dominio_situacaoagua.code = asb_dep_abast_agua_p.situacaoagua + left join dominios.construcao as dominio_construcao on dominio_construcao.code = asb_dep_abast_agua_p.construcao + left join dominios.matconstr as dominio_matconstr on dominio_matconstr.code = asb_dep_abast_agua_p.matconstr + left join dominios.finalidade_asb as dominio_finalidade on dominio_finalidade.code = asb_dep_abast_agua_p.finalidade + left join dominios.situacaofisica as dominio_situacaofisica on dominio_situacaofisica.code = asb_dep_abast_agua_p.situacaofisica left join dominios.operacional as dominio_operacional on dominio_operacional.code = asb_dep_abast_agua_p.operacional # DROP VIEW IF EXISTS views.veg_veg_cultivada_a# -CREATE [VIEW] views.veg_veg_cultivada_a as +CREATE [VIEW] views.veg_veg_cultivada_a as SELECT id as id, nome as nome, @@ -4424,17 +4424,17 @@ CREATE [VIEW] views.veg_veg_cultivada_a as dominio_cultivopredominante.code_name as cultivopredominante, geom as geom [FROM] - cb.veg_veg_cultivada_a - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = veg_veg_cultivada_a.geometriaaproximada - left join dominios.tipolavoura as dominio_tipolavoura on dominio_tipolavoura.code = veg_veg_cultivada_a.tipolavoura - left join dominios.finalidade_veg as dominio_finalidade on dominio_finalidade.code = veg_veg_cultivada_a.finalidade - left join dominios.terreno as dominio_terreno on dominio_terreno.code = veg_veg_cultivada_a.terreno - left join dominios.classificacaoporte as dominio_classificacaoporte on dominio_classificacaoporte.code = veg_veg_cultivada_a.classificacaoporte - left join dominios.denso as dominio_denso on dominio_denso.code = veg_veg_cultivada_a.denso + cb.veg_veg_cultivada_a + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = veg_veg_cultivada_a.geometriaaproximada + left join dominios.tipolavoura as dominio_tipolavoura on dominio_tipolavoura.code = veg_veg_cultivada_a.tipolavoura + left join dominios.finalidade_veg as dominio_finalidade on dominio_finalidade.code = veg_veg_cultivada_a.finalidade + left join dominios.terreno as dominio_terreno on dominio_terreno.code = veg_veg_cultivada_a.terreno + left join dominios.classificacaoporte as dominio_classificacaoporte on dominio_classificacaoporte.code = veg_veg_cultivada_a.classificacaoporte + left join dominios.denso as dominio_denso on dominio_denso.code = veg_veg_cultivada_a.denso left join dominios.cultivopredominante as dominio_cultivopredominante on dominio_cultivopredominante.code = veg_veg_cultivada_a.cultivopredominante # DROP VIEW IF EXISTS views.adm_edif_pub_civil_a# -CREATE [VIEW] views.adm_edif_pub_civil_a as +CREATE [VIEW] views.adm_edif_pub_civil_a as SELECT id as id, nome as nome, @@ -4448,16 +4448,16 @@ CREATE [VIEW] views.adm_edif_pub_civil_a as dominio_tipousoedif.code_name as tipousoedif, id_org_pub_civil as id_org_pub_civil [FROM] - cb.adm_edif_pub_civil_a - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = adm_edif_pub_civil_a.geometriaaproximada - left join dominios.operacional as dominio_operacional on dominio_operacional.code = adm_edif_pub_civil_a.operacional - left join dominios.situacaofisica as dominio_situacaofisica on dominio_situacaofisica.code = adm_edif_pub_civil_a.situacaofisica - left join dominios.matconstr as dominio_matconstr on dominio_matconstr.code = adm_edif_pub_civil_a.matconstr - left join dominios.tipoedifcivil as dominio_tipoedifcivil on dominio_tipoedifcivil.code = adm_edif_pub_civil_a.tipoedifcivil + cb.adm_edif_pub_civil_a + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = adm_edif_pub_civil_a.geometriaaproximada + left join dominios.operacional as dominio_operacional on dominio_operacional.code = adm_edif_pub_civil_a.operacional + left join dominios.situacaofisica as dominio_situacaofisica on dominio_situacaofisica.code = adm_edif_pub_civil_a.situacaofisica + left join dominios.matconstr as dominio_matconstr on dominio_matconstr.code = adm_edif_pub_civil_a.matconstr + left join dominios.tipoedifcivil as dominio_tipoedifcivil on dominio_tipoedifcivil.code = adm_edif_pub_civil_a.tipoedifcivil left join dominios.tipousoedif as dominio_tipousoedif on dominio_tipousoedif.code = adm_edif_pub_civil_a.tipousoedif # DROP VIEW IF EXISTS views.sau_edif_saude_p# -CREATE [VIEW] views.sau_edif_saude_p as +CREATE [VIEW] views.sau_edif_saude_p as SELECT id as id, nome as nome, @@ -4471,16 +4471,16 @@ CREATE [VIEW] views.sau_edif_saude_p as dominio_nivelatencao.code_name as nivelatencao, id_org_saude as id_org_saude [FROM] - cb.sau_edif_saude_p - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = sau_edif_saude_p.geometriaaproximada - left join dominios.operacional as dominio_operacional on dominio_operacional.code = sau_edif_saude_p.operacional - left join dominios.situacaofisica as dominio_situacaofisica on dominio_situacaofisica.code = sau_edif_saude_p.situacaofisica - left join dominios.matconstr as dominio_matconstr on dominio_matconstr.code = sau_edif_saude_p.matconstr - left join dominios.tipoclassecnae as dominio_tipoclassecnae on dominio_tipoclassecnae.code = sau_edif_saude_p.tipoclassecnae + cb.sau_edif_saude_p + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = sau_edif_saude_p.geometriaaproximada + left join dominios.operacional as dominio_operacional on dominio_operacional.code = sau_edif_saude_p.operacional + left join dominios.situacaofisica as dominio_situacaofisica on dominio_situacaofisica.code = sau_edif_saude_p.situacaofisica + left join dominios.matconstr as dominio_matconstr on dominio_matconstr.code = sau_edif_saude_p.matconstr + left join dominios.tipoclassecnae as dominio_tipoclassecnae on dominio_tipoclassecnae.code = sau_edif_saude_p.tipoclassecnae left join dominios.nivelatencao as dominio_nivelatencao on dominio_nivelatencao.code = sau_edif_saude_p.nivelatencao # DROP VIEW IF EXISTS views.enc_area_energia_eletrica_a# -CREATE [VIEW] views.enc_area_energia_eletrica_a as +CREATE [VIEW] views.enc_area_energia_eletrica_a as SELECT id as id, dominio_geometriaaproximada.code_name as geometriaaproximada, @@ -4488,11 +4488,11 @@ CREATE [VIEW] views.enc_area_energia_eletrica_a as id_subestacao_ener_eletr as id_subestacao_ener_eletr, id_complexo_gerad_energ_eletr as id_complexo_gerad_energ_eletr [FROM] - cb.enc_area_energia_eletrica_a + cb.enc_area_energia_eletrica_a left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = enc_area_energia_eletrica_a.geometriaaproximada # DROP VIEW IF EXISTS views.lim_limite_particular_l# -CREATE [VIEW] views.lim_limite_particular_l as +CREATE [VIEW] views.lim_limite_particular_l as SELECT id as id, nome as nome, @@ -4503,24 +4503,24 @@ CREATE [VIEW] views.lim_limite_particular_l as geom as geom, obssituacao as obssituacao [FROM] - cb.lim_limite_particular_l - left join dominios.coincidecomdentrode_lim as dominio_coincidecomdentrode on dominio_coincidecomdentrode.code = lim_limite_particular_l.coincidecomdentrode + cb.lim_limite_particular_l + left join dominios.coincidecomdentrode_lim as dominio_coincidecomdentrode on dominio_coincidecomdentrode.code = lim_limite_particular_l.coincidecomdentrode left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = lim_limite_particular_l.geometriaaproximada # DROP VIEW IF EXISTS views.enc_descontinuidade_geometrica_a# -CREATE [VIEW] views.enc_descontinuidade_geometrica_a as +CREATE [VIEW] views.enc_descontinuidade_geometrica_a as SELECT id as id, dominio_geometriaaproximada.code_name as geometriaaproximada, dominio_motivodescontinuidade.code_name as motivodescontinuidade, geom as geom [FROM] - cb.enc_descontinuidade_geometrica_a - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = enc_descontinuidade_geometrica_a.geometriaaproximada + cb.enc_descontinuidade_geometrica_a + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = enc_descontinuidade_geometrica_a.geometriaaproximada left join dominios.motivodescontinuidade as dominio_motivodescontinuidade on dominio_motivodescontinuidade.code = enc_descontinuidade_geometrica_a.motivodescontinuidade # DROP VIEW IF EXISTS views.tra_identific_trecho_rod_p# -CREATE [VIEW] views.tra_identific_trecho_rod_p as +CREATE [VIEW] views.tra_identific_trecho_rod_p as SELECT id as id, nome as nome, @@ -4532,7 +4532,7 @@ CREATE [VIEW] views.tra_identific_trecho_rod_p as cb.tra_identific_trecho_rod_p # DROP VIEW IF EXISTS views.tra_edif_metro_ferroviaria_a# -CREATE [VIEW] views.tra_edif_metro_ferroviaria_a as +CREATE [VIEW] views.tra_edif_metro_ferroviaria_a as SELECT id as id, nome as nome, @@ -4547,17 +4547,17 @@ CREATE [VIEW] views.tra_edif_metro_ferroviaria_a as dominio_administracao.code_name as administracao, id_estrut_apoio as id_estrut_apoio [FROM] - cb.tra_edif_metro_ferroviaria_a - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = tra_edif_metro_ferroviaria_a.geometriaaproximada - left join dominios.operacional as dominio_operacional on dominio_operacional.code = tra_edif_metro_ferroviaria_a.operacional - left join dominios.situacaofisica as dominio_situacaofisica on dominio_situacaofisica.code = tra_edif_metro_ferroviaria_a.situacaofisica - left join dominios.matconstr as dominio_matconstr on dominio_matconstr.code = tra_edif_metro_ferroviaria_a.matconstr - left join dominios.funcaoedifmetroferrov as dominio_funcaoedifmetroferrov on dominio_funcaoedifmetroferrov.code = tra_edif_metro_ferroviaria_a.funcaoedifmetroferrov - left join dominios.multimodal as dominio_multimodal on dominio_multimodal.code = tra_edif_metro_ferroviaria_a.multimodal + cb.tra_edif_metro_ferroviaria_a + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = tra_edif_metro_ferroviaria_a.geometriaaproximada + left join dominios.operacional as dominio_operacional on dominio_operacional.code = tra_edif_metro_ferroviaria_a.operacional + left join dominios.situacaofisica as dominio_situacaofisica on dominio_situacaofisica.code = tra_edif_metro_ferroviaria_a.situacaofisica + left join dominios.matconstr as dominio_matconstr on dominio_matconstr.code = tra_edif_metro_ferroviaria_a.matconstr + left join dominios.funcaoedifmetroferrov as dominio_funcaoedifmetroferrov on dominio_funcaoedifmetroferrov.code = tra_edif_metro_ferroviaria_a.funcaoedifmetroferrov + left join dominios.multimodal as dominio_multimodal on dominio_multimodal.code = tra_edif_metro_ferroviaria_a.multimodal left join dominios.administracao as dominio_administracao on dominio_administracao.code = tra_edif_metro_ferroviaria_a.administracao # DROP VIEW IF EXISTS views.eco_ext_mineral_p# -CREATE [VIEW] views.eco_ext_mineral_p as +CREATE [VIEW] views.eco_ext_mineral_p as SELECT id as id, nome as nome, @@ -4575,20 +4575,20 @@ CREATE [VIEW] views.eco_ext_mineral_p as id_org_ext_mineral as id_org_ext_mineral, geom as geom [FROM] - cb.eco_ext_mineral_p - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = eco_ext_mineral_p.geometriaaproximada - left join dominios.tiposecaocnae as dominio_tiposecaocnae on dominio_tiposecaocnae.code = eco_ext_mineral_p.tiposecaocnae - left join dominios.operacional as dominio_operacional on dominio_operacional.code = eco_ext_mineral_p.operacional - left join dominios.situacaofisica as dominio_situacaofisica on dominio_situacaofisica.code = eco_ext_mineral_p.situacaofisica - left join dominios.tipoextmin as dominio_tipoextmin on dominio_tipoextmin.code = eco_ext_mineral_p.tipoextmin - left join dominios.tipoprodutoresiduo as dominio_tipoprodutoresiduo on dominio_tipoprodutoresiduo.code = eco_ext_mineral_p.tipoprodutoresiduo - left join dominios.tipopocomina as dominio_tipopocomina on dominio_tipopocomina.code = eco_ext_mineral_p.tipopocomina - left join dominios.procextracao as dominio_procextracao on dominio_procextracao.code = eco_ext_mineral_p.procextracao - left join dominios.formaextracao as dominio_formaextracao on dominio_formaextracao.code = eco_ext_mineral_p.formaextracao + cb.eco_ext_mineral_p + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = eco_ext_mineral_p.geometriaaproximada + left join dominios.tiposecaocnae as dominio_tiposecaocnae on dominio_tiposecaocnae.code = eco_ext_mineral_p.tiposecaocnae + left join dominios.operacional as dominio_operacional on dominio_operacional.code = eco_ext_mineral_p.operacional + left join dominios.situacaofisica as dominio_situacaofisica on dominio_situacaofisica.code = eco_ext_mineral_p.situacaofisica + left join dominios.tipoextmin as dominio_tipoextmin on dominio_tipoextmin.code = eco_ext_mineral_p.tipoextmin + left join dominios.tipoprodutoresiduo as dominio_tipoprodutoresiduo on dominio_tipoprodutoresiduo.code = eco_ext_mineral_p.tipoprodutoresiduo + left join dominios.tipopocomina as dominio_tipopocomina on dominio_tipopocomina.code = eco_ext_mineral_p.tipopocomina + left join dominios.procextracao as dominio_procextracao on dominio_procextracao.code = eco_ext_mineral_p.procextracao + left join dominios.formaextracao as dominio_formaextracao on dominio_formaextracao.code = eco_ext_mineral_p.formaextracao left join dominios.atividade as dominio_atividade on dominio_atividade.code = eco_ext_mineral_p.atividade # DROP VIEW IF EXISTS views.rel_gruta_caverna_p# -CREATE [VIEW] views.rel_gruta_caverna_p as +CREATE [VIEW] views.rel_gruta_caverna_p as SELECT id as id, nome as nome, @@ -4598,24 +4598,24 @@ CREATE [VIEW] views.rel_gruta_caverna_p as geom as geom, dominio_tipogrutacaverna.code_name as tipogrutacaverna [FROM] - cb.rel_gruta_caverna_p - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = rel_gruta_caverna_p.geometriaaproximada - left join dominios.tipoelemnat as dominio_tipoelemnat on dominio_tipoelemnat.code = rel_gruta_caverna_p.tipoelemnat + cb.rel_gruta_caverna_p + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = rel_gruta_caverna_p.geometriaaproximada + left join dominios.tipoelemnat as dominio_tipoelemnat on dominio_tipoelemnat.code = rel_gruta_caverna_p.tipoelemnat left join dominios.tipogrutacaverna as dominio_tipogrutacaverna on dominio_tipogrutacaverna.code = rel_gruta_caverna_p.tipogrutacaverna # DROP VIEW IF EXISTS views.edu_area_lazer_a# -CREATE [VIEW] views.edu_area_lazer_a as +CREATE [VIEW] views.edu_area_lazer_a as SELECT id as id, dominio_geometriaaproximada.code_name as geometriaaproximada, geom as geom, id_complexo_lazer as id_complexo_lazer [FROM] - cb.edu_area_lazer_a + cb.edu_area_lazer_a left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = edu_area_lazer_a.geometriaaproximada # DROP VIEW IF EXISTS views.loc_edificacao_p# -CREATE [VIEW] views.loc_edificacao_p as +CREATE [VIEW] views.loc_edificacao_p as SELECT id as id, nome as nome, @@ -4626,14 +4626,14 @@ CREATE [VIEW] views.loc_edificacao_p as dominio_matconstr.code_name as matconstr, geom as geom [FROM] - cb.loc_edificacao_p - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = loc_edificacao_p.geometriaaproximada - left join dominios.operacional as dominio_operacional on dominio_operacional.code = loc_edificacao_p.operacional - left join dominios.situacaofisica as dominio_situacaofisica on dominio_situacaofisica.code = loc_edificacao_p.situacaofisica + cb.loc_edificacao_p + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = loc_edificacao_p.geometriaaproximada + left join dominios.operacional as dominio_operacional on dominio_operacional.code = loc_edificacao_p.operacional + left join dominios.situacaofisica as dominio_situacaofisica on dominio_situacaofisica.code = loc_edificacao_p.situacaofisica left join dominios.matconstr as dominio_matconstr on dominio_matconstr.code = loc_edificacao_p.matconstr # DROP VIEW IF EXISTS views.tra_local_critico_l# -CREATE [VIEW] views.tra_local_critico_l as +CREATE [VIEW] views.tra_local_critico_l as SELECT id as id, nome as nome, @@ -4642,12 +4642,12 @@ CREATE [VIEW] views.tra_local_critico_l as dominio_tipolocalcrit.code_name as tipolocalcrit, geom as geom [FROM] - cb.tra_local_critico_l - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = tra_local_critico_l.geometriaaproximada + cb.tra_local_critico_l + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = tra_local_critico_l.geometriaaproximada left join dominios.tipolocalcrit as dominio_tipolocalcrit on dominio_tipolocalcrit.code = tra_local_critico_l.tipolocalcrit # DROP VIEW IF EXISTS views.lim_area_uso_comunitario_a# -CREATE [VIEW] views.lim_area_uso_comunitario_a as +CREATE [VIEW] views.lim_area_uso_comunitario_a as SELECT id as id, nome as nome, @@ -4656,12 +4656,12 @@ CREATE [VIEW] views.lim_area_uso_comunitario_a as geom as geom, dominio_tipoareausocomun.code_name as tipoareausocomun [FROM] - cb.lim_area_uso_comunitario_a - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = lim_area_uso_comunitario_a.geometriaaproximada + cb.lim_area_uso_comunitario_a + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = lim_area_uso_comunitario_a.geometriaaproximada left join dominios.tipoareausocomun as dominio_tipoareausocomun on dominio_tipoareausocomun.code = lim_area_uso_comunitario_a.tipoareausocomun # DROP VIEW IF EXISTS views.veg_campinarana_a# -CREATE [VIEW] views.veg_campinarana_a as +CREATE [VIEW] views.veg_campinarana_a as SELECT id as id, nome as nome, @@ -4673,26 +4673,26 @@ CREATE [VIEW] views.veg_campinarana_a as alturamediaindividuos as alturamediaindividuos, dominio_classificacaoporte.code_name as classificacaoporte [FROM] - cb.veg_campinarana_a - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = veg_campinarana_a.geometriaaproximada - left join dominios.denso as dominio_denso on dominio_denso.code = veg_campinarana_a.denso - left join dominios.antropizada as dominio_antropizada on dominio_antropizada.code = veg_campinarana_a.antropizada + cb.veg_campinarana_a + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = veg_campinarana_a.geometriaaproximada + left join dominios.denso as dominio_denso on dominio_denso.code = veg_campinarana_a.denso + left join dominios.antropizada as dominio_antropizada on dominio_antropizada.code = veg_campinarana_a.antropizada left join dominios.classificacaoporte as dominio_classificacaoporte on dominio_classificacaoporte.code = veg_campinarana_a.classificacaoporte # DROP VIEW IF EXISTS views.rel_descontinuidade_geometrica_a# -CREATE [VIEW] views.rel_descontinuidade_geometrica_a as +CREATE [VIEW] views.rel_descontinuidade_geometrica_a as SELECT id as id, dominio_geometriaaproximada.code_name as geometriaaproximada, dominio_motivodescontinuidade.code_name as motivodescontinuidade, geom as geom [FROM] - cb.rel_descontinuidade_geometrica_a - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = rel_descontinuidade_geometrica_a.geometriaaproximada + cb.rel_descontinuidade_geometrica_a + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = rel_descontinuidade_geometrica_a.geometriaaproximada left join dominios.motivodescontinuidade as dominio_motivodescontinuidade on dominio_motivodescontinuidade.code = rel_descontinuidade_geometrica_a.motivodescontinuidade # DROP VIEW IF EXISTS views.hid_quebramar_molhe_a# -CREATE [VIEW] views.hid_quebramar_molhe_a as +CREATE [VIEW] views.hid_quebramar_molhe_a as SELECT id as id, nome as nome, @@ -4705,16 +4705,16 @@ CREATE [VIEW] views.hid_quebramar_molhe_a as dominio_situacaofisica.code_name as situacaofisica, geom as geom [FROM] - cb.hid_quebramar_molhe_a - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = hid_quebramar_molhe_a.geometriaaproximada - left join dominios.tipoquebramolhe as dominio_tipoquebramolhe on dominio_tipoquebramolhe.code = hid_quebramar_molhe_a.tipoquebramolhe - left join dominios.matconstr as dominio_matconstr on dominio_matconstr.code = hid_quebramar_molhe_a.matconstr - left join dominios.situamare as dominio_situamare on dominio_situamare.code = hid_quebramar_molhe_a.situamare - left join dominios.operacional as dominio_operacional on dominio_operacional.code = hid_quebramar_molhe_a.operacional + cb.hid_quebramar_molhe_a + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = hid_quebramar_molhe_a.geometriaaproximada + left join dominios.tipoquebramolhe as dominio_tipoquebramolhe on dominio_tipoquebramolhe.code = hid_quebramar_molhe_a.tipoquebramolhe + left join dominios.matconstr as dominio_matconstr on dominio_matconstr.code = hid_quebramar_molhe_a.matconstr + left join dominios.situamare as dominio_situamare on dominio_situamare.code = hid_quebramar_molhe_a.situamare + left join dominios.operacional as dominio_operacional on dominio_operacional.code = hid_quebramar_molhe_a.operacional left join dominios.situacaofisica as dominio_situacaofisica on dominio_situacaofisica.code = hid_quebramar_molhe_a.situacaofisica # DROP VIEW IF EXISTS views.rel_curva_nivel_l# -CREATE [VIEW] views.rel_curva_nivel_l as +CREATE [VIEW] views.rel_curva_nivel_l as SELECT id as id, dominio_geometriaaproximada.code_name as geometriaaproximada, @@ -4723,13 +4723,13 @@ CREATE [VIEW] views.rel_curva_nivel_l as dominio_indice.code_name as indice, geom as geom [FROM] - cb.rel_curva_nivel_l - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = rel_curva_nivel_l.geometriaaproximada - left join dominios.depressao as dominio_depressao on dominio_depressao.code = rel_curva_nivel_l.depressao + cb.rel_curva_nivel_l + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = rel_curva_nivel_l.geometriaaproximada + left join dominios.depressao as dominio_depressao on dominio_depressao.code = rel_curva_nivel_l.depressao left join dominios.indice as dominio_indice on dominio_indice.code = rel_curva_nivel_l.indice # DROP VIEW IF EXISTS views.hid_quebramar_molhe_l# -CREATE [VIEW] views.hid_quebramar_molhe_l as +CREATE [VIEW] views.hid_quebramar_molhe_l as SELECT id as id, nome as nome, @@ -4742,28 +4742,28 @@ CREATE [VIEW] views.hid_quebramar_molhe_l as dominio_situacaofisica.code_name as situacaofisica, geom as geom [FROM] - cb.hid_quebramar_molhe_l - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = hid_quebramar_molhe_l.geometriaaproximada - left join dominios.tipoquebramolhe as dominio_tipoquebramolhe on dominio_tipoquebramolhe.code = hid_quebramar_molhe_l.tipoquebramolhe - left join dominios.matconstr as dominio_matconstr on dominio_matconstr.code = hid_quebramar_molhe_l.matconstr - left join dominios.situamare as dominio_situamare on dominio_situamare.code = hid_quebramar_molhe_l.situamare - left join dominios.operacional as dominio_operacional on dominio_operacional.code = hid_quebramar_molhe_l.operacional + cb.hid_quebramar_molhe_l + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = hid_quebramar_molhe_l.geometriaaproximada + left join dominios.tipoquebramolhe as dominio_tipoquebramolhe on dominio_tipoquebramolhe.code = hid_quebramar_molhe_l.tipoquebramolhe + left join dominios.matconstr as dominio_matconstr on dominio_matconstr.code = hid_quebramar_molhe_l.matconstr + left join dominios.situamare as dominio_situamare on dominio_situamare.code = hid_quebramar_molhe_l.situamare + left join dominios.operacional as dominio_operacional on dominio_operacional.code = hid_quebramar_molhe_l.operacional left join dominios.situacaofisica as dominio_situacaofisica on dominio_situacaofisica.code = hid_quebramar_molhe_l.situacaofisica # DROP VIEW IF EXISTS views.rel_descontinuidade_geometrica_l# -CREATE [VIEW] views.rel_descontinuidade_geometrica_l as +CREATE [VIEW] views.rel_descontinuidade_geometrica_l as SELECT id as id, dominio_geometriaaproximada.code_name as geometriaaproximada, dominio_motivodescontinuidade.code_name as motivodescontinuidade, geom as geom [FROM] - cb.rel_descontinuidade_geometrica_l - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = rel_descontinuidade_geometrica_l.geometriaaproximada + cb.rel_descontinuidade_geometrica_l + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = rel_descontinuidade_geometrica_l.geometriaaproximada left join dominios.motivodescontinuidade as dominio_motivodescontinuidade on dominio_motivodescontinuidade.code = rel_descontinuidade_geometrica_l.motivodescontinuidade # DROP VIEW IF EXISTS views.veg_brejo_pantano_a# -CREATE [VIEW] views.veg_brejo_pantano_a as +CREATE [VIEW] views.veg_brejo_pantano_a as SELECT id as id, nome as nome, @@ -4776,15 +4776,15 @@ CREATE [VIEW] views.veg_brejo_pantano_a as alturamediaindividuos as alturamediaindividuos, dominio_classificacaoporte.code_name as classificacaoporte [FROM] - cb.veg_brejo_pantano_a - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = veg_brejo_pantano_a.geometriaaproximada - left join dominios.denso as dominio_denso on dominio_denso.code = veg_brejo_pantano_a.denso - left join dominios.antropizada as dominio_antropizada on dominio_antropizada.code = veg_brejo_pantano_a.antropizada - left join dominios.tipobrejopantano as dominio_tipobrejopantano on dominio_tipobrejopantano.code = veg_brejo_pantano_a.tipobrejopantano + cb.veg_brejo_pantano_a + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = veg_brejo_pantano_a.geometriaaproximada + left join dominios.denso as dominio_denso on dominio_denso.code = veg_brejo_pantano_a.denso + left join dominios.antropizada as dominio_antropizada on dominio_antropizada.code = veg_brejo_pantano_a.antropizada + left join dominios.tipobrejopantano as dominio_tipobrejopantano on dominio_tipobrejopantano.code = veg_brejo_pantano_a.tipobrejopantano left join dominios.classificacaoporte as dominio_classificacaoporte on dominio_classificacaoporte.code = veg_brejo_pantano_a.classificacaoporte # DROP VIEW IF EXISTS views.veg_caatinga_a# -CREATE [VIEW] views.veg_caatinga_a as +CREATE [VIEW] views.veg_caatinga_a as SELECT id as id, nome as nome, @@ -4796,14 +4796,14 @@ CREATE [VIEW] views.veg_caatinga_a as alturamediaindividuos as alturamediaindividuos, dominio_classificacaoporte.code_name as classificacaoporte [FROM] - cb.veg_caatinga_a - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = veg_caatinga_a.geometriaaproximada - left join dominios.denso as dominio_denso on dominio_denso.code = veg_caatinga_a.denso - left join dominios.antropizada as dominio_antropizada on dominio_antropizada.code = veg_caatinga_a.antropizada + cb.veg_caatinga_a + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = veg_caatinga_a.geometriaaproximada + left join dominios.denso as dominio_denso on dominio_denso.code = veg_caatinga_a.denso + left join dominios.antropizada as dominio_antropizada on dominio_antropizada.code = veg_caatinga_a.antropizada left join dominios.classificacaoporte as dominio_classificacaoporte on dominio_classificacaoporte.code = veg_caatinga_a.classificacaoporte # DROP VIEW IF EXISTS views.tra_trecho_ferroviario_l# -CREATE [VIEW] views.tra_trecho_ferroviario_l as +CREATE [VIEW] views.tra_trecho_ferroviario_l as SELECT id as id, nome as nome, @@ -4825,21 +4825,21 @@ CREATE [VIEW] views.tra_trecho_ferroviario_l as id_via_ferrea as id_via_ferrea, geom as geom [FROM] - cb.tra_trecho_ferroviario_l - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = tra_trecho_ferroviario_l.geometriaaproximada - left join dominios.posicaorelativa as dominio_posicaorelativa on dominio_posicaorelativa.code = tra_trecho_ferroviario_l.posicaorelativa - left join dominios.tipotrechoferrov as dominio_tipotrechoferrov on dominio_tipotrechoferrov.code = tra_trecho_ferroviario_l.tipotrechoferrov - left join dominios.bitola as dominio_bitola on dominio_bitola.code = tra_trecho_ferroviario_l.bitola - left join dominios.eletrificada as dominio_eletrificada on dominio_eletrificada.code = tra_trecho_ferroviario_l.eletrificada - left join dominios.nrlinhas as dominio_nrlinhas on dominio_nrlinhas.code = tra_trecho_ferroviario_l.nrlinhas - left join dominios.emarruamento as dominio_emarruamento on dominio_emarruamento.code = tra_trecho_ferroviario_l.emarruamento - left join dominios.jurisdicao as dominio_jurisdicao on dominio_jurisdicao.code = tra_trecho_ferroviario_l.jurisdicao - left join dominios.administracao as dominio_administracao on dominio_administracao.code = tra_trecho_ferroviario_l.administracao - left join dominios.operacional as dominio_operacional on dominio_operacional.code = tra_trecho_ferroviario_l.operacional + cb.tra_trecho_ferroviario_l + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = tra_trecho_ferroviario_l.geometriaaproximada + left join dominios.posicaorelativa as dominio_posicaorelativa on dominio_posicaorelativa.code = tra_trecho_ferroviario_l.posicaorelativa + left join dominios.tipotrechoferrov as dominio_tipotrechoferrov on dominio_tipotrechoferrov.code = tra_trecho_ferroviario_l.tipotrechoferrov + left join dominios.bitola as dominio_bitola on dominio_bitola.code = tra_trecho_ferroviario_l.bitola + left join dominios.eletrificada as dominio_eletrificada on dominio_eletrificada.code = tra_trecho_ferroviario_l.eletrificada + left join dominios.nrlinhas as dominio_nrlinhas on dominio_nrlinhas.code = tra_trecho_ferroviario_l.nrlinhas + left join dominios.emarruamento as dominio_emarruamento on dominio_emarruamento.code = tra_trecho_ferroviario_l.emarruamento + left join dominios.jurisdicao as dominio_jurisdicao on dominio_jurisdicao.code = tra_trecho_ferroviario_l.jurisdicao + left join dominios.administracao as dominio_administracao on dominio_administracao.code = tra_trecho_ferroviario_l.administracao + left join dominios.operacional as dominio_operacional on dominio_operacional.code = tra_trecho_ferroviario_l.operacional left join dominios.situacaofisica as dominio_situacaofisica on dominio_situacaofisica.code = tra_trecho_ferroviario_l.situacaofisica # DROP VIEW IF EXISTS views.hid_ponto_drenagem_p# -CREATE [VIEW] views.hid_ponto_drenagem_p as +CREATE [VIEW] views.hid_ponto_drenagem_p as SELECT id as id, nome as nome, @@ -4848,12 +4848,12 @@ CREATE [VIEW] views.hid_ponto_drenagem_p as dominio_relacionado.code_name as relacionado, geom as geom [FROM] - cb.hid_ponto_drenagem_p - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = hid_ponto_drenagem_p.geometriaaproximada + cb.hid_ponto_drenagem_p + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = hid_ponto_drenagem_p.geometriaaproximada left join dominios.relacionado_hid as dominio_relacionado on dominio_relacionado.code = hid_ponto_drenagem_p.relacionado # DROP VIEW IF EXISTS views.sau_edif_servico_social_a# -CREATE [VIEW] views.sau_edif_servico_social_a as +CREATE [VIEW] views.sau_edif_servico_social_a as SELECT id as id, nome as nome, @@ -4866,15 +4866,15 @@ CREATE [VIEW] views.sau_edif_servico_social_a as dominio_tipoclassecnae.code_name as tipoclassecnae, id_org_servico_social as id_org_servico_social [FROM] - cb.sau_edif_servico_social_a - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = sau_edif_servico_social_a.geometriaaproximada - left join dominios.operacional as dominio_operacional on dominio_operacional.code = sau_edif_servico_social_a.operacional - left join dominios.situacaofisica as dominio_situacaofisica on dominio_situacaofisica.code = sau_edif_servico_social_a.situacaofisica - left join dominios.matconstr as dominio_matconstr on dominio_matconstr.code = sau_edif_servico_social_a.matconstr + cb.sau_edif_servico_social_a + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = sau_edif_servico_social_a.geometriaaproximada + left join dominios.operacional as dominio_operacional on dominio_operacional.code = sau_edif_servico_social_a.operacional + left join dominios.situacaofisica as dominio_situacaofisica on dominio_situacaofisica.code = sau_edif_servico_social_a.situacaofisica + left join dominios.matconstr as dominio_matconstr on dominio_matconstr.code = sau_edif_servico_social_a.matconstr left join dominios.tipoclassecnae as dominio_tipoclassecnae on dominio_tipoclassecnae.code = sau_edif_servico_social_a.tipoclassecnae # DROP VIEW IF EXISTS views.lim_linha_de_limite_l# -CREATE [VIEW] views.lim_linha_de_limite_l as +CREATE [VIEW] views.lim_linha_de_limite_l as SELECT id as id, nome as nome, @@ -4884,22 +4884,22 @@ CREATE [VIEW] views.lim_linha_de_limite_l as extensao as extensao, geom as geom [FROM] - cb.lim_linha_de_limite_l - left join dominios.coincidecomdentrode_lim as dominio_coincidecomdentrode on dominio_coincidecomdentrode.code = lim_linha_de_limite_l.coincidecomdentrode + cb.lim_linha_de_limite_l + left join dominios.coincidecomdentrode_lim as dominio_coincidecomdentrode on dominio_coincidecomdentrode.code = lim_linha_de_limite_l.coincidecomdentrode left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = lim_linha_de_limite_l.geometriaaproximada # DROP VIEW IF EXISTS views.tra_area_duto_a# -CREATE [VIEW] views.tra_area_duto_a as +CREATE [VIEW] views.tra_area_duto_a as SELECT id as id, dominio_geometriaaproximada.code_name as geometriaaproximada, geom as geom [FROM] - cb.tra_area_duto_a + cb.tra_area_duto_a left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = tra_area_duto_a.geometriaaproximada # DROP VIEW IF EXISTS views.eco_edif_agrop_ext_veg_pesca_p# -CREATE [VIEW] views.eco_edif_agrop_ext_veg_pesca_p as +CREATE [VIEW] views.eco_edif_agrop_ext_veg_pesca_p as SELECT id as id, nome as nome, @@ -4912,27 +4912,27 @@ CREATE [VIEW] views.eco_edif_agrop_ext_veg_pesca_p as dominio_tipoedifagropec.code_name as tipoedifagropec, id_org_agropec_ext_veg_pesca as id_org_agropec_ext_veg_pesca [FROM] - cb.eco_edif_agrop_ext_veg_pesca_p - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = eco_edif_agrop_ext_veg_pesca_p.geometriaaproximada - left join dominios.operacional as dominio_operacional on dominio_operacional.code = eco_edif_agrop_ext_veg_pesca_p.operacional - left join dominios.situacaofisica as dominio_situacaofisica on dominio_situacaofisica.code = eco_edif_agrop_ext_veg_pesca_p.situacaofisica - left join dominios.matconstr as dominio_matconstr on dominio_matconstr.code = eco_edif_agrop_ext_veg_pesca_p.matconstr + cb.eco_edif_agrop_ext_veg_pesca_p + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = eco_edif_agrop_ext_veg_pesca_p.geometriaaproximada + left join dominios.operacional as dominio_operacional on dominio_operacional.code = eco_edif_agrop_ext_veg_pesca_p.operacional + left join dominios.situacaofisica as dominio_situacaofisica on dominio_situacaofisica.code = eco_edif_agrop_ext_veg_pesca_p.situacaofisica + left join dominios.matconstr as dominio_matconstr on dominio_matconstr.code = eco_edif_agrop_ext_veg_pesca_p.matconstr left join dominios.tipoedifagropec as dominio_tipoedifagropec on dominio_tipoedifagropec.code = eco_edif_agrop_ext_veg_pesca_p.tipoedifagropec # DROP VIEW IF EXISTS views.rel_descontinuidade_geometrica_p# -CREATE [VIEW] views.rel_descontinuidade_geometrica_p as +CREATE [VIEW] views.rel_descontinuidade_geometrica_p as SELECT id as id, dominio_geometriaaproximada.code_name as geometriaaproximada, dominio_motivodescontinuidade.code_name as motivodescontinuidade, geom as geom [FROM] - cb.rel_descontinuidade_geometrica_p - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = rel_descontinuidade_geometrica_p.geometriaaproximada + cb.rel_descontinuidade_geometrica_p + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = rel_descontinuidade_geometrica_p.geometriaaproximada left join dominios.motivodescontinuidade as dominio_motivodescontinuidade on dominio_motivodescontinuidade.code = rel_descontinuidade_geometrica_p.motivodescontinuidade # DROP VIEW IF EXISTS views.lim_unidade_federacao_a# -CREATE [VIEW] views.lim_unidade_federacao_a as +CREATE [VIEW] views.lim_unidade_federacao_a as SELECT id as id, nome as nome, @@ -4942,12 +4942,12 @@ CREATE [VIEW] views.lim_unidade_federacao_a as dominio_sigla.code_name as sigla, geocodigo as geocodigo [FROM] - cb.lim_unidade_federacao_a - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = lim_unidade_federacao_a.geometriaaproximada + cb.lim_unidade_federacao_a + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = lim_unidade_federacao_a.geometriaaproximada left join dominios.sigla as dominio_sigla on dominio_sigla.code = lim_unidade_federacao_a.sigla # DROP VIEW IF EXISTS views.asb_dep_abast_agua_a# -CREATE [VIEW] views.asb_dep_abast_agua_a as +CREATE [VIEW] views.asb_dep_abast_agua_a as SELECT id as id, nome as nome, @@ -4967,18 +4967,18 @@ CREATE [VIEW] views.asb_dep_abast_agua_a as id_org_industrial as id_org_industrial, geom as geom [FROM] - cb.asb_dep_abast_agua_a - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = asb_dep_abast_agua_a.geometriaaproximada - left join dominios.tipodepabast as dominio_tipodepabast on dominio_tipodepabast.code = asb_dep_abast_agua_a.tipodepabast - left join dominios.situacaoagua as dominio_situacaoagua on dominio_situacaoagua.code = asb_dep_abast_agua_a.situacaoagua - left join dominios.construcao as dominio_construcao on dominio_construcao.code = asb_dep_abast_agua_a.construcao - left join dominios.matconstr as dominio_matconstr on dominio_matconstr.code = asb_dep_abast_agua_a.matconstr - left join dominios.finalidade_asb as dominio_finalidade on dominio_finalidade.code = asb_dep_abast_agua_a.finalidade - left join dominios.situacaofisica as dominio_situacaofisica on dominio_situacaofisica.code = asb_dep_abast_agua_a.situacaofisica + cb.asb_dep_abast_agua_a + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = asb_dep_abast_agua_a.geometriaaproximada + left join dominios.tipodepabast as dominio_tipodepabast on dominio_tipodepabast.code = asb_dep_abast_agua_a.tipodepabast + left join dominios.situacaoagua as dominio_situacaoagua on dominio_situacaoagua.code = asb_dep_abast_agua_a.situacaoagua + left join dominios.construcao as dominio_construcao on dominio_construcao.code = asb_dep_abast_agua_a.construcao + left join dominios.matconstr as dominio_matconstr on dominio_matconstr.code = asb_dep_abast_agua_a.matconstr + left join dominios.finalidade_asb as dominio_finalidade on dominio_finalidade.code = asb_dep_abast_agua_a.finalidade + left join dominios.situacaofisica as dominio_situacaofisica on dominio_situacaofisica.code = asb_dep_abast_agua_a.situacaofisica left join dominios.operacional as dominio_operacional on dominio_operacional.code = asb_dep_abast_agua_a.operacional # DROP VIEW IF EXISTS views.veg_mangue_a# -CREATE [VIEW] views.veg_mangue_a as +CREATE [VIEW] views.veg_mangue_a as SELECT id as id, nome as nome, @@ -4989,14 +4989,14 @@ CREATE [VIEW] views.veg_mangue_a as geom as geom, dominio_classificacaoporte.code_name as classificacaoporte [FROM] - cb.veg_mangue_a - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = veg_mangue_a.geometriaaproximada - left join dominios.denso as dominio_denso on dominio_denso.code = veg_mangue_a.denso - left join dominios.antropizada as dominio_antropizada on dominio_antropizada.code = veg_mangue_a.antropizada + cb.veg_mangue_a + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = veg_mangue_a.geometriaaproximada + left join dominios.denso as dominio_denso on dominio_denso.code = veg_mangue_a.denso + left join dominios.antropizada as dominio_antropizada on dominio_antropizada.code = veg_mangue_a.antropizada left join dominios.classificacaoporte as dominio_classificacaoporte on dominio_classificacaoporte.code = veg_mangue_a.classificacaoporte # DROP VIEW IF EXISTS views.tra_travessia_pedestre_p# -CREATE [VIEW] views.tra_travessia_pedestre_p as +CREATE [VIEW] views.tra_travessia_pedestre_p as SELECT id as id, nome as nome, @@ -5010,15 +5010,15 @@ CREATE [VIEW] views.tra_travessia_pedestre_p as extensao as extensao, geom as geom [FROM] - cb.tra_travessia_pedestre_p - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = tra_travessia_pedestre_p.geometriaaproximada - left join dominios.tipotravessiaped as dominio_tipotravessiaped on dominio_tipotravessiaped.code = tra_travessia_pedestre_p.tipotravessiaped - left join dominios.matconstr as dominio_matconstr on dominio_matconstr.code = tra_travessia_pedestre_p.matconstr - left join dominios.operacional as dominio_operacional on dominio_operacional.code = tra_travessia_pedestre_p.operacional + cb.tra_travessia_pedestre_p + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = tra_travessia_pedestre_p.geometriaaproximada + left join dominios.tipotravessiaped as dominio_tipotravessiaped on dominio_tipotravessiaped.code = tra_travessia_pedestre_p.tipotravessiaped + left join dominios.matconstr as dominio_matconstr on dominio_matconstr.code = tra_travessia_pedestre_p.matconstr + left join dominios.operacional as dominio_operacional on dominio_operacional.code = tra_travessia_pedestre_p.operacional left join dominios.situacaofisica as dominio_situacaofisica on dominio_situacaofisica.code = tra_travessia_pedestre_p.situacaofisica # DROP VIEW IF EXISTS views.hid_limite_massa_dagua_l# -CREATE [VIEW] views.hid_limite_massa_dagua_l as +CREATE [VIEW] views.hid_limite_massa_dagua_l as SELECT id as id, dominio_geometriaaproximada.code_name as geometriaaproximada, @@ -5028,13 +5028,13 @@ CREATE [VIEW] views.hid_limite_massa_dagua_l as nomeabrev as nomeabrev, geom as geom [FROM] - cb.hid_limite_massa_dagua_l - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = hid_limite_massa_dagua_l.geometriaaproximada - left join dominios.tipolimmassa as dominio_tipolimmassa on dominio_tipolimmassa.code = hid_limite_massa_dagua_l.tipolimmassa + cb.hid_limite_massa_dagua_l + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = hid_limite_massa_dagua_l.geometriaaproximada + left join dominios.tipolimmassa as dominio_tipolimmassa on dominio_tipolimmassa.code = hid_limite_massa_dagua_l.tipolimmassa left join dominios.materialpredominante as dominio_materialpredominante on dominio_materialpredominante.code = hid_limite_massa_dagua_l.materialpredominante # DROP VIEW IF EXISTS views.tra_tunel_l# -CREATE [VIEW] views.tra_tunel_l as +CREATE [VIEW] views.tra_tunel_l as SELECT id as id, nome as nome, @@ -5052,17 +5052,17 @@ CREATE [VIEW] views.tra_tunel_l as extensao as extensao, geom as geom [FROM] - cb.tra_tunel_l - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = tra_tunel_l.geometriaaproximada - left join dominios.tipotunel as dominio_tipotunel on dominio_tipotunel.code = tra_tunel_l.tipotunel - left join dominios.modaluso as dominio_modaluso on dominio_modaluso.code = tra_tunel_l.modaluso - left join dominios.matconstr as dominio_matconstr on dominio_matconstr.code = tra_tunel_l.matconstr - left join dominios.operacional as dominio_operacional on dominio_operacional.code = tra_tunel_l.operacional - left join dominios.situacaofisica as dominio_situacaofisica on dominio_situacaofisica.code = tra_tunel_l.situacaofisica + cb.tra_tunel_l + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = tra_tunel_l.geometriaaproximada + left join dominios.tipotunel as dominio_tipotunel on dominio_tipotunel.code = tra_tunel_l.tipotunel + left join dominios.modaluso as dominio_modaluso on dominio_modaluso.code = tra_tunel_l.modaluso + left join dominios.matconstr as dominio_matconstr on dominio_matconstr.code = tra_tunel_l.matconstr + left join dominios.operacional as dominio_operacional on dominio_operacional.code = tra_tunel_l.operacional + left join dominios.situacaofisica as dominio_situacaofisica on dominio_situacaofisica.code = tra_tunel_l.situacaofisica left join dominios.posicaopista as dominio_posicaopista on dominio_posicaopista.code = tra_tunel_l.posicaopista # DROP VIEW IF EXISTS views.asb_dep_saneamento_a# -CREATE [VIEW] views.asb_dep_saneamento_a as +CREATE [VIEW] views.asb_dep_saneamento_a as SELECT id as id, nome as nome, @@ -5079,19 +5079,19 @@ CREATE [VIEW] views.asb_dep_saneamento_a as id_complexo_saneamento as id_complexo_saneamento, geom as geom [FROM] - cb.asb_dep_saneamento_a - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = asb_dep_saneamento_a.geometriaaproximada - left join dominios.tipodepsaneam as dominio_tipodepsaneam on dominio_tipodepsaneam.code = asb_dep_saneamento_a.tipodepsaneam - left join dominios.construcao as dominio_construcao on dominio_construcao.code = asb_dep_saneamento_a.construcao - left join dominios.matconstr as dominio_matconstr on dominio_matconstr.code = asb_dep_saneamento_a.matconstr - left join dominios.finalidade_asb as dominio_finalidade on dominio_finalidade.code = asb_dep_saneamento_a.finalidade - left join dominios.operacional as dominio_operacional on dominio_operacional.code = asb_dep_saneamento_a.operacional - left join dominios.situacaofisica as dominio_situacaofisica on dominio_situacaofisica.code = asb_dep_saneamento_a.situacaofisica - left join dominios.residuo as dominio_residuo on dominio_residuo.code = asb_dep_saneamento_a.residuo + cb.asb_dep_saneamento_a + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = asb_dep_saneamento_a.geometriaaproximada + left join dominios.tipodepsaneam as dominio_tipodepsaneam on dominio_tipodepsaneam.code = asb_dep_saneamento_a.tipodepsaneam + left join dominios.construcao as dominio_construcao on dominio_construcao.code = asb_dep_saneamento_a.construcao + left join dominios.matconstr as dominio_matconstr on dominio_matconstr.code = asb_dep_saneamento_a.matconstr + left join dominios.finalidade_asb as dominio_finalidade on dominio_finalidade.code = asb_dep_saneamento_a.finalidade + left join dominios.operacional as dominio_operacional on dominio_operacional.code = asb_dep_saneamento_a.operacional + left join dominios.situacaofisica as dominio_situacaofisica on dominio_situacaofisica.code = asb_dep_saneamento_a.situacaofisica + left join dominios.residuo as dominio_residuo on dominio_residuo.code = asb_dep_saneamento_a.residuo left join dominios.tiporesiduo as dominio_tiporesiduo on dominio_tiporesiduo.code = asb_dep_saneamento_a.tiporesiduo # DROP VIEW IF EXISTS views.hid_queda_dagua_p# -CREATE [VIEW] views.hid_queda_dagua_p as +CREATE [VIEW] views.hid_queda_dagua_p as SELECT id as id, nome as nome, @@ -5101,12 +5101,12 @@ CREATE [VIEW] views.hid_queda_dagua_p as altura as altura, geom as geom [FROM] - cb.hid_queda_dagua_p - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = hid_queda_dagua_p.geometriaaproximada + cb.hid_queda_dagua_p + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = hid_queda_dagua_p.geometriaaproximada left join dominios.tipoqueda as dominio_tipoqueda on dominio_tipoqueda.code = hid_queda_dagua_p.tipoqueda # DROP VIEW IF EXISTS views.rel_alter_fisiog_antropica_a# -CREATE [VIEW] views.rel_alter_fisiog_antropica_a as +CREATE [VIEW] views.rel_alter_fisiog_antropica_a as SELECT id as id, nome as nome, @@ -5115,12 +5115,12 @@ CREATE [VIEW] views.rel_alter_fisiog_antropica_a as dominio_tipoalterantrop.code_name as tipoalterantrop, geom as geom [FROM] - cb.rel_alter_fisiog_antropica_a - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = rel_alter_fisiog_antropica_a.geometriaaproximada + cb.rel_alter_fisiog_antropica_a + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = rel_alter_fisiog_antropica_a.geometriaaproximada left join dominios.tipoalterantrop as dominio_tipoalterantrop on dominio_tipoalterantrop.code = rel_alter_fisiog_antropica_a.tipoalterantrop # DROP VIEW IF EXISTS views.lim_area_especial_p# -CREATE [VIEW] views.lim_area_especial_p as +CREATE [VIEW] views.lim_area_especial_p as SELECT id as id, nome as nome, @@ -5128,11 +5128,11 @@ CREATE [VIEW] views.lim_area_especial_p as dominio_geometriaaproximada.code_name as geometriaaproximada, geom as geom [FROM] - cb.lim_area_especial_p + cb.lim_area_especial_p left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = lim_area_especial_p.geometriaaproximada # DROP VIEW IF EXISTS views.rel_alter_fisiog_antropica_l# -CREATE [VIEW] views.rel_alter_fisiog_antropica_l as +CREATE [VIEW] views.rel_alter_fisiog_antropica_l as SELECT id as id, nome as nome, @@ -5141,12 +5141,12 @@ CREATE [VIEW] views.rel_alter_fisiog_antropica_l as dominio_tipoalterantrop.code_name as tipoalterantrop, geom as geom [FROM] - cb.rel_alter_fisiog_antropica_l - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = rel_alter_fisiog_antropica_l.geometriaaproximada + cb.rel_alter_fisiog_antropica_l + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = rel_alter_fisiog_antropica_l.geometriaaproximada left join dominios.tipoalterantrop as dominio_tipoalterantrop on dominio_tipoalterantrop.code = rel_alter_fisiog_antropica_l.tipoalterantrop # DROP VIEW IF EXISTS views.asb_edif_abast_agua_p# -CREATE [VIEW] views.asb_edif_abast_agua_p as +CREATE [VIEW] views.asb_edif_abast_agua_p as SELECT id as id, nome as nome, @@ -5159,15 +5159,15 @@ CREATE [VIEW] views.asb_edif_abast_agua_p as dominio_tipoedifabast.code_name as tipoedifabast, id_complexo_abast_agua as id_complexo_abast_agua [FROM] - cb.asb_edif_abast_agua_p - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = asb_edif_abast_agua_p.geometriaaproximada - left join dominios.operacional as dominio_operacional on dominio_operacional.code = asb_edif_abast_agua_p.operacional - left join dominios.situacaofisica as dominio_situacaofisica on dominio_situacaofisica.code = asb_edif_abast_agua_p.situacaofisica - left join dominios.matconstr as dominio_matconstr on dominio_matconstr.code = asb_edif_abast_agua_p.matconstr + cb.asb_edif_abast_agua_p + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = asb_edif_abast_agua_p.geometriaaproximada + left join dominios.operacional as dominio_operacional on dominio_operacional.code = asb_edif_abast_agua_p.operacional + left join dominios.situacaofisica as dominio_situacaofisica on dominio_situacaofisica.code = asb_edif_abast_agua_p.situacaofisica + left join dominios.matconstr as dominio_matconstr on dominio_matconstr.code = asb_edif_abast_agua_p.matconstr left join dominios.tipoedifabast as dominio_tipoedifabast on dominio_tipoedifabast.code = asb_edif_abast_agua_p.tipoedifabast # DROP VIEW IF EXISTS views.hid_barragem_a# -CREATE [VIEW] views.hid_barragem_a as +CREATE [VIEW] views.hid_barragem_a as SELECT id as id, nome as nome, @@ -5180,15 +5180,15 @@ CREATE [VIEW] views.hid_barragem_a as id_complexo_gerad_energ_eletr as id_complexo_gerad_energ_eletr, geom as geom [FROM] - cb.hid_barragem_a - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = hid_barragem_a.geometriaaproximada - left join dominios.matconstr as dominio_matconstr on dominio_matconstr.code = hid_barragem_a.matconstr - left join dominios.usoprincipal as dominio_usoprincipal on dominio_usoprincipal.code = hid_barragem_a.usoprincipal - left join dominios.operacional as dominio_operacional on dominio_operacional.code = hid_barragem_a.operacional + cb.hid_barragem_a + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = hid_barragem_a.geometriaaproximada + left join dominios.matconstr as dominio_matconstr on dominio_matconstr.code = hid_barragem_a.matconstr + left join dominios.usoprincipal as dominio_usoprincipal on dominio_usoprincipal.code = hid_barragem_a.usoprincipal + left join dominios.operacional as dominio_operacional on dominio_operacional.code = hid_barragem_a.operacional left join dominios.situacaofisica as dominio_situacaofisica on dominio_situacaofisica.code = hid_barragem_a.situacaofisica # DROP VIEW IF EXISTS views.hid_reservatorio_hidrico_a# -CREATE [VIEW] views.hid_reservatorio_hidrico_a as +CREATE [VIEW] views.hid_reservatorio_hidrico_a as SELECT id as id, nome as nome, @@ -5201,12 +5201,12 @@ CREATE [VIEW] views.hid_reservatorio_hidrico_a as id_complexo_gerad_energ_eletr as id_complexo_gerad_energ_eletr, geom as geom [FROM] - cb.hid_reservatorio_hidrico_a - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = hid_reservatorio_hidrico_a.geometriaaproximada + cb.hid_reservatorio_hidrico_a + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = hid_reservatorio_hidrico_a.geometriaaproximada left join dominios.usoprincipal as dominio_usoprincipal on dominio_usoprincipal.code = hid_reservatorio_hidrico_a.usoprincipal # DROP VIEW IF EXISTS views.tra_galeria_bueiro_l# -CREATE [VIEW] views.tra_galeria_bueiro_l as +CREATE [VIEW] views.tra_galeria_bueiro_l as SELECT id as id, nome as nome, @@ -5217,13 +5217,13 @@ CREATE [VIEW] views.tra_galeria_bueiro_l as dominio_situacaofisica.code_name as situacaofisica, geom as geom [FROM] - cb.tra_galeria_bueiro_l - left join dominios.matconstr as dominio_matconstr on dominio_matconstr.code = tra_galeria_bueiro_l.matconstr - left join dominios.operacional as dominio_operacional on dominio_operacional.code = tra_galeria_bueiro_l.operacional + cb.tra_galeria_bueiro_l + left join dominios.matconstr as dominio_matconstr on dominio_matconstr.code = tra_galeria_bueiro_l.matconstr + left join dominios.operacional as dominio_operacional on dominio_operacional.code = tra_galeria_bueiro_l.operacional left join dominios.situacaofisica as dominio_situacaofisica on dominio_situacaofisica.code = tra_galeria_bueiro_l.situacaofisica # DROP VIEW IF EXISTS views.rel_rocha_a# -CREATE [VIEW] views.rel_rocha_a as +CREATE [VIEW] views.rel_rocha_a as SELECT id as id, nome as nome, @@ -5233,13 +5233,13 @@ CREATE [VIEW] views.rel_rocha_a as geom as geom, dominio_tiporocha.code_name as tiporocha [FROM] - cb.rel_rocha_a - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = rel_rocha_a.geometriaaproximada - left join dominios.tipoelemnat as dominio_tipoelemnat on dominio_tipoelemnat.code = rel_rocha_a.tipoelemnat + cb.rel_rocha_a + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = rel_rocha_a.geometriaaproximada + left join dominios.tipoelemnat as dominio_tipoelemnat on dominio_tipoelemnat.code = rel_rocha_a.tipoelemnat left join dominios.tiporocha as dominio_tiporocha on dominio_tiporocha.code = rel_rocha_a.tiporocha # DROP VIEW IF EXISTS views.loc_edif_habitacional_p# -CREATE [VIEW] views.loc_edif_habitacional_p as +CREATE [VIEW] views.loc_edif_habitacional_p as SELECT id as id, nome as nome, @@ -5251,14 +5251,14 @@ CREATE [VIEW] views.loc_edif_habitacional_p as geom as geom, id_complexo_habitacional as id_complexo_habitacional [FROM] - cb.loc_edif_habitacional_p - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = loc_edif_habitacional_p.geometriaaproximada - left join dominios.operacional as dominio_operacional on dominio_operacional.code = loc_edif_habitacional_p.operacional - left join dominios.situacaofisica as dominio_situacaofisica on dominio_situacaofisica.code = loc_edif_habitacional_p.situacaofisica + cb.loc_edif_habitacional_p + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = loc_edif_habitacional_p.geometriaaproximada + left join dominios.operacional as dominio_operacional on dominio_operacional.code = loc_edif_habitacional_p.operacional + left join dominios.situacaofisica as dominio_situacaofisica on dominio_situacaofisica.code = loc_edif_habitacional_p.situacaofisica left join dominios.matconstr as dominio_matconstr on dominio_matconstr.code = loc_edif_habitacional_p.matconstr # DROP VIEW IF EXISTS views.tra_pista_ponto_pouso_a# -CREATE [VIEW] views.tra_pista_ponto_pouso_a as +CREATE [VIEW] views.tra_pista_ponto_pouso_a as SELECT id as id, nome as nome, @@ -5275,17 +5275,17 @@ CREATE [VIEW] views.tra_pista_ponto_pouso_a as id_complexo_aeroportuario as id_complexo_aeroportuario, geom as geom [FROM] - cb.tra_pista_ponto_pouso_a - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = tra_pista_ponto_pouso_a.geometriaaproximada - left join dominios.tipopista as dominio_tipopista on dominio_tipopista.code = tra_pista_ponto_pouso_a.tipopista - left join dominios.revestimento as dominio_revestimento on dominio_revestimento.code = tra_pista_ponto_pouso_a.revestimento - left join dominios.usopista as dominio_usopista on dominio_usopista.code = tra_pista_ponto_pouso_a.usopista - left join dominios.homologacao as dominio_homologacao on dominio_homologacao.code = tra_pista_ponto_pouso_a.homologacao - left join dominios.operacional as dominio_operacional on dominio_operacional.code = tra_pista_ponto_pouso_a.operacional + cb.tra_pista_ponto_pouso_a + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = tra_pista_ponto_pouso_a.geometriaaproximada + left join dominios.tipopista as dominio_tipopista on dominio_tipopista.code = tra_pista_ponto_pouso_a.tipopista + left join dominios.revestimento as dominio_revestimento on dominio_revestimento.code = tra_pista_ponto_pouso_a.revestimento + left join dominios.usopista as dominio_usopista on dominio_usopista.code = tra_pista_ponto_pouso_a.usopista + left join dominios.homologacao as dominio_homologacao on dominio_homologacao.code = tra_pista_ponto_pouso_a.homologacao + left join dominios.operacional as dominio_operacional on dominio_operacional.code = tra_pista_ponto_pouso_a.operacional left join dominios.situacaofisica as dominio_situacaofisica on dominio_situacaofisica.code = tra_pista_ponto_pouso_a.situacaofisica # DROP VIEW IF EXISTS views.tra_galeria_bueiro_p# -CREATE [VIEW] views.tra_galeria_bueiro_p as +CREATE [VIEW] views.tra_galeria_bueiro_p as SELECT id as id, nome as nome, @@ -5296,13 +5296,13 @@ CREATE [VIEW] views.tra_galeria_bueiro_p as dominio_situacaofisica.code_name as situacaofisica, geom as geom [FROM] - cb.tra_galeria_bueiro_p - left join dominios.matconstr as dominio_matconstr on dominio_matconstr.code = tra_galeria_bueiro_p.matconstr - left join dominios.operacional as dominio_operacional on dominio_operacional.code = tra_galeria_bueiro_p.operacional + cb.tra_galeria_bueiro_p + left join dominios.matconstr as dominio_matconstr on dominio_matconstr.code = tra_galeria_bueiro_p.matconstr + left join dominios.operacional as dominio_operacional on dominio_operacional.code = tra_galeria_bueiro_p.operacional left join dominios.situacaofisica as dominio_situacaofisica on dominio_situacaofisica.code = tra_galeria_bueiro_p.situacaofisica # DROP VIEW IF EXISTS views.hid_queda_dagua_a# -CREATE [VIEW] views.hid_queda_dagua_a as +CREATE [VIEW] views.hid_queda_dagua_a as SELECT id as id, nome as nome, @@ -5312,12 +5312,12 @@ CREATE [VIEW] views.hid_queda_dagua_a as altura as altura, geom as geom [FROM] - cb.hid_queda_dagua_a - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = hid_queda_dagua_a.geometriaaproximada + cb.hid_queda_dagua_a + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = hid_queda_dagua_a.geometriaaproximada left join dominios.tipoqueda as dominio_tipoqueda on dominio_tipoqueda.code = hid_queda_dagua_a.tipoqueda # DROP VIEW IF EXISTS views.loc_localidade_p# -CREATE [VIEW] views.loc_localidade_p as +CREATE [VIEW] views.loc_localidade_p as SELECT id as id, nome as nome, @@ -5331,11 +5331,11 @@ CREATE [VIEW] views.loc_localidade_p as longitude_gms as longitude_gms, geom as geom [FROM] - cb.loc_localidade_p + cb.loc_localidade_p left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = loc_localidade_p.geometriaaproximada # DROP VIEW IF EXISTS views.edu_edif_const_lazer_p# -CREATE [VIEW] views.edu_edif_const_lazer_p as +CREATE [VIEW] views.edu_edif_const_lazer_p as SELECT id as id, nome as nome, @@ -5348,15 +5348,15 @@ CREATE [VIEW] views.edu_edif_const_lazer_p as dominio_tipoediflazer.code_name as tipoediflazer, id_complexo_lazer as id_complexo_lazer [FROM] - cb.edu_edif_const_lazer_p - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = edu_edif_const_lazer_p.geometriaaproximada - left join dominios.operacional as dominio_operacional on dominio_operacional.code = edu_edif_const_lazer_p.operacional - left join dominios.situacaofisica as dominio_situacaofisica on dominio_situacaofisica.code = edu_edif_const_lazer_p.situacaofisica - left join dominios.matconstr as dominio_matconstr on dominio_matconstr.code = edu_edif_const_lazer_p.matconstr + cb.edu_edif_const_lazer_p + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = edu_edif_const_lazer_p.geometriaaproximada + left join dominios.operacional as dominio_operacional on dominio_operacional.code = edu_edif_const_lazer_p.operacional + left join dominios.situacaofisica as dominio_situacaofisica on dominio_situacaofisica.code = edu_edif_const_lazer_p.situacaofisica + left join dominios.matconstr as dominio_matconstr on dominio_matconstr.code = edu_edif_const_lazer_p.matconstr left join dominios.tipoediflazer as dominio_tipoediflazer on dominio_tipoediflazer.code = edu_edif_const_lazer_p.tipoediflazer # DROP VIEW IF EXISTS views.lim_delimitacao_fisica_l# -CREATE [VIEW] views.lim_delimitacao_fisica_l as +CREATE [VIEW] views.lim_delimitacao_fisica_l as SELECT id as id, nome as nome, @@ -5367,14 +5367,14 @@ CREATE [VIEW] views.lim_delimitacao_fisica_l as dominio_eletrificada.code_name as eletrificada, geom as geom [FROM] - cb.lim_delimitacao_fisica_l - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = lim_delimitacao_fisica_l.geometriaaproximada - left join dominios.tipodelimfis as dominio_tipodelimfis on dominio_tipodelimfis.code = lim_delimitacao_fisica_l.tipodelimfis - left join dominios.matconstr as dominio_matconstr on dominio_matconstr.code = lim_delimitacao_fisica_l.matconstr + cb.lim_delimitacao_fisica_l + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = lim_delimitacao_fisica_l.geometriaaproximada + left join dominios.tipodelimfis as dominio_tipodelimfis on dominio_tipodelimfis.code = lim_delimitacao_fisica_l.tipodelimfis + left join dominios.matconstr as dominio_matconstr on dominio_matconstr.code = lim_delimitacao_fisica_l.matconstr left join dominios.eletrificada as dominio_eletrificada on dominio_eletrificada.code = lim_delimitacao_fisica_l.eletrificada # DROP VIEW IF EXISTS views.asb_edif_abast_agua_a# -CREATE [VIEW] views.asb_edif_abast_agua_a as +CREATE [VIEW] views.asb_edif_abast_agua_a as SELECT id as id, nome as nome, @@ -5387,27 +5387,27 @@ CREATE [VIEW] views.asb_edif_abast_agua_a as dominio_tipoedifabast.code_name as tipoedifabast, id_complexo_abast_agua as id_complexo_abast_agua [FROM] - cb.asb_edif_abast_agua_a - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = asb_edif_abast_agua_a.geometriaaproximada - left join dominios.operacional as dominio_operacional on dominio_operacional.code = asb_edif_abast_agua_a.operacional - left join dominios.situacaofisica as dominio_situacaofisica on dominio_situacaofisica.code = asb_edif_abast_agua_a.situacaofisica - left join dominios.matconstr as dominio_matconstr on dominio_matconstr.code = asb_edif_abast_agua_a.matconstr + cb.asb_edif_abast_agua_a + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = asb_edif_abast_agua_a.geometriaaproximada + left join dominios.operacional as dominio_operacional on dominio_operacional.code = asb_edif_abast_agua_a.operacional + left join dominios.situacaofisica as dominio_situacaofisica on dominio_situacaofisica.code = asb_edif_abast_agua_a.situacaofisica + left join dominios.matconstr as dominio_matconstr on dominio_matconstr.code = asb_edif_abast_agua_a.matconstr left join dominios.tipoedifabast as dominio_tipoedifabast on dominio_tipoedifabast.code = asb_edif_abast_agua_a.tipoedifabast # DROP VIEW IF EXISTS views.tra_ponto_ferroviario_p# -CREATE [VIEW] views.tra_ponto_ferroviario_p as +CREATE [VIEW] views.tra_ponto_ferroviario_p as SELECT id as id, dominio_geometriaaproximada.code_name as geometriaaproximada, dominio_relacionado.code_name as relacionado, geom as geom [FROM] - cb.tra_ponto_ferroviario_p - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = tra_ponto_ferroviario_p.geometriaaproximada + cb.tra_ponto_ferroviario_p + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = tra_ponto_ferroviario_p.geometriaaproximada left join dominios.relacionado_fer as dominio_relacionado on dominio_relacionado.code = tra_ponto_ferroviario_p.relacionado # DROP VIEW IF EXISTS views.edu_arquibancada_p# -CREATE [VIEW] views.edu_arquibancada_p as +CREATE [VIEW] views.edu_arquibancada_p as SELECT id as id, nome as nome, @@ -5418,13 +5418,13 @@ CREATE [VIEW] views.edu_arquibancada_p as id_complexo_lazer as id_complexo_lazer, geom as geom [FROM] - cb.edu_arquibancada_p - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = edu_arquibancada_p.geometriaaproximada - left join dominios.operacional as dominio_operacional on dominio_operacional.code = edu_arquibancada_p.operacional + cb.edu_arquibancada_p + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = edu_arquibancada_p.geometriaaproximada + left join dominios.operacional as dominio_operacional on dominio_operacional.code = edu_arquibancada_p.operacional left join dominios.situacaofisica as dominio_situacaofisica on dominio_situacaofisica.code = edu_arquibancada_p.situacaofisica # DROP VIEW IF EXISTS views.enc_antena_comunic_p# -CREATE [VIEW] views.enc_antena_comunic_p as +CREATE [VIEW] views.enc_antena_comunic_p as SELECT id as id, nome as nome, @@ -5434,12 +5434,12 @@ CREATE [VIEW] views.enc_antena_comunic_p as geom as geom, id_complexo_comunicacao as id_complexo_comunicacao [FROM] - cb.enc_antena_comunic_p - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = enc_antena_comunic_p.geometriaaproximada + cb.enc_antena_comunic_p + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = enc_antena_comunic_p.geometriaaproximada left join dominios.posicaoreledific as dominio_posicaoreledific on dominio_posicaoreledific.code = enc_antena_comunic_p.posicaoreledific # DROP VIEW IF EXISTS views.hid_queda_dagua_l# -CREATE [VIEW] views.hid_queda_dagua_l as +CREATE [VIEW] views.hid_queda_dagua_l as SELECT id as id, nome as nome, @@ -5449,12 +5449,12 @@ CREATE [VIEW] views.hid_queda_dagua_l as altura as altura, geom as geom [FROM] - cb.hid_queda_dagua_l - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = hid_queda_dagua_l.geometriaaproximada + cb.hid_queda_dagua_l + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = hid_queda_dagua_l.geometriaaproximada left join dominios.tipoqueda as dominio_tipoqueda on dominio_tipoqueda.code = hid_queda_dagua_l.tipoqueda # DROP VIEW IF EXISTS views.enc_est_gerad_energia_eletr_p# -CREATE [VIEW] views.enc_est_gerad_energia_eletr_p as +CREATE [VIEW] views.enc_est_gerad_energia_eletr_p as SELECT id as id, nome as nome, @@ -5470,15 +5470,15 @@ CREATE [VIEW] views.enc_est_gerad_energia_eletr_p as id_complexo_gerad_energ_eletr as id_complexo_gerad_energ_eletr, geom as geom [FROM] - cb.enc_est_gerad_energia_eletr_p - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = enc_est_gerad_energia_eletr_p.geometriaaproximada - left join dominios.tipoestgerad as dominio_tipoestgerad on dominio_tipoestgerad.code = enc_est_gerad_energia_eletr_p.tipoestgerad - left join dominios.operacional as dominio_operacional on dominio_operacional.code = enc_est_gerad_energia_eletr_p.operacional - left join dominios.situacaofisica as dominio_situacaofisica on dominio_situacaofisica.code = enc_est_gerad_energia_eletr_p.situacaofisica + cb.enc_est_gerad_energia_eletr_p + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = enc_est_gerad_energia_eletr_p.geometriaaproximada + left join dominios.tipoestgerad as dominio_tipoestgerad on dominio_tipoestgerad.code = enc_est_gerad_energia_eletr_p.tipoestgerad + left join dominios.operacional as dominio_operacional on dominio_operacional.code = enc_est_gerad_energia_eletr_p.operacional + left join dominios.situacaofisica as dominio_situacaofisica on dominio_situacaofisica.code = enc_est_gerad_energia_eletr_p.situacaofisica left join dominios.destenergelet as dominio_destenergelet on dominio_destenergelet.code = enc_est_gerad_energia_eletr_p.destenergelet # DROP VIEW IF EXISTS views.veg_vegetacao_a# -CREATE [VIEW] views.veg_vegetacao_a as +CREATE [VIEW] views.veg_vegetacao_a as SELECT id as id, nome as nome, @@ -5488,13 +5488,13 @@ CREATE [VIEW] views.veg_vegetacao_a as dominio_antropizada.code_name as antropizada, geom as geom [FROM] - cb.veg_vegetacao_a - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = veg_vegetacao_a.geometriaaproximada - left join dominios.denso as dominio_denso on dominio_denso.code = veg_vegetacao_a.denso + cb.veg_vegetacao_a + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = veg_vegetacao_a.geometriaaproximada + left join dominios.denso as dominio_denso on dominio_denso.code = veg_vegetacao_a.denso left join dominios.antropizada as dominio_antropizada on dominio_antropizada.code = veg_vegetacao_a.antropizada # DROP VIEW IF EXISTS views.veg_veg_area_contato_a# -CREATE [VIEW] views.veg_veg_area_contato_a as +CREATE [VIEW] views.veg_veg_area_contato_a as SELECT id as id, nome as nome, @@ -5506,14 +5506,14 @@ CREATE [VIEW] views.veg_veg_area_contato_a as dominio_antropizada.code_name as antropizada, geom as geom [FROM] - cb.veg_veg_area_contato_a - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = veg_veg_area_contato_a.geometriaaproximada - left join dominios.classificacaoporte as dominio_classificacaoporte on dominio_classificacaoporte.code = veg_veg_area_contato_a.classificacaoporte - left join dominios.denso as dominio_denso on dominio_denso.code = veg_veg_area_contato_a.denso + cb.veg_veg_area_contato_a + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = veg_veg_area_contato_a.geometriaaproximada + left join dominios.classificacaoporte as dominio_classificacaoporte on dominio_classificacaoporte.code = veg_veg_area_contato_a.classificacaoporte + left join dominios.denso as dominio_denso on dominio_denso.code = veg_veg_area_contato_a.denso left join dominios.antropizada as dominio_antropizada on dominio_antropizada.code = veg_veg_area_contato_a.antropizada # DROP VIEW IF EXISTS views.tra_pista_ponto_pouso_p# -CREATE [VIEW] views.tra_pista_ponto_pouso_p as +CREATE [VIEW] views.tra_pista_ponto_pouso_p as SELECT id as id, nome as nome, @@ -5530,17 +5530,17 @@ CREATE [VIEW] views.tra_pista_ponto_pouso_p as id_complexo_aeroportuario as id_complexo_aeroportuario, geom as geom [FROM] - cb.tra_pista_ponto_pouso_p - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = tra_pista_ponto_pouso_p.geometriaaproximada - left join dominios.tipopista as dominio_tipopista on dominio_tipopista.code = tra_pista_ponto_pouso_p.tipopista - left join dominios.revestimento as dominio_revestimento on dominio_revestimento.code = tra_pista_ponto_pouso_p.revestimento - left join dominios.usopista as dominio_usopista on dominio_usopista.code = tra_pista_ponto_pouso_p.usopista - left join dominios.homologacao as dominio_homologacao on dominio_homologacao.code = tra_pista_ponto_pouso_p.homologacao - left join dominios.operacional as dominio_operacional on dominio_operacional.code = tra_pista_ponto_pouso_p.operacional + cb.tra_pista_ponto_pouso_p + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = tra_pista_ponto_pouso_p.geometriaaproximada + left join dominios.tipopista as dominio_tipopista on dominio_tipopista.code = tra_pista_ponto_pouso_p.tipopista + left join dominios.revestimento as dominio_revestimento on dominio_revestimento.code = tra_pista_ponto_pouso_p.revestimento + left join dominios.usopista as dominio_usopista on dominio_usopista.code = tra_pista_ponto_pouso_p.usopista + left join dominios.homologacao as dominio_homologacao on dominio_homologacao.code = tra_pista_ponto_pouso_p.homologacao + left join dominios.operacional as dominio_operacional on dominio_operacional.code = tra_pista_ponto_pouso_p.operacional left join dominios.situacaofisica as dominio_situacaofisica on dominio_situacaofisica.code = tra_pista_ponto_pouso_p.situacaofisica # DROP VIEW IF EXISTS views.tra_fundeadouro_p# -CREATE [VIEW] views.tra_fundeadouro_p as +CREATE [VIEW] views.tra_fundeadouro_p as SELECT id as id, nome as nome, @@ -5551,13 +5551,13 @@ CREATE [VIEW] views.tra_fundeadouro_p as id_complexo_portuario as id_complexo_portuario, geom as geom [FROM] - cb.tra_fundeadouro_p - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = tra_fundeadouro_p.geometriaaproximada - left join dominios.destinacaofundeadouro as dominio_destinacaofundeadouro on dominio_destinacaofundeadouro.code = tra_fundeadouro_p.destinacaofundeadouro + cb.tra_fundeadouro_p + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = tra_fundeadouro_p.geometriaaproximada + left join dominios.destinacaofundeadouro as dominio_destinacaofundeadouro on dominio_destinacaofundeadouro.code = tra_fundeadouro_p.destinacaofundeadouro left join dominios.administracao as dominio_administracao on dominio_administracao.code = tra_fundeadouro_p.administracao # DROP VIEW IF EXISTS views.lim_municipio_a# -CREATE [VIEW] views.lim_municipio_a as +CREATE [VIEW] views.lim_municipio_a as SELECT id as id, nome as nome, @@ -5567,11 +5567,11 @@ CREATE [VIEW] views.lim_municipio_a as geocodigo as geocodigo, anodereferencia as anodereferencia [FROM] - cb.lim_municipio_a + cb.lim_municipio_a left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = lim_municipio_a.geometriaaproximada # DROP VIEW IF EXISTS views.tra_edif_constr_aeroportuaria_a# -CREATE [VIEW] views.tra_edif_constr_aeroportuaria_a as +CREATE [VIEW] views.tra_edif_constr_aeroportuaria_a as SELECT id as id, nome as nome, @@ -5585,16 +5585,16 @@ CREATE [VIEW] views.tra_edif_constr_aeroportuaria_a as dominio_administracao.code_name as administracao, id_complexo_aeroportuario as id_complexo_aeroportuario [FROM] - cb.tra_edif_constr_aeroportuaria_a - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = tra_edif_constr_aeroportuaria_a.geometriaaproximada - left join dominios.operacional as dominio_operacional on dominio_operacional.code = tra_edif_constr_aeroportuaria_a.operacional - left join dominios.situacaofisica as dominio_situacaofisica on dominio_situacaofisica.code = tra_edif_constr_aeroportuaria_a.situacaofisica - left join dominios.matconstr as dominio_matconstr on dominio_matconstr.code = tra_edif_constr_aeroportuaria_a.matconstr - left join dominios.tipoedifaero as dominio_tipoedifaero on dominio_tipoedifaero.code = tra_edif_constr_aeroportuaria_a.tipoedifaero + cb.tra_edif_constr_aeroportuaria_a + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = tra_edif_constr_aeroportuaria_a.geometriaaproximada + left join dominios.operacional as dominio_operacional on dominio_operacional.code = tra_edif_constr_aeroportuaria_a.operacional + left join dominios.situacaofisica as dominio_situacaofisica on dominio_situacaofisica.code = tra_edif_constr_aeroportuaria_a.situacaofisica + left join dominios.matconstr as dominio_matconstr on dominio_matconstr.code = tra_edif_constr_aeroportuaria_a.matconstr + left join dominios.tipoedifaero as dominio_tipoedifaero on dominio_tipoedifaero.code = tra_edif_constr_aeroportuaria_a.tipoedifaero left join dominios.administracao as dominio_administracao on dominio_administracao.code = tra_edif_constr_aeroportuaria_a.administracao # DROP VIEW IF EXISTS views.tra_cremalheira_p# -CREATE [VIEW] views.tra_cremalheira_p as +CREATE [VIEW] views.tra_cremalheira_p as SELECT id as id, nome as nome, @@ -5604,13 +5604,13 @@ CREATE [VIEW] views.tra_cremalheira_p as dominio_situacaofisica.code_name as situacaofisica, geom as geom [FROM] - cb.tra_cremalheira_p - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = tra_cremalheira_p.geometriaaproximada - left join dominios.operacional as dominio_operacional on dominio_operacional.code = tra_cremalheira_p.operacional + cb.tra_cremalheira_p + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = tra_cremalheira_p.geometriaaproximada + left join dominios.operacional as dominio_operacional on dominio_operacional.code = tra_cremalheira_p.operacional left join dominios.situacaofisica as dominio_situacaofisica on dominio_situacaofisica.code = tra_cremalheira_p.situacaofisica # DROP VIEW IF EXISTS views.eco_equip_agropec_l# -CREATE [VIEW] views.eco_equip_agropec_l as +CREATE [VIEW] views.eco_equip_agropec_l as SELECT id as id, nome as nome, @@ -5623,15 +5623,15 @@ CREATE [VIEW] views.eco_equip_agropec_l as id_org_agropec_ext_veg_pesca as id_org_agropec_ext_veg_pesca, geom as geom [FROM] - cb.eco_equip_agropec_l - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = eco_equip_agropec_l.geometriaaproximada - left join dominios.operacional as dominio_operacional on dominio_operacional.code = eco_equip_agropec_l.operacional - left join dominios.situacaofisica as dominio_situacaofisica on dominio_situacaofisica.code = eco_equip_agropec_l.situacaofisica - left join dominios.tipoequipagropec as dominio_tipoequipagropec on dominio_tipoequipagropec.code = eco_equip_agropec_l.tipoequipagropec + cb.eco_equip_agropec_l + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = eco_equip_agropec_l.geometriaaproximada + left join dominios.operacional as dominio_operacional on dominio_operacional.code = eco_equip_agropec_l.operacional + left join dominios.situacaofisica as dominio_situacaofisica on dominio_situacaofisica.code = eco_equip_agropec_l.situacaofisica + left join dominios.tipoequipagropec as dominio_tipoequipagropec on dominio_tipoequipagropec.code = eco_equip_agropec_l.tipoequipagropec left join dominios.matconstr as dominio_matconstr on dominio_matconstr.code = eco_equip_agropec_l.matconstr # DROP VIEW IF EXISTS views.loc_edificacao_a# -CREATE [VIEW] views.loc_edificacao_a as +CREATE [VIEW] views.loc_edificacao_a as SELECT id as id, nome as nome, @@ -5642,14 +5642,14 @@ CREATE [VIEW] views.loc_edificacao_a as dominio_matconstr.code_name as matconstr, geom as geom [FROM] - cb.loc_edificacao_a - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = loc_edificacao_a.geometriaaproximada - left join dominios.operacional as dominio_operacional on dominio_operacional.code = loc_edificacao_a.operacional - left join dominios.situacaofisica as dominio_situacaofisica on dominio_situacaofisica.code = loc_edificacao_a.situacaofisica + cb.loc_edificacao_a + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = loc_edificacao_a.geometriaaproximada + left join dominios.operacional as dominio_operacional on dominio_operacional.code = loc_edificacao_a.operacional + left join dominios.situacaofisica as dominio_situacaofisica on dominio_situacaofisica.code = loc_edificacao_a.situacaofisica left join dominios.matconstr as dominio_matconstr on dominio_matconstr.code = loc_edificacao_a.matconstr # DROP VIEW IF EXISTS views.pto_pto_controle_p# -CREATE [VIEW] views.pto_pto_controle_p as +CREATE [VIEW] views.pto_pto_controle_p as SELECT id as id, nomeabrev as nomeabrev, @@ -5670,16 +5670,16 @@ CREATE [VIEW] views.pto_pto_controle_p as dominio_materializado.code_name as materializado, codprojeto as codprojeto [FROM] - cb.pto_pto_controle_p - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = pto_pto_controle_p.geometriaaproximada - left join dominios.tiporef as dominio_tiporef on dominio_tiporef.code = pto_pto_controle_p.tiporef - left join dominios.sistemageodesico as dominio_sistemageodesico on dominio_sistemageodesico.code = pto_pto_controle_p.sistemageodesico - left join dominios.referencialaltim as dominio_referencialaltim on dominio_referencialaltim.code = pto_pto_controle_p.referencialaltim - left join dominios.tipoptocontrole as dominio_tipoptocontrole on dominio_tipoptocontrole.code = pto_pto_controle_p.tipoptocontrole + cb.pto_pto_controle_p + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = pto_pto_controle_p.geometriaaproximada + left join dominios.tiporef as dominio_tiporef on dominio_tiporef.code = pto_pto_controle_p.tiporef + left join dominios.sistemageodesico as dominio_sistemageodesico on dominio_sistemageodesico.code = pto_pto_controle_p.sistemageodesico + left join dominios.referencialaltim as dominio_referencialaltim on dominio_referencialaltim.code = pto_pto_controle_p.referencialaltim + left join dominios.tipoptocontrole as dominio_tipoptocontrole on dominio_tipoptocontrole.code = pto_pto_controle_p.tipoptocontrole left join dominios.materializado as dominio_materializado on dominio_materializado.code = pto_pto_controle_p.materializado # DROP VIEW IF EXISTS views.tra_cremalheira_l# -CREATE [VIEW] views.tra_cremalheira_l as +CREATE [VIEW] views.tra_cremalheira_l as SELECT id as id, nome as nome, @@ -5689,13 +5689,13 @@ CREATE [VIEW] views.tra_cremalheira_l as dominio_situacaofisica.code_name as situacaofisica, geom as geom [FROM] - cb.tra_cremalheira_l - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = tra_cremalheira_l.geometriaaproximada - left join dominios.operacional as dominio_operacional on dominio_operacional.code = tra_cremalheira_l.operacional + cb.tra_cremalheira_l + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = tra_cremalheira_l.geometriaaproximada + left join dominios.operacional as dominio_operacional on dominio_operacional.code = tra_cremalheira_l.operacional left join dominios.situacaofisica as dominio_situacaofisica on dominio_situacaofisica.code = tra_cremalheira_l.situacaofisica # DROP VIEW IF EXISTS views.eco_equip_agropec_p# -CREATE [VIEW] views.eco_equip_agropec_p as +CREATE [VIEW] views.eco_equip_agropec_p as SELECT id as id, nome as nome, @@ -5708,15 +5708,15 @@ CREATE [VIEW] views.eco_equip_agropec_p as id_org_agropec_ext_veg_pesca as id_org_agropec_ext_veg_pesca, geom as geom [FROM] - cb.eco_equip_agropec_p - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = eco_equip_agropec_p.geometriaaproximada - left join dominios.operacional as dominio_operacional on dominio_operacional.code = eco_equip_agropec_p.operacional - left join dominios.situacaofisica as dominio_situacaofisica on dominio_situacaofisica.code = eco_equip_agropec_p.situacaofisica - left join dominios.tipoequipagropec as dominio_tipoequipagropec on dominio_tipoequipagropec.code = eco_equip_agropec_p.tipoequipagropec + cb.eco_equip_agropec_p + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = eco_equip_agropec_p.geometriaaproximada + left join dominios.operacional as dominio_operacional on dominio_operacional.code = eco_equip_agropec_p.operacional + left join dominios.situacaofisica as dominio_situacaofisica on dominio_situacaofisica.code = eco_equip_agropec_p.situacaofisica + left join dominios.tipoequipagropec as dominio_tipoequipagropec on dominio_tipoequipagropec.code = eco_equip_agropec_p.tipoequipagropec left join dominios.matconstr as dominio_matconstr on dominio_matconstr.code = eco_equip_agropec_p.matconstr # DROP VIEW IF EXISTS views.enc_est_gerad_energia_eletr_a# -CREATE [VIEW] views.enc_est_gerad_energia_eletr_a as +CREATE [VIEW] views.enc_est_gerad_energia_eletr_a as SELECT id as id, nome as nome, @@ -5732,26 +5732,26 @@ CREATE [VIEW] views.enc_est_gerad_energia_eletr_a as id_complexo_gerad_energ_eletr as id_complexo_gerad_energ_eletr, geom as geom [FROM] - cb.enc_est_gerad_energia_eletr_a - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = enc_est_gerad_energia_eletr_a.geometriaaproximada - left join dominios.tipoestgerad as dominio_tipoestgerad on dominio_tipoestgerad.code = enc_est_gerad_energia_eletr_a.tipoestgerad - left join dominios.operacional as dominio_operacional on dominio_operacional.code = enc_est_gerad_energia_eletr_a.operacional - left join dominios.situacaofisica as dominio_situacaofisica on dominio_situacaofisica.code = enc_est_gerad_energia_eletr_a.situacaofisica + cb.enc_est_gerad_energia_eletr_a + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = enc_est_gerad_energia_eletr_a.geometriaaproximada + left join dominios.tipoestgerad as dominio_tipoestgerad on dominio_tipoestgerad.code = enc_est_gerad_energia_eletr_a.tipoestgerad + left join dominios.operacional as dominio_operacional on dominio_operacional.code = enc_est_gerad_energia_eletr_a.operacional + left join dominios.situacaofisica as dominio_situacaofisica on dominio_situacaofisica.code = enc_est_gerad_energia_eletr_a.situacaofisica left join dominios.destenergelet as dominio_destenergelet on dominio_destenergelet.code = enc_est_gerad_energia_eletr_a.destenergelet # DROP VIEW IF EXISTS views.edu_area_ruinas_a# -CREATE [VIEW] views.edu_area_ruinas_a as +CREATE [VIEW] views.edu_area_ruinas_a as SELECT id as id, dominio_geometriaaproximada.code_name as geometriaaproximada, geom as geom, id_complexo_lazer as id_complexo_lazer [FROM] - cb.edu_area_ruinas_a + cb.edu_area_ruinas_a left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = edu_area_ruinas_a.geometriaaproximada # DROP VIEW IF EXISTS views.tra_fundeadouro_l# -CREATE [VIEW] views.tra_fundeadouro_l as +CREATE [VIEW] views.tra_fundeadouro_l as SELECT id as id, nome as nome, @@ -5762,13 +5762,13 @@ CREATE [VIEW] views.tra_fundeadouro_l as id_complexo_portuario as id_complexo_portuario, geom as geom [FROM] - cb.tra_fundeadouro_l - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = tra_fundeadouro_l.geometriaaproximada - left join dominios.destinacaofundeadouro as dominio_destinacaofundeadouro on dominio_destinacaofundeadouro.code = tra_fundeadouro_l.destinacaofundeadouro + cb.tra_fundeadouro_l + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = tra_fundeadouro_l.geometriaaproximada + left join dominios.destinacaofundeadouro as dominio_destinacaofundeadouro on dominio_destinacaofundeadouro.code = tra_fundeadouro_l.destinacaofundeadouro left join dominios.administracao as dominio_administracao on dominio_administracao.code = tra_fundeadouro_l.administracao # DROP VIEW IF EXISTS views.tra_edif_constr_portuaria_a# -CREATE [VIEW] views.tra_edif_constr_portuaria_a as +CREATE [VIEW] views.tra_edif_constr_portuaria_a as SELECT id as id, nome as nome, @@ -5782,16 +5782,16 @@ CREATE [VIEW] views.tra_edif_constr_portuaria_a as dominio_administracao.code_name as administracao, id_complexo_portuario as id_complexo_portuario [FROM] - cb.tra_edif_constr_portuaria_a - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = tra_edif_constr_portuaria_a.geometriaaproximada - left join dominios.operacional as dominio_operacional on dominio_operacional.code = tra_edif_constr_portuaria_a.operacional - left join dominios.situacaofisica as dominio_situacaofisica on dominio_situacaofisica.code = tra_edif_constr_portuaria_a.situacaofisica - left join dominios.matconstr as dominio_matconstr on dominio_matconstr.code = tra_edif_constr_portuaria_a.matconstr - left join dominios.tipoedifport as dominio_tipoedifport on dominio_tipoedifport.code = tra_edif_constr_portuaria_a.tipoedifport + cb.tra_edif_constr_portuaria_a + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = tra_edif_constr_portuaria_a.geometriaaproximada + left join dominios.operacional as dominio_operacional on dominio_operacional.code = tra_edif_constr_portuaria_a.operacional + left join dominios.situacaofisica as dominio_situacaofisica on dominio_situacaofisica.code = tra_edif_constr_portuaria_a.situacaofisica + left join dominios.matconstr as dominio_matconstr on dominio_matconstr.code = tra_edif_constr_portuaria_a.matconstr + left join dominios.tipoedifport as dominio_tipoedifport on dominio_tipoedifport.code = tra_edif_constr_portuaria_a.tipoedifport left join dominios.administracao as dominio_administracao on dominio_administracao.code = tra_edif_constr_portuaria_a.administracao # DROP VIEW IF EXISTS views.rel_ponto_cotado_altimetrico_p# -CREATE [VIEW] views.rel_ponto_cotado_altimetrico_p as +CREATE [VIEW] views.rel_ponto_cotado_altimetrico_p as SELECT id as id, dominio_geometriaaproximada.code_name as geometriaaproximada, @@ -5799,12 +5799,12 @@ CREATE [VIEW] views.rel_ponto_cotado_altimetrico_p as cota as cota, geom as geom [FROM] - cb.rel_ponto_cotado_altimetrico_p - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = rel_ponto_cotado_altimetrico_p.geometriaaproximada + cb.rel_ponto_cotado_altimetrico_p + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = rel_ponto_cotado_altimetrico_p.geometriaaproximada left join dominios.cotacomprovada as dominio_cotacomprovada on dominio_cotacomprovada.code = rel_ponto_cotado_altimetrico_p.cotacomprovada # DROP VIEW IF EXISTS views.eco_edif_agrop_ext_veg_pesca_a# -CREATE [VIEW] views.eco_edif_agrop_ext_veg_pesca_a as +CREATE [VIEW] views.eco_edif_agrop_ext_veg_pesca_a as SELECT id as id, nome as nome, @@ -5817,15 +5817,15 @@ CREATE [VIEW] views.eco_edif_agrop_ext_veg_pesca_a as dominio_tipoedifagropec.code_name as tipoedifagropec, id_org_agropec_ext_veg_pesca as id_org_agropec_ext_veg_pesca [FROM] - cb.eco_edif_agrop_ext_veg_pesca_a - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = eco_edif_agrop_ext_veg_pesca_a.geometriaaproximada - left join dominios.operacional as dominio_operacional on dominio_operacional.code = eco_edif_agrop_ext_veg_pesca_a.operacional - left join dominios.situacaofisica as dominio_situacaofisica on dominio_situacaofisica.code = eco_edif_agrop_ext_veg_pesca_a.situacaofisica - left join dominios.matconstr as dominio_matconstr on dominio_matconstr.code = eco_edif_agrop_ext_veg_pesca_a.matconstr + cb.eco_edif_agrop_ext_veg_pesca_a + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = eco_edif_agrop_ext_veg_pesca_a.geometriaaproximada + left join dominios.operacional as dominio_operacional on dominio_operacional.code = eco_edif_agrop_ext_veg_pesca_a.operacional + left join dominios.situacaofisica as dominio_situacaofisica on dominio_situacaofisica.code = eco_edif_agrop_ext_veg_pesca_a.situacaofisica + left join dominios.matconstr as dominio_matconstr on dominio_matconstr.code = eco_edif_agrop_ext_veg_pesca_a.matconstr left join dominios.tipoedifagropec as dominio_tipoedifagropec on dominio_tipoedifagropec.code = eco_edif_agrop_ext_veg_pesca_a.tipoedifagropec # DROP VIEW IF EXISTS views.tra_fundeadouro_a# -CREATE [VIEW] views.tra_fundeadouro_a as +CREATE [VIEW] views.tra_fundeadouro_a as SELECT id as id, nome as nome, @@ -5836,13 +5836,13 @@ CREATE [VIEW] views.tra_fundeadouro_a as id_complexo_portuario as id_complexo_portuario, geom as geom [FROM] - cb.tra_fundeadouro_a - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = tra_fundeadouro_a.geometriaaproximada - left join dominios.destinacaofundeadouro as dominio_destinacaofundeadouro on dominio_destinacaofundeadouro.code = tra_fundeadouro_a.destinacaofundeadouro + cb.tra_fundeadouro_a + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = tra_fundeadouro_a.geometriaaproximada + left join dominios.destinacaofundeadouro as dominio_destinacaofundeadouro on dominio_destinacaofundeadouro.code = tra_fundeadouro_a.destinacaofundeadouro left join dominios.administracao as dominio_administracao on dominio_administracao.code = tra_fundeadouro_a.administracao # DROP VIEW IF EXISTS views.tra_trecho_rodoviario_l# -CREATE [VIEW] views.tra_trecho_rodoviario_l as +CREATE [VIEW] views.tra_trecho_rodoviario_l as SELECT id as id, dominio_geometriaaproximada.code_name as geometriaaproximada, @@ -5861,19 +5861,19 @@ CREATE [VIEW] views.tra_trecho_rodoviario_l as geom as geom, id_via_rodoviaria as id_via_rodoviaria [FROM] - cb.tra_trecho_rodoviario_l - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = tra_trecho_rodoviario_l.geometriaaproximada - left join dominios.tipotrechorod as dominio_tipotrechorod on dominio_tipotrechorod.code = tra_trecho_rodoviario_l.tipotrechorod - left join dominios.jurisdicao as dominio_jurisdicao on dominio_jurisdicao.code = tra_trecho_rodoviario_l.jurisdicao - left join dominios.administracao as dominio_administracao on dominio_administracao.code = tra_trecho_rodoviario_l.administracao - left join dominios.revestimento as dominio_revestimento on dominio_revestimento.code = tra_trecho_rodoviario_l.revestimento - left join dominios.operacional as dominio_operacional on dominio_operacional.code = tra_trecho_rodoviario_l.operacional - left join dominios.situacaofisica as dominio_situacaofisica on dominio_situacaofisica.code = tra_trecho_rodoviario_l.situacaofisica - left join dominios.trafego as dominio_trafego on dominio_trafego.code = tra_trecho_rodoviario_l.trafego + cb.tra_trecho_rodoviario_l + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = tra_trecho_rodoviario_l.geometriaaproximada + left join dominios.tipotrechorod as dominio_tipotrechorod on dominio_tipotrechorod.code = tra_trecho_rodoviario_l.tipotrechorod + left join dominios.jurisdicao as dominio_jurisdicao on dominio_jurisdicao.code = tra_trecho_rodoviario_l.jurisdicao + left join dominios.administracao as dominio_administracao on dominio_administracao.code = tra_trecho_rodoviario_l.administracao + left join dominios.revestimento as dominio_revestimento on dominio_revestimento.code = tra_trecho_rodoviario_l.revestimento + left join dominios.operacional as dominio_operacional on dominio_operacional.code = tra_trecho_rodoviario_l.operacional + left join dominios.situacaofisica as dominio_situacaofisica on dominio_situacaofisica.code = tra_trecho_rodoviario_l.situacaofisica + left join dominios.trafego as dominio_trafego on dominio_trafego.code = tra_trecho_rodoviario_l.trafego left join dominios.canteirodivisorio as dominio_canteirodivisorio on dominio_canteirodivisorio.code = tra_trecho_rodoviario_l.canteirodivisorio # DROP VIEW IF EXISTS views.lim_area_particular_a# -CREATE [VIEW] views.lim_area_particular_a as +CREATE [VIEW] views.lim_area_particular_a as SELECT id as id, nome as nome, @@ -5881,11 +5881,11 @@ CREATE [VIEW] views.lim_area_particular_a as dominio_geometriaaproximada.code_name as geometriaaproximada, geom as geom [FROM] - cb.lim_area_particular_a + cb.lim_area_particular_a left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = lim_area_particular_a.geometriaaproximada # DROP VIEW IF EXISTS views.enc_est_gerad_energia_eletr_l# -CREATE [VIEW] views.enc_est_gerad_energia_eletr_l as +CREATE [VIEW] views.enc_est_gerad_energia_eletr_l as SELECT id as id, nome as nome, @@ -5901,15 +5901,15 @@ CREATE [VIEW] views.enc_est_gerad_energia_eletr_l as id_complexo_gerad_energ_eletr as id_complexo_gerad_energ_eletr, geom as geom [FROM] - cb.enc_est_gerad_energia_eletr_l - left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = enc_est_gerad_energia_eletr_l.geometriaaproximada - left join dominios.tipoestgerad as dominio_tipoestgerad on dominio_tipoestgerad.code = enc_est_gerad_energia_eletr_l.tipoestgerad - left join dominios.operacional as dominio_operacional on dominio_operacional.code = enc_est_gerad_energia_eletr_l.operacional - left join dominios.situacaofisica as dominio_situacaofisica on dominio_situacaofisica.code = enc_est_gerad_energia_eletr_l.situacaofisica + cb.enc_est_gerad_energia_eletr_l + left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = enc_est_gerad_energia_eletr_l.geometriaaproximada + left join dominios.tipoestgerad as dominio_tipoestgerad on dominio_tipoestgerad.code = enc_est_gerad_energia_eletr_l.tipoestgerad + left join dominios.operacional as dominio_operacional on dominio_operacional.code = enc_est_gerad_energia_eletr_l.operacional + left join dominios.situacaofisica as dominio_situacaofisica on dominio_situacaofisica.code = enc_est_gerad_energia_eletr_l.situacaofisica left join dominios.destenergelet as dominio_destenergelet on dominio_destenergelet.code = enc_est_gerad_energia_eletr_l.destenergelet # DROP VIEW IF EXISTS views.lim_area_de_litigio_a# -CREATE [VIEW] views.lim_area_de_litigio_a as +CREATE [VIEW] views.lim_area_de_litigio_a as SELECT id as id, nome as nome, @@ -5918,11 +5918,11 @@ CREATE [VIEW] views.lim_area_de_litigio_a as descricao as descricao, geom as geom [FROM] - cb.lim_area_de_litigio_a + cb.lim_area_de_litigio_a left join dominios.geometriaaproximada as dominio_geometriaaproximada on dominio_geometriaaproximada.code = lim_area_de_litigio_a.geometriaaproximada # DROP VIEW IF EXISTS views.asb_complexo_saneamento# -CREATE [VIEW] views.asb_complexo_saneamento as +CREATE [VIEW] views.asb_complexo_saneamento as SELECT id as id, nome as nome, @@ -5931,12 +5931,12 @@ CREATE [VIEW] views.asb_complexo_saneamento as organizacao as organizacao, id_org_comerc_serv as id_org_comerc_serv [FROM] - complexos.asb_complexo_saneamento - left join dominios.tipoclassecnae as dominio_tipoclassecnae on dominio_tipoclassecnae.code = asb_complexo_saneamento.tipoclassecnae + complexos.asb_complexo_saneamento + left join dominios.tipoclassecnae as dominio_tipoclassecnae on dominio_tipoclassecnae.code = asb_complexo_saneamento.tipoclassecnae left join dominios.administracao as dominio_administracao on dominio_administracao.code = asb_complexo_saneamento.administracao # DROP VIEW IF EXISTS views.sau_org_saude# -CREATE [VIEW] views.sau_org_saude as +CREATE [VIEW] views.sau_org_saude as SELECT id as id, nome as nome, @@ -5944,12 +5944,12 @@ CREATE [VIEW] views.sau_org_saude as dominio_administracao.code_name as administracao, dominio_tipogrupocnae.code_name as tipogrupocnae [FROM] - complexos.sau_org_saude - left join dominios.administracao as dominio_administracao on dominio_administracao.code = sau_org_saude.administracao + complexos.sau_org_saude + left join dominios.administracao as dominio_administracao on dominio_administracao.code = sau_org_saude.administracao left join dominios.tipogrupocnae as dominio_tipogrupocnae on dominio_tipogrupocnae.code = sau_org_saude.tipogrupocnae # DROP VIEW IF EXISTS views.hid_trecho_curso_dagua# -CREATE [VIEW] views.hid_trecho_curso_dagua as +CREATE [VIEW] views.hid_trecho_curso_dagua as SELECT id as id, nome as nome, @@ -5959,7 +5959,7 @@ CREATE [VIEW] views.hid_trecho_curso_dagua as complexos.hid_trecho_curso_dagua # DROP VIEW IF EXISTS views.edu_org_ensino_religioso# -CREATE [VIEW] views.edu_org_ensino_religioso as +CREATE [VIEW] views.edu_org_ensino_religioso as SELECT id as id, nome as nome, @@ -5969,13 +5969,13 @@ CREATE [VIEW] views.edu_org_ensino_religioso as dominio_tipoclassecnae.code_name as tipoclassecnae, id_org_religiosa as id_org_religiosa [FROM] - complexos.edu_org_ensino_religioso - left join dominios.administracao as dominio_administracao on dominio_administracao.code = edu_org_ensino_religioso.administracao - left join dominios.tipogrupocnae as dominio_tipogrupocnae on dominio_tipogrupocnae.code = edu_org_ensino_religioso.tipogrupocnae + complexos.edu_org_ensino_religioso + left join dominios.administracao as dominio_administracao on dominio_administracao.code = edu_org_ensino_religioso.administracao + left join dominios.tipogrupocnae as dominio_tipogrupocnae on dominio_tipogrupocnae.code = edu_org_ensino_religioso.tipogrupocnae left join dominios.tipoclassecnae as dominio_tipoclassecnae on dominio_tipoclassecnae.code = edu_org_ensino_religioso.tipoclassecnae # DROP VIEW IF EXISTS views.eco_frigorifico_matadouro# -CREATE [VIEW] views.eco_frigorifico_matadouro as +CREATE [VIEW] views.eco_frigorifico_matadouro as SELECT id as id, nome as nome, @@ -5986,12 +5986,12 @@ CREATE [VIEW] views.eco_frigorifico_matadouro as dominio_frigorifico.code_name as frigorifico, id_org_agropec_ext_veg_pesca as id_org_agropec_ext_veg_pesca [FROM] - complexos.eco_frigorifico_matadouro - left join dominios.tiposecaocnae as dominio_tiposecaocnae on dominio_tiposecaocnae.code = eco_frigorifico_matadouro.tiposecaocnae + complexos.eco_frigorifico_matadouro + left join dominios.tiposecaocnae as dominio_tiposecaocnae on dominio_tiposecaocnae.code = eco_frigorifico_matadouro.tiposecaocnae left join dominios.frigorifico as dominio_frigorifico on dominio_frigorifico.code = eco_frigorifico_matadouro.frigorifico # DROP VIEW IF EXISTS views.tra_duto# -CREATE [VIEW] views.tra_duto as +CREATE [VIEW] views.tra_duto as SELECT id as id, nome as nome @@ -5999,7 +5999,7 @@ CREATE [VIEW] views.tra_duto as complexos.tra_duto # DROP VIEW IF EXISTS views.loc_complexo_habitacional# -CREATE [VIEW] views.loc_complexo_habitacional as +CREATE [VIEW] views.loc_complexo_habitacional as SELECT id as id, nome as nome, @@ -6008,7 +6008,7 @@ CREATE [VIEW] views.loc_complexo_habitacional as complexos.loc_complexo_habitacional # DROP VIEW IF EXISTS views.tra_complexo_portuario# -CREATE [VIEW] views.tra_complexo_portuario as +CREATE [VIEW] views.tra_complexo_portuario as SELECT id as id, nome as nome, @@ -6016,12 +6016,12 @@ CREATE [VIEW] views.tra_complexo_portuario as dominio_tipotransporte.code_name as tipotransporte, dominio_tipocomplexoportuario.code_name as tipocomplexoportuario [FROM] - complexos.tra_complexo_portuario - left join dominios.tipotransporte as dominio_tipotransporte on dominio_tipotransporte.code = tra_complexo_portuario.tipotransporte + complexos.tra_complexo_portuario + left join dominios.tipotransporte as dominio_tipotransporte on dominio_tipotransporte.code = tra_complexo_portuario.tipotransporte left join dominios.tipocomplexoportuario as dominio_tipocomplexoportuario on dominio_tipocomplexoportuario.code = tra_complexo_portuario.tipocomplexoportuario # DROP VIEW IF EXISTS views.enc_complexo_comunicacao# -CREATE [VIEW] views.enc_complexo_comunicacao as +CREATE [VIEW] views.enc_complexo_comunicacao as SELECT id as id, nome as nome, @@ -6029,11 +6029,11 @@ CREATE [VIEW] views.enc_complexo_comunicacao as id_org_comerc_serv as id_org_comerc_serv, id_complexo_comunicacao as id_complexo_comunicacao [FROM] - complexos.enc_complexo_comunicacao + complexos.enc_complexo_comunicacao left join dominios.tipoclassecnae as dominio_tipoclassecnae on dominio_tipoclassecnae.code = enc_complexo_comunicacao.tipoclassecnae # DROP VIEW IF EXISTS views.adm_org_pub_civil# -CREATE [VIEW] views.adm_org_pub_civil as +CREATE [VIEW] views.adm_org_pub_civil as SELECT id as id, nome as nome, @@ -6044,13 +6044,13 @@ CREATE [VIEW] views.adm_org_pub_civil as id_instituicao_publica as id_instituicao_publica, id_org_pub_civil as id_org_pub_civil [FROM] - complexos.adm_org_pub_civil - left join dominios.tipoclassecnae as dominio_tipoclassecnae on dominio_tipoclassecnae.code = adm_org_pub_civil.tipoclassecnae - left join dominios.administracao as dominio_administracao on dominio_administracao.code = adm_org_pub_civil.administracao + complexos.adm_org_pub_civil + left join dominios.tipoclassecnae as dominio_tipoclassecnae on dominio_tipoclassecnae.code = adm_org_pub_civil.tipoclassecnae + left join dominios.administracao as dominio_administracao on dominio_administracao.code = adm_org_pub_civil.administracao left join dominios.poderpublico as dominio_poderpublico on dominio_poderpublico.code = adm_org_pub_civil.poderpublico # DROP VIEW IF EXISTS views.sau_org_saude_militar# -CREATE [VIEW] views.sau_org_saude_militar as +CREATE [VIEW] views.sau_org_saude_militar as SELECT id as id, nome as nome, @@ -6062,15 +6062,15 @@ CREATE [VIEW] views.sau_org_saude_militar as dominio_classificsigiloso.code_name as classificsigiloso, id_org_pub_militar as id_org_pub_militar [FROM] - complexos.sau_org_saude_militar - left join dominios.administracao as dominio_administracao on dominio_administracao.code = sau_org_saude_militar.administracao - left join dominios.tipogrupocnae as dominio_tipogrupocnae on dominio_tipogrupocnae.code = sau_org_saude_militar.tipogrupocnae - left join dominios.tipoclassecnae as dominio_tipoclassecnae on dominio_tipoclassecnae.code = sau_org_saude_militar.tipoclassecnae - left join dominios.instituicao as dominio_instituicao on dominio_instituicao.code = sau_org_saude_militar.instituicao + complexos.sau_org_saude_militar + left join dominios.administracao as dominio_administracao on dominio_administracao.code = sau_org_saude_militar.administracao + left join dominios.tipogrupocnae as dominio_tipogrupocnae on dominio_tipogrupocnae.code = sau_org_saude_militar.tipogrupocnae + left join dominios.tipoclassecnae as dominio_tipoclassecnae on dominio_tipoclassecnae.code = sau_org_saude_militar.tipoclassecnae + left join dominios.instituicao as dominio_instituicao on dominio_instituicao.code = sau_org_saude_militar.instituicao left join dominios.classificsigiloso as dominio_classificsigiloso on dominio_classificsigiloso.code = sau_org_saude_militar.classificsigiloso # DROP VIEW IF EXISTS views.adm_org_pub_militar# -CREATE [VIEW] views.adm_org_pub_militar as +CREATE [VIEW] views.adm_org_pub_militar as SELECT id as id, nome as nome, @@ -6082,14 +6082,14 @@ CREATE [VIEW] views.adm_org_pub_militar as dominio_instituicao.code_name as instituicao, dominio_classificsigiloso.code_name as classificsigiloso [FROM] - complexos.adm_org_pub_militar - left join dominios.tipoclassecnae as dominio_tipoclassecnae on dominio_tipoclassecnae.code = adm_org_pub_militar.tipoclassecnae - left join dominios.administracao as dominio_administracao on dominio_administracao.code = adm_org_pub_militar.administracao - left join dominios.instituicao as dominio_instituicao on dominio_instituicao.code = adm_org_pub_militar.instituicao + complexos.adm_org_pub_militar + left join dominios.tipoclassecnae as dominio_tipoclassecnae on dominio_tipoclassecnae.code = adm_org_pub_militar.tipoclassecnae + left join dominios.administracao as dominio_administracao on dominio_administracao.code = adm_org_pub_militar.administracao + left join dominios.instituicao as dominio_instituicao on dominio_instituicao.code = adm_org_pub_militar.instituicao left join dominios.classificsigiloso as dominio_classificsigiloso on dominio_classificsigiloso.code = adm_org_pub_militar.classificsigiloso # DROP VIEW IF EXISTS views.edu_complexo_lazer# -CREATE [VIEW] views.edu_complexo_lazer as +CREATE [VIEW] views.edu_complexo_lazer as SELECT id as id, nome as nome, @@ -6102,13 +6102,13 @@ CREATE [VIEW] views.edu_complexo_lazer as id_org_pub_militar as id_org_pub_militar, id_org_ensino as id_org_ensino [FROM] - complexos.edu_complexo_lazer - left join dominios.tipocomplexolazer as dominio_tipocomplexolazer on dominio_tipocomplexolazer.code = edu_complexo_lazer.tipocomplexolazer - left join dominios.tipodivisaocnae as dominio_tipodivisaocnae on dominio_tipodivisaocnae.code = edu_complexo_lazer.tipodivisaocnae + complexos.edu_complexo_lazer + left join dominios.tipocomplexolazer as dominio_tipocomplexolazer on dominio_tipocomplexolazer.code = edu_complexo_lazer.tipocomplexolazer + left join dominios.tipodivisaocnae as dominio_tipodivisaocnae on dominio_tipodivisaocnae.code = edu_complexo_lazer.tipodivisaocnae left join dominios.administracao as dominio_administracao on dominio_administracao.code = edu_complexo_lazer.administracao # DROP VIEW IF EXISTS views.hid_curso_dagua# -CREATE [VIEW] views.hid_curso_dagua as +CREATE [VIEW] views.hid_curso_dagua as SELECT id as id, nome as nome, @@ -6117,7 +6117,7 @@ CREATE [VIEW] views.hid_curso_dagua as complexos.hid_curso_dagua # DROP VIEW IF EXISTS views.edu_org_ensino_militar# -CREATE [VIEW] views.edu_org_ensino_militar as +CREATE [VIEW] views.edu_org_ensino_militar as SELECT id as id, nome as nome, @@ -6129,15 +6129,15 @@ CREATE [VIEW] views.edu_org_ensino_militar as dominio_classificsigiloso.code_name as classificsigiloso, id_org_pub_militar as id_org_pub_militar [FROM] - complexos.edu_org_ensino_militar - left join dominios.administracao as dominio_administracao on dominio_administracao.code = edu_org_ensino_militar.administracao - left join dominios.tipogrupocnae as dominio_tipogrupocnae on dominio_tipogrupocnae.code = edu_org_ensino_militar.tipogrupocnae - left join dominios.tipoclassecnae as dominio_tipoclassecnae on dominio_tipoclassecnae.code = edu_org_ensino_militar.tipoclassecnae - left join dominios.instituicao as dominio_instituicao on dominio_instituicao.code = edu_org_ensino_militar.instituicao + complexos.edu_org_ensino_militar + left join dominios.administracao as dominio_administracao on dominio_administracao.code = edu_org_ensino_militar.administracao + left join dominios.tipogrupocnae as dominio_tipogrupocnae on dominio_tipogrupocnae.code = edu_org_ensino_militar.tipogrupocnae + left join dominios.tipoclassecnae as dominio_tipoclassecnae on dominio_tipoclassecnae.code = edu_org_ensino_militar.tipoclassecnae + left join dominios.instituicao as dominio_instituicao on dominio_instituicao.code = edu_org_ensino_militar.instituicao left join dominios.classificsigiloso as dominio_classificsigiloso on dominio_classificsigiloso.code = edu_org_ensino_militar.classificsigiloso # DROP VIEW IF EXISTS views.sau_org_servico_social_pub# -CREATE [VIEW] views.sau_org_servico_social_pub as +CREATE [VIEW] views.sau_org_servico_social_pub as SELECT id as id, nome as nome, @@ -6147,13 +6147,13 @@ CREATE [VIEW] views.sau_org_servico_social_pub as dominio_tipoclassecnae.code_name as tipoclassecnae, id_org_pub_civil as id_org_pub_civil [FROM] - complexos.sau_org_servico_social_pub - left join dominios.administracao as dominio_administracao on dominio_administracao.code = sau_org_servico_social_pub.administracao - left join dominios.tipogrupocnae as dominio_tipogrupocnae on dominio_tipogrupocnae.code = sau_org_servico_social_pub.tipogrupocnae + complexos.sau_org_servico_social_pub + left join dominios.administracao as dominio_administracao on dominio_administracao.code = sau_org_servico_social_pub.administracao + left join dominios.tipogrupocnae as dominio_tipogrupocnae on dominio_tipogrupocnae.code = sau_org_servico_social_pub.tipogrupocnae left join dominios.tipoclassecnae as dominio_tipoclassecnae on dominio_tipoclassecnae.code = sau_org_servico_social_pub.tipoclassecnae # DROP VIEW IF EXISTS views.tra_via_rodoviaria# -CREATE [VIEW] views.tra_via_rodoviaria as +CREATE [VIEW] views.tra_via_rodoviaria as SELECT id as id, nome as nome, @@ -6163,7 +6163,7 @@ CREATE [VIEW] views.tra_via_rodoviaria as complexos.tra_via_rodoviaria # DROP VIEW IF EXISTS views.pto_est_med_fenomenos# -CREATE [VIEW] views.pto_est_med_fenomenos as +CREATE [VIEW] views.pto_est_med_fenomenos as SELECT id as id, nome as nome, @@ -6173,11 +6173,11 @@ CREATE [VIEW] views.pto_est_med_fenomenos as orgaoenteresp as orgaoenteresp, id_est_med_fenomenos as id_est_med_fenomenos [FROM] - complexos.pto_est_med_fenomenos + complexos.pto_est_med_fenomenos left join dominios.tipoestmed as dominio_tipoestmed on dominio_tipoestmed.code = pto_est_med_fenomenos.tipoestmed # DROP VIEW IF EXISTS views.enc_complexo_gerad_energ_eletr# -CREATE [VIEW] views.enc_complexo_gerad_energ_eletr as +CREATE [VIEW] views.enc_complexo_gerad_energ_eletr as SELECT id as id, nome as nome, @@ -6185,11 +6185,11 @@ CREATE [VIEW] views.enc_complexo_gerad_energ_eletr as dominio_tipoclassecnae.code_name as tipoclassecnae, id_org_comerc_serv as id_org_comerc_serv [FROM] - complexos.enc_complexo_gerad_energ_eletr + complexos.enc_complexo_gerad_energ_eletr left join dominios.tipoclassecnae as dominio_tipoclassecnae on dominio_tipoclassecnae.code = enc_complexo_gerad_energ_eletr.tipoclassecnae # DROP VIEW IF EXISTS views.eco_madeireira# -CREATE [VIEW] views.eco_madeireira as +CREATE [VIEW] views.eco_madeireira as SELECT id as id, nome as nome, @@ -6199,11 +6199,11 @@ CREATE [VIEW] views.eco_madeireira as id_org_pub_militar as id_org_pub_militar, id_org_agropec_ext_veg_pesca as id_org_agropec_ext_veg_pesca [FROM] - complexos.eco_madeireira + complexos.eco_madeireira left join dominios.tiposecaocnae as dominio_tiposecaocnae on dominio_tiposecaocnae.code = eco_madeireira.tiposecaocnae # DROP VIEW IF EXISTS views.asb_complexo_abast_agua# -CREATE [VIEW] views.asb_complexo_abast_agua as +CREATE [VIEW] views.asb_complexo_abast_agua as SELECT id as id, nome as nome, @@ -6212,11 +6212,11 @@ CREATE [VIEW] views.asb_complexo_abast_agua as organizacao as organizacao, id_org_comerc_serv as id_org_comerc_serv [FROM] - complexos.asb_complexo_abast_agua + complexos.asb_complexo_abast_agua left join dominios.tipoclassecnae as dominio_tipoclassecnae on dominio_tipoclassecnae.code = asb_complexo_abast_agua.tipoclassecnae # DROP VIEW IF EXISTS views.adm_instituicao_publica# -CREATE [VIEW] views.adm_instituicao_publica as +CREATE [VIEW] views.adm_instituicao_publica as SELECT id as id, nome as nome, @@ -6224,11 +6224,11 @@ CREATE [VIEW] views.adm_instituicao_publica as dominio_tipogrupocnae.code_name as tipogrupocnae, id_instituicao_publica as id_instituicao_publica [FROM] - complexos.adm_instituicao_publica + complexos.adm_instituicao_publica left join dominios.tipogrupocnae as dominio_tipogrupocnae on dominio_tipogrupocnae.code = adm_instituicao_publica.tipogrupocnae # DROP VIEW IF EXISTS views.sau_org_servico_social# -CREATE [VIEW] views.sau_org_servico_social as +CREATE [VIEW] views.sau_org_servico_social as SELECT id as id, nome as nome, @@ -6236,23 +6236,23 @@ CREATE [VIEW] views.sau_org_servico_social as dominio_administracao.code_name as administracao, dominio_tipogrupocnae.code_name as tipogrupocnae [FROM] - complexos.sau_org_servico_social - left join dominios.administracao as dominio_administracao on dominio_administracao.code = sau_org_servico_social.administracao + complexos.sau_org_servico_social + left join dominios.administracao as dominio_administracao on dominio_administracao.code = sau_org_servico_social.administracao left join dominios.tipogrupocnae as dominio_tipogrupocnae on dominio_tipogrupocnae.code = sau_org_servico_social.tipogrupocnae # DROP VIEW IF EXISTS views.edu_org_religiosa# -CREATE [VIEW] views.edu_org_religiosa as +CREATE [VIEW] views.edu_org_religiosa as SELECT id as id, nome as nome, nomeabrev as nomeabrev, dominio_tipoclassecnae.code_name as tipoclassecnae [FROM] - complexos.edu_org_religiosa + complexos.edu_org_religiosa left join dominios.tipoclassecnae as dominio_tipoclassecnae on dominio_tipoclassecnae.code = edu_org_religiosa.tipoclassecnae # DROP VIEW IF EXISTS views.tra_via_ferrea# -CREATE [VIEW] views.tra_via_ferrea as +CREATE [VIEW] views.tra_via_ferrea as SELECT id as id, nome as nome, @@ -6261,7 +6261,7 @@ CREATE [VIEW] views.tra_via_ferrea as complexos.tra_via_ferrea # DROP VIEW IF EXISTS views.loc_aldeia_indigena# -CREATE [VIEW] views.loc_aldeia_indigena as +CREATE [VIEW] views.loc_aldeia_indigena as SELECT id as id, nome as nome, @@ -6273,7 +6273,7 @@ CREATE [VIEW] views.loc_aldeia_indigena as complexos.loc_aldeia_indigena # DROP VIEW IF EXISTS views.eco_org_comerc_serv# -CREATE [VIEW] views.eco_org_comerc_serv as +CREATE [VIEW] views.eco_org_comerc_serv as SELECT id as id, nome as nome, @@ -6281,33 +6281,33 @@ CREATE [VIEW] views.eco_org_comerc_serv as dominio_tipodivisaocnae.code_name as tipodivisaocnae, dominio_finalidade.code_name as finalidade [FROM] - complexos.eco_org_comerc_serv - left join dominios.tipodivisaocnae as dominio_tipodivisaocnae on dominio_tipodivisaocnae.code = eco_org_comerc_serv.tipodivisaocnae + complexos.eco_org_comerc_serv + left join dominios.tipodivisaocnae as dominio_tipodivisaocnae on dominio_tipodivisaocnae.code = eco_org_comerc_serv.tipodivisaocnae left join dominios.finalidade_eco as dominio_finalidade on dominio_finalidade.code = eco_org_comerc_serv.finalidade # DROP VIEW IF EXISTS views.tra_estrut_apoio# -CREATE [VIEW] views.tra_estrut_apoio as +CREATE [VIEW] views.tra_estrut_apoio as SELECT id as id, nome as nome, nomeabrev as nomeabrev, dominio_tipoestrut.code_name as tipoestrut [FROM] - complexos.tra_estrut_apoio + complexos.tra_estrut_apoio left join dominios.tipoestrut as dominio_tipoestrut on dominio_tipoestrut.code = tra_estrut_apoio.tipoestrut # DROP VIEW IF EXISTS views.eco_org_agrop_ext_veg_pesca# -CREATE [VIEW] views.eco_org_agrop_ext_veg_pesca as +CREATE [VIEW] views.eco_org_agrop_ext_veg_pesca as SELECT id as id, nome as nome, dominio_tipodivisaocnae.code_name as tipodivisaocnae [FROM] - complexos.eco_org_agrop_ext_veg_pesca + complexos.eco_org_agrop_ext_veg_pesca left join dominios.tipodivisaocnae as dominio_tipodivisaocnae on dominio_tipodivisaocnae.code = eco_org_agrop_ext_veg_pesca.tipodivisaocnae # DROP VIEW IF EXISTS views.edu_org_ensino_pub# -CREATE [VIEW] views.edu_org_ensino_pub as +CREATE [VIEW] views.edu_org_ensino_pub as SELECT id as id, nome as nome, @@ -6318,14 +6318,14 @@ CREATE [VIEW] views.edu_org_ensino_pub as dominio_poderpublico.code_name as poderpublico, id_org_pub_civil as id_org_pub_civil [FROM] - complexos.edu_org_ensino_pub - left join dominios.administracao as dominio_administracao on dominio_administracao.code = edu_org_ensino_pub.administracao - left join dominios.tipogrupocnae as dominio_tipogrupocnae on dominio_tipogrupocnae.code = edu_org_ensino_pub.tipogrupocnae - left join dominios.tipoclassecnae as dominio_tipoclassecnae on dominio_tipoclassecnae.code = edu_org_ensino_pub.tipoclassecnae + complexos.edu_org_ensino_pub + left join dominios.administracao as dominio_administracao on dominio_administracao.code = edu_org_ensino_pub.administracao + left join dominios.tipogrupocnae as dominio_tipogrupocnae on dominio_tipogrupocnae.code = edu_org_ensino_pub.tipogrupocnae + left join dominios.tipoclassecnae as dominio_tipoclassecnae on dominio_tipoclassecnae.code = edu_org_ensino_pub.tipoclassecnae left join dominios.poderpublico as dominio_poderpublico on dominio_poderpublico.code = edu_org_ensino_pub.poderpublico # DROP VIEW IF EXISTS views.sau_org_saude_pub# -CREATE [VIEW] views.sau_org_saude_pub as +CREATE [VIEW] views.sau_org_saude_pub as SELECT id as id, nome as nome, @@ -6335,24 +6335,24 @@ CREATE [VIEW] views.sau_org_saude_pub as dominio_tipoclassecnae.code_name as tipoclassecnae, id_org_pub_civil as id_org_pub_civil [FROM] - complexos.sau_org_saude_pub - left join dominios.administracao as dominio_administracao on dominio_administracao.code = sau_org_saude_pub.administracao - left join dominios.tipogrupocnae as dominio_tipogrupocnae on dominio_tipogrupocnae.code = sau_org_saude_pub.tipogrupocnae + complexos.sau_org_saude_pub + left join dominios.administracao as dominio_administracao on dominio_administracao.code = sau_org_saude_pub.administracao + left join dominios.tipogrupocnae as dominio_tipogrupocnae on dominio_tipogrupocnae.code = sau_org_saude_pub.tipogrupocnae left join dominios.tipoclassecnae as dominio_tipoclassecnae on dominio_tipoclassecnae.code = sau_org_saude_pub.tipoclassecnae # DROP VIEW IF EXISTS views.eco_org_ext_mineral# -CREATE [VIEW] views.eco_org_ext_mineral as +CREATE [VIEW] views.eco_org_ext_mineral as SELECT id as id, nome as nome, nomeabrev as nomeabrev, dominio_tiposecaocnae.code_name as tiposecaocnae [FROM] - complexos.eco_org_ext_mineral + complexos.eco_org_ext_mineral left join dominios.tiposecaocnae as dominio_tiposecaocnae on dominio_tiposecaocnae.code = eco_org_ext_mineral.tiposecaocnae # DROP VIEW IF EXISTS views.tra_complexo_aeroportuario# -CREATE [VIEW] views.tra_complexo_aeroportuario as +CREATE [VIEW] views.tra_complexo_aeroportuario as SELECT id as id, nome as nome, @@ -6365,12 +6365,12 @@ CREATE [VIEW] views.tra_complexo_aeroportuario as longoficial as longoficial, altitude as altitude [FROM] - complexos.tra_complexo_aeroportuario - left join dominios.tipocomplexoaero as dominio_tipocomplexoaero on dominio_tipocomplexoaero.code = tra_complexo_aeroportuario.tipocomplexoaero + complexos.tra_complexo_aeroportuario + left join dominios.tipocomplexoaero as dominio_tipocomplexoaero on dominio_tipocomplexoaero.code = tra_complexo_aeroportuario.tipocomplexoaero left join dominios.classificacao as dominio_classificacao on dominio_classificacao.code = tra_complexo_aeroportuario.classificacao # DROP VIEW IF EXISTS views.enc_subestacao_ener_eletr# -CREATE [VIEW] views.enc_subestacao_ener_eletr as +CREATE [VIEW] views.enc_subestacao_ener_eletr as SELECT id as id, nome as nome, @@ -6379,13 +6379,13 @@ CREATE [VIEW] views.enc_subestacao_ener_eletr as dominio_operacional.code_name as operacional, id_complexo_gerad_energ_eletr as id_complexo_gerad_energ_eletr [FROM] - complexos.enc_subestacao_ener_eletr - left join dominios.tipoclassecnae as dominio_tipoclassecnae on dominio_tipoclassecnae.code = enc_subestacao_ener_eletr.tipoclassecnae - left join dominios.tipooperativo as dominio_tipooperativo on dominio_tipooperativo.code = enc_subestacao_ener_eletr.tipooperativo + complexos.enc_subestacao_ener_eletr + left join dominios.tipoclassecnae as dominio_tipoclassecnae on dominio_tipoclassecnae.code = enc_subestacao_ener_eletr.tipoclassecnae + left join dominios.tipooperativo as dominio_tipooperativo on dominio_tipooperativo.code = enc_subestacao_ener_eletr.tipooperativo left join dominios.operacional as dominio_operacional on dominio_operacional.code = enc_subestacao_ener_eletr.operacional # DROP VIEW IF EXISTS views.edu_org_ensino# -CREATE [VIEW] views.edu_org_ensino as +CREATE [VIEW] views.edu_org_ensino as SELECT id as id, nome as nome, @@ -6393,12 +6393,12 @@ CREATE [VIEW] views.edu_org_ensino as dominio_administracao.code_name as administracao, dominio_tipogrupocnae.code_name as tipogrupocnae [FROM] - complexos.edu_org_ensino - left join dominios.administracao as dominio_administracao on dominio_administracao.code = edu_org_ensino.administracao + complexos.edu_org_ensino + left join dominios.administracao as dominio_administracao on dominio_administracao.code = edu_org_ensino.administracao left join dominios.tipogrupocnae as dominio_tipogrupocnae on dominio_tipogrupocnae.code = edu_org_ensino.tipogrupocnae # DROP VIEW IF EXISTS views.tra_estrut_transporte# -CREATE [VIEW] views.tra_estrut_transporte as +CREATE [VIEW] views.tra_estrut_transporte as SELECT id as id, nome as nome, @@ -6407,7 +6407,7 @@ CREATE [VIEW] views.tra_estrut_transporte as complexos.tra_estrut_transporte # DROP VIEW IF EXISTS views.tra_hidrovia# -CREATE [VIEW] views.tra_hidrovia as +CREATE [VIEW] views.tra_hidrovia as SELECT id as id, nome as nome, @@ -6415,11 +6415,11 @@ CREATE [VIEW] views.tra_hidrovia as dominio_administracao.code_name as administracao, extensaototal as extensaototal [FROM] - complexos.tra_hidrovia + complexos.tra_hidrovia left join dominios.administracao as dominio_administracao on dominio_administracao.code = tra_hidrovia.administracao # DROP VIEW IF EXISTS views.eco_org_industrial# -CREATE [VIEW] views.eco_org_industrial as +CREATE [VIEW] views.eco_org_industrial as SELECT id as id, nome as nome, @@ -6428,5 +6428,5 @@ CREATE [VIEW] views.eco_org_industrial as id_org_pub_civil as id_org_pub_civil, id_org_pub_militar as id_org_pub_militar [FROM] - complexos.eco_org_industrial - left join dominios.tiposecaocnae as dominio_tiposecaocnae on dominio_tiposecaocnae.code = eco_org_industrial.tiposecaocnae \ No newline at end of file + complexos.eco_org_industrial + left join dominios.tiposecaocnae as dominio_tiposecaocnae on dominio_tiposecaocnae.code = eco_org_industrial.tiposecaocnae diff --git a/DsgTools/core/DbModels/PostGIS/213_Pro/edgv213_pro.sql b/DsgTools/core/DbModels/PostGIS/213_Pro/edgv213_pro.sql index c8abb0173..e22ca1325 100644 --- a/DsgTools/core/DbModels/PostGIS/213_Pro/edgv213_pro.sql +++ b/DsgTools/core/DbModels/PostGIS/213_Pro/edgv213_pro.sql @@ -1162,8 +1162,8 @@ ALTER TABLE edgv.cobter_vegetacao_a ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE edgv.cobter_vegetacao_a - ADD CONSTRAINT cobter_vegetacao_a_tipo_check - CHECK (tipo = ANY(ARRAY[301 :: SMALLINT, 302 :: SMALLINT, 201 :: SMALLINT, 202 :: SMALLINT, 801 :: SMALLINT, 501 :: SMALLINT, 701 :: SMALLINT, 702 :: SMALLINT, 401 :: SMALLINT, 1101 :: SMALLINT, 901 :: SMALLINT, 601 :: SMALLINT, 194 :: SMALLINT, 196 :: SMALLINT, 150 :: SMALLINT, 118 :: SMALLINT, 102 :: SMALLINT, 115 :: SMALLINT, 114 :: SMALLINT, 116 :: SMALLINT, 103 :: SMALLINT, 151 :: SMALLINT, 117 :: SMALLINT, 153 :: SMALLINT, 152 :: SMALLINT, 119 :: SMALLINT, 142 :: SMALLINT, 107 :: SMALLINT, 124 :: SMALLINT, 198 :: SMALLINT, 195 :: SMALLINT, 1296 :: SMALLINT, 1000 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT cobter_vegetacao_a_tipo_check + CHECK (tipo = ANY(ARRAY[301 :: SMALLINT, 302 :: SMALLINT, 201 :: SMALLINT, 202 :: SMALLINT, 801 :: SMALLINT, 501 :: SMALLINT, 701 :: SMALLINT, 702 :: SMALLINT, 401 :: SMALLINT, 1101 :: SMALLINT, 901 :: SMALLINT, 601 :: SMALLINT, 194 :: SMALLINT, 196 :: SMALLINT, 150 :: SMALLINT, 118 :: SMALLINT, 102 :: SMALLINT, 115 :: SMALLINT, 114 :: SMALLINT, 116 :: SMALLINT, 103 :: SMALLINT, 151 :: SMALLINT, 117 :: SMALLINT, 153 :: SMALLINT, 152 :: SMALLINT, 119 :: SMALLINT, 142 :: SMALLINT, 107 :: SMALLINT, 124 :: SMALLINT, 198 :: SMALLINT, 195 :: SMALLINT, 1296 :: SMALLINT, 1000 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE edgv.cobter_vegetacao_a ALTER COLUMN tipo SET DEFAULT 999# ALTER TABLE edgv.cobter_vegetacao_a @@ -1228,8 +1228,8 @@ ALTER TABLE edgv.constr_deposito_a ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE edgv.constr_deposito_a - ADD CONSTRAINT constr_deposito_a_material_construcao_check - CHECK (material_construcao = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 97 :: SMALLINT, 98 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT constr_deposito_a_material_construcao_check + CHECK (material_construcao = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 97 :: SMALLINT, 98 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE edgv.constr_deposito_a ALTER COLUMN material_construcao SET DEFAULT 999# ALTER TABLE edgv.constr_deposito_a @@ -1238,8 +1238,8 @@ ALTER TABLE edgv.constr_deposito_a ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE edgv.constr_deposito_a - ADD CONSTRAINT constr_deposito_a_finalidade_check - CHECK (finalidade = ANY(ARRAY[2 :: SMALLINT, 3 :: SMALLINT, 4 :: SMALLINT, 8 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT constr_deposito_a_finalidade_check + CHECK (finalidade = ANY(ARRAY[2 :: SMALLINT, 3 :: SMALLINT, 4 :: SMALLINT, 8 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE edgv.constr_deposito_a ALTER COLUMN finalidade SET DEFAULT 999# ALTER TABLE edgv.constr_deposito_a @@ -1248,8 +1248,8 @@ ALTER TABLE edgv.constr_deposito_a ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE edgv.constr_deposito_a - ADD CONSTRAINT constr_deposito_a_tipo_produto_residuo_check - CHECK (tipo_produto_residuo = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 5 :: SMALLINT, 6 :: SMALLINT, 9 :: SMALLINT, 12 :: SMALLINT, 13 :: SMALLINT, 14 :: SMALLINT, 15 :: SMALLINT, 16 :: SMALLINT, 17 :: SMALLINT, 18 :: SMALLINT, 19 :: SMALLINT, 20 :: SMALLINT, 21 :: SMALLINT, 22 :: SMALLINT, 23 :: SMALLINT, 24 :: SMALLINT, 25 :: SMALLINT, 26 :: SMALLINT, 27 :: SMALLINT, 28 :: SMALLINT, 29 :: SMALLINT, 30 :: SMALLINT, 31 :: SMALLINT, 32 :: SMALLINT, 33 :: SMALLINT, 34 :: SMALLINT, 35 :: SMALLINT, 36 :: SMALLINT, 41 :: SMALLINT, 95 :: SMALLINT, 98 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT constr_deposito_a_tipo_produto_residuo_check + CHECK (tipo_produto_residuo = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 5 :: SMALLINT, 6 :: SMALLINT, 9 :: SMALLINT, 12 :: SMALLINT, 13 :: SMALLINT, 14 :: SMALLINT, 15 :: SMALLINT, 16 :: SMALLINT, 17 :: SMALLINT, 18 :: SMALLINT, 19 :: SMALLINT, 20 :: SMALLINT, 21 :: SMALLINT, 22 :: SMALLINT, 23 :: SMALLINT, 24 :: SMALLINT, 25 :: SMALLINT, 26 :: SMALLINT, 27 :: SMALLINT, 28 :: SMALLINT, 29 :: SMALLINT, 30 :: SMALLINT, 31 :: SMALLINT, 32 :: SMALLINT, 33 :: SMALLINT, 34 :: SMALLINT, 35 :: SMALLINT, 36 :: SMALLINT, 41 :: SMALLINT, 95 :: SMALLINT, 98 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE edgv.constr_deposito_a ALTER COLUMN tipo_produto_residuo SET DEFAULT 999# ALTER TABLE edgv.constr_deposito_a @@ -1314,8 +1314,8 @@ ALTER TABLE edgv.constr_deposito_p ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE edgv.constr_deposito_p - ADD CONSTRAINT constr_deposito_p_material_construcao_check - CHECK (material_construcao = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 97 :: SMALLINT, 98 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT constr_deposito_p_material_construcao_check + CHECK (material_construcao = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 97 :: SMALLINT, 98 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE edgv.constr_deposito_p ALTER COLUMN material_construcao SET DEFAULT 999# ALTER TABLE edgv.constr_deposito_p @@ -1324,8 +1324,8 @@ ALTER TABLE edgv.constr_deposito_p ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE edgv.constr_deposito_p - ADD CONSTRAINT constr_deposito_p_finalidade_check - CHECK (finalidade = ANY(ARRAY[2 :: SMALLINT, 3 :: SMALLINT, 4 :: SMALLINT, 8 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT constr_deposito_p_finalidade_check + CHECK (finalidade = ANY(ARRAY[2 :: SMALLINT, 3 :: SMALLINT, 4 :: SMALLINT, 8 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE edgv.constr_deposito_p ALTER COLUMN finalidade SET DEFAULT 999# ALTER TABLE edgv.constr_deposito_p @@ -1334,8 +1334,8 @@ ALTER TABLE edgv.constr_deposito_p ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE edgv.constr_deposito_p - ADD CONSTRAINT constr_deposito_p_tipo_produto_residuo_check - CHECK (tipo_produto_residuo = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 5 :: SMALLINT, 6 :: SMALLINT, 9 :: SMALLINT, 12 :: SMALLINT, 13 :: SMALLINT, 14 :: SMALLINT, 15 :: SMALLINT, 16 :: SMALLINT, 17 :: SMALLINT, 18 :: SMALLINT, 19 :: SMALLINT, 20 :: SMALLINT, 21 :: SMALLINT, 22 :: SMALLINT, 23 :: SMALLINT, 24 :: SMALLINT, 25 :: SMALLINT, 26 :: SMALLINT, 27 :: SMALLINT, 28 :: SMALLINT, 29 :: SMALLINT, 30 :: SMALLINT, 31 :: SMALLINT, 32 :: SMALLINT, 33 :: SMALLINT, 34 :: SMALLINT, 35 :: SMALLINT, 36 :: SMALLINT, 41 :: SMALLINT, 95 :: SMALLINT, 98 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT constr_deposito_p_tipo_produto_residuo_check + CHECK (tipo_produto_residuo = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 5 :: SMALLINT, 6 :: SMALLINT, 9 :: SMALLINT, 12 :: SMALLINT, 13 :: SMALLINT, 14 :: SMALLINT, 15 :: SMALLINT, 16 :: SMALLINT, 17 :: SMALLINT, 18 :: SMALLINT, 19 :: SMALLINT, 20 :: SMALLINT, 21 :: SMALLINT, 22 :: SMALLINT, 23 :: SMALLINT, 24 :: SMALLINT, 25 :: SMALLINT, 26 :: SMALLINT, 27 :: SMALLINT, 28 :: SMALLINT, 29 :: SMALLINT, 30 :: SMALLINT, 31 :: SMALLINT, 32 :: SMALLINT, 33 :: SMALLINT, 34 :: SMALLINT, 35 :: SMALLINT, 36 :: SMALLINT, 41 :: SMALLINT, 95 :: SMALLINT, 98 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE edgv.constr_deposito_p ALTER COLUMN tipo_produto_residuo SET DEFAULT 999# ALTER TABLE edgv.constr_deposito_p @@ -1375,8 +1375,8 @@ ALTER TABLE edgv.constr_edificacao_a ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE edgv.constr_edificacao_a - ADD CONSTRAINT constr_edificacao_a_tipo_check - CHECK (tipo = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 101 :: SMALLINT, 102 :: SMALLINT, 103 :: SMALLINT, 104 :: SMALLINT, 201 :: SMALLINT, 301 :: SMALLINT, 302 :: SMALLINT, 303 :: SMALLINT, 395 :: SMALLINT, 398 :: SMALLINT, 403 :: SMALLINT, 405 :: SMALLINT, 406 :: SMALLINT, 407 :: SMALLINT, 498 :: SMALLINT, 516 :: SMALLINT, 517 :: SMALLINT, 518 :: SMALLINT, 519 :: SMALLINT, 520 :: SMALLINT, 521 :: SMALLINT, 522 :: SMALLINT, 523 :: SMALLINT, 524 :: SMALLINT, 525 :: SMALLINT, 595 :: SMALLINT, 601 :: SMALLINT, 602 :: SMALLINT, 603 :: SMALLINT, 604 :: SMALLINT, 605 :: SMALLINT, 606 :: SMALLINT, 607 :: SMALLINT, 698 :: SMALLINT, 709 :: SMALLINT, 710 :: SMALLINT, 711 :: SMALLINT, 712 :: SMALLINT, 713 :: SMALLINT, 798 :: SMALLINT, 801 :: SMALLINT, 802 :: SMALLINT, 803 :: SMALLINT, 804 :: SMALLINT, 805 :: SMALLINT, 806 :: SMALLINT, 807 :: SMALLINT, 808 :: SMALLINT, 898 :: SMALLINT, 903 :: SMALLINT, 904 :: SMALLINT, 905 :: SMALLINT, 906 :: SMALLINT, 907 :: SMALLINT, 998 :: SMALLINT, 1015 :: SMALLINT, 1016 :: SMALLINT, 1017 :: SMALLINT, 1018 :: SMALLINT, 1019 :: SMALLINT, 1020 :: SMALLINT, 1021 :: SMALLINT, 1022 :: SMALLINT, 1023 :: SMALLINT, 1024 :: SMALLINT, 1025 :: SMALLINT, 1026 :: SMALLINT, 1027 :: SMALLINT, 1028 :: SMALLINT, 1029 :: SMALLINT, 1030 :: SMALLINT, 1031 :: SMALLINT, 1032 :: SMALLINT, 1033 :: SMALLINT, 1034 :: SMALLINT, 1035 :: SMALLINT, 1036 :: SMALLINT, 1037 :: SMALLINT, 1045 :: SMALLINT, 1098 :: SMALLINT, 1110 :: SMALLINT, 1111 :: SMALLINT, 1113 :: SMALLINT, 1114 :: SMALLINT, 1198 :: SMALLINT, 1212 :: SMALLINT, 1213 :: SMALLINT, 1214 :: SMALLINT, 1215 :: SMALLINT, 1216 :: SMALLINT, 1217 :: SMALLINT, 1218 :: SMALLINT, 1298 :: SMALLINT, 1301 :: SMALLINT, 1302 :: SMALLINT, 1303 :: SMALLINT, 1304 :: SMALLINT, 1305 :: SMALLINT, 1306 :: SMALLINT, 1307 :: SMALLINT, 1308 :: SMALLINT, 1309 :: SMALLINT, 1322 :: SMALLINT, 1398 :: SMALLINT, 1401 :: SMALLINT, 1501 :: SMALLINT, 1712 :: SMALLINT, 1717 :: SMALLINT, 1718 :: SMALLINT, 1719 :: SMALLINT, 1798 :: SMALLINT, 1820 :: SMALLINT, 1821 :: SMALLINT, 1910 :: SMALLINT, 1911 :: SMALLINT, 1995 :: SMALLINT, 2025 :: SMALLINT, 2026 :: SMALLINT, 2027 :: SMALLINT, 2028 :: SMALLINT, 2029 :: SMALLINT, 2030 :: SMALLINT, 2031 :: SMALLINT, 2132 :: SMALLINT, 2133 :: SMALLINT, 2195 :: SMALLINT, 2208 :: SMALLINT, 2209 :: SMALLINT, 2210 :: SMALLINT, 2212 :: SMALLINT, 2213 :: SMALLINT, 2214 :: SMALLINT, 2298 :: SMALLINT, 2316 :: SMALLINT, 2317 :: SMALLINT, 2318 :: SMALLINT, 2319 :: SMALLINT, 2320 :: SMALLINT, 2398 :: SMALLINT, 2426 :: SMALLINT, 2427 :: SMALLINT, 2428 :: SMALLINT, 2429 :: SMALLINT, 2498 :: SMALLINT, 2526 :: SMALLINT, 2527 :: SMALLINT, 2533 :: SMALLINT, 2534 :: SMALLINT, 2535 :: SMALLINT, 2536 :: SMALLINT, 2598 :: SMALLINT, 2601 :: SMALLINT, 2701 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT constr_edificacao_a_tipo_check + CHECK (tipo = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 101 :: SMALLINT, 102 :: SMALLINT, 103 :: SMALLINT, 104 :: SMALLINT, 201 :: SMALLINT, 301 :: SMALLINT, 302 :: SMALLINT, 303 :: SMALLINT, 395 :: SMALLINT, 398 :: SMALLINT, 403 :: SMALLINT, 405 :: SMALLINT, 406 :: SMALLINT, 407 :: SMALLINT, 498 :: SMALLINT, 516 :: SMALLINT, 517 :: SMALLINT, 518 :: SMALLINT, 519 :: SMALLINT, 520 :: SMALLINT, 521 :: SMALLINT, 522 :: SMALLINT, 523 :: SMALLINT, 524 :: SMALLINT, 525 :: SMALLINT, 595 :: SMALLINT, 601 :: SMALLINT, 602 :: SMALLINT, 603 :: SMALLINT, 604 :: SMALLINT, 605 :: SMALLINT, 606 :: SMALLINT, 607 :: SMALLINT, 698 :: SMALLINT, 709 :: SMALLINT, 710 :: SMALLINT, 711 :: SMALLINT, 712 :: SMALLINT, 713 :: SMALLINT, 798 :: SMALLINT, 801 :: SMALLINT, 802 :: SMALLINT, 803 :: SMALLINT, 804 :: SMALLINT, 805 :: SMALLINT, 806 :: SMALLINT, 807 :: SMALLINT, 808 :: SMALLINT, 898 :: SMALLINT, 903 :: SMALLINT, 904 :: SMALLINT, 905 :: SMALLINT, 906 :: SMALLINT, 907 :: SMALLINT, 998 :: SMALLINT, 1015 :: SMALLINT, 1016 :: SMALLINT, 1017 :: SMALLINT, 1018 :: SMALLINT, 1019 :: SMALLINT, 1020 :: SMALLINT, 1021 :: SMALLINT, 1022 :: SMALLINT, 1023 :: SMALLINT, 1024 :: SMALLINT, 1025 :: SMALLINT, 1026 :: SMALLINT, 1027 :: SMALLINT, 1028 :: SMALLINT, 1029 :: SMALLINT, 1030 :: SMALLINT, 1031 :: SMALLINT, 1032 :: SMALLINT, 1033 :: SMALLINT, 1034 :: SMALLINT, 1035 :: SMALLINT, 1036 :: SMALLINT, 1037 :: SMALLINT, 1045 :: SMALLINT, 1098 :: SMALLINT, 1110 :: SMALLINT, 1111 :: SMALLINT, 1113 :: SMALLINT, 1114 :: SMALLINT, 1198 :: SMALLINT, 1212 :: SMALLINT, 1213 :: SMALLINT, 1214 :: SMALLINT, 1215 :: SMALLINT, 1216 :: SMALLINT, 1217 :: SMALLINT, 1218 :: SMALLINT, 1298 :: SMALLINT, 1301 :: SMALLINT, 1302 :: SMALLINT, 1303 :: SMALLINT, 1304 :: SMALLINT, 1305 :: SMALLINT, 1306 :: SMALLINT, 1307 :: SMALLINT, 1308 :: SMALLINT, 1309 :: SMALLINT, 1322 :: SMALLINT, 1398 :: SMALLINT, 1401 :: SMALLINT, 1501 :: SMALLINT, 1712 :: SMALLINT, 1717 :: SMALLINT, 1718 :: SMALLINT, 1719 :: SMALLINT, 1798 :: SMALLINT, 1820 :: SMALLINT, 1821 :: SMALLINT, 1910 :: SMALLINT, 1911 :: SMALLINT, 1995 :: SMALLINT, 2025 :: SMALLINT, 2026 :: SMALLINT, 2027 :: SMALLINT, 2028 :: SMALLINT, 2029 :: SMALLINT, 2030 :: SMALLINT, 2031 :: SMALLINT, 2132 :: SMALLINT, 2133 :: SMALLINT, 2195 :: SMALLINT, 2208 :: SMALLINT, 2209 :: SMALLINT, 2210 :: SMALLINT, 2212 :: SMALLINT, 2213 :: SMALLINT, 2214 :: SMALLINT, 2298 :: SMALLINT, 2316 :: SMALLINT, 2317 :: SMALLINT, 2318 :: SMALLINT, 2319 :: SMALLINT, 2320 :: SMALLINT, 2398 :: SMALLINT, 2426 :: SMALLINT, 2427 :: SMALLINT, 2428 :: SMALLINT, 2429 :: SMALLINT, 2498 :: SMALLINT, 2526 :: SMALLINT, 2527 :: SMALLINT, 2533 :: SMALLINT, 2534 :: SMALLINT, 2535 :: SMALLINT, 2536 :: SMALLINT, 2598 :: SMALLINT, 2601 :: SMALLINT, 2701 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE edgv.constr_edificacao_a ALTER COLUMN tipo SET DEFAULT 999# ALTER TABLE edgv.constr_edificacao_a @@ -1385,8 +1385,8 @@ ALTER TABLE edgv.constr_edificacao_a ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE edgv.constr_edificacao_a - ADD CONSTRAINT constr_edificacao_a_material_construcao_check - CHECK (material_construcao = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 4 :: SMALLINT, 5 :: SMALLINT, 97 :: SMALLINT, 98 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT constr_edificacao_a_material_construcao_check + CHECK (material_construcao = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 4 :: SMALLINT, 5 :: SMALLINT, 97 :: SMALLINT, 98 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE edgv.constr_edificacao_a ALTER COLUMN material_construcao SET DEFAULT 999# ALTER TABLE edgv.constr_edificacao_a @@ -1433,8 +1433,8 @@ ALTER TABLE edgv.constr_edificacao_p ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE edgv.constr_edificacao_p - ADD CONSTRAINT constr_edificacao_p_material_construcao_check - CHECK (material_construcao = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 4 :: SMALLINT, 5 :: SMALLINT, 97 :: SMALLINT, 98 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT constr_edificacao_p_material_construcao_check + CHECK (material_construcao = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 4 :: SMALLINT, 5 :: SMALLINT, 97 :: SMALLINT, 98 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE edgv.constr_edificacao_p ALTER COLUMN material_construcao SET DEFAULT 999# ALTER TABLE edgv.constr_edificacao_p @@ -1476,8 +1476,8 @@ ALTER TABLE edgv.constr_extracao_mineral_a ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE edgv.constr_extracao_mineral_a - ADD CONSTRAINT constr_extracao_mineral_a_tipo_check - CHECK (tipo = ANY(ARRAY[1 :: SMALLINT, 4 :: SMALLINT, 5 :: SMALLINT, 6 :: SMALLINT, 7 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT constr_extracao_mineral_a_tipo_check + CHECK (tipo = ANY(ARRAY[1 :: SMALLINT, 4 :: SMALLINT, 5 :: SMALLINT, 6 :: SMALLINT, 7 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE edgv.constr_extracao_mineral_a ALTER COLUMN tipo SET DEFAULT 999# ALTER TABLE edgv.constr_extracao_mineral_a @@ -1493,8 +1493,8 @@ ALTER TABLE edgv.constr_extracao_mineral_a ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE edgv.constr_extracao_mineral_a - ADD CONSTRAINT constr_extracao_mineral_a_situacao_fisica_check - CHECK (situacao_fisica = ANY(ARRAY[1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 4 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT constr_extracao_mineral_a_situacao_fisica_check + CHECK (situacao_fisica = ANY(ARRAY[1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 4 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE edgv.constr_extracao_mineral_a ALTER COLUMN situacao_fisica SET DEFAULT 999# ALTER TABLE edgv.constr_extracao_mineral_a @@ -1503,8 +1503,8 @@ ALTER TABLE edgv.constr_extracao_mineral_a ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE edgv.constr_extracao_mineral_a - ADD CONSTRAINT constr_extracao_mineral_a_tipo_produto_residuo_check - CHECK (tipo_produto_residuo = ANY(ARRAY[0 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 18 :: SMALLINT, 22 :: SMALLINT, 23 :: SMALLINT, 24 :: SMALLINT, 25 :: SMALLINT, 26 :: SMALLINT, 27 :: SMALLINT, 32 :: SMALLINT, 33 :: SMALLINT, 34 :: SMALLINT, 35 :: SMALLINT, 37 :: SMALLINT, 38 :: SMALLINT, 39 :: SMALLINT, 40 :: SMALLINT, 42 :: SMALLINT, 43 :: SMALLINT, 98 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT constr_extracao_mineral_a_tipo_produto_residuo_check + CHECK (tipo_produto_residuo = ANY(ARRAY[0 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 18 :: SMALLINT, 22 :: SMALLINT, 23 :: SMALLINT, 24 :: SMALLINT, 25 :: SMALLINT, 26 :: SMALLINT, 27 :: SMALLINT, 32 :: SMALLINT, 33 :: SMALLINT, 34 :: SMALLINT, 35 :: SMALLINT, 37 :: SMALLINT, 38 :: SMALLINT, 39 :: SMALLINT, 40 :: SMALLINT, 42 :: SMALLINT, 43 :: SMALLINT, 98 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE edgv.constr_extracao_mineral_a ALTER COLUMN tipo_produto_residuo SET DEFAULT 999# ALTER TABLE edgv.constr_extracao_mineral_a @@ -1546,8 +1546,8 @@ ALTER TABLE edgv.constr_extracao_mineral_p ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE edgv.constr_extracao_mineral_p - ADD CONSTRAINT constr_extracao_mineral_p_tipo_check - CHECK (tipo = ANY(ARRAY[1 :: SMALLINT, 4 :: SMALLINT, 5 :: SMALLINT, 6 :: SMALLINT, 7 :: SMALLINT, 8 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT constr_extracao_mineral_p_tipo_check + CHECK (tipo = ANY(ARRAY[1 :: SMALLINT, 4 :: SMALLINT, 5 :: SMALLINT, 6 :: SMALLINT, 7 :: SMALLINT, 8 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE edgv.constr_extracao_mineral_p ALTER COLUMN tipo SET DEFAULT 999# ALTER TABLE edgv.constr_extracao_mineral_p @@ -1563,8 +1563,8 @@ ALTER TABLE edgv.constr_extracao_mineral_p ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE edgv.constr_extracao_mineral_p - ADD CONSTRAINT constr_extracao_mineral_p_situacao_fisica_check - CHECK (situacao_fisica = ANY(ARRAY[1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 4 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT constr_extracao_mineral_p_situacao_fisica_check + CHECK (situacao_fisica = ANY(ARRAY[1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 4 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE edgv.constr_extracao_mineral_p ALTER COLUMN situacao_fisica SET DEFAULT 999# ALTER TABLE edgv.constr_extracao_mineral_p @@ -1573,8 +1573,8 @@ ALTER TABLE edgv.constr_extracao_mineral_p ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE edgv.constr_extracao_mineral_p - ADD CONSTRAINT constr_extracao_mineral_p_tipo_produto_residuo_check - CHECK (tipo_produto_residuo = ANY(ARRAY[0 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 18 :: SMALLINT, 22 :: SMALLINT, 23 :: SMALLINT, 24 :: SMALLINT, 25 :: SMALLINT, 26 :: SMALLINT, 27 :: SMALLINT, 32 :: SMALLINT, 33 :: SMALLINT, 34 :: SMALLINT, 35 :: SMALLINT, 37 :: SMALLINT, 38 :: SMALLINT, 39 :: SMALLINT, 40 :: SMALLINT, 42 :: SMALLINT, 43 :: SMALLINT, 98 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT constr_extracao_mineral_p_tipo_produto_residuo_check + CHECK (tipo_produto_residuo = ANY(ARRAY[0 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 18 :: SMALLINT, 22 :: SMALLINT, 23 :: SMALLINT, 24 :: SMALLINT, 25 :: SMALLINT, 26 :: SMALLINT, 27 :: SMALLINT, 32 :: SMALLINT, 33 :: SMALLINT, 34 :: SMALLINT, 35 :: SMALLINT, 37 :: SMALLINT, 38 :: SMALLINT, 39 :: SMALLINT, 40 :: SMALLINT, 42 :: SMALLINT, 43 :: SMALLINT, 98 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE edgv.constr_extracao_mineral_p ALTER COLUMN tipo_produto_residuo SET DEFAULT 999# ALTER TABLE edgv.constr_extracao_mineral_p @@ -1614,8 +1614,8 @@ ALTER TABLE edgv.constr_ocupacao_solo_a ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE edgv.constr_ocupacao_solo_a - ADD CONSTRAINT constr_ocupacao_solo_a_tipo_check - CHECK (tipo = ANY(ARRAY[101 :: SMALLINT, 102 :: SMALLINT, 103 :: SMALLINT, 104 :: SMALLINT, 105 :: SMALLINT, 201 :: SMALLINT, 202 :: SMALLINT, 203 :: SMALLINT, 204 :: SMALLINT, 205 :: SMALLINT, 206 :: SMALLINT, 207 :: SMALLINT, 298 :: SMALLINT, 404 :: SMALLINT, 405 :: SMALLINT, 406 :: SMALLINT, 409 :: SMALLINT, 414 :: SMALLINT, 495 :: SMALLINT, 501 :: SMALLINT, 601 :: SMALLINT, 701 :: SMALLINT, 801 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT constr_ocupacao_solo_a_tipo_check + CHECK (tipo = ANY(ARRAY[101 :: SMALLINT, 102 :: SMALLINT, 103 :: SMALLINT, 104 :: SMALLINT, 105 :: SMALLINT, 201 :: SMALLINT, 202 :: SMALLINT, 203 :: SMALLINT, 204 :: SMALLINT, 205 :: SMALLINT, 206 :: SMALLINT, 207 :: SMALLINT, 298 :: SMALLINT, 404 :: SMALLINT, 405 :: SMALLINT, 406 :: SMALLINT, 409 :: SMALLINT, 414 :: SMALLINT, 495 :: SMALLINT, 501 :: SMALLINT, 601 :: SMALLINT, 701 :: SMALLINT, 801 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE edgv.constr_ocupacao_solo_a ALTER COLUMN tipo SET DEFAULT 999# ALTER TABLE edgv.constr_ocupacao_solo_a @@ -1624,8 +1624,8 @@ ALTER TABLE edgv.constr_ocupacao_solo_a ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE edgv.constr_ocupacao_solo_a - ADD CONSTRAINT constr_ocupacao_solo_a_situacao_fisica_check - CHECK (situacao_fisica = ANY(ARRAY[1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 4 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT constr_ocupacao_solo_a_situacao_fisica_check + CHECK (situacao_fisica = ANY(ARRAY[1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 4 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE edgv.constr_ocupacao_solo_a ALTER COLUMN situacao_fisica SET DEFAULT 999# ALTER TABLE edgv.constr_ocupacao_solo_a @@ -1665,8 +1665,8 @@ ALTER TABLE edgv.constr_ocupacao_solo_l ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE edgv.constr_ocupacao_solo_l - ADD CONSTRAINT constr_ocupacao_solo_l_tipo_check - CHECK (tipo = ANY(ARRAY[301 :: SMALLINT, 302 :: SMALLINT, 303 :: SMALLINT, 304 :: SMALLINT, 305 :: SMALLINT, 398 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT constr_ocupacao_solo_l_tipo_check + CHECK (tipo = ANY(ARRAY[301 :: SMALLINT, 302 :: SMALLINT, 303 :: SMALLINT, 304 :: SMALLINT, 305 :: SMALLINT, 398 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE edgv.constr_ocupacao_solo_l ALTER COLUMN tipo SET DEFAULT 999# ALTER TABLE edgv.constr_ocupacao_solo_l @@ -1675,8 +1675,8 @@ ALTER TABLE edgv.constr_ocupacao_solo_l ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE edgv.constr_ocupacao_solo_l - ADD CONSTRAINT constr_ocupacao_solo_l_situacao_fisica_check - CHECK (situacao_fisica = ANY(ARRAY[1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 4 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT constr_ocupacao_solo_l_situacao_fisica_check + CHECK (situacao_fisica = ANY(ARRAY[1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 4 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE edgv.constr_ocupacao_solo_l ALTER COLUMN situacao_fisica SET DEFAULT 999# ALTER TABLE edgv.constr_ocupacao_solo_l @@ -1716,8 +1716,8 @@ ALTER TABLE edgv.constr_ocupacao_solo_p ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE edgv.constr_ocupacao_solo_p - ADD CONSTRAINT constr_ocupacao_solo_p_tipo_check - CHECK (tipo = ANY(ARRAY[101 :: SMALLINT, 102 :: SMALLINT, 103 :: SMALLINT, 104 :: SMALLINT, 105 :: SMALLINT, 201 :: SMALLINT, 202 :: SMALLINT, 203 :: SMALLINT, 204 :: SMALLINT, 205 :: SMALLINT, 206 :: SMALLINT, 207 :: SMALLINT, 298 :: SMALLINT, 701 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT constr_ocupacao_solo_p_tipo_check + CHECK (tipo = ANY(ARRAY[101 :: SMALLINT, 102 :: SMALLINT, 103 :: SMALLINT, 104 :: SMALLINT, 105 :: SMALLINT, 201 :: SMALLINT, 202 :: SMALLINT, 203 :: SMALLINT, 204 :: SMALLINT, 205 :: SMALLINT, 206 :: SMALLINT, 207 :: SMALLINT, 298 :: SMALLINT, 701 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE edgv.constr_ocupacao_solo_p ALTER COLUMN tipo SET DEFAULT 999# ALTER TABLE edgv.constr_ocupacao_solo_p @@ -1726,8 +1726,8 @@ ALTER TABLE edgv.constr_ocupacao_solo_p ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE edgv.constr_ocupacao_solo_p - ADD CONSTRAINT constr_ocupacao_solo_p_situacao_fisica_check - CHECK (situacao_fisica = ANY(ARRAY[1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 4 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT constr_ocupacao_solo_p_situacao_fisica_check + CHECK (situacao_fisica = ANY(ARRAY[1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 4 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE edgv.constr_ocupacao_solo_p ALTER COLUMN situacao_fisica SET DEFAULT 999# ALTER TABLE edgv.constr_ocupacao_solo_p @@ -1811,8 +1811,8 @@ ALTER TABLE edgv.elemnat_elemento_fisiografico_a ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE edgv.elemnat_elemento_fisiografico_a - ADD CONSTRAINT elemnat_elemento_fisiografico_a_tipo_check - CHECK (tipo = ANY(ARRAY[12 :: SMALLINT, 15 :: SMALLINT, 16 :: SMALLINT, 21 :: SMALLINT, 22 :: SMALLINT, 23 :: SMALLINT, 24 :: SMALLINT, 25 :: SMALLINT, 28 :: SMALLINT, 29 :: SMALLINT, 30 :: SMALLINT, 31 :: SMALLINT, 32 :: SMALLINT, 33 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT elemnat_elemento_fisiografico_a_tipo_check + CHECK (tipo = ANY(ARRAY[12 :: SMALLINT, 15 :: SMALLINT, 16 :: SMALLINT, 21 :: SMALLINT, 22 :: SMALLINT, 23 :: SMALLINT, 24 :: SMALLINT, 25 :: SMALLINT, 28 :: SMALLINT, 29 :: SMALLINT, 30 :: SMALLINT, 31 :: SMALLINT, 32 :: SMALLINT, 33 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE edgv.elemnat_elemento_fisiografico_a ALTER COLUMN tipo SET DEFAULT 999# ALTER TABLE edgv.elemnat_elemento_fisiografico_a @@ -1851,8 +1851,8 @@ ALTER TABLE edgv.elemnat_elemento_fisiografico_l ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE edgv.elemnat_elemento_fisiografico_l - ADD CONSTRAINT elemnat_elemento_fisiografico_l_tipo_check - CHECK (tipo = ANY(ARRAY[1 :: SMALLINT, 8 :: SMALLINT, 12 :: SMALLINT, 13 :: SMALLINT, 14 :: SMALLINT, 26 :: SMALLINT, 27 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT elemnat_elemento_fisiografico_l_tipo_check + CHECK (tipo = ANY(ARRAY[1 :: SMALLINT, 8 :: SMALLINT, 12 :: SMALLINT, 13 :: SMALLINT, 14 :: SMALLINT, 26 :: SMALLINT, 27 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE edgv.elemnat_elemento_fisiografico_l ALTER COLUMN tipo SET DEFAULT 999# ALTER TABLE edgv.elemnat_elemento_fisiografico_l @@ -1891,8 +1891,8 @@ ALTER TABLE edgv.elemnat_elemento_fisiografico_p ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE edgv.elemnat_elemento_fisiografico_p - ADD CONSTRAINT elemnat_elemento_fisiografico_p_tipo_check - CHECK (tipo = ANY(ARRAY[2 :: SMALLINT, 3 :: SMALLINT, 4 :: SMALLINT, 5 :: SMALLINT, 6 :: SMALLINT, 7 :: SMALLINT, 9 :: SMALLINT, 10 :: SMALLINT, 11 :: SMALLINT, 12 :: SMALLINT, 17 :: SMALLINT, 19 :: SMALLINT, 20 :: SMALLINT, 21 :: SMALLINT, 22 :: SMALLINT, 30 :: SMALLINT, 31 :: SMALLINT, 32 :: SMALLINT, 33 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT elemnat_elemento_fisiografico_p_tipo_check + CHECK (tipo = ANY(ARRAY[2 :: SMALLINT, 3 :: SMALLINT, 4 :: SMALLINT, 5 :: SMALLINT, 6 :: SMALLINT, 7 :: SMALLINT, 9 :: SMALLINT, 10 :: SMALLINT, 11 :: SMALLINT, 12 :: SMALLINT, 17 :: SMALLINT, 19 :: SMALLINT, 20 :: SMALLINT, 21 :: SMALLINT, 22 :: SMALLINT, 30 :: SMALLINT, 31 :: SMALLINT, 32 :: SMALLINT, 33 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE edgv.elemnat_elemento_fisiografico_p ALTER COLUMN tipo SET DEFAULT 999# ALTER TABLE edgv.elemnat_elemento_fisiografico_p @@ -1931,8 +1931,8 @@ ALTER TABLE edgv.elemnat_elemento_hidrografico_a ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE edgv.elemnat_elemento_hidrografico_a - ADD CONSTRAINT elemnat_elemento_hidrografico_a_tipo_check - CHECK (tipo = ANY(ARRAY[6 :: SMALLINT, 8 :: SMALLINT, 12 :: SMALLINT, 13 :: SMALLINT, 14 :: SMALLINT, 15 :: SMALLINT, 16 :: SMALLINT, 17 :: SMALLINT, 18 :: SMALLINT, 19 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT elemnat_elemento_hidrografico_a_tipo_check + CHECK (tipo = ANY(ARRAY[6 :: SMALLINT, 8 :: SMALLINT, 12 :: SMALLINT, 13 :: SMALLINT, 14 :: SMALLINT, 15 :: SMALLINT, 16 :: SMALLINT, 17 :: SMALLINT, 18 :: SMALLINT, 19 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE edgv.elemnat_elemento_hidrografico_a ALTER COLUMN tipo SET DEFAULT 999# ALTER TABLE edgv.elemnat_elemento_hidrografico_a @@ -1971,8 +1971,8 @@ ALTER TABLE edgv.elemnat_elemento_hidrografico_l ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE edgv.elemnat_elemento_hidrografico_l - ADD CONSTRAINT elemnat_elemento_hidrografico_l_tipo_check - CHECK (tipo = ANY(ARRAY[8 :: SMALLINT, 9 :: SMALLINT, 10 :: SMALLINT, 11 :: SMALLINT, 12 :: SMALLINT, 18 :: SMALLINT, 19 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT elemnat_elemento_hidrografico_l_tipo_check + CHECK (tipo = ANY(ARRAY[8 :: SMALLINT, 9 :: SMALLINT, 10 :: SMALLINT, 11 :: SMALLINT, 12 :: SMALLINT, 18 :: SMALLINT, 19 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE edgv.elemnat_elemento_hidrografico_l ALTER COLUMN tipo SET DEFAULT 999# ALTER TABLE edgv.elemnat_elemento_hidrografico_l @@ -2011,8 +2011,8 @@ ALTER TABLE edgv.elemnat_elemento_hidrografico_p ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE edgv.elemnat_elemento_hidrografico_p - ADD CONSTRAINT elemnat_elemento_hidrografico_p_tipo_check - CHECK (tipo = ANY(ARRAY[1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 4 :: SMALLINT, 5 :: SMALLINT, 6 :: SMALLINT, 7 :: SMALLINT, 8 :: SMALLINT, 9 :: SMALLINT, 10 :: SMALLINT, 11 :: SMALLINT, 12 :: SMALLINT, 18 :: SMALLINT, 19 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT elemnat_elemento_hidrografico_p_tipo_check + CHECK (tipo = ANY(ARRAY[1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 4 :: SMALLINT, 5 :: SMALLINT, 6 :: SMALLINT, 7 :: SMALLINT, 8 :: SMALLINT, 9 :: SMALLINT, 10 :: SMALLINT, 11 :: SMALLINT, 12 :: SMALLINT, 18 :: SMALLINT, 19 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE edgv.elemnat_elemento_hidrografico_p ALTER COLUMN tipo SET DEFAULT 999# ALTER TABLE edgv.elemnat_elemento_hidrografico_p @@ -2136,8 +2136,8 @@ ALTER TABLE edgv.infra_elemento_infraestrutura_a ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE edgv.infra_elemento_infraestrutura_a - ADD CONSTRAINT infra_elemento_infraestrutura_a_tipo_check - CHECK (tipo = ANY(ARRAY[405 :: SMALLINT, 406 :: SMALLINT, 407 :: SMALLINT, 408 :: SMALLINT, 409 :: SMALLINT, 410 :: SMALLINT, 411 :: SMALLINT, 412 :: SMALLINT, 495 :: SMALLINT, 498 :: SMALLINT, 601 :: SMALLINT, 701 :: SMALLINT, 801 :: SMALLINT, 1001 :: SMALLINT, 1101 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT infra_elemento_infraestrutura_a_tipo_check + CHECK (tipo = ANY(ARRAY[405 :: SMALLINT, 406 :: SMALLINT, 407 :: SMALLINT, 408 :: SMALLINT, 409 :: SMALLINT, 410 :: SMALLINT, 411 :: SMALLINT, 412 :: SMALLINT, 495 :: SMALLINT, 498 :: SMALLINT, 601 :: SMALLINT, 701 :: SMALLINT, 801 :: SMALLINT, 1001 :: SMALLINT, 1101 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE edgv.infra_elemento_infraestrutura_a ALTER COLUMN tipo SET DEFAULT 999# ALTER TABLE edgv.infra_elemento_infraestrutura_a @@ -2153,8 +2153,8 @@ ALTER TABLE edgv.infra_elemento_infraestrutura_a ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE edgv.infra_elemento_infraestrutura_a - ADD CONSTRAINT infra_elemento_infraestrutura_a_material_construcao_check - CHECK (material_construcao = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 4 :: SMALLINT, 5 :: SMALLINT, 23 :: SMALLINT, 97 :: SMALLINT, 98 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT infra_elemento_infraestrutura_a_material_construcao_check + CHECK (material_construcao = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 4 :: SMALLINT, 5 :: SMALLINT, 23 :: SMALLINT, 97 :: SMALLINT, 98 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE edgv.infra_elemento_infraestrutura_a ALTER COLUMN material_construcao SET DEFAULT 999# ALTER TABLE edgv.infra_elemento_infraestrutura_a @@ -2203,8 +2203,8 @@ ALTER TABLE edgv.infra_elemento_infraestrutura_l ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE edgv.infra_elemento_infraestrutura_l - ADD CONSTRAINT infra_elemento_infraestrutura_l_tipo_check - CHECK (tipo = ANY(ARRAY[201 :: SMALLINT, 202 :: SMALLINT, 302 :: SMALLINT, 303 :: SMALLINT, 405 :: SMALLINT, 406 :: SMALLINT, 407 :: SMALLINT, 408 :: SMALLINT, 409 :: SMALLINT, 410 :: SMALLINT, 411 :: SMALLINT, 412 :: SMALLINT, 495 :: SMALLINT, 498 :: SMALLINT, 701 :: SMALLINT, 801 :: SMALLINT, 901 :: SMALLINT, 1001 :: SMALLINT, 1101 :: SMALLINT, 1501 :: SMALLINT, 1700 :: SMALLINT, 1701 :: SMALLINT, 1702 :: SMALLINT, 1703 :: SMALLINT, 1704 :: SMALLINT, 1705 :: SMALLINT, 1706 :: SMALLINT, 1707 :: SMALLINT, 1708 :: SMALLINT, 1709 :: SMALLINT, 1710 :: SMALLINT, 1798 :: SMALLINT, 1801 :: SMALLINT, 1901 :: SMALLINT, 1902 :: SMALLINT, 1998 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT infra_elemento_infraestrutura_l_tipo_check + CHECK (tipo = ANY(ARRAY[201 :: SMALLINT, 202 :: SMALLINT, 302 :: SMALLINT, 303 :: SMALLINT, 405 :: SMALLINT, 406 :: SMALLINT, 407 :: SMALLINT, 408 :: SMALLINT, 409 :: SMALLINT, 410 :: SMALLINT, 411 :: SMALLINT, 412 :: SMALLINT, 495 :: SMALLINT, 498 :: SMALLINT, 701 :: SMALLINT, 801 :: SMALLINT, 901 :: SMALLINT, 1001 :: SMALLINT, 1101 :: SMALLINT, 1501 :: SMALLINT, 1700 :: SMALLINT, 1701 :: SMALLINT, 1702 :: SMALLINT, 1703 :: SMALLINT, 1704 :: SMALLINT, 1705 :: SMALLINT, 1706 :: SMALLINT, 1707 :: SMALLINT, 1708 :: SMALLINT, 1709 :: SMALLINT, 1710 :: SMALLINT, 1798 :: SMALLINT, 1801 :: SMALLINT, 1901 :: SMALLINT, 1902 :: SMALLINT, 1998 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE edgv.infra_elemento_infraestrutura_l ALTER COLUMN tipo SET DEFAULT 999# ALTER TABLE edgv.infra_elemento_infraestrutura_l @@ -2220,8 +2220,8 @@ ALTER TABLE edgv.infra_elemento_infraestrutura_l ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE edgv.infra_elemento_infraestrutura_l - ADD CONSTRAINT infra_elemento_infraestrutura_l_material_construcao_check - CHECK (material_construcao = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 4 :: SMALLINT, 5 :: SMALLINT, 23 :: SMALLINT, 97 :: SMALLINT, 98 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT infra_elemento_infraestrutura_l_material_construcao_check + CHECK (material_construcao = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 4 :: SMALLINT, 5 :: SMALLINT, 23 :: SMALLINT, 97 :: SMALLINT, 98 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE edgv.infra_elemento_infraestrutura_l ALTER COLUMN material_construcao SET DEFAULT 999# ALTER TABLE edgv.infra_elemento_infraestrutura_l @@ -2270,8 +2270,8 @@ ALTER TABLE edgv.infra_elemento_infraestrutura_p ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE edgv.infra_elemento_infraestrutura_p - ADD CONSTRAINT infra_elemento_infraestrutura_p_tipo_check - CHECK (tipo = ANY(ARRAY[405 :: SMALLINT, 406 :: SMALLINT, 407 :: SMALLINT, 408 :: SMALLINT, 409 :: SMALLINT, 410 :: SMALLINT, 411 :: SMALLINT, 412 :: SMALLINT, 495 :: SMALLINT, 498 :: SMALLINT, 601 :: SMALLINT, 901 :: SMALLINT, 1001 :: SMALLINT, 1201 :: SMALLINT, 1301 :: SMALLINT, 1401 :: SMALLINT, 1501 :: SMALLINT, 1601 :: SMALLINT, 1698 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT infra_elemento_infraestrutura_p_tipo_check + CHECK (tipo = ANY(ARRAY[405 :: SMALLINT, 406 :: SMALLINT, 407 :: SMALLINT, 408 :: SMALLINT, 409 :: SMALLINT, 410 :: SMALLINT, 411 :: SMALLINT, 412 :: SMALLINT, 495 :: SMALLINT, 498 :: SMALLINT, 601 :: SMALLINT, 901 :: SMALLINT, 1001 :: SMALLINT, 1201 :: SMALLINT, 1301 :: SMALLINT, 1401 :: SMALLINT, 1501 :: SMALLINT, 1601 :: SMALLINT, 1698 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE edgv.infra_elemento_infraestrutura_p ALTER COLUMN tipo SET DEFAULT 999# ALTER TABLE edgv.infra_elemento_infraestrutura_p @@ -2287,8 +2287,8 @@ ALTER TABLE edgv.infra_elemento_infraestrutura_p ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE edgv.infra_elemento_infraestrutura_p - ADD CONSTRAINT infra_elemento_infraestrutura_p_material_construcao_check - CHECK (material_construcao = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 4 :: SMALLINT, 5 :: SMALLINT, 23 :: SMALLINT, 97 :: SMALLINT, 98 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT infra_elemento_infraestrutura_p_material_construcao_check + CHECK (material_construcao = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 4 :: SMALLINT, 5 :: SMALLINT, 23 :: SMALLINT, 97 :: SMALLINT, 98 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE edgv.infra_elemento_infraestrutura_p ALTER COLUMN material_construcao SET DEFAULT 999# ALTER TABLE edgv.infra_elemento_infraestrutura_p @@ -2335,8 +2335,8 @@ ALTER TABLE edgv.infra_elemento_transportes_a ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE edgv.infra_elemento_transportes_a - ADD CONSTRAINT infra_elemento_transportes_a_tipo_check - CHECK (tipo = ANY(ARRAY[238 :: SMALLINT, 239 :: SMALLINT, 240 :: SMALLINT, 241 :: SMALLINT, 242 :: SMALLINT, 243 :: SMALLINT, 244 :: SMALLINT, 1101 :: SMALLINT, 1201 :: SMALLINT, 1300 :: SMALLINT, 1301 :: SMALLINT, 1302 :: SMALLINT, 1395 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT infra_elemento_transportes_a_tipo_check + CHECK (tipo = ANY(ARRAY[238 :: SMALLINT, 239 :: SMALLINT, 240 :: SMALLINT, 241 :: SMALLINT, 242 :: SMALLINT, 243 :: SMALLINT, 244 :: SMALLINT, 1101 :: SMALLINT, 1201 :: SMALLINT, 1300 :: SMALLINT, 1301 :: SMALLINT, 1302 :: SMALLINT, 1395 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE edgv.infra_elemento_transportes_a ALTER COLUMN tipo SET DEFAULT 999# ALTER TABLE edgv.infra_elemento_transportes_a @@ -2383,8 +2383,8 @@ ALTER TABLE edgv.infra_elemento_transportes_l ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE edgv.infra_elemento_transportes_l - ADD CONSTRAINT infra_elemento_transportes_l_tipo_check - CHECK (tipo = ANY(ARRAY[238 :: SMALLINT, 239 :: SMALLINT, 240 :: SMALLINT, 241 :: SMALLINT, 242 :: SMALLINT, 243 :: SMALLINT, 244 :: SMALLINT, 302 :: SMALLINT, 303 :: SMALLINT, 304 :: SMALLINT, 501 :: SMALLINT, 607 :: SMALLINT, 608 :: SMALLINT, 609 :: SMALLINT, 801 :: SMALLINT, 898 :: SMALLINT, 901 :: SMALLINT, 1001 :: SMALLINT, 1101 :: SMALLINT, 1201 :: SMALLINT, 1401 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT infra_elemento_transportes_l_tipo_check + CHECK (tipo = ANY(ARRAY[238 :: SMALLINT, 239 :: SMALLINT, 240 :: SMALLINT, 241 :: SMALLINT, 242 :: SMALLINT, 243 :: SMALLINT, 244 :: SMALLINT, 302 :: SMALLINT, 303 :: SMALLINT, 304 :: SMALLINT, 501 :: SMALLINT, 607 :: SMALLINT, 608 :: SMALLINT, 609 :: SMALLINT, 801 :: SMALLINT, 898 :: SMALLINT, 901 :: SMALLINT, 1001 :: SMALLINT, 1101 :: SMALLINT, 1201 :: SMALLINT, 1401 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE edgv.infra_elemento_transportes_l ALTER COLUMN tipo SET DEFAULT 999# ALTER TABLE edgv.infra_elemento_transportes_l @@ -2431,8 +2431,8 @@ ALTER TABLE edgv.infra_elemento_transportes_p ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE edgv.infra_elemento_transportes_p - ADD CONSTRAINT infra_elemento_transportes_p_tipo_check - CHECK (tipo = ANY(ARRAY[101 :: SMALLINT, 238 :: SMALLINT, 239 :: SMALLINT, 240 :: SMALLINT, 241 :: SMALLINT, 242 :: SMALLINT, 243 :: SMALLINT, 244 :: SMALLINT, 404 :: SMALLINT, 607 :: SMALLINT, 608 :: SMALLINT, 609 :: SMALLINT, 701 :: SMALLINT, 901 :: SMALLINT, 1001 :: SMALLINT, 1101 :: SMALLINT, 1201 :: SMALLINT, 1300 :: SMALLINT, 1301 :: SMALLINT, 1302 :: SMALLINT, 1395 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT infra_elemento_transportes_p_tipo_check + CHECK (tipo = ANY(ARRAY[101 :: SMALLINT, 238 :: SMALLINT, 239 :: SMALLINT, 240 :: SMALLINT, 241 :: SMALLINT, 242 :: SMALLINT, 243 :: SMALLINT, 244 :: SMALLINT, 404 :: SMALLINT, 607 :: SMALLINT, 608 :: SMALLINT, 609 :: SMALLINT, 701 :: SMALLINT, 901 :: SMALLINT, 1001 :: SMALLINT, 1101 :: SMALLINT, 1201 :: SMALLINT, 1300 :: SMALLINT, 1301 :: SMALLINT, 1302 :: SMALLINT, 1395 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE edgv.infra_elemento_transportes_p ALTER COLUMN tipo SET DEFAULT 999# ALTER TABLE edgv.infra_elemento_transportes_p @@ -2641,8 +2641,8 @@ ALTER TABLE edgv.infra_ferrovia_l ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE edgv.infra_ferrovia_l - ADD CONSTRAINT infra_ferrovia_l_posicao_relativa_check - CHECK (posicao_relativa = ANY(ARRAY[2 :: SMALLINT, 3 :: SMALLINT, 6 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT infra_ferrovia_l_posicao_relativa_check + CHECK (posicao_relativa = ANY(ARRAY[2 :: SMALLINT, 3 :: SMALLINT, 6 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE edgv.infra_ferrovia_l ALTER COLUMN posicao_relativa SET DEFAULT 999# ALTER TABLE edgv.infra_ferrovia_l @@ -2665,8 +2665,8 @@ ALTER TABLE edgv.infra_ferrovia_l ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE edgv.infra_ferrovia_l - ADD CONSTRAINT infra_ferrovia_l_jurisdicao_check - CHECK (jurisdicao = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 6 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT infra_ferrovia_l_jurisdicao_check + CHECK (jurisdicao = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 6 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE edgv.infra_ferrovia_l ALTER COLUMN jurisdicao SET DEFAULT 999# ALTER TABLE edgv.infra_ferrovia_l @@ -2675,8 +2675,8 @@ ALTER TABLE edgv.infra_ferrovia_l ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE edgv.infra_ferrovia_l - ADD CONSTRAINT infra_ferrovia_l_administracao_check - CHECK (administracao = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 6 :: SMALLINT, 7 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT infra_ferrovia_l_administracao_check + CHECK (administracao = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 6 :: SMALLINT, 7 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE edgv.infra_ferrovia_l ALTER COLUMN administracao SET DEFAULT 999# ALTER TABLE edgv.infra_ferrovia_l @@ -2728,8 +2728,8 @@ ALTER TABLE edgv.infra_pista_pouso_a ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE edgv.infra_pista_pouso_a - ADD CONSTRAINT infra_pista_pouso_a_revestimento_check - CHECK (revestimento = ANY(ARRAY[1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 4 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT infra_pista_pouso_a_revestimento_check + CHECK (revestimento = ANY(ARRAY[1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 4 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE edgv.infra_pista_pouso_a ALTER COLUMN revestimento SET DEFAULT 999# ALTER TABLE edgv.infra_pista_pouso_a @@ -2802,8 +2802,8 @@ ALTER TABLE edgv.infra_pista_pouso_l ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE edgv.infra_pista_pouso_l - ADD CONSTRAINT infra_pista_pouso_l_revestimento_check - CHECK (revestimento = ANY(ARRAY[1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 4 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT infra_pista_pouso_l_revestimento_check + CHECK (revestimento = ANY(ARRAY[1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 4 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE edgv.infra_pista_pouso_l ALTER COLUMN revestimento SET DEFAULT 999# ALTER TABLE edgv.infra_pista_pouso_l @@ -2876,8 +2876,8 @@ ALTER TABLE edgv.infra_pista_pouso_p ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE edgv.infra_pista_pouso_p - ADD CONSTRAINT infra_pista_pouso_p_revestimento_check - CHECK (revestimento = ANY(ARRAY[1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 4 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT infra_pista_pouso_p_revestimento_check + CHECK (revestimento = ANY(ARRAY[1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 4 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE edgv.infra_pista_pouso_p ALTER COLUMN revestimento SET DEFAULT 999# ALTER TABLE edgv.infra_pista_pouso_p @@ -2954,8 +2954,8 @@ ALTER TABLE edgv.infra_via_deslocamento_l ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE edgv.infra_via_deslocamento_l - ADD CONSTRAINT infra_via_deslocamento_l_revestimento_check - CHECK (revestimento = ANY(ARRAY[1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 4 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT infra_via_deslocamento_l_revestimento_check + CHECK (revestimento = ANY(ARRAY[1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 4 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE edgv.infra_via_deslocamento_l ALTER COLUMN revestimento SET DEFAULT 999# ALTER TABLE edgv.infra_via_deslocamento_l @@ -2964,8 +2964,8 @@ ALTER TABLE edgv.infra_via_deslocamento_l ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE edgv.infra_via_deslocamento_l - ADD CONSTRAINT infra_via_deslocamento_l_trafego_check - CHECK (trafego = ANY(ARRAY[1 :: SMALLINT, 2 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT infra_via_deslocamento_l_trafego_check + CHECK (trafego = ANY(ARRAY[1 :: SMALLINT, 2 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE edgv.infra_via_deslocamento_l ALTER COLUMN trafego SET DEFAULT 999# ALTER TABLE edgv.infra_via_deslocamento_l @@ -2981,8 +2981,8 @@ ALTER TABLE edgv.infra_via_deslocamento_l ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE edgv.infra_via_deslocamento_l - ADD CONSTRAINT infra_via_deslocamento_l_situacao_fisica_check - CHECK (situacao_fisica = ANY(ARRAY[1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 4 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT infra_via_deslocamento_l_situacao_fisica_check + CHECK (situacao_fisica = ANY(ARRAY[1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 4 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE edgv.infra_via_deslocamento_l ALTER COLUMN situacao_fisica SET DEFAULT 999# ALTER TABLE edgv.infra_via_deslocamento_l @@ -2991,8 +2991,8 @@ ALTER TABLE edgv.infra_via_deslocamento_l ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE edgv.infra_via_deslocamento_l - ADD CONSTRAINT infra_via_deslocamento_l_jurisdicao_check - CHECK (jurisdicao = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT infra_via_deslocamento_l_jurisdicao_check + CHECK (jurisdicao = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE edgv.infra_via_deslocamento_l ALTER COLUMN jurisdicao SET DEFAULT 999# ALTER TABLE edgv.infra_via_deslocamento_l @@ -3001,8 +3001,8 @@ ALTER TABLE edgv.infra_via_deslocamento_l ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE edgv.infra_via_deslocamento_l - ADD CONSTRAINT infra_via_deslocamento_l_administracao_check - CHECK (administracao = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 7 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT infra_via_deslocamento_l_administracao_check + CHECK (administracao = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 7 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE edgv.infra_via_deslocamento_l ALTER COLUMN administracao SET DEFAULT 999# ALTER TABLE edgv.infra_via_deslocamento_l @@ -3048,8 +3048,8 @@ ALTER TABLE edgv.llp_delimitacao_fisica_l ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE edgv.llp_delimitacao_fisica_l - ADD CONSTRAINT llp_delimitacao_fisica_l_material_construcao_check - CHECK (material_construcao = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 4 :: SMALLINT, 5 :: SMALLINT, 6 :: SMALLINT, 7 :: SMALLINT, 8 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT llp_delimitacao_fisica_l_material_construcao_check + CHECK (material_construcao = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 4 :: SMALLINT, 5 :: SMALLINT, 6 :: SMALLINT, 7 :: SMALLINT, 8 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE edgv.llp_delimitacao_fisica_l ALTER COLUMN material_construcao SET DEFAULT 999# ALTER TABLE edgv.llp_delimitacao_fisica_l @@ -3196,8 +3196,8 @@ ALTER TABLE edgv.llp_limite_legal_a ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE edgv.llp_limite_legal_a - ADD CONSTRAINT llp_limite_legal_a_tipo_check - CHECK (tipo = ANY(ARRAY[4 :: SMALLINT, 5 :: SMALLINT, 6 :: SMALLINT, 7 :: SMALLINT, 8 :: SMALLINT, 9 :: SMALLINT, 10 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT llp_limite_legal_a_tipo_check + CHECK (tipo = ANY(ARRAY[4 :: SMALLINT, 5 :: SMALLINT, 6 :: SMALLINT, 7 :: SMALLINT, 8 :: SMALLINT, 9 :: SMALLINT, 10 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE edgv.llp_limite_legal_a ALTER COLUMN tipo SET DEFAULT 999# ALTER TABLE edgv.llp_limite_legal_a @@ -3252,8 +3252,8 @@ ALTER TABLE edgv.llp_limite_legal_l ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE edgv.llp_limite_legal_l - ADD CONSTRAINT llp_limite_legal_l_tipo_check - CHECK (tipo = ANY(ARRAY[1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT llp_limite_legal_l_tipo_check + CHECK (tipo = ANY(ARRAY[1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE edgv.llp_limite_legal_l ALTER COLUMN tipo SET DEFAULT 999# ALTER TABLE edgv.llp_limite_legal_l @@ -4806,8 +4806,8 @@ ALTER TABLE edgv.aquisicao_centroide_vegetacao_p ON UPDATE NO ACTION ON DELETE NO ACTION# ALTER TABLE edgv.aquisicao_centroide_vegetacao_p - ADD CONSTRAINT aquisicao_centroide_vegetacao_p_tipo_check - CHECK (tipo = ANY(ARRAY[301 :: SMALLINT, 302 :: SMALLINT, 201 :: SMALLINT, 202 :: SMALLINT, 801 :: SMALLINT, 501 :: SMALLINT, 701 :: SMALLINT, 702 :: SMALLINT, 401 :: SMALLINT, 1101 :: SMALLINT, 901 :: SMALLINT, 601 :: SMALLINT, 194 :: SMALLINT, 196 :: SMALLINT, 150 :: SMALLINT, 118 :: SMALLINT, 102 :: SMALLINT, 115 :: SMALLINT, 114 :: SMALLINT, 116 :: SMALLINT, 103 :: SMALLINT, 151 :: SMALLINT, 117 :: SMALLINT, 153 :: SMALLINT, 152 :: SMALLINT, 119 :: SMALLINT, 142 :: SMALLINT, 107 :: SMALLINT, 124 :: SMALLINT, 198 :: SMALLINT, 195 :: SMALLINT, 1296 :: SMALLINT, 1000 :: SMALLINT, 999 :: SMALLINT]))# + ADD CONSTRAINT aquisicao_centroide_vegetacao_p_tipo_check + CHECK (tipo = ANY(ARRAY[301 :: SMALLINT, 302 :: SMALLINT, 201 :: SMALLINT, 202 :: SMALLINT, 801 :: SMALLINT, 501 :: SMALLINT, 701 :: SMALLINT, 702 :: SMALLINT, 401 :: SMALLINT, 1101 :: SMALLINT, 901 :: SMALLINT, 601 :: SMALLINT, 194 :: SMALLINT, 196 :: SMALLINT, 150 :: SMALLINT, 118 :: SMALLINT, 102 :: SMALLINT, 115 :: SMALLINT, 114 :: SMALLINT, 116 :: SMALLINT, 103 :: SMALLINT, 151 :: SMALLINT, 117 :: SMALLINT, 153 :: SMALLINT, 152 :: SMALLINT, 119 :: SMALLINT, 142 :: SMALLINT, 107 :: SMALLINT, 124 :: SMALLINT, 198 :: SMALLINT, 195 :: SMALLINT, 1296 :: SMALLINT, 1000 :: SMALLINT, 999 :: SMALLINT]))# ALTER TABLE edgv.aquisicao_centroide_vegetacao_p ALTER COLUMN tipo SET DEFAULT 999# ALTER TABLE edgv.aquisicao_centroide_vegetacao_p @@ -4876,7 +4876,7 @@ $BODY$ querytext1 := 'INSERT INTO ' || quote_ident(TG_TABLE_SCHEMA) || '.' || quote_ident(TG_TABLE_NAME) || '('; querytext2 := 'geom) SELECT '; - FOR r IN SELECT (each(hstore(NEW))).* + FOR r IN SELECT (each(hstore(NEW))).* LOOP IF r.key <> 'geom' AND r.key <> 'id' THEN querytext1 := querytext1 || quote_ident(r.key) || ','; diff --git a/DsgTools/core/DbModels/PostGIS/3/edgv3.sql b/DsgTools/core/DbModels/PostGIS/3/edgv3.sql index d07f597b6..a1aeb3477 100644 --- a/DsgTools/core/DbModels/PostGIS/3/edgv3.sql +++ b/DsgTools/core/DbModels/PostGIS/3/edgv3.sql @@ -2772,8 +2772,8 @@ ALTER TABLE edgv.aer_pista_ponto_pouso_l ON UPDATE NO ACTION ON DELETE NO ACTION; ALTER TABLE edgv.aer_pista_ponto_pouso_l - ADD CONSTRAINT aer_pista_ponto_pouso_l_situacaofisica_check - CHECK (situacaofisica = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 6 :: SMALLINT, 9999 :: SMALLINT])); + ADD CONSTRAINT aer_pista_ponto_pouso_l_situacaofisica_check + CHECK (situacaofisica = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 6 :: SMALLINT, 9999 :: SMALLINT])); ALTER TABLE edgv.aer_pista_ponto_pouso_l ALTER COLUMN situacaofisica SET DEFAULT 9999; CREATE TABLE edgv.aer_pista_ponto_pouso_p( @@ -2838,8 +2838,8 @@ ALTER TABLE edgv.aer_pista_ponto_pouso_p ON UPDATE NO ACTION ON DELETE NO ACTION; ALTER TABLE edgv.aer_pista_ponto_pouso_p - ADD CONSTRAINT aer_pista_ponto_pouso_p_situacaofisica_check - CHECK (situacaofisica = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 6 :: SMALLINT, 9999 :: SMALLINT])); + ADD CONSTRAINT aer_pista_ponto_pouso_p_situacaofisica_check + CHECK (situacaofisica = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 6 :: SMALLINT, 9999 :: SMALLINT])); ALTER TABLE edgv.aer_pista_ponto_pouso_p ALTER COLUMN situacaofisica SET DEFAULT 9999; CREATE TABLE edgv.aer_pista_ponto_pouso_a( @@ -2904,8 +2904,8 @@ ALTER TABLE edgv.aer_pista_ponto_pouso_a ON UPDATE NO ACTION ON DELETE NO ACTION; ALTER TABLE edgv.aer_pista_ponto_pouso_a - ADD CONSTRAINT aer_pista_ponto_pouso_a_situacaofisica_check - CHECK (situacaofisica = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 6 :: SMALLINT, 9999 :: SMALLINT])); + ADD CONSTRAINT aer_pista_ponto_pouso_a_situacaofisica_check + CHECK (situacaofisica = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 5 :: SMALLINT, 6 :: SMALLINT, 9999 :: SMALLINT])); ALTER TABLE edgv.aer_pista_ponto_pouso_a ALTER COLUMN situacaofisica SET DEFAULT 9999; CREATE TABLE edgv.enc_subest_transm_distrib_energia_eletrica_a( @@ -2936,8 +2936,8 @@ ALTER TABLE edgv.enc_subest_transm_distrib_energia_eletrica_a ON UPDATE NO ACTION ON DELETE NO ACTION; ALTER TABLE edgv.enc_subest_transm_distrib_energia_eletrica_a - ADD CONSTRAINT enc_subest_transm_distrib_energia_eletrica_a_classeativecon_check - CHECK (classeativecon = ANY(ARRAY[2 :: SMALLINT, 3 :: SMALLINT, 9999 :: SMALLINT])); + ADD CONSTRAINT enc_subest_transm_distrib_energia_eletrica_a_classeativecon_check + CHECK (classeativecon = ANY(ARRAY[2 :: SMALLINT, 3 :: SMALLINT, 9999 :: SMALLINT])); ALTER TABLE edgv.enc_subest_transm_distrib_energia_eletrica_a ALTER COLUMN classeativecon SET DEFAULT 9999; ALTER TABLE edgv.enc_subest_transm_distrib_energia_eletrica_a @@ -2991,8 +2991,8 @@ ALTER TABLE edgv.cbge_deposito_geral_p ON UPDATE NO ACTION ON DELETE NO ACTION; ALTER TABLE edgv.cbge_deposito_geral_p - ADD CONSTRAINT cbge_deposito_geral_p_tipodepgeral_check - CHECK (tipodepgeral = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 4 :: SMALLINT, 5 :: SMALLINT, 6 :: SMALLINT, 8 :: SMALLINT, 9 :: SMALLINT, 10 :: SMALLINT, 11 :: SMALLINT, 19 :: SMALLINT, 26 :: SMALLINT, 32 :: SMALLINT, 99 :: SMALLINT, 9999 :: SMALLINT])); + ADD CONSTRAINT cbge_deposito_geral_p_tipodepgeral_check + CHECK (tipodepgeral = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 4 :: SMALLINT, 5 :: SMALLINT, 6 :: SMALLINT, 8 :: SMALLINT, 9 :: SMALLINT, 10 :: SMALLINT, 11 :: SMALLINT, 19 :: SMALLINT, 26 :: SMALLINT, 32 :: SMALLINT, 99 :: SMALLINT, 9999 :: SMALLINT])); ALTER TABLE edgv.cbge_deposito_geral_p ALTER COLUMN tipodepgeral SET DEFAULT 9999; ALTER TABLE edgv.cbge_deposito_geral_p @@ -3095,8 +3095,8 @@ ALTER TABLE edgv.cbge_deposito_geral_a ON UPDATE NO ACTION ON DELETE NO ACTION; ALTER TABLE edgv.cbge_deposito_geral_a - ADD CONSTRAINT cbge_deposito_geral_a_tipodepgeral_check - CHECK (tipodepgeral = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 4 :: SMALLINT, 5 :: SMALLINT, 6 :: SMALLINT, 8 :: SMALLINT, 9 :: SMALLINT, 10 :: SMALLINT, 11 :: SMALLINT, 19 :: SMALLINT, 26 :: SMALLINT, 32 :: SMALLINT, 99 :: SMALLINT, 9999 :: SMALLINT])); + ADD CONSTRAINT cbge_deposito_geral_a_tipodepgeral_check + CHECK (tipodepgeral = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 4 :: SMALLINT, 5 :: SMALLINT, 6 :: SMALLINT, 8 :: SMALLINT, 9 :: SMALLINT, 10 :: SMALLINT, 11 :: SMALLINT, 19 :: SMALLINT, 26 :: SMALLINT, 32 :: SMALLINT, 99 :: SMALLINT, 9999 :: SMALLINT])); ALTER TABLE edgv.cbge_deposito_geral_a ALTER COLUMN tipodepgeral SET DEFAULT 9999; ALTER TABLE edgv.cbge_deposito_geral_a @@ -3175,8 +3175,8 @@ ALTER TABLE edgv.cbge_area_agropec_ext_vegetal_pesca_a ON UPDATE NO ACTION ON DELETE NO ACTION; ALTER TABLE edgv.cbge_area_agropec_ext_vegetal_pesca_a - ADD CONSTRAINT cbge_area_agropec_ext_vegetal_pesca_a_tipoarea_check - CHECK (tipoarea = ANY(ARRAY[4 :: SMALLINT, 9999 :: SMALLINT])); + ADD CONSTRAINT cbge_area_agropec_ext_vegetal_pesca_a_tipoarea_check + CHECK (tipoarea = ANY(ARRAY[4 :: SMALLINT, 9999 :: SMALLINT])); ALTER TABLE edgv.cbge_area_agropec_ext_vegetal_pesca_a ALTER COLUMN tipoarea SET DEFAULT 9999; ALTER TABLE edgv.cbge_area_agropec_ext_vegetal_pesca_a @@ -3652,8 +3652,8 @@ ALTER TABLE edgv.cbge_area_habitacional_a ON UPDATE NO ACTION ON DELETE NO ACTION; ALTER TABLE edgv.cbge_area_habitacional_a - ADD CONSTRAINT cbge_area_habitacional_a_tipoarea_check - CHECK (tipoarea = ANY(ARRAY[2 :: SMALLINT, 9999 :: SMALLINT])); + ADD CONSTRAINT cbge_area_habitacional_a_tipoarea_check + CHECK (tipoarea = ANY(ARRAY[2 :: SMALLINT, 9999 :: SMALLINT])); ALTER TABLE edgv.cbge_area_habitacional_a ALTER COLUMN tipoarea SET DEFAULT 9999; CREATE TABLE edgv.cbge_estacionamento_a( @@ -3680,8 +3680,8 @@ ALTER TABLE edgv.cbge_estacionamento_a ON UPDATE NO ACTION ON DELETE NO ACTION; ALTER TABLE edgv.cbge_estacionamento_a - ADD CONSTRAINT cbge_estacionamento_a_modaluso_check - CHECK (modaluso = ANY(ARRAY[4 :: SMALLINT, 9999 :: SMALLINT])); + ADD CONSTRAINT cbge_estacionamento_a_modaluso_check + CHECK (modaluso = ANY(ARRAY[4 :: SMALLINT, 9999 :: SMALLINT])); ALTER TABLE edgv.cbge_estacionamento_a ALTER COLUMN modaluso SET DEFAULT 9999; ALTER TABLE edgv.cbge_estacionamento_a @@ -3711,8 +3711,8 @@ ALTER TABLE edgv.cbge_estacionamento_a ON UPDATE NO ACTION ON DELETE NO ACTION; ALTER TABLE edgv.cbge_estacionamento_a - ADD CONSTRAINT cbge_estacionamento_a_finalidadepatio_check - CHECK (finalidadepatio = ANY(ARRAY[3 :: SMALLINT, 9999 :: SMALLINT])); + ADD CONSTRAINT cbge_estacionamento_a_finalidadepatio_check + CHECK (finalidadepatio = ANY(ARRAY[3 :: SMALLINT, 9999 :: SMALLINT])); ALTER TABLE edgv.cbge_estacionamento_a ALTER COLUMN finalidadepatio SET DEFAULT 9999; ALTER TABLE edgv.cbge_estacionamento_a @@ -3763,8 +3763,8 @@ ALTER TABLE edgv.cbge_area_duto_a ON UPDATE NO ACTION ON DELETE NO ACTION; ALTER TABLE edgv.cbge_area_duto_a - ADD CONSTRAINT cbge_area_duto_a_tipoarea_check - CHECK (tipoarea = ANY(ARRAY[3 :: SMALLINT, 9999 :: SMALLINT])); + ADD CONSTRAINT cbge_area_duto_a_tipoarea_check + CHECK (tipoarea = ANY(ARRAY[3 :: SMALLINT, 9999 :: SMALLINT])); ALTER TABLE edgv.cbge_area_duto_a ALTER COLUMN tipoarea SET DEFAULT 9999; ALTER TABLE edgv.cbge_area_duto_a @@ -3800,8 +3800,8 @@ ALTER TABLE edgv.cbge_area_de_propriedade_particular_a ON UPDATE NO ACTION ON DELETE NO ACTION; ALTER TABLE edgv.cbge_area_de_propriedade_particular_a - ADD CONSTRAINT cbge_area_de_propriedade_particular_a_tipoarea_check - CHECK (tipoarea = ANY(ARRAY[1 :: SMALLINT, 9999 :: SMALLINT])); + ADD CONSTRAINT cbge_area_de_propriedade_particular_a_tipoarea_check + CHECK (tipoarea = ANY(ARRAY[1 :: SMALLINT, 9999 :: SMALLINT])); ALTER TABLE edgv.cbge_area_de_propriedade_particular_a ALTER COLUMN tipoarea SET DEFAULT 9999; CREATE TABLE edgv.cbge_quadra_a( @@ -3835,8 +3835,8 @@ ALTER TABLE edgv.cbge_area_uso_especifico_a ON UPDATE NO ACTION ON DELETE NO ACTION; ALTER TABLE edgv.cbge_area_uso_especifico_a - ADD CONSTRAINT cbge_area_uso_especifico_a_tipoarea_check - CHECK (tipoarea = ANY(ARRAY[0 :: SMALLINT, 5 :: SMALLINT, 6 :: SMALLINT, 7 :: SMALLINT, 8 :: SMALLINT, 9 :: SMALLINT, 10 :: SMALLINT, 11 :: SMALLINT, 12 :: SMALLINT, 13 :: SMALLINT, 14 :: SMALLINT, 15 :: SMALLINT, 16 :: SMALLINT, 17 :: SMALLINT, 18 :: SMALLINT, 19 :: SMALLINT, 99 :: SMALLINT, 9999 :: SMALLINT])); + ADD CONSTRAINT cbge_area_uso_especifico_a_tipoarea_check + CHECK (tipoarea = ANY(ARRAY[0 :: SMALLINT, 5 :: SMALLINT, 6 :: SMALLINT, 7 :: SMALLINT, 8 :: SMALLINT, 9 :: SMALLINT, 10 :: SMALLINT, 11 :: SMALLINT, 12 :: SMALLINT, 13 :: SMALLINT, 14 :: SMALLINT, 15 :: SMALLINT, 16 :: SMALLINT, 17 :: SMALLINT, 18 :: SMALLINT, 19 :: SMALLINT, 99 :: SMALLINT, 9999 :: SMALLINT])); ALTER TABLE edgv.cbge_area_uso_especifico_a ALTER COLUMN tipoarea SET DEFAULT 9999; CREATE TABLE edgv.cbge_passeio_l( @@ -3937,8 +3937,8 @@ ALTER TABLE edgv.dut_galeria_bueiro_l ON UPDATE NO ACTION ON DELETE NO ACTION; ALTER TABLE edgv.dut_galeria_bueiro_l - ADD CONSTRAINT dut_galeria_bueiro_l_tipotrechoduto_check - CHECK (tipotrechoduto = ANY(ARRAY[4 :: SMALLINT, 5 :: SMALLINT, 9999 :: SMALLINT])); + ADD CONSTRAINT dut_galeria_bueiro_l_tipotrechoduto_check + CHECK (tipotrechoduto = ANY(ARRAY[4 :: SMALLINT, 5 :: SMALLINT, 9999 :: SMALLINT])); ALTER TABLE edgv.dut_galeria_bueiro_l ALTER COLUMN tipotrechoduto SET DEFAULT 9999; ALTER TABLE edgv.dut_galeria_bueiro_l @@ -3954,8 +3954,8 @@ ALTER TABLE edgv.dut_galeria_bueiro_l ON UPDATE NO ACTION ON DELETE NO ACTION; ALTER TABLE edgv.dut_galeria_bueiro_l - ADD CONSTRAINT dut_galeria_bueiro_l_setor_check - CHECK (setor = ANY(ARRAY[0 :: SMALLINT, 4 :: SMALLINT, 9999 :: SMALLINT])); + ADD CONSTRAINT dut_galeria_bueiro_l_setor_check + CHECK (setor = ANY(ARRAY[0 :: SMALLINT, 4 :: SMALLINT, 9999 :: SMALLINT])); ALTER TABLE edgv.dut_galeria_bueiro_l ALTER COLUMN setor SET DEFAULT 9999; ALTER TABLE edgv.dut_galeria_bueiro_l @@ -4030,8 +4030,8 @@ ALTER TABLE edgv.dut_galeria_bueiro_p ON UPDATE NO ACTION ON DELETE NO ACTION; ALTER TABLE edgv.dut_galeria_bueiro_p - ADD CONSTRAINT dut_galeria_bueiro_p_tipotrechoduto_check - CHECK (tipotrechoduto = ANY(ARRAY[4 :: SMALLINT, 5 :: SMALLINT, 9999 :: SMALLINT])); + ADD CONSTRAINT dut_galeria_bueiro_p_tipotrechoduto_check + CHECK (tipotrechoduto = ANY(ARRAY[4 :: SMALLINT, 5 :: SMALLINT, 9999 :: SMALLINT])); ALTER TABLE edgv.dut_galeria_bueiro_p ALTER COLUMN tipotrechoduto SET DEFAULT 9999; ALTER TABLE edgv.dut_galeria_bueiro_p @@ -4047,8 +4047,8 @@ ALTER TABLE edgv.dut_galeria_bueiro_p ON UPDATE NO ACTION ON DELETE NO ACTION; ALTER TABLE edgv.dut_galeria_bueiro_p - ADD CONSTRAINT dut_galeria_bueiro_p_setor_check - CHECK (setor = ANY(ARRAY[0 :: SMALLINT, 4 :: SMALLINT, 9999 :: SMALLINT])); + ADD CONSTRAINT dut_galeria_bueiro_p_setor_check + CHECK (setor = ANY(ARRAY[0 :: SMALLINT, 4 :: SMALLINT, 9999 :: SMALLINT])); ALTER TABLE edgv.dut_galeria_bueiro_p ALTER COLUMN setor SET DEFAULT 9999; ALTER TABLE edgv.dut_galeria_bueiro_p @@ -4120,8 +4120,8 @@ ALTER TABLE edgv.dut_trecho_duto_l ON UPDATE NO ACTION ON DELETE NO ACTION; ALTER TABLE edgv.dut_trecho_duto_l - ADD CONSTRAINT dut_trecho_duto_l_tipotrechoduto_check - CHECK (tipotrechoduto = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 9999 :: SMALLINT])); + ADD CONSTRAINT dut_trecho_duto_l_tipotrechoduto_check + CHECK (tipotrechoduto = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 9999 :: SMALLINT])); ALTER TABLE edgv.dut_trecho_duto_l ALTER COLUMN tipotrechoduto SET DEFAULT 9999; ALTER TABLE edgv.dut_trecho_duto_l @@ -4333,8 +4333,8 @@ ALTER TABLE edgv.eco_ext_mineral_p ON UPDATE NO ACTION ON DELETE NO ACTION; ALTER TABLE edgv.eco_ext_mineral_p - ADD CONSTRAINT eco_ext_mineral_p_tipoalterantrop_check - CHECK (tipoalterantrop = ANY(ARRAY[32 :: SMALLINT, 9999 :: SMALLINT])); + ADD CONSTRAINT eco_ext_mineral_p_tipoalterantrop_check + CHECK (tipoalterantrop = ANY(ARRAY[32 :: SMALLINT, 9999 :: SMALLINT])); ALTER TABLE edgv.eco_ext_mineral_p ALTER COLUMN tipoalterantrop SET DEFAULT 9999; ALTER TABLE edgv.eco_ext_mineral_p @@ -4343,8 +4343,8 @@ ALTER TABLE edgv.eco_ext_mineral_p ON UPDATE NO ACTION ON DELETE NO ACTION; ALTER TABLE edgv.eco_ext_mineral_p - ADD CONSTRAINT eco_ext_mineral_p_secaoativecon_check - CHECK (secaoativecon = ANY(ARRAY[1 :: SMALLINT, 9999 :: SMALLINT])); + ADD CONSTRAINT eco_ext_mineral_p_secaoativecon_check + CHECK (secaoativecon = ANY(ARRAY[1 :: SMALLINT, 9999 :: SMALLINT])); ALTER TABLE edgv.eco_ext_mineral_p ALTER COLUMN secaoativecon SET DEFAULT 9999; ALTER TABLE edgv.eco_ext_mineral_p @@ -4431,8 +4431,8 @@ ALTER TABLE edgv.eco_ext_mineral_a ON UPDATE NO ACTION ON DELETE NO ACTION; ALTER TABLE edgv.eco_ext_mineral_a - ADD CONSTRAINT eco_ext_mineral_a_tipoalterantrop_check - CHECK (tipoalterantrop = ANY(ARRAY[32 :: SMALLINT, 9999 :: SMALLINT])); + ADD CONSTRAINT eco_ext_mineral_a_tipoalterantrop_check + CHECK (tipoalterantrop = ANY(ARRAY[32 :: SMALLINT, 9999 :: SMALLINT])); ALTER TABLE edgv.eco_ext_mineral_a ALTER COLUMN tipoalterantrop SET DEFAULT 9999; ALTER TABLE edgv.eco_ext_mineral_a @@ -4441,8 +4441,8 @@ ALTER TABLE edgv.eco_ext_mineral_a ON UPDATE NO ACTION ON DELETE NO ACTION; ALTER TABLE edgv.eco_ext_mineral_a - ADD CONSTRAINT eco_ext_mineral_a_secaoativecon_check - CHECK (secaoativecon = ANY(ARRAY[1 :: SMALLINT, 9999 :: SMALLINT])); + ADD CONSTRAINT eco_ext_mineral_a_secaoativecon_check + CHECK (secaoativecon = ANY(ARRAY[1 :: SMALLINT, 9999 :: SMALLINT])); ALTER TABLE edgv.eco_ext_mineral_a ALTER COLUMN secaoativecon SET DEFAULT 9999; ALTER TABLE edgv.eco_ext_mineral_a @@ -4814,8 +4814,8 @@ ALTER TABLE edgv.edf_edif_constr_turistica_p ON UPDATE NO ACTION ON DELETE NO ACTION; ALTER TABLE edgv.edf_edif_constr_turistica_p - ADD CONSTRAINT edf_edif_constr_turistica_p_turistica_check - CHECK (turistica = ANY(ARRAY[1 :: SMALLINT, 9999 :: SMALLINT])); + ADD CONSTRAINT edf_edif_constr_turistica_p_turistica_check + CHECK (turistica = ANY(ARRAY[1 :: SMALLINT, 9999 :: SMALLINT])); ALTER TABLE edgv.edf_edif_constr_turistica_p ALTER COLUMN turistica SET DEFAULT 9999; ALTER TABLE edgv.edf_edif_constr_turistica_p @@ -4934,8 +4934,8 @@ ALTER TABLE edgv.edf_edif_constr_turistica_a ON UPDATE NO ACTION ON DELETE NO ACTION; ALTER TABLE edgv.edf_edif_constr_turistica_a - ADD CONSTRAINT edf_edif_constr_turistica_a_turistica_check - CHECK (turistica = ANY(ARRAY[1 :: SMALLINT, 9999 :: SMALLINT])); + ADD CONSTRAINT edf_edif_constr_turistica_a_turistica_check + CHECK (turistica = ANY(ARRAY[1 :: SMALLINT, 9999 :: SMALLINT])); ALTER TABLE edgv.edf_edif_constr_turistica_a ALTER COLUMN turistica SET DEFAULT 9999; ALTER TABLE edgv.edf_edif_constr_turistica_a @@ -6704,8 +6704,8 @@ ALTER TABLE edgv.edf_posto_guarda_municipal_p ON UPDATE NO ACTION ON DELETE NO ACTION; ALTER TABLE edgv.edf_posto_guarda_municipal_p - ADD CONSTRAINT edf_posto_guarda_municipal_p_tipousoedif_check - CHECK (tipousoedif = ANY(ARRAY[5 :: SMALLINT, 9999 :: SMALLINT])); + ADD CONSTRAINT edf_posto_guarda_municipal_p_tipousoedif_check + CHECK (tipousoedif = ANY(ARRAY[5 :: SMALLINT, 9999 :: SMALLINT])); ALTER TABLE edgv.edf_posto_guarda_municipal_p ALTER COLUMN tipousoedif SET DEFAULT 9999; ALTER TABLE edgv.edf_posto_guarda_municipal_p @@ -6714,8 +6714,8 @@ ALTER TABLE edgv.edf_posto_guarda_municipal_p ON UPDATE NO ACTION ON DELETE NO ACTION; ALTER TABLE edgv.edf_posto_guarda_municipal_p - ADD CONSTRAINT edf_posto_guarda_municipal_p_jurisdicao_check - CHECK (jurisdicao = ANY(ARRAY[3 :: SMALLINT, 9999 :: SMALLINT])); + ADD CONSTRAINT edf_posto_guarda_municipal_p_jurisdicao_check + CHECK (jurisdicao = ANY(ARRAY[3 :: SMALLINT, 9999 :: SMALLINT])); ALTER TABLE edgv.edf_posto_guarda_municipal_p ALTER COLUMN jurisdicao SET DEFAULT 9999; ALTER TABLE edgv.edf_posto_guarda_municipal_p @@ -6724,8 +6724,8 @@ ALTER TABLE edgv.edf_posto_guarda_municipal_p ON UPDATE NO ACTION ON DELETE NO ACTION; ALTER TABLE edgv.edf_posto_guarda_municipal_p - ADD CONSTRAINT edf_posto_guarda_municipal_p_tipoedifpubcivil_check - CHECK (tipoedifpubcivil = ANY(ARRAY[1 :: SMALLINT, 9999 :: SMALLINT])); + ADD CONSTRAINT edf_posto_guarda_municipal_p_tipoedifpubcivil_check + CHECK (tipoedifpubcivil = ANY(ARRAY[1 :: SMALLINT, 9999 :: SMALLINT])); ALTER TABLE edgv.edf_posto_guarda_municipal_p ALTER COLUMN tipoedifpubcivil SET DEFAULT 9999; ALTER TABLE edgv.edf_posto_guarda_municipal_p @@ -6830,8 +6830,8 @@ ALTER TABLE edgv.edf_posto_guarda_municipal_a ON UPDATE NO ACTION ON DELETE NO ACTION; ALTER TABLE edgv.edf_posto_guarda_municipal_a - ADD CONSTRAINT edf_posto_guarda_municipal_a_tipousoedif_check - CHECK (tipousoedif = ANY(ARRAY[5 :: SMALLINT, 9999 :: SMALLINT])); + ADD CONSTRAINT edf_posto_guarda_municipal_a_tipousoedif_check + CHECK (tipousoedif = ANY(ARRAY[5 :: SMALLINT, 9999 :: SMALLINT])); ALTER TABLE edgv.edf_posto_guarda_municipal_a ALTER COLUMN tipousoedif SET DEFAULT 9999; ALTER TABLE edgv.edf_posto_guarda_municipal_a @@ -6840,8 +6840,8 @@ ALTER TABLE edgv.edf_posto_guarda_municipal_a ON UPDATE NO ACTION ON DELETE NO ACTION; ALTER TABLE edgv.edf_posto_guarda_municipal_a - ADD CONSTRAINT edf_posto_guarda_municipal_a_jurisdicao_check - CHECK (jurisdicao = ANY(ARRAY[3 :: SMALLINT, 9999 :: SMALLINT])); + ADD CONSTRAINT edf_posto_guarda_municipal_a_jurisdicao_check + CHECK (jurisdicao = ANY(ARRAY[3 :: SMALLINT, 9999 :: SMALLINT])); ALTER TABLE edgv.edf_posto_guarda_municipal_a ALTER COLUMN jurisdicao SET DEFAULT 9999; ALTER TABLE edgv.edf_posto_guarda_municipal_a @@ -6850,8 +6850,8 @@ ALTER TABLE edgv.edf_posto_guarda_municipal_a ON UPDATE NO ACTION ON DELETE NO ACTION; ALTER TABLE edgv.edf_posto_guarda_municipal_a - ADD CONSTRAINT edf_posto_guarda_municipal_a_tipoedifpubcivil_check - CHECK (tipoedifpubcivil = ANY(ARRAY[1 :: SMALLINT, 9999 :: SMALLINT])); + ADD CONSTRAINT edf_posto_guarda_municipal_a_tipoedifpubcivil_check + CHECK (tipoedifpubcivil = ANY(ARRAY[1 :: SMALLINT, 9999 :: SMALLINT])); ALTER TABLE edgv.edf_posto_guarda_municipal_a ALTER COLUMN tipoedifpubcivil SET DEFAULT 9999; ALTER TABLE edgv.edf_posto_guarda_municipal_a @@ -7174,8 +7174,8 @@ ALTER TABLE edgv.edf_posto_fiscal_p ON UPDATE NO ACTION ON DELETE NO ACTION; ALTER TABLE edgv.edf_posto_fiscal_p - ADD CONSTRAINT edf_posto_fiscal_p_tipoedifpubcivil_check - CHECK (tipoedifpubcivil = ANY(ARRAY[99 :: SMALLINT, 9999 :: SMALLINT])); + ADD CONSTRAINT edf_posto_fiscal_p_tipoedifpubcivil_check + CHECK (tipoedifpubcivil = ANY(ARRAY[99 :: SMALLINT, 9999 :: SMALLINT])); ALTER TABLE edgv.edf_posto_fiscal_p ALTER COLUMN tipoedifpubcivil SET DEFAULT 9999; ALTER TABLE edgv.edf_posto_fiscal_p @@ -7303,8 +7303,8 @@ ALTER TABLE edgv.edf_posto_fiscal_a ON UPDATE NO ACTION ON DELETE NO ACTION; ALTER TABLE edgv.edf_posto_fiscal_a - ADD CONSTRAINT edf_posto_fiscal_a_tipoedifpubcivil_check - CHECK (tipoedifpubcivil = ANY(ARRAY[99 :: SMALLINT, 9999 :: SMALLINT])); + ADD CONSTRAINT edf_posto_fiscal_a_tipoedifpubcivil_check + CHECK (tipoedifpubcivil = ANY(ARRAY[99 :: SMALLINT, 9999 :: SMALLINT])); ALTER TABLE edgv.edf_posto_fiscal_a ALTER COLUMN tipoedifpubcivil SET DEFAULT 9999; ALTER TABLE edgv.edf_posto_fiscal_a @@ -8209,8 +8209,8 @@ ALTER TABLE edgv.edf_posto_combustivel_p ON UPDATE NO ACTION ON DELETE NO ACTION; ALTER TABLE edgv.edf_posto_combustivel_p - ADD CONSTRAINT edf_posto_combustivel_p_tipoedifcomercserv_check - CHECK (tipoedifcomercserv = ANY(ARRAY[19 :: SMALLINT, 9999 :: SMALLINT])); + ADD CONSTRAINT edf_posto_combustivel_p_tipoedifcomercserv_check + CHECK (tipoedifcomercserv = ANY(ARRAY[19 :: SMALLINT, 9999 :: SMALLINT])); ALTER TABLE edgv.edf_posto_combustivel_p ALTER COLUMN tipoedifcomercserv SET DEFAULT 9999; ALTER TABLE edgv.edf_posto_combustivel_p @@ -8321,8 +8321,8 @@ ALTER TABLE edgv.edf_posto_combustivel_a ON UPDATE NO ACTION ON DELETE NO ACTION; ALTER TABLE edgv.edf_posto_combustivel_a - ADD CONSTRAINT edf_posto_combustivel_a_tipoedifcomercserv_check - CHECK (tipoedifcomercserv = ANY(ARRAY[19 :: SMALLINT, 9999 :: SMALLINT])); + ADD CONSTRAINT edf_posto_combustivel_a_tipoedifcomercserv_check + CHECK (tipoedifcomercserv = ANY(ARRAY[19 :: SMALLINT, 9999 :: SMALLINT])); ALTER TABLE edgv.edf_posto_combustivel_a ALTER COLUMN tipoedifcomercserv SET DEFAULT 9999; ALTER TABLE edgv.edf_posto_combustivel_a @@ -8434,8 +8434,8 @@ ALTER TABLE edgv.edf_posto_policia_militar_p ON UPDATE NO ACTION ON DELETE NO ACTION; ALTER TABLE edgv.edf_posto_policia_militar_p - ADD CONSTRAINT edf_posto_policia_militar_p_tipousoedif_check - CHECK (tipousoedif = ANY(ARRAY[6 :: SMALLINT, 9999 :: SMALLINT])); + ADD CONSTRAINT edf_posto_policia_militar_p_tipousoedif_check + CHECK (tipousoedif = ANY(ARRAY[6 :: SMALLINT, 9999 :: SMALLINT])); ALTER TABLE edgv.edf_posto_policia_militar_p ALTER COLUMN tipousoedif SET DEFAULT 9999; ALTER TABLE edgv.edf_posto_policia_militar_p @@ -8444,8 +8444,8 @@ ALTER TABLE edgv.edf_posto_policia_militar_p ON UPDATE NO ACTION ON DELETE NO ACTION; ALTER TABLE edgv.edf_posto_policia_militar_p - ADD CONSTRAINT edf_posto_policia_militar_p_jurisdicao_check - CHECK (jurisdicao = ANY(ARRAY[2 :: SMALLINT, 9999 :: SMALLINT])); + ADD CONSTRAINT edf_posto_policia_militar_p_jurisdicao_check + CHECK (jurisdicao = ANY(ARRAY[2 :: SMALLINT, 9999 :: SMALLINT])); ALTER TABLE edgv.edf_posto_policia_militar_p ALTER COLUMN jurisdicao SET DEFAULT 9999; ALTER TABLE edgv.edf_posto_policia_militar_p @@ -8454,8 +8454,8 @@ ALTER TABLE edgv.edf_posto_policia_militar_p ON UPDATE NO ACTION ON DELETE NO ACTION; ALTER TABLE edgv.edf_posto_policia_militar_p - ADD CONSTRAINT edf_posto_policia_militar_p_tipoinstalmilitar_check - CHECK (tipoinstalmilitar = ANY(ARRAY[22 :: SMALLINT, 23 :: SMALLINT, 9999 :: SMALLINT])); + ADD CONSTRAINT edf_posto_policia_militar_p_tipoinstalmilitar_check + CHECK (tipoinstalmilitar = ANY(ARRAY[22 :: SMALLINT, 23 :: SMALLINT, 9999 :: SMALLINT])); ALTER TABLE edgv.edf_posto_policia_militar_p ALTER COLUMN tipoinstalmilitar SET DEFAULT 9999; ALTER TABLE edgv.edf_posto_policia_militar_p @@ -8560,8 +8560,8 @@ ALTER TABLE edgv.edf_posto_policia_militar_a ON UPDATE NO ACTION ON DELETE NO ACTION; ALTER TABLE edgv.edf_posto_policia_militar_a - ADD CONSTRAINT edf_posto_policia_militar_a_tipousoedif_check - CHECK (tipousoedif = ANY(ARRAY[6 :: SMALLINT, 9999 :: SMALLINT])); + ADD CONSTRAINT edf_posto_policia_militar_a_tipousoedif_check + CHECK (tipousoedif = ANY(ARRAY[6 :: SMALLINT, 9999 :: SMALLINT])); ALTER TABLE edgv.edf_posto_policia_militar_a ALTER COLUMN tipousoedif SET DEFAULT 9999; ALTER TABLE edgv.edf_posto_policia_militar_a @@ -8570,8 +8570,8 @@ ALTER TABLE edgv.edf_posto_policia_militar_a ON UPDATE NO ACTION ON DELETE NO ACTION; ALTER TABLE edgv.edf_posto_policia_militar_a - ADD CONSTRAINT edf_posto_policia_militar_a_jurisdicao_check - CHECK (jurisdicao = ANY(ARRAY[2 :: SMALLINT, 9999 :: SMALLINT])); + ADD CONSTRAINT edf_posto_policia_militar_a_jurisdicao_check + CHECK (jurisdicao = ANY(ARRAY[2 :: SMALLINT, 9999 :: SMALLINT])); ALTER TABLE edgv.edf_posto_policia_militar_a ALTER COLUMN jurisdicao SET DEFAULT 9999; ALTER TABLE edgv.edf_posto_policia_militar_a @@ -8580,8 +8580,8 @@ ALTER TABLE edgv.edf_posto_policia_militar_a ON UPDATE NO ACTION ON DELETE NO ACTION; ALTER TABLE edgv.edf_posto_policia_militar_a - ADD CONSTRAINT edf_posto_policia_militar_a_tipoinstalmilitar_check - CHECK (tipoinstalmilitar = ANY(ARRAY[22 :: SMALLINT, 23 :: SMALLINT, 9999 :: SMALLINT])); + ADD CONSTRAINT edf_posto_policia_militar_a_tipoinstalmilitar_check + CHECK (tipoinstalmilitar = ANY(ARRAY[22 :: SMALLINT, 23 :: SMALLINT, 9999 :: SMALLINT])); ALTER TABLE edgv.edf_posto_policia_militar_a ALTER COLUMN tipoinstalmilitar SET DEFAULT 9999; ALTER TABLE edgv.edf_posto_policia_militar_a @@ -10170,8 +10170,8 @@ ALTER TABLE edgv.edf_posto_policia_rod_federal_p ON UPDATE NO ACTION ON DELETE NO ACTION; ALTER TABLE edgv.edf_posto_policia_rod_federal_p - ADD CONSTRAINT edf_posto_policia_rod_federal_p_tipousoedif_check - CHECK (tipousoedif = ANY(ARRAY[2 :: SMALLINT, 9999 :: SMALLINT])); + ADD CONSTRAINT edf_posto_policia_rod_federal_p_tipousoedif_check + CHECK (tipousoedif = ANY(ARRAY[2 :: SMALLINT, 9999 :: SMALLINT])); ALTER TABLE edgv.edf_posto_policia_rod_federal_p ALTER COLUMN tipousoedif SET DEFAULT 9999; ALTER TABLE edgv.edf_posto_policia_rod_federal_p @@ -10180,8 +10180,8 @@ ALTER TABLE edgv.edf_posto_policia_rod_federal_p ON UPDATE NO ACTION ON DELETE NO ACTION; ALTER TABLE edgv.edf_posto_policia_rod_federal_p - ADD CONSTRAINT edf_posto_policia_rod_federal_p_jurisdicao_check - CHECK (jurisdicao = ANY(ARRAY[1 :: SMALLINT, 9999 :: SMALLINT])); + ADD CONSTRAINT edf_posto_policia_rod_federal_p_jurisdicao_check + CHECK (jurisdicao = ANY(ARRAY[1 :: SMALLINT, 9999 :: SMALLINT])); ALTER TABLE edgv.edf_posto_policia_rod_federal_p ALTER COLUMN jurisdicao SET DEFAULT 9999; ALTER TABLE edgv.edf_posto_policia_rod_federal_p @@ -10190,8 +10190,8 @@ ALTER TABLE edgv.edf_posto_policia_rod_federal_p ON UPDATE NO ACTION ON DELETE NO ACTION; ALTER TABLE edgv.edf_posto_policia_rod_federal_p - ADD CONSTRAINT edf_posto_policia_rod_federal_p_tipoedifpubcivil_check - CHECK (tipoedifpubcivil = ANY(ARRAY[1 :: SMALLINT, 9999 :: SMALLINT])); + ADD CONSTRAINT edf_posto_policia_rod_federal_p_tipoedifpubcivil_check + CHECK (tipoedifpubcivil = ANY(ARRAY[1 :: SMALLINT, 9999 :: SMALLINT])); ALTER TABLE edgv.edf_posto_policia_rod_federal_p ALTER COLUMN tipoedifpubcivil SET DEFAULT 9999; ALTER TABLE edgv.edf_posto_policia_rod_federal_p @@ -10296,8 +10296,8 @@ ALTER TABLE edgv.edf_posto_policia_rod_federal_a ON UPDATE NO ACTION ON DELETE NO ACTION; ALTER TABLE edgv.edf_posto_policia_rod_federal_a - ADD CONSTRAINT edf_posto_policia_rod_federal_a_tipousoedif_check - CHECK (tipousoedif = ANY(ARRAY[2 :: SMALLINT, 9999 :: SMALLINT])); + ADD CONSTRAINT edf_posto_policia_rod_federal_a_tipousoedif_check + CHECK (tipousoedif = ANY(ARRAY[2 :: SMALLINT, 9999 :: SMALLINT])); ALTER TABLE edgv.edf_posto_policia_rod_federal_a ALTER COLUMN tipousoedif SET DEFAULT 9999; ALTER TABLE edgv.edf_posto_policia_rod_federal_a @@ -10306,8 +10306,8 @@ ALTER TABLE edgv.edf_posto_policia_rod_federal_a ON UPDATE NO ACTION ON DELETE NO ACTION; ALTER TABLE edgv.edf_posto_policia_rod_federal_a - ADD CONSTRAINT edf_posto_policia_rod_federal_a_jurisdicao_check - CHECK (jurisdicao = ANY(ARRAY[1 :: SMALLINT, 9999 :: SMALLINT])); + ADD CONSTRAINT edf_posto_policia_rod_federal_a_jurisdicao_check + CHECK (jurisdicao = ANY(ARRAY[1 :: SMALLINT, 9999 :: SMALLINT])); ALTER TABLE edgv.edf_posto_policia_rod_federal_a ALTER COLUMN jurisdicao SET DEFAULT 9999; ALTER TABLE edgv.edf_posto_policia_rod_federal_a @@ -10316,8 +10316,8 @@ ALTER TABLE edgv.edf_posto_policia_rod_federal_a ON UPDATE NO ACTION ON DELETE NO ACTION; ALTER TABLE edgv.edf_posto_policia_rod_federal_a - ADD CONSTRAINT edf_posto_policia_rod_federal_a_tipoedifpubcivil_check - CHECK (tipoedifpubcivil = ANY(ARRAY[1 :: SMALLINT, 9999 :: SMALLINT])); + ADD CONSTRAINT edf_posto_policia_rod_federal_a_tipoedifpubcivil_check + CHECK (tipoedifpubcivil = ANY(ARRAY[1 :: SMALLINT, 9999 :: SMALLINT])); ALTER TABLE edgv.edf_posto_policia_rod_federal_a ALTER COLUMN tipoedifpubcivil SET DEFAULT 9999; ALTER TABLE edgv.edf_posto_policia_rod_federal_a @@ -10436,8 +10436,8 @@ ALTER TABLE edgv.edf_edif_pub_civil_p ON UPDATE NO ACTION ON DELETE NO ACTION; ALTER TABLE edgv.edf_edif_pub_civil_p - ADD CONSTRAINT edf_edif_pub_civil_p_tipoedifpubcivil_check - CHECK (tipoedifpubcivil = ANY(ARRAY[0 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 4 :: SMALLINT, 5 :: SMALLINT, 6 :: SMALLINT, 7 :: SMALLINT, 8 :: SMALLINT, 9 :: SMALLINT, 10 :: SMALLINT, 12 :: SMALLINT, 13 :: SMALLINT, 14 :: SMALLINT, 15 :: SMALLINT, 16 :: SMALLINT, 22 :: SMALLINT, 99 :: SMALLINT, 9999 :: SMALLINT])); + ADD CONSTRAINT edf_edif_pub_civil_p_tipoedifpubcivil_check + CHECK (tipoedifpubcivil = ANY(ARRAY[0 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 4 :: SMALLINT, 5 :: SMALLINT, 6 :: SMALLINT, 7 :: SMALLINT, 8 :: SMALLINT, 9 :: SMALLINT, 10 :: SMALLINT, 12 :: SMALLINT, 13 :: SMALLINT, 14 :: SMALLINT, 15 :: SMALLINT, 16 :: SMALLINT, 22 :: SMALLINT, 99 :: SMALLINT, 9999 :: SMALLINT])); ALTER TABLE edgv.edf_edif_pub_civil_p ALTER COLUMN tipoedifpubcivil SET DEFAULT 9999; ALTER TABLE edgv.edf_edif_pub_civil_p @@ -10556,8 +10556,8 @@ ALTER TABLE edgv.edf_edif_pub_civil_a ON UPDATE NO ACTION ON DELETE NO ACTION; ALTER TABLE edgv.edf_edif_pub_civil_a - ADD CONSTRAINT edf_edif_pub_civil_a_tipoedifpubcivil_check - CHECK (tipoedifpubcivil = ANY(ARRAY[0 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 4 :: SMALLINT, 5 :: SMALLINT, 6 :: SMALLINT, 7 :: SMALLINT, 8 :: SMALLINT, 9 :: SMALLINT, 10 :: SMALLINT, 12 :: SMALLINT, 13 :: SMALLINT, 14 :: SMALLINT, 15 :: SMALLINT, 16 :: SMALLINT, 22 :: SMALLINT, 99 :: SMALLINT, 9999 :: SMALLINT])); + ADD CONSTRAINT edf_edif_pub_civil_a_tipoedifpubcivil_check + CHECK (tipoedifpubcivil = ANY(ARRAY[0 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 4 :: SMALLINT, 5 :: SMALLINT, 6 :: SMALLINT, 7 :: SMALLINT, 8 :: SMALLINT, 9 :: SMALLINT, 10 :: SMALLINT, 12 :: SMALLINT, 13 :: SMALLINT, 14 :: SMALLINT, 15 :: SMALLINT, 16 :: SMALLINT, 22 :: SMALLINT, 99 :: SMALLINT, 9999 :: SMALLINT])); ALTER TABLE edgv.edf_edif_pub_civil_a ALTER COLUMN tipoedifpubcivil SET DEFAULT 9999; ALTER TABLE edgv.edf_edif_pub_civil_a @@ -10864,8 +10864,8 @@ ALTER TABLE edgv.edf_edif_policia_p ON UPDATE NO ACTION ON DELETE NO ACTION; ALTER TABLE edgv.edf_edif_policia_p - ADD CONSTRAINT edf_edif_policia_p_tipousoedif_check - CHECK (tipousoedif = ANY(ARRAY[0 :: SMALLINT, 2 :: SMALLINT, 5 :: SMALLINT, 6 :: SMALLINT, 9999 :: SMALLINT])); + ADD CONSTRAINT edf_edif_policia_p_tipousoedif_check + CHECK (tipousoedif = ANY(ARRAY[0 :: SMALLINT, 2 :: SMALLINT, 5 :: SMALLINT, 6 :: SMALLINT, 9999 :: SMALLINT])); ALTER TABLE edgv.edf_edif_policia_p ALTER COLUMN tipousoedif SET DEFAULT 9999; ALTER TABLE edgv.edf_edif_policia_p @@ -10874,8 +10874,8 @@ ALTER TABLE edgv.edf_edif_policia_p ON UPDATE NO ACTION ON DELETE NO ACTION; ALTER TABLE edgv.edf_edif_policia_p - ADD CONSTRAINT edf_edif_policia_p_jurisdicao_check - CHECK (jurisdicao = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 9999 :: SMALLINT])); + ADD CONSTRAINT edf_edif_policia_p_jurisdicao_check + CHECK (jurisdicao = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 9999 :: SMALLINT])); ALTER TABLE edgv.edf_edif_policia_p ALTER COLUMN jurisdicao SET DEFAULT 9999; ALTER TABLE edgv.edf_edif_policia_p @@ -10884,8 +10884,8 @@ ALTER TABLE edgv.edf_edif_policia_p ON UPDATE NO ACTION ON DELETE NO ACTION; ALTER TABLE edgv.edf_edif_policia_p - ADD CONSTRAINT edf_edif_policia_p_tipoedifpubcivil_check - CHECK (tipoedifpubcivil = ANY(ARRAY[1 :: SMALLINT, 2 :: SMALLINT, 11 :: SMALLINT, 9999 :: SMALLINT])); + ADD CONSTRAINT edf_edif_policia_p_tipoedifpubcivil_check + CHECK (tipoedifpubcivil = ANY(ARRAY[1 :: SMALLINT, 2 :: SMALLINT, 11 :: SMALLINT, 9999 :: SMALLINT])); ALTER TABLE edgv.edf_edif_policia_p ALTER COLUMN tipoedifpubcivil SET DEFAULT 9999; ALTER TABLE edgv.edf_edif_policia_p @@ -10990,8 +10990,8 @@ ALTER TABLE edgv.edf_edif_policia_a ON UPDATE NO ACTION ON DELETE NO ACTION; ALTER TABLE edgv.edf_edif_policia_a - ADD CONSTRAINT edf_edif_policia_a_tipousoedif_check - CHECK (tipousoedif = ANY(ARRAY[0 :: SMALLINT, 2 :: SMALLINT, 5 :: SMALLINT, 6 :: SMALLINT, 9999 :: SMALLINT])); + ADD CONSTRAINT edf_edif_policia_a_tipousoedif_check + CHECK (tipousoedif = ANY(ARRAY[0 :: SMALLINT, 2 :: SMALLINT, 5 :: SMALLINT, 6 :: SMALLINT, 9999 :: SMALLINT])); ALTER TABLE edgv.edf_edif_policia_a ALTER COLUMN tipousoedif SET DEFAULT 9999; ALTER TABLE edgv.edf_edif_policia_a @@ -11000,8 +11000,8 @@ ALTER TABLE edgv.edf_edif_policia_a ON UPDATE NO ACTION ON DELETE NO ACTION; ALTER TABLE edgv.edf_edif_policia_a - ADD CONSTRAINT edf_edif_policia_a_jurisdicao_check - CHECK (jurisdicao = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 9999 :: SMALLINT])); + ADD CONSTRAINT edf_edif_policia_a_jurisdicao_check + CHECK (jurisdicao = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 9999 :: SMALLINT])); ALTER TABLE edgv.edf_edif_policia_a ALTER COLUMN jurisdicao SET DEFAULT 9999; ALTER TABLE edgv.edf_edif_policia_a @@ -11010,8 +11010,8 @@ ALTER TABLE edgv.edf_edif_policia_a ON UPDATE NO ACTION ON DELETE NO ACTION; ALTER TABLE edgv.edf_edif_policia_a - ADD CONSTRAINT edf_edif_policia_a_tipoedifpubcivil_check - CHECK (tipoedifpubcivil = ANY(ARRAY[1 :: SMALLINT, 2 :: SMALLINT, 11 :: SMALLINT, 9999 :: SMALLINT])); + ADD CONSTRAINT edf_edif_policia_a_tipoedifpubcivil_check + CHECK (tipoedifpubcivil = ANY(ARRAY[1 :: SMALLINT, 2 :: SMALLINT, 11 :: SMALLINT, 9999 :: SMALLINT])); ALTER TABLE edgv.edf_edif_policia_a ALTER COLUMN tipoedifpubcivil SET DEFAULT 9999; ALTER TABLE edgv.edf_edif_policia_a @@ -11116,8 +11116,8 @@ ALTER TABLE edgv.edf_edif_pub_militar_p ON UPDATE NO ACTION ON DELETE NO ACTION; ALTER TABLE edgv.edf_edif_pub_militar_p - ADD CONSTRAINT edf_edif_pub_militar_p_tipousoedif_check - CHECK (tipousoedif = ANY(ARRAY[0 :: SMALLINT, 2 :: SMALLINT, 6 :: SMALLINT, 9999 :: SMALLINT])); + ADD CONSTRAINT edf_edif_pub_militar_p_tipousoedif_check + CHECK (tipousoedif = ANY(ARRAY[0 :: SMALLINT, 2 :: SMALLINT, 6 :: SMALLINT, 9999 :: SMALLINT])); ALTER TABLE edgv.edf_edif_pub_militar_p ALTER COLUMN tipousoedif SET DEFAULT 9999; ALTER TABLE edgv.edf_edif_pub_militar_p @@ -11126,8 +11126,8 @@ ALTER TABLE edgv.edf_edif_pub_militar_p ON UPDATE NO ACTION ON DELETE NO ACTION; ALTER TABLE edgv.edf_edif_pub_militar_p - ADD CONSTRAINT edf_edif_pub_militar_p_jurisdicao_check - CHECK (jurisdicao = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 4 :: SMALLINT, 9999 :: SMALLINT])); + ADD CONSTRAINT edf_edif_pub_militar_p_jurisdicao_check + CHECK (jurisdicao = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 4 :: SMALLINT, 9999 :: SMALLINT])); ALTER TABLE edgv.edf_edif_pub_militar_p ALTER COLUMN jurisdicao SET DEFAULT 9999; ALTER TABLE edgv.edf_edif_pub_militar_p @@ -11239,8 +11239,8 @@ ALTER TABLE edgv.edf_edif_pub_militar_a ON UPDATE NO ACTION ON DELETE NO ACTION; ALTER TABLE edgv.edf_edif_pub_militar_a - ADD CONSTRAINT edf_edif_pub_militar_a_tipousoedif_check - CHECK (tipousoedif = ANY(ARRAY[0 :: SMALLINT, 2 :: SMALLINT, 6 :: SMALLINT, 9999 :: SMALLINT])); + ADD CONSTRAINT edf_edif_pub_militar_a_tipousoedif_check + CHECK (tipousoedif = ANY(ARRAY[0 :: SMALLINT, 2 :: SMALLINT, 6 :: SMALLINT, 9999 :: SMALLINT])); ALTER TABLE edgv.edf_edif_pub_militar_a ALTER COLUMN tipousoedif SET DEFAULT 9999; ALTER TABLE edgv.edf_edif_pub_militar_a @@ -11249,8 +11249,8 @@ ALTER TABLE edgv.edf_edif_pub_militar_a ON UPDATE NO ACTION ON DELETE NO ACTION; ALTER TABLE edgv.edf_edif_pub_militar_a - ADD CONSTRAINT edf_edif_pub_militar_a_jurisdicao_check - CHECK (jurisdicao = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 4 :: SMALLINT, 9999 :: SMALLINT])); + ADD CONSTRAINT edf_edif_pub_militar_a_jurisdicao_check + CHECK (jurisdicao = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 4 :: SMALLINT, 9999 :: SMALLINT])); ALTER TABLE edgv.edf_edif_pub_militar_a ALTER COLUMN jurisdicao SET DEFAULT 9999; ALTER TABLE edgv.edf_edif_pub_militar_a @@ -12096,8 +12096,8 @@ ALTER TABLE edgv.emu_poste_sinalizacao_p ON UPDATE NO ACTION ON DELETE NO ACTION; ALTER TABLE edgv.emu_poste_sinalizacao_p - ADD CONSTRAINT emu_poste_sinalizacao_p_tipoposte_check - CHECK (tipoposte = ANY(ARRAY[5 :: SMALLINT, 9999 :: SMALLINT])); + ADD CONSTRAINT emu_poste_sinalizacao_p_tipoposte_check + CHECK (tipoposte = ANY(ARRAY[5 :: SMALLINT, 9999 :: SMALLINT])); ALTER TABLE edgv.emu_poste_sinalizacao_p ALTER COLUMN tipoposte SET DEFAULT 9999; CREATE TABLE edgv.enc_casa_de_forca_p( @@ -12248,8 +12248,8 @@ ALTER TABLE edgv.enc_est_gerad_energia_eletrica_p ON UPDATE NO ACTION ON DELETE NO ACTION; ALTER TABLE edgv.enc_est_gerad_energia_eletrica_p - ADD CONSTRAINT enc_est_gerad_energia_eletrica_p_tipoestgerad_check - CHECK (tipoestgerad = ANY(ARRAY[0 :: SMALLINT, 6 :: SMALLINT, 7 :: SMALLINT, 99 :: SMALLINT, 9999 :: SMALLINT])); + ADD CONSTRAINT enc_est_gerad_energia_eletrica_p_tipoestgerad_check + CHECK (tipoestgerad = ANY(ARRAY[0 :: SMALLINT, 6 :: SMALLINT, 7 :: SMALLINT, 99 :: SMALLINT, 9999 :: SMALLINT])); ALTER TABLE edgv.enc_est_gerad_energia_eletrica_p ALTER COLUMN tipoestgerad SET DEFAULT 9999; ALTER TABLE edgv.enc_est_gerad_energia_eletrica_p @@ -12289,8 +12289,8 @@ ALTER TABLE edgv.enc_est_gerad_energia_eletrica_a ON UPDATE NO ACTION ON DELETE NO ACTION; ALTER TABLE edgv.enc_est_gerad_energia_eletrica_a - ADD CONSTRAINT enc_est_gerad_energia_eletrica_a_tipoestgerad_check - CHECK (tipoestgerad = ANY(ARRAY[0 :: SMALLINT, 6 :: SMALLINT, 7 :: SMALLINT, 99 :: SMALLINT, 9999 :: SMALLINT])); + ADD CONSTRAINT enc_est_gerad_energia_eletrica_a_tipoestgerad_check + CHECK (tipoestgerad = ANY(ARRAY[0 :: SMALLINT, 6 :: SMALLINT, 7 :: SMALLINT, 99 :: SMALLINT, 9999 :: SMALLINT])); ALTER TABLE edgv.enc_est_gerad_energia_eletrica_a ALTER COLUMN tipoestgerad SET DEFAULT 9999; ALTER TABLE edgv.enc_est_gerad_energia_eletrica_a @@ -12330,8 +12330,8 @@ ALTER TABLE edgv.enc_central_geradora_eolica_p ON UPDATE NO ACTION ON DELETE NO ACTION; ALTER TABLE edgv.enc_central_geradora_eolica_p - ADD CONSTRAINT enc_central_geradora_eolica_p_tipoestgerad_check - CHECK (tipoestgerad = ANY(ARRAY[5 :: SMALLINT, 9999 :: SMALLINT])); + ADD CONSTRAINT enc_central_geradora_eolica_p_tipoestgerad_check + CHECK (tipoestgerad = ANY(ARRAY[5 :: SMALLINT, 9999 :: SMALLINT])); ALTER TABLE edgv.enc_central_geradora_eolica_p ALTER COLUMN tipoestgerad SET DEFAULT 9999; ALTER TABLE edgv.enc_central_geradora_eolica_p @@ -12371,8 +12371,8 @@ ALTER TABLE edgv.enc_central_geradora_eolica_a ON UPDATE NO ACTION ON DELETE NO ACTION; ALTER TABLE edgv.enc_central_geradora_eolica_a - ADD CONSTRAINT enc_central_geradora_eolica_a_tipoestgerad_check - CHECK (tipoestgerad = ANY(ARRAY[5 :: SMALLINT, 9999 :: SMALLINT])); + ADD CONSTRAINT enc_central_geradora_eolica_a_tipoestgerad_check + CHECK (tipoestgerad = ANY(ARRAY[5 :: SMALLINT, 9999 :: SMALLINT])); ALTER TABLE edgv.enc_central_geradora_eolica_a ALTER COLUMN tipoestgerad SET DEFAULT 9999; ALTER TABLE edgv.enc_central_geradora_eolica_a @@ -12425,8 +12425,8 @@ ALTER TABLE edgv.enc_hidreletrica_l ON UPDATE NO ACTION ON DELETE NO ACTION; ALTER TABLE edgv.enc_hidreletrica_l - ADD CONSTRAINT enc_hidreletrica_l_tipoestgerad_check - CHECK (tipoestgerad = ANY(ARRAY[8 :: SMALLINT, 9999 :: SMALLINT])); + ADD CONSTRAINT enc_hidreletrica_l_tipoestgerad_check + CHECK (tipoestgerad = ANY(ARRAY[8 :: SMALLINT, 9999 :: SMALLINT])); ALTER TABLE edgv.enc_hidreletrica_l ALTER COLUMN tipoestgerad SET DEFAULT 9999; ALTER TABLE edgv.enc_hidreletrica_l @@ -12474,8 +12474,8 @@ ALTER TABLE edgv.enc_hidreletrica_p ON UPDATE NO ACTION ON DELETE NO ACTION; ALTER TABLE edgv.enc_hidreletrica_p - ADD CONSTRAINT enc_hidreletrica_p_tipoestgerad_check - CHECK (tipoestgerad = ANY(ARRAY[8 :: SMALLINT, 9999 :: SMALLINT])); + ADD CONSTRAINT enc_hidreletrica_p_tipoestgerad_check + CHECK (tipoestgerad = ANY(ARRAY[8 :: SMALLINT, 9999 :: SMALLINT])); ALTER TABLE edgv.enc_hidreletrica_p ALTER COLUMN tipoestgerad SET DEFAULT 9999; ALTER TABLE edgv.enc_hidreletrica_p @@ -12523,8 +12523,8 @@ ALTER TABLE edgv.enc_hidreletrica_a ON UPDATE NO ACTION ON DELETE NO ACTION; ALTER TABLE edgv.enc_hidreletrica_a - ADD CONSTRAINT enc_hidreletrica_a_tipoestgerad_check - CHECK (tipoestgerad = ANY(ARRAY[8 :: SMALLINT, 9999 :: SMALLINT])); + ADD CONSTRAINT enc_hidreletrica_a_tipoestgerad_check + CHECK (tipoestgerad = ANY(ARRAY[8 :: SMALLINT, 9999 :: SMALLINT])); ALTER TABLE edgv.enc_hidreletrica_a ALTER COLUMN tipoestgerad SET DEFAULT 9999; ALTER TABLE edgv.enc_hidreletrica_a @@ -12592,8 +12592,8 @@ ALTER TABLE edgv.enc_termeletrica_p ON UPDATE NO ACTION ON DELETE NO ACTION; ALTER TABLE edgv.enc_termeletrica_p - ADD CONSTRAINT enc_termeletrica_p_tipoestgerad_check - CHECK (tipoestgerad = ANY(ARRAY[9 :: SMALLINT, 9999 :: SMALLINT])); + ADD CONSTRAINT enc_termeletrica_p_tipoestgerad_check + CHECK (tipoestgerad = ANY(ARRAY[9 :: SMALLINT, 9999 :: SMALLINT])); ALTER TABLE edgv.enc_termeletrica_p ALTER COLUMN tipoestgerad SET DEFAULT 9999; ALTER TABLE edgv.enc_termeletrica_p @@ -12641,8 +12641,8 @@ ALTER TABLE edgv.enc_termeletrica_a ON UPDATE NO ACTION ON DELETE NO ACTION; ALTER TABLE edgv.enc_termeletrica_a - ADD CONSTRAINT enc_termeletrica_a_tipoestgerad_check - CHECK (tipoestgerad = ANY(ARRAY[9 :: SMALLINT, 9999 :: SMALLINT])); + ADD CONSTRAINT enc_termeletrica_a_tipoestgerad_check + CHECK (tipoestgerad = ANY(ARRAY[9 :: SMALLINT, 9999 :: SMALLINT])); ALTER TABLE edgv.enc_termeletrica_a ALTER COLUMN tipoestgerad SET DEFAULT 9999; ALTER TABLE edgv.enc_termeletrica_a @@ -13418,8 +13418,8 @@ ALTER TABLE edgv.hdv_fundeadouro_p ON UPDATE NO ACTION ON DELETE NO ACTION; ALTER TABLE edgv.hdv_fundeadouro_p - ADD CONSTRAINT hdv_fundeadouro_p_administracao_check - CHECK (administracao = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 7 :: SMALLINT, 15 :: SMALLINT, 9999 :: SMALLINT])); + ADD CONSTRAINT hdv_fundeadouro_p_administracao_check + CHECK (administracao = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 7 :: SMALLINT, 15 :: SMALLINT, 9999 :: SMALLINT])); ALTER TABLE edgv.hdv_fundeadouro_p ALTER COLUMN administracao SET DEFAULT 9999; CREATE TABLE edgv.hdv_fundeadouro_a( @@ -13449,8 +13449,8 @@ ALTER TABLE edgv.hdv_fundeadouro_a ON UPDATE NO ACTION ON DELETE NO ACTION; ALTER TABLE edgv.hdv_fundeadouro_a - ADD CONSTRAINT hdv_fundeadouro_a_administracao_check - CHECK (administracao = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 7 :: SMALLINT, 15 :: SMALLINT, 9999 :: SMALLINT])); + ADD CONSTRAINT hdv_fundeadouro_a_administracao_check + CHECK (administracao = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 7 :: SMALLINT, 15 :: SMALLINT, 9999 :: SMALLINT])); ALTER TABLE edgv.hdv_fundeadouro_a ALTER COLUMN administracao SET DEFAULT 9999; CREATE TABLE edgv.hdv_trecho_hidroviario_l( @@ -13539,8 +13539,8 @@ ALTER TABLE edgv.hid_ilha_p ON UPDATE NO ACTION ON DELETE NO ACTION; ALTER TABLE edgv.hid_ilha_p - ADD CONSTRAINT hid_ilha_p_tipoelemnat_check - CHECK (tipoelemnat = ANY(ARRAY[21 :: SMALLINT, 9999 :: SMALLINT])); + ADD CONSTRAINT hid_ilha_p_tipoelemnat_check + CHECK (tipoelemnat = ANY(ARRAY[21 :: SMALLINT, 9999 :: SMALLINT])); ALTER TABLE edgv.hid_ilha_p ALTER COLUMN tipoelemnat SET DEFAULT 9999; ALTER TABLE edgv.hid_ilha_p @@ -13570,8 +13570,8 @@ ALTER TABLE edgv.hid_ilha_a ON UPDATE NO ACTION ON DELETE NO ACTION; ALTER TABLE edgv.hid_ilha_a - ADD CONSTRAINT hid_ilha_a_tipoelemnat_check - CHECK (tipoelemnat = ANY(ARRAY[21 :: SMALLINT, 9999 :: SMALLINT])); + ADD CONSTRAINT hid_ilha_a_tipoelemnat_check + CHECK (tipoelemnat = ANY(ARRAY[21 :: SMALLINT, 9999 :: SMALLINT])); ALTER TABLE edgv.hid_ilha_a ALTER COLUMN tipoelemnat SET DEFAULT 9999; ALTER TABLE edgv.hid_ilha_a @@ -13605,8 +13605,8 @@ ALTER TABLE edgv.hid_vala_l ON UPDATE NO ACTION ON DELETE NO ACTION; ALTER TABLE edgv.hid_vala_l - ADD CONSTRAINT hid_vala_l_tipoalterantrop_check - CHECK (tipoalterantrop = ANY(ARRAY[31 :: SMALLINT, 9999 :: SMALLINT])); + ADD CONSTRAINT hid_vala_l_tipoalterantrop_check + CHECK (tipoalterantrop = ANY(ARRAY[31 :: SMALLINT, 9999 :: SMALLINT])); ALTER TABLE edgv.hid_vala_l ALTER COLUMN tipoalterantrop SET DEFAULT 9999; ALTER TABLE edgv.hid_vala_l @@ -13643,8 +13643,8 @@ ALTER TABLE edgv.hid_vala_l ON UPDATE NO ACTION ON DELETE NO ACTION; ALTER TABLE edgv.hid_vala_l - ADD CONSTRAINT hid_vala_l_finalidade_check - CHECK (finalidade = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 4 :: SMALLINT, 9999 :: SMALLINT])); + ADD CONSTRAINT hid_vala_l_finalidade_check + CHECK (finalidade = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 4 :: SMALLINT, 9999 :: SMALLINT])); ALTER TABLE edgv.hid_vala_l ALTER COLUMN finalidade SET DEFAULT 9999; CREATE TABLE edgv.hid_vala_a( @@ -13671,8 +13671,8 @@ ALTER TABLE edgv.hid_vala_a ON UPDATE NO ACTION ON DELETE NO ACTION; ALTER TABLE edgv.hid_vala_a - ADD CONSTRAINT hid_vala_a_tipoalterantrop_check - CHECK (tipoalterantrop = ANY(ARRAY[31 :: SMALLINT, 9999 :: SMALLINT])); + ADD CONSTRAINT hid_vala_a_tipoalterantrop_check + CHECK (tipoalterantrop = ANY(ARRAY[31 :: SMALLINT, 9999 :: SMALLINT])); ALTER TABLE edgv.hid_vala_a ALTER COLUMN tipoalterantrop SET DEFAULT 9999; ALTER TABLE edgv.hid_vala_a @@ -13709,8 +13709,8 @@ ALTER TABLE edgv.hid_vala_a ON UPDATE NO ACTION ON DELETE NO ACTION; ALTER TABLE edgv.hid_vala_a - ADD CONSTRAINT hid_vala_a_finalidade_check - CHECK (finalidade = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 4 :: SMALLINT, 9999 :: SMALLINT])); + ADD CONSTRAINT hid_vala_a_finalidade_check + CHECK (finalidade = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 4 :: SMALLINT, 9999 :: SMALLINT])); ALTER TABLE edgv.hid_vala_a ALTER COLUMN finalidade SET DEFAULT 9999; CREATE TABLE edgv.hid_dique_l( @@ -13797,8 +13797,8 @@ ALTER TABLE edgv.hid_canal_l ON UPDATE NO ACTION ON DELETE NO ACTION; ALTER TABLE edgv.hid_canal_l - ADD CONSTRAINT hid_canal_l_tipoalterantrop_check - CHECK (tipoalterantrop = ANY(ARRAY[30 :: SMALLINT, 9999 :: SMALLINT])); + ADD CONSTRAINT hid_canal_l_tipoalterantrop_check + CHECK (tipoalterantrop = ANY(ARRAY[30 :: SMALLINT, 9999 :: SMALLINT])); ALTER TABLE edgv.hid_canal_l ALTER COLUMN tipoalterantrop SET DEFAULT 9999; ALTER TABLE edgv.hid_canal_l @@ -13835,8 +13835,8 @@ ALTER TABLE edgv.hid_canal_l ON UPDATE NO ACTION ON DELETE NO ACTION; ALTER TABLE edgv.hid_canal_l - ADD CONSTRAINT hid_canal_l_finalidade_check - CHECK (finalidade = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 4 :: SMALLINT, 9999 :: SMALLINT])); + ADD CONSTRAINT hid_canal_l_finalidade_check + CHECK (finalidade = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 4 :: SMALLINT, 9999 :: SMALLINT])); ALTER TABLE edgv.hid_canal_l ALTER COLUMN finalidade SET DEFAULT 9999; CREATE TABLE edgv.hid_canal_a( @@ -13863,8 +13863,8 @@ ALTER TABLE edgv.hid_canal_a ON UPDATE NO ACTION ON DELETE NO ACTION; ALTER TABLE edgv.hid_canal_a - ADD CONSTRAINT hid_canal_a_tipoalterantrop_check - CHECK (tipoalterantrop = ANY(ARRAY[30 :: SMALLINT, 9999 :: SMALLINT])); + ADD CONSTRAINT hid_canal_a_tipoalterantrop_check + CHECK (tipoalterantrop = ANY(ARRAY[30 :: SMALLINT, 9999 :: SMALLINT])); ALTER TABLE edgv.hid_canal_a ALTER COLUMN tipoalterantrop SET DEFAULT 9999; ALTER TABLE edgv.hid_canal_a @@ -13901,8 +13901,8 @@ ALTER TABLE edgv.hid_canal_a ON UPDATE NO ACTION ON DELETE NO ACTION; ALTER TABLE edgv.hid_canal_a - ADD CONSTRAINT hid_canal_a_finalidade_check - CHECK (finalidade = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 4 :: SMALLINT, 9999 :: SMALLINT])); + ADD CONSTRAINT hid_canal_a_finalidade_check + CHECK (finalidade = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 4 :: SMALLINT, 9999 :: SMALLINT])); ALTER TABLE edgv.hid_canal_a ALTER COLUMN finalidade SET DEFAULT 9999; CREATE TABLE edgv.hid_massa_dagua_a( @@ -14237,8 +14237,8 @@ ALTER TABLE edgv.hid_rocha_em_agua_p ON UPDATE NO ACTION ON DELETE NO ACTION; ALTER TABLE edgv.hid_rocha_em_agua_p - ADD CONSTRAINT hid_rocha_em_agua_p_tipoelemnat_check - CHECK (tipoelemnat = ANY(ARRAY[23 :: SMALLINT, 9999 :: SMALLINT])); + ADD CONSTRAINT hid_rocha_em_agua_p_tipoelemnat_check + CHECK (tipoelemnat = ANY(ARRAY[23 :: SMALLINT, 9999 :: SMALLINT])); ALTER TABLE edgv.hid_rocha_em_agua_p ALTER COLUMN tipoelemnat SET DEFAULT 9999; ALTER TABLE edgv.hid_rocha_em_agua_p @@ -14277,8 +14277,8 @@ ALTER TABLE edgv.hid_rocha_em_agua_a ON UPDATE NO ACTION ON DELETE NO ACTION; ALTER TABLE edgv.hid_rocha_em_agua_a - ADD CONSTRAINT hid_rocha_em_agua_a_tipoelemnat_check - CHECK (tipoelemnat = ANY(ARRAY[23 :: SMALLINT, 9999 :: SMALLINT])); + ADD CONSTRAINT hid_rocha_em_agua_a_tipoelemnat_check + CHECK (tipoelemnat = ANY(ARRAY[23 :: SMALLINT, 9999 :: SMALLINT])); ALTER TABLE edgv.hid_rocha_em_agua_a ALTER COLUMN tipoelemnat SET DEFAULT 9999; ALTER TABLE edgv.hid_rocha_em_agua_a @@ -14674,8 +14674,8 @@ ALTER TABLE edgv.laz_sitio_arqueologico_p ON UPDATE NO ACTION ON DELETE NO ACTION; ALTER TABLE edgv.laz_sitio_arqueologico_p - ADD CONSTRAINT laz_sitio_arqueologico_p_cultura_check - CHECK (cultura = ANY(ARRAY[1 :: SMALLINT, 9999 :: SMALLINT])); + ADD CONSTRAINT laz_sitio_arqueologico_p_cultura_check + CHECK (cultura = ANY(ARRAY[1 :: SMALLINT, 9999 :: SMALLINT])); ALTER TABLE edgv.laz_sitio_arqueologico_p ALTER COLUMN cultura SET DEFAULT 9999; CREATE TABLE edgv.laz_sitio_arqueologico_a( @@ -14705,8 +14705,8 @@ ALTER TABLE edgv.laz_sitio_arqueologico_a ON UPDATE NO ACTION ON DELETE NO ACTION; ALTER TABLE edgv.laz_sitio_arqueologico_a - ADD CONSTRAINT laz_sitio_arqueologico_a_cultura_check - CHECK (cultura = ANY(ARRAY[1 :: SMALLINT, 9999 :: SMALLINT])); + ADD CONSTRAINT laz_sitio_arqueologico_a_cultura_check + CHECK (cultura = ANY(ARRAY[1 :: SMALLINT, 9999 :: SMALLINT])); ALTER TABLE edgv.laz_sitio_arqueologico_a ALTER COLUMN cultura SET DEFAULT 9999; CREATE TABLE edgv.laz_pista_competicao_l( @@ -14972,8 +14972,8 @@ ALTER TABLE edgv.laz_ruina_p ON UPDATE NO ACTION ON DELETE NO ACTION; ALTER TABLE edgv.laz_ruina_p - ADD CONSTRAINT laz_ruina_p_cultura_check - CHECK (cultura = ANY(ARRAY[1 :: SMALLINT, 9999 :: SMALLINT])); + ADD CONSTRAINT laz_ruina_p_cultura_check + CHECK (cultura = ANY(ARRAY[1 :: SMALLINT, 9999 :: SMALLINT])); ALTER TABLE edgv.laz_ruina_p ALTER COLUMN cultura SET DEFAULT 9999; CREATE TABLE edgv.laz_ruina_a( @@ -15003,8 +15003,8 @@ ALTER TABLE edgv.laz_ruina_a ON UPDATE NO ACTION ON DELETE NO ACTION; ALTER TABLE edgv.laz_ruina_a - ADD CONSTRAINT laz_ruina_a_cultura_check - CHECK (cultura = ANY(ARRAY[1 :: SMALLINT, 9999 :: SMALLINT])); + ADD CONSTRAINT laz_ruina_a_cultura_check + CHECK (cultura = ANY(ARRAY[1 :: SMALLINT, 9999 :: SMALLINT])); ALTER TABLE edgv.laz_ruina_a ALTER COLUMN cultura SET DEFAULT 9999; CREATE TABLE edgv.lml_pais_a( @@ -15178,8 +15178,8 @@ ALTER TABLE edgv.lml_unidade_protecao_integral_a ON UPDATE NO ACTION ON DELETE NO ACTION; ALTER TABLE edgv.lml_unidade_protecao_integral_a - ADD CONSTRAINT lml_unidade_protecao_integral_a_tipounidprotegida_check - CHECK (tipounidprotegida = ANY(ARRAY[2 :: SMALLINT, 9999 :: SMALLINT])); + ADD CONSTRAINT lml_unidade_protecao_integral_a_tipounidprotegida_check + CHECK (tipounidprotegida = ANY(ARRAY[2 :: SMALLINT, 9999 :: SMALLINT])); ALTER TABLE edgv.lml_unidade_protecao_integral_a ALTER COLUMN tipounidprotegida SET DEFAULT 9999; ALTER TABLE edgv.lml_unidade_protecao_integral_a @@ -15233,8 +15233,8 @@ ALTER TABLE edgv.lml_unidade_uso_sustentavel_a ON UPDATE NO ACTION ON DELETE NO ACTION; ALTER TABLE edgv.lml_unidade_uso_sustentavel_a - ADD CONSTRAINT lml_unidade_uso_sustentavel_a_tipounidprotegida_check - CHECK (tipounidprotegida = ANY(ARRAY[3 :: SMALLINT, 9999 :: SMALLINT])); + ADD CONSTRAINT lml_unidade_uso_sustentavel_a_tipounidprotegida_check + CHECK (tipounidprotegida = ANY(ARRAY[3 :: SMALLINT, 9999 :: SMALLINT])); ALTER TABLE edgv.lml_unidade_uso_sustentavel_a ALTER COLUMN tipounidprotegida SET DEFAULT 9999; ALTER TABLE edgv.lml_unidade_uso_sustentavel_a @@ -15312,8 +15312,8 @@ ALTER TABLE edgv.lml_area_pub_militar_a ON UPDATE NO ACTION ON DELETE NO ACTION; ALTER TABLE edgv.lml_area_pub_militar_a - ADD CONSTRAINT lml_area_pub_militar_a_administracao_check - CHECK (administracao = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 9999 :: SMALLINT])); + ADD CONSTRAINT lml_area_pub_militar_a_administracao_check + CHECK (administracao = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 9999 :: SMALLINT])); ALTER TABLE edgv.lml_area_pub_militar_a ALTER COLUMN administracao SET DEFAULT 9999; ALTER TABLE edgv.lml_area_pub_militar_a @@ -15322,8 +15322,8 @@ ALTER TABLE edgv.lml_area_pub_militar_a ON UPDATE NO ACTION ON DELETE NO ACTION; ALTER TABLE edgv.lml_area_pub_militar_a - ADD CONSTRAINT lml_area_pub_militar_a_jurisdicao_check - CHECK (jurisdicao = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 9999 :: SMALLINT])); + ADD CONSTRAINT lml_area_pub_militar_a_jurisdicao_check + CHECK (jurisdicao = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 9999 :: SMALLINT])); ALTER TABLE edgv.lml_area_pub_militar_a ALTER COLUMN jurisdicao SET DEFAULT 9999; CREATE TABLE edgv.lml_area_urbana_isolada_a( @@ -15401,8 +15401,8 @@ ALTER TABLE edgv.lml_unidade_conservacao_a ON UPDATE NO ACTION ON DELETE NO ACTION; ALTER TABLE edgv.lml_unidade_conservacao_a - ADD CONSTRAINT lml_unidade_conservacao_a_tipounidprotegida_check - CHECK (tipounidprotegida = ANY(ARRAY[4 :: SMALLINT, 9999 :: SMALLINT])); + ADD CONSTRAINT lml_unidade_conservacao_a_tipounidprotegida_check + CHECK (tipounidprotegida = ANY(ARRAY[4 :: SMALLINT, 9999 :: SMALLINT])); ALTER TABLE edgv.lml_unidade_conservacao_a ALTER COLUMN tipounidprotegida SET DEFAULT 9999; CREATE TABLE edgv.pto_marco_de_limite_p( @@ -15639,8 +15639,8 @@ ALTER TABLE edgv.rel_gruta_caverna_l ON UPDATE NO ACTION ON DELETE NO ACTION; ALTER TABLE edgv.rel_gruta_caverna_l - ADD CONSTRAINT rel_gruta_caverna_l_tipoelemnat_check - CHECK (tipoelemnat = ANY(ARRAY[15 :: SMALLINT, 20 :: SMALLINT, 9999 :: SMALLINT])); + ADD CONSTRAINT rel_gruta_caverna_l_tipoelemnat_check + CHECK (tipoelemnat = ANY(ARRAY[15 :: SMALLINT, 20 :: SMALLINT, 9999 :: SMALLINT])); ALTER TABLE edgv.rel_gruta_caverna_l ALTER COLUMN tipoelemnat SET DEFAULT 9999; CREATE TABLE edgv.rel_gruta_caverna_p( @@ -15662,8 +15662,8 @@ ALTER TABLE edgv.rel_gruta_caverna_p ON UPDATE NO ACTION ON DELETE NO ACTION; ALTER TABLE edgv.rel_gruta_caverna_p - ADD CONSTRAINT rel_gruta_caverna_p_tipoelemnat_check - CHECK (tipoelemnat = ANY(ARRAY[15 :: SMALLINT, 20 :: SMALLINT, 9999 :: SMALLINT])); + ADD CONSTRAINT rel_gruta_caverna_p_tipoelemnat_check + CHECK (tipoelemnat = ANY(ARRAY[15 :: SMALLINT, 20 :: SMALLINT, 9999 :: SMALLINT])); ALTER TABLE edgv.rel_gruta_caverna_p ALTER COLUMN tipoelemnat SET DEFAULT 9999; CREATE TABLE edgv.rel_rocha_l( @@ -15686,8 +15686,8 @@ ALTER TABLE edgv.rel_rocha_l ON UPDATE NO ACTION ON DELETE NO ACTION; ALTER TABLE edgv.rel_rocha_l - ADD CONSTRAINT rel_rocha_l_tipoelemnat_check - CHECK (tipoelemnat = ANY(ARRAY[23 :: SMALLINT, 9999 :: SMALLINT])); + ADD CONSTRAINT rel_rocha_l_tipoelemnat_check + CHECK (tipoelemnat = ANY(ARRAY[23 :: SMALLINT, 9999 :: SMALLINT])); ALTER TABLE edgv.rel_rocha_l ALTER COLUMN tipoelemnat SET DEFAULT 9999; ALTER TABLE edgv.rel_rocha_l @@ -15717,8 +15717,8 @@ ALTER TABLE edgv.rel_rocha_p ON UPDATE NO ACTION ON DELETE NO ACTION; ALTER TABLE edgv.rel_rocha_p - ADD CONSTRAINT rel_rocha_p_tipoelemnat_check - CHECK (tipoelemnat = ANY(ARRAY[23 :: SMALLINT, 9999 :: SMALLINT])); + ADD CONSTRAINT rel_rocha_p_tipoelemnat_check + CHECK (tipoelemnat = ANY(ARRAY[23 :: SMALLINT, 9999 :: SMALLINT])); ALTER TABLE edgv.rel_rocha_p ALTER COLUMN tipoelemnat SET DEFAULT 9999; ALTER TABLE edgv.rel_rocha_p @@ -15748,8 +15748,8 @@ ALTER TABLE edgv.rel_rocha_a ON UPDATE NO ACTION ON DELETE NO ACTION; ALTER TABLE edgv.rel_rocha_a - ADD CONSTRAINT rel_rocha_a_tipoelemnat_check - CHECK (tipoelemnat = ANY(ARRAY[23 :: SMALLINT, 9999 :: SMALLINT])); + ADD CONSTRAINT rel_rocha_a_tipoelemnat_check + CHECK (tipoelemnat = ANY(ARRAY[23 :: SMALLINT, 9999 :: SMALLINT])); ALTER TABLE edgv.rel_rocha_a ALTER COLUMN tipoelemnat SET DEFAULT 9999; ALTER TABLE edgv.rel_rocha_a @@ -15779,8 +15779,8 @@ ALTER TABLE edgv.rel_corte_l ON UPDATE NO ACTION ON DELETE NO ACTION; ALTER TABLE edgv.rel_corte_l - ADD CONSTRAINT rel_corte_l_tipoalterantrop_check - CHECK (tipoalterantrop = ANY(ARRAY[26 :: SMALLINT, 9999 :: SMALLINT])); + ADD CONSTRAINT rel_corte_l_tipoalterantrop_check + CHECK (tipoalterantrop = ANY(ARRAY[26 :: SMALLINT, 9999 :: SMALLINT])); ALTER TABLE edgv.rel_corte_l ALTER COLUMN tipoalterantrop SET DEFAULT 9999; ALTER TABLE edgv.rel_corte_l @@ -15789,8 +15789,8 @@ ALTER TABLE edgv.rel_corte_l ON UPDATE NO ACTION ON DELETE NO ACTION; ALTER TABLE edgv.rel_corte_l - ADD CONSTRAINT rel_corte_l_matconstr_check - CHECK (matconstr = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 4 :: SMALLINT, 23 :: SMALLINT, 99 :: SMALLINT, 9999 :: SMALLINT])); + ADD CONSTRAINT rel_corte_l_matconstr_check + CHECK (matconstr = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 4 :: SMALLINT, 23 :: SMALLINT, 99 :: SMALLINT, 9999 :: SMALLINT])); ALTER TABLE edgv.rel_corte_l ALTER COLUMN matconstr SET DEFAULT 9999; CREATE TABLE edgv.rel_corte_p( @@ -15813,8 +15813,8 @@ ALTER TABLE edgv.rel_corte_p ON UPDATE NO ACTION ON DELETE NO ACTION; ALTER TABLE edgv.rel_corte_p - ADD CONSTRAINT rel_corte_p_tipoalterantrop_check - CHECK (tipoalterantrop = ANY(ARRAY[26 :: SMALLINT, 9999 :: SMALLINT])); + ADD CONSTRAINT rel_corte_p_tipoalterantrop_check + CHECK (tipoalterantrop = ANY(ARRAY[26 :: SMALLINT, 9999 :: SMALLINT])); ALTER TABLE edgv.rel_corte_p ALTER COLUMN tipoalterantrop SET DEFAULT 9999; ALTER TABLE edgv.rel_corte_p @@ -15823,8 +15823,8 @@ ALTER TABLE edgv.rel_corte_p ON UPDATE NO ACTION ON DELETE NO ACTION; ALTER TABLE edgv.rel_corte_p - ADD CONSTRAINT rel_corte_p_matconstr_check - CHECK (matconstr = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 4 :: SMALLINT, 23 :: SMALLINT, 99 :: SMALLINT, 9999 :: SMALLINT])); + ADD CONSTRAINT rel_corte_p_matconstr_check + CHECK (matconstr = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 4 :: SMALLINT, 23 :: SMALLINT, 99 :: SMALLINT, 9999 :: SMALLINT])); ALTER TABLE edgv.rel_corte_p ALTER COLUMN matconstr SET DEFAULT 9999; CREATE TABLE edgv.rel_corte_a( @@ -15847,8 +15847,8 @@ ALTER TABLE edgv.rel_corte_a ON UPDATE NO ACTION ON DELETE NO ACTION; ALTER TABLE edgv.rel_corte_a - ADD CONSTRAINT rel_corte_a_tipoalterantrop_check - CHECK (tipoalterantrop = ANY(ARRAY[26 :: SMALLINT, 9999 :: SMALLINT])); + ADD CONSTRAINT rel_corte_a_tipoalterantrop_check + CHECK (tipoalterantrop = ANY(ARRAY[26 :: SMALLINT, 9999 :: SMALLINT])); ALTER TABLE edgv.rel_corte_a ALTER COLUMN tipoalterantrop SET DEFAULT 9999; ALTER TABLE edgv.rel_corte_a @@ -15857,8 +15857,8 @@ ALTER TABLE edgv.rel_corte_a ON UPDATE NO ACTION ON DELETE NO ACTION; ALTER TABLE edgv.rel_corte_a - ADD CONSTRAINT rel_corte_a_matconstr_check - CHECK (matconstr = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 4 :: SMALLINT, 23 :: SMALLINT, 99 :: SMALLINT, 9999 :: SMALLINT])); + ADD CONSTRAINT rel_corte_a_matconstr_check + CHECK (matconstr = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 4 :: SMALLINT, 23 :: SMALLINT, 99 :: SMALLINT, 9999 :: SMALLINT])); ALTER TABLE edgv.rel_corte_a ALTER COLUMN matconstr SET DEFAULT 9999; CREATE TABLE edgv.rel_terreno_exposto_a( @@ -15907,8 +15907,8 @@ ALTER TABLE edgv.rel_dolina_p ON UPDATE NO ACTION ON DELETE NO ACTION; ALTER TABLE edgv.rel_dolina_p - ADD CONSTRAINT rel_dolina_p_tipoelemnat_check - CHECK (tipoelemnat = ANY(ARRAY[16 :: SMALLINT, 9999 :: SMALLINT])); + ADD CONSTRAINT rel_dolina_p_tipoelemnat_check + CHECK (tipoelemnat = ANY(ARRAY[16 :: SMALLINT, 9999 :: SMALLINT])); ALTER TABLE edgv.rel_dolina_p ALTER COLUMN tipoelemnat SET DEFAULT 9999; CREATE TABLE edgv.rel_dolina_a( @@ -15930,8 +15930,8 @@ ALTER TABLE edgv.rel_dolina_a ON UPDATE NO ACTION ON DELETE NO ACTION; ALTER TABLE edgv.rel_dolina_a - ADD CONSTRAINT rel_dolina_a_tipoelemnat_check - CHECK (tipoelemnat = ANY(ARRAY[16 :: SMALLINT, 9999 :: SMALLINT])); + ADD CONSTRAINT rel_dolina_a_tipoelemnat_check + CHECK (tipoelemnat = ANY(ARRAY[16 :: SMALLINT, 9999 :: SMALLINT])); ALTER TABLE edgv.rel_dolina_a ALTER COLUMN tipoelemnat SET DEFAULT 9999; CREATE TABLE edgv.rel_aterro_l( @@ -15954,8 +15954,8 @@ ALTER TABLE edgv.rel_aterro_l ON UPDATE NO ACTION ON DELETE NO ACTION; ALTER TABLE edgv.rel_aterro_l - ADD CONSTRAINT rel_aterro_l_tipoalterantrop_check - CHECK (tipoalterantrop = ANY(ARRAY[27 :: SMALLINT, 9999 :: SMALLINT])); + ADD CONSTRAINT rel_aterro_l_tipoalterantrop_check + CHECK (tipoalterantrop = ANY(ARRAY[27 :: SMALLINT, 9999 :: SMALLINT])); ALTER TABLE edgv.rel_aterro_l ALTER COLUMN tipoalterantrop SET DEFAULT 9999; ALTER TABLE edgv.rel_aterro_l @@ -15964,8 +15964,8 @@ ALTER TABLE edgv.rel_aterro_l ON UPDATE NO ACTION ON DELETE NO ACTION; ALTER TABLE edgv.rel_aterro_l - ADD CONSTRAINT rel_aterro_l_matconstr_check - CHECK (matconstr = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 4 :: SMALLINT, 23 :: SMALLINT, 99 :: SMALLINT, 9999 :: SMALLINT])); + ADD CONSTRAINT rel_aterro_l_matconstr_check + CHECK (matconstr = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 4 :: SMALLINT, 23 :: SMALLINT, 99 :: SMALLINT, 9999 :: SMALLINT])); ALTER TABLE edgv.rel_aterro_l ALTER COLUMN matconstr SET DEFAULT 9999; CREATE TABLE edgv.rel_aterro_p( @@ -15988,8 +15988,8 @@ ALTER TABLE edgv.rel_aterro_p ON UPDATE NO ACTION ON DELETE NO ACTION; ALTER TABLE edgv.rel_aterro_p - ADD CONSTRAINT rel_aterro_p_tipoalterantrop_check - CHECK (tipoalterantrop = ANY(ARRAY[27 :: SMALLINT, 9999 :: SMALLINT])); + ADD CONSTRAINT rel_aterro_p_tipoalterantrop_check + CHECK (tipoalterantrop = ANY(ARRAY[27 :: SMALLINT, 9999 :: SMALLINT])); ALTER TABLE edgv.rel_aterro_p ALTER COLUMN tipoalterantrop SET DEFAULT 9999; ALTER TABLE edgv.rel_aterro_p @@ -15998,8 +15998,8 @@ ALTER TABLE edgv.rel_aterro_p ON UPDATE NO ACTION ON DELETE NO ACTION; ALTER TABLE edgv.rel_aterro_p - ADD CONSTRAINT rel_aterro_p_matconstr_check - CHECK (matconstr = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 4 :: SMALLINT, 23 :: SMALLINT, 99 :: SMALLINT, 9999 :: SMALLINT])); + ADD CONSTRAINT rel_aterro_p_matconstr_check + CHECK (matconstr = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 4 :: SMALLINT, 23 :: SMALLINT, 99 :: SMALLINT, 9999 :: SMALLINT])); ALTER TABLE edgv.rel_aterro_p ALTER COLUMN matconstr SET DEFAULT 9999; CREATE TABLE edgv.rel_aterro_a( @@ -16022,8 +16022,8 @@ ALTER TABLE edgv.rel_aterro_a ON UPDATE NO ACTION ON DELETE NO ACTION; ALTER TABLE edgv.rel_aterro_a - ADD CONSTRAINT rel_aterro_a_tipoalterantrop_check - CHECK (tipoalterantrop = ANY(ARRAY[27 :: SMALLINT, 9999 :: SMALLINT])); + ADD CONSTRAINT rel_aterro_a_tipoalterantrop_check + CHECK (tipoalterantrop = ANY(ARRAY[27 :: SMALLINT, 9999 :: SMALLINT])); ALTER TABLE edgv.rel_aterro_a ALTER COLUMN tipoalterantrop SET DEFAULT 9999; ALTER TABLE edgv.rel_aterro_a @@ -16032,8 +16032,8 @@ ALTER TABLE edgv.rel_aterro_a ON UPDATE NO ACTION ON DELETE NO ACTION; ALTER TABLE edgv.rel_aterro_a - ADD CONSTRAINT rel_aterro_a_matconstr_check - CHECK (matconstr = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 4 :: SMALLINT, 23 :: SMALLINT, 99 :: SMALLINT, 9999 :: SMALLINT])); + ADD CONSTRAINT rel_aterro_a_matconstr_check + CHECK (matconstr = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 4 :: SMALLINT, 23 :: SMALLINT, 99 :: SMALLINT, 9999 :: SMALLINT])); ALTER TABLE edgv.rel_aterro_a ALTER COLUMN matconstr SET DEFAULT 9999; CREATE TABLE edgv.rel_ponto_cotado_altimetrico_p( @@ -16068,8 +16068,8 @@ ALTER TABLE edgv.rel_elemento_fisiografico_natural_l ON UPDATE NO ACTION ON DELETE NO ACTION; ALTER TABLE edgv.rel_elemento_fisiografico_natural_l - ADD CONSTRAINT rel_elemento_fisiografico_natural_l_tipoelemnat_check - CHECK (tipoelemnat = ANY(ARRAY[1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 4 :: SMALLINT, 5 :: SMALLINT, 6 :: SMALLINT, 7 :: SMALLINT, 8 :: SMALLINT, 9 :: SMALLINT, 10 :: SMALLINT, 11 :: SMALLINT, 12 :: SMALLINT, 13 :: SMALLINT, 14 :: SMALLINT, 18 :: SMALLINT, 19 :: SMALLINT, 99 :: SMALLINT, 9999 :: SMALLINT])); + ADD CONSTRAINT rel_elemento_fisiografico_natural_l_tipoelemnat_check + CHECK (tipoelemnat = ANY(ARRAY[1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 4 :: SMALLINT, 5 :: SMALLINT, 6 :: SMALLINT, 7 :: SMALLINT, 8 :: SMALLINT, 9 :: SMALLINT, 10 :: SMALLINT, 11 :: SMALLINT, 12 :: SMALLINT, 13 :: SMALLINT, 14 :: SMALLINT, 18 :: SMALLINT, 19 :: SMALLINT, 99 :: SMALLINT, 9999 :: SMALLINT])); ALTER TABLE edgv.rel_elemento_fisiografico_natural_l ALTER COLUMN tipoelemnat SET DEFAULT 9999; CREATE TABLE edgv.rel_elemento_fisiografico_natural_p( @@ -16091,8 +16091,8 @@ ALTER TABLE edgv.rel_elemento_fisiografico_natural_p ON UPDATE NO ACTION ON DELETE NO ACTION; ALTER TABLE edgv.rel_elemento_fisiografico_natural_p - ADD CONSTRAINT rel_elemento_fisiografico_natural_p_tipoelemnat_check - CHECK (tipoelemnat = ANY(ARRAY[1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 4 :: SMALLINT, 5 :: SMALLINT, 6 :: SMALLINT, 7 :: SMALLINT, 8 :: SMALLINT, 9 :: SMALLINT, 10 :: SMALLINT, 11 :: SMALLINT, 12 :: SMALLINT, 13 :: SMALLINT, 14 :: SMALLINT, 18 :: SMALLINT, 19 :: SMALLINT, 99 :: SMALLINT, 9999 :: SMALLINT])); + ADD CONSTRAINT rel_elemento_fisiografico_natural_p_tipoelemnat_check + CHECK (tipoelemnat = ANY(ARRAY[1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 4 :: SMALLINT, 5 :: SMALLINT, 6 :: SMALLINT, 7 :: SMALLINT, 8 :: SMALLINT, 9 :: SMALLINT, 10 :: SMALLINT, 11 :: SMALLINT, 12 :: SMALLINT, 13 :: SMALLINT, 14 :: SMALLINT, 18 :: SMALLINT, 19 :: SMALLINT, 99 :: SMALLINT, 9999 :: SMALLINT])); ALTER TABLE edgv.rel_elemento_fisiografico_natural_p ALTER COLUMN tipoelemnat SET DEFAULT 9999; CREATE TABLE edgv.rel_elemento_fisiografico_natural_a( @@ -16114,8 +16114,8 @@ ALTER TABLE edgv.rel_elemento_fisiografico_natural_a ON UPDATE NO ACTION ON DELETE NO ACTION; ALTER TABLE edgv.rel_elemento_fisiografico_natural_a - ADD CONSTRAINT rel_elemento_fisiografico_natural_a_tipoelemnat_check - CHECK (tipoelemnat = ANY(ARRAY[1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 4 :: SMALLINT, 5 :: SMALLINT, 6 :: SMALLINT, 7 :: SMALLINT, 8 :: SMALLINT, 9 :: SMALLINT, 10 :: SMALLINT, 11 :: SMALLINT, 12 :: SMALLINT, 13 :: SMALLINT, 14 :: SMALLINT, 18 :: SMALLINT, 19 :: SMALLINT, 99 :: SMALLINT, 9999 :: SMALLINT])); + ADD CONSTRAINT rel_elemento_fisiografico_natural_a_tipoelemnat_check + CHECK (tipoelemnat = ANY(ARRAY[1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 4 :: SMALLINT, 5 :: SMALLINT, 6 :: SMALLINT, 7 :: SMALLINT, 8 :: SMALLINT, 9 :: SMALLINT, 10 :: SMALLINT, 11 :: SMALLINT, 12 :: SMALLINT, 13 :: SMALLINT, 14 :: SMALLINT, 18 :: SMALLINT, 19 :: SMALLINT, 99 :: SMALLINT, 9999 :: SMALLINT])); ALTER TABLE edgv.rel_elemento_fisiografico_natural_a ALTER COLUMN tipoelemnat SET DEFAULT 9999; CREATE TABLE edgv.rel_pico_p( @@ -16137,8 +16137,8 @@ ALTER TABLE edgv.rel_pico_p ON UPDATE NO ACTION ON DELETE NO ACTION; ALTER TABLE edgv.rel_pico_p - ADD CONSTRAINT rel_pico_p_tipoelemnat_check - CHECK (tipoelemnat = ANY(ARRAY[22 :: SMALLINT, 9999 :: SMALLINT])); + ADD CONSTRAINT rel_pico_p_tipoelemnat_check + CHECK (tipoelemnat = ANY(ARRAY[22 :: SMALLINT, 9999 :: SMALLINT])); ALTER TABLE edgv.rel_pico_p ALTER COLUMN tipoelemnat SET DEFAULT 9999; CREATE TABLE edgv.rel_duna_l( @@ -16161,8 +16161,8 @@ ALTER TABLE edgv.rel_duna_l ON UPDATE NO ACTION ON DELETE NO ACTION; ALTER TABLE edgv.rel_duna_l - ADD CONSTRAINT rel_duna_l_tipoelemnat_check - CHECK (tipoelemnat = ANY(ARRAY[17 :: SMALLINT, 9999 :: SMALLINT])); + ADD CONSTRAINT rel_duna_l_tipoelemnat_check + CHECK (tipoelemnat = ANY(ARRAY[17 :: SMALLINT, 9999 :: SMALLINT])); ALTER TABLE edgv.rel_duna_l ALTER COLUMN tipoelemnat SET DEFAULT 9999; CREATE TABLE edgv.rel_duna_p( @@ -16185,8 +16185,8 @@ ALTER TABLE edgv.rel_duna_p ON UPDATE NO ACTION ON DELETE NO ACTION; ALTER TABLE edgv.rel_duna_p - ADD CONSTRAINT rel_duna_p_tipoelemnat_check - CHECK (tipoelemnat = ANY(ARRAY[17 :: SMALLINT, 9999 :: SMALLINT])); + ADD CONSTRAINT rel_duna_p_tipoelemnat_check + CHECK (tipoelemnat = ANY(ARRAY[17 :: SMALLINT, 9999 :: SMALLINT])); ALTER TABLE edgv.rel_duna_p ALTER COLUMN tipoelemnat SET DEFAULT 9999; CREATE TABLE edgv.rel_duna_a( @@ -16209,8 +16209,8 @@ ALTER TABLE edgv.rel_duna_a ON UPDATE NO ACTION ON DELETE NO ACTION; ALTER TABLE edgv.rel_duna_a - ADD CONSTRAINT rel_duna_a_tipoelemnat_check - CHECK (tipoelemnat = ANY(ARRAY[17 :: SMALLINT, 9999 :: SMALLINT])); + ADD CONSTRAINT rel_duna_a_tipoelemnat_check + CHECK (tipoelemnat = ANY(ARRAY[17 :: SMALLINT, 9999 :: SMALLINT])); ALTER TABLE edgv.rel_duna_a ALTER COLUMN tipoelemnat SET DEFAULT 9999; CREATE TABLE edgv.rel_curva_batimetrica_l( @@ -16244,8 +16244,8 @@ ALTER TABLE edgv.rel_alteracao_fisiografica_antropica_l ON UPDATE NO ACTION ON DELETE NO ACTION; ALTER TABLE edgv.rel_alteracao_fisiografica_antropica_l - ADD CONSTRAINT rel_alteracao_fisiografica_antropica_l_tipoalterantrop_check - CHECK (tipoalterantrop = ANY(ARRAY[0 :: SMALLINT, 24 :: SMALLINT, 28 :: SMALLINT, 29 :: SMALLINT, 32 :: SMALLINT, 99 :: SMALLINT, 9999 :: SMALLINT])); + ADD CONSTRAINT rel_alteracao_fisiografica_antropica_l_tipoalterantrop_check + CHECK (tipoalterantrop = ANY(ARRAY[0 :: SMALLINT, 24 :: SMALLINT, 28 :: SMALLINT, 29 :: SMALLINT, 32 :: SMALLINT, 99 :: SMALLINT, 9999 :: SMALLINT])); ALTER TABLE edgv.rel_alteracao_fisiografica_antropica_l ALTER COLUMN tipoalterantrop SET DEFAULT 9999; CREATE TABLE edgv.rel_alteracao_fisiografica_antropica_p( @@ -16267,8 +16267,8 @@ ALTER TABLE edgv.rel_alteracao_fisiografica_antropica_p ON UPDATE NO ACTION ON DELETE NO ACTION; ALTER TABLE edgv.rel_alteracao_fisiografica_antropica_p - ADD CONSTRAINT rel_alteracao_fisiografica_antropica_p_tipoalterantrop_check - CHECK (tipoalterantrop = ANY(ARRAY[0 :: SMALLINT, 24 :: SMALLINT, 28 :: SMALLINT, 29 :: SMALLINT, 32 :: SMALLINT, 99 :: SMALLINT, 9999 :: SMALLINT])); + ADD CONSTRAINT rel_alteracao_fisiografica_antropica_p_tipoalterantrop_check + CHECK (tipoalterantrop = ANY(ARRAY[0 :: SMALLINT, 24 :: SMALLINT, 28 :: SMALLINT, 29 :: SMALLINT, 32 :: SMALLINT, 99 :: SMALLINT, 9999 :: SMALLINT])); ALTER TABLE edgv.rel_alteracao_fisiografica_antropica_p ALTER COLUMN tipoalterantrop SET DEFAULT 9999; CREATE TABLE edgv.rel_alteracao_fisiografica_antropica_a( @@ -16290,8 +16290,8 @@ ALTER TABLE edgv.rel_alteracao_fisiografica_antropica_a ON UPDATE NO ACTION ON DELETE NO ACTION; ALTER TABLE edgv.rel_alteracao_fisiografica_antropica_a - ADD CONSTRAINT rel_alteracao_fisiografica_antropica_a_tipoalterantrop_check - CHECK (tipoalterantrop = ANY(ARRAY[0 :: SMALLINT, 24 :: SMALLINT, 28 :: SMALLINT, 29 :: SMALLINT, 32 :: SMALLINT, 99 :: SMALLINT, 9999 :: SMALLINT])); + ADD CONSTRAINT rel_alteracao_fisiografica_antropica_a_tipoalterantrop_check + CHECK (tipoalterantrop = ANY(ARRAY[0 :: SMALLINT, 24 :: SMALLINT, 28 :: SMALLINT, 29 :: SMALLINT, 32 :: SMALLINT, 99 :: SMALLINT, 9999 :: SMALLINT])); ALTER TABLE edgv.rel_alteracao_fisiografica_antropica_a ALTER COLUMN tipoalterantrop SET DEFAULT 9999; CREATE TABLE edgv.rel_ponto_cotado_batimetrico_p( @@ -16397,8 +16397,8 @@ ALTER TABLE edgv.rod_trecho_rodoviario_l ON UPDATE NO ACTION ON DELETE NO ACTION; ALTER TABLE edgv.rod_trecho_rodoviario_l - ADD CONSTRAINT rod_trecho_rodoviario_l_tipovia_check - CHECK (tipovia = ANY(ARRAY[2 :: SMALLINT, 4 :: SMALLINT, 5 :: SMALLINT, 6 :: SMALLINT, 7 :: SMALLINT, 99 :: SMALLINT, 9999 :: SMALLINT])); + ADD CONSTRAINT rod_trecho_rodoviario_l_tipovia_check + CHECK (tipovia = ANY(ARRAY[2 :: SMALLINT, 4 :: SMALLINT, 5 :: SMALLINT, 6 :: SMALLINT, 7 :: SMALLINT, 99 :: SMALLINT, 9999 :: SMALLINT])); ALTER TABLE edgv.rod_trecho_rodoviario_l ALTER COLUMN tipovia SET DEFAULT 9999; ALTER TABLE edgv.rod_trecho_rodoviario_l @@ -16506,8 +16506,8 @@ ALTER TABLE edgv.rod_trecho_rodoviario_a ON UPDATE NO ACTION ON DELETE NO ACTION; ALTER TABLE edgv.rod_trecho_rodoviario_a - ADD CONSTRAINT rod_trecho_rodoviario_a_tipovia_check - CHECK (tipovia = ANY(ARRAY[2 :: SMALLINT, 4 :: SMALLINT, 5 :: SMALLINT, 6 :: SMALLINT, 7 :: SMALLINT, 99 :: SMALLINT, 9999 :: SMALLINT])); + ADD CONSTRAINT rod_trecho_rodoviario_a_tipovia_check + CHECK (tipovia = ANY(ARRAY[2 :: SMALLINT, 4 :: SMALLINT, 5 :: SMALLINT, 6 :: SMALLINT, 7 :: SMALLINT, 99 :: SMALLINT, 9999 :: SMALLINT])); ALTER TABLE edgv.rod_trecho_rodoviario_a ALTER COLUMN tipovia SET DEFAULT 9999; ALTER TABLE edgv.rod_trecho_rodoviario_a @@ -16569,8 +16569,8 @@ ALTER TABLE edgv.snb_dep_abast_agua_p ON UPDATE NO ACTION ON DELETE NO ACTION; ALTER TABLE edgv.snb_dep_abast_agua_p - ADD CONSTRAINT snb_dep_abast_agua_p_tipodepgeral_check - CHECK (tipodepgeral = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 19 :: SMALLINT, 99 :: SMALLINT, 9999 :: SMALLINT])); + ADD CONSTRAINT snb_dep_abast_agua_p_tipodepgeral_check + CHECK (tipodepgeral = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 19 :: SMALLINT, 99 :: SMALLINT, 9999 :: SMALLINT])); ALTER TABLE edgv.snb_dep_abast_agua_p ALTER COLUMN tipodepgeral SET DEFAULT 9999; ALTER TABLE edgv.snb_dep_abast_agua_p @@ -16593,8 +16593,8 @@ ALTER TABLE edgv.snb_dep_abast_agua_p ON UPDATE NO ACTION ON DELETE NO ACTION; ALTER TABLE edgv.snb_dep_abast_agua_p - ADD CONSTRAINT snb_dep_abast_agua_p_tipoprodutoresiduo_check - CHECK (tipoprodutoresiduo = ANY(ARRAY[46 :: SMALLINT, 9999 :: SMALLINT])); + ADD CONSTRAINT snb_dep_abast_agua_p_tipoprodutoresiduo_check + CHECK (tipoprodutoresiduo = ANY(ARRAY[46 :: SMALLINT, 9999 :: SMALLINT])); ALTER TABLE edgv.snb_dep_abast_agua_p ALTER COLUMN tipoprodutoresiduo SET DEFAULT 9999; ALTER TABLE edgv.snb_dep_abast_agua_p @@ -16624,8 +16624,8 @@ ALTER TABLE edgv.snb_dep_abast_agua_p ON UPDATE NO ACTION ON DELETE NO ACTION; ALTER TABLE edgv.snb_dep_abast_agua_p - ADD CONSTRAINT snb_dep_abast_agua_p_estadofisico_check - CHECK (estadofisico = ANY(ARRAY[1 :: SMALLINT, 9999 :: SMALLINT])); + ADD CONSTRAINT snb_dep_abast_agua_p_estadofisico_check + CHECK (estadofisico = ANY(ARRAY[1 :: SMALLINT, 9999 :: SMALLINT])); ALTER TABLE edgv.snb_dep_abast_agua_p ALTER COLUMN estadofisico SET DEFAULT 9999; ALTER TABLE edgv.snb_dep_abast_agua_p @@ -16687,8 +16687,8 @@ ALTER TABLE edgv.snb_dep_abast_agua_a ON UPDATE NO ACTION ON DELETE NO ACTION; ALTER TABLE edgv.snb_dep_abast_agua_a - ADD CONSTRAINT snb_dep_abast_agua_a_tipodepgeral_check - CHECK (tipodepgeral = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 19 :: SMALLINT, 99 :: SMALLINT, 9999 :: SMALLINT])); + ADD CONSTRAINT snb_dep_abast_agua_a_tipodepgeral_check + CHECK (tipodepgeral = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 19 :: SMALLINT, 99 :: SMALLINT, 9999 :: SMALLINT])); ALTER TABLE edgv.snb_dep_abast_agua_a ALTER COLUMN tipodepgeral SET DEFAULT 9999; ALTER TABLE edgv.snb_dep_abast_agua_a @@ -16711,8 +16711,8 @@ ALTER TABLE edgv.snb_dep_abast_agua_a ON UPDATE NO ACTION ON DELETE NO ACTION; ALTER TABLE edgv.snb_dep_abast_agua_a - ADD CONSTRAINT snb_dep_abast_agua_a_tipoprodutoresiduo_check - CHECK (tipoprodutoresiduo = ANY(ARRAY[46 :: SMALLINT, 9999 :: SMALLINT])); + ADD CONSTRAINT snb_dep_abast_agua_a_tipoprodutoresiduo_check + CHECK (tipoprodutoresiduo = ANY(ARRAY[46 :: SMALLINT, 9999 :: SMALLINT])); ALTER TABLE edgv.snb_dep_abast_agua_a ALTER COLUMN tipoprodutoresiduo SET DEFAULT 9999; ALTER TABLE edgv.snb_dep_abast_agua_a @@ -16742,8 +16742,8 @@ ALTER TABLE edgv.snb_dep_abast_agua_a ON UPDATE NO ACTION ON DELETE NO ACTION; ALTER TABLE edgv.snb_dep_abast_agua_a - ADD CONSTRAINT snb_dep_abast_agua_a_estadofisico_check - CHECK (estadofisico = ANY(ARRAY[1 :: SMALLINT, 9999 :: SMALLINT])); + ADD CONSTRAINT snb_dep_abast_agua_a_estadofisico_check + CHECK (estadofisico = ANY(ARRAY[1 :: SMALLINT, 9999 :: SMALLINT])); ALTER TABLE edgv.snb_dep_abast_agua_a ALTER COLUMN estadofisico SET DEFAULT 9999; ALTER TABLE edgv.snb_dep_abast_agua_a @@ -16782,8 +16782,8 @@ ALTER TABLE edgv.snb_barragem_calcadao_a ON UPDATE NO ACTION ON DELETE NO ACTION; ALTER TABLE edgv.snb_barragem_calcadao_a - ADD CONSTRAINT snb_barragem_calcadao_a_tipoequipdesenvsocial_check - CHECK (tipoequipdesenvsocial = ANY(ARRAY[2 :: SMALLINT, 9999 :: SMALLINT])); + ADD CONSTRAINT snb_barragem_calcadao_a_tipoequipdesenvsocial_check + CHECK (tipoequipdesenvsocial = ANY(ARRAY[2 :: SMALLINT, 9999 :: SMALLINT])); ALTER TABLE edgv.snb_barragem_calcadao_a ALTER COLUMN tipoequipdesenvsocial SET DEFAULT 9999; ALTER TABLE edgv.snb_barragem_calcadao_a @@ -16874,8 +16874,8 @@ ALTER TABLE edgv.tra_ponte_l ON UPDATE NO ACTION ON DELETE NO ACTION; ALTER TABLE edgv.tra_ponte_l - ADD CONSTRAINT tra_ponte_l_modaluso_check - CHECK (modaluso = ANY(ARRAY[4 :: SMALLINT, 5 :: SMALLINT, 6 :: SMALLINT, 9 :: SMALLINT, 9999 :: SMALLINT])); + ADD CONSTRAINT tra_ponte_l_modaluso_check + CHECK (modaluso = ANY(ARRAY[4 :: SMALLINT, 5 :: SMALLINT, 6 :: SMALLINT, 9 :: SMALLINT, 9999 :: SMALLINT])); ALTER TABLE edgv.tra_ponte_l ALTER COLUMN modaluso SET DEFAULT 9999; ALTER TABLE edgv.tra_ponte_l @@ -16884,8 +16884,8 @@ ALTER TABLE edgv.tra_ponte_l ON UPDATE NO ACTION ON DELETE NO ACTION; ALTER TABLE edgv.tra_ponte_l - ADD CONSTRAINT tra_ponte_l_matconstr_check - CHECK (matconstr = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 4 :: SMALLINT, 5 :: SMALLINT, 8 :: SMALLINT, 99 :: SMALLINT, 9999 :: SMALLINT])); + ADD CONSTRAINT tra_ponte_l_matconstr_check + CHECK (matconstr = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 4 :: SMALLINT, 5 :: SMALLINT, 8 :: SMALLINT, 99 :: SMALLINT, 9999 :: SMALLINT])); ALTER TABLE edgv.tra_ponte_l ALTER COLUMN matconstr SET DEFAULT 9999; ALTER TABLE edgv.tra_ponte_l @@ -16963,8 +16963,8 @@ ALTER TABLE edgv.tra_ponte_p ON UPDATE NO ACTION ON DELETE NO ACTION; ALTER TABLE edgv.tra_ponte_p - ADD CONSTRAINT tra_ponte_p_modaluso_check - CHECK (modaluso = ANY(ARRAY[4 :: SMALLINT, 5 :: SMALLINT, 6 :: SMALLINT, 9 :: SMALLINT, 9999 :: SMALLINT])); + ADD CONSTRAINT tra_ponte_p_modaluso_check + CHECK (modaluso = ANY(ARRAY[4 :: SMALLINT, 5 :: SMALLINT, 6 :: SMALLINT, 9 :: SMALLINT, 9999 :: SMALLINT])); ALTER TABLE edgv.tra_ponte_p ALTER COLUMN modaluso SET DEFAULT 9999; ALTER TABLE edgv.tra_ponte_p @@ -16973,8 +16973,8 @@ ALTER TABLE edgv.tra_ponte_p ON UPDATE NO ACTION ON DELETE NO ACTION; ALTER TABLE edgv.tra_ponte_p - ADD CONSTRAINT tra_ponte_p_matconstr_check - CHECK (matconstr = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 4 :: SMALLINT, 5 :: SMALLINT, 8 :: SMALLINT, 99 :: SMALLINT, 9999 :: SMALLINT])); + ADD CONSTRAINT tra_ponte_p_matconstr_check + CHECK (matconstr = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 4 :: SMALLINT, 5 :: SMALLINT, 8 :: SMALLINT, 99 :: SMALLINT, 9999 :: SMALLINT])); ALTER TABLE edgv.tra_ponte_p ALTER COLUMN matconstr SET DEFAULT 9999; ALTER TABLE edgv.tra_ponte_p @@ -17052,8 +17052,8 @@ ALTER TABLE edgv.tra_ponte_a ON UPDATE NO ACTION ON DELETE NO ACTION; ALTER TABLE edgv.tra_ponte_a - ADD CONSTRAINT tra_ponte_a_modaluso_check - CHECK (modaluso = ANY(ARRAY[4 :: SMALLINT, 5 :: SMALLINT, 6 :: SMALLINT, 9 :: SMALLINT, 9999 :: SMALLINT])); + ADD CONSTRAINT tra_ponte_a_modaluso_check + CHECK (modaluso = ANY(ARRAY[4 :: SMALLINT, 5 :: SMALLINT, 6 :: SMALLINT, 9 :: SMALLINT, 9999 :: SMALLINT])); ALTER TABLE edgv.tra_ponte_a ALTER COLUMN modaluso SET DEFAULT 9999; ALTER TABLE edgv.tra_ponte_a @@ -17062,8 +17062,8 @@ ALTER TABLE edgv.tra_ponte_a ON UPDATE NO ACTION ON DELETE NO ACTION; ALTER TABLE edgv.tra_ponte_a - ADD CONSTRAINT tra_ponte_a_matconstr_check - CHECK (matconstr = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 4 :: SMALLINT, 5 :: SMALLINT, 8 :: SMALLINT, 99 :: SMALLINT, 9999 :: SMALLINT])); + ADD CONSTRAINT tra_ponte_a_matconstr_check + CHECK (matconstr = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 4 :: SMALLINT, 5 :: SMALLINT, 8 :: SMALLINT, 99 :: SMALLINT, 9999 :: SMALLINT])); ALTER TABLE edgv.tra_ponte_a ALTER COLUMN matconstr SET DEFAULT 9999; ALTER TABLE edgv.tra_ponte_a @@ -17453,8 +17453,8 @@ ALTER TABLE edgv.tra_tunel_l ON UPDATE NO ACTION ON DELETE NO ACTION; ALTER TABLE edgv.tra_tunel_l - ADD CONSTRAINT tra_tunel_l_modaluso_check - CHECK (modaluso = ANY(ARRAY[4 :: SMALLINT, 5 :: SMALLINT, 6 :: SMALLINT, 7 :: SMALLINT, 9 :: SMALLINT, 9999 :: SMALLINT])); + ADD CONSTRAINT tra_tunel_l_modaluso_check + CHECK (modaluso = ANY(ARRAY[4 :: SMALLINT, 5 :: SMALLINT, 6 :: SMALLINT, 7 :: SMALLINT, 9 :: SMALLINT, 9999 :: SMALLINT])); ALTER TABLE edgv.tra_tunel_l ALTER COLUMN modaluso SET DEFAULT 9999; ALTER TABLE edgv.tra_tunel_l @@ -17491,8 +17491,8 @@ ALTER TABLE edgv.tra_tunel_l ON UPDATE NO ACTION ON DELETE NO ACTION; ALTER TABLE edgv.tra_tunel_l - ADD CONSTRAINT tra_tunel_l_posicaopista_check - CHECK (posicaopista = ANY(ARRAY[2 :: SMALLINT, 9999 :: SMALLINT])); + ADD CONSTRAINT tra_tunel_l_posicaopista_check + CHECK (posicaopista = ANY(ARRAY[2 :: SMALLINT, 9999 :: SMALLINT])); ALTER TABLE edgv.tra_tunel_l ALTER COLUMN posicaopista SET DEFAULT 9999; ALTER TABLE edgv.tra_tunel_l @@ -17540,8 +17540,8 @@ ALTER TABLE edgv.tra_tunel_p ON UPDATE NO ACTION ON DELETE NO ACTION; ALTER TABLE edgv.tra_tunel_p - ADD CONSTRAINT tra_tunel_p_modaluso_check - CHECK (modaluso = ANY(ARRAY[4 :: SMALLINT, 5 :: SMALLINT, 6 :: SMALLINT, 7 :: SMALLINT, 9 :: SMALLINT, 9999 :: SMALLINT])); + ADD CONSTRAINT tra_tunel_p_modaluso_check + CHECK (modaluso = ANY(ARRAY[4 :: SMALLINT, 5 :: SMALLINT, 6 :: SMALLINT, 7 :: SMALLINT, 9 :: SMALLINT, 9999 :: SMALLINT])); ALTER TABLE edgv.tra_tunel_p ALTER COLUMN modaluso SET DEFAULT 9999; ALTER TABLE edgv.tra_tunel_p @@ -17578,8 +17578,8 @@ ALTER TABLE edgv.tra_tunel_p ON UPDATE NO ACTION ON DELETE NO ACTION; ALTER TABLE edgv.tra_tunel_p - ADD CONSTRAINT tra_tunel_p_posicaopista_check - CHECK (posicaopista = ANY(ARRAY[2 :: SMALLINT, 9999 :: SMALLINT])); + ADD CONSTRAINT tra_tunel_p_posicaopista_check + CHECK (posicaopista = ANY(ARRAY[2 :: SMALLINT, 9999 :: SMALLINT])); ALTER TABLE edgv.tra_tunel_p ALTER COLUMN posicaopista SET DEFAULT 9999; ALTER TABLE edgv.tra_tunel_p @@ -17627,8 +17627,8 @@ ALTER TABLE edgv.tra_tunel_a ON UPDATE NO ACTION ON DELETE NO ACTION; ALTER TABLE edgv.tra_tunel_a - ADD CONSTRAINT tra_tunel_a_modaluso_check - CHECK (modaluso = ANY(ARRAY[4 :: SMALLINT, 5 :: SMALLINT, 6 :: SMALLINT, 7 :: SMALLINT, 9 :: SMALLINT, 9999 :: SMALLINT])); + ADD CONSTRAINT tra_tunel_a_modaluso_check + CHECK (modaluso = ANY(ARRAY[4 :: SMALLINT, 5 :: SMALLINT, 6 :: SMALLINT, 7 :: SMALLINT, 9 :: SMALLINT, 9999 :: SMALLINT])); ALTER TABLE edgv.tra_tunel_a ALTER COLUMN modaluso SET DEFAULT 9999; ALTER TABLE edgv.tra_tunel_a @@ -17665,8 +17665,8 @@ ALTER TABLE edgv.tra_tunel_a ON UPDATE NO ACTION ON DELETE NO ACTION; ALTER TABLE edgv.tra_tunel_a - ADD CONSTRAINT tra_tunel_a_posicaopista_check - CHECK (posicaopista = ANY(ARRAY[2 :: SMALLINT, 9999 :: SMALLINT])); + ADD CONSTRAINT tra_tunel_a_posicaopista_check + CHECK (posicaopista = ANY(ARRAY[2 :: SMALLINT, 9999 :: SMALLINT])); ALTER TABLE edgv.tra_tunel_a ALTER COLUMN posicaopista SET DEFAULT 9999; ALTER TABLE edgv.tra_tunel_a @@ -17718,8 +17718,8 @@ ALTER TABLE edgv.tra_passagem_elevada_viaduto_l ON UPDATE NO ACTION ON DELETE NO ACTION; ALTER TABLE edgv.tra_passagem_elevada_viaduto_l - ADD CONSTRAINT tra_passagem_elevada_viaduto_l_modaluso_check - CHECK (modaluso = ANY(ARRAY[4 :: SMALLINT, 5 :: SMALLINT, 6 :: SMALLINT, 9 :: SMALLINT, 9999 :: SMALLINT])); + ADD CONSTRAINT tra_passagem_elevada_viaduto_l_modaluso_check + CHECK (modaluso = ANY(ARRAY[4 :: SMALLINT, 5 :: SMALLINT, 6 :: SMALLINT, 9 :: SMALLINT, 9999 :: SMALLINT])); ALTER TABLE edgv.tra_passagem_elevada_viaduto_l ALTER COLUMN modaluso SET DEFAULT 9999; ALTER TABLE edgv.tra_passagem_elevada_viaduto_l @@ -17756,8 +17756,8 @@ ALTER TABLE edgv.tra_passagem_elevada_viaduto_l ON UPDATE NO ACTION ON DELETE NO ACTION; ALTER TABLE edgv.tra_passagem_elevada_viaduto_l - ADD CONSTRAINT tra_passagem_elevada_viaduto_l_posicaopista_check - CHECK (posicaopista = ANY(ARRAY[0 :: SMALLINT, 4 :: SMALLINT, 7 :: SMALLINT, 13 :: SMALLINT, 99 :: SMALLINT, 9999 :: SMALLINT])); + ADD CONSTRAINT tra_passagem_elevada_viaduto_l_posicaopista_check + CHECK (posicaopista = ANY(ARRAY[0 :: SMALLINT, 4 :: SMALLINT, 7 :: SMALLINT, 13 :: SMALLINT, 99 :: SMALLINT, 9999 :: SMALLINT])); ALTER TABLE edgv.tra_passagem_elevada_viaduto_l ALTER COLUMN posicaopista SET DEFAULT 9999; ALTER TABLE edgv.tra_passagem_elevada_viaduto_l @@ -17809,8 +17809,8 @@ ALTER TABLE edgv.tra_passagem_elevada_viaduto_p ON UPDATE NO ACTION ON DELETE NO ACTION; ALTER TABLE edgv.tra_passagem_elevada_viaduto_p - ADD CONSTRAINT tra_passagem_elevada_viaduto_p_modaluso_check - CHECK (modaluso = ANY(ARRAY[4 :: SMALLINT, 5 :: SMALLINT, 6 :: SMALLINT, 9 :: SMALLINT, 9999 :: SMALLINT])); + ADD CONSTRAINT tra_passagem_elevada_viaduto_p_modaluso_check + CHECK (modaluso = ANY(ARRAY[4 :: SMALLINT, 5 :: SMALLINT, 6 :: SMALLINT, 9 :: SMALLINT, 9999 :: SMALLINT])); ALTER TABLE edgv.tra_passagem_elevada_viaduto_p ALTER COLUMN modaluso SET DEFAULT 9999; ALTER TABLE edgv.tra_passagem_elevada_viaduto_p @@ -17847,8 +17847,8 @@ ALTER TABLE edgv.tra_passagem_elevada_viaduto_p ON UPDATE NO ACTION ON DELETE NO ACTION; ALTER TABLE edgv.tra_passagem_elevada_viaduto_p - ADD CONSTRAINT tra_passagem_elevada_viaduto_p_posicaopista_check - CHECK (posicaopista = ANY(ARRAY[0 :: SMALLINT, 4 :: SMALLINT, 7 :: SMALLINT, 13 :: SMALLINT, 99 :: SMALLINT, 9999 :: SMALLINT])); + ADD CONSTRAINT tra_passagem_elevada_viaduto_p_posicaopista_check + CHECK (posicaopista = ANY(ARRAY[0 :: SMALLINT, 4 :: SMALLINT, 7 :: SMALLINT, 13 :: SMALLINT, 99 :: SMALLINT, 9999 :: SMALLINT])); ALTER TABLE edgv.tra_passagem_elevada_viaduto_p ALTER COLUMN posicaopista SET DEFAULT 9999; ALTER TABLE edgv.tra_passagem_elevada_viaduto_p @@ -17900,8 +17900,8 @@ ALTER TABLE edgv.tra_passagem_elevada_viaduto_a ON UPDATE NO ACTION ON DELETE NO ACTION; ALTER TABLE edgv.tra_passagem_elevada_viaduto_a - ADD CONSTRAINT tra_passagem_elevada_viaduto_a_modaluso_check - CHECK (modaluso = ANY(ARRAY[4 :: SMALLINT, 5 :: SMALLINT, 6 :: SMALLINT, 9 :: SMALLINT, 9999 :: SMALLINT])); + ADD CONSTRAINT tra_passagem_elevada_viaduto_a_modaluso_check + CHECK (modaluso = ANY(ARRAY[4 :: SMALLINT, 5 :: SMALLINT, 6 :: SMALLINT, 9 :: SMALLINT, 9999 :: SMALLINT])); ALTER TABLE edgv.tra_passagem_elevada_viaduto_a ALTER COLUMN modaluso SET DEFAULT 9999; ALTER TABLE edgv.tra_passagem_elevada_viaduto_a @@ -17938,8 +17938,8 @@ ALTER TABLE edgv.tra_passagem_elevada_viaduto_a ON UPDATE NO ACTION ON DELETE NO ACTION; ALTER TABLE edgv.tra_passagem_elevada_viaduto_a - ADD CONSTRAINT tra_passagem_elevada_viaduto_a_posicaopista_check - CHECK (posicaopista = ANY(ARRAY[0 :: SMALLINT, 4 :: SMALLINT, 7 :: SMALLINT, 13 :: SMALLINT, 99 :: SMALLINT, 9999 :: SMALLINT])); + ADD CONSTRAINT tra_passagem_elevada_viaduto_a_posicaopista_check + CHECK (posicaopista = ANY(ARRAY[0 :: SMALLINT, 4 :: SMALLINT, 7 :: SMALLINT, 13 :: SMALLINT, 99 :: SMALLINT, 9999 :: SMALLINT])); ALTER TABLE edgv.tra_passagem_elevada_viaduto_a ALTER COLUMN posicaopista SET DEFAULT 9999; ALTER TABLE edgv.tra_passagem_elevada_viaduto_a @@ -18007,8 +18007,8 @@ ALTER TABLE edgv.tra_patio_a ON UPDATE NO ACTION ON DELETE NO ACTION; ALTER TABLE edgv.tra_patio_a - ADD CONSTRAINT tra_patio_a_finalidadepatio_check - CHECK (finalidadepatio = ANY(ARRAY[0 :: SMALLINT, 2 :: SMALLINT, 4 :: SMALLINT, 5 :: SMALLINT, 6 :: SMALLINT, 7 :: SMALLINT, 8 :: SMALLINT, 99 :: SMALLINT, 9999 :: SMALLINT])); + ADD CONSTRAINT tra_patio_a_finalidadepatio_check + CHECK (finalidadepatio = ANY(ARRAY[0 :: SMALLINT, 2 :: SMALLINT, 4 :: SMALLINT, 5 :: SMALLINT, 6 :: SMALLINT, 7 :: SMALLINT, 8 :: SMALLINT, 99 :: SMALLINT, 9999 :: SMALLINT])); ALTER TABLE edgv.tra_patio_a ALTER COLUMN finalidadepatio SET DEFAULT 9999; CREATE TABLE edgv.veg_floresta_a( @@ -18034,8 +18034,8 @@ ALTER TABLE edgv.veg_floresta_a ON UPDATE NO ACTION ON DELETE NO ACTION; ALTER TABLE edgv.veg_floresta_a - ADD CONSTRAINT veg_floresta_a_classificacaoporte_check - CHECK (classificacaoporte = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 9999 :: SMALLINT])); + ADD CONSTRAINT veg_floresta_a_classificacaoporte_check + CHECK (classificacaoporte = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 9999 :: SMALLINT])); ALTER TABLE edgv.veg_floresta_a ALTER COLUMN classificacaoporte SET DEFAULT 9999; ALTER TABLE edgv.veg_floresta_a @@ -18384,8 +18384,8 @@ ALTER TABLE edgv.veg_reflorestamento_a ON UPDATE NO ACTION ON DELETE NO ACTION; ALTER TABLE edgv.veg_reflorestamento_a - ADD CONSTRAINT veg_reflorestamento_a_tipolavoura_check - CHECK (tipolavoura = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 9999 :: SMALLINT])); + ADD CONSTRAINT veg_reflorestamento_a_tipolavoura_check + CHECK (tipolavoura = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 9999 :: SMALLINT])); ALTER TABLE edgv.veg_reflorestamento_a ALTER COLUMN tipolavoura SET DEFAULT 9999; ALTER TABLE edgv.veg_reflorestamento_a @@ -18408,8 +18408,8 @@ ALTER TABLE edgv.veg_reflorestamento_a ON UPDATE NO ACTION ON DELETE NO ACTION; ALTER TABLE edgv.veg_reflorestamento_a - ADD CONSTRAINT veg_reflorestamento_a_cultivopredominante_check - CHECK (cultivopredominante = ANY(ARRAY[20 :: SMALLINT, 21 :: SMALLINT, 23 :: SMALLINT, 96 :: SMALLINT, 98 :: SMALLINT, 99 :: SMALLINT, 9999 :: SMALLINT])); + ADD CONSTRAINT veg_reflorestamento_a_cultivopredominante_check + CHECK (cultivopredominante = ANY(ARRAY[20 :: SMALLINT, 21 :: SMALLINT, 23 :: SMALLINT, 96 :: SMALLINT, 98 :: SMALLINT, 99 :: SMALLINT, 9999 :: SMALLINT])); ALTER TABLE edgv.veg_reflorestamento_a ALTER COLUMN cultivopredominante SET DEFAULT 9999; CREATE TABLE edgv.veg_campo_a( @@ -18435,8 +18435,8 @@ ALTER TABLE edgv.veg_campo_a ON UPDATE NO ACTION ON DELETE NO ACTION; ALTER TABLE edgv.veg_campo_a - ADD CONSTRAINT veg_campo_a_classificacaoporte_check - CHECK (classificacaoporte = ANY(ARRAY[0 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 4 :: SMALLINT, 9999 :: SMALLINT])); + ADD CONSTRAINT veg_campo_a_classificacaoporte_check + CHECK (classificacaoporte = ANY(ARRAY[0 :: SMALLINT, 2 :: SMALLINT, 3 :: SMALLINT, 4 :: SMALLINT, 9999 :: SMALLINT])); ALTER TABLE edgv.veg_campo_a ALTER COLUMN classificacaoporte SET DEFAULT 9999; ALTER TABLE edgv.veg_campo_a @@ -18452,8 +18452,8 @@ ALTER TABLE edgv.veg_campo_a ON UPDATE NO ACTION ON DELETE NO ACTION; ALTER TABLE edgv.veg_campo_a - ADD CONSTRAINT veg_campo_a_densidade_check - CHECK (densidade = ANY(ARRAY[2 :: SMALLINT, 9999 :: SMALLINT])); + ADD CONSTRAINT veg_campo_a_densidade_check + CHECK (densidade = ANY(ARRAY[2 :: SMALLINT, 9999 :: SMALLINT])); ALTER TABLE edgv.veg_campo_a ALTER COLUMN densidade SET DEFAULT 9999; ALTER TABLE edgv.veg_campo_a @@ -18607,8 +18607,8 @@ ALTER TABLE edgv.ver_jardim_a ON UPDATE NO ACTION ON DELETE NO ACTION; ALTER TABLE edgv.ver_jardim_a - ADD CONSTRAINT ver_jardim_a_tipolavoura_check - CHECK (tipolavoura = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 9999 :: SMALLINT])); + ADD CONSTRAINT ver_jardim_a_tipolavoura_check + CHECK (tipolavoura = ANY(ARRAY[0 :: SMALLINT, 1 :: SMALLINT, 2 :: SMALLINT, 9999 :: SMALLINT])); ALTER TABLE edgv.ver_jardim_a ALTER COLUMN tipolavoura SET DEFAULT 9999; ALTER TABLE edgv.ver_jardim_a @@ -18617,8 +18617,8 @@ ALTER TABLE edgv.ver_jardim_a ON UPDATE NO ACTION ON DELETE NO ACTION; ALTER TABLE edgv.ver_jardim_a - ADD CONSTRAINT ver_jardim_a_finalidade_check - CHECK (finalidade = ANY(ARRAY[4 :: SMALLINT, 9999 :: SMALLINT])); + ADD CONSTRAINT ver_jardim_a_finalidade_check + CHECK (finalidade = ANY(ARRAY[4 :: SMALLINT, 9999 :: SMALLINT])); ALTER TABLE edgv.ver_jardim_a ALTER COLUMN finalidade SET DEFAULT 9999; ALTER TABLE edgv.ver_jardim_a diff --git a/DsgTools/core/DbModels/PostGIS/admin/dsgtools_admindb.sql b/DsgTools/core/DbModels/PostGIS/admin/dsgtools_admindb.sql index c0d82543e..6fbfdd28d 100644 --- a/DsgTools/core/DbModels/PostGIS/admin/dsgtools_admindb.sql +++ b/DsgTools/core/DbModels/PostGIS/admin/dsgtools_admindb.sql @@ -12,7 +12,7 @@ -- CREATE DATABASE dsgtools_admindb -- ; -- -- ddl-end -- --- +-- -- object: topology | type: SCHEMA -- -- DROP SCHEMA IF EXISTS topology CASCADE; @@ -228,4 +228,4 @@ CREATE TABLE public.applied_style( CONSTRAINT applied_style_config_id_style_fk FOREIGN KEY (id_style) REFERENCES public.style (id) MATCH SIMPLE ON UPDATE NO ACTION ON DELETE CASCADE ); -- ddl-end -- -ALTER TABLE public.applied_style OWNER TO postgres; \ No newline at end of file +ALTER TABLE public.applied_style OWNER TO postgres; diff --git a/DsgTools/core/DbTools/Templates/headerConversionSummaryTemplate.html b/DsgTools/core/DbTools/Templates/headerConversionSummaryTemplate.html index c88755b1e..13b2d40bf 100644 --- a/DsgTools/core/DbTools/Templates/headerConversionSummaryTemplate.html +++ b/DsgTools/core/DbTools/Templates/headerConversionSummaryTemplate.html @@ -1,3 +1,3 @@

DSGTools Dataset Conversion Tool Summary

Total Elapsed Time: ELAPSED_TIME

-

\ No newline at end of file +

diff --git a/DsgTools/core/DbTools/dbConverter.py b/DsgTools/core/DbTools/dbConverter.py index 36aa8741b..7899eb8b7 100644 --- a/DsgTools/core/DbTools/dbConverter.py +++ b/DsgTools/core/DbTools/dbConverter.py @@ -24,17 +24,26 @@ import time from qgis.PyQt.QtCore import QObject, pyqtSignal, QSettings -from qgis.core import QgsFeatureRequest, QgsProject, QgsProcessingContext, \ - QgsProcessingMultiStepFeedback, QgsProcessingMultiStepFeedback, \ - QgsTask, QgsProcessingFeedback +from qgis.core import ( + QgsFeatureRequest, + QgsProject, + QgsProcessingContext, + QgsProcessingMultiStepFeedback, + QgsProcessingMultiStepFeedback, + QgsTask, + QgsProcessingFeedback, +) from DsgTools.core.dsgEnums import DsgEnums from DsgTools.core.Factories.DbFactory.dbFactory import DbFactory -from DsgTools.core.Factories.LayerLoaderFactory.layerLoaderFactory import LayerLoaderFactory +from DsgTools.core.Factories.LayerLoaderFactory.layerLoaderFactory import ( + LayerLoaderFactory, +) from DsgTools.core.GeometricTools.layerHandler import LayerHandler from DsgTools.core.GeometricTools.featureHandler import FeatureHandler from DsgTools.core.Factories.DbCreatorFactory.dbCreatorFactory import DbCreatorFactory + class DbConverter(QgsTask): conversionUpdated = pyqtSignal(str) conversionFinished = pyqtSignal() @@ -49,7 +58,10 @@ class DbConverter(QgsTask): 3.b- apply feature map to destination - feature level; and 4- each successfully filtered and mapped layer will be then sent to be perpetuated to output - layer level. """ - def __init__(self, iface, conversionMap=None, description='', flags=QgsTask.CanCancel): + + def __init__( + self, iface, conversionMap=None, description="", flags=QgsTask.CanCancel + ): """ Class constructor. :param iface: (QgsInterface) QGIS interface object (for runtime operations). @@ -60,11 +72,11 @@ def __init__(self, iface, conversionMap=None, description='', flags=QgsTask.CanC self.conversionMap = conversionMap self.coordinateTransformers = {} self.output = { - 'creationErrors' : {}, - 'successfulLayers' : {}, - 'failedLayers' : {}, - 'status' : False, - 'log' : '' + "creationErrors": {}, + "successfulLayers": {}, + "failedLayers": {}, + "status": False, + "log": "", } self.feedback = QgsProcessingFeedback() self.feedback.progressChanged.connect(self.setProgress) @@ -110,7 +122,7 @@ def getAllUniqueOutputDb(self, conversionMap=None): for ds, convMaps in conversionMap.items(): # datasources are key to conversion map dict for convMap in convMaps: - ds = convMap['outDs'] + ds = convMap["outDs"] if ds not in dsList: dsList.append(ds) return dsList @@ -123,7 +135,7 @@ def getDefaultPgDb(self, hostName): """ abstractDb = DbFactory().createDbFactory(driver=DsgEnums.DriverPostGIS) (host, port, user, password) = abstractDb.getServerConfiguration(hostName) - abstractDb.connectDatabaseWithParameters(host, port, 'postgres', user, password) + abstractDb.connectDatabaseWithParameters(host, port, "postgres", user, password) return abstractDb def createDataset(self, parameters): @@ -132,20 +144,33 @@ def createDataset(self, parameters): :param parameters: (dict) dict with all necessary parameters for a supported drivers. """ if self.connectToDb(parameters=parameters) is not None: - raise Exception(self.tr("Dataset {0} already exists.").format(parameters["db"])) + raise Exception( + self.tr("Dataset {0} already exists.").format(parameters["db"]) + ) driverName, createParam = { - DsgEnums.DriverPostGIS : lambda : ("QPSQL", self.getDefaultPgDb(parameters['host'])), - DsgEnums.DriverSpatiaLite : lambda : ("QSQLITE", os.path.dirname(parameters["path"])), - DsgEnums.DriverGeopackage : lambda : ("GPKG", os.path.dirname(parameters["path"])), - DsgEnums.DriverShapefile : lambda : ("SHP", parameters["path"]) - }[parameters['driver']]() - dbCreator = DbCreatorFactory().createDbCreatorFactory(driverName=driverName, createParam=createParam) + DsgEnums.DriverPostGIS: lambda: ( + "QPSQL", + self.getDefaultPgDb(parameters["host"]), + ), + DsgEnums.DriverSpatiaLite: lambda: ( + "QSQLITE", + os.path.dirname(parameters["path"]), + ), + DsgEnums.DriverGeopackage: lambda: ( + "GPKG", + os.path.dirname(parameters["path"]), + ), + DsgEnums.DriverShapefile: lambda: ("SHP", parameters["path"]), + }[parameters["driver"]]() + dbCreator = DbCreatorFactory().createDbCreatorFactory( + driverName=driverName, createParam=createParam + ) return dbCreator.createDb( - dbName=parameters['db'], - srid=parameters['srid'], - paramDict=parameters, - parentWidget=None - ) + dbName=parameters["db"], + srid=parameters["srid"], + paramDict=parameters, + parentWidget=None, + ) def checkAndCreateDataset(self, conversionStepMap): """ @@ -158,24 +183,28 @@ def checkAndCreateDataset(self, conversionStepMap): try: parameters = self.parseDatasourcePath(datasource=output) # filling missing parameters as required by dbCreator - parameters['srid'] = conversionStepMap['crs'].split(":")[-1] - parameters['isTemplateEdgv'] = True - parameters['version'], parameters['templateName'] = { - "EDGV 2.1.3" : ("2.1.3", 'template_edgv_213'), - "EDGV 2.1.3 F Ter" : ("FTer_2a_Ed", 'template_edgv_fter_2a_ed'), - "EDGV 2.1.3 Pro" : ("2.1.3 Pro", 'template_edgv_213_pro'), - "EDGV 3.0" : ("3.0", 'template_edgv_3') + parameters["srid"] = conversionStepMap["crs"].split(":")[-1] + parameters["isTemplateEdgv"] = True + parameters["version"], parameters["templateName"] = { + "EDGV 2.1.3": ("2.1.3", "template_edgv_213"), + "EDGV 2.1.3 F Ter": ("FTer_2a_Ed", "template_edgv_fter_2a_ed"), + "EDGV 2.1.3 Pro": ("2.1.3 Pro", "template_edgv_213_pro"), + "EDGV 3.0": ("3.0", "template_edgv_3") # "EDGV 3.0 Pro" : ("3.0", 'template_edgv_3_pro') - }[conversionStepMap['edgv']] - if 'path' in parameters: - parameters['db'] = os.path.basename(os.path.splitext(parameters['path'])[0]) + }[conversionStepMap["edgv"]] + if "path" in parameters: + parameters["db"] = os.path.basename( + os.path.splitext(parameters["path"])[0] + ) abstractDb = self.createDataset(parameters=parameters) msg = "" except Exception as e: if abstractDb is not None: abstractDb.closeDatabase() abstractDb = None - msg = "{0} dataset creation has failed: '{1}'".format(output, "; ".join(map(str, e.args))) + msg = "{0} dataset creation has failed: '{1}'".format( + output, "; ".join(map(str, e.args)) + ) return abstractDb, msg def getPgParamaters(self, parameters, conn): @@ -185,9 +214,9 @@ def getPgParamaters(self, parameters, conn): :param conn: (str) connection string. """ # connection string: USER@HOST:PORT.DATABASE - parameters['username'], part = conn.split('@') - parameters['host'], part = part.split(':') - parameters['port'], parameters['db'] = part.split('.') + parameters["username"], part = conn.split("@") + parameters["host"], part = part.split(":") + parameters["port"], parameters["db"] = part.split(".") def parseDatasourcePath(self, datasource): """ @@ -196,34 +225,34 @@ def parseDatasourcePath(self, datasource): :return: (dict) a dict containing all connection parameters. """ drivers = { - 'pg' : DsgEnums.DriverPostGIS, - 'sqlite' : DsgEnums.DriverSpatiaLite, - 'shp' : DsgEnums.DriverShapefile, - 'gpkg' : DsgEnums.DriverGeopackage - } + "pg": DsgEnums.DriverPostGIS, + "sqlite": DsgEnums.DriverSpatiaLite, + "shp": DsgEnums.DriverShapefile, + "gpkg": DsgEnums.DriverGeopackage, + } parameters = dict() - driver = datasource.split(':')[0] - conn = datasource[len(driver) + 1:] - if driver == 'pg': + driver = datasource.split(":")[0] + conn = datasource[len(driver) + 1 :] + if driver == "pg": self.getPgParamaters(parameters=parameters, conn=conn) else: - parameters['path'] = conn - parameters['driver'] = drivers[driver] + parameters["path"] = conn + parameters["driver"] = drivers[driver] return parameters def userPasswordFromHost(self, hostname, username): """ - Gets the password of an user to a server from its name. + Gets the password of an user to a server from its name. """ settings = QSettings() - settings.beginGroup('PostgreSQL/servers') + settings.beginGroup("PostgreSQL/servers") connections = settings.childGroups() settings.endGroup() for connection in connections: - settings.beginGroup('PostgreSQL/servers/{0}'.format(connection)) - host = settings.value('host') - user = settings.value('username') - password = settings.value('password') + settings.beginGroup("PostgreSQL/servers/{0}".format(connection)) + host = settings.value("host") + user = settings.value("username") + password = settings.value("password") settings.endGroup() if host == hostname and username == user: return password @@ -235,12 +264,21 @@ def connectToPostgis(self, parameters): :param parameters: (dict) a dict containing all connection parameters. :return: (AbstractDb) returns the DSGTools database object. """ - user, host, port, db = parameters['username'], parameters['host'], parameters['port'], parameters['db'] + user, host, port, db = ( + parameters["username"], + parameters["host"], + parameters["port"], + parameters["db"], + ) # initiate abstractDb abstractDb = DbFactory().createDbFactory(driver=DsgEnums.DriverPostGIS) # ignore all info except for the password password = self.userPasswordFromHost(hostname=host, username=user) - return abstractDb if abstractDb.testCredentials(host, port, db, user, password) else None + return ( + abstractDb + if abstractDb.testCredentials(host, port, db, user, password) + else None + ) def connectToSpatialite(self, parameters): """ @@ -249,9 +287,9 @@ def connectToSpatialite(self, parameters): :return: (AbstractDb) returns the DSGTools database object. """ abstractDb = None - if os.path.exists(parameters['path']): + if os.path.exists(parameters["path"]): abstractDb = DbFactory().createDbFactory(driver=DsgEnums.DriverSpatiaLite) - abstractDb.connectDatabase(conn=parameters['path']) + abstractDb.connectDatabase(conn=parameters["path"]) return abstractDb def connectToGeopackage(self, parameters): @@ -261,9 +299,9 @@ def connectToGeopackage(self, parameters): :return: (AbstractDb) returns the DSGTools database object. """ abstractDb = None - if os.path.exists(parameters['path']): + if os.path.exists(parameters["path"]): abstractDb = DbFactory().createDbFactory(driver=DsgEnums.DriverGeopackage) - abstractDb.connectDatabase(conn=parameters['path']) + abstractDb.connectDatabase(conn=parameters["path"]) return abstractDb def connectToShapefile(self, parameters): @@ -273,8 +311,8 @@ def connectToShapefile(self, parameters): :return: (AbstractDb) returns the DSGTools database object. """ abstractDb = DbFactory().createDbFactory(driver=DsgEnums.DriverShapefile) - abstractDb.connectDatabase(conn=parameters['path']) - return abstractDb if abstractDb.getDatabaseName() != '' else None + abstractDb.connectDatabase(conn=parameters["path"]) + return abstractDb if abstractDb.getDatabaseName() != "" else None def connectToDb(self, parameters): """ @@ -283,12 +321,20 @@ def connectToDb(self, parameters): :return: (AbstractDb) returns the DSGTools database object. """ drivers = { - DsgEnums.DriverPostGIS : lambda : self.connectToPostgis(parameters=parameters), - DsgEnums.DriverSpatiaLite : lambda : self.connectToSpatialite(parameters=parameters), - DsgEnums.DriverGeopackage : lambda : self.connectToGeopackage(parameters=parameters), - DsgEnums.DriverShapefile : lambda : self.connectToShapefile(parameters=parameters) + DsgEnums.DriverPostGIS: lambda: self.connectToPostgis( + parameters=parameters + ), + DsgEnums.DriverSpatiaLite: lambda: self.connectToSpatialite( + parameters=parameters + ), + DsgEnums.DriverGeopackage: lambda: self.connectToGeopackage( + parameters=parameters + ), + DsgEnums.DriverShapefile: lambda: self.connectToShapefile( + parameters=parameters + ), } - driver = parameters['driver'] + driver = parameters["driver"] return drivers[driver]() if driver in drivers else None def getSpatialFilterBehaviour(self, predicate): @@ -298,11 +344,7 @@ def getSpatialFilterBehaviour(self, predicate): :param spatialFilter: (str) spatial predicate. :return: (int) behaviour code. """ - predicates = { - "Intersects" : 1, - "Clip" : 2, - "Buffer" : 3 - } + predicates = {"Intersects": 1, "Clip": 2, "Buffer": 3} return predicates[predicate] if predicate in predicates else None def readInputLayers(self, datasourcePath, feedback=None): @@ -319,11 +361,17 @@ def readInputLayers(self, datasourcePath, feedback=None): return {} layerLoader = LayerLoaderFactory().makeLoader(self.iface, abstractDb) - geometricLayers = list(abstractDb.listClassesWithElementsFromDatabase([]).keys()) + geometricLayers = list( + abstractDb.listClassesWithElementsFromDatabase([]).keys() + ) complexLayers = abstractDb.listComplexClassesFromDatabase() if feedback is not None: - stepSize = 100 / (len(geometricLayers) + len(complexLayers)) if len(geometricLayers) + len(complexLayers) else 0 + stepSize = ( + 100 / (len(geometricLayers) + len(complexLayers)) + if len(geometricLayers) + len(complexLayers) + else 0 + ) curr = 0 for curr, l in enumerate(geometricLayers): if feedback is not None and feedback.isCanceled(): @@ -332,7 +380,7 @@ def readInputLayers(self, datasourcePath, feedback=None): inputLayerMap[vl.name()] = vl if feedback is not None: feedback.setProgress(curr * stepSize) - + for currComplex, l in enumerate(complexLayers): if feedback is not None and feedback.isCanceled(): return inputLayerMap @@ -363,16 +411,18 @@ def readOutputLayers(self, datasourcePath, feedback=None): geometricLayers = abstractDb.listGeomClassesFromDatabase([]) complexLayers = abstractDb.listComplexClassesFromDatabase() if feedback is not None: - multiStepFeedback = QgsProcessingMultiStepFeedback(len(geometricLayers) + len(complexLayers), feedback) - - for curr, l in enumerate(geometricLayers): + multiStepFeedback = QgsProcessingMultiStepFeedback( + len(geometricLayers) + len(complexLayers), feedback + ) + + for curr, l in enumerate(geometricLayers): if feedback is not None and multiStepFeedback.isCanceled(): return outputLayerMap vl = layerLoader.getLayerByName(l) outputLayerMap[vl.name()] = vl if feedback is not None: multiStepFeedback.setCurrentStep(curr) - + for currComplex, l in enumerate(complexLayers): if feedback is not None and multiStepFeedback.isCanceled(): return outputLayerMap @@ -392,20 +442,28 @@ def prepareSpatialFilterLayer(self, spatialFilters, context=None): :return: (QgsVectorLayer) reference layer as requested in the spatial filters. """ # layer always comes from canvas - spatialFilterlLayer = QgsProject.instance().mapLayersByName(spatialFilters["layer"]) - spatialFilterlLayer = spatialFilterlLayer[0] if spatialFilterlLayer != [] else None + spatialFilterlLayer = QgsProject.instance().mapLayersByName( + spatialFilters["layer"] + ) + spatialFilterlLayer = ( + spatialFilterlLayer[0] if spatialFilterlLayer != [] else None + ) if spatialFilters["expression"]: context = context if context is not None else QgsProcessingContext() - spatialFilterlLayer = LayerHandler().filterByExpression(layer=spatialFilterlLayer,\ - expression=spatialFilters["expression"],\ - context=context) + spatialFilterlLayer = LayerHandler().filterByExpression( + layer=spatialFilterlLayer, + expression=spatialFilters["expression"], + context=context, + ) return spatialFilterlLayer - def prepareInputLayers(self, inputLayers, stepConversionMap, context=None, feedback=None): + def prepareInputLayers( + self, inputLayers, stepConversionMap, context=None, feedback=None + ): """ Prepare layers for a translation unit (step) to be executed (e.g. applies filters). :param inputLayers: (dict) a map from layer name to each vector layer contained by the - input datasource. + input datasource. :param stepConversionMap: (dict) conversion map generated by Datasource Conversion tool for a conversion step. :param context: (QgsProcessingContext) environment parameters in which processing tools are used. @@ -417,11 +475,17 @@ def prepareInputLayers(self, inputLayers, stepConversionMap, context=None, feedb layerFilters = stepConversionMap["filter"]["layer_filter"] spatialFilters = stepConversionMap["filter"]["spatial_filter"] # in case a selection of layers was made, only chosen layers should be translated - inputLayers = inputLayers if layerFilters == {} else {layer : inputLayers[layer] for layer in layerFilters} + inputLayers = ( + inputLayers + if layerFilters == {} + else {layer: inputLayers[layer] for layer in layerFilters} + ) multiStepFeedback = QgsProcessingMultiStepFeedback(len(inputLayers), feedback) if spatialFilters: # spatial filtering behaviour is set based on the modes defined in convertLayer2LayerAlgorithm - behaviour = self.getSpatialFilterBehaviour(spatialFilters["predicate"] if "predicate" in spatialFilters else None) + behaviour = self.getSpatialFilterBehaviour( + spatialFilters["predicate"] if "predicate" in spatialFilters else None + ) spatialFilterLayer = self.prepareSpatialFilterLayer(spatialFilters, context) else: behaviour = None @@ -435,19 +499,27 @@ def prepareInputLayers(self, inputLayers, stepConversionMap, context=None, feedb break currentStep += 1 translatedLayer = lh.prepareConversion( - inputLyr=vl, - context=context, - inputExpression=layerFilters[layer]["expression"] if layer in layerFilters else None, - filterLyr=spatialFilterLayer, - behavior=behaviour, - conversionMap=stepConversionMap, - feedback=multiStepFeedback if feedback is not None else None - ) + inputLyr=vl, + context=context, + inputExpression=layerFilters[layer]["expression"] + if layer in layerFilters + else None, + filterLyr=spatialFilterLayer, + behavior=behaviour, + conversionMap=stepConversionMap, + feedback=multiStepFeedback if feedback is not None else None, + ) if translatedLayer.featureCount() > 0: preparedLayers[layer] = translatedLayer return preparedLayers - def mapFeatures(self, inputPreparedLayers, outputLayers, featureConversionMap=None, feedback=None): + def mapFeatures( + self, + inputPreparedLayers, + outputLayers, + featureConversionMap=None, + feedback=None, + ): """ Maps features from a given set of layers to a different set of layers (including attributes). :param inputPreparedLayers: (dict) map of layers to be translated. @@ -464,32 +536,36 @@ def mapFeatures(self, inputPreparedLayers, outputLayers, featureConversionMap=No lh = LayerHandler() fh = FeatureHandler() if feedback is not None: - stepSize = 100 / len(inputPreparedLayers) if len(inputPreparedLayers) else 0 + stepSize = ( + 100 / len(inputPreparedLayers) if len(inputPreparedLayers) else 0 + ) for current, (layer, vl) in enumerate(inputPreparedLayers.items()): if feedback is not None and feedback.isCanceled(): - break + break if vl.featureCount() == 0 or layer not in outputLayers: continue outuputLayer = outputLayers[layer] k = "{0}->{1}".format(vl.crs().authid(), outuputLayer.crs().authid()) if k not in self.coordinateTransformers: - self.coordinateTransformers[k] = lh.getCoordinateTransformer(inputLyr=vl, outputLyr=outuputLayer) + self.coordinateTransformers[k] = lh.getCoordinateTransformer( + inputLyr=vl, outputLyr=outuputLayer + ) coordinateTransformer = self.coordinateTransformers[k] param = lh.getDestinationParameters(vl) for feature in vl.getFeatures(QgsFeatureRequest()): featuresMap[layer] |= fh.handleConvertedFeature( - feat=feature, - lyr=outuputLayer, - parameterDict=param, - coordinateTransformer=coordinateTransformer - ) + feat=feature, + lyr=outuputLayer, + parameterDict=param, + coordinateTransformer=coordinateTransformer, + ) if feedback is not None: feedback.setProgress(current * stepSize) return featuresMap # def fanOut(self, inputLayers, preparedLayers, referenceLayer, fanOutFieldName, context=None, feedback=None): # """ - + # """ # idx = referenceLayer.fields().indexFromName(fanOutFieldName) # reference = referenceLayer.uniqueValues(idx) @@ -513,7 +589,14 @@ def mapFeatures(self, inputPreparedLayers, outputLayers, featureConversionMap=No # fannedOutLayers[value][layer] = fannedOut # return fannedOutLayers - def loadToOuput(self, featuresMap, outputLayers, conversionMode, featureConversionMap=None, feedback=None): + def loadToOuput( + self, + featuresMap, + outputLayers, + conversionMode, + featureConversionMap=None, + feedback=None, + ): """ Loads converted features to output dataset. :param preparedLayers: (dict) map of (list-of-QgsFeature) features to be added to output layer. @@ -542,10 +625,14 @@ def loadToOuput(self, featuresMap, outputLayers, conversionMode, featureConversi count += vl.addFeature(featureSet.pop()) vl.updateExtents() if vl.commitChanges(): - self.conversionUpdated.emit(self.tr("{0} successfully loaded.").format(vl.name())) + self.conversionUpdated.emit( + self.tr("{0} successfully loaded.").format(vl.name()) + ) success[layer] = count else: - self.conversionUpdated.emit(self.tr("{0} failed to be loaded.").format(vl.name())) + self.conversionUpdated.emit( + self.tr("{0} failed to be loaded.").format(vl.name()) + ) fail[layer] = outputLayers[layer].commitErrors()[0] if feedback is not None: feedback.setProgress(current * stepSize) @@ -557,10 +644,27 @@ def getLogHeader(self): """ # any header info insertion should be through template # header's data handling should be in this method! - with open(os.path.join(os.path.dirname(__file__), 'Templates', 'headerConversionSummaryTemplate.html'), 'r') as f: + with open( + os.path.join( + os.path.dirname(__file__), + "Templates", + "headerConversionSummaryTemplate.html", + ), + "r", + ) as f: return f.read() - def addConversionStepToLog(self, conversionStep, inputDb, outputDb, inputLayers, creationErrors, successfulLayers, failedLayers, elapsedTime): + def addConversionStepToLog( + self, + conversionStep, + inputDb, + outputDb, + inputLayers, + creationErrors, + successfulLayers, + failedLayers, + elapsedTime, + ): """ Builds conversion summary log message. :param conversionStep: (int) current conversion step. @@ -573,11 +677,18 @@ def addConversionStepToLog(self, conversionStep, inputDb, outputDb, inputLayers, :param elapsedTime: (str) current step elapsed time. :return: (str) conversion step HTML text. """ - with open(os.path.join(os.path.dirname(__file__), 'Templates', 'bodyConversionSummaryTemplate.html'), 'r') as f: + with open( + os.path.join( + os.path.dirname(__file__), + "Templates", + "bodyConversionSummaryTemplate.html", + ), + "r", + ) as f: bodyHtml = f.read() - bodyHtml = bodyHtml.replace('CONVERSION_STEP', str(conversionStep)) - bodyHtml = bodyHtml.replace('INPUT_DATASET', inputDb) - bodyHtml = bodyHtml.replace('OUTPUT_DATASET', outputDb) + bodyHtml = bodyHtml.replace("CONVERSION_STEP", str(conversionStep)) + bodyHtml = bodyHtml.replace("INPUT_DATASET", inputDb) + bodyHtml = bodyHtml.replace("OUTPUT_DATASET", outputDb) inputTable = "" for layer, vl in inputLayers.items(): inputTable += """ @@ -585,8 +696,10 @@ def addConversionStepToLog(self, conversionStep, inputDb, outputDb, inputLayers, {0} {1} - """.format(layer, len([f for f in vl.getFeatures()])) - bodyHtml = bodyHtml.replace('INPUT_TABLE', inputTable) + """.format( + layer, len([f for f in vl.getFeatures()]) + ) + bodyHtml = bodyHtml.replace("INPUT_TABLE", inputTable) outputTable = "" for layer, feat_count in successfulLayers.items(): outputTable += """ @@ -594,8 +707,10 @@ def addConversionStepToLog(self, conversionStep, inputDb, outputDb, inputLayers, {0} {1} - """.format(layer, feat_count) - bodyHtml = bodyHtml.replace('OUTPUT_TABLE', outputTable) + """.format( + layer, feat_count + ) + bodyHtml = bodyHtml.replace("OUTPUT_TABLE", outputTable) dsErrors = "" if "{0} to {1}".format(inputDb, outputDb) in creationErrors: dsErrors = """ @@ -603,8 +718,10 @@ def addConversionStepToLog(self, conversionStep, inputDb, outputDb, inputLayers, {0} {1} - """.format(outputDb, creationErrors["{0} to {1}".format(inputDb, outputDb)]) - bodyHtml = bodyHtml.replace('DATASET_CREATION_ERROR', dsErrors) + """.format( + outputDb, creationErrors["{0} to {1}".format(inputDb, outputDb)] + ) + bodyHtml = bodyHtml.replace("DATASET_CREATION_ERROR", dsErrors) errors = "" for layer, reason in failedLayers.items(): errors += """ @@ -612,11 +729,15 @@ def addConversionStepToLog(self, conversionStep, inputDb, outputDb, inputLayers, {0} {1} - """.format(layer, reason) - bodyHtml = bodyHtml.replace('WRITTING_ERRORS', errors) - return bodyHtml.replace('STEP_ELAPSED_TIME', elapsedTime) + "\n" + """.format( + layer, reason + ) + bodyHtml = bodyHtml.replace("WRITTING_ERRORS", errors) + return bodyHtml.replace("STEP_ELAPSED_TIME", elapsedTime) + "\n" - def convertFromMap(self, conversionMap=None, featureConversionMap=None, feedback=None): + def convertFromMap( + self, conversionMap=None, featureConversionMap=None, feedback=None + ): """ Converts all datasets from a conversion map. :param conversionMap: (dict) conversion map generated by Datasource Conversion tool. @@ -644,10 +765,16 @@ def convertFromMap(self, conversionMap=None, featureConversionMap=None, feedback multiStepFeedback.setCurrentStep(currentStep) currentStep += 1 # input setup - self.conversionUpdated.emit(self.tr("\nConversion Step {0} started...\n\n").format(conversionStep)) - self.conversionUpdated.emit(self.tr("[INPUT] Reading {0}'s layers...\n").format(inputDb)) + self.conversionUpdated.emit( + self.tr("\nConversion Step {0} started...\n\n").format(conversionStep) + ) + self.conversionUpdated.emit( + self.tr("[INPUT] Reading {0}'s layers...\n").format(inputDb) + ) if inputDb not in allInputLayers: - allInputLayers[inputDb] = self.readInputLayers(datasourcePath=inputDb, feedback=multiStepFeedback) + allInputLayers[inputDb] = self.readInputLayers( + datasourcePath=inputDb, feedback=multiStepFeedback + ) inputLayers = allInputLayers[inputDb] for currentOutput, conversionStepMap in enumerate(conversionStepMaps): startTime = time.time() @@ -657,57 +784,98 @@ def convertFromMap(self, conversionMap=None, featureConversionMap=None, feedback outputDb = conversionStepMap["outDs"] if outputDb not in allOutputLayers: if conversionStepMap["createDs"]: - self.conversionUpdated.emit(self.tr("[OUTPUT] Creating dataset {0}...\n").format(outputDb)) - outputAbstractDb, error = self.checkAndCreateDataset(conversionStepMap) + self.conversionUpdated.emit( + self.tr("[OUTPUT] Creating dataset {0}...\n").format( + outputDb + ) + ) + outputAbstractDb, error = self.checkAndCreateDataset( + conversionStepMap + ) del outputAbstractDb if error != "": k = "{0} to {1}".format(inputDb, outputDb) - self.conversionUpdated.emit(self.tr("Dataset creation error ({0}): '{1}'\n").format(outputDb, error)) + self.conversionUpdated.emit( + self.tr("Dataset creation error ({0}): '{1}'\n").format( + outputDb, error + ) + ) errors[k] = error - conversionSummary += self.addConversionStepToLog(conversionStep, inputDb, outputDb, \ - inputLayers, errors, {}, {}, "{0:.2f} s".format(time.time() - startTime)) + conversionSummary += self.addConversionStepToLog( + conversionStep, + inputDb, + outputDb, + inputLayers, + errors, + {}, + {}, + "{0:.2f} s".format(time.time() - startTime), + ) conversionStep += 1 continue - self.conversionUpdated.emit(self.tr("[OUTPUT] Reading {0}'s layers...\n").format(outputDb)) + self.conversionUpdated.emit( + self.tr("[OUTPUT] Reading {0}'s layers...\n").format(outputDb) + ) multiStepFeedback.setCurrentStep(currentStep) currentStep += 1 - allOutputLayers[outputDb] = self.readOutputLayers(datasourcePath=outputDb, feedback=multiStepFeedback) + allOutputLayers[outputDb] = self.readOutputLayers( + datasourcePath=outputDb, feedback=multiStepFeedback + ) outputLayers = allOutputLayers[outputDb] # now conversion starts - self.conversionUpdated.emit(self.tr("Preparing {0}'s layers for conversion...").format(inputDb)) + self.conversionUpdated.emit( + self.tr("Preparing {0}'s layers for conversion...").format(inputDb) + ) multiStepFeedback.setCurrentStep(currentStep) currentStep += 1 - preparedLayers = self.prepareInputLayers(inputLayers, conversionStepMap, feedback=multiStepFeedback) + preparedLayers = self.prepareInputLayers( + inputLayers, conversionStepMap, feedback=multiStepFeedback + ) self.conversionUpdated.emit(self.tr("Mapping features...")) multiStepFeedback.setCurrentStep(currentStep) currentStep += 1 - mappedFeatures = self.mapFeatures(preparedLayers, outputLayers, feedback=multiStepFeedback) + mappedFeatures = self.mapFeatures( + preparedLayers, outputLayers, feedback=multiStepFeedback + ) - self.conversionUpdated.emit(self.tr("Loading layers to {0}...").format(outputDb)) + self.conversionUpdated.emit( + self.tr("Loading layers to {0}...").format(outputDb) + ) multiStepFeedback.setCurrentStep(currentStep) currentStep += 1 successfulLayers, failedLayers = self.loadToOuput( - mappedFeatures, outputLayers, conversionStepMap["conversionMode"],\ - feedback=multiStepFeedback - ) + mappedFeatures, + outputLayers, + conversionStepMap["conversionMode"], + feedback=multiStepFeedback, + ) # log update - conversionSummary += self.addConversionStepToLog(conversionStep, inputDb, outputDb, inputLayers, \ - errors, successfulLayers, failedLayers, "{0:.2f} s".format(time.time() - startTime)) + conversionSummary += self.addConversionStepToLog( + conversionStep, + inputDb, + outputDb, + inputLayers, + errors, + successfulLayers, + failedLayers, + "{0:.2f} s".format(time.time() - startTime), + ) conversionStep += 1 self.conversionFinished.emit() return { - 'creationErrors' : errors, - 'successfulLayers' : successfulLayers, - 'failedLayers' : failedLayers, - 'status' : not feedback.isCanceled(), - 'log' : conversionSummary + "creationErrors": errors, + "successfulLayers": successfulLayers, + "failedLayers": failedLayers, + "status": not feedback.isCanceled(), + "log": conversionSummary, } - + def run(self): elapsedTime = time.time() self.output = self.convertFromMap() - self.output['elapsedTime'] = "{0:.2f} s".format(time.time() - elapsedTime) - self.output['log'] = self.output['log'].replace('ELAPSED_TIME', self.output['elapsedTime']) - return self.output['status'] - + self.output["elapsedTime"] = "{0:.2f} s".format(time.time() - elapsedTime) + self.output["log"] = self.output["log"].replace( + "ELAPSED_TIME", self.output["elapsedTime"] + ) + return self.output["status"] diff --git a/DsgTools/core/EditingTools/editingHandler.py b/DsgTools/core/EditingTools/editingHandler.py index 68ab3a044..6cfcf03ff 100644 --- a/DsgTools/core/EditingTools/editingHandler.py +++ b/DsgTools/core/EditingTools/editingHandler.py @@ -21,5 +21,6 @@ ***************************************************************************/ """ + class EditingHandler: - pass \ No newline at end of file + pass diff --git a/DsgTools/core/EditingTools/enviromentSetter.py b/DsgTools/core/EditingTools/enviromentSetter.py index be334461b..d590a3069 100644 --- a/DsgTools/core/EditingTools/enviromentSetter.py +++ b/DsgTools/core/EditingTools/enviromentSetter.py @@ -20,14 +20,17 @@ * * ***************************************************************************/ """ -from DsgTools.core.Factories.LayerLoaderFactory.layerLoaderFactory import LayerLoaderFactory +from DsgTools.core.Factories.LayerLoaderFactory.layerLoaderFactory import ( + LayerLoaderFactory, +) from qgis.core import QgsProject + class EnviromentSetter: def __init__(self, iface): self.layerFactory = LayerLoaderFactory() self.iface = iface - + def setEnviroment(self, parameterDict): """ :param parameterDict (dict): dictionary with parameters @@ -39,22 +42,20 @@ def setEnviroment(self, parameterDict): 'framePolygon' : polygon of the working area } """ - #Step 1: Load layers + # Step 1: Load layers layerLoader = self.layerFactory.makeLoader( - iface=self.iface, - abstractDb=parameterDict['abstractDb'] + iface=self.iface, abstractDb=parameterDict["abstractDb"] ) loadedLayerDict = layerLoader.loadedLayers( - inputList=parameterDict['layerList'], - stylePath=parameterDict['stylePath'], - loadEditingStructure=True + inputList=parameterDict["layerList"], + stylePath=parameterDict["stylePath"], + loadEditingStructure=True, ) self.setLayerOrdering( - vectorLayerDict=loadedLayerDict, - layerOrder=parameterDict['layerList'] + vectorLayerDict=loadedLayerDict, layerOrder=parameterDict["layerList"] ) - self.createGrid(parameterDict['workingAreaPolygon']) - self.setWorkArea(parameterDict['workingAreaPolygon']) + self.createGrid(parameterDict["workingAreaPolygon"]) + self.setWorkArea(parameterDict["workingAreaPolygon"]) def createGrid(self, workingAreaPolygon): """ diff --git a/DsgTools/core/EditingTools/gridAndLabelCreator.py b/DsgTools/core/EditingTools/gridAndLabelCreator.py index 9e6346d77..ce1166fa6 100644 --- a/DsgTools/core/EditingTools/gridAndLabelCreator.py +++ b/DsgTools/core/EditingTools/gridAndLabelCreator.py @@ -22,13 +22,27 @@ """ from builtins import str, range, abs, round from math import floor, ceil, pow -from qgis.core import QgsProject, QgsVectorLayer, QgsCoordinateTransform, \ - QgsCoordinateReferenceSystem, QgsFillSymbol, QgsLineSymbol, \ - QgsSimpleFillSymbolLayer, QgsSingleSymbolRenderer, \ - QgsInvertedPolygonRenderer, QgsRuleBasedRenderer, QgsPoint,\ - QgsGeometry, QgsGeometryGeneratorSymbolLayer -from qgis.core import QgsRuleBasedLabeling, QgsPalLayerSettings, QgsTextFormat, \ - QgsPropertyCollection +from qgis.core import ( + QgsProject, + QgsVectorLayer, + QgsCoordinateTransform, + QgsCoordinateReferenceSystem, + QgsFillSymbol, + QgsLineSymbol, + QgsSimpleFillSymbolLayer, + QgsSingleSymbolRenderer, + QgsInvertedPolygonRenderer, + QgsRuleBasedRenderer, + QgsPoint, + QgsGeometry, + QgsGeometryGeneratorSymbolLayer, +) +from qgis.core import ( + QgsRuleBasedLabeling, + QgsPalLayerSettings, + QgsTextFormat, + QgsPropertyCollection, +) from qgis.utils import iface from qgis.gui import QgsMessageBar from PyQt5.QtGui import QColor, QFont @@ -37,12 +51,57 @@ class GridAndLabelCreator(object): def __init__(self, parent=None): super(GridAndLabelCreator, self).__init__() - - def geo_test(self, layer, index, id_attr, id_value, spacing, crossX, crossY, scale, color, fontSize, font, fontLL, llcolor): + + def geo_test( + self, + layer, + index, + id_attr, + id_value, + spacing, + crossX, + crossY, + scale, + color, + fontSize, + font, + fontLL, + llcolor, + ): if layer.crs().isGeographic() == False: - self.styleCreator(layer, index, id_attr, id_value, spacing, crossX, crossY, scale, color, fontSize, font, fontLL, llcolor, True) + self.styleCreator( + layer, + index, + id_attr, + id_value, + spacing, + crossX, + crossY, + scale, + color, + fontSize, + font, + fontLL, + llcolor, + True, + ) else: - self.styleCreator(layer, index, id_attr, id_value, spacing, crossX, crossY, scale, color, fontSize, font, fontLL, llcolor, False) + self.styleCreator( + layer, + index, + id_attr, + id_value, + spacing, + crossX, + crossY, + scale, + color, + fontSize, + font, + fontLL, + llcolor, + False, + ) pass def utmLLtransform(self, utmcheck, p1, trLLUTM): @@ -51,21 +110,47 @@ def utmLLtransform(self, utmcheck, p1, trLLUTM): return p1 pass - def crossLinegenerator(self, xmin_source, ymin_source, px, py, u, t, dx, dy, utmcheck, trLLUTM): - p1 = QgsPoint(xmin_source+px*u, ymin_source+py*t) - p2 = QgsPoint(xmin_source+px*u+dx, ymin_source+py*t+dy) + def crossLinegenerator( + self, xmin_source, ymin_source, px, py, u, t, dx, dy, utmcheck, trLLUTM + ): + p1 = QgsPoint(xmin_source + px * u, ymin_source + py * t) + p2 = QgsPoint(xmin_source + px * u + dx, ymin_source + py * t + dy) self.utmLLtransform(utmcheck, p1, trLLUTM) self.utmLLtransform(utmcheck, p2, trLLUTM) - properties = {'color': 'black'} + properties = {"color": "black"} line_temp = QgsLineSymbol.createSimple(properties) line_temp.setWidth(0.05) symb = QgsGeometryGeneratorSymbolLayer.create(properties) symb.setSymbolType(1) symb.setSubSymbol(line_temp) - symb.setGeometryExpression('make_line(make_point('+str(p1.x())+',('+str(p1.y())+')),make_point('+str(p2.x())+',('+str(p2.y())+')))') + symb.setGeometryExpression( + "make_line(make_point(" + + str(p1.x()) + + ",(" + + str(p1.y()) + + ")),make_point(" + + str(p2.x()) + + ",(" + + str(p2.y()) + + ")))" + ) return symb - def gridLinesymbolMaker(self, x1, y1, x2, y2, xmax_source, xmin_source, ymax_source, ymin_source, trUTMLL, trLLUTM, utmcheck, isVertical): + def gridLinesymbolMaker( + self, + x1, + y1, + x2, + y2, + xmax_source, + xmin_source, + ymax_source, + ymin_source, + trUTMLL, + trLLUTM, + utmcheck, + isVertical, + ): a1 = QgsPoint(x1, y1) a2 = QgsPoint(x2, y2) a1.transform(trUTMLL) @@ -80,9 +165,25 @@ def gridLinesymbolMaker(self, x1, y1, x2, y2, xmax_source, xmin_source, ymax_sou p2 = QgsPoint(xmax_source, a2.y()) self.utmLLtransform(utmcheck, p1, trLLUTM) self.utmLLtransform(utmcheck, p2, trLLUTM) - return [a1,a2,p1,p2] + return [a1, a2, p1, p2] - def utm_symb_generator(self, grid_spacing, trUTMLL, trLLUTM, grid_symb, properties, geo_number_x, geo_number_y, UTM_num_x, UTM_num_y, t, u, geo_bound_bb, bound_UTM_bb, utmcheck): + def utm_symb_generator( + self, + grid_spacing, + trUTMLL, + trLLUTM, + grid_symb, + properties, + geo_number_x, + geo_number_y, + UTM_num_x, + UTM_num_y, + t, + u, + geo_bound_bb, + bound_UTM_bb, + utmcheck, + ): xmin_source = float(geo_bound_bb.split()[1]) ymin_source = float(geo_bound_bb.split()[2]) xmax_source = float(geo_bound_bb.split()[3]) @@ -91,156 +192,416 @@ def utm_symb_generator(self, grid_spacing, trUTMLL, trLLUTM, grid_symb, properti ymin_UTM = float(bound_UTM_bb.split()[2]) xmax_UTM = float(bound_UTM_bb.split()[3]) ymax_UTM = float(bound_UTM_bb.split()[4]) - test_line = [None]*2 - properties = {'color': 'black'} + test_line = [None] * 2 + properties = {"color": "black"} line_temp = QgsLineSymbol.createSimple(properties) line_temp.setWidth(0.05) symb = QgsGeometryGeneratorSymbolLayer.create(properties) symb.setSymbolType(1) symb.setSubSymbol(line_temp) - #Test First And Last Grid Lines - #Vertical + # Test First And Last Grid Lines + # Vertical if (t == 1 and u == 0) or (t == UTM_num_x and u == 0): - #Symbol vertices - auxPointlist = self.gridLinesymbolMaker(((floor(xmin_UTM/grid_spacing)+t)*grid_spacing), ymin_UTM, ((floor(xmin_UTM/grid_spacing)+t)*grid_spacing), ymax_UTM, xmax_source, xmin_source, ymax_source, ymin_source, trUTMLL, trLLUTM, utmcheck, True) - #0: left bound; 1: right bound - test_line[0] = QgsGeometry.fromWkt('LINESTRING ('+str(xmin_source)+' '+str(ymin_source)+','+str(xmin_source)+' '+str(ymax_source)+')') - test_line[1] = QgsGeometry.fromWkt('LINESTRING ('+str(xmax_source)+' '+str(ymin_source)+','+str(xmax_source)+' '+str(ymax_source)+')') - test_grid = QgsGeometry.fromPolyline([auxPointlist[0],auxPointlist[1]]) + # Symbol vertices + auxPointlist = self.gridLinesymbolMaker( + ((floor(xmin_UTM / grid_spacing) + t) * grid_spacing), + ymin_UTM, + ((floor(xmin_UTM / grid_spacing) + t) * grid_spacing), + ymax_UTM, + xmax_source, + xmin_source, + ymax_source, + ymin_source, + trUTMLL, + trLLUTM, + utmcheck, + True, + ) + # 0: left bound; 1: right bound + test_line[0] = QgsGeometry.fromWkt( + "LINESTRING (" + + str(xmin_source) + + " " + + str(ymin_source) + + "," + + str(xmin_source) + + " " + + str(ymax_source) + + ")" + ) + test_line[1] = QgsGeometry.fromWkt( + "LINESTRING (" + + str(xmax_source) + + " " + + str(ymin_source) + + "," + + str(xmax_source) + + " " + + str(ymax_source) + + ")" + ) + test_grid = QgsGeometry.fromPolyline([auxPointlist[0], auxPointlist[1]]) if test_line[0].intersects(test_grid): mid_point = test_line[0].intersection(test_grid).vertexAt(0) self.utmLLtransform(utmcheck, mid_point, trLLUTM) if auxPointlist[0].x() > auxPointlist[1].x(): - symb.setGeometryExpression('make_line(make_point('+str(auxPointlist[2].x())+','+str(auxPointlist[2].y())+'), make_point('+str(mid_point.x())+','+str(mid_point.y())+'))') + symb.setGeometryExpression( + "make_line(make_point(" + + str(auxPointlist[2].x()) + + "," + + str(auxPointlist[2].y()) + + "), make_point(" + + str(mid_point.x()) + + "," + + str(mid_point.y()) + + "))" + ) else: - symb.setGeometryExpression('make_line(make_point('+str(mid_point.x())+','+str(mid_point.y())+'), make_point('+str(auxPointlist[3].x())+','+str(auxPointlist[3].y())+'))') + symb.setGeometryExpression( + "make_line(make_point(" + + str(mid_point.x()) + + "," + + str(mid_point.y()) + + "), make_point(" + + str(auxPointlist[3].x()) + + "," + + str(auxPointlist[3].y()) + + "))" + ) elif test_line[1].intersects(test_grid): mid_point = test_line[1].intersection(test_grid).vertexAt(0) self.utmLLtransform(utmcheck, mid_point, trLLUTM) if auxPointlist[0].x() < auxPointlist[1].x(): - symb.setGeometryExpression('make_line(make_point('+str(auxPointlist[2].x())+','+str(auxPointlist[2].y())+'), make_point('+str(mid_point.x())+','+str(mid_point.y())+'))') + symb.setGeometryExpression( + "make_line(make_point(" + + str(auxPointlist[2].x()) + + "," + + str(auxPointlist[2].y()) + + "), make_point(" + + str(mid_point.x()) + + "," + + str(mid_point.y()) + + "))" + ) else: - symb.setGeometryExpression('make_line(make_point('+str(mid_point.x())+','+str(mid_point.y())+'), make_point('+str(auxPointlist[3].x())+','+str(auxPointlist[3].y())+'))') + symb.setGeometryExpression( + "make_line(make_point(" + + str(mid_point.x()) + + "," + + str(mid_point.y()) + + "), make_point(" + + str(auxPointlist[3].x()) + + "," + + str(auxPointlist[3].y()) + + "))" + ) else: - symb.setGeometryExpression('make_line(make_point('+str(auxPointlist[2].x())+','+str(auxPointlist[2].y())+'), make_point('+str(auxPointlist[3].x())+','+str(auxPointlist[3].y())+'))') + symb.setGeometryExpression( + "make_line(make_point(" + + str(auxPointlist[2].x()) + + "," + + str(auxPointlist[2].y()) + + "), make_point(" + + str(auxPointlist[3].x()) + + "," + + str(auxPointlist[3].y()) + + "))" + ) - #Horizontal + # Horizontal elif (u == 1 and t == 0) or (u == UTM_num_y and t == 0): - #Symbol vertices - auxPointlist = self.gridLinesymbolMaker(xmin_UTM, ((floor(ymin_UTM/grid_spacing)+u)*grid_spacing), xmax_UTM, ((floor(ymin_UTM/grid_spacing)+u)*grid_spacing), xmax_source, xmin_source, ymax_source, ymin_source, trUTMLL, trLLUTM, utmcheck, False) - #0: bottom bound; 1: upper bound - test_line[0] = QgsGeometry.fromWkt('LINESTRING ('+str(xmin_source)+' '+str(ymin_source)+','+str(xmax_source)+' '+str(ymin_source)+')') - test_line[1] = QgsGeometry.fromWkt('LINESTRING ('+str(xmin_source)+' '+str(ymax_source)+','+str(xmax_source)+' '+str(ymax_source)+')') - test_grid = QgsGeometry.fromPolyline([auxPointlist[0],auxPointlist[1]]) + # Symbol vertices + auxPointlist = self.gridLinesymbolMaker( + xmin_UTM, + ((floor(ymin_UTM / grid_spacing) + u) * grid_spacing), + xmax_UTM, + ((floor(ymin_UTM / grid_spacing) + u) * grid_spacing), + xmax_source, + xmin_source, + ymax_source, + ymin_source, + trUTMLL, + trLLUTM, + utmcheck, + False, + ) + # 0: bottom bound; 1: upper bound + test_line[0] = QgsGeometry.fromWkt( + "LINESTRING (" + + str(xmin_source) + + " " + + str(ymin_source) + + "," + + str(xmax_source) + + " " + + str(ymin_source) + + ")" + ) + test_line[1] = QgsGeometry.fromWkt( + "LINESTRING (" + + str(xmin_source) + + " " + + str(ymax_source) + + "," + + str(xmax_source) + + " " + + str(ymax_source) + + ")" + ) + test_grid = QgsGeometry.fromPolyline([auxPointlist[0], auxPointlist[1]]) if test_line[0].intersects(test_grid): mid_point = test_line[0].intersection(test_grid).vertexAt(0) self.utmLLtransform(utmcheck, mid_point, trLLUTM) if auxPointlist[0].y() > auxPointlist[1].y(): - symb.setGeometryExpression('make_line(make_point('+str(auxPointlist[2].x())+','+str(auxPointlist[2].y())+'), make_point('+str(mid_point.x())+','+str(mid_point.y())+'))') + symb.setGeometryExpression( + "make_line(make_point(" + + str(auxPointlist[2].x()) + + "," + + str(auxPointlist[2].y()) + + "), make_point(" + + str(mid_point.x()) + + "," + + str(mid_point.y()) + + "))" + ) else: - symb.setGeometryExpression('make_line(make_point('+str(mid_point.x())+','+str(mid_point.y())+'), make_point('+str(auxPointlist[3].x())+','+str(auxPointlist[3].y())+'))') + symb.setGeometryExpression( + "make_line(make_point(" + + str(mid_point.x()) + + "," + + str(mid_point.y()) + + "), make_point(" + + str(auxPointlist[3].x()) + + "," + + str(auxPointlist[3].y()) + + "))" + ) elif test_line[1].intersects(test_grid): mid_point = test_line[1].intersection(test_grid).vertexAt(0) self.utmLLtransform(utmcheck, mid_point, trLLUTM) if auxPointlist[0].y() < auxPointlist[1].y(): - symb.setGeometryExpression('make_line(make_point('+str(auxPointlist[2].x())+','+str(auxPointlist[2].y())+'), make_point('+str(mid_point.x())+','+str(mid_point.y())+'))') + symb.setGeometryExpression( + "make_line(make_point(" + + str(auxPointlist[2].x()) + + "," + + str(auxPointlist[2].y()) + + "), make_point(" + + str(mid_point.x()) + + "," + + str(mid_point.y()) + + "))" + ) else: - symb.setGeometryExpression('make_line(make_point('+str(mid_point.x())+','+str(mid_point.y())+'), make_point('+str(auxPointlist[3].x())+','+str(auxPointlist[3].y())+'))') + symb.setGeometryExpression( + "make_line(make_point(" + + str(mid_point.x()) + + "," + + str(mid_point.y()) + + "), make_point(" + + str(auxPointlist[3].x()) + + "," + + str(auxPointlist[3].y()) + + "))" + ) else: - symb.setGeometryExpression("make_line(make_point("+str(auxPointlist[2].x())+","+str(auxPointlist[2].y())+"), make_point("+str(auxPointlist[3].x())+","+str(auxPointlist[3].y())+"))") - - #Inner Grid Lines - #Vertical - elif (not(t == 1)) and (not(t == UTM_num_x)) and u == 0: - auxPointlist = self.gridLinesymbolMaker(((floor(xmin_UTM/grid_spacing)+t)*grid_spacing), ymin_UTM, ((floor(xmin_UTM/grid_spacing)+t)*grid_spacing), ymax_UTM, xmax_source, xmin_source, ymax_source, ymin_source, trUTMLL, trLLUTM, utmcheck, True) - symb.setGeometryExpression('make_line(make_point('+str(auxPointlist[2].x())+','+str(auxPointlist[2].y())+'), make_point('+str(auxPointlist[3].x())+','+str(auxPointlist[3].y())+'))') - #Horizontal - elif (not(u == 1)) and (not(u == UTM_num_y)) and t == 0: - auxPointlist = self.gridLinesymbolMaker(xmin_UTM, ((floor(ymin_UTM/grid_spacing)+u)*grid_spacing), xmax_UTM, ((floor(ymin_UTM/grid_spacing)+u)*grid_spacing), xmax_source, xmin_source, ymax_source, ymin_source, trUTMLL, trLLUTM, utmcheck, False) - symb.setGeometryExpression("make_line(make_point("+str(auxPointlist[2].x())+","+str(auxPointlist[2].y())+"), make_point("+str(auxPointlist[3].x())+","+str(auxPointlist[3].y())+"))") + symb.setGeometryExpression( + "make_line(make_point(" + + str(auxPointlist[2].x()) + + "," + + str(auxPointlist[2].y()) + + "), make_point(" + + str(auxPointlist[3].x()) + + "," + + str(auxPointlist[3].y()) + + "))" + ) + + # Inner Grid Lines + # Vertical + elif (not (t == 1)) and (not (t == UTM_num_x)) and u == 0: + auxPointlist = self.gridLinesymbolMaker( + ((floor(xmin_UTM / grid_spacing) + t) * grid_spacing), + ymin_UTM, + ((floor(xmin_UTM / grid_spacing) + t) * grid_spacing), + ymax_UTM, + xmax_source, + xmin_source, + ymax_source, + ymin_source, + trUTMLL, + trLLUTM, + utmcheck, + True, + ) + symb.setGeometryExpression( + "make_line(make_point(" + + str(auxPointlist[2].x()) + + "," + + str(auxPointlist[2].y()) + + "), make_point(" + + str(auxPointlist[3].x()) + + "," + + str(auxPointlist[3].y()) + + "))" + ) + # Horizontal + elif (not (u == 1)) and (not (u == UTM_num_y)) and t == 0: + auxPointlist = self.gridLinesymbolMaker( + xmin_UTM, + ((floor(ymin_UTM / grid_spacing) + u) * grid_spacing), + xmax_UTM, + ((floor(ymin_UTM / grid_spacing) + u) * grid_spacing), + xmax_source, + xmin_source, + ymax_source, + ymin_source, + trUTMLL, + trLLUTM, + utmcheck, + False, + ) + symb.setGeometryExpression( + "make_line(make_point(" + + str(auxPointlist[2].x()) + + "," + + str(auxPointlist[2].y()) + + "), make_point(" + + str(auxPointlist[3].x()) + + "," + + str(auxPointlist[3].y()) + + "))" + ) grid_symb.appendSymbolLayer(symb) return grid_symb - def grid_labeler(self, coord_base_x, coord_base_y, px, py, u, t, dx, dy, vAlign, hAlign, desc, fSize, fontType, expression_str, trLLUTM, trUTMLL, llcolor, utmcheck, scale): + def grid_labeler( + self, + coord_base_x, + coord_base_y, + px, + py, + u, + t, + dx, + dy, + vAlign, + hAlign, + desc, + fSize, + fontType, + expression_str, + trLLUTM, + trUTMLL, + llcolor, + utmcheck, + scale, + ): if utmcheck: - pgrid = QgsPoint(coord_base_x + px*u, coord_base_y + py*t) + pgrid = QgsPoint(coord_base_x + px * u, coord_base_y + py * t) pgrid.transform(trLLUTM) - pgrid = QgsPoint(pgrid.x()+ dx, pgrid.y()+ dy) + pgrid = QgsPoint(pgrid.x() + dx, pgrid.y() + dy) else: - pgrid = QgsPoint(coord_base_x + px*u + dx, coord_base_y + py*t + dy) + pgrid = QgsPoint(coord_base_x + px * u + dx, coord_base_y + py * t + dy) - #Label Format Settings + # Label Format Settings settings = QgsPalLayerSettings() settings.Placement = QgsPalLayerSettings.Free settings.isExpression = True textprop = QgsTextFormat() textprop.setColor(llcolor) textprop.setSizeUnit(1) - textprop.setSize(fSize*scale*1.324) + textprop.setSize(fSize * scale * 1.324) textprop.setFont(QFont(fontType)) textprop.setLineHeight(1) settings.setFormat(textprop) settings.fieldName = expression_str - #Label Name and Position + # Label Name and Position datadefined = QgsPropertyCollection() datadefined.setProperty(9, pgrid.x()) datadefined.setProperty(10, pgrid.y()) - if not(hAlign == ''): + if not (hAlign == ""): datadefined.setProperty(11, hAlign) - if not(vAlign == ''): + if not (vAlign == ""): datadefined.setProperty(12, vAlign) datadefined.setProperty(20, 1) - - #Creating and Activating Labeling Rule + + # Creating and Activating Labeling Rule settings.setDataDefinedProperties(datadefined) rule = QgsRuleBasedLabeling.Rule(settings) rule.setDescription(desc) rule.setActive(True) - - return rule - def utm_grid_labeler(self, root_rule, x_UTM, y_UTM, x_geo, y_geo, px, py, trUTMLL, trLLUTM, u, isVertical, dx, dy, dyO, dy1, vAlign, hAlign, desc, fSize, fontType, grid_spacing, scale, utmcheck, geo_bound_bb, rangetest, geo_bb_or): + return rule + def utm_grid_labeler( + self, + root_rule, + x_UTM, + y_UTM, + x_geo, + y_geo, + px, + py, + trUTMLL, + trLLUTM, + u, + isVertical, + dx, + dy, + dyO, + dy1, + vAlign, + hAlign, + desc, + fSize, + fontType, + grid_spacing, + scale, + utmcheck, + geo_bound_bb, + rangetest, + geo_bb_or, + ): - x_colec = [float(geo_bb_or.split()[2*i]) for i in range(1,5)] + x_colec = [float(geo_bb_or.split()[2 * i]) for i in range(1, 5)] x_colec.sort() - y_colec = [float(geo_bb_or.split()[2*i+1]) for i in range(1,5)] + y_colec = [float(geo_bb_or.split()[2 * i + 1]) for i in range(1, 5)] y_colec.sort() ang = float(geo_bb_or.split()[13]) if ang > 0: - if 'Bot' in desc: + if "Bot" in desc: x_min_test = x_colec[0] x_max_test = x_colec[2] - elif 'Up' in desc: + elif "Up" in desc: x_min_test = x_colec[1] x_max_test = x_colec[3] - elif 'Left' in desc: + elif "Left" in desc: y_min_test = y_colec[1] y_max_test = y_colec[3] - elif 'Right' in desc: + elif "Right" in desc: y_min_test = y_colec[0] y_max_test = y_colec[2] elif ang <= 0: - if 'Bot' in desc: + if "Bot" in desc: x_min_test = x_colec[1] x_max_test = x_colec[3] - elif 'Up' in desc: + elif "Up" in desc: x_min_test = x_colec[0] x_max_test = x_colec[2] - elif 'Left' in desc: + elif "Left" in desc: y_min_test = y_colec[0] y_max_test = y_colec[2] - elif 'Right' in desc: + elif "Right" in desc: y_min_test = y_colec[1] y_max_test = y_colec[3] x_min = float(geo_bound_bb.split()[1]) y_min = float(geo_bound_bb.split()[2]) x_max = float(geo_bound_bb.split()[3]) y_max = float(geo_bound_bb.split()[4]) - + # Check if is labeling grid's vertical lines if isVertical: # Displacing UTM Label that overlaps Geo Label @@ -249,189 +610,531 @@ def utm_grid_labeler(self, root_rule, x_UTM, y_UTM, x_geo, y_geo, px, py, trUTML else: dx0 = dx dx = 0 - test_plac = QgsPoint(((floor(x_UTM/grid_spacing)+u)*grid_spacing),y_UTM) + test_plac = QgsPoint( + ((floor(x_UTM / grid_spacing) + u) * grid_spacing), y_UTM + ) test_plac.transform(trUTMLL) - ancX = QgsPoint(((floor(x_UTM/grid_spacing)+u)*grid_spacing)+dx,y_UTM) + ancX = QgsPoint( + ((floor(x_UTM / grid_spacing) + u) * grid_spacing) + dx, y_UTM + ) ancX.transform(trUTMLL) - ancY = QgsPoint(ancX.x(),y_geo) + ancY = QgsPoint(ancX.x(), y_geo) if utmcheck: ancY.transform(trLLUTM) - test = QgsPoint(((floor(x_UTM/grid_spacing)+u)*grid_spacing),y_UTM) + test = QgsPoint(((floor(x_UTM / grid_spacing) + u) * grid_spacing), y_UTM) test.transform(trUTMLL) - if u == 1 and 'Up' in desc: + if u == 1 and "Up" in desc: deltaDneg = 0.0022 deltaDpos = 0.0011 - elif u == 1 and 'Bot' in desc: + elif u == 1 and "Bot" in desc: deltaDneg = 0.00125 deltaDpos = 0.0011 else: deltaDneg = 0.00095 deltaDpos = 0.0011 - testif = abs(floor(abs(round(test.x(), 4) - (x_min % (px)) - (deltaDneg*(fSize/1.5) * scale/10))/px) - floor(abs(round(test.x(), 4) - (x_min % (px)) + (deltaDpos*(fSize/1.5) * scale/10))/px)) + testif = abs( + floor( + abs( + round(test.x(), 4) + - (x_min % (px)) + - (deltaDneg * (fSize / 1.5) * scale / 10) + ) + / px + ) + - floor( + abs( + round(test.x(), 4) + - (x_min % (px)) + + (deltaDpos * (fSize / 1.5) * scale / 10) + ) + / px + ) + ) if testif >= 1: - ancY = QgsPoint(ancY.x(),ancY.y()+dyO) + ancY = QgsPoint(ancY.x(), ancY.y() + dyO) else: - ancY = QgsPoint(ancY.x(),ancY.y()+dy) + ancY = QgsPoint(ancY.x(), ancY.y() + dy) x = ancX.x() + dx0 if utmcheck: ancY.transform(trUTMLL) - y =ancY.y() - full_label = str((floor(x_UTM/grid_spacing)+u)*grid_spacing) - if test_plac.x() < (x_min_test + (0.0005 * scale/10)) or test_plac.x() > (x_max_test - (0.0005 * scale/10)): - rule_fake = self.grid_labeler(x, y, 0, 0, 0, 0, 0, 0, vAlign, hAlign, desc, fSize, fontType, 'fail', trLLUTM, trUTMLL, QColor('black'), utmcheck, scale) + y = ancY.y() + full_label = str((floor(x_UTM / grid_spacing) + u) * grid_spacing) + if test_plac.x() < (x_min_test + (0.0005 * scale / 10)) or test_plac.x() > ( + x_max_test - (0.0005 * scale / 10) + ): + rule_fake = self.grid_labeler( + x, + y, + 0, + 0, + 0, + 0, + 0, + 0, + vAlign, + hAlign, + desc, + fSize, + fontType, + "fail", + trLLUTM, + trUTMLL, + QColor("black"), + utmcheck, + scale, + ) root_rule.appendChild(rule_fake) return root_rule # Labeling grid's horizontal lines else: - test_plac = QgsPoint(x_UTM,(floor(y_UTM/grid_spacing)+u)*grid_spacing) + test_plac = QgsPoint( + x_UTM, (floor(y_UTM / grid_spacing) + u) * grid_spacing + ) test_plac.transform(trUTMLL) - ancX = QgsPoint(x_UTM,(floor(y_UTM/grid_spacing)+u)*grid_spacing) + ancX = QgsPoint(x_UTM, (floor(y_UTM / grid_spacing) + u) * grid_spacing) ancX.transform(trUTMLL) ancX = QgsPoint(x_geo, ancX.y()) ancY = QgsPoint(x_geo, ancX.y()) if utmcheck: ancY.transform(trLLUTM) # Displacing UTM Label it overlaps with Geo Label - test = QgsPoint(x_UTM,(floor(y_UTM/grid_spacing)+u)*grid_spacing) + test = QgsPoint(x_UTM, (floor(y_UTM / grid_spacing) + u) * grid_spacing) test.transform(trUTMLL) - testif = abs(floor(abs(round(test.y(), 4) - (y_min % (py)) - (0.0004*(fSize/1.5) * scale/10))/py) - floor(abs(round(test.y(), 4) - (y_min % (py)))/py)) + testif = abs( + floor( + abs( + round(test.y(), 4) + - (y_min % (py)) + - (0.0004 * (fSize / 1.5) * scale / 10) + ) + / py + ) + - floor(abs(round(test.y(), 4) - (y_min % (py))) / py) + ) if testif >= 1: - ancY = QgsPoint(ancY.x(),ancY.y()+dy1) + ancY = QgsPoint(ancY.x(), ancY.y() + dy1) else: - testif2 = abs(floor(abs(round(test.y(), 4) - (y_min % (py)))/py) - floor(abs(round(test.y(), 4) - (y_min % (py)) + (0.0004*(fSize/1.5) * scale/10))/py)) + testif2 = abs( + floor(abs(round(test.y(), 4) - (y_min % (py))) / py) + - floor( + abs( + round(test.y(), 4) + - (y_min % (py)) + + (0.0004 * (fSize / 1.5) * scale / 10) + ) + / py + ) + ) if testif2 >= 1: - ancY = QgsPoint(ancY.x(),ancY.y()+dyO) + ancY = QgsPoint(ancY.x(), ancY.y() + dyO) else: - ancY = QgsPoint(ancY.x(),ancY.y()+dy) + ancY = QgsPoint(ancY.x(), ancY.y() + dy) if utmcheck: dx0 = 0 ancX.transform(trLLUTM) - ancX = QgsPoint(ancX.x()+dx, ancX.y()) + ancX = QgsPoint(ancX.x() + dx, ancX.y()) ancX.transform(trUTMLL) ancY.transform(trUTMLL) else: dx0 = dx x = ancX.x() + dx0 y = ancY.y() - full_label = str((floor(y_UTM/grid_spacing)+u)*grid_spacing) - if test_plac.y() < (y_min_test + (0.0002 * scale/10)) or test_plac.y() > (y_max_test- (0.0002 * scale/10)): - rule_fake = self.grid_labeler(x, y, 0, 0, 0, 0, 0, 0, vAlign, hAlign, desc, fSize, fontType, 'fail', trLLUTM, trUTMLL, QColor('black'), utmcheck, scale) + full_label = str((floor(y_UTM / grid_spacing) + u) * grid_spacing) + if test_plac.y() < (y_min_test + (0.0002 * scale / 10)) or test_plac.y() > ( + y_max_test - (0.0002 * scale / 10) + ): + rule_fake = self.grid_labeler( + x, + y, + 0, + 0, + 0, + 0, + 0, + 0, + vAlign, + hAlign, + desc, + fSize, + fontType, + "fail", + trLLUTM, + trUTMLL, + QColor("black"), + utmcheck, + scale, + ) root_rule.appendChild(rule_fake) return root_rule - ctrl_uni = {0:u'\u2070',1:u'\u00B9',2:u'\u00B2',3:u'\u00B3',4:u'\u2074',5:u'\u2075',6:u'\u2076',7:u'\u2077',8:u'\u2078',9:u'\u2079','m':u'\u1D50'} + ctrl_uni = { + 0: "\u2070", + 1: "\u00B9", + 2: "\u00B2", + 3: "\u00B3", + 4: "\u2074", + 5: "\u2075", + 6: "\u2076", + 7: "\u2077", + 8: "\u2078", + 9: "\u2079", + "m": "\u1D50", + } full_label = [char for char in full_label] - for j in range(0,len(full_label)): - if not (j == len(full_label)-5 or j == len(full_label)-4): + for j in range(0, len(full_label)): + if not (j == len(full_label) - 5 or j == len(full_label) - 4): full_label[j] = ctrl_uni[int(full_label[j])] - full_label = ''.join(full_label) - expression_str = str('\'') + full_label + str('\'') + full_label = "".join(full_label) + expression_str = str("'") + full_label + str("'") fontType.setWeight(50) - fSizeAlt = fSize * 5/3 - if u == min(rangetest) and any(spec_lbl in desc for spec_lbl in ('Bot','Left')): - extra_label = ' ' + 'N' - dyT = 0.5*scale*fSize/1.5 + fSizeAlt = fSize * 5 / 3 + if u == min(rangetest) and any( + spec_lbl in desc for spec_lbl in ("Bot", "Left") + ): + extra_label = " " + "N" + dyT = 0.5 * scale * fSize / 1.5 if len(expression_str) == 9: - dxT = 3.5*scale*fSize/1.5 + dxT = 3.5 * scale * fSize / 1.5 elif len(expression_str) == 6: - dxT = 1.5*scale*fSize/1.5 + dxT = 1.5 * scale * fSize / 1.5 elif len(expression_str) == 7: - dxT = 2.5*scale*fSize/1.5 + dxT = 2.5 * scale * fSize / 1.5 if isVertical: - extra_label = ' ' + 'E' - dyT = 0.5*scale*fSize/1.5 - dxT = 3.0*scale*fSize/1.5 - expression_str =str('\'') + full_label + extra_label + str('\'') - plac_m = QgsPoint(x,y) + extra_label = " " + "E" + dyT = 0.5 * scale * fSize / 1.5 + dxT = 3.0 * scale * fSize / 1.5 + expression_str = str("'") + full_label + extra_label + str("'") + plac_m = QgsPoint(x, y) plac_m.transform(trLLUTM) - plac_new = QgsPoint(plac_m.x()+dxT,plac_m.y()+dyT) + plac_new = QgsPoint(plac_m.x() + dxT, plac_m.y() + dyT) plac_new.transform(trUTMLL) - ruleUTM2 = self.grid_labeler(plac_new.x(), plac_new.y(), 0, 0, 0, 0, 0, 0, vAlign, 'Center', desc+'m', fSizeAlt, fontType, str('\'')+ctrl_uni['m']+str('\''), trLLUTM, trUTMLL, QColor('black'), utmcheck, scale) + ruleUTM2 = self.grid_labeler( + plac_new.x(), + plac_new.y(), + 0, + 0, + 0, + 0, + 0, + 0, + vAlign, + "Center", + desc + "m", + fSizeAlt, + fontType, + str("'") + ctrl_uni["m"] + str("'"), + trLLUTM, + trUTMLL, + QColor("black"), + utmcheck, + scale, + ) root_rule.appendChild(ruleUTM2) - ruleUTM = self.grid_labeler(x, y, 0, 0, 0, 0, 0, 0, vAlign, hAlign, desc, fSizeAlt, fontType, expression_str, trLLUTM, trUTMLL, QColor('black'), utmcheck, scale) + ruleUTM = self.grid_labeler( + x, + y, + 0, + 0, + 0, + 0, + 0, + 0, + vAlign, + hAlign, + desc, + fSizeAlt, + fontType, + expression_str, + trLLUTM, + trUTMLL, + QColor("black"), + utmcheck, + scale, + ) root_rule.appendChild(ruleUTM) return root_rule def conv_dec_gms(self, base_coord, coord_spacing, u, neg_character, pos_character): - - xbase = base_coord + coord_spacing*u + + xbase = base_coord + coord_spacing * u x = abs(xbase) - xdeg = floor(round(x,4)) - xmin = floor(round(((x - xdeg)*60),4)) - xseg = floor(round(((x - xdeg - xmin/60)*3600),4)) + xdeg = floor(round(x, 4)) + xmin = floor(round(((x - xdeg) * 60), 4)) + xseg = floor(round(((x - xdeg - xmin / 60) * 3600), 4)) if xbase < 0: xhem = neg_character else: xhem = pos_character - conv_exp_str = '\'' + str(xdeg).rjust(2,'0') + 'º ' + str(xmin).rjust(2,'0') + str('\\') + str('\' ') + str(xseg).rjust(2,'0') + '"\'' + '+\' ' + str(xhem) + '\'' + conv_exp_str = ( + "'" + + str(xdeg).rjust(2, "0") + + "º " + + str(xmin).rjust(2, "0") + + str("\\") + + str("' ") + + str(xseg).rjust(2, "0") + + "\"'" + + "+' " + + str(xhem) + + "'" + ) return conv_exp_str - def geoGridcreator(self, grid_symb, geo_bound_bb, geo_number_x, geo_number_y, scale, utmcheck, trLLUTM): + def geoGridcreator( + self, + grid_symb, + geo_bound_bb, + geo_number_x, + geo_number_y, + scale, + utmcheck, + trLLUTM, + ): xmin_source = float(geo_bound_bb.split()[1]) ymin_source = float(geo_bound_bb.split()[2]) xmax_source = float(geo_bound_bb.split()[3]) ymax_source = float(geo_bound_bb.split()[4]) - - px = (xmax_source-xmin_source)/(geo_number_x+1) - py = (ymax_source-ymin_source)/(geo_number_y+1) - - for u in range(1, (geo_number_x+2)): - for t in range(0, (geo_number_y+2)): - symb_cross = self.crossLinegenerator(xmin_source, ymin_source, px, py, u, t, -0.00002145*scale, 0, utmcheck, trLLUTM) + + px = (xmax_source - xmin_source) / (geo_number_x + 1) + py = (ymax_source - ymin_source) / (geo_number_y + 1) + + for u in range(1, (geo_number_x + 2)): + for t in range(0, (geo_number_y + 2)): + symb_cross = self.crossLinegenerator( + xmin_source, + ymin_source, + px, + py, + u, + t, + -0.00002145 * scale, + 0, + utmcheck, + trLLUTM, + ) grid_symb.appendSymbolLayer(symb_cross) - for u in range(0, (geo_number_x+2)): - for t in range(1, (geo_number_y+2)): - symb_cross = self.crossLinegenerator(xmin_source, ymin_source, px, py, u, t, 0, -0.00002145*scale, utmcheck, trLLUTM) + for u in range(0, (geo_number_x + 2)): + for t in range(1, (geo_number_y + 2)): + symb_cross = self.crossLinegenerator( + xmin_source, + ymin_source, + px, + py, + u, + t, + 0, + -0.00002145 * scale, + utmcheck, + trLLUTM, + ) grid_symb.appendSymbolLayer(symb_cross) - for u in range(0, (geo_number_x+1)): - for t in range(0, (geo_number_y+2)): - symb_cross = self.crossLinegenerator(xmin_source, ymin_source, px, py, u, t, 0.00002145*scale, 0, utmcheck, trLLUTM) + for u in range(0, (geo_number_x + 1)): + for t in range(0, (geo_number_y + 2)): + symb_cross = self.crossLinegenerator( + xmin_source, + ymin_source, + px, + py, + u, + t, + 0.00002145 * scale, + 0, + utmcheck, + trLLUTM, + ) grid_symb.appendSymbolLayer(symb_cross) - for u in range(0, (geo_number_x+2)): - for t in range(0, (geo_number_y+1)): - symb_cross = self.crossLinegenerator(xmin_source, ymin_source, px, py, u, t, 0, 0.00002145*scale, utmcheck, trLLUTM) + for u in range(0, (geo_number_x + 2)): + for t in range(0, (geo_number_y + 1)): + symb_cross = self.crossLinegenerator( + xmin_source, + ymin_source, + px, + py, + u, + t, + 0, + 0.00002145 * scale, + utmcheck, + trLLUTM, + ) grid_symb.appendSymbolLayer(symb_cross) - + return grid_symb - def geoGridlabelPlacer(self, geo_bound_bb, geo_number_x, geo_number_y, dx, dy, fSize, LLfontType, trLLUTM, trUTMLL, llcolor, utmcheck, scale): + def geoGridlabelPlacer( + self, + geo_bound_bb, + geo_number_x, + geo_number_y, + dx, + dy, + fSize, + LLfontType, + trLLUTM, + trUTMLL, + llcolor, + utmcheck, + scale, + ): xmin_source = float(geo_bound_bb.split()[1]) ymin_source = float(geo_bound_bb.split()[2]) xmax_source = float(geo_bound_bb.split()[3]) ymax_source = float(geo_bound_bb.split()[4]) - px = (xmax_source-xmin_source)/(geo_number_x+1) - py = (ymax_source-ymin_source)/(geo_number_y+1) + px = (xmax_source - xmin_source) / (geo_number_x + 1) + py = (ymax_source - ymin_source) / (geo_number_y + 1) root_rule = QgsRuleBasedLabeling.Rule(QgsPalLayerSettings()) - #Upper - for u in range(0, geo_number_x+2): - if u ==0: - ruletemp = self.grid_labeler (xmin_source, ymax_source, px, py, u, 0, dx[2], dy[0], '', 'Center', 'Up '+str(u+1), fSize, LLfontType, str(self.conv_dec_gms(xmin_source, px, u, 'W', 'E'))+'+\'. GREENWICH\'', trLLUTM, trUTMLL, llcolor, utmcheck, scale) + # Upper + for u in range(0, geo_number_x + 2): + if u == 0: + ruletemp = self.grid_labeler( + xmin_source, + ymax_source, + px, + py, + u, + 0, + dx[2], + dy[0], + "", + "Center", + "Up " + str(u + 1), + fSize, + LLfontType, + str(self.conv_dec_gms(xmin_source, px, u, "W", "E")) + + "+'. GREENWICH'", + trLLUTM, + trUTMLL, + llcolor, + utmcheck, + scale, + ) root_rule.appendChild(ruletemp) else: - ruletemp = self.grid_labeler (xmin_source, ymax_source, px, py, u, 0, 0, dy[0], '', 'Center', 'Up '+str(u+1), fSize, LLfontType, self.conv_dec_gms(xmin_source, px, u, 'W', 'E'), trLLUTM, trUTMLL, llcolor, utmcheck, scale) + ruletemp = self.grid_labeler( + xmin_source, + ymax_source, + px, + py, + u, + 0, + 0, + dy[0], + "", + "Center", + "Up " + str(u + 1), + fSize, + LLfontType, + self.conv_dec_gms(xmin_source, px, u, "W", "E"), + trLLUTM, + trUTMLL, + llcolor, + utmcheck, + scale, + ) root_rule.appendChild(ruletemp) - #Bottom - for b in range(0, geo_number_x+2): - ruletemp = self.grid_labeler (xmin_source, ymin_source, px, py, b, 0, 0, dy[1], '', 'Center', 'Bot '+str(b+1), fSize, LLfontType, self.conv_dec_gms(xmin_source, px, b, 'W', 'E'), trLLUTM, trUTMLL, llcolor, utmcheck, scale) + # Bottom + for b in range(0, geo_number_x + 2): + ruletemp = self.grid_labeler( + xmin_source, + ymin_source, + px, + py, + b, + 0, + 0, + dy[1], + "", + "Center", + "Bot " + str(b + 1), + fSize, + LLfontType, + self.conv_dec_gms(xmin_source, px, b, "W", "E"), + trLLUTM, + trUTMLL, + llcolor, + utmcheck, + scale, + ) root_rule.appendChild(ruletemp) - #Right - for r in range(0, geo_number_y+2): - ruletemp = self.grid_labeler (xmax_source, ymin_source, px, py, 0, r, dx[0], 0, 'Half', '', 'Right '+str(r+1), fSize, LLfontType, self.conv_dec_gms(ymin_source, py, r, 'S', 'N'), trLLUTM, trUTMLL, llcolor, utmcheck, scale) + # Right + for r in range(0, geo_number_y + 2): + ruletemp = self.grid_labeler( + xmax_source, + ymin_source, + px, + py, + 0, + r, + dx[0], + 0, + "Half", + "", + "Right " + str(r + 1), + fSize, + LLfontType, + self.conv_dec_gms(ymin_source, py, r, "S", "N"), + trLLUTM, + trUTMLL, + llcolor, + utmcheck, + scale, + ) root_rule.appendChild(ruletemp) - #Left - for l in range(0, geo_number_y+2): - ruletemp = self.grid_labeler (xmin_source, ymin_source, px, py, 0, l, dx[1], 0, 'Half', '', 'Left '+str(l+1), fSize, LLfontType, self.conv_dec_gms(ymin_source, py, l, 'S', 'N'), trLLUTM, trUTMLL, llcolor, utmcheck, scale) + # Left + for l in range(0, geo_number_y + 2): + ruletemp = self.grid_labeler( + xmin_source, + ymin_source, + px, + py, + 0, + l, + dx[1], + 0, + "Half", + "", + "Left " + str(l + 1), + fSize, + LLfontType, + self.conv_dec_gms(ymin_source, py, l, "S", "N"), + trLLUTM, + trUTMLL, + llcolor, + utmcheck, + scale, + ) root_rule.appendChild(ruletemp) return root_rule - def utmGridlabelPlacer(self, root_rule, grid_spacing, geo_bound_bb, bound_UTM_bb, geo_number_x, geo_number_y, UTM_num_x, UTM_num_y, trUTMLL, trLLUTM, dx, dy, dy0, dy1, fSize, fontType, scale, utmcheck, geo_bb_or): + def utmGridlabelPlacer( + self, + root_rule, + grid_spacing, + geo_bound_bb, + bound_UTM_bb, + geo_number_x, + geo_number_y, + UTM_num_x, + UTM_num_y, + trUTMLL, + trLLUTM, + dx, + dy, + dy0, + dy1, + fSize, + fontType, + scale, + utmcheck, + geo_bb_or, + ): xmin_source = float(geo_bound_bb.split()[1]) ymin_source = float(geo_bound_bb.split()[2]) xmax_source = float(geo_bound_bb.split()[3]) @@ -440,50 +1143,228 @@ def utmGridlabelPlacer(self, root_rule, grid_spacing, geo_bound_bb, bound_UTM_bb ymin_UTM = float(bound_UTM_bb.split()[2]) xmax_UTM = float(bound_UTM_bb.split()[3]) ymax_UTM = float(bound_UTM_bb.split()[4]) - px = (xmax_source-xmin_source)/(geo_number_x+1) - py = (ymax_source-ymin_source)/(geo_number_y+1) + px = (xmax_source - xmin_source) / (geo_number_x + 1) + py = (ymax_source - ymin_source) / (geo_number_y + 1) if grid_spacing > 0: # Bottom ruletest = QgsRuleBasedLabeling.Rule(QgsPalLayerSettings()) - ruletest = self.utm_grid_labeler (ruletest, xmin_UTM, ymin_UTM, 0, ymin_source, px, py, trUTMLL, trLLUTM, 1, True, 0, dy[1]+0.4*(scale)*fSize/1.5, dy0[1]+0.4*(scale)*fSize/1.5, 0, 'Top', 'Center', 'UTMBotTest', fSize, fontType, grid_spacing, scale, utmcheck, geo_bound_bb, range(1), geo_bb_or) + ruletest = self.utm_grid_labeler( + ruletest, + xmin_UTM, + ymin_UTM, + 0, + ymin_source, + px, + py, + trUTMLL, + trLLUTM, + 1, + True, + 0, + dy[1] + 0.4 * (scale) * fSize / 1.5, + dy0[1] + 0.4 * (scale) * fSize / 1.5, + 0, + "Top", + "Center", + "UTMBotTest", + fSize, + fontType, + grid_spacing, + scale, + utmcheck, + geo_bound_bb, + range(1), + geo_bb_or, + ) rulechild = ruletest.children()[0] - if rulechild.settings().fieldName == 'fail': - rangeUD = range(2, UTM_num_x+1) + if rulechild.settings().fieldName == "fail": + rangeUD = range(2, UTM_num_x + 1) else: - rangeUD = range(1, UTM_num_x+1) + rangeUD = range(1, UTM_num_x + 1) for u in rangeUD: - root_rule = self.utm_grid_labeler (root_rule, xmin_UTM, ymin_UTM, 0, ymin_source, px, py, trUTMLL, trLLUTM, u, True, 0, dy[1]+0.4*(scale)*fSize/1.5, dy0[1]+0.4*(scale)*fSize/1.5, 0, 'Top', 'Center', 'UTMBot'+str(u), fSize, fontType, grid_spacing, scale, utmcheck, geo_bound_bb, rangeUD, geo_bb_or) + root_rule = self.utm_grid_labeler( + root_rule, + xmin_UTM, + ymin_UTM, + 0, + ymin_source, + px, + py, + trUTMLL, + trLLUTM, + u, + True, + 0, + dy[1] + 0.4 * (scale) * fSize / 1.5, + dy0[1] + 0.4 * (scale) * fSize / 1.5, + 0, + "Top", + "Center", + "UTMBot" + str(u), + fSize, + fontType, + grid_spacing, + scale, + utmcheck, + geo_bound_bb, + rangeUD, + geo_bb_or, + ) # Upper - rangeUD = range(1, UTM_num_x+1) + rangeUD = range(1, UTM_num_x + 1) for u in rangeUD: - root_rule = self.utm_grid_labeler (root_rule, xmin_UTM, ymax_UTM, 0, ymax_source, px, py, trUTMLL, trLLUTM, u, True, 0, dy[0]-1.3*(scale)*fSize/1.5, dy0[0]-1.3*(scale)*fSize/1.5, 0, 'Bottom', 'Center', 'UTMUp'+str(u), fSize, fontType, grid_spacing, scale, utmcheck, geo_bound_bb, rangeUD, geo_bb_or) + root_rule = self.utm_grid_labeler( + root_rule, + xmin_UTM, + ymax_UTM, + 0, + ymax_source, + px, + py, + trUTMLL, + trLLUTM, + u, + True, + 0, + dy[0] - 1.3 * (scale) * fSize / 1.5, + dy0[0] - 1.3 * (scale) * fSize / 1.5, + 0, + "Bottom", + "Center", + "UTMUp" + str(u), + fSize, + fontType, + grid_spacing, + scale, + utmcheck, + geo_bound_bb, + rangeUD, + geo_bb_or, + ) # Left ruletest = QgsRuleBasedLabeling.Rule(QgsPalLayerSettings()) - ruletest = self.utm_grid_labeler (ruletest, xmin_UTM, ymin_UTM, xmin_source, 0, px, py, trUTMLL, trLLUTM, 1, False, dx[2]-3.1*scale*fSize/1.5, dy[3], dy0[3], dy1[1], 'Bottom', 'Center', 'UTMLeftTest', fSize, fontType, grid_spacing, scale, utmcheck, geo_bound_bb, range(1), geo_bb_or) + ruletest = self.utm_grid_labeler( + ruletest, + xmin_UTM, + ymin_UTM, + xmin_source, + 0, + px, + py, + trUTMLL, + trLLUTM, + 1, + False, + dx[2] - 3.1 * scale * fSize / 1.5, + dy[3], + dy0[3], + dy1[1], + "Bottom", + "Center", + "UTMLeftTest", + fSize, + fontType, + grid_spacing, + scale, + utmcheck, + geo_bound_bb, + range(1), + geo_bb_or, + ) rulechild = ruletest.children()[0] - if rulechild.settings().fieldName == 'fail': - rangeLat = range(2, UTM_num_y+1) + if rulechild.settings().fieldName == "fail": + rangeLat = range(2, UTM_num_y + 1) else: - rangeLat = range(1, UTM_num_y+1) + rangeLat = range(1, UTM_num_y + 1) for u in rangeLat: - if u==min(rangeLat): - extra_dist = -2.0*scale*fSize/1.5 + if u == min(rangeLat): + extra_dist = -2.0 * scale * fSize / 1.5 else: extra_dist = 0 - root_rule = self.utm_grid_labeler (root_rule, xmin_UTM, ymin_UTM, xmin_source, 0, px, py, trUTMLL, trLLUTM, u, False, dx[2]+extra_dist, dy[3], dy0[3], dy1[1], 'Bottom', 'Center', 'UTMLeft'+str(u), fSize, fontType, grid_spacing, scale, utmcheck, geo_bound_bb, rangeLat, geo_bb_or) + root_rule = self.utm_grid_labeler( + root_rule, + xmin_UTM, + ymin_UTM, + xmin_source, + 0, + px, + py, + trUTMLL, + trLLUTM, + u, + False, + dx[2] + extra_dist, + dy[3], + dy0[3], + dy1[1], + "Bottom", + "Center", + "UTMLeft" + str(u), + fSize, + fontType, + grid_spacing, + scale, + utmcheck, + geo_bound_bb, + rangeLat, + geo_bb_or, + ) # Right - rangeLat = range(1, UTM_num_y+1) + rangeLat = range(1, UTM_num_y + 1) for u in rangeLat: - root_rule = self.utm_grid_labeler (root_rule, xmax_UTM, ymin_UTM, xmax_source, 0, px, py, trUTMLL, trLLUTM, u, False, dx[3], dy[3], dy0[3], dy1[1], '', 'Center', 'UTMRight'+str(1), fSize, fontType, grid_spacing, scale, utmcheck, geo_bound_bb, rangeLat, geo_bb_or) + root_rule = self.utm_grid_labeler( + root_rule, + xmax_UTM, + ymin_UTM, + xmax_source, + 0, + px, + py, + trUTMLL, + trLLUTM, + u, + False, + dx[3], + dy[3], + dy0[3], + dy1[1], + "", + "Center", + "UTMRight" + str(1), + fSize, + fontType, + grid_spacing, + scale, + utmcheck, + geo_bound_bb, + rangeLat, + geo_bb_or, + ) return root_rule - def styleCreator(self, layer, index, id_attr, id_value, spacing, crossX, crossY, scale, color, fontSize, font, fontLL, llcolor, utmcheck): + def styleCreator( + self, + layer, + index, + id_attr, + id_value, + spacing, + crossX, + crossY, + scale, + color, + fontSize, + font, + fontLL, + llcolor, + utmcheck, + ): """Getting Input Data For Grid Generation""" grid_spacing = spacing geo_number_x = crossX @@ -492,23 +1373,27 @@ def styleCreator(self, layer, index, id_attr, id_value, spacing, crossX, crossY, fontType = font LLfontType = fontLL - #Loading feature + # Loading feature layer_bound = layer - query = '"'+str(id_attr)+'"='+str(id_value) + query = '"' + str(id_attr) + '"=' + str(id_value) layer_bound.selectByExpression(query, QgsVectorLayer.SelectBehavior(0)) feature_bound = layer_bound.selectedFeatures()[0] layer_bound.removeSelection() - #Getting Feature Source CRS and Geometry + # Getting Feature Source CRS and Geometry if utmcheck: feature_geometry = feature_bound.geometry() bound_UTM = layer_bound.crs().authid() feature_bbox = feature_geometry.boundingBox() - bound_UTM_bb = str(feature_bbox).replace(',','').replace('>','') + bound_UTM_bb = str(feature_bbox).replace(",", "").replace(">", "") # Transforming to Geographic - transform_feature = QgsCoordinateTransform(QgsCoordinateReferenceSystem(bound_UTM), QgsCoordinateReferenceSystem('EPSG:4674'), QgsProject.instance()) + transform_feature = QgsCoordinateTransform( + QgsCoordinateReferenceSystem(bound_UTM), + QgsCoordinateReferenceSystem("EPSG:4674"), + QgsProject.instance(), + ) feature_geometry.transform(transform_feature) - bound_sourcecrs = 'EPSG:4674' + bound_sourcecrs = "EPSG:4674" feature_bbox = feature_geometry.boundingBox() feature_bbox_or = feature_geometry.orientedMinimumBoundingBox() else: @@ -516,106 +1401,195 @@ def styleCreator(self, layer, index, id_attr, id_value, spacing, crossX, crossY, bound_sourcecrs = layer_bound.crs().authid() feature_bbox = feature_geometry.boundingBox() feature_bbox_or = feature_geometry.orientedMinimumBoundingBox() - geo_bound_bb = str(feature_bbox).replace(',','').replace('>','') - oriented_geo_bb = str(feature_bbox_or).replace(',','').replace('>','').replace('((','').replace('))','') + geo_bound_bb = str(feature_bbox).replace(",", "").replace(">", "") + oriented_geo_bb = ( + str(feature_bbox_or) + .replace(",", "") + .replace(">", "") + .replace("((", "") + .replace("))", "") + ) - #Defining CRSs Transformations + # Defining CRSs Transformations inom = feature_bound[index] - if inom[0]=='N': - bound_UTM = 'EPSG:319' + str(72 + int(inom[3:5])-18) - elif inom[0]=='S': - bound_UTM = 'EPSG:319' + str(78 + int(inom[3:5])-18) + if inom[0] == "N": + bound_UTM = "EPSG:319" + str(72 + int(inom[3:5]) - 18) + elif inom[0] == "S": + bound_UTM = "EPSG:319" + str(78 + int(inom[3:5]) - 18) else: - iface.messageBar().pushMessage("Error", "Invalid index attribute", level=Qgis.Critical) + iface.messageBar().pushMessage( + "Error", "Invalid index attribute", level=Qgis.Critical + ) return - trLLUTM = QgsCoordinateTransform(QgsCoordinateReferenceSystem(bound_sourcecrs), QgsCoordinateReferenceSystem(bound_UTM), QgsProject.instance()) - trUTMLL = QgsCoordinateTransform(QgsCoordinateReferenceSystem(bound_UTM), QgsCoordinateReferenceSystem(bound_sourcecrs), QgsProject.instance()) + trLLUTM = QgsCoordinateTransform( + QgsCoordinateReferenceSystem(bound_sourcecrs), + QgsCoordinateReferenceSystem(bound_UTM), + QgsProject.instance(), + ) + trUTMLL = QgsCoordinateTransform( + QgsCoordinateReferenceSystem(bound_UTM), + QgsCoordinateReferenceSystem(bound_sourcecrs), + QgsProject.instance(), + ) - #Defining UTM Grid Symbology Type + # Defining UTM Grid Symbology Type renderer = layer.renderer() - properties = {'color': 'black'} + properties = {"color": "black"} grid_symb = QgsFillSymbol.createSimple(properties) symb_out = QgsSimpleFillSymbolLayer() - symb_out.setStrokeColor(QColor('black')) - symb_out.setFillColor(QColor('white')) + symb_out.setStrokeColor(QColor("black")) + symb_out.setFillColor(QColor("white")) symb_out.setStrokeWidth(0.05) - """ Creating UTM Grid """ if not utmcheck: geo_UTM = feature_bound.geometry() geo_UTM.transform(trLLUTM) - bound_UTM_bb = str(geo_UTM.boundingBox()).replace(',','').replace('>','') + bound_UTM_bb = str(geo_UTM.boundingBox()).replace(",", "").replace(">", "") xmin_UTM = float(bound_UTM_bb.split()[1]) ymin_UTM = float(bound_UTM_bb.split()[2]) xmax_UTM = float(bound_UTM_bb.split()[3]) ymax_UTM = float(bound_UTM_bb.split()[4]) if grid_spacing > 0: - UTM_num_x = floor(xmax_UTM/grid_spacing) - floor(xmin_UTM/grid_spacing) - UTM_num_y = floor(ymax_UTM/grid_spacing) - floor(ymin_UTM/grid_spacing) - #Generating Vertical Lines - for x in range(1, UTM_num_x+1): - grid_symb= self.utm_symb_generator (grid_spacing, trUTMLL, trLLUTM, grid_symb, properties, geo_number_x, geo_number_y, UTM_num_x, UTM_num_y, x, 0, geo_bound_bb, bound_UTM_bb, utmcheck) - #Generating Horizontal Lines - for y in range(1, UTM_num_y+1): - grid_symb = self.utm_symb_generator (grid_spacing, trUTMLL, trLLUTM, grid_symb, properties, geo_number_x, geo_number_y, UTM_num_x, UTM_num_y, 0, y, geo_bound_bb, bound_UTM_bb, utmcheck) + UTM_num_x = floor(xmax_UTM / grid_spacing) - floor(xmin_UTM / grid_spacing) + UTM_num_y = floor(ymax_UTM / grid_spacing) - floor(ymin_UTM / grid_spacing) + # Generating Vertical Lines + for x in range(1, UTM_num_x + 1): + grid_symb = self.utm_symb_generator( + grid_spacing, + trUTMLL, + trLLUTM, + grid_symb, + properties, + geo_number_x, + geo_number_y, + UTM_num_x, + UTM_num_y, + x, + 0, + geo_bound_bb, + bound_UTM_bb, + utmcheck, + ) + # Generating Horizontal Lines + for y in range(1, UTM_num_y + 1): + grid_symb = self.utm_symb_generator( + grid_spacing, + trUTMLL, + trLLUTM, + grid_symb, + properties, + geo_number_x, + geo_number_y, + UTM_num_x, + UTM_num_y, + 0, + y, + geo_bound_bb, + bound_UTM_bb, + utmcheck, + ) """ Creating Geo Grid """ - grid_symb = self.geoGridcreator(grid_symb, geo_bound_bb, geo_number_x, geo_number_y, scale, utmcheck, trLLUTM) + grid_symb = self.geoGridcreator( + grid_symb, + geo_bound_bb, + geo_number_x, + geo_number_y, + scale, + utmcheck, + trLLUTM, + ) """ Rendering UTM and Geographic Grid """ - #Changing UTM Grid Color + # Changing UTM Grid Color grid_symb.setColor(color) grid_symb.changeSymbolLayer(0, symb_out) - #Creating Rule Based Renderer (Rule For The Other Features) - properties = {'color': 'white'} + # Creating Rule Based Renderer (Rule For The Other Features) + properties = {"color": "white"} ext_grid_symb = QgsFillSymbol.createSimple(properties) symb_ot = QgsRuleBasedRenderer.Rule(ext_grid_symb) - symb_ot.setFilterExpression('\"'+str(id_attr)+'\" <> '+str(id_value)) - symb_ot.setLabel('other') - #Creating Rule Based Renderer (Rule For The Selected Feature, Root Rule) + symb_ot.setFilterExpression('"' + str(id_attr) + '" <> ' + str(id_value)) + symb_ot.setLabel("other") + # Creating Rule Based Renderer (Rule For The Selected Feature, Root Rule) symb_new = QgsRuleBasedRenderer.Rule(grid_symb) - symb_new.setFilterExpression('\"'+str(id_attr)+'\" = '+str(id_value)) - symb_new.setLabel('layer') + symb_new.setFilterExpression('"' + str(id_attr) + '" = ' + str(id_value)) + symb_new.setLabel("layer") symb_new.appendChild(symb_ot) - #Applying New Renderer + # Applying New Renderer render_base = QgsRuleBasedRenderer(symb_new) new_renderer = QgsInvertedPolygonRenderer.convertFromRenderer(render_base) layer_bound.setRenderer(new_renderer) """ Labeling Geo Grid """ if utmcheck: - dx = [2*scale*fSize/1.5, -13.6*scale*fSize/1.5, 6*scale*fSize/1.5] - dy = [1.7*scale*fSize/1.5, -3.8*scale*fSize/1.5] + dx = [ + 2 * scale * fSize / 1.5, + -13.6 * scale * fSize / 1.5, + 6 * scale * fSize / 1.5, + ] + dy = [1.7 * scale * fSize / 1.5, -3.8 * scale * fSize / 1.5] else: - dx = [0.000018*scale, -0.000120*scale, 0.00005*scale] - dy = [0.000015*scale, -0.000040*scale] + dx = [0.000018 * scale, -0.000120 * scale, 0.00005 * scale] + dy = [0.000015 * scale, -0.000040 * scale] - root_rule = self.geoGridlabelPlacer(geo_bound_bb, geo_number_x, geo_number_y, dx, dy, fSize, LLfontType, trLLUTM, trUTMLL, llcolor, utmcheck, scale) + root_rule = self.geoGridlabelPlacer( + geo_bound_bb, + geo_number_x, + geo_number_y, + dx, + dy, + fSize, + LLfontType, + trLLUTM, + trUTMLL, + llcolor, + utmcheck, + scale, + ) """ Labeling UTM Grid""" if utmcheck: dx = [-2.7, -9.7, -6.2, 5.4] - dx = [i*scale*fSize/1.5 for i in dx] + dx = [i * scale * fSize / 1.5 for i in dx] dy = [2.5, -1.7, -0.5, -1.5] - dy = [i*scale*fSize/1.5 for i in dy] + dy = [i * scale * fSize / 1.5 for i in dy] dy0 = [5.45, -4.8, -3.2, -4.2] - dy0 = [i*scale*fSize/1.5 for i in dy0] + dy0 = [i * scale * fSize / 1.5 for i in dy0] dy1 = [2.15, 1.2] - dy1 = [i*scale*fSize/1.5 for i in dy1] + dy1 = [i * scale * fSize / 1.5 for i in dy1] else: dx = [-0.00003, -0.000107, -0.000070, 0.000060] - dx = [i*scale*fSize/1.5 for i in dx] + dx = [i * scale * fSize / 1.5 for i in dx] dy = [0.000027, 0.000016, -0.000041, -0.000052] - dy = [i*scale*fSize/1.5 for i in dy] + dy = [i * scale * fSize / 1.5 for i in dy] dy0 = [0.0000644, 0.000053, -0.000076, -0.000087] - dy0 = [i*scale*fSize/1.5 for i in dy0] + dy0 = [i * scale * fSize / 1.5 for i in dy0] dy1 = [0.000032, 0.000020] - dy1 = [i*scale*fSize/1.5 for i in dy1] - - root_rule = self.utmGridlabelPlacer(root_rule, grid_spacing, geo_bound_bb, bound_UTM_bb, geo_number_x, geo_number_y, UTM_num_x, UTM_num_y, trUTMLL, trLLUTM, dx, dy, dy0, dy1, fSize, fontType, scale, utmcheck, oriented_geo_bb) + dy1 = [i * scale * fSize / 1.5 for i in dy1] + root_rule = self.utmGridlabelPlacer( + root_rule, + grid_spacing, + geo_bound_bb, + bound_UTM_bb, + geo_number_x, + geo_number_y, + UTM_num_x, + UTM_num_y, + trUTMLL, + trLLUTM, + dx, + dy, + dy0, + dy1, + fSize, + fontType, + scale, + utmcheck, + oriented_geo_bb, + ) """ Activating Labels """ rules = QgsRuleBasedLabeling(root_rule) diff --git a/DsgTools/core/EditingTools/productExporter.py b/DsgTools/core/EditingTools/productExporter.py index f4a34f86e..22a449d51 100644 --- a/DsgTools/core/EditingTools/productExporter.py +++ b/DsgTools/core/EditingTools/productExporter.py @@ -24,6 +24,7 @@ from qgis.core import QgsLayoutExporter, QgsProject, QgsPrintLayout, QgsReadWriteContext from qgis.PyQt.QtXml import QDomDocument + class ProductExporter(object): def __init__(self): self.layout = QgsPrintLayout(QgsProject.instance()) @@ -31,7 +32,7 @@ def __init__(self): def populateTemplate(self, templateXMLContent): templateDomDoc = QDomDocument() templateDomDoc.setContent(templateXMLContent) - #TODO: Adicionar um parser para o XML para substituir + # TODO: Adicionar um parser para o XML para substituir # informações pertinentes, como por exemplo, id da # camada de atlas. self.layout.loadFromTemplate(templateDomDoc, QgsReadWriteContext()) @@ -41,11 +42,12 @@ def export(self, parameterDict): def exportPdf(self, outputPath, feedback=None): exporter = QgsLayoutExporter(self.layout) - result, error = exporter.exportToPdfs(self.layout.atlas(), - outputPath, - settings=QgsLayoutExporter.PdfExportSettings(), - feedback=feedback - ) + result, error = exporter.exportToPdfs( + self.layout.atlas(), + outputPath, + settings=QgsLayoutExporter.PdfExportSettings(), + feedback=feedback, + ) return result, error def exportTiff(self): diff --git a/DsgTools/core/Factories/DbCreatorFactory/dbCreator.py b/DsgTools/core/Factories/DbCreatorFactory/dbCreator.py index b378b7731..f3530c6c4 100644 --- a/DsgTools/core/Factories/DbCreatorFactory/dbCreator.py +++ b/DsgTools/core/Factories/DbCreatorFactory/dbCreator.py @@ -21,117 +21,163 @@ ***************************************************************************/ """ -#5 Imports +# 5 Imports from builtins import str from builtins import range from qgis.PyQt.QtCore import QSettings, pyqtSignal, QObject -#DsgTools imports +# DsgTools imports from ..DbFactory.dbFactory import DbFactory from ..DbFactory.abstractDb import AbstractDb from ....gui.CustomWidgets.BasicInterfaceWidgets.progressWidget import ProgressWidget + class DbCreator(QObject): - def __init__(self, createParam, parentWidget = None): - super(DbCreator,self).__init__() + def __init__(self, createParam, parentWidget=None): + super(DbCreator, self).__init__() self.dbFactory = DbFactory() self.parentWidget = parentWidget if isinstance(createParam, str): self.outputDir = createParam if isinstance(createParam, AbstractDb): self.abstractDb = createParam - self.scaleMIDict = {1:'100k',2:'50k',3:'25k',4:'10k',5:'5k',6:'2k',7:'1k'} - + self.scaleMIDict = { + 1: "100k", + 2: "50k", + 3: "25k", + 4: "10k", + 5: "5k", + 6: "2k", + 7: "1k", + } + def getType(self): - #Abstract method. + # Abstract method. return None - - def createDb(self, dbName, srid, paramDict = dict(), parentWidget = None): - #Abstract method. + + def createDb(self, dbName, srid, paramDict=dict(), parentWidget=None): + # Abstract method. pass - def buildDatabaseName(self, dbBaseName, prefix = None, sufix = None): + def buildDatabaseName(self, dbBaseName, prefix=None, sufix=None): attrNameList = [] if prefix: attrNameList.append(prefix) attrNameList.append(dbBaseName) if sufix: attrNameList.append(sufix) - return '_'.join(attrNameList) - - def buildAutoIncrementingDbNameList(self, dbInitialBaseName, numberOfDatabases, prefix = None, sufix = None): + return "_".join(attrNameList) + + def buildAutoIncrementingDbNameList( + self, dbInitialBaseName, numberOfDatabases, prefix=None, sufix=None + ): dbNameList = [] for i in range(numberOfDatabases): - dbBaseName = dbInitialBaseName + str(i+1) + dbBaseName = dbInitialBaseName + str(i + 1) dbNameList.append(self.buildDatabaseName(dbBaseName, prefix, sufix)) return dbNameList - - def batchCreateDb(self, dbNameList, srid, paramDict = dict()): + + def batchCreateDb(self, dbNameList, srid, paramDict=dict()): outputDbDict = dict() errorDict = dict() templateDb = None if self.parentWidget: - progress = ProgressWidget(1,len(dbNameList),self.tr('Creating databases... '),parent = self.parentWidget) + progress = ProgressWidget( + 1, + len(dbNameList), + self.tr("Creating databases... "), + parent=self.parentWidget, + ) progress.initBar() for dbName in dbNameList: try: - if not templateDb: - newDb = self.createDb(dbName, srid, paramDict = paramDict, parentWidget = self.parentWidget) + if not templateDb: + newDb = self.createDb( + dbName, + srid, + paramDict=paramDict, + parentWidget=self.parentWidget, + ) templateDb = dbName else: - paramDict['templateDb'] = templateDb - newDb = self.createDb(dbName, srid, paramDict, parentWidget = self.parentWidget) + paramDict["templateDb"] = templateDb + newDb = self.createDb( + dbName, srid, paramDict, parentWidget=self.parentWidget + ) outputDbDict[dbName] = newDb except Exception as e: if dbName not in list(errorDict.keys()): - errorDict[dbName] = ':'.join(e.args) + errorDict[dbName] = ":".join(e.args) else: - errorDict[dbName] += '\n' + ':'.join(e.args) + errorDict[dbName] += "\n" + ":".join(e.args) if self.parentWidget: progress.step() return outputDbDict, errorDict - - def createDbWithAutoIncrementingName(self, dbInitialBaseName, srid, numberOfDatabases, prefix = None, sufix = None, paramDict = dict()): - dbNameList = self.buildAutoIncrementingDbNameList(dbInitialBaseName, numberOfDatabases, prefix, sufix) + + def createDbWithAutoIncrementingName( + self, + dbInitialBaseName, + srid, + numberOfDatabases, + prefix=None, + sufix=None, + paramDict=dict(), + ): + dbNameList = self.buildAutoIncrementingDbNameList( + dbInitialBaseName, numberOfDatabases, prefix, sufix + ) return self.batchCreateDb(dbNameList, srid, paramDict) - - def createDbFromMIList(self, miList, srid, prefix = None, sufix = None, createFrame = False, paramDict = dict()): + + def createDbFromMIList( + self, miList, srid, prefix=None, sufix=None, createFrame=False, paramDict=dict() + ): outputDbDict = dict() errorDict = dict() templateDb = None if self.parentWidget: - progress = ProgressWidget(1,2*len(miList)+1,self.tr('Creating databases... '),parent = self.parentWidget) + progress = ProgressWidget( + 1, + 2 * len(miList) + 1, + self.tr("Creating databases... "), + parent=self.parentWidget, + ) progress.initBar() progress.step() for mi in miList: dbName = self.buildDatabaseName(mi, prefix, sufix) try: - if not templateDb: - newDb = self.createDb(dbName, srid, paramDict, parentWidget = self.parentWidget) + if not templateDb: + newDb = self.createDb( + dbName, srid, paramDict, parentWidget=self.parentWidget + ) templateDb = dbName else: - paramDict['templateDb'] = templateDb - newDb = self.createDb(dbName, srid, paramDict, parentWidget = self.parentWidget) + paramDict["templateDb"] = templateDb + newDb = self.createDb( + dbName, srid, paramDict, parentWidget=self.parentWidget + ) outputDbDict[dbName] = newDb except Exception as e: if dbName not in list(errorDict.keys()): - errorDict[dbName] = ':'.join(e.args) + errorDict[dbName] = ":".join(e.args) else: - errorDict[dbName] += '\n' + ':'.join(e.args) + errorDict[dbName] += "\n" + ":".join(e.args) if self.parentWidget: progress.step() if createFrame: for dbName in list(outputDbDict.keys()): - try: - scale = self.scaleMIDict[len(mi.split('-'))] + try: + scale = self.scaleMIDict[len(mi.split("-"))] mi = [i for i in miList if i in dbName][0] - outputDbDict[dbName].createFrame('mi', scale, mi, paramDict = paramDict) + outputDbDict[dbName].createFrame( + "mi", scale, mi, paramDict=paramDict + ) except Exception as e: if dbName not in list(errorDict.keys()): - errorDict[dbName] = ':'.join(e.args) + errorDict[dbName] = ":".join(e.args) else: - errorDict[dbName] += '\n' + ':'.join(e.args) + errorDict[dbName] += "\n" + ":".join(e.args) if self.parentWidget: progress.step() - return outputDbDict, errorDict \ No newline at end of file + return outputDbDict, errorDict diff --git a/DsgTools/core/Factories/DbCreatorFactory/dbCreatorFactory.py b/DsgTools/core/Factories/DbCreatorFactory/dbCreatorFactory.py index 9f5edab97..55294a118 100644 --- a/DsgTools/core/Factories/DbCreatorFactory/dbCreatorFactory.py +++ b/DsgTools/core/Factories/DbCreatorFactory/dbCreatorFactory.py @@ -25,23 +25,33 @@ from qgis.core import Qgis, QgsMessageLog from qgis.PyQt.QtSql import QSqlDatabase -#DSG Tools imports + +# DSG Tools imports from .spatialiteDbCreator import SpatialiteDbCreator from .postgisDbCreator import PostgisDbCreator from .geopackageDbCreator import GeopackageDbCreator + class DbCreatorFactory(object): - def createDbCreatorFactory(self, driverName, createParam, parentWidget = None): - #TODO Treat none return - if not ('QPSQL' in QSqlDatabase.drivers()): #Driver wasn't loaded - QgsMessageLog.logMessage('QT PSQL driver not installed!', 'DSGTools Plugin', Qgis.Critical) + def createDbCreatorFactory(self, driverName, createParam, parentWidget=None): + # TODO Treat none return + if not ("QPSQL" in QSqlDatabase.drivers()): # Driver wasn't loaded + QgsMessageLog.logMessage( + "QT PSQL driver not installed!", "DSGTools Plugin", Qgis.Critical + ) + return None + if not ("QSQLITE" in QSqlDatabase.drivers()): # Driver wasn't loaded + QgsMessageLog.logMessage( + "QT QSQLITE driver not installed!", "DSGTools Plugin", Qgis.Critical + ) return None - if not ('QSQLITE' in QSqlDatabase.drivers()): #Driver wasn't loaded - QgsMessageLog.logMessage('QT QSQLITE driver not installed!', 'DSGTools Plugin', Qgis.Critical) - return None creators = { - "QSQLITE" : SpatialiteDbCreator, - "QPSQL" : PostgisDbCreator, - "GPKG" : GeopackageDbCreator + "QSQLITE": SpatialiteDbCreator, + "QPSQL": PostgisDbCreator, + "GPKG": GeopackageDbCreator, } - return creators[driverName](createParam, parentWidget) if driverName in creators else None + return ( + creators[driverName](createParam, parentWidget) + if driverName in creators + else None + ) diff --git a/DsgTools/core/Factories/DbCreatorFactory/geopackageDbCreator.py b/DsgTools/core/Factories/DbCreatorFactory/geopackageDbCreator.py index 577b25a8a..26afc593e 100644 --- a/DsgTools/core/Factories/DbCreatorFactory/geopackageDbCreator.py +++ b/DsgTools/core/Factories/DbCreatorFactory/geopackageDbCreator.py @@ -26,47 +26,64 @@ from DsgTools.core.Factories.DbFactory.dbFactory import DbFactory from DsgTools.core.Factories.DbCreatorFactory.dbCreator import DbCreator -from DsgTools.gui.CustomWidgets.BasicInterfaceWidgets.progressWidget import ProgressWidget +from DsgTools.gui.CustomWidgets.BasicInterfaceWidgets.progressWidget import ( + ProgressWidget, +) from DsgTools.core.dsgEnums import DsgEnums + class GeopackageDbCreator(DbCreator): - - def __init__(self, createParam, parentWidget = None): - super(GeopackageDbCreator,self).__init__(createParam) + def __init__(self, createParam, parentWidget=None): + super(GeopackageDbCreator, self).__init__(createParam) self.parentWidget = parentWidget - + def instantiateNewDb(self, dbPath): newDb = self.dbFactory.createDbFactory(DsgEnums.DriverGeopackage) newDb.connectDatabase(dbPath) return newDb - + def getTemplateLocation(self, version): - if version == '2.1.3': + if version == "2.1.3": return os.path.join( - os.path.dirname(__file__), '..', '..', '..', 'core', - 'DbModels', 'Geopackage', '213', 'seed_edgv213.gpkg' - ) - elif version == '3.0': + os.path.dirname(__file__), + "..", + "..", + "..", + "core", + "DbModels", + "Geopackage", + "213", + "seed_edgv213.gpkg", + ) + elif version == "3.0": return os.path.join( - os.path.dirname(__file__), '..', '..', '..', 'core', - 'DbModels', 'Geopackage', '3', 'seed_edgv3.gpkg' - ) - return '' - - def createDb(self, dbName, srid, paramDict = dict(), parentWidget = None): - destination = os.path.join(self.outputDir,dbName+'.gpkg') - if 'version' not in list(paramDict.keys()): - raise Exception('Undefined database version') - edgvPath = self.getTemplateLocation(paramDict['version']) - f = open(edgvPath,'rb') - g = open(destination,'wb') + os.path.dirname(__file__), + "..", + "..", + "..", + "core", + "DbModels", + "Geopackage", + "3", + "seed_edgv3.gpkg", + ) + return "" + + def createDb(self, dbName, srid, paramDict=dict(), parentWidget=None): + destination = os.path.join(self.outputDir, dbName + ".gpkg") + if "version" not in list(paramDict.keys()): + raise Exception("Undefined database version") + edgvPath = self.getTemplateLocation(paramDict["version"]) + f = open(edgvPath, "rb") + g = open(destination, "wb") x = f.readlines() if parentWidget: progress = ProgressWidget( - 1, len(x)+2, - self.tr('Creating Geopackage {0}... ').format(dbName), - parent=parentWidget - ) + 1, + len(x) + 2, + self.tr("Creating Geopackage {0}... ").format(dbName), + parent=parentWidget, + ) progress.initBar() for i in x: g.write(i) @@ -74,7 +91,7 @@ def createDb(self, dbName, srid, paramDict = dict(), parentWidget = None): progress.step() g.close() f.close() - #TODO: put defineSrid into AbstractDb + # TODO: put defineSrid into AbstractDb self.defineSrid(destination, srid) if parentWidget: progress.step() @@ -82,11 +99,13 @@ def createDb(self, dbName, srid, paramDict = dict(), parentWidget = None): if parentWidget: progress.step() return newDb - + def defineSrid(self, destination, srid): con = sqlite3.connect(destination) cursor = con.cursor() - cursor.execute("UPDATE gpkg_geometry_columns SET srs_id={srid}".format(srid=srid)) + cursor.execute( + "UPDATE gpkg_geometry_columns SET srs_id={srid}".format(srid=srid) + ) con.commit() cursor.close() con.close() diff --git a/DsgTools/core/Factories/DbCreatorFactory/postgisDbCreator.py b/DsgTools/core/Factories/DbCreatorFactory/postgisDbCreator.py index 70ec47522..9a9029aaf 100644 --- a/DsgTools/core/Factories/DbCreatorFactory/postgisDbCreator.py +++ b/DsgTools/core/Factories/DbCreatorFactory/postgisDbCreator.py @@ -25,12 +25,12 @@ from ....gui.CustomWidgets.BasicInterfaceWidgets.progressWidget import ProgressWidget from DsgTools.core.dsgEnums import DsgEnums + class PostgisDbCreator(DbCreator): - - def __init__(self, createParam, parentWidget = None): - super(self.__class__,self).__init__(createParam) + def __init__(self, createParam, parentWidget=None): + super(self.__class__, self).__init__(createParam) self.parentWidget = parentWidget - + def instantiateNewDb(self, dbName): host = self.abstractDb.db.hostName() port = self.abstractDb.db.port() @@ -39,11 +39,11 @@ def instantiateNewDb(self, dbName): newDb = self.dbFactory.createDbFactory(DsgEnums.DriverPostGIS) newDb.connectDatabaseWithParameters(host, port, dbName, user, password) return newDb - + def checkAndCreateTemplate(self, version): - ''' + """ checks and create an edgv template - ''' + """ if version: hasTemplate = self.abstractDb.checkTemplate(version) if hasTemplate: @@ -53,32 +53,38 @@ def checkAndCreateTemplate(self, version): if mustUpdateTemplate: templateName = templateDb.db.databaseName() templateDb.__del__() - self.abstractDb.dropDatabase(templateName, dropTemplate = True) + self.abstractDb.dropDatabase(templateName, dropTemplate=True) hasTemplate = False if not hasTemplate: self.abstractDb.createTemplateDatabase(version) templateName = self.abstractDb.getTemplateName(version) templateDb = self.instantiateNewDb(templateName) templateDb.setStructureFromSql(version, 4674) - - def createDb(self, dbName, srid, paramDict = dict(), parentWidget = None): - ''' + + def createDb(self, dbName, srid, paramDict=dict(), parentWidget=None): + """ dbName: new database name srid: coordinate system of database paramDict = {'templateDb': database to be used as template. Default is edgv} - ''' - #0. if 'templateDb' in paramDict.keys: use createFromTemplate then end createDb - if 'templateDb' in list(paramDict.keys()): - self.abstractDb.createDbFromTemplate(dbName, templateName = paramDict['templateDb'], parentWidget = parentWidget) + """ + # 0. if 'templateDb' in paramDict.keys: use createFromTemplate then end createDb + if "templateDb" in list(paramDict.keys()): + self.abstractDb.createDbFromTemplate( + dbName, templateName=paramDict["templateDb"], parentWidget=parentWidget + ) return self.instantiateNewDb(dbName) else: - #1. test if edgv template is created - #2. if edgv template is not created, create it - if paramDict['isTemplateEdgv']: - self.checkAndCreateTemplate(paramDict['version']) - #3. create db from template - self.abstractDb.createDbFromTemplate(dbName, templateName = paramDict['templateName'], parentWidget = parentWidget) + # 1. test if edgv template is created + # 2. if edgv template is not created, create it + if paramDict["isTemplateEdgv"]: + self.checkAndCreateTemplate(paramDict["version"]) + # 3. create db from template + self.abstractDb.createDbFromTemplate( + dbName, + templateName=paramDict["templateName"], + parentWidget=parentWidget, + ) newDb = self.instantiateNewDb(dbName) - newDb.updateDbSRID(srid, parentWidget = parentWidget) + newDb.updateDbSRID(srid, parentWidget=parentWidget) newDb.checkAndCreateStyleTable() return newDb diff --git a/DsgTools/core/Factories/DbCreatorFactory/spatialiteDbCreator.py b/DsgTools/core/Factories/DbCreatorFactory/spatialiteDbCreator.py index 631f6d325..7100309be 100644 --- a/DsgTools/core/Factories/DbCreatorFactory/spatialiteDbCreator.py +++ b/DsgTools/core/Factories/DbCreatorFactory/spatialiteDbCreator.py @@ -29,35 +29,60 @@ from ....gui.CustomWidgets.BasicInterfaceWidgets.progressWidget import ProgressWidget from DsgTools.core.dsgEnums import DsgEnums + class SpatialiteDbCreator(DbCreator): - - def __init__(self, createParam, parentWidget = None): - super(self.__class__,self).__init__(createParam) + def __init__(self, createParam, parentWidget=None): + super(self.__class__, self).__init__(createParam) self.parentWidget = parentWidget - + def instantiateNewDb(self, dbPath): newDb = self.dbFactory.createDbFactory(DsgEnums.DriverSpatiaLite) newDb.connectDatabase(dbPath) return newDb - + def getTemplateLocation(self, version): currentPath = os.path.dirname(__file__) - if version == '2.1.3': - edgvPath = os.path.join(currentPath,'..','..','..','core','DbModels','SpatiaLite', '213', 'seed_edgv213.sqlite') - elif version == '3.0': - edgvPath = os.path.join(currentPath,'..','..','..','core','DbModels','SpatiaLite', '3', 'seed_edgv3.sqlite') + if version == "2.1.3": + edgvPath = os.path.join( + currentPath, + "..", + "..", + "..", + "core", + "DbModels", + "SpatiaLite", + "213", + "seed_edgv213.sqlite", + ) + elif version == "3.0": + edgvPath = os.path.join( + currentPath, + "..", + "..", + "..", + "core", + "DbModels", + "SpatiaLite", + "3", + "seed_edgv3.sqlite", + ) return edgvPath - - def createDb(self, dbName, srid, paramDict = dict(), parentWidget = None): - destination = os.path.join(self.outputDir,dbName+'.sqlite') - if 'version' not in list(paramDict.keys()): - raise Exception('Undefined database version') - edgvPath = self.getTemplateLocation(paramDict['version']) - f = open(edgvPath,'rb') - g = open(destination,'wb') + + def createDb(self, dbName, srid, paramDict=dict(), parentWidget=None): + destination = os.path.join(self.outputDir, dbName + ".sqlite") + if "version" not in list(paramDict.keys()): + raise Exception("Undefined database version") + edgvPath = self.getTemplateLocation(paramDict["version"]) + f = open(edgvPath, "rb") + g = open(destination, "wb") x = f.readlines() if parentWidget: - progress = ProgressWidget(1,len(x)+2,self.tr('Creating Spatialite {0}... ').format(dbName), parent = parentWidget) + progress = ProgressWidget( + 1, + len(x) + 2, + self.tr("Creating Spatialite {0}... ").format(dbName), + parent=parentWidget, + ) progress.initBar() for i in x: g.write(i) @@ -65,7 +90,7 @@ def createDb(self, dbName, srid, paramDict = dict(), parentWidget = None): progress.step() g.close() f.close() - #TODO: put defineSrid into AbstractDb + # TODO: put defineSrid into AbstractDb self.defineSrid(destination, srid) if parentWidget: progress.step() @@ -73,11 +98,11 @@ def createDb(self, dbName, srid, paramDict = dict(), parentWidget = None): if parentWidget: progress.step() return newDb - + def defineSrid(self, destination, srid): con = sqlite3.connect(destination) cursor = con.cursor() srid_sql = (srid,) - cursor.execute("UPDATE geometry_columns SET srid=?",srid_sql) + cursor.execute("UPDATE geometry_columns SET srid=?", srid_sql) con.commit() - con.close() \ No newline at end of file + con.close() diff --git a/DsgTools/core/Factories/DbCustomizationFactory/attributeCustomization.py b/DsgTools/core/Factories/DbCustomizationFactory/attributeCustomization.py index b5119d24a..9a1cd943c 100644 --- a/DsgTools/core/Factories/DbCustomizationFactory/attributeCustomization.py +++ b/DsgTools/core/Factories/DbCustomizationFactory/attributeCustomization.py @@ -1,4 +1,4 @@ - # -*- coding: utf-8 -*- +# -*- coding: utf-8 -*- """ /*************************************************************************** DsgTools @@ -20,56 +20,89 @@ * * ***************************************************************************/ """ -#DsgTools Imports +# DsgTools Imports from builtins import map -from DsgTools.core.Factories.DbCustomizationFactory.dbCustomization import DbCustomization +from DsgTools.core.Factories.DbCustomizationFactory.dbCustomization import ( + DbCustomization, +) + class AttributeCustomization(DbCustomization): def __init__(self, customJson): super(AttributeCustomization, self).__init__(customJson) - + def buildSql(self): - ''' + """ self.customJson['AttributeToAdd'] = [{'schemaName':'schema', 'tableName':'nome', 'attrList':[-list of attrDef-], childrenToAlter:[-list of children-]}] attrDef = [{'attrName':'nome', 'attrType':'varchar(80)', 'isPk':False, 'isNullable':True, 'references':None, 'defaultValue':None, 'filter':[]}] - ''' - #Abstract method. Must be reimplemented in each child. - sql = '' - for modItem in self.customJson['AttributeToAdd']: - schema = modItem['schemaName'] - table = modItem['tableName'] - for attr in modItem['attrList']: - auxSql = 'ALTER TABLE "{0}"."{1}" ADD COLUMN {2} {3}'.format(schema,table,attr['attrName'],attr['attrType']) - if not attr['isNullable']: - auxSql += ' NOT NULL ' - if 'references' in list(attr.keys()): - if attr['references']: - if attr['defaultValue']: - auxSql += ' REFERENCES {0} DEFAULT {1}'.format(attr['references'], attr['defaultValue']) + """ + # Abstract method. Must be reimplemented in each child. + sql = "" + for modItem in self.customJson["AttributeToAdd"]: + schema = modItem["schemaName"] + table = modItem["tableName"] + for attr in modItem["attrList"]: + auxSql = 'ALTER TABLE "{0}"."{1}" ADD COLUMN {2} {3}'.format( + schema, table, attr["attrName"], attr["attrType"] + ) + if not attr["isNullable"]: + auxSql += " NOT NULL " + if "references" in list(attr.keys()): + if attr["references"]: + if attr["defaultValue"]: + auxSql += " REFERENCES {0} DEFAULT {1}".format( + attr["references"], attr["defaultValue"] + ) else: - auxSql += ' REFERENCES {0}'.format(attr['references']) - auxSql += ';\n' + auxSql += " REFERENCES {0}".format(attr["references"]) + auxSql += ";\n" sql += auxSql - if len(attr['filter']) > 0: - sql += '''ALTER TABLE "{0}"."{1}" ADD CONSTRAINT "{1}_{2}_check CHECK ({2} = ANY(ARRAY[{3}]);\n'''.format(schema, table, attr['attrName'], '::SMALLINT,'.join(map(str,attr['filter']))+'::SMALLINT') - for child in modItem['childrenToAlter']: - sql += '''ALTER TABLE "{0}"."{1}" ADD CONSTRAINT "{1}_{2}_check CHECK ({2} = ANY(ARRAY[{3}]);\n'''.format(child['schema'], child['table'], attr['attrName'], '::SMALLINT,'.join(map(str,attr['filter']))+'::SMALLINT') - if attr['references']: - sql += '''ALTER TABLE "{0}"."{1}"\n ADD CONSTRAINT "{1}_{2}_fk FOREIGN KEY({2}) \n REFERENCES dominios."{3}" (code) MATCH FULL \n ON UPDATE NO ACTION ON DELETE NO ACTION;\n'''.format(schema, table, attr['attrName'], attr['references']) - for child in modItem['childrenToAlter']: - sql += '''ALTER TABLE "{0}"."{1}"\n ADD CONSTRAINT "{1}_{2}_fk FOREIGN KEY({2}) \n REFERENCES dominios."{3}" (code) MATCH FULL \n ON UPDATE NO ACTION ON DELETE NO ACTION;\n'''.format(child['schema'], child['table'], attr['attrName'], attr['references']) - if attr['defaultValue']: - sql += '''ALTER TABLE ONLY "{0}"."{1}" ALTER COLUMN {2} SET DEFAULT {3};'''.format(schema, table, attr['attrName'], attr['defaultValue']) - for child in modItem['childrenToAlter']: - sql += '''ALTER TABLE ONLY "{0}"."{1}" ALTER COLUMN {2} SET DEFAULT {3};'''.format(child['schema'], child['table'], attr['attrName'], attr['defaultValue']) + if len(attr["filter"]) > 0: + sql += """ALTER TABLE "{0}"."{1}" ADD CONSTRAINT "{1}_{2}_check CHECK ({2} = ANY(ARRAY[{3}]);\n""".format( + schema, + table, + attr["attrName"], + "::SMALLINT,".join(map(str, attr["filter"])) + "::SMALLINT", + ) + for child in modItem["childrenToAlter"]: + sql += """ALTER TABLE "{0}"."{1}" ADD CONSTRAINT "{1}_{2}_check CHECK ({2} = ANY(ARRAY[{3}]);\n""".format( + child["schema"], + child["table"], + attr["attrName"], + "::SMALLINT,".join(map(str, attr["filter"])) + "::SMALLINT", + ) + if attr["references"]: + sql += """ALTER TABLE "{0}"."{1}"\n ADD CONSTRAINT "{1}_{2}_fk FOREIGN KEY({2}) \n REFERENCES dominios."{3}" (code) MATCH FULL \n ON UPDATE NO ACTION ON DELETE NO ACTION;\n""".format( + schema, table, attr["attrName"], attr["references"] + ) + for child in modItem["childrenToAlter"]: + sql += """ALTER TABLE "{0}"."{1}"\n ADD CONSTRAINT "{1}_{2}_fk FOREIGN KEY({2}) \n REFERENCES dominios."{3}" (code) MATCH FULL \n ON UPDATE NO ACTION ON DELETE NO ACTION;\n""".format( + child["schema"], + child["table"], + attr["attrName"], + attr["references"], + ) + if attr["defaultValue"]: + sql += """ALTER TABLE ONLY "{0}"."{1}" ALTER COLUMN {2} SET DEFAULT {3};""".format( + schema, table, attr["attrName"], attr["defaultValue"] + ) + for child in modItem["childrenToAlter"]: + sql += """ALTER TABLE ONLY "{0}"."{1}" ALTER COLUMN {2} SET DEFAULT {3};""".format( + child["schema"], + child["table"], + attr["attrName"], + attr["defaultValue"], + ) return sql - + def buildUndoSql(self): - #Abstract method. Must be reimplemented in each child. - sql = '' - for modItem in self.customJson['AttributeToAdd']: - schema = modItem['schemaName'] - table = modItem['tableName'] - for attr in modItem['attrList']: - sql += 'ALTER TABLE "{0}"."{1}" DROP COLUMN IF EXISTS "{2}" CASCADE;'.format(schema, table, attr['attrName']) - return sql \ No newline at end of file + # Abstract method. Must be reimplemented in each child. + sql = "" + for modItem in self.customJson["AttributeToAdd"]: + schema = modItem["schemaName"] + table = modItem["tableName"] + for attr in modItem["attrList"]: + sql += 'ALTER TABLE "{0}"."{1}" DROP COLUMN IF EXISTS "{2}" CASCADE;'.format( + schema, table, attr["attrName"] + ) + return sql diff --git a/DsgTools/core/Factories/DbCustomizationFactory/classCustomization.py b/DsgTools/core/Factories/DbCustomizationFactory/classCustomization.py index 313eebe68..bf06cc264 100644 --- a/DsgTools/core/Factories/DbCustomizationFactory/classCustomization.py +++ b/DsgTools/core/Factories/DbCustomizationFactory/classCustomization.py @@ -20,44 +20,55 @@ * * ***************************************************************************/ """ -#DsgTools Imports -from DsgTools.core.Factories.DbCustomizationFactory.dbCustomization import DbCustomization +# DsgTools Imports +from DsgTools.core.Factories.DbCustomizationFactory.dbCustomization import ( + DbCustomization, +) + class ClassCustomization(DbCustomization): def __init__(self, customJson): super(ClassCustomization, self).__init__(customJson) - + def buildSql(self): """ Parses customJson and builds sqls to create class {'name':name, 'attrs':attrList,'schema':schema} """ - #Abstract method. Must be reimplemented in each child. + # Abstract method. Must be reimplemented in each child. sql = """""" pkClause = """""" - for table in self.customJson['ClassToAdd']: - sql += """CREATE TABLE "{0}"."{1}" (\n""".format(table['schema'],table['name']) + for table in self.customJson["ClassToAdd"]: + sql += """CREATE TABLE "{0}"."{1}" (\n""".format( + table["schema"], table["name"] + ) pkClause = None paramsSqlList = [] - for params in table['attrs']: - paramSql = """ "{0}" {1}""".format(params['attrName'], params['attrType']) - if not params['isNullable']: + for params in table["attrs"]: + paramSql = """ "{0}" {1}""".format( + params["attrName"], params["attrType"] + ) + if not params["isNullable"]: paramSql += """ NOT NULL""" - if params['isPk']: - pkClause = """ CONSTRAINT {0}_pk PRIMARY KEY ({1})""".format(table['name'],params['attrName']) + if params["isPk"]: + pkClause = """ CONSTRAINT {0}_pk PRIMARY KEY ({1})""".format( + table["name"], params["attrName"] + ) paramsSqlList.append(paramSql) if pkClause: paramsSqlList.append(pkClause) sql += """,\n""".join(paramsSqlList) sql += """\n);\n""" return sql - + def buildUndoSql(self): """ Parses customJson and builds undo sql. """ - #Abstract method. Must be reimplemented in each child. - sql = '' - for table in self.customJson['ClassToAdd']: - sql += """DROP TABLE "{0}"."{1}";\n""".format(table['schema'],table['name']) - return sql \ No newline at end of file + # Abstract method. Must be reimplemented in each child. + sql = "" + for table in self.customJson["ClassToAdd"]: + sql += """DROP TABLE "{0}"."{1}";\n""".format( + table["schema"], table["name"] + ) + return sql diff --git a/DsgTools/core/Factories/DbCustomizationFactory/codeNameCustomization.py b/DsgTools/core/Factories/DbCustomizationFactory/codeNameCustomization.py index 68e1e4aea..dede22e9e 100644 --- a/DsgTools/core/Factories/DbCustomizationFactory/codeNameCustomization.py +++ b/DsgTools/core/Factories/DbCustomizationFactory/codeNameCustomization.py @@ -20,26 +20,33 @@ * * ***************************************************************************/ """ -#DsgTools Imports -from DsgTools.core.Factories.DbCustomizationFactory.dbCustomization import DbCustomization +# DsgTools Imports +from DsgTools.core.Factories.DbCustomizationFactory.dbCustomization import ( + DbCustomization, +) + class CodeNameCustomization(DbCustomization): def __init__(self, customJson): super(CodeNameCustomization, self).__init__(customJson) - + def buildSql(self): - ''' + """ {'domainTable':domainTable, 'codeValue':codeValue, 'oldCodeName':oldCodeName, 'newCodeName':newCodeName} - ''' - #Abstract method. Must be reimplemented in each child. - sql = '' - for modItem in self.customJson['CodeNameToChange']: - sql += '''UPDATE dominios."{0}" SET code_name = '{1}' where code = {2};\n'''.format(modItem['domainTable'], modItem['newCodeName'], modItem['codeValue']) + """ + # Abstract method. Must be reimplemented in each child. + sql = "" + for modItem in self.customJson["CodeNameToChange"]: + sql += """UPDATE dominios."{0}" SET code_name = '{1}' where code = {2};\n""".format( + modItem["domainTable"], modItem["newCodeName"], modItem["codeValue"] + ) return sql - + def buildUndoSql(self): - #Abstract method. Must be reimplemented in each child. - sql = '' - for modItem in self.customJson['CodeNameToChange']: - sql += '''UPDATE dominios."{0}" SET code_name = '{1}' where code = {2};\n'''.format(modItem['domainTable'], modItem['oldCodeName'], modItem['codeValue']) - return sql \ No newline at end of file + # Abstract method. Must be reimplemented in each child. + sql = "" + for modItem in self.customJson["CodeNameToChange"]: + sql += """UPDATE dominios."{0}" SET code_name = '{1}' where code = {2};\n""".format( + modItem["domainTable"], modItem["oldCodeName"], modItem["codeValue"] + ) + return sql diff --git a/DsgTools/core/Factories/DbCustomizationFactory/dbCustomization.py b/DsgTools/core/Factories/DbCustomizationFactory/dbCustomization.py index 46879c266..19700257a 100644 --- a/DsgTools/core/Factories/DbCustomizationFactory/dbCustomization.py +++ b/DsgTools/core/Factories/DbCustomizationFactory/dbCustomization.py @@ -20,30 +20,36 @@ * * ***************************************************************************/ """ -#Qt Imports +# Qt Imports from builtins import str from qgis.PyQt.Qt import QObject + class DbCustomization(QObject): def __init__(self, validatedJSONDict): super(DbCustomization, self).__init__() - self.log = '' - self.errorLog = '' + self.log = "" + self.errorLog = "" self.jsonDict = validatedJSONDict - + def getName(self): - return str(self.__class__).split('.')[-1].replace('\'>', '').replace('Customization','') - + return ( + str(self.__class__) + .split(".")[-1] + .replace("'>", "") + .replace("Customization", "") + ) + def getLog(self): return self.log - - def logEvent(self,event): + + def logEvent(self, event): self.log += event - + def buildSql(self): - #Abstract method. Must be reimplemented in each child. + # Abstract method. Must be reimplemented in each child. pass - + def buildUndoSql(self): - #Abstract method. Must be reimplemented in each child. - pass \ No newline at end of file + # Abstract method. Must be reimplemented in each child. + pass diff --git a/DsgTools/core/Factories/DbCustomizationFactory/dbCustomizationFactory.py b/DsgTools/core/Factories/DbCustomizationFactory/dbCustomizationFactory.py index c17fb8535..c235bc8ef 100644 --- a/DsgTools/core/Factories/DbCustomizationFactory/dbCustomizationFactory.py +++ b/DsgTools/core/Factories/DbCustomizationFactory/dbCustomizationFactory.py @@ -20,35 +20,51 @@ * * ***************************************************************************/ """ -#DsgTools imports +# DsgTools imports from builtins import object -from DsgTools.core.Factories.DbCustomizationFactory.attributeCustomization import AttributeCustomization -from DsgTools.core.Factories.DbCustomizationFactory.classCustomization import ClassCustomization -from DsgTools.core.Factories.DbCustomizationFactory.codeNameCustomization import CodeNameCustomization -from DsgTools.core.Factories.DbCustomizationFactory.defaultCustomization import DefaultCustomization -from DsgTools.core.Factories.DbCustomizationFactory.newDomainTableCustomization import NewDomainTableCustomization -from DsgTools.core.Factories.DbCustomizationFactory.domainValueCustomization import DomainValueCustomization -from DsgTools.core.Factories.DbCustomizationFactory.nullityCustomization import NullityCustomization -from DsgTools.core.Factories.DbCustomizationFactory.filterCustomization import FilterCustomization +from DsgTools.core.Factories.DbCustomizationFactory.attributeCustomization import ( + AttributeCustomization, +) +from DsgTools.core.Factories.DbCustomizationFactory.classCustomization import ( + ClassCustomization, +) +from DsgTools.core.Factories.DbCustomizationFactory.codeNameCustomization import ( + CodeNameCustomization, +) +from DsgTools.core.Factories.DbCustomizationFactory.defaultCustomization import ( + DefaultCustomization, +) +from DsgTools.core.Factories.DbCustomizationFactory.newDomainTableCustomization import ( + NewDomainTableCustomization, +) +from DsgTools.core.Factories.DbCustomizationFactory.domainValueCustomization import ( + DomainValueCustomization, +) +from DsgTools.core.Factories.DbCustomizationFactory.nullityCustomization import ( + NullityCustomization, +) +from DsgTools.core.Factories.DbCustomizationFactory.filterCustomization import ( + FilterCustomization, +) class DbCustomizationFactory(object): def createCustomization(self, type, validatedJSONDict): - if type == 'attribute': + if type == "attribute": return AttributeCustomization(validatedJSONDict) - elif type == 'class': + elif type == "class": return ClassCustomization(validatedJSONDict) - elif type == 'codeName': + elif type == "codeName": return CodeNameCustomization(validatedJSONDict) - elif type == 'default': - return DefaultCustomization(validatedJSONDict) - elif type == 'domain': + elif type == "default": + return DefaultCustomization(validatedJSONDict) + elif type == "domain": return NewDomainTableCustomization(validatedJSONDict) - elif type == 'domainValue': + elif type == "domainValue": return DomainValueCustomization(validatedJSONDict) - elif type == 'nullity': + elif type == "nullity": return NullityCustomization(validatedJSONDict) - elif type == 'filter': + elif type == "filter": return FilterCustomization(validatedJSONDict) else: - raise Exception(self.tr('Customization type not defined.')) + raise Exception(self.tr("Customization type not defined.")) diff --git a/DsgTools/core/Factories/DbCustomizationFactory/defaultCustomization.py b/DsgTools/core/Factories/DbCustomizationFactory/defaultCustomization.py index a843dc8af..ff87fb3ee 100644 --- a/DsgTools/core/Factories/DbCustomizationFactory/defaultCustomization.py +++ b/DsgTools/core/Factories/DbCustomizationFactory/defaultCustomization.py @@ -20,30 +20,42 @@ * * ***************************************************************************/ """ -#DsgTools Imports -from DsgTools.core.Factories.DbCustomizationFactory.dbCustomization import DbCustomization +# DsgTools Imports +from DsgTools.core.Factories.DbCustomizationFactory.dbCustomization import ( + DbCustomization, +) + class DefaultCustomization(DbCustomization): def __init__(self, customJson): super(DefaultCustomization, self).__init__(customJson) - + def buildSql(self, abstractDb): """ {'schema': schema, 'table': table, 'attrName':attrName, 'oldValue':oldValue, 'newValue':newValue} """ - #Abstract method. Must be reimplemented in each child. + # Abstract method. Must be reimplemented in each child. sql = """""" - for modItem in self.customJson['ChangeDefault']: - sql += """ALTER TABLE ONLY "{0}"."{1}" ALTER COLUMN "{2}" SET DEFAULT {3};\n""".format(modItem['schema'], modItem['table'], modItem['attrName'], modItem['newValue']) + for modItem in self.customJson["ChangeDefault"]: + sql += """ALTER TABLE ONLY "{0}"."{1}" ALTER COLUMN "{2}" SET DEFAULT {3};\n""".format( + modItem["schema"], + modItem["table"], + modItem["attrName"], + modItem["newValue"], + ) return sql - + def buildUndoSql(self): """ {'schema': schema, 'table': table, 'attrName':attrName, 'oldValue':oldValue, 'newValue':newValue} """ - #Abstract method. Must be reimplemented in each child. + # Abstract method. Must be reimplemented in each child. sql = """""" - for modItem in self.customJson['ChangeDefault']: - sql += """ALTER TABLE ONLY "{0}"."{1}" ALTER COLUMN "{2}" SET DEFAULT {3};\n""".format(modItem['schema'], modItem['table'], modItem['attrName'], modItem['oldValue']) + for modItem in self.customJson["ChangeDefault"]: + sql += """ALTER TABLE ONLY "{0}"."{1}" ALTER COLUMN "{2}" SET DEFAULT {3};\n""".format( + modItem["schema"], + modItem["table"], + modItem["attrName"], + modItem["oldValue"], + ) return sql - \ No newline at end of file diff --git a/DsgTools/core/Factories/DbCustomizationFactory/domainValueCustomization.py b/DsgTools/core/Factories/DbCustomizationFactory/domainValueCustomization.py index 1c4b14893..936eb862e 100644 --- a/DsgTools/core/Factories/DbCustomizationFactory/domainValueCustomization.py +++ b/DsgTools/core/Factories/DbCustomizationFactory/domainValueCustomization.py @@ -20,29 +20,36 @@ * * ***************************************************************************/ """ -#DsgTools Imports -from DsgTools.core.Factories.DbCustomizationFactory.dbCustomization import DbCustomization +# DsgTools Imports +from DsgTools.core.Factories.DbCustomizationFactory.dbCustomization import ( + DbCustomization, +) + class DomainValueCustomization(DbCustomization): def __init__(self, customJson): super(DomainValueCustomization, self).__init__(customJson) - + def buildSql(self): - ''' + """ {'domainName':domainName, 'code':code, 'codeName':codeName} - ''' - #Abstract method. Must be reimplemented in each child. - sql = '' - for modItem in self.customJson['domainValue']: - sql += '''INSERT INTO dominios."{0}" (code, code_name) VALUES ({1}, '{2}');\n'''.format(modItem['domainName'], modItem['code'], modItem['codeName']) + """ + # Abstract method. Must be reimplemented in each child. + sql = "" + for modItem in self.customJson["domainValue"]: + sql += """INSERT INTO dominios."{0}" (code, code_name) VALUES ({1}, '{2}');\n""".format( + modItem["domainName"], modItem["code"], modItem["codeName"] + ) return sql - + def buildUndoSql(self): - ''' + """ {'domainName':domainName, 'valueDict': valueDict} - ''' - #Abstract method. Must be reimplemented in each child. - sql = '' - for modItem in self.customJson['domainValue']: - sql += '''DELETE FROM dominios."{0}" where code = {1};'''.format(modItem['domainName'], modItem['code']) - return sql \ No newline at end of file + """ + # Abstract method. Must be reimplemented in each child. + sql = "" + for modItem in self.customJson["domainValue"]: + sql += """DELETE FROM dominios."{0}" where code = {1};""".format( + modItem["domainName"], modItem["code"] + ) + return sql diff --git a/DsgTools/core/Factories/DbCustomizationFactory/filterCustomization.py b/DsgTools/core/Factories/DbCustomizationFactory/filterCustomization.py index 19609ea3e..a627c16ae 100644 --- a/DsgTools/core/Factories/DbCustomizationFactory/filterCustomization.py +++ b/DsgTools/core/Factories/DbCustomizationFactory/filterCustomization.py @@ -20,36 +20,59 @@ * * ***************************************************************************/ """ -#DsgTools Imports +# DsgTools Imports from builtins import map -from DsgTools.core.Factories.DbCustomizationFactory.dbCustomization import DbCustomization +from DsgTools.core.Factories.DbCustomizationFactory.dbCustomization import ( + DbCustomization, +) + class FilterCustomization(DbCustomization): def __init__(self, customJson): super(FilterCustomization, self).__init__(customJson) - + def buildSql(self): - ''' + """ {'schema':schema, 'tableName':tableName, 'attrName':attrName, 'filterName':filterName,'originalFilterList':originalFilterList, 'valueList':valueList, 'operation':operation, 'isMulti':isMulti} - ''' - #Abstract method. Must be reimplemented in each child. - sql = '' - for modItem in self.customJson['FilterValue']: - filterList = modItem['originalFilterList'] - if modItem['code'] not in filterList: - filterList.append(modItem['code']) - sql += ''''ALTER TABLE "{0}"."{1}" DROP CONSTRAINT IF EXISTS {2};\n'''.format(modItem['schema'], modItem['tableName'], modItem['filterName']) - sql += '''ALTER TABLE "{0}"."{1}" ADD CONSTRAINT {2} CHECK ({3} = ANY(ARRAY[{4}]);\n'''.format(modItem['schema'], modItem['tableName'], modItem['filterName'], modItem['attrName'], '::SMALLINT,'.join(map(str,filterList))+'::SMALLINT') + """ + # Abstract method. Must be reimplemented in each child. + sql = "" + for modItem in self.customJson["FilterValue"]: + filterList = modItem["originalFilterList"] + if modItem["code"] not in filterList: + filterList.append(modItem["code"]) + sql += ( + """'ALTER TABLE "{0}"."{1}" DROP CONSTRAINT IF EXISTS {2};\n""".format( + modItem["schema"], modItem["tableName"], modItem["filterName"] + ) + ) + sql += """ALTER TABLE "{0}"."{1}" ADD CONSTRAINT {2} CHECK ({3} = ANY(ARRAY[{4}]);\n""".format( + modItem["schema"], + modItem["tableName"], + modItem["filterName"], + modItem["attrName"], + "::SMALLINT,".join(map(str, filterList)) + "::SMALLINT", + ) return sql - + def buildUndoSql(self): - ''' + """ {'domainName':domainName, 'valueDict': valueDict} - ''' - #Abstract method. Must be reimplemented in each child. - sql = '' - for modItem in self.customJson['FilterValue']: - filterList = modItem['originalFilterList'] - sql += '''ALTER TABLE "{0}"."{1}" DROP CONSTRAINT IF EXISTS "{2}";\n'''.format(modItem['schema'], modItem['tableName'], modItem['filterName']) - sql += '''ALTER TABLE "{0}"."{1}" ADD CONSTRAINT "{2}" CHECK ({3} = ANY(ARRAY[{4}]);\n'''.format(modItem['schema'], modItem['tableName'], modItem['filterName'], modItem['attrName'], '::SMALLINT,'.join(map(str,filterList))+'::SMALLINT') - return sql \ No newline at end of file + """ + # Abstract method. Must be reimplemented in each child. + sql = "" + for modItem in self.customJson["FilterValue"]: + filterList = modItem["originalFilterList"] + sql += ( + """ALTER TABLE "{0}"."{1}" DROP CONSTRAINT IF EXISTS "{2}";\n""".format( + modItem["schema"], modItem["tableName"], modItem["filterName"] + ) + ) + sql += """ALTER TABLE "{0}"."{1}" ADD CONSTRAINT "{2}" CHECK ({3} = ANY(ARRAY[{4}]);\n""".format( + modItem["schema"], + modItem["tableName"], + modItem["filterName"], + modItem["attrName"], + "::SMALLINT,".join(map(str, filterList)) + "::SMALLINT", + ) + return sql diff --git a/DsgTools/core/Factories/DbCustomizationFactory/newDomainTableCustomization.py b/DsgTools/core/Factories/DbCustomizationFactory/newDomainTableCustomization.py index b7596c09d..973194601 100644 --- a/DsgTools/core/Factories/DbCustomizationFactory/newDomainTableCustomization.py +++ b/DsgTools/core/Factories/DbCustomizationFactory/newDomainTableCustomization.py @@ -20,32 +20,41 @@ * * ***************************************************************************/ """ -#DsgTools Imports -from DsgTools.core.Factories.DbCustomizationFactory.dbCustomization import DbCustomization +# DsgTools Imports +from DsgTools.core.Factories.DbCustomizationFactory.dbCustomization import ( + DbCustomization, +) + class NewDomainTableCustomization(DbCustomization): def __init__(self, customJson): super(NewDomainTableCustomization, self).__init__(customJson) - + def buildSql(self): - ''' + """ {'domainName':domainName, 'valueDict': valueDict} - ''' - #Abstract method. Must be reimplemented in each child. - sql = '' - for modItem in self.customJson['AddDomainTable']: - sql += '''CREATE TABLE IF NOT EXISTS dominios."{0}";\n'''.format(modItem['domainName']) - for code in list(modItem['valueDict'].keys()): - sql += '''INSERT INTO dominios."{0}" (code, code_name) VALUES ({1}, '{2}');\n'''.format(modItem['domainName'],code, modItem['valueDict'][code]) + """ + # Abstract method. Must be reimplemented in each child. + sql = "" + for modItem in self.customJson["AddDomainTable"]: + sql += """CREATE TABLE IF NOT EXISTS dominios."{0}";\n""".format( + modItem["domainName"] + ) + for code in list(modItem["valueDict"].keys()): + sql += """INSERT INTO dominios."{0}" (code, code_name) VALUES ({1}, '{2}');\n""".format( + modItem["domainName"], code, modItem["valueDict"][code] + ) return sql - + def buildUndoSql(self): - ''' + """ {'domainName':domainName, 'valueDict': valueDict} - ''' - #Abstract method. Must be reimplemented in each child. - sql = '' - for modItem in self.customJson['AddDomainTable']: - for code in list(modItem['valueDict'].keys()): - sql += '''DROP TABLE IF EXISTS dominios."{0}";'''.format(modItem['domainName']) - return sql \ No newline at end of file + """ + # Abstract method. Must be reimplemented in each child. + sql = "" + for modItem in self.customJson["AddDomainTable"]: + for code in list(modItem["valueDict"].keys()): + sql += """DROP TABLE IF EXISTS dominios."{0}";""".format( + modItem["domainName"] + ) + return sql diff --git a/DsgTools/core/Factories/DbCustomizationFactory/newDomainValueCustomization.py b/DsgTools/core/Factories/DbCustomizationFactory/newDomainValueCustomization.py index addc0ba25..0fd56be18 100644 --- a/DsgTools/core/Factories/DbCustomizationFactory/newDomainValueCustomization.py +++ b/DsgTools/core/Factories/DbCustomizationFactory/newDomainValueCustomization.py @@ -20,29 +20,36 @@ * * ***************************************************************************/ """ -#DsgTools Imports -from DsgTools.core.Factories.DbCustomizationFactory.dbCustomization import DbCustomization +# DsgTools Imports +from DsgTools.core.Factories.DbCustomizationFactory.dbCustomization import ( + DbCustomization, +) + class NewDomainValueCustomization(DbCustomization): def __init__(self, customJson): super(NewDomainValueCustomization, self).__init__(customJson) - + def buildSql(self): - ''' + """ {'domainName':domainName, 'code':code, 'code_name':code_name} - ''' - #Abstract method. Must be reimplemented in each child. - sql = '' - for modItem in self.customJson['AddDomainValue']: - sql += '''INSERT INTO dominios."{0}" (code, code_name) VALUES ({1}, '{2}');\n'''.format(modItem['domainName'], code, code_name) + """ + # Abstract method. Must be reimplemented in each child. + sql = "" + for modItem in self.customJson["AddDomainValue"]: + sql += """INSERT INTO dominios."{0}" (code, code_name) VALUES ({1}, '{2}');\n""".format( + modItem["domainName"], code, code_name + ) return sql - + def buildUndoSql(self): - ''' + """ {'domainName':domainName, 'code':code, 'code_name':code_name} - ''' - #Abstract method. Must be reimplemented in each child. - sql = '' - for modItem in self.customJson['AddDomainValue']: - sql += '''DELETE FROM dominios."{0}" where code = {1};\n'''.format(modItem['domainName'], modItem['code']) - return sql \ No newline at end of file + """ + # Abstract method. Must be reimplemented in each child. + sql = "" + for modItem in self.customJson["AddDomainValue"]: + sql += """DELETE FROM dominios."{0}" where code = {1};\n""".format( + modItem["domainName"], modItem["code"] + ) + return sql diff --git a/DsgTools/core/Factories/DbCustomizationFactory/nullityCustomization.py b/DsgTools/core/Factories/DbCustomizationFactory/nullityCustomization.py index ad812a700..49d5a593b 100644 --- a/DsgTools/core/Factories/DbCustomizationFactory/nullityCustomization.py +++ b/DsgTools/core/Factories/DbCustomizationFactory/nullityCustomization.py @@ -20,37 +20,44 @@ * * ***************************************************************************/ """ -#DsgTools Imports -from DsgTools.core.Factories.DbCustomizationFactory.dbCustomization import DbCustomization +# DsgTools Imports +from DsgTools.core.Factories.DbCustomizationFactory.dbCustomization import ( + DbCustomization, +) + class NullityCustomization(DbCustomization): def __init__(self, customJson): super(NullityCustomization, self).__init__(customJson) - + def buildSql(self): """ {'schema':schema, 'table':table, 'attrName':attrName, 'notNull':notNull} """ - #Abstract method. Must be reimplemented in each child. + # Abstract method. Must be reimplemented in each child. sql = """""" - for modItem in self.customJson['ChangeNullity']: - if modItem['notNull']: - nullClause = 'SET' + for modItem in self.customJson["ChangeNullity"]: + if modItem["notNull"]: + nullClause = "SET" else: - nullClause = 'DROP' - sql += """ALTER TABLE ONLY "{0}"."{1}" ALTER COLUMN "{2}" {3} NOT NULL;\n""".format(modItem['schema'], modItem['table'], modItem['attrName'], nullClause) + nullClause = "DROP" + sql += """ALTER TABLE ONLY "{0}"."{1}" ALTER COLUMN "{2}" {3} NOT NULL;\n""".format( + modItem["schema"], modItem["table"], modItem["attrName"], nullClause + ) return sql - + def buildUndoSql(self): """ {'schema':schema, 'table':table, 'attrName':attrName, 'notNull':notNull} """ - #Abstract method. Must be reimplemented in each child. + # Abstract method. Must be reimplemented in each child. sql = """""" - for modItem in self.customJson['ChangeNullity']: - if not modItem['notNull']: - nullClause = 'SET' + for modItem in self.customJson["ChangeNullity"]: + if not modItem["notNull"]: + nullClause = "SET" else: - nullClause = 'DROP' - sql += """ALTER TABLE ONLY "{0}"."{1}" ALTER COLUMN "{2}" {3} NOT NULL;\n""".format(modItem['schema'], modItem['table'], modItem['attrName'], nullClause) - return sql \ No newline at end of file + nullClause = "DROP" + sql += """ALTER TABLE ONLY "{0}"."{1}" ALTER COLUMN "{2}" {3} NOT NULL;\n""".format( + modItem["schema"], modItem["table"], modItem["attrName"], nullClause + ) + return sql diff --git a/DsgTools/core/Factories/DbFactory/abstractDb.py b/DsgTools/core/Factories/DbFactory/abstractDb.py index 61282d3f0..745a687c9 100644 --- a/DsgTools/core/Factories/DbFactory/abstractDb.py +++ b/DsgTools/core/Factories/DbFactory/abstractDb.py @@ -32,21 +32,31 @@ from ...Utils.utils import Utils from DsgTools.core.Utils.FrameTools.map_index import UtmGrid + class DbSignals(QObject): updateLog = pyqtSignal(str) clearLog = pyqtSignal() + class AbstractDb(QObject): def __init__(self): """ Constructor """ - super(AbstractDb,self).__init__() - self.conversionTypeDict = dict({'QPSQL':'postgis','QSQLITE':'spatialite'}) + super(AbstractDb, self).__init__() + self.conversionTypeDict = dict({"QPSQL": "postgis", "QSQLITE": "spatialite"}) self.utils = Utils() self.signals = DbSignals() self.slotConnected = False - self.versionFolderDict = dict({'2.1.3':'edgv_213','2.1.3 Pro':'edgv_213_pro','FTer_2a_Ed':'edgv_FTer_2a_Ed','3.0':'3','3.0 Pro':'3_Pro'}) + self.versionFolderDict = dict( + { + "2.1.3": "edgv_213", + "2.1.3 Pro": "edgv_213_pro", + "FTer_2a_Ed": "edgv_FTer_2a_Ed", + "3.0": "3", + "3.0 Pro": "3_Pro", + } + ) self.utmGrid = UtmGrid() def __del__(self): @@ -57,17 +67,19 @@ def __del__(self): self.closeDatabase() except: pass - + def closeDatabase(self): pass - + def checkAndOpenDb(self): """ Check and open the database """ if not self.db.isOpen(): if not self.db.open(): - raise Exception(self.tr('Error opening database: ')+self.db.lastError().text()) + raise Exception( + self.tr("Error opening database: ") + self.db.lastError().text() + ) def getType(self): """ @@ -90,60 +102,61 @@ def countElements(self, layers): listaQuantidades = [] for layer in layers: (schema, className) = self.getTableSchema(layer) - if layer.split('_')[-1].lower() in ['p','l','a'] or schema == 'complexos': + if layer.split("_")[-1].lower() in ["p", "l", "a"] or schema == "complexos": sql = self.gen.getElementCountFromLayer(layer) - query = QSqlQuery(sql,self.db) + query = QSqlQuery(sql, self.db) query.next() number = query.value(0) if not query.exec_(sql): - raise Exception(self.tr("Problem counting elements: ")+query.lastError().text()) + raise Exception( + self.tr("Problem counting elements: ") + + query.lastError().text() + ) listaQuantidades.append([layer, number]) return listaQuantidades - + def getLayersWithElements(self, layerList): self.checkAndOpenDb() lyrWithElemList = [] for lyr in layerList: # schema=self.getTableSchemaFromDb(lyr) sql = self.gen.getElementCountFromLayer(lyr) - query = QSqlQuery(sql,self.db) + query = QSqlQuery(sql, self.db) query.next() if query.value(0) is not None and query.value(0) > 1: lyrWithElemList.append(lyr) return lyrWithElemList - def getLayersWithElementsV2(self, layerList, useInheritance = False): + def getLayersWithElementsV2(self, layerList, useInheritance=False): self.checkAndOpenDb() lyrWithElemList = [] for layer in layerList: if isinstance(layer, dict): - schema = layer['tableSchema'] - lyr = layer['tableName'] + schema = layer["tableSchema"] + lyr = layer["tableName"] else: - if '.' in layer: - schema, lyr = layer.replace('"','').split('.') + if "." in layer: + schema, lyr = layer.replace('"', "").split(".") else: lyr = layer schema = self.getTableSchemaFromDb(lyr) sql = self.gen.getElementCountFromLayerV2(schema, lyr, useInheritance) - query = QSqlQuery(sql,self.db) + query = QSqlQuery(sql, self.db) if not query.next(): # use may not have permission to read the table from schema QgsMessageLog.logMessage( - self.tr("Unable to read table {0}. Error message: '{1}'")\ - .format( - self.db.databaseName(), - self.db.lastError().databaseText() - ), + self.tr("Unable to read table {0}. Error message: '{1}'").format( + self.db.databaseName(), self.db.lastError().databaseText() + ), "DSGTools Plugin", - Qgis.Warning + Qgis.Warning, ) continue if query.value(0) > 0: lyrWithElemList.append(lyr) return lyrWithElemList - + def findEPSG(self, parameters=dict()): """ Finds the database EPSG @@ -152,7 +165,9 @@ def findEPSG(self, parameters=dict()): sql = self.gen.getSrid(parameters=parameters) query = QSqlQuery(sql, self.db) if not query.isActive(): - raise Exception(self.tr("Problem finding EPSG: ")+query.lastError().text()) + raise Exception( + self.tr("Problem finding EPSG: ") + query.lastError().text() + ) srid = -1 while query.next(): srid = query.value(0) @@ -168,11 +183,11 @@ def listWithElementsFromDatabase(self, classList): classListWithNumber = self.countElements(classList) classesWithElements = dict() for cl in classListWithNumber: - if cl[1]>0: - classesWithElements[cl[0]]=cl[1] + if cl[1] > 0: + classesWithElements[cl[0]] = cl[1] return classesWithElements - def listClassesWithElementsFromDatabase(self, useComplex = True, primitiveFilter = []): + def listClassesWithElementsFromDatabase(self, useComplex=True, primitiveFilter=[]): """ List classes with elements. Uses all classes (complex included) """ @@ -193,7 +208,10 @@ def getAggregationAttributes(self): sql = self.gen.getAggregationColumn() query = QSqlQuery(sql, self.db) if not query.isActive(): - raise Exception(self.tr("Problem getting aggregation attributes: ")+query.lastError().text()) + raise Exception( + self.tr("Problem getting aggregation attributes: ") + + query.lastError().text() + ) while query.next(): value = query.value(0) columns.append(value) @@ -217,18 +235,18 @@ def buildFieldMap(self): def validateWithOutputDatabaseSchema(self, outputAbstractDb): return None - + def convertDatabase(self, outputAbstractDb, type): """ Converts database """ self.signals.clearLog.emit() - if outputAbstractDb.db.driverName() == 'QPSQL': - return self.convertToPostgis(outputAbstractDb,type) - if outputAbstractDb.db.driverName() == 'QSQLITE': - return self.convertToSpatialite(outputAbstractDb,type) + if outputAbstractDb.db.driverName() == "QPSQL": + return self.convertToPostgis(outputAbstractDb, type) + if outputAbstractDb.db.driverName() == "QSQLITE": + return self.convertToSpatialite(outputAbstractDb, type) return None - + def makeValidationSummary(self, invalidatedDataDict): """ Makes the database conversion validation summary @@ -238,108 +256,210 @@ def makeValidationSummary(self, invalidatedDataDict): if len(invalidatedDataDict[key]) > 0: hasErrors = True if hasErrors: - self.signals.updateLog.emit('\n'+'{:-^60}'.format(self.tr('Validation Problems Summary'))) + self.signals.updateLog.emit( + "\n" + "{:-^60}".format(self.tr("Validation Problems Summary")) + ) for key in list(invalidatedDataDict.keys()): - - if key == 'nullLine' and len(invalidatedDataDict[key])>0: - self.signals.updateLog.emit('\n\n'+self.tr('Classes with null lines:')+'\n') - self.signals.updateLog.emit('\n\n'+'{:<50}'.format(self.tr('Class'))+self.tr('Elements')+'\n\n') + + if key == "nullLine" and len(invalidatedDataDict[key]) > 0: + self.signals.updateLog.emit( + "\n\n" + self.tr("Classes with null lines:") + "\n" + ) + self.signals.updateLog.emit( + "\n\n" + + "{:<50}".format(self.tr("Class")) + + self.tr("Elements") + + "\n\n" + ) for cl in list(invalidatedDataDict[key].keys()): - self.signals.updateLog.emit('{:<50}'.format(cl)+str(invalidatedDataDict[key][cl])+'\n') + self.signals.updateLog.emit( + "{:<50}".format(cl) + + str(invalidatedDataDict[key][cl]) + + "\n" + ) - if key == 'nullPk' and len(invalidatedDataDict[key])>0: - self.signals.updateLog.emit('\n\n'+self.tr('Classes with null primary keys:')+'\n') - self.signals.updateLog.emit('\n\n'+'{:<50}'.format(self.tr('Class'))+self.tr('Elements')+'\n\n') + if key == "nullPk" and len(invalidatedDataDict[key]) > 0: + self.signals.updateLog.emit( + "\n\n" + self.tr("Classes with null primary keys:") + "\n" + ) + self.signals.updateLog.emit( + "\n\n" + + "{:<50}".format(self.tr("Class")) + + self.tr("Elements") + + "\n\n" + ) for cl in list(invalidatedDataDict[key].keys()): - self.signals.updateLog.emit('{:<50}'.format(cl)+str(invalidatedDataDict[key][cl])+'\n') + self.signals.updateLog.emit( + "{:<50}".format(cl) + + str(invalidatedDataDict[key][cl]) + + "\n" + ) - if key == 'notInDomain' and len(invalidatedDataDict[key])>0: - self.signals.updateLog.emit('\n\n'+self.tr('Features with attributes not in domain:')+'\n\n') + if key == "notInDomain" and len(invalidatedDataDict[key]) > 0: + self.signals.updateLog.emit( + "\n\n" + + self.tr("Features with attributes not in domain:") + + "\n\n" + ) for cl in list(invalidatedDataDict[key].keys()): - self.signals.updateLog.emit('\n'+self.tr('Class: ')+cl+'\n') + self.signals.updateLog.emit( + "\n" + self.tr("Class: ") + cl + "\n" + ) for id in list(invalidatedDataDict[key][cl].keys()): - attrCommaList = '(id,'+','.join(list(invalidatedDataDict[key][cl][id].keys()))+') = ' + attrCommaList = ( + "(id," + + ",".join( + list(invalidatedDataDict[key][cl][id].keys()) + ) + + ") = " + ) at = list(invalidatedDataDict[key][cl][id].keys()) - valueList = '('+str(id) + valueList = "(" + str(id) for i in range(len(at)): - valueList += ','+str(invalidatedDataDict[key][cl][id][at[i]]) - valueList += ')\n' - self.signals.updateLog.emit(attrCommaList+valueList) + valueList += "," + str( + invalidatedDataDict[key][cl][id][at[i]] + ) + valueList += ")\n" + self.signals.updateLog.emit(attrCommaList + valueList) - if key == 'nullAttribute' and len(invalidatedDataDict[key])>0: - self.signals.updateLog.emit('\n\n'+self.tr('Features with null attributes in a not null field:')+'\n\n') + if key == "nullAttribute" and len(invalidatedDataDict[key]) > 0: + self.signals.updateLog.emit( + "\n\n" + + self.tr("Features with null attributes in a not null field:") + + "\n\n" + ) for cl in list(invalidatedDataDict[key].keys()): - self.signals.updateLog.emit(self.tr('Class: ')+cl+'\n') + self.signals.updateLog.emit(self.tr("Class: ") + cl + "\n") for id in list(invalidatedDataDict[key][cl].keys()): - attrCommaList = '(id,'+','.join(list(invalidatedDataDict[key][cl][id].keys()))+') = ' - valueList = '('+str(id) + attrCommaList = ( + "(id," + + ",".join( + list(invalidatedDataDict[key][cl][id].keys()) + ) + + ") = " + ) + valueList = "(" + str(id) for attr in list(invalidatedDataDict[key][cl][id].keys()): - valueList += ','+str(invalidatedDataDict[key][cl][id][attr]) - valueList += ')\n' - self.signals.updateLog.emit(attrCommaList+valueList) + valueList += "," + str( + invalidatedDataDict[key][cl][id][attr] + ) + valueList += ")\n" + self.signals.updateLog.emit(attrCommaList + valueList) - if key == 'nullComplexFk' and len(invalidatedDataDict[key])>0: - self.signals.updateLog.emit('\n\n'+self.tr('Features with invalid uuid foreign key:')+'\n\n') + if key == "nullComplexFk" and len(invalidatedDataDict[key]) > 0: + self.signals.updateLog.emit( + "\n\n" + + self.tr("Features with invalid uuid foreign key:") + + "\n\n" + ) for cl in list(invalidatedDataDict[key].keys()): - self.signals.updateLog.emit(self.tr('Class: ')+cl+'\n') + self.signals.updateLog.emit(self.tr("Class: ") + cl + "\n") for id in list(invalidatedDataDict[key][cl].keys()): - attrCommaList = '(id,'+','.join(list(invalidatedDataDict[key][cl][id].keys()))+') = ' - valueList = '('+str(id) + attrCommaList = ( + "(id," + + ",".join( + list(invalidatedDataDict[key][cl][id].keys()) + ) + + ") = " + ) + valueList = "(" + str(id) for attr in list(invalidatedDataDict[key][cl][id].keys()): - valueList += ','+str(invalidatedDataDict[key][cl][id][attr]) - valueList += ')\n' - self.signals.updateLog.emit(attrCommaList+valueList) - - if key == 'classNotFoundInOutput' and len(invalidatedDataDict[key])>0: - self.signals.updateLog.emit('\n\n'+self.tr('Classes with classes that have elements but do not have output equivalent:')+'\n\n') + valueList += "," + str( + invalidatedDataDict[key][cl][id][attr] + ) + valueList += ")\n" + self.signals.updateLog.emit(attrCommaList + valueList) + + if key == "classNotFoundInOutput" and len(invalidatedDataDict[key]) > 0: + self.signals.updateLog.emit( + "\n\n" + + self.tr( + "Classes with classes that have elements but do not have output equivalent:" + ) + + "\n\n" + ) for cl in invalidatedDataDict[key]: - self.signals.updateLog.emit(self.tr('Class: ')+cl+'\n') - - if key == 'attributeNotFoundInOutput' and len(invalidatedDataDict[key])>0: - self.signals.updateLog.emit('\n\n'+self.tr('Classes with attributes that have no output attribute equivalent:')+'\n\n') + self.signals.updateLog.emit(self.tr("Class: ") + cl + "\n") + + if ( + key == "attributeNotFoundInOutput" + and len(invalidatedDataDict[key]) > 0 + ): + self.signals.updateLog.emit( + "\n\n" + + self.tr( + "Classes with attributes that have no output attribute equivalent:" + ) + + "\n\n" + ) for cl in list(invalidatedDataDict[key].keys()): - self.signals.updateLog.emit(self.tr('Class: ')+cl+'\n') - valueList = '('+','.join(invalidatedDataDict[key][cl])+')\n' + self.signals.updateLog.emit(self.tr("Class: ") + cl + "\n") + valueList = "(" + ",".join(invalidatedDataDict[key][cl]) + ")\n" self.signals.updateLog.emit(valueList) - + return hasErrors - - def buildReadSummary(self,inputOgrDb,outputAbstractDb,classList): + + def buildReadSummary(self, inputOgrDb, outputAbstractDb, classList): """ Builds the conversion read summary """ - self.signals.clearLog.emit() #Clears log + self.signals.clearLog.emit() # Clears log inputType = self.conversionTypeDict[self.db.driverName()] outputType = self.conversionTypeDict[outputAbstractDb.db.driverName()] - self.signals.updateLog.emit(self.tr('Conversion type: ')+inputType+'2'+outputType+'\n') - self.signals.updateLog.emit('\n'+self.tr('Input database: ')+self.db.databaseName()+'\n') - self.signals.updateLog.emit('\n'+self.tr('Output database: ')+outputAbstractDb.db.databaseName()+'\n') - self.signals.updateLog.emit('\n'+'{:-^60}'.format(self.tr('Read Summary'))) - self.signals.updateLog.emit('\n\n'+'{:<50}'.format(self.tr('Class'))+self.tr('Elements')+'\n\n') + self.signals.updateLog.emit( + self.tr("Conversion type: ") + inputType + "2" + outputType + "\n" + ) + self.signals.updateLog.emit( + "\n" + self.tr("Input database: ") + self.db.databaseName() + "\n" + ) + self.signals.updateLog.emit( + "\n" + + self.tr("Output database: ") + + outputAbstractDb.db.databaseName() + + "\n" + ) + self.signals.updateLog.emit("\n" + "{:-^60}".format(self.tr("Read Summary"))) + self.signals.updateLog.emit( + "\n\n" + "{:<50}".format(self.tr("Class")) + self.tr("Elements") + "\n\n" + ) for cl in classList: - self.signals.updateLog.emit('{:<50}'.format(cl)+str(inputOgrDb.GetLayerByName(str(cl)).GetFeatureCount())+'\n') + self.signals.updateLog.emit( + "{:<50}".format(cl) + + str(inputOgrDb.GetLayerByName(str(cl)).GetFeatureCount()) + + "\n" + ) return None - + def makeTranslationMap(self, layerName, layer, outLayer, fieldMapper): """ Makes the translation map """ - layerFieldMapper=fieldMapper[layerName] + layerFieldMapper = fieldMapper[layerName] layerDef = layer.GetLayerDefn() outLayerDef = outLayer.GetLayerDefn() - panMap = [] + panMap = [] for i in range(layerDef.GetFieldCount()): featureDef = layerDef.GetFieldDefn(i) fieldName = featureDef.GetName() if fieldName in list(layerFieldMapper.keys()): name = layerFieldMapper[fieldName] fieldId = outLayerDef.GetFieldIndex(name) - panMap.append(fieldId) + panMap.append(fieldId) else: panMap.append(-1) return panMap - - def translateLayer(self, inputLayer, inputLayerName, outputLayer, outputFileName, layerPanMap, errorDict, defaults={}, translateValues={}): + + def translateLayer( + self, + inputLayer, + inputLayerName, + outputLayer, + outputFileName, + layerPanMap, + errorDict, + defaults={}, + translateValues={}, + ): """ Makes the layer conversion """ @@ -351,66 +471,87 @@ def translateLayer(self, inputLayer, inputLayerName, outputLayer, outputFileName coordTrans = osr.CoordinateTransformation(inSpatialRef, outSpatialRef) initialCount = outputLayer.GetFeatureCount() count = 0 - feat=inputLayer.GetNextFeature() - #for feat in inputLayer: + feat = inputLayer.GetNextFeature() + # for feat in inputLayer: while feat: if not feat.geometry(): continue inputId = feat.GetFID() if feat.geometry().GetGeometryCount() > 1: - #Deaggregator + # Deaggregator for geom in feat.geometry(): - newFeat=ogr.Feature(outputLayer.GetLayerDefn()) - newFeat.SetFromWithMap(feat,True,layerPanMap) + newFeat = ogr.Feature(outputLayer.GetLayerDefn()) + newFeat.SetFromWithMap(feat, True, layerPanMap) auxGeom = ogr.Geometry(newFeat.geometry().GetGeometryType()) - auxGeom.AssignSpatialReference(newFeat.geometry().GetSpatialReference()) + auxGeom.AssignSpatialReference( + newFeat.geometry().GetSpatialReference() + ) auxGeom.AddGeometry(geom) if coordTrans != None: auxGeom.Transform(coordTrans) newFeat.SetGeometry(auxGeom) - out=outputLayer.CreateFeature(newFeat) + out = outputLayer.CreateFeature(newFeat) if out != 0: - self.utils.buildNestedDict(errorDict, [inputLayerName], [inputId]) + self.utils.buildNestedDict( + errorDict, [inputLayerName], [inputId] + ) else: count += 1 else: - newFeat=ogr.Feature(outputLayer.GetLayerDefn()) - newFeat.SetFromWithMap(feat,True,layerPanMap) + newFeat = ogr.Feature(outputLayer.GetLayerDefn()) + newFeat.SetFromWithMap(feat, True, layerPanMap) if coordTrans != None: geom = feat.GetGeometryRef() geom.Transform(coordTrans) newFeat.SetGeometry(geom) - out=outputLayer.CreateFeature(newFeat) + out = outputLayer.CreateFeature(newFeat) if out != 0: self.utils.buildNestedDict(errorDict, [inputLayerName], [inputId]) else: count += 1 - feat=inputLayer.GetNextFeature() + feat = inputLayer.GetNextFeature() return count - - def translateDS(self, inputDS, outputDS, fieldMap, inputLayerList, errorDict,invalidated=None): + + def translateDS( + self, inputDS, outputDS, fieldMap, inputLayerList, errorDict, invalidated=None + ): """ Translates the data source """ - self.signals.updateLog.emit('\n'+'{:-^60}'.format(self.tr('Write Summary'))) - self.signals.updateLog.emit('\n\n'+'{:<50}'.format(self.tr('Class'))+self.tr('Elements')+'\n\n') + self.signals.updateLog.emit("\n" + "{:-^60}".format(self.tr("Write Summary"))) + self.signals.updateLog.emit( + "\n\n" + "{:<50}".format(self.tr("Class")) + self.tr("Elements") + "\n\n" + ) status = False for inputLyr in list(inputLayerList.keys()): schema = self.getTableSchema(inputLyr) attrList = list(fieldMap[inputLyr].keys()) - - #sql = self.gen.getFeaturesWithSQL(inputLyr,attrList) #order elements here - #inputOgrLayer = inputDS.ExecuteSQL(sql.encode('utf-8')) - #Here I had to change the way of loading because of features ids. I need to use inputDs.GetLayerByName - - inputOgrLayer = inputDS.GetLayerByName(str(inputLyr)) #new way of loading layer. The old way was an attempt to make a general rule for conversion between edgv versions - outputFileName = self.translateOGRLayerNameToOutputFormat(inputLyr,outputDS) - outputLayer=outputDS.GetLayerByName(outputFileName) - #order conversion here - layerPanMap=self.makeTranslationMap(inputLyr, inputOgrLayer,outputLayer, fieldMap) + + # sql = self.gen.getFeaturesWithSQL(inputLyr,attrList) #order elements here + # inputOgrLayer = inputDS.ExecuteSQL(sql.encode('utf-8')) + # Here I had to change the way of loading because of features ids. I need to use inputDs.GetLayerByName + + inputOgrLayer = inputDS.GetLayerByName( + str(inputLyr) + ) # new way of loading layer. The old way was an attempt to make a general rule for conversion between edgv versions + outputFileName = self.translateOGRLayerNameToOutputFormat( + inputLyr, outputDS + ) + outputLayer = outputDS.GetLayerByName(outputFileName) + # order conversion here + layerPanMap = self.makeTranslationMap( + inputLyr, inputOgrLayer, outputLayer, fieldMap + ) ini = outputLayer.GetFeatureCount() if invalidated == None: - iter=self.translateLayer(inputOgrLayer, inputLyr, outputLayer, outputFileName, layerPanMap, errorDict) + iter = self.translateLayer( + inputOgrLayer, + inputLyr, + outputLayer, + outputFileName, + layerPanMap, + errorDict, + ) else: needsFix = False for keyDict in list(invalidated.values()): @@ -423,38 +564,62 @@ def translateDS(self, inputDS, outputDS, fieldMap, inputLayerList, errorDict,inv needsFix = True break if needsFix: - iter = self.translateLayerWithDataFix(inputOgrLayer, inputLyr, outputLayer, outputFileName, layerPanMap, invalidated, errorDict) + iter = self.translateLayerWithDataFix( + inputOgrLayer, + inputLyr, + outputLayer, + outputFileName, + layerPanMap, + invalidated, + errorDict, + ) else: - iter=self.translateLayer(inputOgrLayer, inputLyr, outputLayer, outputFileName, layerPanMap, errorDict) + iter = self.translateLayer( + inputOgrLayer, + inputLyr, + outputLayer, + outputFileName, + layerPanMap, + errorDict, + ) if iter == -1: status = False - self.signals.updateLog.emit('{:<50}'.format(self.tr('Error on layer ')+inputLyr+self.tr('. Conversion not performed.')+'\n')) + self.signals.updateLog.emit( + "{:<50}".format( + self.tr("Error on layer ") + + inputLyr + + self.tr(". Conversion not performed.") + + "\n" + ) + ) return status - diff = outputLayer.GetFeatureCount()-ini + diff = outputLayer.GetFeatureCount() - ini if iter == diff: status = True else: status = False - self.signals.updateLog.emit('{:<50}'.format(str(outputFileName))+str(diff)+'\n') + self.signals.updateLog.emit( + "{:<50}".format(str(outputFileName)) + str(diff) + "\n" + ) self.writeErrorLog(errorDict) outputDS.Destroy() return status - + def buildInvalidatedDict(self): """ Builds the initial state of the conversion invalidated dictionary """ invalidated = dict() - invalidated['nullLine'] = dict() - invalidated['nullPk'] = dict() - invalidated['notInDomain'] = dict() - invalidated['nullAttribute'] = dict() - invalidated['classNotFoundInOutput'] = [] - invalidated['attributeNotFoundInOutput'] = dict() - invalidated['nullComplexFk'] = dict() + invalidated["nullLine"] = dict() + invalidated["nullPk"] = dict() + invalidated["notInDomain"] = dict() + invalidated["nullAttribute"] = dict() + invalidated["classNotFoundInOutput"] = [] + invalidated["attributeNotFoundInOutput"] = dict() + invalidated["nullComplexFk"] = dict() return invalidated - - def prepareForConversion(self,outputAbstractDb): + + def prepareForConversion(self, outputAbstractDb): """ Executes preconditions for the conversion """ @@ -465,10 +630,21 @@ def prepareForConversion(self,outputAbstractDb): outputOgrDb = outputAbstractDb.buildOgrDatabase() inputLayerList = self.listClassesWithElementsFromDatabase() errorDict = dict() - self.buildReadSummary(inputOgrDb,outputAbstractDb,inputLayerList) + self.buildReadSummary(inputOgrDb, outputAbstractDb, inputLayerList) return (inputOgrDb, outputOgrDb, fieldMap, inputLayerList, errorDict) - def translateLayerWithDataFix(self, inputLayer, inputLayerName, outputLayer, outputFileName, layerPanMap, invalidated, errorDict, defaults={}, translateValues={}): + def translateLayerWithDataFix( + self, + inputLayer, + inputLayerName, + outputLayer, + outputFileName, + layerPanMap, + invalidated, + errorDict, + defaults={}, + translateValues={}, + ): """ casos e tratamentos: 1. nullLine: os atributos devem ser varridos e, caso seja linha nula, ignorar o envio @@ -489,15 +665,15 @@ def translateLayerWithDataFix(self, inputLayer, inputLayerName, outputLayer, out if inSpatialRef != outSpatialRef: coordTrans = osr.CoordinateTransformation(inSpatialRef, outSpatialRef) count = 0 - feat=inputLayer.GetNextFeature() - (schema,className) = self.getTableSchema(inputLayerName) + feat = inputLayer.GetNextFeature() + (schema, className) = self.getTableSchema(inputLayerName) outputOgrLyrDict = self.getOgrLayerIndexDict(outputLayer) - if inputLayerName not in invalidated['classNotFoundInOutput']: + if inputLayerName not in invalidated["classNotFoundInOutput"]: while feat: if not feat.geometry(): continue nullLine = True - #Case 1: nullLine + # Case 1: nullLine for i in range(fieldCount): if feat.GetField(i) != None: nullLine = False @@ -505,43 +681,97 @@ def translateLayerWithDataFix(self, inputLayer, inputLayerName, outputLayer, out if feat.GetFID() != -1 or feat.geometry() != None: nullLine = False if not nullLine: - if inputLayerName not in invalidated['classNotFoundInOutput']: - newFeat=ogr.Feature(outputLayer.GetLayerDefn()) + if inputLayerName not in invalidated["classNotFoundInOutput"]: + newFeat = ogr.Feature(outputLayer.GetLayerDefn()) inputId = feat.GetFID() - #Case 2: nullPk in complex: - newFeat.SetFromWithMap(feat,True,layerPanMap) - if schema == 'complexos' and feat.GetFID() == -1: + # Case 2: nullPk in complex: + newFeat.SetFromWithMap(feat, True, layerPanMap) + if schema == "complexos" and feat.GetFID() == -1: newFeat.SetFID(uuid4()) - #Case 3 + # Case 3 for j in range(inputLayer.GetLayerDefn().GetFieldCount()): if layerPanMap[j] != -1: - if inputLayerName in list(invalidated['notInDomain'].keys()): - if inputId in list(invalidated['notInDomain'][inputLayerName].keys()): - if outputLayer.GetLayerDefn().GetFieldDefn(layerPanMap[j]).GetName() in list(invalidated['notInDomain'][inputLayerName][inputId].keys()): + if inputLayerName in list( + invalidated["notInDomain"].keys() + ): + if inputId in list( + invalidated["notInDomain"][ + inputLayerName + ].keys() + ): + if outputLayer.GetLayerDefn().GetFieldDefn( + layerPanMap[j] + ).GetName() in list( + invalidated["notInDomain"][inputLayerName][ + inputId + ].keys() + ): newFeat.UnsetField(layerPanMap[j]) - if inputLayerName in list(invalidated['nullAttribute'].keys()): - if inputId in list(invalidated['nullAttribute'][inputLayerName].keys()): - if outputLayer.GetLayerDefn().GetFieldDefn(layerPanMap[j]).GetName() in list(invalidated['nullAttribute'][inputLayerName][inputId].keys()): - if outputLayer.GetLayerDefn().GetFieldDefn(layerPanMap[j]).GetTypeName() == 'String': - newFeat.SetField(layerPanMap[j],'-9999') - if outputLayer.GetLayerDefn().GetFieldDefn(layerPanMap[j]).GetTypeName() == 'Integer': - newFeat.SetField(layerPanMap[j],-9999) - if inputLayerName in list(invalidated['nullComplexFk'].keys()): - if inputId in list(invalidated['nullComplexFk'][inputLayerName].keys()): - if outputLayer.GetLayerDefn().GetFieldDefn(layerPanMap[j]).GetName() in list(invalidated['nullComplexFk'][inputLayerName][inputId].keys()): + if inputLayerName in list( + invalidated["nullAttribute"].keys() + ): + if inputId in list( + invalidated["nullAttribute"][ + inputLayerName + ].keys() + ): + if outputLayer.GetLayerDefn().GetFieldDefn( + layerPanMap[j] + ).GetName() in list( + invalidated["nullAttribute"][ + inputLayerName + ][inputId].keys() + ): + if ( + outputLayer.GetLayerDefn() + .GetFieldDefn(layerPanMap[j]) + .GetTypeName() + == "String" + ): + newFeat.SetField( + layerPanMap[j], "-9999" + ) + if ( + outputLayer.GetLayerDefn() + .GetFieldDefn(layerPanMap[j]) + .GetTypeName() + == "Integer" + ): + newFeat.SetField(layerPanMap[j], -9999) + if inputLayerName in list( + invalidated["nullComplexFk"].keys() + ): + if inputId in list( + invalidated["nullComplexFk"][ + inputLayerName + ].keys() + ): + if outputLayer.GetLayerDefn().GetFieldDefn( + layerPanMap[j] + ).GetName() in list( + invalidated["nullComplexFk"][ + inputLayerName + ][inputId].keys() + ): newFeat.UnsetField(layerPanMap[j]) if newFeat.geometry().GetGeometryCount() > 1: - #Deaggregator + # Deaggregator for geom in newFeat.geometry(): - auxGeom = ogr.Geometry(newFeat.geometry().GetGeometryType()) - auxGeom.AssignSpatialReference(newFeat.geometry().GetSpatialReference()) + auxGeom = ogr.Geometry( + newFeat.geometry().GetGeometryType() + ) + auxGeom.AssignSpatialReference( + newFeat.geometry().GetSpatialReference() + ) auxGeom.AddGeometry(geom) if coordTrans != None: auxGeom.Transform(coordTrans) newFeat.SetGeometry(auxGeom) - out=outputLayer.CreateFeature(newFeat) + out = outputLayer.CreateFeature(newFeat) if out != 0: - self.utils.buildNestedDict(errorDict, [inputLayerName], [inputId]) + self.utils.buildNestedDict( + errorDict, [inputLayerName], [inputId] + ) else: count += 1 else: @@ -549,39 +779,41 @@ def translateLayerWithDataFix(self, inputLayer, inputLayerName, outputLayer, out geom = feat.GetGeometryRef() geom.Transform(coordTrans) newFeat.SetGeometry(geom) - out=outputLayer.CreateFeature(newFeat) + out = outputLayer.CreateFeature(newFeat) if out != 0: - self.utils.buildNestedDict(errorDict, [inputLayerName], [inputId]) + self.utils.buildNestedDict( + errorDict, [inputLayerName], [inputId] + ) else: count += 1 - feat=inputLayer.GetNextFeature() + feat = inputLayer.GetNextFeature() return count else: return -1 - + def buildOgrDatabase(self): """ Build a OGR database """ con = self.makeOgrConn() - ogrDb = ogr.Open(con,update=1) + ogrDb = ogr.Open(con, update=1) return ogrDb - + def reorderTupleList(self, ls): """ Reorders a tuple list ls: list to be reordered """ - if 'OGC_FID' in ls: - idField = 'OGC_FID' + if "OGC_FID" in ls: + idField = "OGC_FID" else: - idField = 'id' + idField = "id" index = ls.index(idField) reordered = [ls[index]] reordered.extend(ls[0:index]) - reordered.extend(ls[index+1::]) + reordered.extend(ls[index + 1 : :]) return reordered - + def getOgrLayerIndexDict(self, lyr): """ Gets ogr field definitions @@ -589,21 +821,28 @@ def getOgrLayerIndexDict(self, lyr): ogrDict = dict() layerDef = lyr.GetLayerDefn() for i in range(layerDef.GetFieldCount()): - ogrDict[i] = layerDef.GetFieldDefn(i).GetName() + ogrDict[i] = layerDef.GetFieldDefn(i).GetName() return ogrDict - - def writeErrorLog(self,errorDict): + + def writeErrorLog(self, errorDict): """ Writes conversion error log """ errorClasses = list(errorDict.keys()) - if len(errorClasses)>0: - self.signals.updateLog.emit('\n'+'{:-^60}'.format(self.tr('Features not converted'))) - self.signals.updateLog.emit('\n\n'+'{:<50}'.format(self.tr('Class'))+self.tr('Feature id')+'\n\n') + if len(errorClasses) > 0: + self.signals.updateLog.emit( + "\n" + "{:-^60}".format(self.tr("Features not converted")) + ) + self.signals.updateLog.emit( + "\n\n" + + "{:<50}".format(self.tr("Class")) + + self.tr("Feature id") + + "\n\n" + ) for cl in errorClasses: for id in errorDict[cl]: - self.signals.updateLog.emit('\n\n'+'{:<50}'.format(cl+str(id))) - + self.signals.updateLog.emit("\n\n" + "{:<50}".format(cl + str(id))) + def getQmlDir(self): """ Gets the QML directory @@ -612,95 +851,99 @@ def getQmlDir(self): if Qgis.QGIS_VERSION_INT >= 30000: # treat old implementations (bug fixes on domain values) implVersion = self.implementationVersion() - if implVersion == '' or float(implVersion) < 3: - qmlVersionPath = os.path.join(currentPath, '..', '..', 'Qmls', 'qgis_37_impl_2') + if implVersion == "" or float(implVersion) < 3: + qmlVersionPath = os.path.join( + currentPath, "..", "..", "Qmls", "qgis_37_impl_2" + ) else: - qmlVersionPath = os.path.join(currentPath, '..', '..', 'Qmls', 'qgis_37') + qmlVersionPath = os.path.join( + currentPath, "..", "..", "Qmls", "qgis_37" + ) elif Qgis.QGIS_VERSION_INT >= 20600: - qmlVersionPath = os.path.join(currentPath, '..', '..', 'Qmls', 'qgis_26') + qmlVersionPath = os.path.join(currentPath, "..", "..", "Qmls", "qgis_26") else: - qmlVersionPath = os.path.join(currentPath, '..', '..', 'Qmls', 'qgis_22') + qmlVersionPath = os.path.join(currentPath, "..", "..", "Qmls", "qgis_22") version = self.getDatabaseVersion() - if version == '3.0': - qmlPath = os.path.join(qmlVersionPath, 'edgv_3') - elif version == '3.0 Pro': - qmlPath = os.path.join(qmlVersionPath, 'edgv_3_pro') - elif version == '2.1.3': - qmlPath = os.path.join(qmlVersionPath, 'edgv_213') - elif version == '2.1.3 Pro': - qmlPath = os.path.join(qmlVersionPath, 'edgv_213_pro') - elif version == 'FTer_2a_Ed': - qmlPath = os.path.join(qmlVersionPath, 'FTer_2a_Ed') + if version == "3.0": + qmlPath = os.path.join(qmlVersionPath, "edgv_3") + elif version == "3.0 Pro": + qmlPath = os.path.join(qmlVersionPath, "edgv_3_pro") + elif version == "2.1.3": + qmlPath = os.path.join(qmlVersionPath, "edgv_213") + elif version == "2.1.3 Pro": + qmlPath = os.path.join(qmlVersionPath, "edgv_213_pro") + elif version == "FTer_2a_Ed": + qmlPath = os.path.join(qmlVersionPath, "FTer_2a_Ed") else: - qmlPath = '' + qmlPath = "" return qmlPath - + def getStyleDirectory(self, dbVersion): """ dbVersion: database version in the format of abstractDb.getVersion() Gets the directory of the styles """ currentPath = os.path.dirname(__file__) - styleDir = os.path.join(currentPath, '..', '..', 'Styles') - if dbVersion == '2.1.3': - styleDir = os.path.join(styleDir, 'edgv_213') - elif dbVersion == '2.1.3 Pro': - styleDir = os.path.join(styleDir, 'edgv_213_pro') - elif dbVersion == '3.0': - styleDir = os.path.join(styleDir, 'edgv_3') - elif dbVersion == '3.0 Pro': - styleDir = os.path.join(styleDir, 'edgv_3_pro') - elif dbVersion == 'FTer_2a_Ed': - styleDir = os.path.join(styleDir, 'edgv_FTer_2a_Ed') + styleDir = os.path.join(currentPath, "..", "..", "Styles") + if dbVersion == "2.1.3": + styleDir = os.path.join(styleDir, "edgv_213") + elif dbVersion == "2.1.3 Pro": + styleDir = os.path.join(styleDir, "edgv_213_pro") + elif dbVersion == "3.0": + styleDir = os.path.join(styleDir, "edgv_3") + elif dbVersion == "3.0 Pro": + styleDir = os.path.join(styleDir, "edgv_3_pro") + elif dbVersion == "FTer_2a_Ed": + styleDir = os.path.join(styleDir, "edgv_FTer_2a_Ed") else: - styleDir = os.path.join(styleDir, 'Non_EDGV') + styleDir = os.path.join(styleDir, "Non_EDGV") return styleDir def getStyleDict(self, dbVersion): """ dbVersion: database version in the format of abstractDb.getVersion() - The first iteration of walk lists all dirs as the second element of the list in next(os.walk(styleDir))[1]. + The first iteration of walk lists all dirs as the second element of the list in next(os.walk(styleDir))[1]. """ styleDir = self.getStyleDirectory(dbVersion) styleList = [] try: for f in os.listdir(styleDir): - if '.py' in f.lower() or '.pyc' in f.lower(): + if ".py" in f.lower() or ".pyc" in f.lower(): continue styleList.append(f) except FileNotFoundError: # in case style folder is not found, it will be created currentPath = os.path.dirname(__file__) - if not os.path.exists(os.path.join(currentPath, '..', '..', 'Styles')): - os.makedirs(os.path.join(currentPath, '..', '..', 'Styles')) + if not os.path.exists(os.path.join(currentPath, "..", "..", "Styles")): + os.makedirs(os.path.join(currentPath, "..", "..", "Styles")) if not os.path.exists(styleDir): os.makedirs(styleDir) styleDict = dict() try: for s in styleList: - if '.DS_Store' not in s: #mac os ignore - styleDict['dir:'+s] = os.path.join(styleDir, s) - #here we get the styles from db if there are any + if ".DS_Store" not in s: # mac os ignore + styleDict["dir:" + s] = os.path.join(styleDir, s) + # here we get the styles from db if there are any except: pass try: dbStyles = self.getStylesFromDb(dbVersion) if dbStyles: for style in dbStyles: - name = style.split('/')[-1] - styleDict['db:'+name] = 'db:'+style + name = style.split("/")[-1] + styleDict["db:" + name] = "db:" + style except: pass return styleDict - + def makeValueRelationDict(self, table, codes): """ Makes the value relation dictionary (multi valued attributes) """ self.checkAndOpenDb() ret = dict() - in_clause = '(%s)' % ",".join(map(str, codes)) + in_clause = "(%s)" % ",".join(map(str, codes)) sql = self.gen.makeRelationDict(table, in_clause) query = QSqlQuery(sql, self.db) while query.next(): @@ -708,35 +951,41 @@ def makeValueRelationDict(self, table, codes): code_name = query.value(1) ret[code_name] = code return ret - + def createFrameFromInom(self, inom): frame = self.utmGrid.getQgsPolygonFrame(inom) return frame - - def insertFrame(self, scale, mi, inom, frame, paramDict = dict()): + + def insertFrame(self, scale, mi, inom, frame, paramDict=dict()): self.checkAndOpenDb() srid = self.findEPSG() - geoSrid = QgsCoordinateReferenceSystem(int(srid)).geographicCrsAuthId().split(':')[-1] - sql = self.gen.insertFrame(scale, mi, inom, frame, srid, geoSrid, paramDict = paramDict) + geoSrid = ( + QgsCoordinateReferenceSystem(int(srid)).geographicCrsAuthId().split(":")[-1] + ) + sql = self.gen.insertFrame( + scale, mi, inom, frame, srid, geoSrid, paramDict=paramDict + ) self.db.transaction() query = QSqlQuery(self.db) if not query.exec_(sql): self.db.rollback() self.db.close() - raise Exception(self.tr('Problem inserting frame: ') + query.lastError().text()) + raise Exception( + self.tr("Problem inserting frame: ") + query.lastError().text() + ) self.db.commit() # self.db.close() - + def prepareCreateFrame(self, type, scale, param): - if type == 'mi': + if type == "mi": mi = str(param) - if scale == '250k': + if scale == "250k": inom = self.utmGrid.getINomenFromMIR(str(param)) else: inom = self.utmGrid.getINomenFromMI(str(param)) - elif type == 'inom': + elif type == "inom": inom = str(param) - if scale == '250k': + if scale == "250k": mi = self.utmGrid.getINomenFromMIR(inom) else: mi = self.utmGrid.getMIfromInom(inom) @@ -745,7 +994,10 @@ def prepareCreateFrame(self, type, scale, param): def getQmlDict(self, layerList): edgvVersion = self.getDatabaseVersion() - if edgvVersion in ['2.1.3','FTer_2a_Ed']: #this does not have 3.0, do not change it!!!! + if edgvVersion in [ + "2.1.3", + "FTer_2a_Ed", + ]: # this does not have 3.0, do not change it!!!! qmlPath = self.getQmlDir() return self.utils.parseMultiQml(qmlPath, layerList) else: @@ -755,7 +1007,7 @@ def getQmlDict(self, layerList): qmlPath = self.getQmlDir() return self.utils.parseMultiQml(qmlPath, layerList) return self.utils.parseMultiFromDb(qmlRecordDict, layerList) - + def getQmlRecordDict(self, inputLayer): self.checkAndOpenDb() if isinstance(inputLayer, list): @@ -764,23 +1016,25 @@ def getQmlRecordDict(self, inputLayer): sql = self.gen.getQmlRecords([inputLayer]) query = QSqlQuery(sql, self.db) if not query.isActive(): - raise Exception(self.tr("Problem getting qmlRecordDict: ")+query.lastError().text()) + raise Exception( + self.tr("Problem getting qmlRecordDict: ") + query.lastError().text() + ) qmlDict = dict() while query.next(): - if isinstance(inputLayer, list): + if isinstance(inputLayer, list): qmlDict[query.value(0)] = query.value(1) else: return query.value(1) return qmlDict - + def getQml(self, layerName): - if self.getDatabaseVersion() == '3.0': + if self.getDatabaseVersion() == "3.0": try: - return (self.getQmlRecordDict(layerName), 'db') + return (self.getQmlRecordDict(layerName), "db") except: - return (self.getQmlDir(), 'dir') + return (self.getQmlDir(), "dir") else: - return (self.getQmlDir(), 'dir') + return (self.getQmlDir(), "dir") def implementationVersion(self): """ @@ -792,17 +1046,17 @@ def implementationVersion(self): self.checkAndOpenDb() query = QSqlQuery(self.gen.implementationVersion(), self.db) if not query.isActive(): - return '' + return "" while query.next(): version = query.value(0) break return version if version is not None else -1 - + def getVersionString(self): version = self.getDatabaseVersion() - if version == 'Non_EDGV': + if version == "Non_EDGV": return self.tr("Unknown DB model") - if version in ['2.1.3', '3.0']: + if version in ["2.1.3", "3.0"]: version = f"EDGV {version}" implementation = self.implementationVersion() return f"{version} impl. {implementation}" @@ -815,7 +1069,9 @@ def getImplementationVersion(self): sql = self.gen.getImplementationVersion() query = QSqlQuery(sql, self.db) if not query.isActive(): - raise Exception(self.tr('Problem getting implementation version: ') + query.lastError().text()) + raise Exception( + self.tr("Problem getting implementation version: ") + + query.lastError().text() + ) while query.next(): return query.value(0) - diff --git a/DsgTools/core/Factories/DbFactory/dbFactory.py b/DsgTools/core/Factories/DbFactory/dbFactory.py index 4a0f879d9..3826729f6 100644 --- a/DsgTools/core/Factories/DbFactory/dbFactory.py +++ b/DsgTools/core/Factories/DbFactory/dbFactory.py @@ -24,7 +24,7 @@ from qgis.PyQt.QtSql import QSqlDatabase from qgis.core import QgsMessageLog, Qgis -#DSG Tools imports +# DSG Tools imports from .spatialiteDb import SpatialiteDb from .postgisDb import PostgisDb from .geopackageDb import GeopackageDb @@ -34,17 +34,18 @@ from builtins import object import os + class DbFactory(object): def createDbFactory(self, driver): - #TODO Treat none return - if not ('QPSQL' in QSqlDatabase.drivers()): #Driver wasn't loaded - raise Exception('QT PSQL driver not installed!') - if not ('QSQLITE' in QSqlDatabase.drivers()): #Driver wasn't loaded - raise Exception('QT QSQLITE driver not installed!') + # TODO Treat none return + if not ("QPSQL" in QSqlDatabase.drivers()): # Driver wasn't loaded + raise Exception("QT PSQL driver not installed!") + if not ("QSQLITE" in QSqlDatabase.drivers()): # Driver wasn't loaded + raise Exception("QT QSQLITE driver not installed!") dbs = { - DsgEnums.DriverSpatiaLite : lambda : SpatialiteDb(), - DsgEnums.DriverPostGIS : lambda : PostgisDb(), - DsgEnums.DriverGeopackage : lambda : GeopackageDb(), - DsgEnums.DriverShapefile : lambda : ShapefileDb() + DsgEnums.DriverSpatiaLite: lambda: SpatialiteDb(), + DsgEnums.DriverPostGIS: lambda: PostgisDb(), + DsgEnums.DriverGeopackage: lambda: GeopackageDb(), + DsgEnums.DriverShapefile: lambda: ShapefileDb(), } return dbs[driver]() if driver in dbs else None diff --git a/DsgTools/core/Factories/DbFactory/geopackageDb.py b/DsgTools/core/Factories/DbFactory/geopackageDb.py index 4645ebf08..3772e2540 100644 --- a/DsgTools/core/Factories/DbFactory/geopackageDb.py +++ b/DsgTools/core/Factories/DbFactory/geopackageDb.py @@ -23,7 +23,7 @@ from qgis.PyQt.QtSql import QSqlQuery, QSqlDatabase from qgis.PyQt.QtWidgets import QFileDialog -from qgis.core import QgsCoordinateReferenceSystem +from qgis.core import QgsCoordinateReferenceSystem from .spatialiteDb import SpatialiteDb from ..SqlFactory.sqlGeneratorFactory import SqlGeneratorFactory @@ -32,33 +32,40 @@ from osgeo import ogr, osr import os + class GeopackageDb(SpatialiteDb): """ Geopackage is an OGC format base on SpatiLite, hence, it should inherit methods from SpatiaLite driver. """ + def __init__(self): """ Constructor. """ super(GeopackageDb, self).__init__() - self.gen = SqlGeneratorFactory().createSqlGenerator(driver=DsgEnums.DriverGeopackage) - + self.gen = SqlGeneratorFactory().createSqlGenerator( + driver=DsgEnums.DriverGeopackage + ) + def getDatabaseName(self): """ Gets the database name. :return: (str) database name. """ # reimplementation - return os.path.basename(self.db.databaseName()).split('.gpkg')[0] - + return os.path.basename(self.db.databaseName()).split(".gpkg")[0] + def connectDatabaseWithGui(self): """ Connects to database using user interface dialog """ # reimplementation fd = QFileDialog() - filename = fd.getOpenFileName(caption=self.tr('Select a DSGTools Geopackage file'),filter=self.tr('Geopackage file databases (*.gpkg)')) + filename = fd.getOpenFileName( + caption=self.tr("Select a DSGTools Geopackage file"), + filter=self.tr("Geopackage file databases (*.gpkg)"), + ) filename = filename[0] if isinstance(filename, tuple) else filename self.db.setDatabaseName(filename) @@ -73,11 +80,13 @@ def listClassesFromDatabase(self): query = QSqlQuery(sql, self.db) if not query.isActive(): self.db.close() - raise Exception(self.tr("Problem listing geom classes: ")+query.lastError().text()) + raise Exception( + self.tr("Problem listing geom classes: ") + query.lastError().text() + ) while query.next(): classList.append(str(query.value(0))) return classList - + def getTablesFromDatabase(self): """ Gets all tables from database except for configuration tables. @@ -90,15 +99,22 @@ def getTablesFromDatabase(self): query = QSqlQuery(sql, self.db) if not query.isActive(): self.db.close() - raise Exception(self.tr("Problem getting tables from database: ")+query.lastError().text()) + raise Exception( + self.tr("Problem getting tables from database: ") + + query.lastError().text() + ) while query.next(): - #table name + # table name table = query.value(0) - if 'gpkg_' not in table.lower() and 'rtree_' not in table.lower() and table.lower() != 'sqlite_sequence': + if ( + "gpkg_" not in table.lower() + and "rtree_" not in table.lower() + and table.lower() != "sqlite_sequence" + ): ret.append(table) return ret - + def getGeomColumnDict(self): """ Dict in the form 'geomName':[-list of table names-] @@ -107,25 +123,29 @@ def getGeomColumnDict(self): sql = self.gen.getGeomColumnDict() query = QSqlQuery(sql, self.db) if not query.isActive(): - raise Exception(self.tr("Problem getting geom column dict: ")+query.lastError().text()) + raise Exception( + self.tr("Problem getting geom column dict: ") + query.lastError().text() + ) geomDict = dict() while query.next(): geomColumn = query.value(0) tableName = query.value(1) - lyrName = '_'.join(tableName.split('_')[1::]) + lyrName = "_".join(tableName.split("_")[1::]) if geomColumn not in list(geomDict.keys()): geomDict[geomColumn] = [] geomDict[geomColumn].append(lyrName) return geomDict - + def getTableSchemaFromDb(self, table): self.checkAndOpenDb() sql = self.gen.getFullTablesName(table) query = QSqlQuery(sql, self.db) if not query.isActive(): - raise Exception(self.tr("Problem getting full table name: ")+query.lastError().text()) + raise Exception( + self.tr("Problem getting full table name: ") + query.lastError().text() + ) while query.next(): - return query.value(0).split('_')[0] + return query.value(0).split("_")[0] def getGeomTypeDict(self, loadCentroids=False): self.checkAndOpenDb() @@ -133,57 +153,65 @@ def getGeomTypeDict(self, loadCentroids=False): sql = self.gen.getGeomByPrimitive(edgvVersion) query = QSqlQuery(sql, self.db) if not query.isActive(): - raise Exception(self.tr("Problem getting geom types from db: ")+query.lastError().text()) + raise Exception( + self.tr("Problem getting geom types from db: ") + + query.lastError().text() + ) geomDict = dict() while query.next(): - if edgvVersion in ('2.1.3','FTer_2a_Ed'): + if edgvVersion in ("2.1.3", "FTer_2a_Ed"): type_ = query.value(0) else: type_ = self.getResolvedGeomType(query.value(0)) tableName = query.value(1) - layerName = '_'.join(tableName.split('_')[1::]) + layerName = "_".join(tableName.split("_")[1::]) if type_ not in list(geomDict.keys()): geomDict[type_] = [] if layerName not in geomDict[type_]: geomDict[type_].append(layerName) return geomDict - def getGeomDict(self, getCentroids = False): - ''' + def getGeomDict(self, getCentroids=False): + """ returns a dict like this: {'tablePerspective' : { 'layerName' : - ''' + """ self.checkAndOpenDb() edgvVersion = self.getDatabaseVersion() sql = self.gen.getGeomTablesFromGeometryColumns(edgvVersion) query = QSqlQuery(sql, self.db) if not query.isActive(): - raise Exception(self.tr("Problem getting geom tables from db: ")+query.lastError().text()) + raise Exception( + self.tr("Problem getting geom tables from db: ") + + query.lastError().text() + ) geomDict = dict() - geomDict['primitivePerspective'] = self.getGeomTypeDict() - geomDict['tablePerspective'] = dict() + geomDict["primitivePerspective"] = self.getGeomTypeDict() + geomDict["tablePerspective"] = dict() while query.next(): isCentroid = False srid = query.value(0) - if edgvVersion in ('2.1.3','FTer_2a_Ed'): + if edgvVersion in ("2.1.3", "FTer_2a_Ed"): geometryType = query.value(2) else: geometryType = self.getResolvedGeomType(query.value(2)) tableName = query.value(3) - tableSchema = tableName.split('_')[0] + tableSchema = tableName.split("_")[0] geometryColumn = query.value(1) - layerName = '_'.join(tableName.split('_')[1::]) - if layerName not in list(geomDict['tablePerspective'].keys()): - geomDict['tablePerspective'][layerName] = dict() - geomDict['tablePerspective'][layerName]['schema'] = tableSchema - geomDict['tablePerspective'][layerName]['srid'] = str(srid) - geomDict['tablePerspective'][layerName]['geometryColumn'] = geometryColumn - geomDict['tablePerspective'][layerName]['geometryType'] = geometryType - geomDict['tablePerspective'][layerName]['tableName'] = tableName + layerName = "_".join(tableName.split("_")[1::]) + if layerName not in list(geomDict["tablePerspective"].keys()): + geomDict["tablePerspective"][layerName] = dict() + geomDict["tablePerspective"][layerName]["schema"] = tableSchema + geomDict["tablePerspective"][layerName]["srid"] = str(srid) + geomDict["tablePerspective"][layerName][ + "geometryColumn" + ] = geometryColumn + geomDict["tablePerspective"][layerName]["geometryType"] = geometryType + geomDict["tablePerspective"][layerName]["tableName"] = tableName return geomDict - def getGeomColumnTupleList(self, showViews = False): + def getGeomColumnTupleList(self, showViews=False): """ list in the format [(table_schema, table_name, geometryColumn, geometryType, tableType)] centroids are hidden by default @@ -193,42 +221,50 @@ def getGeomColumnTupleList(self, showViews = False): sql = self.gen.getGeomColumnTupleList(edgvVersion) query = QSqlQuery(sql, self.db) if not query.isActive(): - raise Exception(self.tr("Problem getting geom tuple list: ")+query.lastError().text()) + raise Exception( + self.tr("Problem getting geom tuple list: ") + query.lastError().text() + ) geomList = [] while query.next(): geomList.append( ( - query.value(0).split('_')[0], - '_'.join(query.value(0).split('_')[1::]), + query.value(0).split("_")[0], + "_".join(query.value(0).split("_")[1::]), query.value(1), self.getResolvedGeomType(query.value(2)), - 'BASE TABLE' + "BASE TABLE", ) ) return geomList - + def getResolvedGeomType(self, geometryType): - geomDict = {0:'GEOMETRY', - 1:'POINT', - 2:'LINESTRING', - 3:'POLYGON', - 4:'MULTIPOINT', - 5:'MULTILINESTRING', - 6:'MULTIPOLYGON', - 7:'GEOMETRYCOLLECTION', - 8:'CIRCULARSTRING', - 9:'COMPOUNDCURVE', - 10:'CURVEPOLYGON', - 11:'MULTICURVE', - 12:'MULTISURFACE', - 13:'CURVE', - 14:'SURFACE'} - return geometryType if geometryType in geomDict.values() else geomDict[int(geometryType)] + geomDict = { + 0: "GEOMETRY", + 1: "POINT", + 2: "LINESTRING", + 3: "POLYGON", + 4: "MULTIPOINT", + 5: "MULTILINESTRING", + 6: "MULTIPOLYGON", + 7: "GEOMETRYCOLLECTION", + 8: "CIRCULARSTRING", + 9: "COMPOUNDCURVE", + 10: "CURVEPOLYGON", + 11: "MULTICURVE", + 12: "MULTISURFACE", + 13: "CURVE", + 14: "SURFACE", + } + return ( + geometryType + if geometryType in geomDict.values() + else geomDict[int(geometryType)] + ) def getType(self): """ Gets the driver name. :return: (str) driver name. """ - return 'GPKG' + return "GPKG" diff --git a/DsgTools/core/Factories/DbFactory/postgisDb.py b/DsgTools/core/Factories/DbFactory/postgisDb.py index 17fbf06fd..eef08558a 100644 --- a/DsgTools/core/Factories/DbFactory/postgisDb.py +++ b/DsgTools/core/Factories/DbFactory/postgisDb.py @@ -24,11 +24,13 @@ from qgis.core import Qgis from qgis.PyQt.QtSql import QSqlQuery, QSqlDatabase from qgis.PyQt.QtCore import QSettings -from qgis.core import (Qgis, - QgsMessageLog, - QgsCredentials, - QgsVectorLayer, - QgsDataSourceUri) +from qgis.core import ( + Qgis, + QgsMessageLog, + QgsCredentials, + QgsVectorLayer, + QgsDataSourceUri, +) from .abstractDb import AbstractDb from ..SqlFactory.sqlGeneratorFactory import SqlGeneratorFactory @@ -48,11 +50,13 @@ def __init__(self): Constructor """ super(PostgisDb, self).__init__() - #setting database type to postgresql - self.db = QSqlDatabase('QPSQL') - #setting up a sql generator - self.gen = SqlGeneratorFactory().createSqlGenerator(driver=DsgEnums.DriverPostGIS) - self.databaseEncoding = 'utf-8' + # setting database type to postgresql + self.db = QSqlDatabase("QPSQL") + # setting up a sql generator + self.gen = SqlGeneratorFactory().createSqlGenerator( + driver=DsgEnums.DriverPostGIS + ) + self.databaseEncoding = "utf-8" def closeDatabase(self): if self.db is not None and self.db.isOpen(): @@ -63,7 +67,12 @@ def getDatabaseParameters(self): """ Gets (host, port, user, password) """ - return (self.db.hostName(), self.db.port(), self.db.userName(), self.db.password()) + return ( + self.db.hostName(), + self.db.port(), + self.db.userName(), + self.db.password(), + ) def getDatabaseName(self): """ @@ -79,13 +88,19 @@ def connectDatabase(self, conn=None): Connects to database conn: connection parameters. It can be a OGR connection or a QSettings connection """ - if conn.split(':')[0] == 'PG': - connSplit = conn.split(' ') + if conn.split(":")[0] == "PG": + connSplit = conn.split(" ") parDict = dict() for i in connSplit[1::]: - par = i.split('=') + par = i.split("=") parDict[par[0]] = par[1] - self.connectDatabaseWithParameters(parDict['host'], parDict['port'], parDict['dbname'], parDict['user'], parDict['password']) + self.connectDatabaseWithParameters( + parDict["host"], + parDict["port"], + parDict["dbname"], + parDict["user"], + parDict["password"], + ) else: self.connectDatabaseWithQSettings(conn) @@ -105,7 +120,9 @@ def getCredentials(self, host, port, user, database): conInfo = "host={0} port={1} dbname={2}".format(host, port, database) check = False while not check: - (success, user, password) = QgsCredentials.instance().get(conInfo, user, None) + (success, user, password) = QgsCredentials.instance().get( + conInfo, user, None + ) if not success: return if self.testCredentials(host, port, database, user, password): @@ -131,21 +148,23 @@ def connectDatabaseWithQSettings(self, name): Connects to database with parameters name: QSettings connection name """ - #getting connection parameters from qsettings + # getting connection parameters from qsettings (host, port, database, user, password) = self.getConnectionFromQSettings(name) self.db.setHostName(host) - if type(port) != 'int': + if type(port) != "int": self.db.setPort(int(port)) else: self.db.setPort(port) self.db.setDatabaseName(database) self.db.setUserName(user) - if not password or password == '': - conInfo = 'host='+host+' port='+port+' dbname='+database + if not password or password == "": + conInfo = "host=" + host + " port=" + port + " dbname=" + database check = False while not check: try: - (success, user, password) = QgsCredentials.instance().get(conInfo, user, None) + (success, user, password) = QgsCredentials.instance().get( + conInfo, user, None + ) if not success: return self.db.setPassword(password) @@ -165,13 +184,19 @@ def getDatabaseVersion(self): sql = self.gen.getEDGVVersion() query = QSqlQuery(sql, self.db) if not query.isActive(): - return 'Non_EDGV' - version = '-1' + return "Non_EDGV" + version = "-1" while query.next(): version = query.value(0) return version - def listGeomClassesFromDatabase(self, primitiveFilter = [], withElements = False, excludeViews = True, getGeometryColumn = False): + def listGeomClassesFromDatabase( + self, + primitiveFilter=[], + withElements=False, + excludeViews=True, + getGeometryColumn=False, + ): """ Gets a list with geometry classes from database returns dict if getGeometryColumn = True @@ -179,45 +204,63 @@ def listGeomClassesFromDatabase(self, primitiveFilter = [], withElements = False """ self.checkAndOpenDb() classList = [] - schemaList = [i for i in self.getGeomSchemaList() if i not in ['validation', 'views']] - #primitiveFilter building + schemaList = [ + i for i in self.getGeomSchemaList() if i not in ["validation", "views"] + ] + # primitiveFilter building dbPrimitiveList = [] if len(primitiveFilter) > 0: for primitive in primitiveFilter: - if primitive == 'p': - dbPrimitiveList.append('POINT') - dbPrimitiveList.append('MULTIPOINT') - if primitive == 'l': - dbPrimitiveList.append('LINESTRING') - dbPrimitiveList.append('MULTILINESTRING') - if primitive == 'a': - dbPrimitiveList.append('POLYGON') - dbPrimitiveList.append('MULTIPOLYGON') - sql = self.gen.getGeomTables(schemaList, dbPrimitiveList = dbPrimitiveList, excludeViews = excludeViews, geomColumn = getGeometryColumn) - query = QSqlQuery(sql, self.db) - if not query.isActive(): - raise Exception(self.tr("Problem listing geom classes: ")+query.lastError().text()) + if primitive == "p": + dbPrimitiveList.append("POINT") + dbPrimitiveList.append("MULTIPOINT") + if primitive == "l": + dbPrimitiveList.append("LINESTRING") + dbPrimitiveList.append("MULTILINESTRING") + if primitive == "a": + dbPrimitiveList.append("POLYGON") + dbPrimitiveList.append("MULTIPOLYGON") + sql = self.gen.getGeomTables( + schemaList, + dbPrimitiveList=dbPrimitiveList, + excludeViews=excludeViews, + geomColumn=getGeometryColumn, + ) + query = QSqlQuery(sql, self.db) + if not query.isActive(): + raise Exception( + self.tr("Problem listing geom classes: ") + query.lastError().text() + ) localList = [] while query.next(): tableSchema = query.value(0) tableName = query.value(1) - layerName = tableSchema+'.'+tableName - geometryColumn = '' + layerName = tableSchema + "." + tableName + geometryColumn = "" if getGeometryColumn: geometryColumn = query.value(2) - localList.append({'schema':tableSchema, 'tableName':tableName, 'layerName':layerName, 'geometryColumn':geometryColumn}) - #remove possible duplicates to filter layers with elements + localList.append( + { + "schema": tableSchema, + "tableName": tableName, + "layerName": layerName, + "geometryColumn": geometryColumn, + } + ) + # remove possible duplicates to filter layers with elements layerNameList = [] for i in localList: - if i['layerName'] not in layerNameList: - layerNameList.append(i['layerName']) + if i["layerName"] not in layerNameList: + layerNameList.append(i["layerName"]) if withElements: listWithElements = self.getLayersWithElementsV2(layerNameList) - partialTagList = [i for i in localList if i['tableName'] in listWithElements] + partialTagList = [ + i for i in localList if i["tableName"] in listWithElements + ] else: partialTagList = localList if not getGeometryColumn: - classList = [i['layerName'] for i in partialTagList] + classList = [i["layerName"] for i in partialTagList] else: classList = partialTagList return classList @@ -231,12 +274,14 @@ def listComplexClassesFromDatabase(self): sql = self.gen.getTablesFromDatabase() query = QSqlQuery(sql, self.db) if not query.isActive(): - raise Exception(self.tr("Problem listing complex classes: ")+query.lastError().text()) + raise Exception( + self.tr("Problem listing complex classes: ") + query.lastError().text() + ) while query.next(): tableSchema = query.value(0) tableName = query.value(1) - layerName = tableSchema+'.'+tableName - if tableSchema == 'complexos': + layerName = tableSchema + "." + tableName + if tableSchema == "complexos": classList.append(layerName) classList.sort() return classList @@ -247,15 +292,15 @@ def storeConnection(self, server): """ (host, port, user, password) = self.getServerConfiguration(server) database = self.db.databaseName() - connection = server+'_'+database + connection = server + "_" + database settings = QSettings() - if not settings.contains('PostgreSQL/connections/'+connection+'/database'): - settings.beginGroup('PostgreSQL/connections/'+connection) - settings.setValue('database', database) - settings.setValue('host', host) - settings.setValue('port', port) - settings.setValue('username', user) - settings.setValue('password', password) + if not settings.contains("PostgreSQL/connections/" + connection + "/database"): + settings.beginGroup("PostgreSQL/connections/" + connection) + settings.setValue("database", database) + settings.setValue("host", host) + settings.setValue("port", port) + settings.setValue("username", user) + settings.setValue("password", password) settings.endGroup() return True return False @@ -266,14 +311,14 @@ def getConnectionFromQSettings(self, conName): conName: connection name stored """ settings = QSettings() - settings.beginGroup('PostgreSQL/connections/'+conName) - host = settings.value('host') - port = settings.value('port') - database = settings.value('database') - user = settings.value('username') - password = settings.value('password') + settings.beginGroup("PostgreSQL/connections/" + conName) + host = settings.value("host") + port = settings.value("port") + database = settings.value("database") + user = settings.value("username") + password = settings.value("password") settings.endGroup() - return (host, port, database, user, password) + return (host, port, database, user, password) def getServerConfiguration(self, name): """ @@ -281,11 +326,11 @@ def getServerConfiguration(self, name): name: server name """ settings = QSettings() - settings.beginGroup('PostgreSQL/servers/'+name) - host = settings.value('host') - port = settings.value('port') - user = settings.value('username') - password = settings.value('password') + settings.beginGroup("PostgreSQL/servers/" + name) + host = settings.value("host") + port = settings.value("port") + user = settings.value("username") + password = settings.value("password") settings.endGroup() return (host, port, user, password) @@ -295,23 +340,32 @@ def getStructureDict(self): """ self.checkAndOpenDb() classDict = dict() - sql = self.gen.getStructure(self.getDatabaseVersion()) + sql = self.gen.getStructure(self.getDatabaseVersion()) query = QSqlQuery(sql, self.db) if not query.isActive(): - raise Exception(self.tr("Problem getting database structure: ")+query.lastError().text()) + raise Exception( + self.tr("Problem getting database structure: ") + + query.lastError().text() + ) while query.next(): - className = str(query.value(0))+'.'+str(query.value(1)) + className = str(query.value(0)) + "." + str(query.value(1)) fieldName = str(query.value(2)) - if str(query.value(0)) == 'complexos' or className.split('_')[-1] in ['p','l','a']: + if str(query.value(0)) == "complexos" or className.split("_")[-1] in [ + "p", + "l", + "a", + ]: if className not in list(classDict.keys()): - classDict[className]=dict() - classDict[className][fieldName]=fieldName - if 'geom' in list(classDict[className].keys()): - classDict[className]['geom'] = 'GEOMETRY' - if str(query.value(0)) != 'complexos' and 'id' in list(classDict[className].keys()): - classDict[className]['id'] = 'OGC_FID' + classDict[className] = dict() + classDict[className][fieldName] = fieldName + if "geom" in list(classDict[className].keys()): + classDict[className]["geom"] = "GEOMETRY" + if str(query.value(0)) != "complexos" and "id" in list( + classDict[className].keys() + ): + classDict[className]["id"] = "OGC_FID" return classDict - + def makeOgrConn(self): """ Makes a OGR connection string @@ -321,7 +375,18 @@ def makeOgrConn(self): dbHost = self.db.hostName() dbPass = self.db.password() dbPort = str(self.db.port()) - constring = 'PG: dbname=\''+dbName+'\' user=\''+dbUser+'\' host=\''+dbHost+'\' password=\''+dbPass+'\' port='+dbPort + constring = ( + "PG: dbname='" + + dbName + + "' user='" + + dbUser + + "' host='" + + dbHost + + "' password='" + + dbPass + + "' port=" + + dbPort + ) return constring def getNotNullDict(self): @@ -329,26 +394,32 @@ def getNotNullDict(self): Gets a dictionary with all not null fields for the edgv database used """ self.checkAndOpenDb() - if self.getDatabaseVersion() == '2.1.3': - schemaList = ['cb', 'complexos'] - elif self.getDatabaseVersion() in ('3.0', '2.1.3 Pro', '3.0 Pro'): - schemaList = ['edgv', 'complexos'] - elif self.getDatabaseVersion() == 'FTer_2a_Ed': - schemaList = ['pe','ge', 'complexos'] + if self.getDatabaseVersion() == "2.1.3": + schemaList = ["cb", "complexos"] + elif self.getDatabaseVersion() in ("3.0", "2.1.3 Pro", "3.0 Pro"): + schemaList = ["edgv", "complexos"] + elif self.getDatabaseVersion() == "FTer_2a_Ed": + schemaList = ["pe", "ge", "complexos"] else: - QgsMessageLog.logMessage(self.tr('Operation not defined for this database version!'), "DSGTools Plugin", Qgis.Critical) + QgsMessageLog.logMessage( + self.tr("Operation not defined for this database version!"), + "DSGTools Plugin", + Qgis.Critical, + ) return None - + sql = self.gen.getNotNullFields(schemaList) query = QSqlQuery(sql, self.db) if not query.isActive(): - raise Exception(self.tr("Problem executing query: ")+query.lastError().text()) + raise Exception( + self.tr("Problem executing query: ") + query.lastError().text() + ) notNullDict = dict() while query.next(): schemaName = str(query.value(0)) className = str(query.value(1)) attName = str(query.value(2)) - cl = schemaName+'.'+className + cl = schemaName + "." + className if cl not in list(notNullDict.keys()): notNullDict[cl] = [] notNullDict[cl].append(attName) @@ -359,21 +430,27 @@ def getDomainDict(self): SHOULD BE DEPRECATED OR IN FOR A MAJOR REFACTORY!!!!! Gets the domain dictionary for the edgv database used """ - self.checkAndOpenDb() - if self.getDatabaseVersion() == '2.1.3': - schemaList = ['cb', 'complexos', 'dominios'] - elif self.getDatabaseVersion() in ('3.0', '2.1.3 Pro', '3.0 Pro'): - schemaList = ['edgv', 'complexos', 'dominios'] - elif self.getDatabaseVersion() == 'FTer_2a_Ed': - schemaList = ['pe','ge', 'complexos'] + self.checkAndOpenDb() + if self.getDatabaseVersion() == "2.1.3": + schemaList = ["cb", "complexos", "dominios"] + elif self.getDatabaseVersion() in ("3.0", "2.1.3 Pro", "3.0 Pro"): + schemaList = ["edgv", "complexos", "dominios"] + elif self.getDatabaseVersion() == "FTer_2a_Ed": + schemaList = ["pe", "ge", "complexos"] else: - QgsMessageLog.logMessage(self.tr('Operation not defined for this database version!'), "DSGTools Plugin", Qgis.Critical) + QgsMessageLog.logMessage( + self.tr("Operation not defined for this database version!"), + "DSGTools Plugin", + Qgis.Critical, + ) return - + sql = self.gen.validateWithDomain(schemaList) query = QSqlQuery(sql, self.db) if not query.isActive(): - raise Exception(self.tr("Problem executing query: ")+query.lastError().text()) + raise Exception( + self.tr("Problem executing query: ") + query.lastError().text() + ) classDict = dict() domainDict = dict() @@ -384,11 +461,13 @@ def getDomainDict(self): domainName = str(query.value(3)) domainTable = str(query.value(4)) domainQuery = str(query.value(5)) - cl = schemaName+'.'+className - query2 = QSqlQuery(domainQuery,self.db) + cl = schemaName + "." + className + query2 = QSqlQuery(domainQuery, self.db) while query2.next(): value = int(query2.value(0)) - classDict = self.utils.buildNestedDict(classDict,[str(cl),str(attName)],[value]) + classDict = self.utils.buildNestedDict( + classDict, [str(cl), str(attName)], [value] + ) return classDict def translateAbstractDbLayerNameToOutputFormat(self, lyr, outputAbstractDb): @@ -397,9 +476,9 @@ def translateAbstractDbLayerNameToOutputFormat(self, lyr, outputAbstractDb): lyr: layer name that will be translated outputAbstractDb: output database """ - if outputAbstractDb.db.driverName() == 'QSQLITE': - return str(lyr.split('.')[0]+'_'+'_'.join(lyr.split('.')[1::])) - if outputAbstractDb.db.driverName() == 'QPSQL': + if outputAbstractDb.db.driverName() == "QSQLITE": + return str(lyr.split(".")[0] + "_" + "_".join(lyr.split(".")[1::])) + if outputAbstractDb.db.driverName() == "QPSQL": return lyr def translateOGRLayerNameToOutputFormat(self, lyr, ogrOutput): @@ -408,31 +487,39 @@ def translateOGRLayerNameToOutputFormat(self, lyr, ogrOutput): lyr: layer name that will be translated ogrOutput: ogr output """ - if ogrOutput.GetDriver().name == 'SQLite': - return str(lyr.split('.')[0]+'_'+'_'.join(lyr.split('.')[1::])) - if ogrOutput.GetDriver().name == 'PostgreSQL': + if ogrOutput.GetDriver().name == "SQLite": + return str(lyr.split(".")[0] + "_" + "_".join(lyr.split(".")[1::])) + if ogrOutput.GetDriver().name == "PostgreSQL": return lyr - def getTableSchema(self,lyr): + def getTableSchema(self, lyr): """ DEPRECATED Gets the table schema lyr: layer name """ - schema = lyr.split('.')[0] - className = '_'.join(lyr.split('.')[1::]) + schema = lyr.split(".")[0] + className = "_".join(lyr.split(".")[1::]) return (schema, className) - + def convertToSpatialite(self, outputAbstractDb, type=None): """ Converts this to a spatialite database outputAbstractDb: spatialite output type: conversion type """ - (inputOgrDb, outputOgrDb, fieldMap, inputLayerList, errorDict) = self.prepareForConversion(outputAbstractDb) - status = self.translateDS(inputOgrDb, outputOgrDb, fieldMap, inputLayerList, errorDict) + ( + inputOgrDb, + outputOgrDb, + fieldMap, + inputLayerList, + errorDict, + ) = self.prepareForConversion(outputAbstractDb) + status = self.translateDS( + inputOgrDb, outputOgrDb, fieldMap, inputLayerList, errorDict + ) return status - + def obtainLinkColumn(self, complexClass, aggregatedClass): """ Obtains the link column between complex and aggregated class @@ -440,44 +527,52 @@ def obtainLinkColumn(self, complexClass, aggregatedClass): aggregatedClass: aggregated class name """ self.checkAndOpenDb() - complexClass = complexClass.replace('complexos.', '') - #query to obtain the link column between the complex and the feature layer + complexClass = complexClass.replace("complexos.", "") + # query to obtain the link column between the complex and the feature layer sql = self.gen.getLinkColumn(complexClass, aggregatedClass) query = QSqlQuery(sql, self.db) if not query.isActive(): - raise Exception(self.tr("Problem obtaining link column: ")+query.lastError().text()) - column_name = '' + raise Exception( + self.tr("Problem obtaining link column: ") + query.lastError().text() + ) + column_name = "" while query.next(): column_name = query.value(0) return column_name def loadAssociatedFeatures(self, complex): """ - Loads all the features associated to the complex + Loads all the features associated to the complex complex: complex class name """ self.checkAndOpenDb() associatedDict = dict() - complex = complex.replace('complexos.', '') - #query to get the possible links to the selected complex in the combobox + complex = complex.replace("complexos.", "") + # query to get the possible links to the selected complex in the combobox sql = self.gen.getComplexLinks(complex) query = QSqlQuery(sql, self.db) if not query.isActive(): - raise Exception(self.tr("Problem loading associated features: ")+query.lastError().text()) + raise Exception( + self.tr("Problem loading associated features: ") + + query.lastError().text() + ) while query.next(): - #setting the variables + # setting the variables complex_schema = query.value(0) complex = query.value(1) aggregated_schema = query.value(2) aggregated_class = query.value(3) column_name = query.value(4) - #query to obtain the created complexes + # query to obtain the created complexes sql = self.gen.getComplexData(complex_schema, complex) complexQuery = QSqlQuery(sql, self.db) if not complexQuery.isActive(): - raise Exception(self.tr("Problem loading associated features: ")+complexQuery.lastError().text()) + raise Exception( + self.tr("Problem loading associated features: ") + + complexQuery.lastError().text() + ) while complexQuery.next(): complex_uuid = complexQuery.value(0) @@ -485,30 +580,43 @@ def loadAssociatedFeatures(self, complex): if not (complex_uuid and name): continue - - associatedDict = self.utils.buildNestedDict(associatedDict, [name, complex_uuid, aggregated_class], []) - - #query to obtain the id of the associated feature - sql = self.gen.getAssociatedFeaturesData(aggregated_schema, aggregated_class, column_name, complex_uuid) + + associatedDict = self.utils.buildNestedDict( + associatedDict, [name, complex_uuid, aggregated_class], [] + ) + + # query to obtain the id of the associated feature + sql = self.gen.getAssociatedFeaturesData( + aggregated_schema, aggregated_class, column_name, complex_uuid + ) associatedQuery = QSqlQuery(sql, self.db) if not associatedQuery.isActive(): - raise Exception(self.tr("Problem loading associated features: ")+associatedQuery.lastError().text()) + raise Exception( + self.tr("Problem loading associated features: ") + + associatedQuery.lastError().text() + ) while associatedQuery.next(): ogc_fid = associatedQuery.value(0) - associatedDict = self.utils.buildNestedDict(associatedDict, [name, complex_uuid, aggregated_class], [ogc_fid]) + associatedDict = self.utils.buildNestedDict( + associatedDict, + [name, complex_uuid, aggregated_class], + [ogc_fid], + ) return associatedDict - + def isComplexClass(self, className): """ Checks if a class is a complex class className: class name to be checked """ self.checkAndOpenDb() - #getting all complex tables + # getting all complex tables query = QSqlQuery(self.gen.getComplexTablesFromDatabase(), self.db) if not query.isActive(): - raise Exception(self.tr("Problem executing query: ")+query.lastError().text()) + raise Exception( + self.tr("Problem executing query: ") + query.lastError().text() + ) while query.next(): if query.value(0) == className: @@ -525,23 +633,29 @@ def disassociateComplexFromComplex(self, aggregated_class, link_column, id): sql = self.gen.disassociateComplexFromComplex(aggregated_class, link_column, id) query = QSqlQuery(self.db) if not query.exec_(sql): - raise Exception(self.tr('Problem disassociating complex from complex: ') + '\n' + query.lastError().text()) - + raise Exception( + self.tr("Problem disassociating complex from complex: ") + + "\n" + + query.lastError().text() + ) + def getUsers(self): """ Gets 'this' database users """ self.checkAndOpenDb() ret = [] - + sql = self.gen.getUsers() query = QSqlQuery(sql, self.db) if not query.isActive(): - raise Exception(self.tr("Problem getting users: ")+query.lastError().text()) + raise Exception( + self.tr("Problem getting users: ") + query.lastError().text() + ) while query.next(): ret.append(query.value(0)) - + ret.sort() return ret @@ -557,7 +671,9 @@ def getUserRelatedRoles(self, username): sql = self.gen.getUserRelatedRoles(username) query = QSqlQuery(sql, self.db) if not query.isActive(): - raise Exception(self.tr("Problem getting user roles: ")+query.lastError().text()) + raise Exception( + self.tr("Problem getting user roles: ") + query.lastError().text() + ) while query.next(): rolname = query.value(0) @@ -570,7 +686,7 @@ def getUserRelatedRoles(self, username): installed.sort() assigned.sort() return installed, assigned - + def getRoles(self): """ Gets roles installed in 'this' database @@ -581,7 +697,9 @@ def getRoles(self): sql = self.gen.getRoles() query = QSqlQuery(sql, self.db) if not query.isActive(): - raise Exception(self.tr("Problem getting roles: ")+query.lastError().text()) + raise Exception( + self.tr("Problem getting roles: ") + query.lastError().text() + ) while query.next(): ret.append(query.value(0)) @@ -589,27 +707,32 @@ def getRoles(self): ret.sort() return ret - def createRole(self, role, roleDict, permissionManager = False): + def createRole(self, role, roleDict, permissionManager=False): """ Creates a role into this database role: role name dict: role definitions """ self.checkAndOpenDb() - #making this so the instaciated permissions stay with different names - uuid = str(uuid4()).replace('-', '_') - role += '_'+uuid + # making this so the instaciated permissions stay with different names + uuid = str(uuid4()).replace("-", "_") + role += "_" + uuid sql = self.gen.createRole(role, roleDict) - split = sql.split(';') + split = sql.split(";") query = QSqlQuery(self.db) - + if permissionManager: if not query.exec_(sql): - raise Exception(self.tr('Problem assigning profile: ') +role+'\n'+query.lastError().text()) + raise Exception( + self.tr("Problem assigning profile: ") + + role + + "\n" + + query.lastError().text() + ) return role - #try to revoke the permissions + # try to revoke the permissions try: self.dropRole(role) except: @@ -617,12 +740,17 @@ def createRole(self, role, roleDict, permissionManager = False): for inner in split: if not query.exec_(inner): - if '42710' in query.lastError().text(): - #In this case the role is already created (duplicate object error). We just need to proceed executing the grants. + if "42710" in query.lastError().text(): + # In this case the role is already created (duplicate object error). We just need to proceed executing the grants. continue else: - raise Exception(self.tr('Problem assigning profile: ') +role+'\n'+query.lastError().text()) - + raise Exception( + self.tr("Problem assigning profile: ") + + role + + "\n" + + query.lastError().text() + ) + def dropRole(self, role): """ Deletes a role from 'this' database @@ -630,16 +758,21 @@ def dropRole(self, role): """ self.checkAndOpenDb() sql = self.gen.dropRole(role) - split = sql.split('#') + split = sql.split("#") query = QSqlQuery(self.db) for inner in split: if not query.exec_(inner): - if '2BP01' in query.lastError().text(): - #In this case the role is still used by other databases, therefore it shouldn't be dropped. + if "2BP01" in query.lastError().text(): + # In this case the role is still used by other databases, therefore it shouldn't be dropped. continue else: - raise Exception(self.tr('Problem removing profile: ') +role+'\n'+query.lastError().text()) + raise Exception( + self.tr("Problem removing profile: ") + + role + + "\n" + + query.lastError().text() + ) def alterUserPass(self, user, newpassword): """ @@ -652,7 +785,12 @@ def alterUserPass(self, user, newpassword): query = QSqlQuery(self.db) if not query.exec_(sql): - raise Exception(self.tr('Problem altering user\'s password: ') +user+'\n'+query.lastError().text()) + raise Exception( + self.tr("Problem altering user's password: ") + + user + + "\n" + + query.lastError().text() + ) def createUser(self, user, password, isSuperUser): """ @@ -666,7 +804,12 @@ def createUser(self, user, password, isSuperUser): query = QSqlQuery(self.db) if not query.exec_(sql): - raise Exception(self.tr('Problem creating user: ') +user+'\n'+query.lastError().text()) + raise Exception( + self.tr("Problem creating user: ") + + user + + "\n" + + query.lastError().text() + ) def removeUser(self, user): """ @@ -678,7 +821,12 @@ def removeUser(self, user): query = QSqlQuery(self.db) if not query.exec_(sql): - raise Exception(self.tr('Problem removing user: ') +user+'\n'+query.lastError().text()) + raise Exception( + self.tr("Problem removing user: ") + + user + + "\n" + + query.lastError().text() + ) def grantRole(self, user, role): """ @@ -691,7 +839,12 @@ def grantRole(self, user, role): query = QSqlQuery(self.db) if not query.exec_(sql): - raise Exception(self.tr('Problem granting profile: ') +role+'\n'+query.lastError().text()) + raise Exception( + self.tr("Problem granting profile: ") + + role + + "\n" + + query.lastError().text() + ) def revokeRole(self, user, role): """ @@ -704,7 +857,12 @@ def revokeRole(self, user, role): query = QSqlQuery(self.db) if not query.exec_(sql): - raise Exception(self.tr('Problem revoking profile: ') +role+'\n'+query.lastError().text()) + raise Exception( + self.tr("Problem revoking profile: ") + + role + + "\n" + + query.lastError().text() + ) def getTablesFromDatabase(self): """ @@ -716,10 +874,13 @@ def getTablesFromDatabase(self): sql = self.gen.getTablesFromDatabase() query = QSqlQuery(sql, self.db) if not query.isActive(): - raise Exception(self.tr("Problem getting tables from database: ")+query.lastError().text()) + raise Exception( + self.tr("Problem getting tables from database: ") + + query.lastError().text() + ) while query.next(): - #table name + # table name ret.append("{0}.{1}".format(query.value(0), query.value(1))) return ret @@ -732,72 +893,99 @@ def getRolePrivileges(self, role, dbname): """ self.checkAndOpenDb() privilegesDict = dict() - + sql = self.gen.getRolePrivileges(role, dbname) query = QSqlQuery(sql, self.db) if not query.isActive(): - raise Exception(self.tr("Problem getting role privileges: ")+query.lastError().text()) - + raise Exception( + self.tr("Problem getting role privileges: ") + query.lastError().text() + ) + while query.next(): schema = query.value(3) table = query.value(4) privilege = query.value(5) - - if schema in ['cb', 'public', 'complexos', 'dominios', 'pe', 'ge']: - privilegesDict = self.utils.buildNestedDict(privilegesDict, [schema, table], [privilege]) - + + if schema in ["cb", "public", "complexos", "dominios", "pe", "ge"]: + privilegesDict = self.utils.buildNestedDict( + privilegesDict, [schema, table], [privilege] + ) + permissionsDict = dict() for schema in list(privilegesDict.keys()): for table in list(privilegesDict[schema].keys()): - split = table.split('_') + split = table.split("_") category = split[0] - layerName = schema+'.'+table - + layerName = schema + "." + table + if schema not in list(permissionsDict.keys()): permissionsDict[schema] = dict() - + if category not in list(permissionsDict[schema].keys()): permissionsDict[schema][category] = dict() privileges = privilegesDict[schema][table] - write = ['DELETE', 'INSERT', 'SELECT', 'UPDATE', 'TRUNCATE', 'REFERENCES', 'TRIGGER'] + write = [ + "DELETE", + "INSERT", + "SELECT", + "UPDATE", + "TRUNCATE", + "REFERENCES", + "TRIGGER", + ] if all((permission in privileges for permission in write)): if layerName not in permissionsDict[schema][category]: permissionsDict[schema][category][layerName] = dict() - permissionsDict[schema][category][layerName]['read'] = '2'#read yes - permissionsDict[schema][category][layerName]['write'] = '2'#write yes + permissionsDict[schema][category][layerName][ + "read" + ] = "2" # read yes + permissionsDict[schema][category][layerName][ + "write" + ] = "2" # write yes else: if layerName not in permissionsDict[schema][category]: permissionsDict[schema][category][layerName] = dict() - permissionsDict[schema][category][layerName]['read'] = '2'#read yes - permissionsDict[schema][category][layerName]['write'] = '0'#write no - - return permissionsDict + permissionsDict[schema][category][layerName][ + "read" + ] = "2" # read yes + permissionsDict[schema][category][layerName][ + "write" + ] = "0" # write no + + return permissionsDict def getFrameLayerName(self): """ Gets the frame layer name """ - return 'public.aux_moldura_a' - - def getEDGVDbsFromServer(self, parentWidget = None, getDatabaseVersions = True): + return "public.aux_moldura_a" + + def getEDGVDbsFromServer(self, parentWidget=None, getDatabaseVersions=True): """ Gets edgv databases from 'this' server """ - #Can only be used in postgres database. + # Can only be used in postgres database. self.checkAndOpenDb() - query = QSqlQuery(self.gen.getDatabasesFromServer(),self.db) + query = QSqlQuery(self.gen.getDatabasesFromServer(), self.db) if not query.isActive(): - raise Exception(self.tr("Problem getting EDGV databases: ")+query.lastError().text()) + raise Exception( + self.tr("Problem getting EDGV databases: ") + query.lastError().text() + ) dbList = [] - + while query.next(): dbList.append(query.value(0)) - + edvgDbList = [] if parentWidget: - progress = ProgressWidget(1,len(dbList),self.tr('Reading selected databases... '), parent = parentWidget) + progress = ProgressWidget( + 1, + len(dbList), + self.tr("Reading selected databases... "), + parent=parentWidget, + ) progress.initBar() if getDatabaseVersions: for database in dbList: @@ -811,10 +999,11 @@ def getEDGVDbsFromServer(self, parentWidget = None, getDatabaseVersions = True): if not db.open(): # raise Exception(self.tr("Problem opening databases: ")+db.lastError().databaseText()) QgsMessageLog.logMessage( - self.tr("Unable to load {0}. Error message: '{1}'")\ - .format(database, db.lastError().databaseText()), + self.tr("Unable to load {0}. Error message: '{1}'").format( + database, db.lastError().databaseText() + ), "DSGTools Plugin", - Qgis.Warning + Qgis.Warning, ) continue @@ -824,53 +1013,67 @@ def getEDGVDbsFromServer(self, parentWidget = None, getDatabaseVersions = True): count = query2.value(0) if count > 0: query3 = QSqlQuery(db) - if query3.exec_(self.gen.getEDGVVersionAndImplementationVersion()): + if query3.exec_( + self.gen.getEDGVVersionAndImplementationVersion() + ): while query3.next(): version = query3.value(0) implVersion = query3.value(1) if version: - edvgDbList.append((database, version, implVersion)) - else: edvgDbList.append( - (database, 'Non_EDGV', -1)) + (database, version, implVersion) + ) + else: + edvgDbList.append((database, "Non_EDGV", -1)) elif "42501" in query3.lastError().databaseText(): # user may have some privileges on database, # but may not be granted on all schemas of a # database QgsMessageLog.logMessage( - self.tr("Unable to load '{0}'. User '{1}'" - " has insufficient privileges.")\ - .format(database, db.userName()), + self.tr( + "Unable to load '{0}'. User '{1}'" + " has insufficient privileges." + ).format(database, db.userName()), "DSGTools Plugin", - Qgis.Warning + Qgis.Warning, ) else: - edvgDbList.append((database,'Non_EDGV', -1)) + edvgDbList.append((database, "Non_EDGV", -1)) if parentWidget: progress.step() else: for database in dbList: - if database not in ['postgres', 'dsgtools_admindb', 'template_edgv_213', 'template_edgv_3', 'template_edgv_fter_2a_ed', 'template0', 'template1']: + if database not in [ + "postgres", + "dsgtools_admindb", + "template_edgv_213", + "template_edgv_3", + "template_edgv_fter_2a_ed", + "template0", + "template1", + ]: edvgDbList.append(database) if parentWidget: - progress.step() + progress.step() return edvgDbList - + def getDbsFromServer(self): """ Gets databases from 'this' server """ - #Can only be used in postgres database. + # Can only be used in postgres database. self.checkAndOpenDb() - query = QSqlQuery(self.gen.getDatabasesFromServer(),self.db) + query = QSqlQuery(self.gen.getDatabasesFromServer(), self.db) if not query.isActive(): - raise Exception(self.tr("Problem getting databases: ")+query.lastError().text()) + raise Exception( + self.tr("Problem getting databases: ") + query.lastError().text() + ) dbList = [] - + while query.next(): dbList.append(query.value(0)) return dbList - + def checkSuperUser(self): """ Checks if the user used to connect to this database is a super user @@ -882,10 +1085,12 @@ def checkSuperUser(self): value = query.value(0) return value else: - raise Exception(self.tr("Problem checking user: ")+query.lastError().text()) + raise Exception( + self.tr("Problem checking user: ") + query.lastError().text() + ) return False - - def checkTemplateImplementationVersion(self, edgvVersion = None): + + def checkTemplateImplementationVersion(self, edgvVersion=None): """ Returns True if templateSql version is larger than installed template Works when abstractDb is connected to the template @@ -899,7 +1104,8 @@ def checkTemplateImplementationVersion(self, edgvVersion = None): return True else: return False - def dropDatabase(self, candidateName, dropTemplate = False): + + def dropDatabase(self, candidateName, dropTemplate=False): """ Drops a database from server candidataName: database name @@ -907,16 +1113,24 @@ def dropDatabase(self, candidateName, dropTemplate = False): self.checkAndOpenDb() if self.checkSuperUser(): if dropTemplate: - self.setDbAsTemplate(dbName = candidateName, setTemplate = False) + self.setDbAsTemplate(dbName=candidateName, setTemplate=False) self.dropAllConections(candidateName) sql = self.gen.dropDatabase(candidateName) query = QSqlQuery(self.db) if not query.exec_(sql): - raise Exception(self.tr('Problem dropping database: ') + query.lastError().text()) + raise Exception( + self.tr("Problem dropping database: ") + query.lastError().text() + ) else: - raise Exception(self.tr('Problem dropping database: user must have permission for that.')) - - def createResolvedDomainViews(self, createViewClause, fromClause, useTransaction = True): + raise Exception( + self.tr( + "Problem dropping database: user must have permission for that." + ) + ) + + def createResolvedDomainViews( + self, createViewClause, fromClause, useTransaction=True + ): """ Creates a view with all domain values resolved createViewClause: sql query to create the view @@ -926,23 +1140,28 @@ def createResolvedDomainViews(self, createViewClause, fromClause, useTransaction if self.checkSuperUser(): filename = self.getSqlViewFile() if filename != None: - file = codecs.open(filename, encoding='utf-8', mode="r") + file = codecs.open(filename, encoding="utf-8", mode="r") sql = file.read() - sql = sql.replace('[VIEW]', createViewClause).replace('[FROM]', fromClause) + sql = sql.replace("[VIEW]", createViewClause).replace( + "[FROM]", fromClause + ) file.close() - commands = sql.split('#') - commands = [i for i in sql.split('#') if i != ''] + commands = sql.split("#") + commands = [i for i in sql.split("#") if i != ""] if useTransaction: self.db.transaction() query = QSqlQuery(self.db) for command in commands: if not query.exec_(command): if useTransaction: - self.db.rollback() - raise Exception(self.tr('Problem creating views: ') + query.lastError().text()) + self.db.rollback() + raise Exception( + self.tr("Problem creating views: ") + + query.lastError().text() + ) if useTransaction: self.db.commit() - + def getSqlViewFile(self): """ Gets the sql view file @@ -951,12 +1170,30 @@ def getSqlViewFile(self): currentPath = os.path.dirname(__file__) dbVersion = self.getDatabaseVersion() file = None - if dbVersion == '2.1.3': - file = os.path.join(currentPath,'..','..','DbTools','PostGISTool', 'sqls', '213', 'views_213.sql') - if dbVersion == 'FTer_2a_Ed': - file = os.path.join(currentPath,'..','..','DbTools','PostGISTool', 'sqls', 'FTer_2a_Ed', 'views_edgvFter_2a_Ed.sql') + if dbVersion == "2.1.3": + file = os.path.join( + currentPath, + "..", + "..", + "DbTools", + "PostGISTool", + "sqls", + "213", + "views_213.sql", + ) + if dbVersion == "FTer_2a_Ed": + file = os.path.join( + currentPath, + "..", + "..", + "DbTools", + "PostGISTool", + "sqls", + "FTer_2a_Ed", + "views_edgvFter_2a_Ed.sql", + ) return file - + def getInvalidGeomRecords(self, cl, geometryColumn, keyColumn): """ Gets invalid geometry data from database @@ -967,15 +1204,18 @@ def getInvalidGeomRecords(self, cl, geometryColumn, keyColumn): sql = self.gen.getInvalidGeom(tableSchema, tableName, geometryColumn, keyColumn) query = QSqlQuery(sql, self.db) if not query.isActive(): - raise Exception(self.tr("Problem getting invalid geometries: ")+query.lastError().text()) + raise Exception( + self.tr("Problem getting invalid geometries: ") + + query.lastError().text() + ) while query.next(): featId = query.value(0) reason = query.value(1) geom = query.value(2) - invalidRecordsList.append( (featId, reason, geom) ) + invalidRecordsList.append((featId, reason, geom)) return invalidRecordsList - - def insertFlags(self, flagTupleList, processName, useTransaction = True): + + def insertFlags(self, flagTupleList, processName, useTransaction=True): """ Inserts flags into database flagTupleList: flag tuple list @@ -988,29 +1228,53 @@ def insertFlags(self, flagTupleList, processName, useTransaction = True): query = QSqlQuery(self.db) for record in flagTupleList: try: - dimension = self.getDimension(record[3]) # getting geometry dimension + dimension = self.getDimension( + record[3] + ) # getting geometry dimension except Exception as e: raise e # specific EPSG search - flagSRID = self.findEPSG(parameters={'tableSchema':'validation', 'tableName':'aux_flags_validacao_p', 'geometryColumn':'geom'}) + flagSRID = self.findEPSG( + parameters={ + "tableSchema": "validation", + "tableName": "aux_flags_validacao_p", + "geometryColumn": "geom", + } + ) try: - tableSchema, tableName = record[0].split('.') - parameters = {'tableSchema':tableSchema, 'tableName':tableName, 'geometryColumn':record[4]} + tableSchema, tableName = record[0].split(".") + parameters = { + "tableSchema": tableSchema, + "tableName": tableName, + "geometryColumn": record[4], + } srid = self.findEPSG(parameters=parameters) except: srid = flagSRID - #actual flag insertion - sql = self.gen.insertFlagIntoDb(record[0], record[1], record[2], record[3], srid, processName, dimension, record[4], flagSRID) + # actual flag insertion + sql = self.gen.insertFlagIntoDb( + record[0], + record[1], + record[2], + record[3], + srid, + processName, + dimension, + record[4], + flagSRID, + ) if not query.exec_(sql): if useTransaction: self.db.rollback() - raise Exception(self.tr('Problem inserting flags: ') + query.lastError().text()) + raise Exception( + self.tr("Problem inserting flags: ") + query.lastError().text() + ) if useTransaction: self.db.commit() return len(flagTupleList) else: return 0 - + def deleteProcessFlags(self, processName=None, className=None, flagId=None): """ Deletes flags from database @@ -1018,17 +1282,21 @@ def deleteProcessFlags(self, processName=None, className=None, flagId=None): className: class name that will have all flags removed """ self.checkAndOpenDb() - sql = self.gen.deleteFlags(processName = processName, className = className, flagId = flagId) - sqlList = sql.split('#') + sql = self.gen.deleteFlags( + processName=processName, className=className, flagId=flagId + ) + sqlList = sql.split("#") query = QSqlQuery(self.db) self.db.transaction() for inner in sqlList: if not query.exec_(inner): self.db.rollback() - raise Exception(self.tr('Problem deleting flags: ') + query.lastError().text()) + raise Exception( + self.tr("Problem deleting flags: ") + query.lastError().text() + ) self.db.commit() - - def checkAndCreateValidationStructure(self, useTransaction = True): + + def checkAndCreateValidationStructure(self, useTransaction=True): """ Checks if the validation structure is already created, if not it should be created now """ @@ -1036,14 +1304,16 @@ def checkAndCreateValidationStructure(self, useTransaction = True): sql = self.gen.checkValidationStructure() query = QSqlQuery(sql, self.db) if not query.isActive(): - raise Exception(self.tr('Problem creating structure: ')+query.lastError().text()) + raise Exception( + self.tr("Problem creating structure: ") + query.lastError().text() + ) created = True while query.next(): if query.value(0) == 0: created = False if not created: sqltext = self.gen.createValidationStructure(self.findEPSG()) - sqlList = sqltext.split('#') + sqlList = sqltext.split("#") query2 = QSqlQuery(self.db) if useTransaction: self.db.transaction() @@ -1051,10 +1321,13 @@ def checkAndCreateValidationStructure(self, useTransaction = True): if not query2.exec_(sql2): if useTransaction: self.db.rollback() - raise Exception(self.tr('Problem creating structure: ') + query.lastError().text()) + raise Exception( + self.tr("Problem creating structure: ") + + query.lastError().text() + ) if useTransaction: self.db.commit() - + def getValidationStatus(self, processName): """ Gets the validation status for a specific process @@ -1062,9 +1335,11 @@ def getValidationStatus(self, processName): """ self.checkAndOpenDb() sql = self.gen.validationStatus(processName) - query = QSqlQuery(sql,self.db) + query = QSqlQuery(sql, self.db) if not query.isActive(): - raise Exception(self.tr('Problem acquiring status: ') + query.lastError().text()) + raise Exception( + self.tr("Problem acquiring status: ") + query.lastError().text() + ) ret = None while query.next(): ret = query.value(0) @@ -1079,7 +1354,9 @@ def getValidationStatusText(self, processName): sql = self.gen.validationStatusText(processName) query = QSqlQuery(sql, self.db) if not query.isActive(): - raise Exception(self.tr('Problem acquiring status: ') + query.lastError().text()) + raise Exception( + self.tr("Problem acquiring status: ") + query.lastError().text() + ) ret = None while query.next(): ret = query.value(0) @@ -1094,8 +1371,10 @@ def setValidationProcessStatus(self, processName, log, status): sql = self.gen.setValidationStatusQuery(processName, log, status) query = QSqlQuery(self.db) if not query.exec_(sql): - raise Exception(self.tr('Problem setting status: ') + query.lastError().text()) - + raise Exception( + self.tr("Problem setting status: ") + query.lastError().text() + ) + def getRunningProc(self): """ Gets the active running process into database @@ -1104,14 +1383,16 @@ def getRunningProc(self): sql = self.gen.getRunningProc() query = QSqlQuery(sql, self.db) if not query.isActive(): - raise Exception(self.tr('Problem getting running process: ') + query.lastError().text()) + raise Exception( + self.tr("Problem getting running process: ") + query.lastError().text() + ) while query.next(): processName = query.value(0) status = query.value(1) if status == 3: return processName return None - + def isLyrInDb(self, lyr): """ Checks if a layer is in the database @@ -1120,25 +1401,57 @@ def isLyrInDb(self, lyr): candidateHost = candidateUri.host() candidatePort = int(candidateUri.port()) candidateDb = candidateUri.database() - if self.db.hostName() == candidateHost and self.db.port() == candidatePort and self.db.databaseName() == candidateDb: + if ( + self.db.hostName() == candidateHost + and self.db.port() == candidatePort + and self.db.databaseName() == candidateDb + ): return True else: return False - - def testSpatialRule(self, class_a, necessity, predicate_function, class_b, min_card, max_card, rule, aKeyColumn, bKeyColumn, aGeomColumn, bGeomColumn): + + def testSpatialRule( + self, + class_a, + necessity, + predicate_function, + class_b, + min_card, + max_card, + rule, + aKeyColumn, + bKeyColumn, + aGeomColumn, + bGeomColumn, + ): """ Tests spatial predicates to check whether a rule is broken """ self.checkAndOpenDb() - sql = self.gen.testSpatialRule(class_a, necessity, predicate_function, class_b, min_card, max_card, aKeyColumn, bKeyColumn, aGeomColumn, bGeomColumn) + sql = self.gen.testSpatialRule( + class_a, + necessity, + predicate_function, + class_b, + min_card, + max_card, + aKeyColumn, + bKeyColumn, + aGeomColumn, + bGeomColumn, + ) query = QSqlQuery(sql, self.db) if not query.isActive(): - raise Exception(self.tr('Problem testing spatial rule: ') + query.lastError().text()) + raise Exception( + self.tr("Problem testing spatial rule: ") + query.lastError().text() + ) ret = [] - flagClass = class_a.replace('_temp', '') + flagClass = class_a.replace("_temp", "") while query.next(): feat_id = query.value(0) - reason = self.tr('Feature id {} from {} violates rule {} {}').format(feat_id, class_a, rule.decode('utf-8'), class_b) + reason = self.tr("Feature id {} from {} violates rule {} {}").format( + feat_id, class_a, rule.decode("utf-8"), class_b + ) geom = query.value(1) # storing flags for class_a ret.append((flagClass, feat_id, reason, geom, aGeomColumn)) @@ -1153,27 +1466,31 @@ def getDimension(self, geom): sql = self.gen.getDimension(geom) query = QSqlQuery(sql, self.db) if not query.isActive(): - raise Exception(self.tr('Problem getting dimension: ') + query.lastError().text()) + raise Exception( + self.tr("Problem getting dimension: ") + query.lastError().text() + ) dimension = 0 while query.next(): dimension = query.value(0) return dimension - + def getExplodeCandidates(self, cl): """ Gets multi geometries (i.e number of parts > 1) that will be deaggregated later """ self.checkAndOpenDb() - sql= self.gen.getMulti(cl) + sql = self.gen.getMulti(cl) query = QSqlQuery(sql, self.db) if not query.isActive(): - raise Exception(self.tr('Problem exploding candidates: ') + query.lastError().text()) + raise Exception( + self.tr("Problem exploding candidates: ") + query.lastError().text() + ) idList = [] while query.next(): idList.append(query.value(0)) return idList - def getURI(self, table, useOnly = True, geomColumn = 'geom'): + def getURI(self, table, useOnly=True, geomColumn="geom"): """ Gets tabel URI table: table name @@ -1187,21 +1504,21 @@ def getURI(self, table, useOnly = True, geomColumn = 'geom'): database = self.db.databaseName() user = self.db.userName() password = self.db.password() - + if useOnly: sql = self.gen.loadLayerFromDatabase(table) else: sql = self.gen.loadLayerFromDatabaseUsingInh(table) - + uri = QgsDataSourceUri() - uri.setConnection(str(host),str(port), str(database), str(user), str(password)) + uri.setConnection(str(host), str(port), str(database), str(user), str(password)) id = self.getPrimaryKeyColumn(table) uri.setDataSource(schema, layer_name, geomColumn, sql, id) uri.disableSelectAtId(True) - + return uri - - def getURIV2(self, tableSchema, tableName, geometryColumnm, sql = ''): + + def getURIV2(self, tableSchema, tableName, geometryColumnm, sql=""): """ New inplementation giving parameters. """ @@ -1212,12 +1529,12 @@ def getURIV2(self, tableSchema, tableName, geometryColumnm, sql = ''): password = self.db.password() uri = QgsDataSourceUri() - uri.setConnection(str(host),str(port), str(database), str(user), str(password)) - id = self.getPrimaryKeyColumn('{0}.{1}'.format(tableSchema, tableName)) + uri.setConnection(str(host), str(port), str(database), str(user), str(password)) + id = self.getPrimaryKeyColumn("{0}.{1}".format(tableSchema, tableName)) uri.setDataSource(tableSchema, tableName, geometryColumnm, sql, id) - + return uri - + def getDuplicatedGeomRecords(self, cl, geometryColumn, keyColumn): """ Gets duplicated records @@ -1228,12 +1545,17 @@ def getDuplicatedGeomRecords(self, cl, geometryColumn, keyColumn): self.checkAndOpenDb() tupleList = [] tableSchema, tableName = self.getTableSchema(cl) - sql = self.gen.getDuplicatedGeom(tableSchema, tableName, geometryColumn, keyColumn) + sql = self.gen.getDuplicatedGeom( + tableSchema, tableName, geometryColumn, keyColumn + ) query = QSqlQuery(sql, self.db) if not query.isActive(): - raise Exception(self.tr('Problem getting duplicated geometries: ') + query.lastError().text()) + raise Exception( + self.tr("Problem getting duplicated geometries: ") + + query.lastError().text() + ) while query.next(): - tupleList.append( (query.value(0),query.value(2)) ) + tupleList.append((query.value(0), query.value(2))) return tupleList def getSmallAreasRecords(self, cl, tol, geometryColumn, keyColumn): @@ -1246,17 +1568,21 @@ def getSmallAreasRecords(self, cl, tol, geometryColumn, keyColumn): self.checkAndOpenDb() smallAreasTupleList = [] tableSchema, tableName = self.getTableSchema(cl) - sql = self.gen.getSmallAreas(tableSchema, tableName, tol, geometryColumn, keyColumn) + sql = self.gen.getSmallAreas( + tableSchema, tableName, tol, geometryColumn, keyColumn + ) query = QSqlQuery(sql, self.db) if not query.isActive(): - raise Exception(self.tr('Problem getting small areas: ') + query.lastError().text()) + raise Exception( + self.tr("Problem getting small areas: ") + query.lastError().text() + ) while query.next(): - smallAreasTupleList.append( (query.value(0),query.value(1)) ) + smallAreasTupleList.append((query.value(0), query.value(1))) return smallAreasTupleList - def getSmallLinesRecords(self,classesWithGeom, tol, geometryColumn, keyColumn): + def getSmallLinesRecords(self, classesWithGeom, tol, geometryColumn, keyColumn): """ - Gets small lines records + Gets small lines records tol: tolerance geometryColumn: geometryColumn keyColumn: pk column @@ -1265,15 +1591,30 @@ def getSmallLinesRecords(self,classesWithGeom, tol, geometryColumn, keyColumn): smallLinesDict = dict() for cl in classesWithGeom: tableSchema, tableName = self.getTableSchema(cl) - sql = self.gen.getSmallLines(tableSchema, tableName, tol, geometryColumn, keyColumn) + sql = self.gen.getSmallLines( + tableSchema, tableName, tol, geometryColumn, keyColumn + ) query = QSqlQuery(sql, self.db) if not query.isActive(): - raise Exception(self.tr('Problem getting small lines: ') + query.lastError().text()) + raise Exception( + self.tr("Problem getting small lines: ") + query.lastError().text() + ) while query.next(): - smallLinesDict = self.utils.buildNestedDict(smallLinesDict, [cl,query.value(0)], query.value(1)) + smallLinesDict = self.utils.buildNestedDict( + smallLinesDict, [cl, query.value(0)], query.value(1) + ) return smallLinesDict - def getVertexNearEdgesRecords(self, tableSchema, tableName, tol, geometryColumn, keyColumn, geomType, useTransaction = True): + def getVertexNearEdgesRecords( + self, + tableSchema, + tableName, + tol, + geometryColumn, + keyColumn, + geomType, + useTransaction=True, + ): """ Gets vertexes near edges. These vertexes are problematic and should be treated tableSchema: table schema @@ -1284,8 +1625,10 @@ def getVertexNearEdgesRecords(self, tableSchema, tableName, tol, geometryColumn, """ self.checkAndOpenDb() result = [] - sql = self.gen.prepareVertexNearEdgesStruct(tableSchema, tableName, geometryColumn, keyColumn, geomType) - sqlList = sql.split('#') + sql = self.gen.prepareVertexNearEdgesStruct( + tableSchema, tableName, geometryColumn, keyColumn, geomType + ) + sqlList = sql.split("#") if useTransaction: self.db.transaction() for sql2 in sqlList: @@ -1293,25 +1636,35 @@ def getVertexNearEdgesRecords(self, tableSchema, tableName, tol, geometryColumn, if not query.exec_(sql2): if useTransaction: self.db.rollback() - raise Exception(self.tr('Problem preparing auxiliary structure: ') + query.lastError().text()) + raise Exception( + self.tr("Problem preparing auxiliary structure: ") + + query.lastError().text() + ) # specific EPSG search - parameters = {'tableSchema': tableSchema, 'tableName': tableName, 'geometryColumn': geometryColumn} + parameters = { + "tableSchema": tableSchema, + "tableName": tableName, + "geometryColumn": geometryColumn, + } epsg = self.findEPSG(parameters=parameters) sql = self.gen.getVertexNearEdgesStruct(epsg, tol, geometryColumn, keyColumn) - query = QSqlQuery(sql,self.db) + query = QSqlQuery(sql, self.db) if not query.isActive(): if useTransaction: self.db.rollback() - raise Exception(self.tr('Problem getting vertex near edges: ') + query.lastError().text()) + raise Exception( + self.tr("Problem getting vertex near edges: ") + + query.lastError().text() + ) while query.next(): id = query.value(0) geom = query.value(1) - result.append((id,geom)) + result.append((id, geom)) if useTransaction: self.db.commit() return result - def removeFeatures(self, cl, processList, keyColumn, useTransaction = True): + def removeFeatures(self, cl, processList, keyColumn, useTransaction=True): """ Removes features from class cl: class name @@ -1320,7 +1673,7 @@ def removeFeatures(self, cl, processList, keyColumn, useTransaction = True): """ self.checkAndOpenDb() tableSchema, tableName = self.getTableSchema(cl) - idList = [i['id'] for i in processList] + idList = [i["id"] for i in processList] sql = self.gen.deleteFeatures(tableSchema, tableName, idList, keyColumn) query = QSqlQuery(self.db) if useTransaction: @@ -1328,7 +1681,12 @@ def removeFeatures(self, cl, processList, keyColumn, useTransaction = True): if not query.exec_(sql): if useTransaction: self.db.rollback() - raise Exception(self.tr('Problem deleting features from ')+cl+': '+ query.lastError().text()) + raise Exception( + self.tr("Problem deleting features from ") + + cl + + ": " + + query.lastError().text() + ) if useTransaction: self.db.commit() return len(idList) @@ -1346,12 +1704,17 @@ def getNotSimpleRecords(self, cl, geometryColumn, keyColumn): sql = self.gen.getNotSimple(tableSchema, tableName, geometryColumn, keyColumn) query = QSqlQuery(sql, self.db) if not query.isActive(): - raise Exception(self.tr('Problem getting not simple geometries: ') + query.lastError().text()) + raise Exception( + self.tr("Problem getting not simple geometries: ") + + query.lastError().text() + ) while query.next(): - tupleList.append( (query.value(0), query.value(1)) ) + tupleList.append((query.value(0), query.value(1))) return tupleList - def getOutOfBoundsAnglesRecords(self, tableSchema, tableName, tol, geometryColumn, geomType, keyColumn): + def getOutOfBoundsAnglesRecords( + self, tableSchema, tableName, tol, geometryColumn, geomType, keyColumn + ): """ Gets records with anchor points (points between segments) that are out of bounds (i.e outside a limit tolerance) tableSchema: table schema @@ -1362,10 +1725,15 @@ def getOutOfBoundsAnglesRecords(self, tableSchema, tableName, tol, geometryColum """ self.checkAndOpenDb() result = [] - sql = self.gen.getOutofBoundsAngles(tableSchema, tableName, tol, geometryColumn, geomType, keyColumn) + sql = self.gen.getOutofBoundsAngles( + tableSchema, tableName, tol, geometryColumn, geomType, keyColumn + ) query = QSqlQuery(sql, self.db) if not query.isActive(): - raise Exception(self.tr('Problem getting not out of bounds angles: ') + query.lastError().text()) + raise Exception( + self.tr("Problem getting not out of bounds angles: ") + + query.lastError().text() + ) while query.next(): id = query.value(0) geom = query.value(1) @@ -1382,17 +1750,19 @@ def getFlagsDictByProcess(self, processName): sql = self.gen.getFlagsByProcess(processName) query = QSqlQuery(sql, self.db) if not query.isActive(): - raise Exception(self.tr('Problem getting flags dict: ') + query.lastError().text()) + raise Exception( + self.tr("Problem getting flags dict: ") + query.lastError().text() + ) while query.next(): cl = query.value(0) id = query.value(1) - geometry_column = query.value(2) + geometry_column = query.value(2) if cl not in list(flagsDict.keys()): flagsDict[cl] = [] - flagsDict[cl].append({'id':str(id), 'geometry_column':geometry_column}) + flagsDict[cl].append({"id": str(id), "geometry_column": geometry_column}) return flagsDict - - def forceValidity(self, cl, processList, keyColumn, useTransaction = True): + + def forceValidity(self, cl, processList, keyColumn, useTransaction=True): """ Forces geometry validity (i.e uses ST_MakeValid) cl: class @@ -1401,23 +1771,34 @@ def forceValidity(self, cl, processList, keyColumn, useTransaction = True): """ self.checkAndOpenDb() tableSchema, tableName = self.getTableSchema(cl) - idList = [i['id'] for i in processList] - geometryColumn = processList[0]['geometry_column'] + idList = [i["id"] for i in processList] + geometryColumn = processList[0]["geometry_column"] # specific EPSG search - parameters = {'tableSchema':tableSchema, 'tableName':tableName, 'geometryColumn':geometryColumn} + parameters = { + "tableSchema": tableSchema, + "tableName": tableName, + "geometryColumn": geometryColumn, + } srid = self.findEPSG(parameters=parameters) - sql = self.gen.forceValidity(tableSchema, tableName, idList, srid, keyColumn, geometryColumn) + sql = self.gen.forceValidity( + tableSchema, tableName, idList, srid, keyColumn, geometryColumn + ) query = QSqlQuery(self.db) if useTransaction: self.db.transaction() if not query.exec_(sql): if useTransaction: self.db.rollback() - raise Exception(self.tr('Problem forcing validity of features from ')+cl+': '+ query.lastError().text()) + raise Exception( + self.tr("Problem forcing validity of features from ") + + cl + + ": " + + query.lastError().text() + ) if useTransaction: self.db.commit() return len(idList) - + def getTableExtent(self, tableSchema, tableName): """ Forces geometry validity (i.e uses ST_MakeValid) @@ -1428,8 +1809,10 @@ def getTableExtent(self, tableSchema, tableName): sql = self.gen.getTableExtent(tableSchema, tableName) query = QSqlQuery(sql, self.db) if not query.isActive(): - raise Exception(self.tr('Problem getting table extent: ') + query.lastError().text()) - + raise Exception( + self.tr("Problem getting table extent: ") + query.lastError().text() + ) + extent = None while query.next(): xmin = query.value(0) @@ -1439,7 +1822,7 @@ def getTableExtent(self, tableSchema, tableName): extent = (xmin, xmax, ymin, ymax) return extent - def getOrphanGeomTables(self, loading = False): + def getOrphanGeomTables(self, loading=False): """ Gets parent classes """ @@ -1447,13 +1830,15 @@ def getOrphanGeomTables(self, loading = False): sql = self.gen.getOrphanGeomTablesWithElements(loading) query = QSqlQuery(sql, self.db) if not query.isActive(): - raise Exception(self.tr('Problem getting orphan tables: ') + query.lastError().text()) + raise Exception( + self.tr("Problem getting orphan tables: ") + query.lastError().text() + ) result = [] while query.next(): result.append(query.value(0)) return result - def getOrphanGeomTablesWithElements(self, loading = False): + def getOrphanGeomTablesWithElements(self, loading=False): """ Gets populated parent classes """ @@ -1461,20 +1846,27 @@ def getOrphanGeomTablesWithElements(self, loading = False): sql = self.gen.getOrphanGeomTablesWithElements(loading) query = QSqlQuery(sql, self.db) if not query.isActive(): - raise Exception(self.tr('Problem getting orphan tables: ') + query.lastError().text()) + raise Exception( + self.tr("Problem getting orphan tables: ") + query.lastError().text() + ) result = [] while query.next(): orphanCandidate = query.value(0) sql2 = self.gen.getOrphanTableElementCount(orphanCandidate) query2 = QSqlQuery(sql2, self.db) if not query2.isActive(): - raise Exception(self.tr('Problem counting orphan table: ') + query2.lastError().text()) + raise Exception( + self.tr("Problem counting orphan table: ") + + query2.lastError().text() + ) while query2.next(): if query2.value(0): result.append(query.value(0)) return result - - def updateGeometries(self, tableSchema, tableName, tuplas, epsg, useTransaction = True): + + def updateGeometries( + self, tableSchema, tableName, tuplas, epsg, useTransaction=True + ): """ Updates geometries on database tableSchema: table schema @@ -1491,16 +1883,22 @@ def updateGeometries(self, tableSchema, tableName, tuplas, epsg, useTransaction if not query.exec_(sql): if useTransaction: self.db.rollback() - raise Exception(self.tr('Problem updating geometries: ') + query.lastError().text()) - sqlDel = self.gen.deleteFeaturesNotIn(tableSchema, tableName, list(tuplas.keys())) + raise Exception( + self.tr("Problem updating geometries: ") + query.lastError().text() + ) + sqlDel = self.gen.deleteFeaturesNotIn( + tableSchema, tableName, list(tuplas.keys()) + ) query2 = QSqlQuery(self.db) if not query2.exec_(sqlDel): if useTransaction: self.db.rollback() - raise Exception(self.tr('Problem deleting geometries: ') + query.lastError().text()) + raise Exception( + self.tr("Problem deleting geometries: ") + query.lastError().text() + ) if useTransaction: self.db.commit() - + def checkCentroidAuxStruct(self): """ Checks the centroid structure @@ -1509,13 +1907,15 @@ def checkCentroidAuxStruct(self): sql = self.gen.checkCentroidAuxStruct() query = QSqlQuery(sql, self.db) if not query.isActive(): - raise Exception(self.tr('Problem checking structure: ')+query.lastError().text()) + raise Exception( + self.tr("Problem checking structure: ") + query.lastError().text() + ) while query.next(): if query.value(0) == None: return False return True - - def createCentroidAuxStruct(self, earthCoverageClasses, useTransaction = True): + + def createCentroidAuxStruct(self, earthCoverageClasses, useTransaction=True): """ Creates the centroid structure earthCoverageClasses: earth coverage configuration diciotnary @@ -1525,26 +1925,29 @@ def createCentroidAuxStruct(self, earthCoverageClasses, useTransaction = True): self.db.transaction() for cl in earthCoverageClasses: # getting table schema - if '.' in cl: - tableSchema = cl.split('.')[0] - tableName = cl.split('.')[-1] + if "." in cl: + tableSchema = cl.split(".")[0] + tableName = cl.split(".")[-1] else: tableSchema = self.getTableSchemaFromDb(cl) tableName = cl # specific EPSG search - parameters = {'tableSchema':tableSchema, 'tableName':tableName} + parameters = {"tableSchema": tableSchema, "tableName": tableName} srid = self.findEPSG(parameters=parameters) sqltext = self.gen.createCentroidColumn(tableSchema, tableName, srid) - sqlList = sqltext.split('#') + sqlList = sqltext.split("#") query = QSqlQuery(self.db) for sql2 in sqlList: if not query.exec_(sql2): if useTransaction: self.db.rollback() - raise Exception(self.tr('Problem creating centroid structure: ') + query.lastError().text()) + raise Exception( + self.tr("Problem creating centroid structure: ") + + query.lastError().text() + ) if useTransaction: self.db.commit() - + def checkAndCreateCentroidAuxStruct(self, earthCoverageClasses): """ Checks the centroid structure. If not already created, it creates the centroid structure @@ -1552,7 +1955,7 @@ def checkAndCreateCentroidAuxStruct(self, earthCoverageClasses): """ if not self.checkCentroidAuxStruct(): self.createCentroidAuxStruct(earthCoverageClasses) - + def getEarthCoverageClasses(self): """ Gets the earth coverage classes from earth coverage configuration dictionary. @@ -1561,7 +1964,10 @@ def getEarthCoverageClasses(self): sql = self.gen.getEarthCoverageDict() query = QSqlQuery(sql, self.db) if not query.isActive(): - raise Exception(self.tr('Problem getting earth coverage tables: ') + query.lastError().text()) + raise Exception( + self.tr("Problem getting earth coverage tables: ") + + query.lastError().text() + ) result = [] while query.next(): result.append(query.value(0)) @@ -1575,11 +1981,14 @@ def getEarthCoverageDict(self): sql = self.gen.getEarthCoverageDict() query = QSqlQuery(sql, self.db) if not query.isActive(): - raise Exception(self.tr('Problem getting earth coverage structure: ') + query.lastError().text()) + raise Exception( + self.tr("Problem getting earth coverage structure: ") + + query.lastError().text() + ) while query.next(): return query.value(0) - def setEarthCoverageDict(self, textDict, useTransaction = True): + def setEarthCoverageDict(self, textDict, useTransaction=True): """ Sets the earth coverage configuration dictionary. textDict: earth coverage configuration dictionary @@ -1592,11 +2001,14 @@ def setEarthCoverageDict(self, textDict, useTransaction = True): if not query.exec_(sql): if useTransaction: self.db.rollback() - raise Exception(self.tr('Problem setting earth coverage structure: ') + query.lastError().text()) + raise Exception( + self.tr("Problem setting earth coverage structure: ") + + query.lastError().text() + ) if useTransaction: self.db.commit() - def updateEarthCoverageDict(self, updateDict, oldDict, useTransaction = True): + def updateEarthCoverageDict(self, updateDict, oldDict, useTransaction=True): """ Updates earthCoverage, creating new centroids and removing old unused ones. """ @@ -1610,11 +2022,10 @@ def updateEarthCoverageDict(self, updateDict, oldDict, useTransaction = True): for centroid in oldList: if centroid not in updateList: removalList.append(centroid) - self.createCentroidAuxStruct(creationList, useTransaction = useTransaction) - self.dropCentroids(removalList, useTransaction = useTransaction) + self.createCentroidAuxStruct(creationList, useTransaction=useTransaction) + self.dropCentroids(removalList, useTransaction=useTransaction) - - def dropCentroids(self, classList, useTransaction = True): + def dropCentroids(self, classList, useTransaction=True): """ Drops the centroid structure classList: classes to be altered @@ -1625,9 +2036,9 @@ def dropCentroids(self, classList, useTransaction = True): query = QSqlQuery(self.db) for cl in classList: # getting table schema - if '.' not in cl: + if "." not in cl: tableSchema = self.getTableSchemaFromDb(cl) - fullTableName = tableSchema+'.'+cl + fullTableName = tableSchema + "." + cl else: fullTableName = cl # making the query using table schema and table name @@ -1635,7 +2046,9 @@ def dropCentroids(self, classList, useTransaction = True): if not query.exec_(sql): if useTransaction: self.db.rollback() - raise Exception(self.tr('Problem dropping centroids: ') + query.lastError().text()) + raise Exception( + self.tr("Problem dropping centroids: ") + query.lastError().text() + ) if useTransaction: self.db.commit() @@ -1659,11 +2072,14 @@ def getEarthCoverageCentroids(self): query = QSqlQuery(sql, self.db) centroidList = [] if not query.isActive(): - raise Exception(self.tr('Problem getting earth coverage structure: ') + query.lastError().text()) + raise Exception( + self.tr("Problem getting earth coverage structure: ") + + query.lastError().text() + ) while query.next(): - table = query.value(0).split('_') - table[-1] = 'c' - layerName = '_'.join(table) + table = query.value(0).split("_") + table[-1] = "c" + layerName = "_".join(table) centroidList.append(layerName) return centroidList @@ -1677,20 +2093,24 @@ def getWhoAmI(self, cl, id): sql = self.gen.getWhoAmI(cl, id) query = QSqlQuery(sql, self.db) if not query.isActive(): - raise Exception(self.tr('Problem getting class name: ') + query.lastError().text()) + raise Exception( + self.tr("Problem getting class name: ") + query.lastError().text() + ) while query.next(): return query.value(0) - + def getDbOID(self): self.checkAndOpenDb() sql = self.gen.getDbOID(self.db.databaseName()) query = QSqlQuery(sql, self.db) if not query.isActive(): - raise Exception(self.tr('Problem getting db oid: ') + query.lastError().text()) + raise Exception( + self.tr("Problem getting db oid: ") + query.lastError().text() + ) while query.next(): return query.value(0) - - def snapToGrid(self, classList, tol, srid, geometryColumn, useTransaction = True): + + def snapToGrid(self, classList, tol, srid, geometryColumn, useTransaction=True): """ Snaps tables to grid (i.e executes ST_SnapToGrid) classList: classes to be altered @@ -1706,11 +2126,15 @@ def snapToGrid(self, classList, tol, srid, geometryColumn, useTransaction = True if not query.exec_(sql): if useTransaction: self.db.rollback() - raise Exception(self.tr('Problem snapping to grid: ') + query.lastError().text()) + raise Exception( + self.tr("Problem snapping to grid: ") + query.lastError().text() + ) if useTransaction: self.db.commit() - - def snapLinesToFrame(self, classList, frameTable, tol, geometryColumn, keyColumn, frameGeometryColumn): + + def snapLinesToFrame( + self, classList, frameTable, tol, geometryColumn, keyColumn, frameGeometryColumn + ): """ Snaps lines to frame. This means the lines are prolonged to the frame according to the specified tolerance classList: classes to be altered @@ -1723,14 +2147,27 @@ def snapLinesToFrame(self, classList, frameTable, tol, geometryColumn, keyColumn self.db.transaction() query = QSqlQuery(self.db) for cl in classList: - sqls = self.gen.snapLinesToFrame(cl, frameTable, tol, geometryColumn, keyColumn, frameGeometryColumn) - for sql in sqls.split('#'): + sqls = self.gen.snapLinesToFrame( + cl, frameTable, tol, geometryColumn, keyColumn, frameGeometryColumn + ) + for sql in sqls.split("#"): if not query.exec_(sql): self.db.rollback() - raise Exception(self.tr('Problem snapping to frame: ') + query.lastError().text()) + raise Exception( + self.tr("Problem snapping to frame: ") + + query.lastError().text() + ) self.db.commit() - - def densifyFrame(self, classList, frameTable, snapTolerance, geometryColumn, frameGeometryColumn, useTransaction = True): + + def densifyFrame( + self, + classList, + frameTable, + snapTolerance, + geometryColumn, + frameGeometryColumn, + useTransaction=True, + ): """ Densifies the frame creating new vertexes where the lines were snapped classList: classes to be altered @@ -1740,15 +2177,21 @@ def densifyFrame(self, classList, frameTable, snapTolerance, geometryColumn, fra self.db.transaction() query = QSqlQuery(self.db) for cl in classList: - sql = self.gen.densifyFrame(cl, frameTable, snapTolerance, geometryColumn, frameGeometryColumn) + sql = self.gen.densifyFrame( + cl, frameTable, snapTolerance, geometryColumn, frameGeometryColumn + ) if not query.exec_(sql): if useTransaction: self.db.rollback() - raise Exception(self.tr('Problem densifying frame: ') + query.lastError().text()) + raise Exception( + self.tr("Problem densifying frame: ") + query.lastError().text() + ) if useTransaction: self.db.commit() - - def recursiveSnap(self, classList, tol, geometryColumn, keyColumn, useTransaction = True): + + def recursiveSnap( + self, classList, tol, geometryColumn, keyColumn, useTransaction=True + ): """ Executes a recursive snap within the class classList: classes to be snapped @@ -1762,17 +2205,22 @@ def recursiveSnap(self, classList, tol, geometryColumn, keyColumn, useTransactio if not query.exec_(sql): if useTransaction: self.db.rollback() - raise Exception(self.tr('Problem creating recursive snap function: ') + query.lastError().text()) + raise Exception( + self.tr("Problem creating recursive snap function: ") + + query.lastError().text() + ) for cl in classList: sql = self.gen.executeRecursiveSnap(cl, tol) if not query.exec_(sql): if useTransaction: self.db.rollback() - raise Exception(self.tr('Problem snapping class: ') + query.lastError().text()) + raise Exception( + self.tr("Problem snapping class: ") + query.lastError().text() + ) if useTransaction: self.db.commit() - - def runQuery(self, sql, errorMsg, params, useTransaction = True): + + def runQuery(self, sql, errorMsg, params, useTransaction=True): self.checkAndOpenDb() if useTransaction: self.db.transaction() @@ -1782,7 +2230,7 @@ def runQuery(self, sql, errorMsg, params, useTransaction = True): self.db.rollback() raise Exception(errorMsg + query.lastError().text()) result = dict() - key = ','.join(params) + key = ",".join(params) result[key] = [] while query.next(): newElement = [] @@ -1799,21 +2247,31 @@ def createTempTable(self, tableName, geomColumnName, useTransaction=True): self.db.transaction() query = QSqlQuery(self.db) sql = self.gen.createTempTable(tableName) - sqls = sql.split('#') + sqls = sql.split("#") for s in sqls: if not query.exec_(s): if useTransaction: self.db.rollback() - raise Exception(self.tr('Problem creating temp table {}: '.format(tableName)) + query.lastError().text()) + raise Exception( + self.tr("Problem creating temp table {}: ".format(tableName)) + + query.lastError().text() + ) indexSql = self.gen.createSpatialIndex(tableName, geomColumnName) if not query.exec_(indexSql): if useTransaction: self.db.rollback() - raise Exception(self.tr('Problem creating spatial index on temp table {}: '.format(tableName)) + query.lastError().text()) + raise Exception( + self.tr( + "Problem creating spatial index on temp table {}: ".format( + tableName + ) + ) + + query.lastError().text() + ) if useTransaction: - self.db.commit() - - def dropTempTable(self, tableName, useTransaction = True): + self.db.commit() + + def dropTempTable(self, tableName, useTransaction=True): self.checkAndOpenDb() if useTransaction: self.db.transaction() @@ -1822,11 +2280,14 @@ def dropTempTable(self, tableName, useTransaction = True): if not query.exec_(sql): if useTransaction: self.db.rollback() - raise Exception(self.tr('Problem dropping temp table {}: '.format(tableName)) + query.lastError().text()) + raise Exception( + self.tr("Problem dropping temp table {}: ".format(tableName)) + + query.lastError().text() + ) if useTransaction: self.db.commit() - - def createStyleTable(self, useTransaction = True): + + def createStyleTable(self, useTransaction=True): if useTransaction: self.db.transaction() createSql = self.gen.createStyleTable() @@ -1834,16 +2295,20 @@ def createStyleTable(self, useTransaction = True): if not query.exec_(createSql): if useTransaction: self.db.rollback() - raise Exception(self.tr('Problem creating style table: ') + query.lastError().text()) + raise Exception( + self.tr("Problem creating style table: ") + query.lastError().text() + ) if useTransaction: self.db.commit() - def checkAndCreateStyleTable(self, useTransaction = True): + def checkAndCreateStyleTable(self, useTransaction=True): self.checkAndOpenDb() sql = self.gen.checkStyleTable() query = QSqlQuery(sql, self.db) if not query.isActive(): - raise Exception(self.tr("Problem getting style table: ") + query.lastError().text()) + raise Exception( + self.tr("Problem getting style table: ") + query.lastError().text() + ) query.next() created = query.value(0) if not created: @@ -1854,61 +2319,76 @@ def checkAndCreateStyleTable(self, useTransaction = True): if not query.exec_(createSql): if useTransaction: self.db.rollback() - raise Exception(self.tr('Problem creating style table: ') + query.lastError().text()) + raise Exception( + self.tr("Problem creating style table: ") + query.lastError().text() + ) if useTransaction: self.db.commit() return created - - def getStylesFromDb(self,dbVersion): + + def getStylesFromDb(self, dbVersion): self.checkAndOpenDb() sql = self.gen.getStylesFromDb(dbVersion) if not sql: return [] query = QSqlQuery(sql, self.db) if not query.isActive(): - raise Exception(self.tr("Problem getting styles from db: ") + query.lastError().text()) + raise Exception( + self.tr("Problem getting styles from db: ") + query.lastError().text() + ) styleList = [] while query.next(): styleList.append(query.value(0)) return styleList - - def getStyle(self, styleName, table_name, parsing = True): + + def getStyle(self, styleName, table_name, parsing=True): self.checkAndOpenDb() sql = self.gen.getStyle(styleName, table_name) query = QSqlQuery(sql, self.db) if not query.isActive(): - raise Exception(self.tr("Problem getting styles from db: ") + query.lastError().text()) + raise Exception( + self.tr("Problem getting styles from db: ") + query.lastError().text() + ) styleList = [] query.next() qml = query.value(0) - #TODO: post parse qml to remove possible attribute value type + # TODO: post parse qml to remove possible attribute value type if parsing: if qml: qml = self.utils.parseStyle(qml) tempPath = None if qml: - tempPath = os.path.join(os.path.dirname(__file__), 'temp.qml') - with open(tempPath, 'w') as f: + tempPath = os.path.join(os.path.dirname(__file__), "temp.qml") + with open(tempPath, "w") as f: f.writelines(qml) f.close() return tempPath - - def importStyle(self, styleName, table_name, qml, tableSchema, useTransaction = True): + + def importStyle(self, styleName, table_name, qml, tableSchema, useTransaction=True): self.checkAndOpenDb() if useTransaction: self.db.transaction() query = QSqlQuery(self.db) parsedQml = self.utils.parseStyle(qml) dbName = self.db.databaseName() - sql = self.gen.importStyle(styleName, table_name, parsedQml, tableSchema,dbName) + sql = self.gen.importStyle( + styleName, table_name, parsedQml, tableSchema, dbName + ) if not query.exec_(sql): if useTransaction: self.db.rollback() - raise Exception(self.tr('Problem importing style')+ styleName+'/'+ table_name +':' + query.lastError().text()) + raise Exception( + self.tr("Problem importing style") + + styleName + + "/" + + table_name + + ":" + + query.lastError().text() + ) if useTransaction: self.db.commit() - - def updateStyle(self, styleName, table_name, qml, tableSchema, useTransaction = True): + + def updateStyle(self, styleName, table_name, qml, tableSchema, useTransaction=True): self.checkAndOpenDb() if useTransaction: self.db.transaction() @@ -1918,11 +2398,18 @@ def updateStyle(self, styleName, table_name, qml, tableSchema, useTransaction = if not query.exec_(sql): if useTransaction: self.db.rollback() - raise Exception(self.tr('Problem importing style')+ styleName+'/'+ table_name +':' + query.lastError().text()) + raise Exception( + self.tr("Problem importing style") + + styleName + + "/" + + table_name + + ":" + + query.lastError().text() + ) if useTransaction: self.db.commit() - - def deleteStyle(self, styleName, useTransaction = True): + + def deleteStyle(self, styleName, useTransaction=True): self.checkAndOpenDb() if useTransaction: self.db.transaction() @@ -1931,76 +2418,112 @@ def deleteStyle(self, styleName, useTransaction = True): if not query.exec_(sql): if useTransaction: self.db.rollback() - raise Exception(self.tr('Problem importing style')+ styleName+':' + query.lastError().text()) + raise Exception( + self.tr("Problem importing style") + + styleName + + ":" + + query.lastError().text() + ) if useTransaction: self.db.commit() - - def importStylesIntoDb(self, styleFolder, useTransaction = True): + + def importStylesIntoDb(self, styleFolder, useTransaction=True): """ path: path to folder styleFolder: folder with version. Example: edgv_213/example """ if self.versionFolderDict[self.getDatabaseVersion()] not in styleFolder: - raise Exception(self.tr('Style ')+styleFolder+self.tr(' does not match the version of database ') + self.db.databaseName()) - path = os.path.join(os.path.dirname(__file__),'..', '..','Styles') - stylePath = os.path.join(path,styleFolder) + raise Exception( + self.tr("Style ") + + styleFolder + + self.tr(" does not match the version of database ") + + self.db.databaseName() + ) + path = os.path.join(os.path.dirname(__file__), "..", "..", "Styles") + stylePath = os.path.join(path, styleFolder) availableStyles = next(os.walk(stylePath))[2] - created = self.checkAndCreateStyleTable(useTransaction = useTransaction) + created = self.checkAndCreateStyleTable(useTransaction=useTransaction) for style in availableStyles: - #filtering and checking file names for special characters - if style[0] == '.': + # filtering and checking file names for special characters + if style[0] == ".": continue if not re.match("^[a-zA-Z0-9_.]*$", style): - raise Exception(self.tr('Problem importing style ')+style) + raise Exception(self.tr("Problem importing style ") + style) - tableName = style.split('.')[0] - localStyle = os.path.join(stylePath,style) + tableName = style.split(".")[0] + localStyle = os.path.join(stylePath, style) tableSchema = self.getTableSchemaFromDb(tableName) - #check if style already exists. If it does, update it. - #if style does not exist, create one. - if self.getStyle(styleFolder, tableName, parsing = False): - self.updateStyle(styleFolder, tableName, localStyle, tableSchema, useTransaction = useTransaction) + # check if style already exists. If it does, update it. + # if style does not exist, create one. + if self.getStyle(styleFolder, tableName, parsing=False): + self.updateStyle( + styleFolder, + tableName, + localStyle, + tableSchema, + useTransaction=useTransaction, + ) else: try: - self.importStyle(styleFolder, tableName, localStyle, tableSchema, useTransaction = useTransaction) + self.importStyle( + styleFolder, + tableName, + localStyle, + tableSchema, + useTransaction=useTransaction, + ) except Exception as e: - raise Exception(self.tr('Problem importing style ')+style+':'+':'.join(e.args)) + raise Exception( + self.tr("Problem importing style ") + + style + + ":" + + ":".join(e.args) + ) - def getTableSchemaFromDb(self,table): + def getTableSchemaFromDb(self, table): self.checkAndOpenDb() sql = self.gen.getTableSchemaFromDb(table) query = QSqlQuery(sql, self.db) if not query.isActive(): - raise Exception(self.tr("Problem getting table schema from db: ") + query.lastError().text()) + raise Exception( + self.tr("Problem getting table schema from db: ") + + query.lastError().text() + ) while query.next(): return query.value(0) - - def getAllStylesDict(self, perspective = 'style'): + + def getAllStylesDict(self, perspective="style"): """ Returns a dict of styles in a form acording to perspective: if perspective = 'style' : [styleName][dbName][tableName] = timestamp - if perspective = 'database' : [dbName][styleName][tableName] = timestamp + if perspective = 'database' : [dbName][styleName][tableName] = timestamp """ self.checkAndOpenDb() sql = self.gen.getAllStylesFromDb() query = QSqlQuery(sql, self.db) if not query.isActive(): - raise Exception(self.tr("Problem getting styles from db: ") + query.lastError().text()) + raise Exception( + self.tr("Problem getting styles from db: ") + query.lastError().text() + ) styleDict = dict() while query.next(): dbName = query.value(0) styleName = query.value(1) tableName = query.value(2) timestamp = query.value(3) - if perspective == 'style': - styleDict = self.utils.buildNestedDict(styleDict, [styleName, dbName, tableName], timestamp) - elif perspective == 'database': - styleDict = self.utils.buildNestedDict(styleDict, [dbName, styleName, tableName], timestamp) + if perspective == "style": + styleDict = self.utils.buildNestedDict( + styleDict, [styleName, dbName, tableName], timestamp + ) + elif perspective == "database": + styleDict = self.utils.buildNestedDict( + styleDict, [dbName, styleName, tableName], timestamp + ) return styleDict - - def runSqlFromFile(self, sqlFilePath, useTransaction = True, encoding = 'utf-8'): + + def runSqlFromFile(self, sqlFilePath, useTransaction=True, encoding="utf-8"): self.checkAndOpenDb() - file = codecs.open(sqlFilePath, encoding=encoding, mode='r') + file = codecs.open(sqlFilePath, encoding=encoding, mode="r") sql = file.read() query = QSqlQuery(self.db) if useTransaction: @@ -2008,28 +2531,39 @@ def runSqlFromFile(self, sqlFilePath, useTransaction = True, encoding = 'utf-8') if not query.exec_(sql): if useTransaction: self.db.rollback() - raise Exception(self.tr('Problem running sql ')+ sqlFilePath +':' + query.lastError().text()) + raise Exception( + self.tr("Problem running sql ") + + sqlFilePath + + ":" + + query.lastError().text() + ) if useTransaction: self.db.commit() - + def getStructureDict2(self): """ Don't know the purpose of this method """ self.checkAndOpenDb() - - if self.getDatabaseVersion() == '2.1.3': - schemaList = ['cb', 'complexos', 'dominios'] - elif self.getDatabaseVersion() == 'FTer_2a_Ed': - schemaList = ['pe','ge', 'complexos'] + + if self.getDatabaseVersion() == "2.1.3": + schemaList = ["cb", "complexos", "dominios"] + elif self.getDatabaseVersion() == "FTer_2a_Ed": + schemaList = ["pe", "ge", "complexos"] else: - QgsMessageLog.logMessage(self.tr('Operation not defined for this database version!'), "DSGTools Plugin", Qgis.Critical) + QgsMessageLog.logMessage( + self.tr("Operation not defined for this database version!"), + "DSGTools Plugin", + Qgis.Critical, + ) return - + sql = self.gen.validateWithDomain(schemaList) query = QSqlQuery(sql, self.db) if not query.isActive(): - raise Exception(self.tr("Problem executing query: ")+query.lastError().text()) + raise Exception( + self.tr("Problem executing query: ") + query.lastError().text() + ) classDict = dict() domainDict = dict() @@ -2040,27 +2574,32 @@ def getStructureDict2(self): domainName = str(query.value(3)) domainTable = str(query.value(4)) domainQuery = str(query.value(5)) - cl = schemaName+'.'+className - query2 = QSqlQuery(domainQuery,self.db) + cl = schemaName + "." + className + query2 = QSqlQuery(domainQuery, self.db) while query2.next(): value = int(query2.value(0)) code_name = query2.value(1) - classDict = self.utils.buildNestedDict(classDict,[str(cl),str(attName)],[(value,code_name)]) - #TODO: get constraints + classDict = self.utils.buildNestedDict( + classDict, [str(cl), str(attName)], [(value, code_name)] + ) + # TODO: get constraints return classDict - + def getGeomSchemaList(self): self.checkAndOpenDb() sql = self.gen.getGeometricSchemas() query = QSqlQuery(sql, self.db) if not query.isActive(): - raise Exception(self.tr("Problem getting geom schemas from db: ")+query.lastError().text()) + raise Exception( + self.tr("Problem getting geom schemas from db: ") + + query.lastError().text() + ) schemaList = [] while query.next(): schemaList.append(query.value(0)) return schemaList - - def getGeomDict(self, geomTypeDict, insertCategory = False): + + def getGeomDict(self, geomTypeDict, insertCategory=False): """ returns a dict like this: {'tablePerspective' : { @@ -2071,10 +2610,13 @@ def getGeomDict(self, geomTypeDict, insertCategory = False): sql = self.gen.getGeomTablesFromGeometryColumns() query = QSqlQuery(sql, self.db) if not query.isActive(): - raise Exception(self.tr("Problem getting geom tables from db: ")+query.lastError().text()) + raise Exception( + self.tr("Problem getting geom tables from db: ") + + query.lastError().text() + ) geomDict = dict() - geomDict['primitivePerspective'] = geomTypeDict - geomDict['tablePerspective'] = dict() + geomDict["primitivePerspective"] = geomTypeDict + geomDict["tablePerspective"] = dict() while query.next(): isCentroid = False srid = query.value(0) @@ -2083,25 +2625,29 @@ def getGeomDict(self, geomTypeDict, insertCategory = False): tableName = query.value(4) geometryColumn = query.value(1) layerName = tableName - if geometryColumn == 'centroid': - table = layerName.split('_') - table[-1] = 'c' - layerName = '_'.join(table) - if layerName not in list(geomDict['tablePerspective'].keys()): - geomDict['tablePerspective'][layerName] = dict() - geomDict['tablePerspective'][layerName]['schema'] = tableSchema - geomDict['tablePerspective'][layerName]['srid'] = str(srid) - geomDict['tablePerspective'][layerName]['geometryColumn'] = geometryColumn - geomDict['tablePerspective'][layerName]['geometryType'] = geometryType - geomDict['tablePerspective'][layerName]['tableName'] = tableName + if geometryColumn == "centroid": + table = layerName.split("_") + table[-1] = "c" + layerName = "_".join(table) + if layerName not in list(geomDict["tablePerspective"].keys()): + geomDict["tablePerspective"][layerName] = dict() + geomDict["tablePerspective"][layerName]["schema"] = tableSchema + geomDict["tablePerspective"][layerName]["srid"] = str(srid) + geomDict["tablePerspective"][layerName][ + "geometryColumn" + ] = geometryColumn + geomDict["tablePerspective"][layerName]["geometryType"] = geometryType + geomDict["tablePerspective"][layerName]["tableName"] = tableName if insertCategory: - if edgvVersion == 'Non_EDGV': - geomDict['tablePerspective'][layerName]['category'] = '' + if edgvVersion == "Non_EDGV": + geomDict["tablePerspective"][layerName]["category"] = "" else: - geomDict['tablePerspective'][layerName]['category'] = layerName.split('_')[0] + geomDict["tablePerspective"][layerName][ + "category" + ] = layerName.split("_")[0] return geomDict - - def getDbDomainDict(self, auxGeomDict, buildOtherInfo = False): + + def getDbDomainDict(self, auxGeomDict, buildOtherInfo=False): """ returns a dict like this: {'adm_posto_fiscal_a': { @@ -2117,66 +2663,92 @@ def getDbDomainDict(self, auxGeomDict, buildOtherInfo = False): } """ self.checkAndOpenDb() - #gets only schemas of classes with geom, to speed up the process. + # gets only schemas of classes with geom, to speed up the process. checkConstraintDict = self.getCheckConstraintDict() notNullDict = self.getNotNullDictV2() multiDict = self.getMultiColumnsDict() sql = self.gen.getGeomTablesDomains() query = QSqlQuery(sql, self.db) if not query.isActive(): - raise Exception(self.tr("Problem getting geom schemas from db: ")+query.lastError().text()) + raise Exception( + self.tr("Problem getting geom schemas from db: ") + + query.lastError().text() + ) geomDict = dict() while query.next(): - #parse done in parseFkQuery to make code cleaner. - tableName, fkAttribute, domainTable, domainReferencedAttribute = self.parseFkQuery(query.value(0),query.value(1)) + # parse done in parseFkQuery to make code cleaner. + ( + tableName, + fkAttribute, + domainTable, + domainReferencedAttribute, + ) = self.parseFkQuery(query.value(0), query.value(1)) if tableName not in list(geomDict.keys()): geomDict[tableName] = dict() - if 'columns' not in list(geomDict[tableName].keys()): - geomDict[tableName]['columns'] = dict() - if fkAttribute not in list(geomDict[tableName]['columns'].keys()): - geomDict[tableName]['columns'][fkAttribute] = dict() - geomDict[tableName]['columns'][fkAttribute]['references'] = domainTable - geomDict[tableName]['columns'][fkAttribute]['refPk'] = domainReferencedAttribute - values, otherKey = self.getLayerColumnDict(domainReferencedAttribute, domainTable) - geomDict[tableName]['columns'][fkAttribute]['values'] = values - geomDict[tableName]['columns'][fkAttribute]['otherKey'] = otherKey - geomDict[tableName]['columns'][fkAttribute]['constraintList'] = [] - geomDict[tableName]['columns'][fkAttribute]['isMulti'] = False + if "columns" not in list(geomDict[tableName].keys()): + geomDict[tableName]["columns"] = dict() + if fkAttribute not in list(geomDict[tableName]["columns"].keys()): + geomDict[tableName]["columns"][fkAttribute] = dict() + geomDict[tableName]["columns"][fkAttribute]["references"] = domainTable + geomDict[tableName]["columns"][fkAttribute][ + "refPk" + ] = domainReferencedAttribute + values, otherKey = self.getLayerColumnDict( + domainReferencedAttribute, domainTable + ) + geomDict[tableName]["columns"][fkAttribute]["values"] = values + geomDict[tableName]["columns"][fkAttribute]["otherKey"] = otherKey + geomDict[tableName]["columns"][fkAttribute]["constraintList"] = [] + geomDict[tableName]["columns"][fkAttribute]["isMulti"] = False if tableName in list(checkConstraintDict.keys()): if fkAttribute in list(checkConstraintDict[tableName].keys()): - geomDict[tableName]['columns'][fkAttribute]['constraintList'] = checkConstraintDict[tableName][fkAttribute] - geomDict[tableName]['columns'][fkAttribute]['nullable'] = True + geomDict[tableName]["columns"][fkAttribute][ + "constraintList" + ] = checkConstraintDict[tableName][fkAttribute] + geomDict[tableName]["columns"][fkAttribute]["nullable"] = True if tableName in list(notNullDict.keys()): - if fkAttribute in notNullDict[tableName]['attributes']: - geomDict[tableName]['columns'][fkAttribute]['nullable'] = False + if fkAttribute in notNullDict[tableName]["attributes"]: + geomDict[tableName]["columns"][fkAttribute]["nullable"] = False if tableName in list(multiDict.keys()): if fkAttribute in multiDict[tableName]: - geomDict[tableName]['columns'][fkAttribute]['isMulti'] = True + geomDict[tableName]["columns"][fkAttribute]["isMulti"] = True for tableName in list(multiDict.keys()): - if tableName in list(auxGeomDict['tablePerspective'].keys()): + if tableName in list(auxGeomDict["tablePerspective"].keys()): for fkAttribute in multiDict[tableName]: if tableName not in list(geomDict.keys()): geomDict[tableName] = dict() - if 'columns' not in list(geomDict[tableName].keys()): - geomDict[tableName]['columns'] = dict() - if fkAttribute not in list(geomDict[tableName]['columns'].keys()): - geomDict[tableName]['columns'][fkAttribute] = dict() - geomDict[tableName]['columns'][fkAttribute]['references'] = None + if "columns" not in list(geomDict[tableName].keys()): + geomDict[tableName]["columns"] = dict() + if fkAttribute not in list(geomDict[tableName]["columns"].keys()): + geomDict[tableName]["columns"][fkAttribute] = dict() + geomDict[tableName]["columns"][fkAttribute]["references"] = None if fkAttribute in list(checkConstraintDict[tableName].keys()): - geomDict[tableName]['columns'][fkAttribute]['constraintList'] = checkConstraintDict[tableName][fkAttribute] - geomDict[tableName]['columns'][fkAttribute]['nullable'] = True + geomDict[tableName]["columns"][fkAttribute][ + "constraintList" + ] = checkConstraintDict[tableName][fkAttribute] + geomDict[tableName]["columns"][fkAttribute]["nullable"] = True if tableName in list(notNullDict.keys()): - if fkAttribute in notNullDict[tableName]['attributes']: - geomDict[tableName]['columns'][fkAttribute]['nullable'] = False + if fkAttribute in notNullDict[tableName]["attributes"]: + geomDict[tableName]["columns"][fkAttribute][ + "nullable" + ] = False if tableName in list(multiDict.keys()): if fkAttribute in multiDict[tableName]: - geomDict[tableName]['columns'][fkAttribute]['isMulti'] = True - geomDict[tableName]['columns'][fkAttribute]['refPk'] = 'code' - geomDict[tableName]['columns'][fkAttribute]['otherKey'] = 'code_name' - geomDict[tableName]['columns'][fkAttribute]['values'] = dict() - + geomDict[tableName]["columns"][fkAttribute][ + "isMulti" + ] = True + geomDict[tableName]["columns"][fkAttribute][ + "refPk" + ] = "code" + geomDict[tableName]["columns"][fkAttribute][ + "otherKey" + ] = "code_name" + geomDict[tableName]["columns"][fkAttribute][ + "values" + ] = dict() + return geomDict - + def getCheckConstraintDict(self, layerFilter=None): """ returns a dict like this: @@ -2188,127 +2760,168 @@ def getCheckConstraintDict(self, layerFilter=None): } """ self.checkAndOpenDb() - #gets only schemas of classes with geom, to speed up the process. + # gets only schemas of classes with geom, to speed up the process. sql = self.gen.getGeomTableConstraints(layerFilter=layerFilter) query = QSqlQuery(sql, self.db) if not query.isActive(): - raise Exception(self.tr("Problem getting geom schemas from db: ")+query.lastError().text()) + raise Exception( + self.tr("Problem getting geom schemas from db: ") + + query.lastError().text() + ) geomDict = dict() while query.next(): - #parse done in parseCheckConstraintQuery to make code cleaner. - tableName, attribute, checkList = self.parseCheckConstraintQuery(query.value(0),query.value(1)) + # parse done in parseCheckConstraintQuery to make code cleaner. + tableName, attribute, checkList = self.parseCheckConstraintQuery( + query.value(0), query.value(1) + ) if tableName not in list(geomDict.keys()): geomDict[tableName] = dict() geomDict[tableName][attribute] = checkList return geomDict - + def parseFkQuery(self, queryValue0, queryValue1): - if '.' in queryValue0: - splitList = queryValue0.split('.') + if "." in queryValue0: + splitList = queryValue0.split(".") tableName = splitList[1] else: tableName = queryValue0 fkText = queryValue1 - fkAttribute = fkText.split(')')[0].replace('FOREIGN KEY (','') - subtextList = fkText.split(' REFERENCES ')[-1].replace(' MATCH FULL','').split('(') + fkAttribute = fkText.split(")")[0].replace("FOREIGN KEY (", "") + subtextList = ( + fkText.split(" REFERENCES ")[-1].replace(" MATCH FULL", "").split("(") + ) domainTable = subtextList[0] - if '.' not in domainTable: - auxDomain = domainTable.replace('"','') - domainTable = '''"{0}"."{1}"'''.format(self.getTableSchemaFromDb(auxDomain), auxDomain) - domainReferencedAttribute = subtextList[1].replace(')','') - return tableName.replace('"',''), fkAttribute.replace('"',''), domainTable, domainReferencedAttribute + if "." not in domainTable: + auxDomain = domainTable.replace('"', "") + domainTable = '''"{0}"."{1}"'''.format( + self.getTableSchemaFromDb(auxDomain), auxDomain + ) + domainReferencedAttribute = subtextList[1].replace(")", "") + return ( + tableName.replace('"', ""), + fkAttribute.replace('"', ""), + domainTable, + domainReferencedAttribute, + ) def parseCheckConstraintQuery(self, queryValue0, queryValue1): try: - if 'ANY' in queryValue1 or '@' in queryValue1: + if "ANY" in queryValue1 or "@" in queryValue1: return self.parseCheckConstraintWithAny(queryValue0, queryValue1) else: return self.parseCheckConstraintWithOr(queryValue0, queryValue1) except Exception as e: - raise Exception(self.tr("Error parsing check constraint!\n"+':'.join(e.args))) - + raise Exception( + self.tr("Error parsing check constraint!\n" + ":".join(e.args)) + ) + def parseCheckConstraintWithOr(self, queryValue0, queryValue1): - if '.' in queryValue0: - query0Split = queryValue0.split('.') + if "." in queryValue0: + query0Split = queryValue0.split(".") tableSchema = query0Split[0] tableName = query0Split[1] else: tableName = queryValue0 - query1Split = queryValue1.replace('CHECK ','').replace('(','').replace(')','').replace(' ','').replace('"','').split('OR') + query1Split = ( + queryValue1.replace("CHECK ", "") + .replace("(", "") + .replace(")", "") + .replace(" ", "") + .replace('"', "") + .split("OR") + ) checkList = [] for i in query1Split: - attrSplit = i.split('=') + attrSplit = i.split("=") attribute = attrSplit[0] try: checkList.append(int(attrSplit[1])) except: - pass #ignore checks that are not from dsgtools + pass # ignore checks that are not from dsgtools return tableName, attribute, checkList - + def parseCheckConstraintWithAny(self, queryValue0, queryValue1): - if '.' in queryValue0: - query0Split = queryValue0.split('.') + if "." in queryValue0: + query0Split = queryValue0.split(".") tableSchema = query0Split[0] tableName = query0Split[1] else: tableName = queryValue0 - query1Split = queryValue1.replace('"','').replace('ANY','').replace('ARRAY','').replace('::smallint','').replace('(','').replace(')','').replace('CHECK','').replace('[','').replace(']','').replace(' ','') + query1Split = ( + queryValue1.replace('"', "") + .replace("ANY", "") + .replace("ARRAY", "") + .replace("::smallint", "") + .replace("(", "") + .replace(")", "") + .replace("CHECK", "") + .replace("[", "") + .replace("]", "") + .replace(" ", "") + ) checkList = [] - splitToken = '' - if '=' in query1Split: - splitToken = '=' - elif '<@' in query1Split: - splitToken = '<@' + splitToken = "" + if "=" in query1Split: + splitToken = "=" + elif "<@" in query1Split: + splitToken = "<@" equalSplit = query1Split.split(splitToken) attribute = equalSplit[0] - checkList = list(map(int,equalSplit[1].split(','))) + checkList = list(map(int, equalSplit[1].split(","))) return tableName, attribute, checkList - + def getMultiColumnsDict(self, layerFilter=None): """ - { 'table_name':[-list of columns-] } + { 'table_name':[-list of columns-] } """ self.checkAndOpenDb() - #gets only schemas of classes with geom, to speed up the process. + # gets only schemas of classes with geom, to speed up the process. if layerFilter: sql = self.gen.getMultiColumnsFromTableList(layerFilter) else: - sql = self.gen.getMultiColumns( - schemaList=self.getGeomSchemaList() - ) + sql = self.gen.getMultiColumns(schemaList=self.getGeomSchemaList()) query = QSqlQuery(sql, self.db) if not query.isActive(): - raise Exception(self.tr("Problem getting geom schemas from db: ")+query.lastError().text()) + raise Exception( + self.tr("Problem getting geom schemas from db: ") + + query.lastError().text() + ) geomDict = dict() while query.next(): - #TODO: check if 2.1.3 raises problem, because of empty query + # TODO: check if 2.1.3 raises problem, because of empty query aux = json.loads(query.value(0)) - geomDict[aux['table_name']]=aux['attributes'] + geomDict[aux["table_name"]] = aux["attributes"] return geomDict - + def getTablesJsonList(self): self.checkAndOpenDb() sql = self.gen.getTablesJsonList() query = QSqlQuery(sql, self.db) if not query.isActive(): - raise Exception(self.tr("Problem getting tables dict from db: ")+query.lastError().text()) + raise Exception( + self.tr("Problem getting tables dict from db: ") + + query.lastError().text() + ) geomList = [] while query.next(): geomList.append(json.loads(query.value(0))) - return geomList - + return geomList + def getGeomTypeDict(self, loadCentroids=False): self.checkAndOpenDb() sql = self.gen.getGeomByPrimitive() query = QSqlQuery(sql, self.db) if not query.isActive(): - raise Exception(self.tr("Problem getting geom types from db: ")+query.lastError().text()) + raise Exception( + self.tr("Problem getting geom types from db: ") + + query.lastError().text() + ) geomDict = dict() while query.next(): aux = json.loads(query.value(0)) - geomDict[aux['geomtype']] = aux['classlist'] + geomDict[aux["geomtype"]] = aux["classlist"] return geomDict - + def getGeomColumnDict(self): """ Dict in the form 'geomName':[-list of table names-] @@ -2317,16 +2930,25 @@ def getGeomColumnDict(self): sql = self.gen.getGeomColumnDict() query = QSqlQuery(sql, self.db) if not query.isActive(): - raise Exception(self.tr("Problem getting geom column dict: ")+query.lastError().text()) + raise Exception( + self.tr("Problem getting geom column dict: ") + query.lastError().text() + ) geomDict = dict() while query.next(): aux = json.loads(query.value(0)) - if aux['f2'] not in list(geomDict.keys()): - geomDict[aux['f2']] = [] - geomDict[aux['f2']].append(aux['f1']) + if aux["f2"] not in list(geomDict.keys()): + geomDict[aux["f2"]] = [] + geomDict[aux["f2"]].append(aux["f1"]) return geomDict - - def getGeomColumnTupleList(self, showViews = False, hideCentroids = True, primitiveFilter = None, withElements = False, layerFilter = None): + + def getGeomColumnTupleList( + self, + showViews=False, + hideCentroids=True, + primitiveFilter=None, + withElements=False, + layerFilter=None, + ): """ list in the format [(table_schema, table_name, geometryColumn, geometryType, tableType)] centroids are hidden by default @@ -2338,120 +2960,160 @@ def getGeomColumnTupleList(self, showViews = False, hideCentroids = True, primit try: edgvVersion = self.getDatabaseVersion() if hideCentroids: - if self.checkIfExistsConfigTable('EarthCoverage'): - propertyDict = self.getAllSettingsFromAdminDb('EarthCoverage') + if self.checkIfExistsConfigTable("EarthCoverage"): + propertyDict = self.getAllSettingsFromAdminDb("EarthCoverage") propertyName = propertyDict[edgvVersion][0] dbName = self.db.databaseName() - settingDict = json.loads(self.getSettingFromAdminDb('EarthCoverage', propertyName, edgvVersion)) - earthCoverageDict = settingDict['earthCoverageDict'] - centroidTableList = [i.split('.')[-1] for i in list(earthCoverageDict.keys())] + settingDict = json.loads( + self.getSettingFromAdminDb( + "EarthCoverage", propertyName, edgvVersion + ) + ) + earthCoverageDict = settingDict["earthCoverageDict"] + centroidTableList = [ + i.split(".")[-1] for i in list(earthCoverageDict.keys()) + ] except: pass - - sql = self.gen.getGeomColumnTupleList(showViews = showViews) + + sql = self.gen.getGeomColumnTupleList(showViews=showViews) query = QSqlQuery(sql, self.db) if not query.isActive(): - raise Exception(self.tr("Problem getting geom tuple list: ")+query.lastError().text()) + raise Exception( + self.tr("Problem getting geom tuple list: ") + query.lastError().text() + ) localList = [] while query.next(): - if query.value(2) == 'centroid' and query.value(3) == 'POINT' and query.value(1) in centroidTableList: + if ( + query.value(2) == "centroid" + and query.value(3) == "POINT" + and query.value(1) in centroidTableList + ): continue else: - localList.append((query.value(0), query.value(1), query.value(2), query.value(3), query.value(4))) + localList.append( + ( + query.value(0), + query.value(1), + query.value(2), + query.value(3), + query.value(4), + ) + ) if not withElements and primitiveFilter == []: return localList if withElements: - listWithElements = self.getLayersWithElementsV2([{'tableSchema':i[0],'tableName':i[1]} for i in localList]) + listWithElements = self.getLayersWithElementsV2( + [{"tableSchema": i[0], "tableName": i[1]} for i in localList] + ) geomList = [i for i in localList if i[1] in listWithElements] else: geomList = localList if primitiveFilter != []: geomTypeFilter = [] - if 'p' in primitiveFilter: - geomTypeFilter.append('POINT') - geomTypeFilter.append('MULTIPOINT') - if 'l' in primitiveFilter: - geomTypeFilter.append('LINESTRING') - geomTypeFilter.append('MULTILINESTRING') - if 'a' in primitiveFilter: - geomTypeFilter.append('POLYGON') - geomTypeFilter.append('MULTIPOLYGON') + if "p" in primitiveFilter: + geomTypeFilter.append("POINT") + geomTypeFilter.append("MULTIPOINT") + if "l" in primitiveFilter: + geomTypeFilter.append("LINESTRING") + geomTypeFilter.append("MULTILINESTRING") + if "a" in primitiveFilter: + geomTypeFilter.append("POLYGON") + geomTypeFilter.append("MULTIPOLYGON") geomList = [i for i in geomList if i[3] in geomTypeFilter] return geomList - - def getGeomColumnDictV2(self, showViews = False, hideCentroids = True, primitiveFilter = [], withElements = False, excludeValidation = False): - geomList = self.getGeomColumnTupleList(showViews = showViews, hideCentroids = hideCentroids, primitiveFilter = primitiveFilter, withElements = withElements) + + def getGeomColumnDictV2( + self, + showViews=False, + hideCentroids=True, + primitiveFilter=[], + withElements=False, + excludeValidation=False, + ): + geomList = self.getGeomColumnTupleList( + showViews=showViews, + hideCentroids=hideCentroids, + primitiveFilter=primitiveFilter, + withElements=withElements, + ) edgvVersion = self.getDatabaseVersion() lyrDict = dict() for tableSchema, tableName, geom, geomType, tableType in geomList: if excludeValidation: - if tableSchema == 'validation': + if tableSchema == "validation": continue - if edgvVersion == 'Non_EDGV': + if edgvVersion == "Non_EDGV": lyrName = tableName cat = tableSchema else: - lyrName = '_'.join(tableName.split('_')[1::]) - cat = tableName.split('_')[0] - key = ','.join([cat, lyrName, geom, geomType, tableType]) - lyrDict[key] = {'tableSchema':tableSchema, 'tableName':tableName, 'geom':geom, 'geomType':geomType, 'tableType':tableType, 'lyrName':lyrName, 'cat':cat} + lyrName = "_".join(tableName.split("_")[1::]) + cat = tableName.split("_")[0] + key = ",".join([cat, lyrName, geom, geomType, tableType]) + lyrDict[key] = { + "tableSchema": tableSchema, + "tableName": tableName, + "geom": geom, + "geomType": geomType, + "tableType": tableType, + "lyrName": lyrName, + "cat": cat, + } return lyrDict - - def getAuxInfoDict(self, layerFilter = None): + + def getAuxInfoDict(self, layerFilter=None): """ - Dict with values of check constraint, null values and multi attributes + Dict with values of check constraint, null values and multi attributes """ return { - 'attributeDomainDict' : self.getAttributeDomainDict( - layerFilter = layerFilter - ), - 'checkConstraintDict' : self.getCheckConstraintDict( - layerFilter = layerFilter - ) + "attributeDomainDict": self.getAttributeDomainDict(layerFilter=layerFilter), + "checkConstraintDict": self.getCheckConstraintDict(layerFilter=layerFilter), } - - def getAttributeDomainDict(self, layerFilter = None): + + def getAttributeDomainDict(self, layerFilter=None): self.checkAndOpenDb() sql = self.gen.getGeomTablesDomains(layerFilter=layerFilter) query = QSqlQuery(sql, self.db) if not query.isActive(): - raise Exception(self.tr("Problem getting AttributeDomainDict: ")+query.lastError().text()) - attributeDomainDict = defaultdict( - lambda : defaultdict(dict) - ) + raise Exception( + self.tr("Problem getting AttributeDomainDict: ") + + query.lastError().text() + ) + attributeDomainDict = defaultdict(lambda: defaultdict(dict)) while query.next(): - tableName, fkAttribute, domainTable, domainReferencedAttribute = self.parseFkQuery( - query.value(0),query.value(1) - ) + ( + tableName, + fkAttribute, + domainTable, + domainReferencedAttribute, + ) = self.parseFkQuery(query.value(0), query.value(1)) newAttrDict = attributeDomainDict[tableName][fkAttribute] domainPk = self.getPrimaryKeyColumn(domainTable) - newAttrDict['references'] = domainTable - newAttrDict['refPk'] = domainPk + newAttrDict["references"] = domainTable + newAttrDict["refPk"] = domainPk values, otherKey = self.getLayerColumnDict(domainPk, domainTable) - newAttrDict['otherKey'] = otherKey - newAttrDict['values'] = values - newAttrDict['filterAttr'] = self.getFilter( - domainTable, domainPk, otherKey - ) - - + newAttrDict["otherKey"] = otherKey + newAttrDict["values"] = values + newAttrDict["filterAttr"] = self.getFilter(domainTable, domainPk, otherKey) + return attributeDomainDict def getFilter(self, domainTable, domainPk, otherKey): - tableSchema, tableName = domainTable.split('.') + tableSchema, tableName = domainTable.split(".") knownColumns = [domainPk, otherKey] sql = self.gen.getAttributesFromTable(tableSchema, tableName) query = QSqlQuery(sql, self.db) if not query.isActive(): - raise Exception(self.tr("Problem getting filter: ")+query.lastError().text()) + raise Exception( + self.tr("Problem getting filter: ") + query.lastError().text() + ) while query.next(): column_name = query.value(0) if column_name not in knownColumns: return column_name return None - - def getTableMetadataDict(self, layerFilter = None, showViews = False): + def getTableMetadataDict(self, layerFilter=None, showViews=False): """ New method to handle information from database. Must be migrated to new postgisDb returns a dict of 'table_name' : { @@ -2482,47 +3144,46 @@ def getTableMetadataDict(self, layerFilter = None, showViews = False): sql = self.gen.getTableMetadataDict(layerFilter=layerFilter) query = QSqlQuery(sql, self.db) if not query.isActive(): - raise Exception(self.tr("Problem getting geom tuple list: ")+query.lastError().text()) - metadataDict = defaultdict(lambda :{"columns" : defaultdict(dict)}) + raise Exception( + self.tr("Problem getting geom tuple list: ") + query.lastError().text() + ) + metadataDict = defaultdict(lambda: {"columns": defaultdict(dict)}) while query.next(): auxDict = json.loads(query.value(0)) newDict = metadataDict[auxDict["table_name"]] self.setNewDictTableInfo(newDict, auxDict) attrDict = newDict["columns"][auxDict["attr_name"]] self.setNewAttrInfo(attrDict, auxDict, auxInfoDict) - + return metadataDict def setNewDictTableInfo(self, newDict, auxDict): newDict["table_name"] = auxDict["table_name"] newDict["table_schema"] = auxDict["table_schema"] newDict["primary_key"] = self.getPrimaryKeyColumn( - '.'.join( - [ - auxDict["table_schema"], - auxDict["table_name"] - ] - ) - ) + ".".join([auxDict["table_schema"], auxDict["table_name"]]) + ) newDict["geometry_column"] = auxDict["geometry_column"] newDict["geometry_type"] = auxDict["geometry_type"] - + def setNewAttrInfo(self, attrDict, auxDict, auxInfoDict): attrDict["name"] = auxDict["attr_name"] attrDict["nullable"] = auxDict["nullable"] attrDict["column_type"] = auxDict["column_type"] - attrDict["isMulti"] = True if 'ARRAY' in auxDict["column_type"] else False - self.setReferenceInfo(attrDict, auxDict, auxInfoDict['attributeDomainDict']) - self.setConstraintInfo(attrDict, auxDict, auxInfoDict['checkConstraintDict']) - + attrDict["isMulti"] = True if "ARRAY" in auxDict["column_type"] else False + self.setReferenceInfo(attrDict, auxDict, auxInfoDict["attributeDomainDict"]) + self.setConstraintInfo(attrDict, auxDict, auxInfoDict["checkConstraintDict"]) + def setReferenceInfo(self, attrDict, auxDict, attributeDomainDict): - if auxDict['table_name'] in attributeDomainDict and \ - auxDict["attr_name"] in attributeDomainDict[auxDict['table_name']]: - attr_name_dict = attributeDomainDict[auxDict['table_name']][auxDict["attr_name"]] - attrDict.update( - attr_name_dict - ) - + if ( + auxDict["table_name"] in attributeDomainDict + and auxDict["attr_name"] in attributeDomainDict[auxDict["table_name"]] + ): + attr_name_dict = attributeDomainDict[auxDict["table_name"]][ + auxDict["attr_name"] + ] + attrDict.update(attr_name_dict) + def getDomainDictFromDomainTable(self, refPk, domainTable, otherKey): domainDict = dict() self.checkAndOpenDb() @@ -2531,24 +3192,28 @@ def getDomainDictFromDomainTable(self, refPk, domainTable, otherKey): if not query.isActive(): raise Exception( self.tr( - "Problem getting getDomainDictFromDomainTable from table {table_name}:{query_error}" - ).format(table_name=domainTable, query_error=query.lastError().text()) + "Problem getting getDomainDictFromDomainTable from table {table_name}:{query_error}" + ).format(table_name=domainTable, query_error=query.lastError().text()) ) while query.next(): aux = json.loads(query.value(0)) - domainDict.update({aux[refPk]:aux[otherKey]}) + domainDict.update({aux[refPk]: aux[otherKey]}) return domainDict - + def setConstraintInfo(self, attrDict, auxDict, checkConstraintDict): - if auxDict["table_name"] in checkConstraintDict and \ - auxDict["attr_name"] in checkConstraintDict[auxDict["table_name"]]: - attrDict["constraintList"] = checkConstraintDict[auxDict["table_name"]][auxDict["attr_name"]] + if ( + auxDict["table_name"] in checkConstraintDict + and auxDict["attr_name"] in checkConstraintDict[auxDict["table_name"]] + ): + attrDict["constraintList"] = checkConstraintDict[auxDict["table_name"]][ + auxDict["attr_name"] + ] def getLayersFilterByInheritance(self, layerList): - filter = [i.split('.')[-1] for i in self.getOrphanGeomTables(loading = True)] + filter = [i.split(".")[-1] for i in self.getOrphanGeomTables(loading=True)] filtered = [] for lyr in layerList: - clause = lyr['tableName'] if isinstance(lyr, dict) else lyr + clause = lyr["tableName"] if isinstance(lyr, dict) else lyr if clause in filter: filtered.append(lyr) return filtered @@ -2562,48 +3227,60 @@ def getNotNullDictV2(self, layerFilter=None): sql = self.gen.getNotNullDict(layerFilter=layerFilter) query = QSqlQuery(sql, self.db) if not query.isActive(): - raise Exception(self.tr("Problem getting not null dict: ")+query.lastError().text()) + raise Exception( + self.tr("Problem getting not null dict: ") + query.lastError().text() + ) notNullDict = dict() while query.next(): aux = json.loads(query.value(0)) - if aux['f1'] not in list(notNullDict.keys()): - notNullDict[aux['f1']] = dict() - notNullDict[aux['f1']]['schema'] = aux['f2'] - if 'attributes' not in list(notNullDict[aux['f1']].keys()): - notNullDict[aux['f1']]['attributes'] = [] - notNullDict[aux['f1']]['attributes'] = aux['f3'] + if aux["f1"] not in list(notNullDict.keys()): + notNullDict[aux["f1"]] = dict() + notNullDict[aux["f1"]]["schema"] = aux["f2"] + if "attributes" not in list(notNullDict[aux["f1"]].keys()): + notNullDict[aux["f1"]]["attributes"] = [] + notNullDict[aux["f1"]]["attributes"] = aux["f3"] return notNullDict - + def getDomainDictV2(self, domainTable): self.checkAndOpenDb() sql = self.gen.getDomainDict(domainTable) query = QSqlQuery(sql, self.db) if not query.isActive(): - raise Exception(self.tr("Problem getting domain dict from table ")+domainTable+':'+query.lastError().text()) + raise Exception( + self.tr("Problem getting domain dict from table ") + + domainTable + + ":" + + query.lastError().text() + ) domainDict = dict() while query.next(): aux = json.loads(query.value(0)) - domainDict[aux['f2']] = aux['f1'] + domainDict[aux["f2"]] = aux["f1"] return domainDict - + def getLayerColumnDict(self, refPk, domainTable): self.checkAndOpenDb() sql = self.gen.getDomainCodeDict(domainTable) query = QSqlQuery(sql, self.db) if not query.isActive(): - raise Exception(self.tr("Problem getting layer column dict from table ")+domainTable+':'+query.lastError().text()) + raise Exception( + self.tr("Problem getting layer column dict from table ") + + domainTable + + ":" + + query.lastError().text() + ) domainDict = dict() otherKey = None while query.next(): aux = json.loads(query.value(0)) if not otherKey: - if 'code_name' in list(aux.keys()): - otherKey = 'code_name' + if "code_name" in list(aux.keys()): + otherKey = "code_name" else: otherKey = [key for key in list(aux.keys()) if key != refPk][0] domainDict[aux[refPk]] = aux[otherKey] return domainDict, otherKey - + def getGeomStructDict(self): """ Returns dict in the following format: @@ -2611,25 +3288,34 @@ def getGeomStructDict(self): """ self.checkAndOpenDb() sql = self.gen.getGeomStructDict() - yesNoDict = {'YES':True, 'NO':False} + yesNoDict = {"YES": True, "NO": False} query = QSqlQuery(sql, self.db) if not query.isActive(): - raise Exception(self.tr("Problem getting geom struct dict: ")+query.lastError().text()) + raise Exception( + self.tr("Problem getting geom struct dict: ") + query.lastError().text() + ) geomStructDict = dict() while query.next(): aux = json.loads(query.value(0)) - tableName = aux['table_name'] + tableName = aux["table_name"] if tableName not in list(geomStructDict.keys()): geomStructDict[tableName] = dict() - for d in aux['array_agg']: - geomStructDict[tableName][d['f1']] = yesNoDict[d['f2']] + for d in aux["array_agg"]: + geomStructDict[tableName][d["f1"]] = yesNoDict[d["f2"]] return geomStructDict - - def createDbFromTemplate(self, dbName, templateName, parentWidget = None): - #check if created, if created prompt if drop is needed + + def createDbFromTemplate(self, dbName, templateName, parentWidget=None): + # check if created, if created prompt if drop is needed self.checkAndOpenDb() if parentWidget: - progress = ProgressWidget(1,2,self.tr('Creating database {0} from template {1}... ').format(dbName, templateName), parent = parentWidget) + progress = ProgressWidget( + 1, + 2, + self.tr("Creating database {0} from template {1}... ").format( + dbName, templateName + ), + parent=parentWidget, + ) progress.initBar() self.dropAllConections(templateName) if parentWidget: @@ -2637,32 +3323,56 @@ def createDbFromTemplate(self, dbName, templateName, parentWidget = None): sql = self.gen.createFromTemplate(dbName, templateName) query = QSqlQuery(self.db) if not query.exec_(sql): - raise Exception(self.tr('Problem creating from template: ') + query.lastError().text()) + raise Exception( + self.tr("Problem creating from template: ") + query.lastError().text() + ) self.checkAndCreateStyleTable() - #this close is to allow creation from template + # this close is to allow creation from template self.db.close() if parentWidget: progress.step() - + def getViewDefinition(self, viewName): self.checkAndOpenDb() sql = self.gen.getViewDefinition(viewName) query = QSqlQuery(sql, self.db) if not query.isActive(): - raise Exception(self.tr("Problem getting view definition: ")+query.lastError().text()) + raise Exception( + self.tr("Problem getting view definition: ") + query.lastError().text() + ) while query.next(): return query.value(0) - - def updateDbSRID(self, srid, useTransaction = True, closeAfterUse = True, parentWidget = None, threading = False): - self.checkAndOpenDb() - tableDictList = self.getParentGeomTables(getDictList = True, showViews = False, hideCentroids = False) - viewList = ['''"{0}"."{1}"'''.format(i['tableSchema'],i['tableName']) for i in list(self.getGeomColumnDictV2(showViews = True, hideCentroids = False).values()) if i['tableType'] == 'VIEW'] - viewDefinitionDict = {i:self.getViewDefinition(i) for i in viewList} + + def updateDbSRID( + self, + srid, + useTransaction=True, + closeAfterUse=True, + parentWidget=None, + threading=False, + ): + self.checkAndOpenDb() + tableDictList = self.getParentGeomTables( + getDictList=True, showViews=False, hideCentroids=False + ) + viewList = [ + '''"{0}"."{1}"'''.format(i["tableSchema"], i["tableName"]) + for i in list( + self.getGeomColumnDictV2(showViews=True, hideCentroids=False).values() + ) + if i["tableType"] == "VIEW" + ] + viewDefinitionDict = {i: self.getViewDefinition(i) for i in viewList} if useTransaction: self.db.transaction() if parentWidget: - progress = ProgressWidget(1, 2*len(viewList)+len(tableDictList), self.tr('Updating SRIDs from {0}... ').format(self.db.databaseName()), parent = parentWidget) + progress = ProgressWidget( + 1, + 2 * len(viewList) + len(tableDictList), + self.tr("Updating SRIDs from {0}... ").format(self.db.databaseName()), + parent=parentWidget, + ) progress.initBar() for view in viewList: viewSql = self.gen.dropView(view) @@ -2673,7 +3383,9 @@ def updateDbSRID(self, srid, useTransaction = True, closeAfterUse = True, parent if threading: return (viewSql, query) else: - raise Exception(self.tr('Problem dropping views: ') + query.lastError().text()) + raise Exception( + self.tr("Problem dropping views: ") + query.lastError().text() + ) if parentWidget: progress.step() @@ -2686,11 +3398,15 @@ def updateDbSRID(self, srid, useTransaction = True, closeAfterUse = True, parent if threading: return (sridSql, query) else: - raise Exception(self.tr('Problem dropping views: ') + query.lastError().text()) + raise Exception( + self.tr("Problem dropping views: ") + query.lastError().text() + ) if parentWidget: progress.step() for viewName in viewList: - createViewSql = self.gen.createViewStatement(viewName, viewDefinitionDict[viewName]) + createViewSql = self.gen.createViewStatement( + viewName, viewDefinitionDict[viewName] + ) query = QSqlQuery(self.db) if not query.exec_(createViewSql): if useTransaction: @@ -2698,16 +3414,18 @@ def updateDbSRID(self, srid, useTransaction = True, closeAfterUse = True, parent if threading: return (createViewSql, query) else: - raise Exception(self.tr('Problem dropping views: ') + query.lastError().text()) + raise Exception( + self.tr("Problem dropping views: ") + query.lastError().text() + ) if parentWidget: progress.step() if useTransaction: self.db.commit() - #this close is to allow creation from template + # this close is to allow creation from template if closeAfterUse: self.db.close() - - def checkTemplate(self, version = None): + + def checkTemplate(self, version=None): self.checkAndOpenDb() if not version: version = self.getDatabaseVersion() @@ -2715,12 +3433,14 @@ def checkTemplate(self, version = None): sql = self.gen.checkTemplate() query = QSqlQuery(sql, self.db) if not query.isActive(): - raise Exception(self.tr("Problem setting as template: ")+query.lastError().text()) + raise Exception( + self.tr("Problem setting as template: ") + query.lastError().text() + ) while query.next(): if query.value(0) == dbName: return True return False - + def createTemplateDatabase(self, version): """ version: edgv version @@ -2733,7 +3453,7 @@ def createTemplateDatabase(self, version): except: pass self.createDatabase(dbName) - + def createDatabase(self, dbName): """ Creates a database with a given name @@ -2742,21 +3462,25 @@ def createDatabase(self, dbName): sql = self.gen.getCreateDatabase(dbName) query = QSqlQuery(self.db) if not query.exec_(sql): - raise Exception(self.tr("Problem creating database: ")+query.lastError().text()) - + raise Exception( + self.tr("Problem creating database: ") + query.lastError().text() + ) + def getTemplateName(self, version): - if version == '2.1.3': - return 'template_edgv_213' - elif version == '2.1.3 Pro' or version == 'EDGV 2.1.3 Pro': - return 'template_edgv_213_pro' - elif version == 'FTer_2a_Ed': - return 'template_edgv_fter_2a_ed' - elif version == '3.0': - return 'template_edgv_3' - elif version in ('EDGV 3.0 Pro', '3.0 Pro'): - return 'template_edgv_3_pro' - - def setDbAsTemplate(self, version = None, dbName = None, setTemplate = True, useTransaction = True): + if version == "2.1.3": + return "template_edgv_213" + elif version == "2.1.3 Pro" or version == "EDGV 2.1.3 Pro": + return "template_edgv_213_pro" + elif version == "FTer_2a_Ed": + return "template_edgv_fter_2a_ed" + elif version == "3.0": + return "template_edgv_3" + elif version in ("EDGV 3.0 Pro", "3.0 Pro"): + return "template_edgv_3_pro" + + def setDbAsTemplate( + self, version=None, dbName=None, setTemplate=True, useTransaction=True + ): self.checkAndOpenDb() if not dbName: dbName = self.getTemplateName(version) @@ -2767,7 +3491,10 @@ def setDbAsTemplate(self, version = None, dbName = None, setTemplate = True, use if not query.exec_(sql): if useTransaction: self.db.rollback() - raise Exception(self.tr("Problem setting database as template: ")+query.lastError().text()) + raise Exception( + self.tr("Problem setting database as template: ") + + query.lastError().text() + ) if useTransaction: self.db.commit() @@ -2776,51 +3503,122 @@ def checkIfTemplate(self, dbName): sql = self.gen.checkIfTemplate(dbName) query = QSqlQuery(sql, self.db) if not query.isActive(): - raise Exception(self.tr("Problem checking template: ")+query.lastError().text()) + raise Exception( + self.tr("Problem checking template: ") + query.lastError().text() + ) while query.next(): return query.value(0) - + def getCreationSqlPath(self, version): currentPath = os.path.dirname(__file__) - edgvPath = '' - if version == '2.1.3': - edgvPath = os.path.join(currentPath,'..','..','..','core','DbModels','PostGIS', '213', 'edgv213.sql') - elif version == '2.1.3 Pro' or version == 'EDGV 2.1.3 Pro': - edgvPath = os.path.join(currentPath,'..','..','..','core','DbModels','PostGIS', '213_Pro', 'edgv213_pro.sql') - elif version == 'FTer_2a_Ed': - edgvPath = os.path.join(currentPath,'..','..','..','core','DbModels','PostGIS', 'FTer_2a_Ed', 'edgvFter_2a_Ed.sql') - elif version == '3.0': - edgvPath = os.path.join(currentPath,'..','..','..','core','DbModels','PostGIS', '3', 'edgv3.sql') - elif version == '3.0 Pro': - edgvPath = os.path.join(currentPath,'..','..','..','core','DbModels','PostGIS', '3_Pro', 'edgv3_pro.sql') - elif version == 'admin': - edgvPath = os.path.join(currentPath,'..','..','..','core','DbModels','PostGIS', 'admin', 'dsgtools_admindb.sql') + edgvPath = "" + if version == "2.1.3": + edgvPath = os.path.join( + currentPath, + "..", + "..", + "..", + "core", + "DbModels", + "PostGIS", + "213", + "edgv213.sql", + ) + elif version == "2.1.3 Pro" or version == "EDGV 2.1.3 Pro": + edgvPath = os.path.join( + currentPath, + "..", + "..", + "..", + "core", + "DbModels", + "PostGIS", + "213_Pro", + "edgv213_pro.sql", + ) + elif version == "FTer_2a_Ed": + edgvPath = os.path.join( + currentPath, + "..", + "..", + "..", + "core", + "DbModels", + "PostGIS", + "FTer_2a_Ed", + "edgvFter_2a_Ed.sql", + ) + elif version == "3.0": + edgvPath = os.path.join( + currentPath, + "..", + "..", + "..", + "core", + "DbModels", + "PostGIS", + "3", + "edgv3.sql", + ) + elif version == "3.0 Pro": + edgvPath = os.path.join( + currentPath, + "..", + "..", + "..", + "core", + "DbModels", + "PostGIS", + "3_Pro", + "edgv3_pro.sql", + ) + elif version == "admin": + edgvPath = os.path.join( + currentPath, + "..", + "..", + "..", + "core", + "DbModels", + "PostGIS", + "admin", + "dsgtools_admindb.sql", + ) return edgvPath - - def getCommandsFromFile(self, edgvPath, epsg = None): + + def getCommandsFromFile(self, edgvPath, epsg=None): """ Gets all sql commands from file """ - file = codecs.open(edgvPath, encoding='utf-8', mode="r") + file = codecs.open(edgvPath, encoding="utf-8", mode="r") sql = file.read() if epsg: - sql = sql.replace('[epsg]', str(epsg)) + sql = sql.replace("[epsg]", str(epsg)) file.close() - commands = sql.split('#') + commands = sql.split("#") return commands - + def getImplementationVersionFromFile(self, edgvVersion): edgvPath = self.getCreationSqlPath(edgvVersion) commands = self.getCommandsFromFile(edgvPath) - searchString = 'INSERT INTO public.db_metadata (edgvversion, dbimplversion) VALUES (' + searchString = ( + "INSERT INTO public.db_metadata (edgvversion, dbimplversion) VALUES (" + ) for command in commands: if searchString in command: - return command.split(searchString)[-1].split(',')[-1].replace(')','').replace("'","") + return ( + command.split(searchString)[-1] + .split(",")[-1] + .replace(")", "") + .replace("'", "") + ) - def setStructureFromSql(self, version, epsg, useTransaction = True, closeAfterUsage = True): + def setStructureFromSql( + self, version, epsg, useTransaction=True, closeAfterUsage=True + ): self.checkAndOpenDb() edgvPath = self.getCreationSqlPath(version) - commands = [i for i in self.getCommandsFromFile(edgvPath, epsg = epsg) if i != ''] + commands = [i for i in self.getCommandsFromFile(edgvPath, epsg=epsg) if i != ""] if useTransaction: self.db.transaction() query = QSqlQuery(self.db) @@ -2829,17 +3627,21 @@ def setStructureFromSql(self, version, epsg, useTransaction = True, closeAfterUs if command and not query.exec_(command): if useTransaction: self.db.rollback() - raise Exception(self.tr('Error on database creation! ')+query.lastError().text()+ self.tr(' Db will be dropped.')) + raise Exception( + self.tr("Error on database creation! ") + + query.lastError().text() + + self.tr(" Db will be dropped.") + ) if useTransaction: self.db.commit() - self.alterSearchPath(version, useTransaction = useTransaction) - self.setDbAsTemplate(version = version, useTransaction = useTransaction) - self.createStyleTable(useTransaction = useTransaction) - #this close is to allow creation from template + self.alterSearchPath(version, useTransaction=useTransaction) + self.setDbAsTemplate(version=version, useTransaction=useTransaction) + self.createStyleTable(useTransaction=useTransaction) + # this close is to allow creation from template if closeAfterUsage: self.db.close() - - def alterSearchPath(self, version, useTransaction = True): + + def alterSearchPath(self, version, useTransaction=True): self.checkAndOpenDb() dbName = self.db.databaseName() sql = self.gen.alterSearchPath(dbName, version) @@ -2847,33 +3649,42 @@ def alterSearchPath(self, version, useTransaction = True): query = QSqlQuery(self.db) if not query.exec_(sql): self.db.rollback() - raise Exception(self.tr("Problem altering search path: ")+query.lastError().text()) + raise Exception( + self.tr("Problem altering search path: ") + query.lastError().text() + ) self.db.commit() - def createFrame(self, type, scale, param, paramDict = dict()): + def createFrame(self, type, scale, param, paramDict=dict()): mi, inom, frame = self.prepareCreateFrame(type, scale, param) - self.insertFrame(scale, mi, inom, frame.asWkb(), paramDict = paramDict) + self.insertFrame(scale, mi, inom, frame.asWkb(), paramDict=paramDict) return frame - + def getUsersFromServer(self): self.checkAndOpenDb() ret = [] sql = self.gen.getUsersFromServer() query = QSqlQuery(sql, self.db) if not query.isActive(): - raise Exception(self.tr("Problem getting users: ")+query.lastError().text()) + raise Exception( + self.tr("Problem getting users: ") + query.lastError().text() + ) while query.next(): ret.append((query.value(0), query.value(1))) return ret - + def reassignAndDropUser(self, user): self.checkAndOpenDb() sql = self.gen.reasignAndDropUser(user) query = QSqlQuery(self.db) if not query.exec_(sql): - raise Exception(self.tr('Problem removing user: ') +user+'\n'+query.lastError().text()) - - def removeFeatureFlags(self, layer, featureId, processName, useTransaction = True): + raise Exception( + self.tr("Problem removing user: ") + + user + + "\n" + + query.lastError().text() + ) + + def removeFeatureFlags(self, layer, featureId, processName, useTransaction=True): """ Removes flags for a specific layer, feature id and process name layer: layer name @@ -2888,11 +3699,13 @@ def removeFeatureFlags(self, layer, featureId, processName, useTransaction = Tru if not query.exec_(sql): if useTransaction: self.db.rollback() - raise Exception(self.tr('Problem deleting flag: ') + query.lastError().text()) + raise Exception( + self.tr("Problem deleting flag: ") + query.lastError().text() + ) if useTransaction: self.db.commit() - - def removeEmptyGeometries(self, layer, geometryColumn, useTransaction = True): + + def removeEmptyGeometries(self, layer, geometryColumn, useTransaction=True): """ Removes empty geometries from layer layer: layer name @@ -2906,10 +3719,13 @@ def removeEmptyGeometries(self, layer, geometryColumn, useTransaction = True): if not query.exec_(sql): if useTransaction: self.db.rollback() - raise Exception(self.tr('Problem removing empty geometries: ') + query.lastError().text()) + raise Exception( + self.tr("Problem removing empty geometries: ") + + query.lastError().text() + ) if useTransaction: self.db.commit() - + def getParamsFromConectedDb(self): self.checkAndOpenDb() host = self.db.hostName() @@ -2923,11 +3739,13 @@ def createAdminDb(self): Creates a database with a given name """ self.checkAndOpenDb() - sql = self.gen.getCreateDatabase('dsgtools_admindb') + sql = self.gen.getCreateDatabase("dsgtools_admindb") query = QSqlQuery(self.db) if not query.exec_(sql): - raise Exception(self.tr("Problem creating database: ")+query.lastError().text()) - + raise Exception( + self.tr("Problem creating database: ") + query.lastError().text() + ) + def hasAdminDb(self): """ Checks if server has a dsgtools_admindb @@ -2936,12 +3754,14 @@ def hasAdminDb(self): sql = self.gen.hasAdminDb() query = QSqlQuery(sql, self.db) if not query.isActive(): - raise Exception(self.tr("Problem looking for admindb: ")+query.lastError().text()) + raise Exception( + self.tr("Problem looking for admindb: ") + query.lastError().text() + ) while query.next(): if query.value(0): return True return False - + def getRolesDict(self): """ Gets a dict with the format: 'dbname':{[-list of roles-]} @@ -2950,27 +3770,34 @@ def getRolesDict(self): sql = self.gen.getRolesDict() query = QSqlQuery(sql, self.db) if not query.isActive(): - raise Exception(self.tr("Problem getting roles dict: ")+query.lastError().text()) + raise Exception( + self.tr("Problem getting roles dict: ") + query.lastError().text() + ) rolesDict = dict() while query.next(): aux = json.loads(query.value(0)) - if aux['dbname'] not in list(rolesDict.keys()): - rolesDict[aux['dbname']] = [] - rolesDict[aux['dbname']].append(aux['rolename']) + if aux["dbname"] not in list(rolesDict.keys()): + rolesDict[aux["dbname"]] = [] + rolesDict[aux["dbname"]].append(aux["rolename"]) return rolesDict - + def insertIntoPermissionProfile(self, name, jsondict, edgvversion): """ Inserts into public.permission_profile on dsgtools_admindb (name, jsondict, edgvversion) """ self.checkAndOpenDb() - if self.db.databaseName() != 'dsgtools_admindb': - raise Exception(self.tr('Error! Operation not defined for non dsgtools_admindb')) + if self.db.databaseName() != "dsgtools_admindb": + raise Exception( + self.tr("Error! Operation not defined for non dsgtools_admindb") + ) sql = self.gen.insertIntoPermissionProfile(name, jsondict, edgvversion) query = QSqlQuery(self.db) if not query.exec_(sql): - raise Exception(self.tr("Problem inserting into permission profile: ")+query.lastError().text()) - + raise Exception( + self.tr("Problem inserting into permission profile: ") + + query.lastError().text() + ) + def dropRoleOnDatabase(self, roleName): """ Drops role using drop owned by and drop role. @@ -2980,8 +3807,13 @@ def dropRoleOnDatabase(self, roleName): sql = self.gen.dropRoleOnDatabase(roleName) query = QSqlQuery(self.db) if not query.exec_(sql): - raise Exception(self.tr("Problem dropping profile: ")+ roleName + ' :' + query.lastError().text()) - + raise Exception( + self.tr("Problem dropping profile: ") + + roleName + + " :" + + query.lastError().text() + ) + def getRoleFromAdminDb(self, roleName, edgvVersion): """ Gets role from public.permission_profile @@ -2990,10 +3822,13 @@ def getRoleFromAdminDb(self, roleName, edgvVersion): sql = self.gen.getPermissionProfile(roleName, edgvVersion) query = QSqlQuery(sql, self.db) if not query.isActive(): - raise Exception(self.tr("Problem getting roles from adminDb: ")+query.lastError().text()) + raise Exception( + self.tr("Problem getting roles from adminDb: ") + + query.lastError().text() + ) while query.next(): return query.value(0) - + def getAllRolesFromAdminDb(self): """ Gets role from public.permission_profile and returns a dict with format {edgvVersion:[-list of roles-]} @@ -3002,13 +3837,16 @@ def getAllRolesFromAdminDb(self): sql = self.gen.getAllPermissionProfiles() query = QSqlQuery(sql, self.db) if not query.isActive(): - raise Exception(self.tr("Problem getting all roles from adminDb: ")+query.lastError().text()) + raise Exception( + self.tr("Problem getting all roles from adminDb: ") + + query.lastError().text() + ) allRolesDict = dict() while query.next(): aux = json.loads(query.value(0)) - allRolesDict[aux['edgvversion']] = aux['profiles'] + allRolesDict[aux["edgvversion"]] = aux["profiles"] return allRolesDict - + def deletePermissionProfile(self, name, edgvversion): """ Deletes profile from public.permission_profiles @@ -3017,38 +3855,49 @@ def deletePermissionProfile(self, name, edgvversion): sql = self.gen.deletePermissionProfile(name, edgvversion) query = QSqlQuery(self.db) if not query.exec_(sql): - raise Exception(self.tr("Problem deleting permission profile: ")+query.lastError().text()) - + raise Exception( + self.tr("Problem deleting permission profile: ") + + query.lastError().text() + ) + def getGrantedRolesDict(self): """ Gets a dict in the format: - { roleName : [-list of users-] } + { roleName : [-list of users-] } """ self.checkAndOpenDb() sql = self.gen.getRolesWithGrantedUsers() query = QSqlQuery(sql, self.db) if not query.isActive(): - raise Exception(self.tr("Problem getting granted roles dict: ")+query.lastError().text()) + raise Exception( + self.tr("Problem getting granted roles dict: ") + + query.lastError().text() + ) grantedRolesDict = dict() while query.next(): aux = json.loads(query.value(0)) - if aux['profile'] not in list(grantedRolesDict.keys()): - grantedRolesDict[aux['profile']] = [] - for user in aux['users']: - if user not in grantedRolesDict[aux['profile']]: - grantedRolesDict[aux['profile']].append(user) + if aux["profile"] not in list(grantedRolesDict.keys()): + grantedRolesDict[aux["profile"]] = [] + for user in aux["users"]: + if user not in grantedRolesDict[aux["profile"]]: + grantedRolesDict[aux["profile"]].append(user) return grantedRolesDict - + def updatePermissionProfile(self, name, edgvVersion, newjsondict): """ Updates public.permission_profile with new definition. """ self.checkAndOpenDb() - sql = self.gen.updateRecordFromPropertyTable('Permission', name, edgvVersion, newjsondict) + sql = self.gen.updateRecordFromPropertyTable( + "Permission", name, edgvVersion, newjsondict + ) query = QSqlQuery(self.db) if not query.exec_(sql): - raise Exception(self.tr("Problem updating permission profile: ")+query.lastError().text()) - + raise Exception( + self.tr("Problem updating permission profile: ") + + query.lastError().text() + ) + def getDomainTables(self): """ Lists all domain tables available. @@ -3057,12 +3906,14 @@ def getDomainTables(self): sql = self.gen.getDomainTables() query = QSqlQuery(sql, self.db) if not query.isActive(): - raise Exception(self.tr("Problem getting domain tables: ")+query.lastError().text()) + raise Exception( + self.tr("Problem getting domain tables: ") + query.lastError().text() + ) domainList = [] while query.next(): domainList.append(query.value(0)) return domainList - + def getGeometricSchemaList(self): """ Lists all schemas with geometries. @@ -3071,12 +3922,15 @@ def getGeometricSchemaList(self): sql = self.gen.getGeometricSchemaList() query = QSqlQuery(sql, self.db) if not query.isActive(): - raise Exception(self.tr("Problem getting geometric schema list: ")+query.lastError().text()) + raise Exception( + self.tr("Problem getting geometric schema list: ") + + query.lastError().text() + ) schemaList = [] while query.next(): schemaList.append(query.value(0)) return schemaList - + def getGeometricTableListFromSchema(self, schema): """ Lists all tables with geometries from schema @@ -3085,19 +3939,32 @@ def getGeometricTableListFromSchema(self, schema): sql = self.gen.getGeometricTableListFromSchema(schema) query = QSqlQuery(sql, self.db) if not query.isActive(): - raise Exception(self.tr("Problem getting geometric table list: ")+query.lastError().text()) + raise Exception( + self.tr("Problem getting geometric table list: ") + + query.lastError().text() + ) tableList = [] while query.next(): tableList.append(query.value(1)) return tableList - - def getParentGeomTables(self, getTuple = False, getFullName = False, primitiveFilter = [], showViews = False, hideCentroids = True, getDictList = False): + + def getParentGeomTables( + self, + getTuple=False, + getFullName=False, + primitiveFilter=[], + showViews=False, + hideCentroids=True, + getDictList=False, + ): """ Lists all tables with geometries from schema that are parents. """ self.checkAndOpenDb() - layerDictList = self.getGeomColumnDictV2(showViews = showViews, hideCentroids = hideCentroids) - geomTables = [i['tableName'] for i in list(layerDictList.values())] + layerDictList = self.getGeomColumnDictV2( + showViews=showViews, hideCentroids=hideCentroids + ) + geomTables = [i["tableName"] for i in list(layerDictList.values())] inhDict = self.getInheritanceDict() # final parent list @@ -3116,9 +3983,13 @@ def getParentGeomTables(self, getTuple = False, getFullName = False, primitiveFi # we must check tables orphan tables (no parent and no child) # if a table like this is a geometry table it should be stored for geomTable in geomTables: - if geomTable not in childList and geomTable not in parentList and geomTable not in parentGeomTables: + if ( + geomTable not in childList + and geomTable not in parentList + and geomTable not in parentGeomTables + ): parentGeomTables.append(geomTable) - + # analyzing only the inheritance information for parent in list(inhDict.keys()): if parent in geomTables: @@ -3129,48 +4000,67 @@ def getParentGeomTables(self, getTuple = False, getFullName = False, primitiveFi # if the parent is not a geometry table all its children should be stored for child in inhDict[parent]: if child not in parentGeomTables: - parentGeomTables.append(child) + parentGeomTables.append(child) - #filters in case of filter + # filters in case of filter if primitiveFilter != []: - filterList = [i['tableName'] for i in list(self.getGeomColumnDictV2(showViews = showViews, hideCentroids = hideCentroids, primitiveFilter = primitiveFilter).values())] + filterList = [ + i["tableName"] + for i in list( + self.getGeomColumnDictV2( + showViews=showViews, + hideCentroids=hideCentroids, + primitiveFilter=primitiveFilter, + ).values() + ) + ] aux = [i for i in parentGeomTables if i in filterList] parentGeomTables = aux parentGeomTables.sort() if getDictList: - filteredDictList = [i for i in list(layerDictList.values()) if i['tableName'] in parentGeomTables] + filteredDictList = [ + i + for i in list(layerDictList.values()) + if i["tableName"] in parentGeomTables + ] return filteredDictList - #output types + # output types if getFullName: parentFullList = [] for parent in parentGeomTables: schema = self.getTableSchemaFromDb(parent) - if schema not in ['views', 'validation'] and schema: - parentFullList.append( schema+'.'+parent ) + if schema not in ["views", "validation"] and schema: + parentFullList.append(schema + "." + parent) return parentFullList if not getTuple: - return [i for i in parentGeomTables if self.getTableSchemaFromDb(i) not in ['views', 'validation'] ] + return [ + i + for i in parentGeomTables + if self.getTableSchemaFromDb(i) not in ["views", "validation"] + ] else: parentTupleList = [] for parent in parentGeomTables: schema = self.getTableSchemaFromDb(parent) - if schema not in ['views', 'validation']: - parentTupleList.append( (schema, parent) ) + if schema not in ["views", "validation"]: + parentTupleList.append((schema, parent)) return parentTupleList - + def getInheritanceDict(self): self.checkAndOpenDb() sql = self.gen.getInheritanceDict() query = QSqlQuery(sql, self.db) inhDict = dict() if not query.isActive(): - raise Exception(self.tr("Problem getting inheritance: ")+query.lastError().text()) + raise Exception( + self.tr("Problem getting inheritance: ") + query.lastError().text() + ) while query.next(): aux = json.loads(query.value(0)) - inhDict[aux['parentname']] = aux['childname'] + inhDict[aux["parentname"]] = aux["childname"] return inhDict - - def getInheritanceBloodLine(self, parent, inhDict = None): + + def getInheritanceBloodLine(self, parent, inhDict=None): """ Lists all tables that have parent as an ancestor. """ @@ -3179,10 +4069,10 @@ def getInheritanceBloodLine(self, parent, inhDict = None): bloodLine = [] self.utils.getRecursiveInheritance(parent, bloodLine, inhDict) return bloodLine - + def getFullBloodLineDict(self, candidate): pass - + def getAttributeListFromTable(self, schema, tableName): """ Lists all attributes from table. @@ -3191,24 +4081,28 @@ def getAttributeListFromTable(self, schema, tableName): sql = self.gen.getAttributeListFromTable(schema, tableName) query = QSqlQuery(sql, self.db) if not query.isActive(): - raise Exception(self.tr("Problem getting attribute list: ")+query.lastError().text()) + raise Exception( + self.tr("Problem getting attribute list: ") + query.lastError().text() + ) attributeList = [] while query.next(): attributeList.append(query.value(0)) return attributeList - + def getAttributeJsonFromDb(self): self.checkAndOpenDb() sql = self.gen.getAttributeDictFromDb() query = QSqlQuery(sql, self.db) if not query.isActive(): - raise Exception(self.tr("Problem getting attribute list: ")+query.lastError().text()) + raise Exception( + self.tr("Problem getting attribute list: ") + query.lastError().text() + ) attributeJson = [] while query.next(): attributeJson.append(json.loads(query.value(0))) return attributeJson - - def getAllDomainValues(self, domainTableList = []): + + def getAllDomainValues(self, domainTableList=[]): self.checkAndOpenDb() if domainTableList == []: domainTableList = self.getDomainTables() @@ -3222,12 +4116,12 @@ def getAllDomainValues(self, domainTableList = []): valueList.append(value) valueList.sort() return valueList - + def getInheritanceTreeDict(self): self.checkAndOpenDb() inhDict = self.getInheritanceDict() layerList = self.listGeomClassesFromDatabase() - geomTables = [i.split('.')[-1] for i in layerList] + geomTables = [i.split(".")[-1] for i in layerList] inhTreeDict = dict() for parent in list(inhDict.keys()): self.utils.getRecursiveInheritanceTreeDict(parent, inhTreeDict, inhDict) @@ -3242,19 +4136,19 @@ def getInheritanceTreeDict(self): for item in blackList: inhTreeDict.pop(item) childBlackList = [] - self.utils.getAllItemsInDict(inhTreeDict,childBlackList) + self.utils.getAllItemsInDict(inhTreeDict, childBlackList) for geomTable in geomTables: if geomTable not in childBlackList: schema = self.getTableSchemaFromDb(geomTable) - if schema not in ['views', 'validation']: + if schema not in ["views", "validation"]: inhTreeDict[geomTable] = dict() - r = {'root':inhTreeDict} + r = {"root": inhTreeDict} return r - + # def getInheritanceConstraintDict(self): # """ # Returns a dict in the form: - # {'tableName':{'attributeName': {'tableName','constraintName', 'filter'} + # {'tableName':{'attributeName': {'tableName','constraintName', 'filter'} # } # } # """ @@ -3272,7 +4166,7 @@ def getInheritanceTreeDict(self): # inhConstrDict[tableName] = dict() # defList = queryResult['array_agg'] # for value in defList: - # constraintName = value['f1'] + # constraintName = value['f1'] # constraintDef = value['f2'] # attrName = constraintName.split('_')[-2] # currTableName = constraintName.split('_'+attrName)[0] @@ -3284,7 +4178,7 @@ def getInheritanceTreeDict(self): # if currTag not in inhConstrDict[tableName][attrName]: # inhConstrDict[tableName][attrName].append(currTag) # return inhConstrDict - + def getDefaultFromDb(self, schema, tableName, attrName): """ Gets default value from table @@ -3293,23 +4187,34 @@ def getDefaultFromDb(self, schema, tableName, attrName): sql = self.gen.getDefaultFromDb(schema, tableName, attrName) query = QSqlQuery(sql, self.db) if not query.isActive(): - raise Exception(self.tr("Problem getting default from db: ")+query.lastError().text()) + raise Exception( + self.tr("Problem getting default from db: ") + query.lastError().text() + ) while query.next(): return query.value(0) - + def insertSettingIntoAdminDb(self, settingType, name, jsondict, edgvversion): """ Inserts setting into dsgtools_admindb (name, jsondict, edgvversion), according to settingType """ self.checkAndOpenDb() - if self.db.databaseName() != 'dsgtools_admindb': - raise Exception(self.tr('Error! Operation not defined for non dsgtools_admindb')) - sql = self.gen.insertSettingIntoAdminDb(settingType, name, jsondict, edgvversion) + if self.db.databaseName() != "dsgtools_admindb": + raise Exception( + self.tr("Error! Operation not defined for non dsgtools_admindb") + ) + sql = self.gen.insertSettingIntoAdminDb( + settingType, name, jsondict, edgvversion + ) query = QSqlQuery(self.db) if not query.exec_(sql): - raise Exception(self.tr("Problem inserting property ")+settingType+self.tr(' into dsgtools_admindb: ')+query.lastError().text()) - + raise Exception( + self.tr("Problem inserting property ") + + settingType + + self.tr(" into dsgtools_admindb: ") + + query.lastError().text() + ) + def getSettingFromAdminDb(self, settingType, settingName, edgvVersion): """ Gets role from public.permission_profile @@ -3318,19 +4223,25 @@ def getSettingFromAdminDb(self, settingType, settingName, edgvVersion): sql = self.gen.getSettingFromAdminDb(settingType, settingName, edgvVersion) query = QSqlQuery(sql, self.db) if not query.isActive(): - raise Exception(self.tr("Problem getting setting from adminDb: ")+query.lastError().text()) + raise Exception( + self.tr("Problem getting setting from adminDb: ") + + query.lastError().text() + ) while query.next(): return query.value(0) - + def getSettingVersion(self, settingType, settingName): self.checkAndOpenDb() sql = self.gen.getSettingVersion(settingType, settingName) query = QSqlQuery(sql, self.db) if not query.isActive(): - raise Exception(self.tr("Problem getting setting from adminDb: ")+query.lastError().text()) + raise Exception( + self.tr("Problem getting setting from adminDb: ") + + query.lastError().text() + ) while query.next(): return query.value(0) - + def getAllSettingsFromAdminDb(self, settingType): """ Gets role from public.permission_profile and returns a dict with format {edgvVersion:[-list of roles-]} @@ -3341,13 +4252,16 @@ def getAllSettingsFromAdminDb(self, settingType): sql = self.gen.getAllSettingsFromAdminDb(settingType) query = QSqlQuery(sql, self.db) if not query.isActive(): - raise Exception(self.tr("Problem getting settings from adminDb: ")+query.lastError().text()) + raise Exception( + self.tr("Problem getting settings from adminDb: ") + + query.lastError().text() + ) allRolesDict = dict() while query.next(): aux = json.loads(query.value(0)) - allRolesDict[aux['edgvversion']] = aux['settings'] + allRolesDict[aux["edgvversion"]] = aux["settings"] return allRolesDict - + def deleteSettingFromAdminDb(self, settingType, name, edgvversion): """ Deletes profile from public.permission_profiles @@ -3356,9 +4270,12 @@ def deleteSettingFromAdminDb(self, settingType, name, edgvversion): sql = self.gen.deleteSettingFromAdminDb(settingType, name, edgvversion) query = QSqlQuery(self.db) if not query.exec_(sql): - raise Exception(self.tr("Problem deleting permission setting: ")+query.lastError().text()) + raise Exception( + self.tr("Problem deleting permission setting: ") + + query.lastError().text() + ) - def upgradePostgis(self, useTransaction = True): + def upgradePostgis(self, useTransaction=True): self.checkAndOpenDb() updateDict = self.getPostgisVersion() if updateDict != dict(): @@ -3369,67 +4286,90 @@ def upgradePostgis(self, useTransaction = True): if not query.exec_(sql): if useTransaction: self.db.rollback() - raise Exception(self.tr("Problem upgrading postgis: ")+query.lastError().text()) + raise Exception( + self.tr("Problem upgrading postgis: ") + query.lastError().text() + ) if useTransaction: self.db.commit() - + def getPostgisVersion(self): self.checkAndOpenDb() sql = self.gen.getPostgisVersion() query = QSqlQuery(sql, self.db) if not query.isActive(): - raise Exception(self.tr("Problem getting postgis version: ")+query.lastError().text()) + raise Exception( + self.tr("Problem getting postgis version: ") + query.lastError().text() + ) updateDict = dict() while query.next(): defaultVersion = query.value(1) installedVersion = query.value(2) - if defaultVersion != installedVersion and installedVersion not in ['', None]: - updateDict[query.value(0)] = {'defaultVersion':defaultVersion, 'installedVersion':installedVersion} + if defaultVersion != installedVersion and installedVersion not in [ + "", + None, + ]: + updateDict[query.value(0)] = { + "defaultVersion": defaultVersion, + "installedVersion": installedVersion, + } return updateDict - + def getCustomizationPerspectiveDict(self, perspective): self.checkAndOpenDb() sql = self.gen.getCustomizationPerspectiveDict(perspective) query = QSqlQuery(sql, self.db) if not query.isActive(): - raise Exception(self.tr("Problem getting applied customizations: ")+query.lastError().text()) + raise Exception( + self.tr("Problem getting applied customizations: ") + + query.lastError().text() + ) customDict = dict() while query.next(): jsonDict = json.loads(query.value(0)) - customDict[jsonDict['name']] = jsonDict['array_agg'] + customDict[jsonDict["name"]] = jsonDict["array_agg"] return customDict - def getPropertyPerspectiveDict(self, settingType, perspective, versionFilter = None): + def getPropertyPerspectiveDict(self, settingType, perspective, versionFilter=None): self.checkAndOpenDb() - sql = self.gen.getPropertyPerspectiveDict(settingType, perspective, versionFilter) + sql = self.gen.getPropertyPerspectiveDict( + settingType, perspective, versionFilter + ) query = QSqlQuery(sql, self.db) if not query.isActive(): - raise Exception(self.tr("Problem getting applied customizations: ")+query.lastError().text()) + raise Exception( + self.tr("Problem getting applied customizations: ") + + query.lastError().text() + ) customDict = dict() while query.next(): jsonDict = json.loads(query.value(0)) - customDict[jsonDict['name']] = jsonDict['array_agg'] + customDict[jsonDict["name"]] = jsonDict["array_agg"] return customDict - - def createPropertyTable(self, settingType, useTransaction = True, isAdminDb = False): + + def createPropertyTable(self, settingType, useTransaction=True, isAdminDb=False): self.checkAndOpenDb() if useTransaction: self.db.transaction() - createSql = self.gen.createPropertyTable(settingType, isAdminDb = isAdminDb) + createSql = self.gen.createPropertyTable(settingType, isAdminDb=isAdminDb) query = QSqlQuery(self.db) if not query.exec_(createSql): if useTransaction: self.db.rollback() - raise Exception(self.tr('Problem creating Setting table: ') + query.lastError().text()) + raise Exception( + self.tr("Problem creating Setting table: ") + query.lastError().text() + ) if useTransaction: self.db.commit() - + def checkIfTableExists(self, schema, tableName): self.checkAndOpenDb() sql = self.gen.checkIfTableExists(schema, tableName) query = QSqlQuery(sql, self.db) if not query.isActive(): - raise Exception(self.tr("Problem getting checking if table exists: ")+query.lastError().text()) + raise Exception( + self.tr("Problem getting checking if table exists: ") + + query.lastError().text() + ) while query.next(): if query.value(0): return True @@ -3437,27 +4377,32 @@ def checkIfTableExists(self, schema, tableName): def checkIfExistsConfigTable(self, settingType): settingTable = self.gen.getSettingTable(settingType) - return self.checkIfTableExists('public', settingTable) - + return self.checkIfTableExists("public", settingTable) + def getRecordFromAdminDb(self, settingType, propertyName, edgvVersion): self.checkAndOpenDb() sql = self.gen.getRecordFromAdminDb(settingType, propertyName, edgvVersion) query = QSqlQuery(sql, self.db) if not query.isActive(): - raise Exception(self.tr("Problem getting getting record from adminDb: ")+query.lastError().text()) + raise Exception( + self.tr("Problem getting getting record from adminDb: ") + + query.lastError().text() + ) retDict = dict() while query.next(): - retDict['id'] = query.value(0) - retDict['name'] = query.value(1) - retDict['jsondict'] = query.value(2) - retDict['edgvversion'] = query.value(3) - #yes, this return is inside the while. Why? Because I said so! + retDict["id"] = query.value(0) + retDict["name"] = query.value(1) + retDict["jsondict"] = query.value(2) + retDict["edgvversion"] = query.value(3) + # yes, this return is inside the while. Why? Because I said so! return retDict - - def insertRecordInsidePropertyTable(self, settingType, settingDict, edgvVersion, useTransaction = False): + + def insertRecordInsidePropertyTable( + self, settingType, settingDict, edgvVersion, useTransaction=False + ): self.checkAndOpenDb() if edgvVersion != self.getDatabaseVersion(): - raise Exception(self.tr('Invalid property with database version.')) + raise Exception(self.tr("Invalid property with database version.")) if useTransaction: self.db.transaction() createSql = self.gen.insertRecordInsidePropertyTable(settingType, settingDict) @@ -3465,18 +4410,24 @@ def insertRecordInsidePropertyTable(self, settingType, settingDict, edgvVersion, if not query.exec_(createSql): if useTransaction: self.db.rollback() - raise Exception(self.tr('Problem inserting record inside property table: ') + query.lastError().text()) + raise Exception( + self.tr("Problem inserting record inside property table: ") + + query.lastError().text() + ) if useTransaction: self.db.commit() - - def getPropertyDict(self, settingType, getOnlySameVersion = False): + + def getPropertyDict(self, settingType, getOnlySameVersion=False): self.checkAndOpenDb() if getOnlySameVersion: myEdgvVersion = self.getDatabaseVersion() sql = self.gen.getAllPropertiesFromDb(settingType) query = QSqlQuery(sql, self.db) if not query.isActive(): - raise Exception(self.tr("Problem getting getting property dict: ")+query.lastError().text()) + raise Exception( + self.tr("Problem getting getting property dict: ") + + query.lastError().text() + ) propertyDict = dict() while query.next(): edgvVersion = query.value(0) @@ -3489,70 +4440,101 @@ def getPropertyDict(self, settingType, getOnlySameVersion = False): propertyDict[edgvVersion] = dict() propertyDict[edgvVersion][name] = jsonDict return propertyDict - - def insertInstalledRecordIntoAdminDb(self, settingType, recDict, dbOid, useTransaction = False): + + def insertInstalledRecordIntoAdminDb( + self, settingType, recDict, dbOid, useTransaction=False + ): self.checkAndOpenDb() if useTransaction: self.db.transaction() - createSql = self.gen.insertInstalledRecordIntoAdminDb(settingType, recDict, dbOid) + createSql = self.gen.insertInstalledRecordIntoAdminDb( + settingType, recDict, dbOid + ) query = QSqlQuery(self.db) if not query.exec_(createSql): if useTransaction: self.db.rollback() - raise Exception(self.tr('Problem inserting installed record into adminDb: ') + query.lastError().text()) + raise Exception( + self.tr("Problem inserting installed record into adminDb: ") + + query.lastError().text() + ) if useTransaction: self.db.commit() - - def removeRecordFromPropertyTable(self, settingType, configName, edgvVersion, useTransaction = False): + + def removeRecordFromPropertyTable( + self, settingType, configName, edgvVersion, useTransaction=False + ): self.checkAndOpenDb() if useTransaction: self.db.transaction() - createSql = self.gen.removeRecordFromPropertyTable(settingType, configName, edgvVersion) + createSql = self.gen.removeRecordFromPropertyTable( + settingType, configName, edgvVersion + ) query = QSqlQuery(self.db) if not query.exec_(createSql): if useTransaction: self.db.rollback() - raise Exception(self.tr('Problem removing installed record into db: ') + query.lastError().text()) + raise Exception( + self.tr("Problem removing installed record into db: ") + + query.lastError().text() + ) if useTransaction: self.db.commit() - def updateRecordFromPropertyTable(self, settingType, configName, edgvVersion, jsonDict, useTransaction = False): + def updateRecordFromPropertyTable( + self, settingType, configName, edgvVersion, jsonDict, useTransaction=False + ): self.checkAndOpenDb() if useTransaction: self.db.transaction() - if isinstance(jsonDict,dict): + if isinstance(jsonDict, dict): jsonDict = json.dumps(jsonDict, sort_keys=True, indent=4) - createSql = self.gen.updateRecordFromPropertyTable(settingType, configName, edgvVersion, jsonDict) + createSql = self.gen.updateRecordFromPropertyTable( + settingType, configName, edgvVersion, jsonDict + ) query = QSqlQuery(self.db) if not query.exec_(createSql): if useTransaction: self.db.rollback() - raise Exception(self.tr('Problem removing installed record into db: ') + query.lastError().text()) + raise Exception( + self.tr("Problem removing installed record into db: ") + + query.lastError().text() + ) if useTransaction: self.db.commit() - - def uninstallPropertyOnAdminDb(self, settingType, configName, edgvVersion, useTransaction = False, dbName = None): + + def uninstallPropertyOnAdminDb( + self, settingType, configName, edgvVersion, useTransaction=False, dbName=None + ): self.checkAndOpenDb() if useTransaction: self.db.transaction() - createSql = self.gen.uninstallPropertyOnAdminDb(settingType, configName, edgvVersion, dbName = dbName) + createSql = self.gen.uninstallPropertyOnAdminDb( + settingType, configName, edgvVersion, dbName=dbName + ) query = QSqlQuery(self.db) if not query.exec_(createSql): if useTransaction: self.db.rollback() - raise Exception(self.tr('Problem removing installed record into db: ') + query.lastError().text()) + raise Exception( + self.tr("Problem removing installed record into db: ") + + query.lastError().text() + ) if useTransaction: self.db.commit() - + def getPrimaryKeyColumn(self, tableName): self.checkAndOpenDb() sql = self.gen.getPrimaryKeyColumn(tableName) query = QSqlQuery(sql, self.db) if not query.isActive(): - raise Exception(self.tr("Problem getting primary key column: ")+query.lastError().text()) + raise Exception( + self.tr("Problem getting primary key column: ") + + query.lastError().text() + ) while query.next(): return query.value(0) - + def dropAllConections(self, dbName): """ Terminates all database conections @@ -3562,26 +4544,39 @@ def dropAllConections(self, dbName): sql = self.gen.dropAllConections(dbName) query = QSqlQuery(self.db) if not query.exec_(sql): - raise Exception(self.tr('Problem dropping database conections: ') + query.lastError().text()) - - def getAttributesFromTable(self, tableSchema, tableName, typeFilter = [], returnType = 'list'): + raise Exception( + self.tr("Problem dropping database conections: ") + + query.lastError().text() + ) + + def getAttributesFromTable( + self, tableSchema, tableName, typeFilter=[], returnType="list" + ): """ Gets attributes from "tableSchema"."tableName" according to typeFilter """ self.checkAndOpenDb() - sql = self.gen.getAttributesFromTable(tableSchema, tableName, typeFilter = typeFilter) + sql = self.gen.getAttributesFromTable( + tableSchema, tableName, typeFilter=typeFilter + ) query = QSqlQuery(sql, self.db) if not query.isActive(): - raise Exception(self.tr("Problem getting attributes from table {0}.{1}: {2}").format(tableSchema, tableName, query.lastError().text())) + raise Exception( + self.tr("Problem getting attributes from table {0}.{1}: {2}").format( + tableSchema, tableName, query.lastError().text() + ) + ) returnStruct = [] while query.next(): - if returnType == 'list': + if returnType == "list": returnStruct.append(query.value(0)) else: - returnStruct.append({'attrName':query.value(0), 'attrType':query.value(1)}) + returnStruct.append( + {"attrName": query.value(0), "attrType": query.value(1)} + ) return returnStruct - def checkAndCreatePostGISAddonsFunctions(self, useTransaction = True): + def checkAndCreatePostGISAddonsFunctions(self, useTransaction=True): """ Checks if PostGIS Add-ons functions are installed in the PostgreSQL choosed server. If not, it creates the functions based on our git submodule (ext_dep folder) @@ -3590,17 +4585,21 @@ def checkAndCreatePostGISAddonsFunctions(self, useTransaction = True): sql = self.gen.checkPostGISAddonsInstallation() query = QSqlQuery(sql, self.db) if not query.isActive(): - raise Exception(self.tr('Problem creating structure: ')+query.lastError().text()) + raise Exception( + self.tr("Problem creating structure: ") + query.lastError().text() + ) created = True while query.next(): if query.value(0) == 0: created = False if not created: current_dir = os.path.dirname(__file__) - sql_file_path = os.path.join(current_dir, '..', '..', 'ext_dep', 'postgisaddon', 'postgis_addons.sql') + sql_file_path = os.path.join( + current_dir, "..", "..", "ext_dep", "postgisaddon", "postgis_addons.sql" + ) self.runSqlFromFile(sql_file_path, useTransaction) - def createAndPopulateCoverageTempTable(self, coverageLayer, useTransaction = True): + def createAndPopulateCoverageTempTable(self, coverageLayer, useTransaction=True): """ Creates and populates a postgis table with features that compose the coverage layer """ @@ -3608,33 +4607,38 @@ def createAndPopulateCoverageTempTable(self, coverageLayer, useTransaction = Tru if useTransaction: self.db.transaction() query = QSqlQuery(self.db) - #getting srid from something like 'EPSG:31983' - srid = coverageLayer.crs().authid().split(':')[-1] - #complete table name - tableName = 'validation.coverage' + # getting srid from something like 'EPSG:31983' + srid = coverageLayer.crs().authid().split(":")[-1] + # complete table name + tableName = "validation.coverage" sql = self.gen.createCoverageTempTable(srid) if not query.exec_(sql): if useTransaction: self.db.rollback() - raise Exception(self.tr('Problem creating coverage temp table: ') + query.lastError().text()) + raise Exception( + self.tr("Problem creating coverage temp table: ") + + query.lastError().text() + ) for feat in coverageLayer.getFeatures(): # getting only the needed attribute values - featid = feat['featid'] - classname = feat['classname'] + featid = feat["featid"] + classname = feat["classname"] if not feat.geometry(): continue geometry = binascii.hexlify(feat.geometry().asWkb()) # values list and attributes list values = [featid, classname, geometry] - attributes = ['featid', 'classname', 'geom'] - # preparing + attributes = ["featid", "classname", "geom"] + # preparing prepareValues = [] for attr in attributes: - if attr == 'geom': - prepareValues.append("""ST_SetSRID(ST_Multi(:{0}),{1})""".format(attr,str(srid))) + if attr == "geom": + prepareValues.append( + """ST_SetSRID(ST_Multi(:{0}),{1})""".format(attr, str(srid)) + ) else: - prepareValues.append(':'+attr) - #getting sql + prepareValues.append(":" + attr) + # getting sql insertSql = self.gen.populateTempTable(tableName, attributes, prepareValues) query.prepare(insertSql) # binding my values to avoid injections @@ -3644,16 +4648,22 @@ def createAndPopulateCoverageTempTable(self, coverageLayer, useTransaction = Tru if not query.exec_(): if useTransaction: self.db.rollback() - raise Exception(self.tr('Problem populating coverage temp table: ') + query.lastError().text()) - indexSql = self.gen.createSpatialIndex(tableName, 'geom') + raise Exception( + self.tr("Problem populating coverage temp table: ") + + query.lastError().text() + ) + indexSql = self.gen.createSpatialIndex(tableName, "geom") if not query.exec_(indexSql): if useTransaction: self.db.rollback() - raise Exception(self.tr('Problem creating spatial index on coverage temp table: ') + query.lastError().text()) + raise Exception( + self.tr("Problem creating spatial index on coverage temp table: ") + + query.lastError().text() + ) if useTransaction: - self.db.commit() + self.db.commit() - def getGapsAndOverlapsRecords(self, frameTable, geomColumn, useTransaction = True): + def getGapsAndOverlapsRecords(self, frameTable, geomColumn, useTransaction=True): """ Identify gaps and overlaps in the coverage layer """ @@ -3663,18 +4673,24 @@ def getGapsAndOverlapsRecords(self, frameTable, geomColumn, useTransaction = Tru sql = self.gen.checkCoverageForGapsWithFrame(frameTable, geomColumn) query = QSqlQuery(sql, self.db) if not query.isActive(): - raise Exception(self.tr("Problem getting gaps: ")+query.lastError().text()) + raise Exception( + self.tr("Problem getting gaps: ") + query.lastError().text() + ) while query.next(): - reason = self.tr('Gap between the frame layer and coverage layer') + reason = self.tr("Gap between the frame layer and coverage layer") geom = query.value(0) - invalidCoverageRecordsList.append( (0, reason, geom) ) + invalidCoverageRecordsList.append((0, reason, geom)) # checking for overlaps in coverage - invalidCoverageRecordsList += self.getOverlapsRecords('validation.coverage_temp','geom','id') + invalidCoverageRecordsList += self.getOverlapsRecords( + "validation.coverage_temp", "geom", "id" + ) # checking for inner gaps in coverage - invalidCoverageRecordsList += self.getGapsRecords('validation.coverage_temp','geom','id') + invalidCoverageRecordsList += self.getGapsRecords( + "validation.coverage_temp", "geom", "id" + ) return invalidCoverageRecordsList - def getOverlapsRecords(self, table, geomColumn, keyColumn, useTransaction = True): + def getOverlapsRecords(self, table, geomColumn, keyColumn, useTransaction=True): """ Identify gaps and overlaps in the coverage layer """ @@ -3685,13 +4701,15 @@ def getOverlapsRecords(self, table, geomColumn, keyColumn, useTransaction = True sql = self.gen.checkCoverageForOverlaps(table, geomColumn, keyColumn) query = QSqlQuery(sql, self.db) if not query.isActive(): - raise Exception(self.tr("Problem getting overlaps: ")+query.lastError().text()) + raise Exception( + self.tr("Problem getting overlaps: ") + query.lastError().text() + ) while query.next(): - reason = self.tr('Overlap between the features of the layer') + reason = self.tr("Overlap between the features of the layer") geom = query.value(0) - invalidRecordsList.append( (0, reason, geom) ) + invalidRecordsList.append((0, reason, geom)) return invalidRecordsList - + def fillComboBoxProcessOrClasses(self, filterType=None): """ Returns a list of possible classes or processes @@ -3703,29 +4721,33 @@ def fillComboBoxProcessOrClasses(self, filterType=None): classesOrProcesses = [] query = QSqlQuery(sql, self.db) if not query.isActive(): - raise Exception(self.tr("Problem filtering flags: ")+query.lastError().text()) + raise Exception( + self.tr("Problem filtering flags: ") + query.lastError().text() + ) classesOrProcesses.append("") while query.next(): classesOrProcesses.append(str(query.value(0))) return classesOrProcesses - def getFilteredFlagsView(self, filterType=None,filteredElement=None): + def getFilteredFlagsView(self, filterType=None, filteredElement=None): """ Returns a list of flagged features accordingly to what was chosen to filter and which element was chosen as such - (e.g. a process named 'identifyDuplicatedGeometries') - """ + (e.g. a process named 'identifyDuplicatedGeometries') + """ self.checkAndOpenDb() sql = self.gen.getFilteredFlagsQuery(filterType, filteredElement) outFiltered = [] query = QSqlQuery(sql, self.db) if not query.isActive(): - raise Exception(self.tr("Problem filtering flags: ")+query.lastError().text()) + raise Exception( + self.tr("Problem filtering flags: ") + query.lastError().text() + ) while query.next(): outFiltered.append(str(query.value(0))) return outFiltered - def createFilteredFlagsViewTable(self, filterType=None,filteredElement=None): + def createFilteredFlagsViewTable(self, filterType=None, filteredElement=None): """ Cretas a View Table if it doesn't exist and populates it with data considering the users selection of filtering @@ -3734,10 +4756,12 @@ def createFilteredFlagsViewTable(self, filterType=None,filteredElement=None): sql = self.gen.createFilteredFlagsViewTableQuery(filterType, filteredElement) query = QSqlQuery(sql, self.db) if not query.isActive(): - raise Exception(self.tr("Problem filtering flags: ")+query.lastError().text()) + raise Exception( + self.tr("Problem filtering flags: ") + query.lastError().text() + ) return - def getGapsRecords(self, table, geomColumn, keyColumn, useTransaction = True): + def getGapsRecords(self, table, geomColumn, keyColumn, useTransaction=True): """ Identify gaps and overlaps in the coverage layer """ @@ -3748,11 +4772,13 @@ def getGapsRecords(self, table, geomColumn, keyColumn, useTransaction = True): sql = self.gen.checkCoverageForGaps(table, geomColumn, keyColumn) query = QSqlQuery(sql, self.db) if not query.isActive(): - raise Exception(self.tr("Problem getting gaps: ")+query.lastError().text()) + raise Exception( + self.tr("Problem getting gaps: ") + query.lastError().text() + ) while query.next(): - reason = self.tr('Gap between the features of the layer') + reason = self.tr("Gap between the features of the layer") geom = query.value(0) - invalidRecordsList.append( (0, reason, geom) ) + invalidRecordsList.append((0, reason, geom)) return invalidRecordsList def getNumberOfFlagsByProcess(self, processName): @@ -3763,7 +4789,10 @@ def getNumberOfFlagsByProcess(self, processName): sql = self.gen.getFlagsByProcess(processName) query = QSqlQuery(sql, self.db) if not query.isActive(): - raise Exception(self.tr('Problem while retrieving flags dict: ') + query.lastError().text()) + raise Exception( + self.tr("Problem while retrieving flags dict: ") + + query.lastError().text() + ) nrFlags = 0 while query.next(): nrFlags += 1 @@ -3771,15 +4800,18 @@ def getNumberOfFlagsByProcess(self, processName): def createValidationHistoryViewTable(self, idListString=None): """ - Creates the view table for validation processes history. + Creates the view table for validation processes history. """ self.checkAndOpenDb() sql = self.gen.createValidationHistoryViewTableQuery(idListString=idListString) query = QSqlQuery(sql, self.db) if not query.isActive(): - raise Exception(self.tr("Problem while retrieving validation processes history table: ")+query.lastError().text()) + raise Exception( + self.tr("Problem while retrieving validation processes history table: ") + + query.lastError().text() + ) return - + def getValidationLog(self, idList=False): """ Returns a list of all logs registered for each process executed. @@ -3788,18 +4820,21 @@ def getValidationLog(self, idList=False): self.checkAndOpenDb() sql = self.gen.getValidationLogQuery() query = QSqlQuery(sql, self.db) - log = [] # list of logs - idL = [] # list of ID in the same order as the logs appears + log = [] # list of logs + idL = [] # list of ID in the same order as the logs appears if not query.isActive(): - raise Exception(self.tr("Problem while retrieving validation processes history table: ")+query.lastError().text()) + raise Exception( + self.tr("Problem while retrieving validation processes history table: ") + + query.lastError().text() + ) while query.next(): log.append(query.value(0).encode(self.databaseEncoding)) idL.append(query.value(1)) - if idList: + if idList: return log, idL else: return log - + def getValidationHistory(self, idListString=False): """ Returns a list of all logs registered for each process executed. @@ -3810,11 +4845,22 @@ def getValidationHistory(self, idListString=False): self.checkAndOpenDb() sql = self.gen.getValidationHistoryQuery(idListString=idListString) query = QSqlQuery(sql, self.db) - history = [] # list of logs + history = [] # list of logs if not query.isActive(): - raise Exception(self.tr("Problem while retrieving validation processes history table: ")+query.lastError().text()) + raise Exception( + self.tr("Problem while retrieving validation processes history table: ") + + query.lastError().text() + ) while query.next(): - history.append([query.value(0), query.value(1), query.value(2), query.value(3), query.value(4)]) + history.append( + [ + query.value(0), + query.value(1), + query.value(2), + query.value(3), + query.value(4), + ] + ) return history def createCompactValidationHistory(self, compactHistory): @@ -3826,23 +4872,32 @@ def createCompactValidationHistory(self, compactHistory): sql = self.gen.createCompactValidationHistoryQuery() query = QSqlQuery(sql, self.db) if not query.isActive(): - raise Exception(self.tr("Problem while creating compact validation processes history table: ")+query.lastError().text()) + raise Exception( + self.tr( + "Problem while creating compact validation processes history table: " + ) + + query.lastError().text() + ) # table population for log in compactHistory: sql = self.gen.populateCompactValidationHistoryQuery(log=log) query = QSqlQuery(sql, self.db) if not query.isActive(): self.db.rollback() - raise Exception(self.tr("Problem while populating compact validation processes history table: ")+query.lastError().text()) + raise Exception( + self.tr( + "Problem while populating compact validation processes history table: " + ) + + query.lastError().text() + ) self.db.commit() return True def instantiateQgsVectorLayer(self, uri): pass - - def setDataSourceUri(self, schema, tableName, geometryColumn, sql, pkColumm): - uri = QgsDataSourceUri() + def setDataSourceUri(self, schema, tableName, geometryColumn, sql, pkColumm): + uri = QgsDataSourceUri() def getLayerDict(self): """ @@ -3850,25 +4905,39 @@ def getLayerDict(self): {'table_schema.table_name (geometryColumn):QgsVectorLayer'} """ lyrDict = dict() - inputDict = self.getGeomColumnDictV2(excludeValidation = True) + inputDict = self.getGeomColumnDictV2(excludeValidation=True) for key in list(inputDict.keys()): - uri = self.getURIV2(inputDict[key]['tableSchema'], inputDict[key]['tableName'], inputDict[key]['geom'], '') - lyr = QgsVectorLayer(uri.uri(), inputDict[key]['lyrName'], 'postgres', False) - outputKey = '{0}.{1} ({2})'.format(inputDict[key]['tableSchema'], inputDict[key]['tableName'], inputDict[key]['geom']) + uri = self.getURIV2( + inputDict[key]["tableSchema"], + inputDict[key]["tableName"], + inputDict[key]["geom"], + "", + ) + lyr = QgsVectorLayer( + uri.uri(), inputDict[key]["lyrName"], "postgres", False + ) + outputKey = "{0}.{1} ({2})".format( + inputDict[key]["tableSchema"], + inputDict[key]["tableName"], + inputDict[key]["geom"], + ) lyrDict[outputKey] = lyr return lyrDict - + def getAttrListWithFilter(self): self.checkAndOpenDb() sql = self.gen.getAttrListWithFilter() query = QSqlQuery(sql, self.db) if not query.isActive(): - raise Exception(self.tr("Problem getting list of attributes with filter: ")+query.lastError().text()) + raise Exception( + self.tr("Problem getting list of attributes with filter: ") + + query.lastError().text() + ) attrList = [] while query.next(): attrList.append(query.value(0)) return attrList - + def getAttrFilterDomainJsonList(self, domainNameList): self.checkAndOpenDb() jsonDict = dict() @@ -3877,12 +4946,15 @@ def getAttrFilterDomainJsonList(self, domainNameList): query = QSqlQuery(sql, self.db) localList = [] if not query.isActive(): - raise Exception(self.tr("Problem getting domain json list: ")+query.lastError().text()) + raise Exception( + self.tr("Problem getting domain json list: ") + + query.lastError().text() + ) while query.next(): localList.append(json.loads(query.value(0))) jsonDict[domainName] = localList return jsonDict - + def getFilterDict(self): """ returns a dict: @@ -3894,15 +4966,23 @@ def getFilterDict(self): sql = self.gen.getGeomTablesDomains() query = QSqlQuery(sql, self.db) if not query.isActive(): - raise Exception(self.tr("Problem getting geom schemas from db: ")+query.lastError().text()) + raise Exception( + self.tr("Problem getting geom schemas from db: ") + + query.lastError().text() + ) filterDict = dict() attrList = self.getAttrListWithFilter() jsonDict = self.getAttrFilterDomainJsonList(attrList) while query.next(): - #parse done in parseFkQuery to make code cleaner. - tableName, fkAttribute, domainTable, domainReferencedAttribute = self.parseFkQuery(query.value(0),query.value(1)) - if domainTable.split('.')[-1] in attrList: - filterDict[tableName] = jsonDict[domainTable.split('.')[-1]] + # parse done in parseFkQuery to make code cleaner. + ( + tableName, + fkAttribute, + domainTable, + domainReferencedAttribute, + ) = self.parseFkQuery(query.value(0), query.value(1)) + if domainTable.split(".")[-1] in attrList: + filterDict[tableName] = jsonDict[domainTable.split(".")[-1]] return filterDict def databaseInfo(self): @@ -3915,14 +4995,17 @@ def databaseInfo(self): sql = self.gen.databaseInfo() query = QSqlQuery(sql, self.db) if not query.isActive(): - raise Exception(self.tr("Problem getting geom schemas from db: ")+query.lastError().text()) + raise Exception( + self.tr("Problem getting geom schemas from db: ") + + query.lastError().text() + ) out = [] while query.next(): rowDict = dict() - rowDict['schema'] = query.value(0) - rowDict['layer'] = query.value(1) - rowDict['geomCol'] = query.value(2) - rowDict['geomType'] = query.value(3) - rowDict['srid'] = str(query.value(4)) + rowDict["schema"] = query.value(0) + rowDict["layer"] = query.value(1) + rowDict["geomCol"] = query.value(2) + rowDict["geomType"] = query.value(3) + rowDict["srid"] = str(query.value(4)) out.append(rowDict) return out diff --git a/DsgTools/core/Factories/DbFactory/shapefileDb.py b/DsgTools/core/Factories/DbFactory/shapefileDb.py index 134ee739d..08a194951 100644 --- a/DsgTools/core/Factories/DbFactory/shapefileDb.py +++ b/DsgTools/core/Factories/DbFactory/shapefileDb.py @@ -28,14 +28,16 @@ from .abstractDb import AbstractDb from DsgTools.core.dsgEnums import DsgEnums -from DsgTools.core.Factories.LayerLoaderFactory.layerLoaderFactory import LayerLoaderFactory +from DsgTools.core.Factories.LayerLoaderFactory.layerLoaderFactory import ( + LayerLoaderFactory, +) from osgeo import ogr, osr import os, json -class ShapefileDb(AbstractDb): - def __init__(self, path=''): +class ShapefileDb(AbstractDb): + def __init__(self, path=""): """ Constructor """ @@ -48,7 +50,7 @@ def getLayerLoader(self): Gets the shapefile layer loader as designed in DSGTools plugin. LAYER LOADERS SHOULD NOT be imported in abstract db. (Shapefile AbstractDb)s are a concept extrapolation, and this is specific for this case. - :return: (ShapefileLayerLoader) shapefile layer loader object. + :return: (ShapefileLayerLoader) shapefile layer loader object. """ # DIAMOND PROBLEM ALERT: this method requires care to be used; similar methods should be avoided! return LayerLoaderFactory().makeLoader(iface, self) @@ -60,12 +62,12 @@ def setLayersDict(self): self.layerGeomCrsDict, temp = dict(), dict() if self.databaseName(): ll = self.getLayerLoader() - layerByNameAlias = lambda l : ll.getLayerByName(layer=l) + layerByNameAlias = lambda l: ll.getLayerByName(layer=l) for shpLayer in self.getTablesFromDatabase(): temp[shpLayer] = dict() vl = layerByNameAlias(l=shpLayer) - temp[shpLayer]['crs'] = vl.crs() - temp[shpLayer]['geomType'] = vl.geometryType() + temp[shpLayer]["crs"] = vl.crs() + temp[shpLayer]["geomType"] = vl.geometryType() self.layerGeomCrsDict = temp def __del__(self): @@ -78,18 +80,22 @@ def __del__(self): def isOpen(self): """ Checks if there is a loaded shapefile dataset (directory). - :return: (bool) whether there is a valid dataset open. + :return: (bool) whether there is a valid dataset open. """ dn = self.databaseName() - return dn is None or dn == '' + return dn is None or dn == "" def checkAndOpenDb(self): """ Checks and opens the database (in this case, simply checks whether a valid path was chosen). """ fullpath = self.databaseName() - if fullpath is None or fullpath == '': - raise Exception(self.tr('Error opening database: a (valid) shapefiles path was not given.')) + if fullpath is None or fullpath == "": + raise Exception( + self.tr( + "Error opening database: a (valid) shapefiles path was not given." + ) + ) # MUDAR AQUI QUANDO HOUVER MÉTODO DE LEITURA DE CAMADAS # if : # raise Exception(self.tr('Error opening database: ')+self.db.lastError().text()) @@ -99,7 +105,7 @@ def databaseName(self): Gets full path for selected dataset. :return: (str) fullpath as selected. """ - return self.fullpath if self.fullpath is not None else '' + return self.fullpath if self.fullpath is not None else "" def getDatabaseName(self): """ @@ -107,9 +113,9 @@ def getDatabaseName(self): :return: (str) dataset name. """ fullpath = self.databaseName() - splitChar = '/' if '/' in fullpath else '\\' - return fullpath.split(splitChar)[-1] if fullpath else '' - + splitChar = "/" if "/" in fullpath else "\\" + return fullpath.split(splitChar)[-1] if fullpath else "" + def connectDatabase(self, conn=None): """ Connects to database. @@ -119,13 +125,15 @@ def connectDatabase(self, conn=None): self.connectDatabaseWithGui() else: self.setDatabaseName(conn) - + def connectDatabaseWithGui(self): """ Connects to database using user interface dialog. """ fd = QFileDialog() - filename = fd.getExistingDirectory(caption=self.tr('Select a Path to Shapefiles')) + filename = fd.getExistingDirectory( + caption=self.tr("Select a Path to Shapefiles") + ) filename = filename[0] if isinstance(filename, tuple) else filename self.setDatabaseName(filename) @@ -135,7 +143,7 @@ def setDatabaseName(self, path): :para path: (str) path to directory containing shapefiles. """ self.fullpath = path - if path != '': + if path != "": # update layers dict self.setLayersDict() else: @@ -143,7 +151,7 @@ def setDatabaseName(self, path): # MUDAR AQUI O QUE FAZER QUANDO ALTERAR O NOME DA BASE DE DADOS - def listGeomClassesFromDatabase(self, primitiveFilter = []): + def listGeomClassesFromDatabase(self, primitiveFilter=[]): """ Gets a list with geometry classes from database. :return: (list-of-str) a list with all spatial SHP found, according to EDGV filing name standards. @@ -156,7 +164,7 @@ def listGeomClassesFromDatabase(self, primitiveFilter = []): # raise Exception(self.tr("Problem listing geom classes: ")+query.lastError().text()) for f in fileList: layerName, ext = os.path.splitext(f) - if ext.lower() != '.shp': + if ext.lower() != ".shp": continue if layerName.lower()[-2:] in ["_p", "_l", "_a"]: classList.append(layerName) @@ -171,7 +179,7 @@ def getTablesFromDatabase(self): fileList = next(os.walk(self.databaseName()))[2] for f in fileList: layerName, ext = os.path.splitext(f) - if ext.lower() != '.shp': + if ext.lower() != ".shp": continue classList.append(layerName) return classList @@ -183,10 +191,10 @@ def listComplexClassesFromDatabase(self): self.checkAndOpenDb() classList = [] for layerName in self.getTablesFromDatabase(): - tableSchema = layerName.split('_')[0] - if tableSchema.lower() == 'complexos': - classList.append(layerName) - return classList + tableSchema = layerName.split("_")[0] + if tableSchema.lower() == "complexos": + classList.append(layerName) + return classList def getAttributesFromLayer(self, layer, layerLoader): """ @@ -210,50 +218,58 @@ def getStructureDict(self): layerLoader = self.getLayerLoader() for shpLayer in self.getTablesFromDatabase(): schema, className = self.getTableSchema(lyr=shpLayer) - if schema == 'complexos' or className[-2:].lower() in ['_p','_l','_a']: + if schema == "complexos" or className[-2:].lower() in ["_p", "_l", "_a"]: if shpLayer not in list(classDict.keys()): classDict[shpLayer] = dict() # read attributes from .dbf file attributes = [] - for att in self.getAttributesFromLayer(layer=shpLayer, layerLoader=layerLoader): - classDict[shpLayer][att]=att - if 'GEOMETRY' in list(classDict[shpLayer].keys()): - classDict[shpLayer]['GEOMETRY'] = 'geom' - elif 'geometry' in list(classDict[shpLayer].keys()): - classDict[shpLayer]['geometry'] = 'geom' - if 'OGC_FID' in list(classDict[shpLayer].keys()): - classDict[shpLayer]['OGC_FID'] = 'id' + for att in self.getAttributesFromLayer( + layer=shpLayer, layerLoader=layerLoader + ): + classDict[shpLayer][att] = att + if "GEOMETRY" in list(classDict[shpLayer].keys()): + classDict[shpLayer]["GEOMETRY"] = "geom" + elif "geometry" in list(classDict[shpLayer].keys()): + classDict[shpLayer]["geometry"] = "geom" + if "OGC_FID" in list(classDict[shpLayer].keys()): + classDict[shpLayer]["OGC_FID"] = "id" return classDict - - def getTableSchema(self,lyr): + + def getTableSchema(self, lyr): """ Gets the table schema. :param lyr: (str) layer name. :return: (tuple-of-str) layer schema and name, in that order. """ - schema = lyr.split('_')[0] - className = lyr[len(schema) + 1:] + schema = lyr.split("_")[0] + className = lyr[len(schema) + 1 :] return (schema, className) - + def getDatabaseVersion(self): """ Gets the database EDGV version. """ - edgvDict = {'213' : '2.1.3', '213pro' : '2.1.3 Pro', '213fter' : '2.1.3 FTer', '30' : '3.0', '30pro' : '3.0 Pro'} + edgvDict = { + "213": "2.1.3", + "213pro": "2.1.3 Pro", + "213fter": "2.1.3 FTer", + "30": "3.0", + "30pro": "3.0 Pro", + } self.checkAndOpenDb() - edgvVersion = 'Non EDGV' - if 'DSGTools.edgv' in next(os.walk(self.databaseName()))[2]: - with open(os.path.join(self.databaseName(), 'DSGTools.edgv'), 'r') as cf: + edgvVersion = "Non EDGV" + if "DSGTools.edgv" in next(os.walk(self.databaseName()))[2]: + with open(os.path.join(self.databaseName(), "DSGTools.edgv"), "r") as cf: config = json.loads(cf.read()) - edgvVersion = config['edgv'] - return edgvDict[edgvVersion] if edgvVersion in edgvDict else 'Non EDGV' + edgvVersion = config["edgv"] + return edgvDict[edgvVersion] if edgvVersion in edgvDict else "Non EDGV" # if not query.isActive(): # raise Exception(self.tr("Problem getting database version: ")+query.lastError().text()) while query.next(): version = query.value(0) return version - + def obtainLinkColumn(self, complexClass, aggregatedClass): """ Obtains the link column between complex and aggregated class @@ -261,12 +277,16 @@ def obtainLinkColumn(self, complexClass, aggregatedClass): aggregatedClass: aggregated class name """ self.checkAndOpenDb() - #query to obtain the link column between the complex and the feature layer - sql = self.gen.getLinkColumn(complexClass.replace('complexos_', ''), aggregatedClass) + # query to obtain the link column between the complex and the feature layer + sql = self.gen.getLinkColumn( + complexClass.replace("complexos_", ""), aggregatedClass + ) query = QSqlQuery(sql, self.db) if not query.isActive(): self.db.close() - raise Exception(self.tr("Problem obtaining link column: ")+query.lastError().text()) + raise Exception( + self.tr("Problem obtaining link column: ") + query.lastError().text() + ) column_name = "" while query.next(): column_name = query.value(0) @@ -274,36 +294,42 @@ def obtainLinkColumn(self, complexClass, aggregatedClass): def loadAssociatedFeatures(self, complex): """ - Loads all the features associated to the complex + Loads all the features associated to the complex complex: complex class name """ self.checkAndOpenDb() associatedDict = dict() # query to get the possible links to the selected complex in the combobox - complexName = complex.replace('complexos_', '') + complexName = complex.replace("complexos_", "") sql = self.gen.getComplexLinks(complexName) query = QSqlQuery(sql, self.db) if not query.isActive(): self.db.close() - raise Exception(self.tr("Problem loading associated features: ")+query.lastError().text()) + raise Exception( + self.tr("Problem loading associated features: ") + + query.lastError().text() + ) while query.next(): - #setting the variables + # setting the variables complex_schema = query.value(0) complex = query.value(1) aggregated_schema = query.value(2) aggregated_class = query.value(3) column_name = query.value(4) - - if aggregated_class.split('_')[-1] not in ['p', 'l', 'a']: + + if aggregated_class.split("_")[-1] not in ["p", "l", "a"]: continue - #query to obtain the created complexes + # query to obtain the created complexes sql = self.gen.getComplexData(complex_schema, complex) complexQuery = QSqlQuery(sql, self.db) if not complexQuery.isActive(): self.db.close() - raise Exception(self.tr("Problem executing query: ")+complexQuery.lastError().text()) + raise Exception( + self.tr("Problem executing query: ") + + complexQuery.lastError().text() + ) while next(complexQuery): complex_uuid = complexQuery.value(0) @@ -312,20 +338,31 @@ def loadAssociatedFeatures(self, complex): if not (complex_uuid and name): continue - associatedDict = self.utils.buildNestedDict(associatedDict, [name, complex_uuid, aggregated_class], []) + associatedDict = self.utils.buildNestedDict( + associatedDict, [name, complex_uuid, aggregated_class], [] + ) - #query to obtain the id of the associated feature - sql = self.gen.getAssociatedFeaturesData(aggregated_schema, aggregated_class, column_name, complex_uuid) + # query to obtain the id of the associated feature + sql = self.gen.getAssociatedFeaturesData( + aggregated_schema, aggregated_class, column_name, complex_uuid + ) associatedQuery = QSqlQuery(sql, self.db) if not associatedQuery.isActive(): self.db.close() - raise Exception(self.tr("Problem executing query: ")+associatedQuery.lastError().text()) + raise Exception( + self.tr("Problem executing query: ") + + associatedQuery.lastError().text() + ) while next(associatedQuery): ogc_fid = associatedQuery.value(0) - associatedDict = self.utils.buildNestedDict(associatedDict, [name, complex_uuid, aggregated_class], [ogc_fid]) + associatedDict = self.utils.buildNestedDict( + associatedDict, + [name, complex_uuid, aggregated_class], + [ogc_fid], + ) return associatedDict - + def isComplexClass(self, layer): """ Checks if a class is a complex class. @@ -358,33 +395,35 @@ def getFrameLayerName(self): """ Gets the frame layer name """ - return 'public_aux_moldura_a' + return "public_aux_moldura_a" - def getOrphanGeomTablesWithElements(self, loading = False): + def getOrphanGeomTablesWithElements(self, loading=False): return [] - + def getOrphanGeomTables(self): return [] - + def checkAndCreateStyleTable(self): return None - def getStylesFromDb(self,dbVersion): + def getStylesFromDb(self, dbVersion): return None def getGeomTypeDict(self, loadCentroids=False): self.checkAndOpenDb() geomDict = dict() - if self.databaseName() != '' and self.layerGeomCrsDict != dict(): + if self.databaseName() != "" and self.layerGeomCrsDict != dict(): for shpLayer in self.getTablesFromDatabase(): - geomType = self.getQgisResolvideGeomType(geometryType=self.layerGeomCrsDict[shpLayer]['geomType']) + geomType = self.getQgisResolvideGeomType( + geometryType=self.layerGeomCrsDict[shpLayer]["geomType"] + ) schema, layer = self.getTableSchema(lyr=shpLayer) if geomType not in geomDict: geomDict[geomType] = [] geomDict[geomType].append(layer) return geomDict - - def getGeomDict(self, getCentroids = False): + + def getGeomDict(self, getCentroids=False): pass """ returns a dict like this: @@ -393,68 +432,72 @@ def getGeomDict(self, getCentroids = False): """ self.checkAndOpenDb() geomDict = dict() - geomDict['primitivePerspective'] = self.getGeomTypeDict() - geomDict['tablePerspective'] = dict() - if self.databaseName() != '' and self.layerGeomCrsDict != dict(): + geomDict["primitivePerspective"] = self.getGeomTypeDict() + geomDict["tablePerspective"] = dict() + if self.databaseName() != "" and self.layerGeomCrsDict != dict(): for shpLayer in self.getTablesFromDatabase(): - srid = self.layerGeomCrsDict[shpLayer]['crs'].authid().split(':')[-1] - geometryType = self.layerGeomCrsDict[shpLayer]['geomType'] + srid = self.layerGeomCrsDict[shpLayer]["crs"].authid().split(":")[-1] + geometryType = self.layerGeomCrsDict[shpLayer]["geomType"] schema, layerName = self.getTableSchema(lyr=shpLayer) # start this layer's dict and fill it up - geomDict['tablePerspective'][layerName] = dict() - geomDict['tablePerspective'][layerName]['schema'] = schema - geomDict['tablePerspective'][layerName]['srid'] = str(srid) - geomDict['tablePerspective'][layerName]['geometryColumn'] = 'N/A' - geomDict['tablePerspective'][layerName]['geometryType'] = geometryType - geomDict['tablePerspective'][layerName]['tableName'] = shpLayer + geomDict["tablePerspective"][layerName] = dict() + geomDict["tablePerspective"][layerName]["schema"] = schema + geomDict["tablePerspective"][layerName]["srid"] = str(srid) + geomDict["tablePerspective"][layerName]["geometryColumn"] = "N/A" + geomDict["tablePerspective"][layerName]["geometryType"] = geometryType + geomDict["tablePerspective"][layerName]["tableName"] = shpLayer return geomDict - + def getGeomColumnDict(self): pass """ Dict in the form 'geomName':[-list of table names-] """ self.checkAndOpenDb() - return { 'N/A' : self.listGeomClassesFromDatabase() } + return {"N/A": self.listGeomClassesFromDatabase()} - def createFrame(self, type_, scale, param, paramDict = dict()): + def createFrame(self, type_, scale, param, paramDict=dict()): mi, inom, frame = self.prepareCreateFrame(type_, scale, param) self.insertFrame(scale, mi, inom, frame.asWkb()) return frame - + def insertFrame(self, scale, mi, inom, frame): self.checkAndOpenDb() srid = self.findEPSG() - geoSrid = QgsCoordinateReferenceSystem(int(srid)).geographicCRSAuthId().split(':')[-1] + geoSrid = ( + QgsCoordinateReferenceSystem(int(srid)).geographicCRSAuthId().split(":")[-1] + ) ogr.UseExceptions() outputDS = self.buildOgrDatabase() - outputLayer=outputDS.GetLayerByName(self.getFrameLayerName()) - newFeat=ogr.Feature(outputLayer.GetLayerDefn()) + outputLayer = outputDS.GetLayerByName(self.getFrameLayerName()) + newFeat = ogr.Feature(outputLayer.GetLayerDefn()) auxGeom = ogr.CreateGeometryFromWkb(frame) - #set geographic srid from frame + # set geographic srid from frame geoSrs = ogr.osr.SpatialReference() geoSrs.ImportFromEPSG(int(geoSrid)) auxGeom.AssignSpatialReference(geoSrs) - #reproject geom + # reproject geom outSpatialRef = outputLayer.GetSpatialRef() coordTrans = osr.CoordinateTransformation(geoSrs, outSpatialRef) auxGeom.Transform(coordTrans) newFeat.SetGeometry(auxGeom) - newFeat.SetField('mi', mi) - newFeat.SetField('inom', inom) - newFeat.SetField('escala', str(scale)) - out=outputLayer.CreateFeature(newFeat) + newFeat.SetField("mi", mi) + newFeat.SetField("inom", inom) + newFeat.SetField("escala", str(scale)) + out = outputLayer.CreateFeature(newFeat) outputDS.Destroy() - + def getTableSchemaFromDb(self, table): self.checkAndOpenDb() for shpLayer in self.getTablesFromDatabase(): schema, layer = self.getTableSchema(lyr=shpLayer) if table.lower() == layer.lower(): return schema - raise Exception(self.tr("Unable to locate file '[SCHEMA]_{}.shp'.").format(table)) - - def getGeomColumnTupleList(self, showViews = False): + raise Exception( + self.tr("Unable to locate file '[SCHEMA]_{}.shp'.").format(table) + ) + + def getGeomColumnTupleList(self, showViews=False): """ list in the format [(table_schema, table_name, geometryColumn, geometryType, tableType)] centroids are hidden by default @@ -463,8 +506,10 @@ def getGeomColumnTupleList(self, showViews = False): geomList = [] for shpLayer in self.getTablesFromDatabase(): schema, table = self.getTableSchema(lyr=shpLayer) - geomType = self.getQgisResolvideGeomType(geometryType=self.layerGeomCrsDict[shpLayer]['geomType']) - geomList.append((schema, table, 'N/A', geomType, 'ESRI SHAPEFILE')) + geomType = self.getQgisResolvideGeomType( + geometryType=self.layerGeomCrsDict[shpLayer]["geomType"] + ) + geomList.append((schema, table, "N/A", geomType, "ESRI SHAPEFILE")) return geomList def countElements(self, layers): @@ -475,7 +520,7 @@ def countElements(self, layers): """ self.checkAndOpenDb() listaQuantidades = [] - ll = lambda l : self.getLayerLoader().getLayerByName(layer=l) + ll = lambda l: self.getLayerLoader().getLayerByName(layer=l) for layer in layers: vl = ll(l=layer) listaQuantidades.append([layer, vl.featureCount()]) @@ -502,7 +547,7 @@ def findEPSG(self, parameters=dict()): """ srid = None for shp in self.layerGeomCrsDict: - srid = self.layerGeomCrsDict[shp]['crs'].authid().split(':')[1] + srid = self.layerGeomCrsDict[shp]["crs"].authid().split(":")[1] break return int(srid) @@ -513,29 +558,27 @@ def getQgisResolvideGeomType(self, geometryType): :param geometryType: (int) geometry type code. :return: (str) geometry type name. """ - geomDict = { - 0 : 'POINT', - 1 : 'LINESTRING', - 2 : 'POLYGON' - } - return geomDict[geometryType] if geometryType in geomDict else '' + geomDict = {0: "POINT", 1: "LINESTRING", 2: "POLYGON"} + return geomDict[geometryType] if geometryType in geomDict else "" def getResolvedGeomType(self, geometryType): - geomDict = {0:'GEOMETRY', - 1:'POINT', - 2:'LINESTRING', - 3:'POLYGON', - 4:'MULTIPOINT', - 5:'MULTILINESTRING', - 6:'MULTIPOLYGON', - 7:'GEOMETRYCOLLECTION', - 8:'CIRCULARSTRING', - 9:'COMPOUNDCURVE', - 10:'CURVEPOLYGON', - 11:'MULTICURVE', - 12:'MULTISURFACE', - 13:'CURVE', - 14:'SURFACE'} + geomDict = { + 0: "GEOMETRY", + 1: "POINT", + 2: "LINESTRING", + 3: "POLYGON", + 4: "MULTIPOINT", + 5: "MULTILINESTRING", + 6: "MULTIPOLYGON", + 7: "GEOMETRYCOLLECTION", + 8: "CIRCULARSTRING", + 9: "COMPOUNDCURVE", + 10: "CURVEPOLYGON", + 11: "MULTICURVE", + 12: "MULTISURFACE", + 13: "CURVE", + 14: "SURFACE", + } return geomDict[geometryType] def databaseInfo(self): @@ -547,18 +590,20 @@ def databaseInfo(self): self.checkAndOpenDb() out = [] ll = self.getLayerLoader() - layerByNameAlias = lambda l : ll.getLayerByName(layer=l) + layerByNameAlias = lambda l: ll.getLayerByName(layer=l) for shpLayer in self.getTablesFromDatabase(): # run through all .SHP files found (to include complexes and others non-EDGV filenames) schema, table = self.getTableSchema(lyr=shpLayer) vl = layerByNameAlias(l=shpLayer) rowDict = dict() - rowDict['schema'] = schema - rowDict['layer'] = table - rowDict['geomCol'] = 'N/A' # shape doesn't have geom column + rowDict["schema"] = schema + rowDict["layer"] = table + rowDict["geomCol"] = "N/A" # shape doesn't have geom column # TODO: check geometry type for shapefile - such as in getResolvedGeomType, for SpatiaLite, for instance - rowDict['geomType'] = self.getQgisResolvideGeomType(geometryType=vl.geometryType()) - rowDict['srid'] = vl.crs().authid().split(':')[-1] + rowDict["geomType"] = self.getQgisResolvideGeomType( + geometryType=vl.geometryType() + ) + rowDict["srid"] = vl.crs().authid().split(":")[-1] out.append(rowDict) return out @@ -567,7 +612,7 @@ def getType(self): Gets the driver name. :return: (str) driver name. """ - return 'SHP' + return "SHP" def untouchedMethods(self): """ @@ -579,5 +624,5 @@ def untouchedMethods(self): disassociateComplexFromComplex, createFrame, insertFrame, - getResolvedGeomType + getResolvedGeomType, ] diff --git a/DsgTools/core/Factories/DbFactory/spatialiteDb.py b/DsgTools/core/Factories/DbFactory/spatialiteDb.py index be528b870..91f1f49b0 100644 --- a/DsgTools/core/Factories/DbFactory/spatialiteDb.py +++ b/DsgTools/core/Factories/DbFactory/spatialiteDb.py @@ -25,7 +25,7 @@ from qgis.PyQt.QtSql import QSqlQuery, QSqlDatabase from qgis.PyQt.QtWidgets import QFileDialog -from qgis.core import QgsCoordinateReferenceSystem +from qgis.core import QgsCoordinateReferenceSystem from .abstractDb import AbstractDb from ..SqlFactory.sqlGeneratorFactory import SqlGeneratorFactory @@ -33,150 +33,180 @@ from osgeo import ogr, osr -class SpatialiteDb(AbstractDb): +class SpatialiteDb(AbstractDb): def __init__(self): - ''' + """ Constructor - ''' - super(SpatialiteDb,self).__init__() - self.db = QSqlDatabase('QSQLITE') - self.gen = SqlGeneratorFactory().createSqlGenerator(driver=DsgEnums.DriverSpatiaLite) + """ + super(SpatialiteDb, self).__init__() + self.db = QSqlDatabase("QSQLITE") + self.gen = SqlGeneratorFactory().createSqlGenerator( + driver=DsgEnums.DriverSpatiaLite + ) def closeDatabase(self): if self.db is not None and self.db.isOpen(): self.db.close() def getDatabaseName(self): - ''' + """ Gets the database name - ''' - return self.db.databaseName().split('.sqlite')[0].split('/')[-1] - - def connectDatabase(self, conn = None): - ''' + """ + return self.db.databaseName().split(".sqlite")[0].split("/")[-1] + + def connectDatabase(self, conn=None): + """ Connects to database conn: Database name - ''' + """ if conn is None: self.connectDatabaseWithGui() else: self.db.setDatabaseName(conn) - + def connectDatabaseWithGui(self): - ''' + """ Connects to database using user interface dialog - ''' + """ fd = QFileDialog() - filename = fd.getOpenFileName(caption=self.tr('Select a DSGTools Spatialite file'),filter=self.tr('Spatialite file databases (*.sqlite)')) + filename = fd.getOpenFileName( + caption=self.tr("Select a DSGTools Spatialite file"), + filter=self.tr("Spatialite file databases (*.sqlite)"), + ) filename = filename[0] if isinstance(filename, tuple) else filename self.db.setDatabaseName(filename) - - def listGeomClassesFromDatabase(self, primitiveFilter = []): - ''' + + def listGeomClassesFromDatabase(self, primitiveFilter=[]): + """ Gets a list with geometry classes from database - ''' + """ self.checkAndOpenDb() classList = [] sql = self.gen.getTablesFromDatabase() query = QSqlQuery(sql, self.db) if not query.isActive(): self.db.close() - raise Exception(self.tr("Problem listing geom classes: ")+query.lastError().text()) + raise Exception( + self.tr("Problem listing geom classes: ") + query.lastError().text() + ) while query.next(): tableName = str(query.value(0)) layerName = tableName if tableName[-2:].lower() in ["_p", "_l", "_a"]: classList.append(layerName) return classList - + def listComplexClassesFromDatabase(self): - ''' + """ Gets a list with complex classes from database - ''' + """ self.checkAndOpenDb() classList = [] sql = self.gen.getTablesFromDatabase() query = QSqlQuery(sql, self.db) if not query.isActive(): self.db.close() - raise Exception(self.tr("Problem listing complex classes: ")+query.lastError().text()) + raise Exception( + self.tr("Problem listing complex classes: ") + query.lastError().text() + ) while query.next(): - tableName = str(query.value(0)) - layerName = tableName - tableSchema = layerName.split('_')[0] - if tableSchema == 'complexos': - classList.append(layerName) - return classList + tableName = str(query.value(0)) + layerName = tableName + tableSchema = layerName.split("_")[0] + if tableSchema == "complexos": + classList.append(layerName) + return classList def getStructureDict(self): - ''' + """ Gets database structure according to the edgv version - ''' + """ self.checkAndOpenDb() classDict = dict() - sql = self.gen.getStructure(self.getDatabaseVersion()) + sql = self.gen.getStructure(self.getDatabaseVersion()) query = QSqlQuery(sql, self.db) if not query.isActive(): self.db.close() - raise Exception(self.tr("Problem getting database structure: ")+query.lastError().text()) + raise Exception( + self.tr("Problem getting database structure: ") + + query.lastError().text() + ) while query.next(): className = str(query.value(0)) classSql = str(query.value(1)) - if className.split('_')[0] == 'complexos' or className.split('_')[-1] in ['p','l','a']: + if className.split("_")[0] == "complexos" or className.split("_")[-1] in [ + "p", + "l", + "a", + ]: if className not in list(classDict.keys()): - classDict[className]=dict() + classDict[className] = dict() classSql = classSql.split(className)[1] - sqlList = classSql.replace('(','').replace(')','').replace('\"','').replace('\'','').split(',') + sqlList = ( + classSql.replace("(", "") + .replace(")", "") + .replace('"', "") + .replace("'", "") + .split(",") + ) for s in sqlList: - fieldName = str(s.strip().split(' ')[0]) - classDict[className][fieldName]=fieldName + fieldName = str(s.strip().split(" ")[0]) + classDict[className][fieldName] = fieldName - if 'GEOMETRY' in list(classDict[className].keys()): - classDict[className]['GEOMETRY'] = 'geom' - if 'geometry' in list(classDict[className].keys()): - classDict[className]['geometry'] = 'geom' - if 'OGC_FID' in list(classDict[className].keys()): - classDict[className]['OGC_FID'] = 'id' + if "GEOMETRY" in list(classDict[className].keys()): + classDict[className]["GEOMETRY"] = "geom" + if "geometry" in list(classDict[className].keys()): + classDict[className]["geometry"] = "geom" + if "OGC_FID" in list(classDict[className].keys()): + classDict[className]["OGC_FID"] = "id" return classDict - + def makeOgrConn(self): - ''' + """ Makes a connection string for spatialite databases (e.g just the name) - ''' + """ constring = self.db.databaseName() return constring def validateWithOutputDatabaseSchema(self, outputAbstractDb): - ''' + """ Validates the conversion with the output database. It generates a dictionary (invalidated) that stores conversion problems - ''' + """ self.checkAndOpenDb() invalidated = self.buildInvalidatedDict() inputdbStructure = self.getStructureDict() outputdbStructure = outputAbstractDb.getStructureDict() domainDict = outputAbstractDb.getDomainDict() - classes = self.listClassesWithElementsFromDatabase() + classes = self.listClassesWithElementsFromDatabase() notNullDict = outputAbstractDb.getNotNullDict() - + for inputClass in list(classes.keys()): - outputClass = self.translateAbstractDbLayerNameToOutputFormat(inputClass,outputAbstractDb) - (schema,className) = self.getTableSchema(inputClass) + outputClass = self.translateAbstractDbLayerNameToOutputFormat( + inputClass, outputAbstractDb + ) + (schema, className) = self.getTableSchema(inputClass) if outputClass in list(outputdbStructure.keys()): - outputAttrList = self.reorderTupleList(list(outputdbStructure[outputClass].keys())) - inputAttrList = self.reorderTupleList(list(inputdbStructure[inputClass].keys())) - - sql = self.gen.getFeaturesWithSQL(inputClass,inputAttrList) + outputAttrList = self.reorderTupleList( + list(outputdbStructure[outputClass].keys()) + ) + inputAttrList = self.reorderTupleList( + list(inputdbStructure[inputClass].keys()) + ) + + sql = self.gen.getFeaturesWithSQL(inputClass, inputAttrList) query = QSqlQuery(sql, self.db) if not query.isActive(): self.db.close() - raise Exception(self.tr("Problem executing query: ")+query.lastError().text()) - + raise Exception( + self.tr("Problem executing query: ") + query.lastError().text() + ) + while query.next(): id = query.value(0) - #detects null lines + # detects null lines for i in range(len(inputAttrList)): nullLine = True value = query.value(i) @@ -184,112 +214,208 @@ def validateWithOutputDatabaseSchema(self, outputAbstractDb): nullLine = False break if nullLine: - if cl not in list(invalidated['nullLine'].keys()): - invalidated['nullLine'][inputClass]=0 - invalidated['nullLine'][inputClass]+=1 - - #validates pks + if cl not in list(invalidated["nullLine"].keys()): + invalidated["nullLine"][inputClass] = 0 + invalidated["nullLine"][inputClass] += 1 + + # validates pks if id == None and (not nullLine): - if cl not in list(invalidated['nullPk'].keys()): - invalidated['nullPk'][inputClass]=0 - invalidated['nullPk'][inputClass]+=1 - + if cl not in list(invalidated["nullPk"].keys()): + invalidated["nullPk"][inputClass] = 0 + invalidated["nullPk"][inputClass] += 1 + for i in range(len(inputAttrList)): value = query.value(i) - #validates domain - if outputClass in list(domainDict.keys()): + # validates domain + if outputClass in list(domainDict.keys()): if inputAttrList[i] in list(domainDict[outputClass].keys()): - if value not in domainDict[outputClass][inputAttrList[i]] and (not nullLine): - invalidated = self.utils.buildNestedDict(invalidated, ['notInDomain',inputClass,id,inputAttrList[i]], value) - #validates not nulls + if value not in domainDict[outputClass][ + inputAttrList[i] + ] and (not nullLine): + invalidated = self.utils.buildNestedDict( + invalidated, + [ + "notInDomain", + inputClass, + id, + inputAttrList[i], + ], + value, + ) + # validates not nulls if outputClass in list(notNullDict.keys()): if outputClass in list(domainDict.keys()): - if inputAttrList[i] in notNullDict[outputClass] and inputAttrList[i] not in list(domainDict[outputClass].keys()): - if (value == None) and (not nullLine) and (inputAttrList[i] not in list(domainDict[outputClass].keys())): - invalidated = self.utils.buildNestedDict(invalidated, ['nullAttribute',inputClass,id,inputAttrList[i]], value) + if inputAttrList[i] in notNullDict[ + outputClass + ] and inputAttrList[i] not in list( + domainDict[outputClass].keys() + ): + if ( + (value == None) + and (not nullLine) + and ( + inputAttrList[i] + not in list(domainDict[outputClass].keys()) + ) + ): + invalidated = self.utils.buildNestedDict( + invalidated, + [ + "nullAttribute", + inputClass, + id, + inputAttrList[i], + ], + value, + ) else: if inputAttrList[i] in notNullDict[outputClass]: try: if value.isNull(): - invalidated = self.utils.buildNestedDict(invalidated, ['nullAttribute',inputClass,id,inputAttrList[i]], value) + invalidated = self.utils.buildNestedDict( + invalidated, + [ + "nullAttribute", + inputClass, + id, + inputAttrList[i], + ], + value, + ) except: - if (value == None) and (not nullLine) and (inputAttrList[i] not in list(domainDict[outputClass].keys())): - invalidated = self.utils.buildNestedDict(invalidated, ['nullAttribute',inputClass,id,inputAttrList[i]], value) + if ( + (value == None) + and (not nullLine) + and ( + inputAttrList[i] + not in list( + domainDict[outputClass].keys() + ) + ) + ): + invalidated = self.utils.buildNestedDict( + invalidated, + [ + "nullAttribute", + inputClass, + id, + inputAttrList[i], + ], + value, + ) if outputClass in list(domainDict.keys()): - if (inputAttrList[i] not in ['geom','GEOMETRY','geometry','id','OGC_FID'] and schema != 'complexos') or (schema == 'complexos' and inputAttrList[i] != 'id'): - if inputAttrList[i] not in list(outputdbStructure[outputClass].keys()): - invalidated = self.utils.buildNestedDict(invalidated, ['attributeNotFoundInOutput',inputClass], [inputAttrList[i]]) - #validates fk field - if 'id_' == inputAttrList[0:3]: + if ( + inputAttrList[i] + not in ["geom", "GEOMETRY", "geometry", "id", "OGC_FID"] + and schema != "complexos" + ) or (schema == "complexos" and inputAttrList[i] != "id"): + if inputAttrList[i] not in list( + outputdbStructure[outputClass].keys() + ): + invalidated = self.utils.buildNestedDict( + invalidated, + ["attributeNotFoundInOutput", inputClass], + [inputAttrList[i]], + ) + # validates fk field + if "id_" == inputAttrList[0:3]: if not self.validateUUID(value): - if inputAttrList[i] not in list(outputdbStructure[outputClass].keys()): - invalidated = self.utils.buildNestedDict(invalidated, ['nullComplexFk',inputClass], [inputAttrList[i]]) + if inputAttrList[i] not in list( + outputdbStructure[outputClass].keys() + ): + invalidated = self.utils.buildNestedDict( + invalidated, + ["nullComplexFk", inputClass], + [inputAttrList[i]], + ) else: - invalidated['classNotFoundInOutput'].append(inputAttrList) + invalidated["classNotFoundInOutput"].append(inputAttrList) return invalidated - + def translateAbstractDbLayerNameToOutputFormat(self, lyr, outputAbstractDb): - ''' + """ Translates abstractdb layer name to output format lyr: layer name that will be translated outputAbstractDb: output database - ''' - if outputAbstractDb.db.driverName() == 'QSQLITE': + """ + if outputAbstractDb.db.driverName() == "QSQLITE": return lyr - if outputAbstractDb.db.driverName() == 'QPSQL': - return str(lyr.split('_')[0]+'.'+'_'.join(lyr.split('_')[1::])) - + if outputAbstractDb.db.driverName() == "QPSQL": + return str(lyr.split("_")[0] + "." + "_".join(lyr.split("_")[1::])) + def translateOGRLayerNameToOutputFormat(self, lyr, ogrOutput): - ''' + """ Translates ogr layer name to output format lyr: layer name that will be translated ogrOutput: ogr output - ''' - if ogrOutput.GetDriver().name == 'SQLite': + """ + if ogrOutput.GetDriver().name == "SQLite": return lyr - if ogrOutput.GetDriver().name == 'PostgreSQL': - return str(lyr.split('_')[0]+'.'+'_'.join(lyr.split('_')[1::])) - - def getTableSchema(self,lyr): - ''' + if ogrOutput.GetDriver().name == "PostgreSQL": + return str(lyr.split("_")[0] + "." + "_".join(lyr.split("_")[1::])) + + def getTableSchema(self, lyr): + """ Gets the table schema lyr: layer name - ''' - schema = lyr.split('_')[0] - className = '_'.join(lyr.split('_')[1::]) + """ + schema = lyr.split("_")[0] + className = "_".join(lyr.split("_")[1::]) return (schema, className) - + def convertToPostgis(self, outputAbstractDb, type=None): - ''' + """ Converts this to a postgis database outputAbstractDb: postgis output type: conversion type - ''' - (inputOgrDb, outputOgrDb, fieldMap, inputLayerList, errorDict) = self.prepareForConversion(outputAbstractDb) + """ + ( + inputOgrDb, + outputOgrDb, + fieldMap, + inputLayerList, + errorDict, + ) = self.prepareForConversion(outputAbstractDb) invalidated = self.validateWithOutputDatabaseSchema(outputAbstractDb) hasErrors = self.makeValidationSummary(invalidated) - if type == 'untouchedData': + if type == "untouchedData": if hasErrors: - self.signals.updateLog.emit('\n\n\n'+self.tr('Conversion not perfomed due to validation errors! Check log above for more information.')) + self.signals.updateLog.emit( + "\n\n\n" + + self.tr( + "Conversion not perfomed due to validation errors! Check log above for more information." + ) + ) return False else: - status = self.translateDS(inputOgrDb, outputOgrDb, fieldMap, inputLayerList, errorDict) + status = self.translateDS( + inputOgrDb, outputOgrDb, fieldMap, inputLayerList, errorDict + ) return status - if type == 'fixData': + if type == "fixData": if hasErrors: - status = self.translateDS(inputOgrDb, outputOgrDb, fieldMap, inputLayerList, errorDict, invalidated) + status = self.translateDS( + inputOgrDb, + outputOgrDb, + fieldMap, + inputLayerList, + errorDict, + invalidated, + ) return status else: - status = self.translateDS(inputOgrDb, outputOgrDb, fieldMap, inputLayerList, errorDict) + status = self.translateDS( + inputOgrDb, outputOgrDb, fieldMap, inputLayerList, errorDict + ) return status return False - + def getDatabaseVersion(self): - ''' + """ Gets the database version - ''' + """ self.checkAndOpenDb() - version = '2.1.3' + version = "2.1.3" sql = self.gen.getEDGVVersion() query = QSqlQuery(sql, self.db) # if not query.isActive(): @@ -297,57 +423,67 @@ def getDatabaseVersion(self): while query.next(): version = query.value(0) return version - + def obtainLinkColumn(self, complexClass, aggregatedClass): - ''' + """ Obtains the link column between complex and aggregated class complexClass: complex class name aggregatedClass: aggregated class name - ''' + """ self.checkAndOpenDb() - #query to obtain the link column between the complex and the feature layer - sql = self.gen.getLinkColumn(complexClass.replace('complexos_', ''), aggregatedClass) + # query to obtain the link column between the complex and the feature layer + sql = self.gen.getLinkColumn( + complexClass.replace("complexos_", ""), aggregatedClass + ) query = QSqlQuery(sql, self.db) if not query.isActive(): self.db.close() - raise Exception(self.tr("Problem obtaining link column: ")+query.lastError().text()) + raise Exception( + self.tr("Problem obtaining link column: ") + query.lastError().text() + ) column_name = "" while query.next(): column_name = query.value(0) return column_name def loadAssociatedFeatures(self, complex): - ''' - Loads all the features associated to the complex + """ + Loads all the features associated to the complex complex: complex class name - ''' + """ self.checkAndOpenDb() associatedDict = dict() - #query to get the possible links to the selected complex in the combobox - complexName = complex.replace('complexos_', '') + # query to get the possible links to the selected complex in the combobox + complexName = complex.replace("complexos_", "") sql = self.gen.getComplexLinks(complexName) query = QSqlQuery(sql, self.db) if not query.isActive(): self.db.close() - raise Exception(self.tr("Problem loading associated features: ")+query.lastError().text()) + raise Exception( + self.tr("Problem loading associated features: ") + + query.lastError().text() + ) while query.next(): - #setting the variables + # setting the variables complex_schema = query.value(0) complex = query.value(1) aggregated_schema = query.value(2) aggregated_class = query.value(3) column_name = query.value(4) - - if aggregated_class.split('_')[-1] not in ['p', 'l', 'a']: + + if aggregated_class.split("_")[-1] not in ["p", "l", "a"]: continue - #query to obtain the created complexes + # query to obtain the created complexes sql = self.gen.getComplexData(complex_schema, complex) complexQuery = QSqlQuery(sql, self.db) if not complexQuery.isActive(): self.db.close() - raise Exception(self.tr("Problem executing query: ")+complexQuery.lastError().text()) + raise Exception( + self.tr("Problem executing query: ") + + complexQuery.lastError().text() + ) while next(complexQuery): complex_uuid = complexQuery.value(0) @@ -356,54 +492,73 @@ def loadAssociatedFeatures(self, complex): if not (complex_uuid and name): continue - associatedDict = self.utils.buildNestedDict(associatedDict, [name, complex_uuid, aggregated_class], []) + associatedDict = self.utils.buildNestedDict( + associatedDict, [name, complex_uuid, aggregated_class], [] + ) - #query to obtain the id of the associated feature - sql = self.gen.getAssociatedFeaturesData(aggregated_schema, aggregated_class, column_name, complex_uuid) + # query to obtain the id of the associated feature + sql = self.gen.getAssociatedFeaturesData( + aggregated_schema, aggregated_class, column_name, complex_uuid + ) associatedQuery = QSqlQuery(sql, self.db) if not associatedQuery.isActive(): self.db.close() - raise Exception(self.tr("Problem executing query: ")+associatedQuery.lastError().text()) + raise Exception( + self.tr("Problem executing query: ") + + associatedQuery.lastError().text() + ) while next(associatedQuery): ogc_fid = associatedQuery.value(0) - associatedDict = self.utils.buildNestedDict(associatedDict, [name, complex_uuid, aggregated_class], [ogc_fid]) + associatedDict = self.utils.buildNestedDict( + associatedDict, + [name, complex_uuid, aggregated_class], + [ogc_fid], + ) return associatedDict - + def isComplexClass(self, className): - ''' + """ Checks if a class is a complex class className: class name to be checked - ''' + """ self.checkAndOpenDb() - #getting all complex tables + # getting all complex tables query = QSqlQuery(self.gen.getComplexTablesFromDatabase(), self.db) if not query.isActive(): self.db.close() - raise Exception(self.tr("Problem executing query: ")+query.lastError().text()) + raise Exception( + self.tr("Problem executing query: ") + query.lastError().text() + ) while query.next(): - if query.value(0) == 'complexos_'+className: + if query.value(0) == "complexos_" + className: return True return False def disassociateComplexFromComplex(self, aggregated_class, link_column, id): - ''' + """ Disassociates a complex from another complex aggregated_class: aggregated class that will be disassociated link_column: link column between complex and its aggregated class id: complex id (uid) to be disassociated - ''' - sql = self.gen.disassociateComplexFromComplex('complexos_'+aggregated_class, link_column, id) + """ + sql = self.gen.disassociateComplexFromComplex( + "complexos_" + aggregated_class, link_column, id + ) query = QSqlQuery(self.db) if not query.exec_(sql): self.db.close() - raise Exception(self.tr('Problem disassociating complex from complex: ') + '\n' + query.lastError().text()) + raise Exception( + self.tr("Problem disassociating complex from complex: ") + + "\n" + + query.lastError().text() + ) def getTablesFromDatabase(self): - ''' + """ Gets all tables from database - ''' + """ self.checkAndOpenDb() ret = [] @@ -411,29 +566,32 @@ def getTablesFromDatabase(self): query = QSqlQuery(sql, self.db) if not query.isActive(): self.db.close() - raise Exception(self.tr("Problem getting tables from database: ")+query.lastError().text()) + raise Exception( + self.tr("Problem getting tables from database: ") + + query.lastError().text() + ) while query.next(): - #table name + # table name ret.append(query.value(0)) return ret def getFrameLayerName(self): - ''' + """ Gets the frame layer name - ''' - return 'public_aux_moldura_a' + """ + return "public_aux_moldura_a" - def getOrphanGeomTablesWithElements(self, loading = False): + def getOrphanGeomTablesWithElements(self, loading=False): return [] - + def getOrphanGeomTables(self): return [] - + def checkAndCreateStyleTable(self): return None - def getStylesFromDb(self,dbVersion): + def getStylesFromDb(self, dbVersion): return None def getGeomTypeDict(self, loadCentroids=False): @@ -442,114 +600,128 @@ def getGeomTypeDict(self, loadCentroids=False): sql = self.gen.getGeomByPrimitive(edgvVersion) query = QSqlQuery(sql, self.db) if not query.isActive(): - raise Exception(self.tr("Problem getting geom types from db: ")+query.lastError().text()) + raise Exception( + self.tr("Problem getting geom types from db: ") + + query.lastError().text() + ) geomDict = dict() while query.next(): - if edgvVersion in ('2.1.3','FTer_2a_Ed'): + if edgvVersion in ("2.1.3", "FTer_2a_Ed"): type = query.value(0) else: type = self.getResolvedGeomType(query.value(0)) tableName = query.value(1) - layerName = '_'.join(tableName.split('_')[1::]) + layerName = "_".join(tableName.split("_")[1::]) if type not in list(geomDict.keys()): geomDict[type] = [] if layerName not in geomDict[type]: geomDict[type].append(layerName) return geomDict - - def getGeomDict(self, getCentroids = False): - ''' + + def getGeomDict(self, getCentroids=False): + """ returns a dict like this: {'tablePerspective' : { 'layerName' : - ''' + """ self.checkAndOpenDb() edgvVersion = self.getDatabaseVersion() sql = self.gen.getGeomTablesFromGeometryColumns(edgvVersion) query = QSqlQuery(sql, self.db) if not query.isActive(): - raise Exception(self.tr("Problem getting geom tables from db: ")+query.lastError().text()) + raise Exception( + self.tr("Problem getting geom tables from db: ") + + query.lastError().text() + ) geomDict = dict() - geomDict['primitivePerspective'] = self.getGeomTypeDict() - geomDict['tablePerspective'] = dict() + geomDict["primitivePerspective"] = self.getGeomTypeDict() + geomDict["tablePerspective"] = dict() while query.next(): isCentroid = False srid = query.value(0) - if edgvVersion in ('2.1.3','FTer_2a_Ed'): + if edgvVersion in ("2.1.3", "FTer_2a_Ed"): geometryType = query.value(2) else: geometryType = self.getResolvedGeomType(query.value(2)) tableName = query.value(3) - tableSchema = tableName.split('_')[0] + tableSchema = tableName.split("_")[0] geometryColumn = query.value(1) - layerName = '_'.join(tableName.split('_')[1::]) - if layerName not in list(geomDict['tablePerspective'].keys()): - geomDict['tablePerspective'][layerName] = dict() - geomDict['tablePerspective'][layerName]['schema'] = tableSchema - geomDict['tablePerspective'][layerName]['srid'] = str(srid) - geomDict['tablePerspective'][layerName]['geometryColumn'] = geometryColumn - geomDict['tablePerspective'][layerName]['geometryType'] = geometryType - geomDict['tablePerspective'][layerName]['tableName'] = tableName + layerName = "_".join(tableName.split("_")[1::]) + if layerName not in list(geomDict["tablePerspective"].keys()): + geomDict["tablePerspective"][layerName] = dict() + geomDict["tablePerspective"][layerName]["schema"] = tableSchema + geomDict["tablePerspective"][layerName]["srid"] = str(srid) + geomDict["tablePerspective"][layerName][ + "geometryColumn" + ] = geometryColumn + geomDict["tablePerspective"][layerName]["geometryType"] = geometryType + geomDict["tablePerspective"][layerName]["tableName"] = tableName return geomDict - + def getGeomColumnDict(self): - ''' + """ Dict in the form 'geomName':[-list of table names-] - ''' + """ self.checkAndOpenDb() sql = self.gen.getGeomColumnDict() query = QSqlQuery(sql, self.db) if not query.isActive(): - raise Exception(self.tr("Problem getting geom column dict: ")+query.lastError().text()) + raise Exception( + self.tr("Problem getting geom column dict: ") + query.lastError().text() + ) geomDict = dict() while query.next(): geomColumn = query.value(0) tableName = query.value(1) - lyrName = '_'.join(tableName.split('_')[1::]) + lyrName = "_".join(tableName.split("_")[1::]) if geomColumn not in list(geomDict.keys()): geomDict[geomColumn] = [] geomDict[geomColumn].append(lyrName) return geomDict - def createFrame(self, type, scale, param, paramDict = dict()): + def createFrame(self, type, scale, param, paramDict=dict()): mi, inom, frame = self.prepareCreateFrame(type, scale, param) self.insertFrame(scale, mi, inom, frame.asWkb()) return frame - + def insertFrame(self, scale, mi, inom, frame): self.checkAndOpenDb() srid = self.findEPSG() - geoSrid = QgsCoordinateReferenceSystem(int(srid)).geographicCRSAuthId().split(':')[-1] + geoSrid = ( + QgsCoordinateReferenceSystem(int(srid)).geographicCRSAuthId().split(":")[-1] + ) ogr.UseExceptions() outputDS = self.buildOgrDatabase() - outputLayer=outputDS.GetLayerByName('public_aux_moldura_a') - newFeat=ogr.Feature(outputLayer.GetLayerDefn()) + outputLayer = outputDS.GetLayerByName("public_aux_moldura_a") + newFeat = ogr.Feature(outputLayer.GetLayerDefn()) auxGeom = ogr.CreateGeometryFromWkb(frame) - #set geographic srid from frame + # set geographic srid from frame geoSrs = ogr.osr.SpatialReference() geoSrs.ImportFromEPSG(int(geoSrid)) auxGeom.AssignSpatialReference(geoSrs) - #reproject geom + # reproject geom outSpatialRef = outputLayer.GetSpatialRef() coordTrans = osr.CoordinateTransformation(geoSrs, outSpatialRef) auxGeom.Transform(coordTrans) newFeat.SetGeometry(auxGeom) - newFeat.SetField('mi', mi) - newFeat.SetField('inom', inom) - newFeat.SetField('escala', str(scale)) - out=outputLayer.CreateFeature(newFeat) + newFeat.SetField("mi", mi) + newFeat.SetField("inom", inom) + newFeat.SetField("escala", str(scale)) + out = outputLayer.CreateFeature(newFeat) outputDS.Destroy() - + def getTableSchemaFromDb(self, table): self.checkAndOpenDb() sql = self.gen.getFullTablesName(table) query = QSqlQuery(sql, self.db) if not query.isActive(): - raise Exception(self.tr("Problem getting full table name: ")+query.lastError().text()) + raise Exception( + self.tr("Problem getting full table name: ") + query.lastError().text() + ) while query.next(): - return query.value(0).split('_')[0] - - def getGeomColumnTupleList(self, showViews = False): + return query.value(0).split("_")[0] + + def getGeomColumnTupleList(self, showViews=False): """ list in the format [(table_schema, table_name, geometryColumn, geometryType, tableType)] centroids are hidden by default @@ -559,31 +731,51 @@ def getGeomColumnTupleList(self, showViews = False): sql = self.gen.getGeomColumnTupleList(edgvVersion) query = QSqlQuery(sql, self.db) if not query.isActive(): - raise Exception(self.tr("Problem getting geom tuple list: ")+query.lastError().text()) + raise Exception( + self.tr("Problem getting geom tuple list: ") + query.lastError().text() + ) geomList = [] while query.next(): - if edgvVersion in ['2.1.3','FTer_2a_Ed']: - geomList.append((query.value(0).split('_')[0], '_'.join(query.value(0).split('_')[1::]), query.value(1), query.value(2), 'BASE TABLE')) + if edgvVersion in ["2.1.3", "FTer_2a_Ed"]: + geomList.append( + ( + query.value(0).split("_")[0], + "_".join(query.value(0).split("_")[1::]), + query.value(1), + query.value(2), + "BASE TABLE", + ) + ) else: - geomList.append((query.value(0).split('_')[0], '_'.join(query.value(0).split('_')[1::]), query.value(1), self.getResolvedGeomType(int(query.value(2))), 'BASE TABLE')) + geomList.append( + ( + query.value(0).split("_")[0], + "_".join(query.value(0).split("_")[1::]), + query.value(1), + self.getResolvedGeomType(int(query.value(2))), + "BASE TABLE", + ) + ) return geomList - + def getResolvedGeomType(self, geometryType): - geomDict = {0:'GEOMETRY', - 1:'POINT', - 2:'LINESTRING', - 3:'POLYGON', - 4:'MULTIPOINT', - 5:'MULTILINESTRING', - 6:'MULTIPOLYGON', - 7:'GEOMETRYCOLLECTION', - 8:'CIRCULARSTRING', - 9:'COMPOUNDCURVE', - 10:'CURVEPOLYGON', - 11:'MULTICURVE', - 12:'MULTISURFACE', - 13:'CURVE', - 14:'SURFACE'} + geomDict = { + 0: "GEOMETRY", + 1: "POINT", + 2: "LINESTRING", + 3: "POLYGON", + 4: "MULTIPOINT", + 5: "MULTILINESTRING", + 6: "MULTIPOLYGON", + 7: "GEOMETRYCOLLECTION", + 8: "CIRCULARSTRING", + 9: "COMPOUNDCURVE", + 10: "CURVEPOLYGON", + 11: "MULTICURVE", + 12: "MULTISURFACE", + 13: "CURVE", + 14: "SURFACE", + } return geomDict[geometryType] def databaseInfo(self): @@ -596,15 +788,18 @@ def databaseInfo(self): sql = self.gen.databaseInfo() query = QSqlQuery(sql, self.db) if not query.isActive(): - raise Exception(self.tr("Problem getting geom schemas from db: ")+query.lastError().text()) + raise Exception( + self.tr("Problem getting geom schemas from db: ") + + query.lastError().text() + ) out = [] while query.next(): rowDict = dict() - rowDict['schema'] = query.value(0).split('_')[0] - rowDict['layer'] = query.value(0)[len(rowDict['schema']) + 1 :] - rowDict['geomCol'] = query.value(1) - rowDict['geomType'] = query.value(2) - rowDict['srid'] = str(query.value(3)) + rowDict["schema"] = query.value(0).split("_")[0] + rowDict["layer"] = query.value(0)[len(rowDict["schema"]) + 1 :] + rowDict["geomCol"] = query.value(1) + rowDict["geomType"] = query.value(2) + rowDict["srid"] = str(query.value(3)) out.append(rowDict) return out @@ -619,7 +814,9 @@ def tableFields(self, table): sql = self.gen.tableFields(table) query = QSqlQuery(sql, self.db) if not query.isActive(): - raise Exception(self.tr("Problem getting geom tuple list: ")+query.lastError().text()) + raise Exception( + self.tr("Problem getting geom tuple list: ") + query.lastError().text() + ) while query.next(): attrs.append(query.value(1)) return attrs diff --git a/DsgTools/core/Factories/LayerLoaderFactory/edgvLayerLoader.py b/DsgTools/core/Factories/LayerLoaderFactory/edgvLayerLoader.py index 113197c74..bc73ed7e2 100644 --- a/DsgTools/core/Factories/LayerLoaderFactory/edgvLayerLoader.py +++ b/DsgTools/core/Factories/LayerLoaderFactory/edgvLayerLoader.py @@ -23,13 +23,15 @@ from collections import defaultdict import os -from qgis.core import (Qgis, - QgsField, - QgsWkbTypes, - QgsMessageLog, - QgsVectorLayer, - QgsDataSourceUri, - QgsVectorLayerJoinInfo) +from qgis.core import ( + Qgis, + QgsField, + QgsWkbTypes, + QgsMessageLog, + QgsVectorLayer, + QgsDataSourceUri, + QgsVectorLayerJoinInfo, +) from qgis.utils import iface from qgis.PyQt.QtCore import QVariant from qgis.PyQt.Qt import QObject @@ -37,41 +39,63 @@ from DsgTools.core.Utils.utils import Utils + class EDGVLayerLoader(QObject): - def __init__(self, iface, abstractDb, loadCentroids): """Constructor.""" super(EDGVLayerLoader, self).__init__() - + self.abstractDb = abstractDb - self.uri = QgsDataSourceUri() + self.uri = QgsDataSourceUri() self.iface = iface self.utils = Utils() self.logErrorDict = dict() - self.errorLog = '' + self.errorLog = "" self.geomTypeDict = self.abstractDb.getGeomTypeDict(loadCentroids) self.geomDict = self.abstractDb.getGeomDict(self.geomTypeDict) - self.correspondenceDict = {'POINT':'Point', 'MULTIPOINT':'Point', 'LINESTRING':'Line','MULTILINESTRING':'Line', 'POLYGON':'Area', 'MULTIPOLYGON':'Area'} - + self.correspondenceDict = { + "POINT": "Point", + "MULTIPOINT": "Point", + "LINESTRING": "Line", + "MULTILINESTRING": "Line", + "POLYGON": "Area", + "MULTIPOLYGON": "Area", + } + def preLoadStep(self, inputList): if len(inputList) == 0: return [], False else: if isinstance(inputList[0], dict): - lyrList = [i['tableName'] for i in inputList] + lyrList = [i["tableName"] for i in inputList] return lyrList, True else: return inputList, False - def load(self, inputList, useQml=False, uniqueLoad=False, useInheritance=False, stylePath=None, onlyWithElements=False, geomFilterList=[], isEdgv=True, customForm=False, loadEditingStructure=False, parent=None): + def load( + self, + inputList, + useQml=False, + uniqueLoad=False, + useInheritance=False, + stylePath=None, + onlyWithElements=False, + geomFilterList=[], + isEdgv=True, + customForm=False, + loadEditingStructure=False, + parent=None, + ): return None - + def getStyle(self, stylePath, className): - if 'db:' in stylePath['style']: - return self.abstractDb.getStyle(stylePath['style'].split(':')[-1], className) + if "db:" in stylePath["style"]: + return self.abstractDb.getStyle( + stylePath["style"].split(":")[-1], className + ) else: - return self.getStyleFromFile(stylePath['style'], className) - + return self.getStyleFromFile(stylePath["style"], className) + def getStyleFromFile(self, stylePath, className): styleName = "{0}.qml".format(className) if styleName.lower() in [f.lower() for f in os.listdir(stylePath)]: @@ -79,34 +103,40 @@ def getStyleFromFile(self, stylePath, className): # dsgtools have the right to write on its own directory # a temporary file "temp.qml" tempPath = os.path.join(stylePath, "temp.qml") - with open(tempPath, "w", encoding='utf-8') as f: + with open(tempPath, "w", encoding="utf-8") as f: f.writelines(qml) f.close() return tempPath else: return None - + def prepareLoad(self): dbName = self.abstractDb.getDatabaseName() - groupList = iface.legendInterface().groups() + groupList = iface.legendInterface().groups() if dbName in groupList: return groupList.index(dbName) else: - parentTreeNode = iface.legendInterface().addGroup(self.abstractDb.getDatabaseName(), -1) + parentTreeNode = iface.legendInterface().addGroup( + self.abstractDb.getDatabaseName(), -1 + ) return parentTreeNode def createMeasureColumn(self, layer): if layer.geometryType() == QgsWkbTypes.PolygonGeometry: - layer.addExpressionField('$area', QgsField(self.tr('area_otf'), QVariant.Double)) + layer.addExpressionField( + "$area", QgsField(self.tr("area_otf"), QVariant.Double) + ) elif layer.geometryType() == QgsWkbTypes.LineGeometry: - layer.addExpressionField('$length', QgsField(self.tr('length_otf'), QVariant.Double)) + layer.addExpressionField( + "$length", QgsField(self.tr("length_otf"), QVariant.Double) + ) return layer - + def getDatabaseGroup(self, rootNode): dbName = self.abstractDb.getDatabaseName() return self.createGroup(dbName, rootNode) - def getLyrDict(self, inputList, isEdgv = True): + def getLyrDict(self, inputList, isEdgv=True): """ Builds lyrDict in order to build loading tree lyrList: list of layers to be loaded @@ -114,21 +144,26 @@ def getLyrDict(self, inputList, isEdgv = True): """ lyrDict = defaultdict(lambda: defaultdict(list)) if isinstance(inputList, list) and len(inputList) > 0: - if isinstance(inputList[0],dict): + if isinstance(inputList[0], dict): for elem in inputList: - if elem['geomType'] == 'GEOMETRY': + if elem["geomType"] == "GEOMETRY": continue - lyrDict[self.correspondenceDict[elem['geomType']]][elem['cat']].append(elem) + lyrDict[self.correspondenceDict[elem["geomType"]]][ + elem["cat"] + ].append(elem) else: for type in list(self.geomTypeDict.keys()): # some tables are only registered as GEOMETRY and should not be considered - if type == 'GEOMETRY': + if type == "GEOMETRY": continue for lyr in self.geomTypeDict[type]: if lyr not in inputList: continue - cat = lyr.split('_')[0] if isEdgv \ + cat = ( + lyr.split("_")[0] + if isEdgv else self.abstractDb.getTableSchemaFromDb(lyr) + ) lyrDict[self.correspondenceDict[type]][cat].append(lyr) for type in list(lyrDict.keys()): if lyrDict[type] == dict(): @@ -146,18 +181,20 @@ def prepareGroups(self, rootNode, lyrDict): catList = list(lyrDict[geomNodeName].keys()) catList.sort() for catNodeName in catList: - groupDict[geomNodeName][catNodeName] = self.createGroup(catNodeName, geomNode) + groupDict[geomNodeName][catNodeName] = self.createGroup( + catNodeName, geomNode + ) return groupDict - + def createGroup(self, groupName, rootNode): groupNode = rootNode.findGroup(groupName) if groupNode: return groupNode else: return rootNode.addGroup(groupName) - + def loadDomains(self, layerList, dbRootNode, edgvVersion): - if edgvVersion not in ('FTer_2a_Ed', '3.0'): + if edgvVersion not in ("FTer_2a_Ed", "3.0"): return dict() domLayerDict = dict() try: @@ -165,7 +202,11 @@ def loadDomains(self, layerList, dbRootNode, edgvVersion): except: return dict() domainNode = self.createGroup(self.tr("Domains"), dbRootNode) - loadedDomainsDict = {} if not domainNode.findLayers() else {i.layer().name() : i.layer() for i in domainNode.findLayers()} + loadedDomainsDict = ( + {} + if not domainNode.findLayers() + else {i.layer().name(): i.layer() for i in domainNode.findLayers()} + ) for lyr in layerList: if lyr in qmlDict: for attr in qmlDict[lyr]: @@ -176,48 +217,49 @@ def loadDomains(self, layerList, dbRootNode, edgvVersion): if attr not in list(domLayerDict[lyr].keys()): domLayerDict[lyr][attr] = domLyr return domLayerDict - + def getDomainLyr(self, domain, loadedDomainsDict, domainNode): if domain in loadedDomainsDict: return loadedDomainsDict[domain] domainLyr = self.loadDomain(domain, domainNode) loadedDomainsDict[domain] = domainLyr return domainLyr - def logError(self): - msg = '' + msg = "" for lyr in self.logErrorDict: - msg += self.tr('Error for lyr ')+ lyr + ': ' +self.logErrorDict[lyr] + '\n' + msg += ( + self.tr("Error for lyr ") + lyr + ": " + self.logErrorDict[lyr] + "\n" + ) self.errorLog += msg - def setDataSource(self, schema, layer, geomColumn, sql, pkColumn='id'): + def setDataSource(self, schema, layer, geomColumn, sql, pkColumn="id"): self.uri.setDataSource(schema, layer, geomColumn, sql, pkColumn) - if sql == '': + if sql == "": self.uri.disableSelectAtId(False) else: self.uri.disableSelectAtId(True) def setDomainsAndRestrictionsWithQml(self, vlayer): - qmldir = '' + qmldir = "" try: qmldir, qmlType = self.abstractDb.getQml(vlayer.name()) except Exception as e: - QgsMessageLog.logMessage(':'.join(e.args), "DSGTools Plugin", Qgis.Critical) + QgsMessageLog.logMessage(":".join(e.args), "DSGTools Plugin", Qgis.Critical) return None - if qmlType == 'db': + if qmlType == "db": tempPath = os.path.join(os.path.dirname(__file__), "temp.qml") - with open(tempPath, "w", encoding='utf-8') as f: + with open(tempPath, "w", encoding="utf-8") as f: f.writelines(qmldir) f.close() vlayer.loadNamedStyle(tempPath, True) os.remove(tempPath) else: - vlayerQml = os.path.join(qmldir, vlayer.name()+'.qml') - #treat case of qml with multi + vlayerQml = os.path.join(qmldir, vlayer.name() + ".qml") + # treat case of qml with multi vlayer.loadNamedStyle(vlayerQml, True) return vlayer - + def removeEmptyNodes(self, dbNode): for geomNode in dbNode.children(): if not geomNode.findLayers(): @@ -226,31 +268,31 @@ def removeEmptyNodes(self, dbNode): for catNode in geomNode.children(): if not catNode.findLayers(): geomNode.removeChildNode(catNode) - + def getParams(self, inputParam): if isinstance(inputParam, dict): - lyrName = inputParam['lyrName'] - schema = inputParam['tableSchema'] - geomColumn = inputParam['geom'] - tableName = inputParam['tableName'] - srid = self.geomDict['tablePerspective'][tableName]['srid'] + lyrName = inputParam["lyrName"] + schema = inputParam["tableSchema"] + geomColumn = inputParam["geom"] + tableName = inputParam["tableName"] + srid = self.geomDict["tablePerspective"][tableName]["srid"] elif isinstance(inputParam, tuple): schema, tableName = inputParam lyrName = tableName - geomColumn, srid = '', '' + geomColumn, srid = "", "" else: lyrName = inputParam - tableName = self.geomDict['tablePerspective'][lyrName]['tableName'] - schema = self.geomDict['tablePerspective'][lyrName]['schema'] - geomColumn = self.geomDict['tablePerspective'][lyrName]['geometryColumn'] - srid = self.geomDict['tablePerspective'][lyrName]['srid'] + tableName = self.geomDict["tablePerspective"][lyrName]["tableName"] + schema = self.geomDict["tablePerspective"][lyrName]["schema"] + geomColumn = self.geomDict["tablePerspective"][lyrName]["geometryColumn"] + srid = self.geomDict["tablePerspective"][lyrName]["srid"] return lyrName, schema, geomColumn, tableName, srid def getLayerByName(self, layer): """ Return the layer layer from a given layer name. :param layer: (str) layer name. - :return: (QgsVectorLayer) vector layer. + :return: (QgsVectorLayer) vector layer. """ try: # self.provider is added on children classes @@ -262,7 +304,7 @@ def getComplexLayerByName(self, layer): """ Return the layer layer from a given layer name. :param layer: (str) layer name. - :return: (QgsVectorLayer) vector layer. + :return: (QgsVectorLayer) vector layer. """ try: # self.provider is added on children classes] @@ -270,8 +312,10 @@ def getComplexLayerByName(self, layer): return QgsVectorLayer(self.uri.uri(), table, self.provider) except: return None - - def buildJoin(self, originalLyr, originalLyrFieldName, joinnedLyr, joinLyrFieldName): + + def buildJoin( + self, originalLyr, originalLyrFieldName, joinnedLyr, joinLyrFieldName + ): """ Builds a join bewteen lyr and joinnedLyr. :param originalLyr: QgsVectorLayer original layer; @@ -284,7 +328,7 @@ def buildJoin(self, originalLyr, originalLyrFieldName, joinnedLyr, joinLyrFieldN joinObject.setTargetFieldName(originalLyrFieldName) joinObject.setJoinLayer(joinnedLyr) joinObject.setJoinFieldNamesSubset() - joinObject.upsertOnEdit(True) #set to enable edit on original lyr + joinObject.upsertOnEdit(True) # set to enable edit on original lyr joinObject.setCascadedDelete(True) joinObject.setDynamicFormEnabled(True) joinObject.setEditable(True) diff --git a/DsgTools/core/Factories/LayerLoaderFactory/geopackageLayerLoader.py b/DsgTools/core/Factories/LayerLoaderFactory/geopackageLayerLoader.py index fb7cd469f..1c8af6b7b 100644 --- a/DsgTools/core/Factories/LayerLoaderFactory/geopackageLayerLoader.py +++ b/DsgTools/core/Factories/LayerLoaderFactory/geopackageLayerLoader.py @@ -22,21 +22,28 @@ """ import os -from qgis.core import QgsVectorLayer, QgsMessageLog, QgsCoordinateReferenceSystem, Qgis, QgsProject +from qgis.core import ( + QgsVectorLayer, + QgsMessageLog, + QgsCoordinateReferenceSystem, + Qgis, + QgsProject, +) from .spatialiteLayerLoader import SpatialiteLayerLoader + class GeopackageLayerLoader(SpatialiteLayerLoader): def __init__(self, iface, abstractDb, loadCentroids): """Constructor.""" super(GeopackageLayerLoader, self).__init__(iface, abstractDb, loadCentroids) - - self.provider = 'geopackage' - + + self.provider = "geopackage" + try: dbVersion = abstractDb.getDatabaseVersion() except Exception as e: - QgsMessageLog.logMessage(':'.join(e.args), 'DSGTools Plugin', Qgis.Critical) + QgsMessageLog.logMessage(":".join(e.args), "DSGTools Plugin", Qgis.Critical) return self.buildUri() @@ -57,12 +64,16 @@ def loadLayer(self, inputParam, parentNode, uniqueLoad, stylePath, domLayerDict) return lyr vlayer = self.getLayerByName("{0}_{1}".format(schema, tableName)) if not vlayer.isValid(): - QgsMessageLog.logMessage(vlayer.error().summary(), "DSGTools Plugin", Qgis.Critical) - QgsProject.instance().addMapLayer(vlayer, addToLegend = False) - crs = QgsCoordinateReferenceSystem(int(srid), QgsCoordinateReferenceSystem.EpsgCrsId) + QgsMessageLog.logMessage( + vlayer.error().summary(), "DSGTools Plugin", Qgis.Critical + ) + QgsProject.instance().addMapLayer(vlayer, addToLegend=False) + crs = QgsCoordinateReferenceSystem( + int(srid), QgsCoordinateReferenceSystem.EpsgCrsId + ) vlayer.setCrs(crs) vlayer = self.setDomainsAndRestrictionsWithQml(vlayer) - vlayer = self.setMulti(vlayer,domLayerDict) + vlayer = self.setMulti(vlayer, domLayerDict) if stylePath: fullPath = self.getStyle(stylePath, tableName) if fullPath: @@ -75,11 +86,15 @@ def getLayerByName(self, layer): """ Return the layer layer from a given layer name. :param layer: (str) table name - for GPKG it is [SCHEMA]_[CATEGORY]_[CLASS]. - :return: (QgsVectorLayer) vector layer. + :return: (QgsVectorLayer) vector layer. """ # parent class reimplementation - schema = layer.split('_')[0] - table = layer[len(schema) + 1:] + schema = layer.split("_")[0] + table = layer[len(schema) + 1 :] lyrName, schema, geomColumn, tableName, srid = self.getParams(table) - self.setDataSource('', layer, geomColumn, '') - return QgsVectorLayer("{0}|layername={1}".format(self.abstractDb.db.databaseName(), layer), table, "ogr") + self.setDataSource("", layer, geomColumn, "") + return QgsVectorLayer( + "{0}|layername={1}".format(self.abstractDb.db.databaseName(), layer), + table, + "ogr", + ) diff --git a/DsgTools/core/Factories/LayerLoaderFactory/layerLoaderFactory.py b/DsgTools/core/Factories/LayerLoaderFactory/layerLoaderFactory.py index df6a661da..14ae83e12 100644 --- a/DsgTools/core/Factories/LayerLoaderFactory/layerLoaderFactory.py +++ b/DsgTools/core/Factories/LayerLoaderFactory/layerLoaderFactory.py @@ -27,6 +27,7 @@ from .geopackageLayerLoader import GeopackageLayerLoader from .shapefileLayerLoader import ShapefileLayerLoader + class LayerLoaderFactory(object): def makeLoader(self, iface, abstractDb, loadCentroids=False): """ @@ -37,9 +38,9 @@ def makeLoader(self, iface, abstractDb, loadCentroids=False): """ driverName = abstractDb.getType() loaders = { - 'GPKG' : lambda : GeopackageLayerLoader(iface, abstractDb, loadCentroids), - 'QSQLITE' : lambda : SpatialiteLayerLoader(iface, abstractDb, loadCentroids), - 'QPSQL' : lambda : PostGISLayerLoader(iface, abstractDb, loadCentroids), - 'SHP' : lambda : ShapefileLayerLoader(iface, abstractDb) + "GPKG": lambda: GeopackageLayerLoader(iface, abstractDb, loadCentroids), + "QSQLITE": lambda: SpatialiteLayerLoader(iface, abstractDb, loadCentroids), + "QPSQL": lambda: PostGISLayerLoader(iface, abstractDb, loadCentroids), + "SHP": lambda: ShapefileLayerLoader(iface, abstractDb), } return loaders[driverName]() if driverName in loaders else None diff --git a/DsgTools/core/Factories/LayerLoaderFactory/postgisLayerLoader.py b/DsgTools/core/Factories/LayerLoaderFactory/postgisLayerLoader.py index 97494bcfd..08dfad72d 100644 --- a/DsgTools/core/Factories/LayerLoaderFactory/postgisLayerLoader.py +++ b/DsgTools/core/Factories/LayerLoaderFactory/postgisLayerLoader.py @@ -24,22 +24,29 @@ from builtins import map, range, str # QGIS imports -from qgis.core import (Qgis, QgsCoordinateReferenceSystem, QgsDataSourceUri, - QgsEditorWidgetSetup, QgsMessageLog, QgsProject, - QgsVectorLayer) +from qgis.core import ( + Qgis, + QgsCoordinateReferenceSystem, + QgsDataSourceUri, + QgsEditorWidgetSetup, + QgsMessageLog, + QgsProject, + QgsVectorLayer, +) + # Qt imports from qgis.PyQt import QtCore, QtGui, uic from qgis.PyQt.Qt import QObject from qgis.PyQt.QtCore import pyqtSignal, pyqtSlot from qgis.utils import iface -from ....core.LayerTools.CustomFormTools.customFormGenerator import \ - CustomFormGenerator -from ....core.LayerTools.CustomFormTools.customInitCodeGenerator import \ - CustomInitCodeGenerator -from ....gui.CustomWidgets.BasicInterfaceWidgets.progressWidget import \ - ProgressWidget -#DsgTools imports +from ....core.LayerTools.CustomFormTools.customFormGenerator import CustomFormGenerator +from ....core.LayerTools.CustomFormTools.customInitCodeGenerator import ( + CustomInitCodeGenerator, +) +from ....gui.CustomWidgets.BasicInterfaceWidgets.progressWidget import ProgressWidget + +# DsgTools imports from .edgvLayerLoader import EDGVLayerLoader @@ -47,8 +54,8 @@ class PostGISLayerLoader(EDGVLayerLoader): def __init__(self, iface, abstractDb, loadCentroids): """Constructor.""" super(self.__class__, self).__init__(iface, abstractDb, loadCentroids) - - self.provider = 'postgres' + + self.provider = "postgres" self.setDatabaseConnection() self.buildUri() self.customFormGenerator = CustomFormGenerator() @@ -65,10 +72,14 @@ def checkLoaded(self, name): for ll in self.iface.mapCanvas().layers(): if ll.name() == name: candidateUri = QgsDataSourceUri(ll.dataProvider().dataSourceUri()) - if self.host == candidateUri.host() and self.database == candidateUri.database() and self.port == int(candidateUri.port()): + if ( + self.host == candidateUri.host() + and self.database == candidateUri.database() + and self.port == int(candidateUri.port()) + ): return ll return loaded - + def setDatabaseConnection(self): """ Sets database connection parameters @@ -79,15 +90,23 @@ def setDatabaseConnection(self): self.database = self.abstractDb.db.databaseName() self.user = self.abstractDb.db.userName() self.password = self.abstractDb.db.password() - + def buildUri(self): """ Builds the database uri :return: """ - self.uri.setConnection(str(self.host),str(self.port), str(self.database), str(self.user), str(self.password)) - - def filterLayerList(self, layerList, useInheritance, onlyWithElements, geomFilterList): + self.uri.setConnection( + str(self.host), + str(self.port), + str(self.database), + str(self.user), + str(self.password), + ) + + def filterLayerList( + self, layerList, useInheritance, onlyWithElements, geomFilterList + ): """ Filters the layers to be loaded :param layerList: list of layers @@ -97,27 +116,45 @@ def filterLayerList(self, layerList, useInheritance, onlyWithElements, geomFilte :return: """ filterList = [] - lyrsWithElements = self.abstractDb.getLayersWithElementsV2( - layerList, - useInheritance=useInheritance - ) if onlyWithElements else layerList + lyrsWithElements = ( + self.abstractDb.getLayersWithElementsV2( + layerList, useInheritance=useInheritance + ) + if onlyWithElements + else layerList + ) if len(geomFilterList) > 0: finalSet = set() for key in self.correspondenceDict: finalSet = finalSet.union( { - lyr for lyr in lyrsWithElements if self.correspondenceDict[key] in geomFilterList \ - and key in self.geomTypeDict and lyr in self.geomTypeDict[key] + lyr + for lyr in lyrsWithElements + if self.correspondenceDict[key] in geomFilterList + and key in self.geomTypeDict + and lyr in self.geomTypeDict[key] } ) finalList = list(finalSet) else: finalList = lyrsWithElements if finalList and isinstance(finalList[0], dict): - finalList = [i['tableName'] for i in finalList] + finalList = [i["tableName"] for i in finalList] return finalList - def load(self, inputList, useQml=False, uniqueLoad=False, useInheritance=False, stylePath=None, onlyWithElements=False, geomFilterList=[], customForm=False, loadEditingStructure=False, parent=None): + def load( + self, + inputList, + useQml=False, + uniqueLoad=False, + useInheritance=False, + stylePath=None, + onlyWithElements=False, + geomFilterList=[], + customForm=False, + loadEditingStructure=False, + parent=None, + ): """ 1. Get loaded layers 2. Filter layers; @@ -126,18 +163,24 @@ def load(self, inputList, useQml=False, uniqueLoad=False, useInheritance=False, 5. Build Groups; 6. Load Layers; """ - self.iface.mapCanvas().freeze() #done to speedup things + self.iface.mapCanvas().freeze() # done to speedup things layerList, isDictList = self.preLoadStep(inputList) - #2. Filter Layers: - filteredLayerList = self.filterLayerList(inputList, useInheritance, onlyWithElements, geomFilterList) - filteredDictList = [i for i in inputList if i['tableName'] in filteredLayerList] if isDictList else filteredLayerList + # 2. Filter Layers: + filteredLayerList = self.filterLayerList( + inputList, useInheritance, onlyWithElements, geomFilterList + ) + filteredDictList = ( + [i for i in inputList if i["tableName"] in filteredLayerList] + if isDictList + else filteredLayerList + ) edgvVersion = self.abstractDb.getDatabaseVersion() isEdgv = not edgvVersion == "Non_EDGV" rootNode = QgsProject.instance().layerTreeRoot() dbNode = self.getDatabaseGroup(rootNode) - #3. Load Domains + # 3. Load Domains domLayerDict = self.loadDomains(filteredLayerList, dbNode, edgvVersion) - #4. Get Aux dicts + # 4. Get Aux dicts domainDict = self.abstractDb.getDbDomainDict(self.geomDict) constraintDict = self.abstractDb.getCheckConstraintDict() multiColumnsDict = self.abstractDb.getMultiColumnsDict() @@ -147,10 +190,10 @@ def load(self, inputList, useQml=False, uniqueLoad=False, useInheritance=False, if customForm: self.filterDict = self.abstractDb.getFilterDict() self.rulesDict = dict() - - #5. Build Groups + + # 5. Build Groups groupDict = self.prepareGroups(dbNode, lyrDict) - #6. load layers + # 6. load layers loadedDict = dict() if parent: primNumber = 0 @@ -158,7 +201,9 @@ def load(self, inputList, useQml=False, uniqueLoad=False, useInheritance=False, for cat in list(lyrDict[prim].keys()): for lyr in lyrDict[prim][cat]: primNumber += 1 - localProgress = ProgressWidget(1, primNumber-1, self.tr('Loading layers... '), parent=parent) + localProgress = ProgressWidget( + 1, primNumber - 1, self.tr("Loading layers... "), parent=parent + ) for prim in list(lyrDict.keys()): for cat in list(lyrDict[prim].keys()): for lyr in lyrDict[prim][cat]: @@ -175,23 +220,41 @@ def load(self, inputList, useQml=False, uniqueLoad=False, useInheritance=False, domLayerDict=domLayerDict, edgvVersion=edgvVersion, editingDict=editingDict, - customForm = customForm + customForm=customForm, ) if vlayer is None: continue - key = lyr['lyrName'] if isinstance(lyr, dict) else lyr - loadedDict[key]=vlayer + key = lyr["lyrName"] if isinstance(lyr, dict) else lyr + loadedDict[key] = vlayer except Exception as e: - key = lyr['lyrName'] if isinstance(lyr, dict) else lyr - self.logErrorDict[key] = self.tr('Error for layer ')+key+': '+':'.join(e.args) + key = lyr["lyrName"] if isinstance(lyr, dict) else lyr + self.logErrorDict[key] = ( + self.tr("Error for layer ") + key + ": " + ":".join(e.args) + ) self.logError() if parent: localProgress.step() self.removeEmptyNodes(dbNode) - self.iface.mapCanvas().freeze(False) #done to speedup things + self.iface.mapCanvas().freeze(False) # done to speedup things return loadedDict - def loadLayer(self, inputParam, parentNode, useInheritance, useQml, uniqueLoad, stylePath, domainDict, multiColumnsDict, domLayerDict, edgvVersion, geomColumn = None, isView = False, editingDict=None, customForm = False): + def loadLayer( + self, + inputParam, + parentNode, + useInheritance, + useQml, + uniqueLoad, + stylePath, + domainDict, + multiColumnsDict, + domLayerDict, + edgvVersion, + geomColumn=None, + isView=False, + editingDict=None, + customForm=False, + ): """ Loads a layer :param lyrName: Layer name @@ -209,26 +272,35 @@ def loadLayer(self, inputParam, parentNode, useInheritance, useQml, uniqueLoad, schema=schema, layer=tableName, geomColumn=geomColumn, - sql='', - pkColumn=self.abstractDb.getPrimaryKeyColumn(f'''"{schema}"."{tableName}"''') + sql="", + pkColumn=self.abstractDb.getPrimaryKeyColumn( + f'''"{schema}"."{tableName}"''' + ), ) vlayer = QgsVectorLayer(self.uri.uri(), tableName, self.provider) - QgsProject.instance().addMapLayer(vlayer, addToLegend = False) - crs = QgsCoordinateReferenceSystem(int(srid), QgsCoordinateReferenceSystem.EpsgCrsId) + QgsProject.instance().addMapLayer(vlayer, addToLegend=False) + crs = QgsCoordinateReferenceSystem( + int(srid), QgsCoordinateReferenceSystem.EpsgCrsId + ) if vlayer is None: return vlayer if not vlayer.isValid(): - QgsMessageLog.logMessage(vlayer.error().summary(), "DSGTools Plugin", Qgis.Critical) + QgsMessageLog.logMessage( + vlayer.error().summary(), "DSGTools Plugin", Qgis.Critical + ) vlayer.setCrs(crs) - vlayer = self.setDomainsAndRestrictionsWithQml(vlayer) if useQml \ + vlayer = ( + self.setDomainsAndRestrictionsWithQml(vlayer) + if useQml else self.setDomainsAndRestrictions( lyr=vlayer, lyrName=tableName, domainDict=domainDict, multiColumnsDict=multiColumnsDict, - domLayerDict=domLayerDict + domLayerDict=domLayerDict, ) + ) if stylePath is not None: fullPath = self.getStyle(stylePath, tableName) if fullPath: @@ -240,7 +312,7 @@ def loadLayer(self, inputParam, parentNode, useInheritance, useQml, uniqueLoad, vlayer = self.createMeasureColumn(vlayer) parentNode.addLayer(vlayer) return vlayer - + def loadEditLayer(self, schema, tableName): """ Parses database to check which is the referenced edit layer and loads it @@ -248,18 +320,23 @@ def loadEditLayer(self, schema, tableName): :param tableName: original table name returns editLyr, joinLyrFieldName """ - editLyrSchema, editLyrTableName, pkName, joinLyrFieldName = self.abstractDb.getEditTable(schema, tableName) + ( + editLyrSchema, + editLyrTableName, + pkName, + joinLyrFieldName, + ) = self.abstractDb.getEditTable(schema, tableName) uri = """dbname='{database}' host={host} port={port} user='{user}' password='{password}' key={primary_key} table=\"{schema}\".\"{table}\" sql=""".format( - database=self.database, - host=self.host, - port=self.port, - user=self.user, - password=self.password, - primary_key=pkName, - schema=editLyrSchema, - table=editLyrTableName - ) - + database=self.database, + host=self.host, + port=self.port, + user=self.user, + password=self.password, + primary_key=pkName, + schema=editLyrSchema, + table=editLyrTableName, + ) + def loadDomain(self, domainTableName, domainGroup): """ Loads layer domains @@ -267,8 +344,18 @@ def loadDomain(self, domainTableName, domainGroup): :param domainGroup: :return: """ - #TODO: Avaliar se o table = deve ser diferente - uri = "dbname='%s' host=%s port=%s user='%s' password='%s' key=code table=\"dominios\".\"%s\" sql=" % (self.database, self.host, self.port, self.user, self.password, domainTableName) + # TODO: Avaliar se o table = deve ser diferente + uri = ( + "dbname='%s' host=%s port=%s user='%s' password='%s' key=code table=\"dominios\".\"%s\" sql=" + % ( + self.database, + self.host, + self.port, + self.user, + self.password, + domainTableName, + ) + ) domLayer = QgsVectorLayer(uri, domainTableName, self.provider) domainGroup.addLayer(domLayer) return domLayer @@ -282,7 +369,9 @@ def getStyleFromDb(self, edgvVersion, className): """ return self.abstractDb.getLyrStyle(edgvVersion, className) - def setDomainsAndRestrictions(self, lyr, lyrName, domainDict, multiColumnsDict, domLayerDict): + def setDomainsAndRestrictions( + self, lyr, lyrName, domainDict, multiColumnsDict, domLayerDict + ): """ Adjusts the domain restriction to all attributes in the layer :param lyr: @@ -296,39 +385,68 @@ def setDomainsAndRestrictions(self, lyr, lyrName, domainDict, multiColumnsDict, pkIdxList = lyr.primaryKeyAttributes() for i in range(len(lyrAttributes)): attrName = lyrAttributes[i].name() - if attrName == 'id' or 'id_' in lyrAttributes[i].name() or i in pkIdxList: - lyr.editFormConfig().setReadOnly(i,True) + if attrName == "id" or "id_" in lyrAttributes[i].name() or i in pkIdxList: + lyr.editFormConfig().setReadOnly(i, True) else: if lyrName in domainDict.keys(): - if attrName in list(domainDict[lyrName]['columns'].keys()): - refTable = domainDict[lyrName]['columns'][attrName]['references'] - refPk = domainDict[lyrName]['columns'][attrName]['refPk'] - otherKey = domainDict[lyrName]['columns'][attrName]['otherKey'] - valueDict = domainDict[lyrName]['columns'][attrName]['values'] + if attrName in list(domainDict[lyrName]["columns"].keys()): + refTable = domainDict[lyrName]["columns"][attrName][ + "references" + ] + refPk = domainDict[lyrName]["columns"][attrName]["refPk"] + otherKey = domainDict[lyrName]["columns"][attrName]["otherKey"] + valueDict = domainDict[lyrName]["columns"][attrName]["values"] isMulti = self.checkMulti(lyrName, attrName, multiColumnsDict) if isMulti: - #make filter - if 'constraintList' in list(domainDict[lyrName]['columns'][attrName].keys()): - #make editDict + # make filter + if "constraintList" in list( + domainDict[lyrName]["columns"][attrName].keys() + ): + # make editDict if lyrName in domLayerDict: if attrName in domLayerDict[lyrName]: - filter = '{0} in ({1})'.format(refPk,','.join(map(str,domainDict[lyrName]['columns'][attrName]['constraintList']))) - allowNull = domainDict[lyrName]['columns'][attrName]['nullable'] + filter = "{0} in ({1})".format( + refPk, + ",".join( + map( + str, + domainDict[lyrName]["columns"][ + attrName + ]["constraintList"], + ) + ), + ) + allowNull = domainDict[lyrName]["columns"][ + attrName + ]["nullable"] dom = domLayerDict[lyrName][attrName] - editDict = {'Layer':dom.id(),'Key':refPk,'Value':otherKey,'AllowMulti':True,'AllowNull':allowNull,'FilterExpression':filter} - widgetSetup = QgsEditorWidgetSetup('ValueRelation', editDict) + editDict = { + "Layer": dom.id(), + "Key": refPk, + "Value": otherKey, + "AllowMulti": True, + "AllowNull": allowNull, + "FilterExpression": filter, + } + widgetSetup = QgsEditorWidgetSetup( + "ValueRelation", editDict + ) lyr.setEditorWidgetSetup(i, widgetSetup) else: - #filter value dict - constraintList = domainDict[lyrName]['columns'][attrName]['constraintList'] + # filter value dict + constraintList = domainDict[lyrName]["columns"][attrName][ + "constraintList" + ] valueRelationDict = dict() for key in list(valueDict.keys()): - if len(constraintList) > 0: + if len(constraintList) > 0: if key in constraintList: valueRelationDict[valueDict[key]] = str(key) else: valueRelationDict[valueDict[key]] = str(key) - widgetSetup = QgsEditorWidgetSetup('ValueMap',{'map':valueRelationDict}) + widgetSetup = QgsEditorWidgetSetup( + "ValueMap", {"map": valueRelationDict} + ) lyr.setEditorWidgetSetup(i, widgetSetup) return lyr @@ -344,7 +462,7 @@ def checkMulti(self, tableName, attrName, multiColumnsDict): if attrName in multiColumnsDict[tableName]: return True return False - + def checkNotNull(self, lyrName, notNullDict): """ Checks not null attributes @@ -354,27 +472,31 @@ def checkNotNull(self, lyrName, notNullDict): """ allowNull = True if lyrName in list(notNullDict.keys()): - if attrName in notNullDict[lyrName]['attributes']: + if attrName in notNullDict[lyrName]["attributes"]: allowNull = False return allowNull def getPathUiForm(self, dbName, layerName): - #alterar - pathUiForm = os.path.join( - os.path.dirname(__file__), '..', '..', 'LayerTools', 'CustomFormTools', - 'formsCustom' , - '{0}_{1}.ui'.format(dbName, layerName) + # alterar + pathUiForm = os.path.join( + os.path.dirname(__file__), + "..", + "..", + "LayerTools", + "CustomFormTools", + "formsCustom", + "{0}_{1}.ui".format(dbName, layerName), ) return pathUiForm def newUiForm(self, pathUiForm): formFile = open(pathUiForm, "wb") return formFile - + def loadFormCustom(self, lyr): pathUiForm = self.getPathUiForm(self.database, lyr.name()) formFile = self.newUiForm(pathUiForm) - #inserir flag do filtro + # inserir flag do filtro withFilter = lyr.name() in self.filterDict self.customFormGenerator.create(formFile, lyr, withFilter=withFilter) lyr.editFormConfig().setInitCodeSource(2) @@ -390,7 +512,7 @@ def getRulesSelected(self, lyr): rules = [] # currentlayerName = lyr.name() # if self.getRules(): - # allRules = self.getRules().getRulesToForm() + # allRules = self.getRules().getRulesToForm() # selectedRuleOnOrder = { allRules["order_rules"][k.encode("utf-8")] : k.encode("utf-8") for k in data['selectedRulesType']} # for order in reversed(sorted(selectedRuleOnOrder)): # ruleName = selectedRuleOnOrder[order] @@ -406,7 +528,9 @@ def createCustomInitCode(self, lyr): # dbData = data['userData']['dbJson'][data['dbAlias']] # layerData = dbData[data['nameGeom']][data['nameCatLayer']][data['layerName']] if lyr.name() in list(self.filterDict.keys()): - initCode = self.customInitCodeGenerator.getInitCodeWithFilter(self.filterDict[lyr.name()], rules) #layerData['filter'] é o resultado da query select * from dominios. + initCode = self.customInitCodeGenerator.getInitCodeWithFilter( + self.filterDict[lyr.name()], rules + ) # layerData['filter'] é o resultado da query select * from dominios. return initCode else: initCode = self.customInitCodeGenerator.getInitCodeNotFilter(rules) @@ -416,20 +540,24 @@ def getLayerByName(self, layer): """ Return the layer layer from a given layer name. :param layer: (str) layer name. - :return: (QgsVectorLayer) vector layer. + :return: (QgsVectorLayer) vector layer. """ # parent class reimplementation - table = layer.split('.')[1] + table = layer.split(".")[1] return self.loadQgsVectorLayer(table) - - def loadQgsVectorLayer(self, inputParam, uniqueLoad=False, addToCanvas=False, nonSpatial=False): + + def loadQgsVectorLayer( + self, inputParam, uniqueLoad=False, addToCanvas=False, nonSpatial=False + ): """ Returns a QgsVectorLayer using the parameters from inputParam. If uniqueLoad=True, checks if layer is already loaded and if it is, returns it. """ try: - lyrName, schema, geomColumn, tableName, srid = self.getParams(inputParam=inputParam) + lyrName, schema, geomColumn, tableName, srid = self.getParams( + inputParam=inputParam + ) except: return None lyr = self.checkLoaded(tableName) @@ -437,8 +565,7 @@ def loadQgsVectorLayer(self, inputParam, uniqueLoad=False, addToCanvas=False, no return lyr pkColumn = self.abstractDb.getPrimaryKeyColumn( "{table_schema}.{table_name}".format( - table_schema=schema, - table_name=tableName + table_schema=schema, table_name=tableName ) ) if nonSpatial: @@ -450,23 +577,29 @@ def loadQgsVectorLayer(self, inputParam, uniqueLoad=False, addToCanvas=False, no password=self.password, pk=pkColumn, table_schema=schema, - table_name=tableName + table_name=tableName, ) else: - self.setDataSource(schema, tableName, geomColumn, '', pkColumn=pkColumn) + self.setDataSource(schema, tableName, geomColumn, "", pkColumn=pkColumn) uri = self.uri.uri() lyr = QgsVectorLayer(uri, tableName, self.provider) QgsProject.instance().addMapLayer(lyr, addToLegend=addToCanvas) return lyr - - def loadLayersInsideProcessing(self, inputParamList, uniqueLoad=False, addToCanvas=True, nonSpatial=False, feedback=None): + def loadLayersInsideProcessing( + self, + inputParamList, + uniqueLoad=False, + addToCanvas=True, + nonSpatial=False, + feedback=None, + ): """ Loads layer inside qgis using processing. If uniqueLoad=True, only loads if it is not loaded. """ outputLayers = [] - progressStep = 100/len(inputParamList) if len(inputParamList) else 0 + progressStep = 100 / len(inputParamList) if len(inputParamList) else 0 for current, inputParam in enumerate(inputParamList): if feedback is not None and feedback.isCanceled(): break @@ -474,10 +607,10 @@ def loadLayersInsideProcessing(self, inputParamList, uniqueLoad=False, addToCanv inputParam=inputParam, uniqueLoad=uniqueLoad, addToCanvas=addToCanvas, - nonSpatial=nonSpatial + nonSpatial=nonSpatial, ) if lyr is not None: outputLayers.append(lyr) if feedback is not None: - feedback.setProgress(current*progressStep) + feedback.setProgress(current * progressStep) return outputLayers diff --git a/DsgTools/core/Factories/LayerLoaderFactory/shapefileLayerLoader.py b/DsgTools/core/Factories/LayerLoaderFactory/shapefileLayerLoader.py index 75d0c055b..9494353a2 100644 --- a/DsgTools/core/Factories/LayerLoaderFactory/shapefileLayerLoader.py +++ b/DsgTools/core/Factories/LayerLoaderFactory/shapefileLayerLoader.py @@ -29,12 +29,22 @@ from qgis.PyQt.Qt import QObject # QGIS imports -from qgis.core import QgsVectorLayer, QgsDataSourceUri, QgsMessageLog, QgsCoordinateReferenceSystem, QgsMessageLog, Qgis, QgsProject, QgsEditorWidgetSetup +from qgis.core import ( + QgsVectorLayer, + QgsDataSourceUri, + QgsMessageLog, + QgsCoordinateReferenceSystem, + QgsMessageLog, + Qgis, + QgsProject, + QgsEditorWidgetSetup, +) -#DsgTools imports +# DsgTools imports from .edgvLayerLoader import EDGVLayerLoader from ....gui.CustomWidgets.BasicInterfaceWidgets.progressWidget import ProgressWidget + class ShapefileLayerLoader(EDGVLayerLoader): def __init__(self, iface, abstractDb): """ @@ -44,11 +54,11 @@ def __init__(self, iface, abstractDb): """ # no reason for centroids to be used, so it'll be set to False always (parent requirement to init) super(ShapefileLayerLoader, self).__init__(iface, abstractDb, False) - self.provider = 'shapefile' + self.provider = "shapefile" try: dbVersion = abstractDb.getDatabaseVersion() except Exception as e: - QgsMessageLog.logMessage(':'.join(e.args), 'DSGTools Plugin', Qgis.Critical) + QgsMessageLog.logMessage(":".join(e.args), "DSGTools Plugin", Qgis.Critical) return self.buildUri() @@ -58,11 +68,11 @@ def buildUri(self): :return: """ self.uri.setDatabase(self.abstractDb.databaseName()) - + def checkLoaded(self, name): """ Checks if the layers is already loaded in the QGIS' TOC - :param name: + :param name: :return: """ loaded = None @@ -74,7 +84,20 @@ def checkLoaded(self, name): return ll return loaded - def load(self, inputList, useQml=False, uniqueLoad=False, useInheritance=False, stylePath=None, onlyWithElements=False, geomFilterList=[], isEdgv=True, customForm=False, editingDict=None, parent=None): + def load( + self, + inputList, + useQml=False, + uniqueLoad=False, + useInheritance=False, + stylePath=None, + onlyWithElements=False, + geomFilterList=[], + isEdgv=True, + customForm=False, + editingDict=None, + parent=None, + ): """ 1. Get loaded layers 2. Filter layers; @@ -83,52 +106,68 @@ def load(self, inputList, useQml=False, uniqueLoad=False, useInheritance=False, 5. Build Groups; 6. Load Layers; """ - self.iface.mapCanvas().freeze() #done to speedup things + self.iface.mapCanvas().freeze() # done to speedup things layerList, isDictList = self.preLoadStep(inputList) - #2. Filter Layers: - filteredLayerList = self.filterLayerList(layerList, False, onlyWithElements, geomFilterList) - filteredDictList = [i for i in inputList if i['tableName'] in filteredLayerList] if isDictList else filteredLayerList + # 2. Filter Layers: + filteredLayerList = self.filterLayerList( + layerList, False, onlyWithElements, geomFilterList + ) + filteredDictList = ( + [i for i in inputList if i["tableName"] in filteredLayerList] + if isDictList + else filteredLayerList + ) edgvVersion = self.abstractDb.getDatabaseVersion() rootNode = QgsProject.instance().layerTreeRoot() dbNode = self.getDatabaseGroup(rootNode) - #3. Load Domains - #do this only if EDGV Version = FTer + # 3. Load Domains + # do this only if EDGV Version = FTer domLayerDict = self.loadDomains(filteredLayerList, dbNode, edgvVersion) - #4. Get Aux dicts - lyrDict = self.getLyrDict(filteredDictList, isEdgv = isEdgv) - #5. Build Groups + # 4. Get Aux dicts + lyrDict = self.getLyrDict(filteredDictList, isEdgv=isEdgv) + # 5. Build Groups groupDict = self.prepareGroups(dbNode, lyrDict) - #5. load layers + # 5. load layers if parent: primNumber = 0 for prim in list(lyrDict.keys()): for cat in list(lyrDict[prim].keys()): for lyr in lyrDict[prim][cat]: primNumber += 1 - localProgress = ProgressWidget(1, primNumber-1, self.tr('Loading layers... '), parent=parent) + localProgress = ProgressWidget( + 1, primNumber - 1, self.tr("Loading layers... "), parent=parent + ) loadedDict = dict() for prim in list(lyrDict.keys()): for cat in list(lyrDict[prim].keys()): for lyr in lyrDict[prim][cat]: try: - vlayer = self.loadLayer(lyr, groupDict[prim][cat], uniqueLoad, stylePath, domLayerDict) + vlayer = self.loadLayer( + lyr, + groupDict[prim][cat], + uniqueLoad, + stylePath, + domLayerDict, + ) if vlayer: if isinstance(lyr, dict): - key = lyr['lyrName'] + key = lyr["lyrName"] else: key = lyr - loadedDict[key]=vlayer + loadedDict[key] = vlayer except Exception as e: if isinstance(lyr, dict): - key = lyr['lyrName'] + key = lyr["lyrName"] else: key = lyr - self.logErrorDict[key] = self.tr('Error for layer ')+key+': '+':'.join(e.args) + self.logErrorDict[key] = ( + self.tr("Error for layer ") + key + ": " + ":".join(e.args) + ) self.logError() if parent: localProgress.step() self.removeEmptyNodes(dbNode) - self.iface.mapCanvas().freeze(False) #done to speedup things + self.iface.mapCanvas().freeze(False) # done to speedup things return loadedDict def loadLayer(self, inputParam, parentNode, uniqueLoad, stylePath, domLayerDict): @@ -145,21 +184,25 @@ def loadLayer(self, inputParam, parentNode, uniqueLoad, stylePath, domLayerDict) lyr = self.checkLoaded(tableName) if uniqueLoad and lyr: return lyr - self.setDataSource('', '_'.join([schema,tableName]), geomColumn, '') + self.setDataSource("", "_".join([schema, tableName]), geomColumn, "") vlayer = QgsVectorLayer(self.uri.uri(), tableName, self.provider) - QgsProject.instance().addMapLayer(vlayer, addToLegend = False) - crs = QgsCoordinateReferenceSystem(int(srid), QgsCoordinateReferenceSystem.EpsgCrsId) + QgsProject.instance().addMapLayer(vlayer, addToLegend=False) + crs = QgsCoordinateReferenceSystem( + int(srid), QgsCoordinateReferenceSystem.EpsgCrsId + ) vlayer.setCrs(crs) vlayer = self.setDomainsAndRestrictionsWithQml(vlayer) - vlayer = self.setMulti(vlayer,domLayerDict) + vlayer = self.setMulti(vlayer, domLayerDict) if stylePath: fullPath = self.getStyle(stylePath, tableName) if fullPath: vlayer.loadNamedStyle(fullPath, True) - parentNode.addLayer(vlayer) + parentNode.addLayer(vlayer) if not vlayer.isValid(): - QgsMessageLog.logMessage(vlayer.error().summary(), "DSGTools Plugin", Qgis.Critical) + QgsMessageLog.logMessage( + vlayer.error().summary(), "DSGTools Plugin", Qgis.Critical + ) vlayer = self.createMeasureColumn(vlayer) return vlayer @@ -170,11 +213,11 @@ def loadDomain(self, domainTableName, domainGroup): :param domainGroup: :return: """ - #TODO: Avaliar se o table = deve ser diferente + # TODO: Avaliar se o table = deve ser diferente uri = QgsDataSourceUri() uri.setDatabase(self.abstractDb.db.databaseName()) - uri.setDataSource('', 'dominios_'+domainTableName, None) - #TODO Load domain layer into a group + uri.setDataSource("", "dominios_" + domainTableName, None) + # TODO Load domain layer into a group domLayer = iface.addVectorLayer(uri.uri(), domainTableName, self.provider) self.iface.legendInterface().moveLayer(domLayer, domainGroup) return domLayer @@ -182,7 +225,9 @@ def loadDomain(self, domainTableName, domainGroup): def getStyleFromDb(self, edgvVersion, className): return None - def filterLayerList(self, layerList, useInheritance, onlyWithElements, geomFilterList): + def filterLayerList( + self, layerList, useInheritance, onlyWithElements, geomFilterList + ): """ Filters the layers to be loaded :param layerList: list of layers @@ -193,7 +238,9 @@ def filterLayerList(self, layerList, useInheritance, onlyWithElements, geomFilte """ filterList = [] if onlyWithElements: - semifinalList = self.abstractDb.getLayersWithElementsV2(layerList, useInheritance=False) + semifinalList = self.abstractDb.getLayersWithElementsV2( + layerList, useInheritance=False + ) else: semifinalList = layerList if len(geomFilterList) > 0: @@ -202,12 +249,12 @@ def filterLayerList(self, layerList, useInheritance, onlyWithElements, geomFilte if self.correspondenceDict[key] in geomFilterList: if key in self.geomTypeDict: for lyr in semifinalList: - if lyr in self.geomTypeDict[key] and lyr not in finalList: + if lyr in self.geomTypeDict[key] and lyr not in finalList: finalList.append(lyr) else: finalList = semifinalList return finalList - + def setMulti(self, vlayer, domLayerDict): """ Sets attributes with value relation @@ -215,15 +262,15 @@ def setMulti(self, vlayer, domLayerDict): :param domLayerDict: :return: """ - #sweep vlayer to find v2 + # sweep vlayer to find v2 attrList = vlayer.fields() for field in attrList: i = attrList.lookupField(field.name()) editorWidgetSetup = vlayer.editorWidgetSetup(i) - if editorWidgetSetup.type() == 'ValueRelation': + if editorWidgetSetup.type() == "ValueRelation": valueRelationDict = editorWidgetSetup.config() domLayer = domLayerDict[vlayer.name()][field.name()] - valueRelationDict['Layer'] = domLayer.id() + valueRelationDict["Layer"] = domLayer.id() vlayer.setEditorWidgetSetup(i, valueRelationDict) return vlayer @@ -231,10 +278,10 @@ def getLayerByName(self, layer): """ Return the layer layer from a given layer name. :param layer: (str) layer name. - :return: (QgsVectorLayer) vector layer. + :return: (QgsVectorLayer) vector layer. """ # parent class reimplementation path = os.path.join(self.abstractDb.databaseName(), "{0}.shp".format(layer)) - schema = layer.split('_')[0] - table = layer[len(schema) + 1:].lower() + schema = layer.split("_")[0] + table = layer[len(schema) + 1 :].lower() return QgsVectorLayer(path, table, "ogr") diff --git a/DsgTools/core/Factories/LayerLoaderFactory/spatialiteLayerLoader.py b/DsgTools/core/Factories/LayerLoaderFactory/spatialiteLayerLoader.py index d6a522c88..45f22f436 100644 --- a/DsgTools/core/Factories/LayerLoaderFactory/spatialiteLayerLoader.py +++ b/DsgTools/core/Factories/LayerLoaderFactory/spatialiteLayerLoader.py @@ -24,29 +24,32 @@ import json from collections import defaultdict -from qgis.core import (Qgis, - QgsProject, - QgsMessageLog, - QgsVectorLayer, - QgsDataSourceUri, - QgsEditorWidgetSetup, - QgsCoordinateReferenceSystem) +from qgis.core import ( + Qgis, + QgsProject, + QgsMessageLog, + QgsVectorLayer, + QgsDataSourceUri, + QgsEditorWidgetSetup, + QgsCoordinateReferenceSystem, +) from qgis.PyQt.QtSql import QSqlQuery from .edgvLayerLoader import EDGVLayerLoader from ....gui.CustomWidgets.BasicInterfaceWidgets.progressWidget import ProgressWidget + class SpatialiteLayerLoader(EDGVLayerLoader): def __init__(self, iface, abstractDb, loadCentroids): """Constructor.""" super(SpatialiteLayerLoader, self).__init__(iface, abstractDb, loadCentroids) - - self.provider = 'spatialite' - + + self.provider = "spatialite" + try: dbVersion = abstractDb.getDatabaseVersion() except Exception as e: - QgsMessageLog.logMessage(':'.join(e.args), 'DSGTools Plugin', Qgis.Critical) + QgsMessageLog.logMessage(":".join(e.args), "DSGTools Plugin", Qgis.Critical) return self.buildUri() @@ -57,11 +60,11 @@ def buildUri(self): :return: """ self.uri.setDatabase(self.abstractDb.db.databaseName()) - + def checkLoaded(self, name): """ Checks if the layers is already loaded in the QGIS' TOC - :param name: + :param name: :return: """ loaded = None @@ -77,7 +80,7 @@ def specialEdgvAttributes(self): """ Gets the list of attributes shared by many EDGV classes and have a different domain depending on which category the EDGV class belongs to. - :return: (list-of-str) list of "special" EDGV classes. + :return: (list-of-str) list of "special" EDGV classes. """ return ["finalidade", "relacionado", "coincidecomdentrode", "tipo"] @@ -105,14 +108,15 @@ def domainMapping(self, modelVersion): } """ basePath = os.path.join( - os.path.dirname(__file__), "..", "..", "DbModels", "DomainMapping") + os.path.dirname(__file__), "..", "..", "DbModels", "DomainMapping" + ) path = { "EDGV 3.0": os.path.join(basePath, "edgv_3.json"), "3.0": os.path.join(basePath, "edgv_3.json"), "EDGV 2.1.3 Pro": os.path.join(basePath, "edgv_213_pro.json"), "2.1.3 Pro": os.path.join(basePath, "edgv_213_pro.json"), "EDGV 2.1.3": os.path.join(basePath, "edgv_213.json"), - "2.1.3": os.path.join(basePath, "edgv_213.json") + "2.1.3": os.path.join(basePath, "edgv_213.json"), }.pop(modelVersion, None) if path is None or not os.path.exists(path): return dict() @@ -133,7 +137,7 @@ def getAllEdgvDomainsFromTableName(self, schema, table): edgv = self.abstractDb.getDatabaseVersion() domainMap = self.domainMapping(edgv) fullTablaName = schema + "_" + table - sql = 'select code, code_name from dominios_{field} order by code' + sql = "select code, code_name from dominios_{field} order by code" for fieldName in self.tableFields(fullTablaName): if fullTablaName in domainMap: domains = domainMap[fullTablaName] @@ -165,7 +169,19 @@ def getAllEdgvDomainsFromTableName(self, schema, table): ret[fieldName][code_name] = code return ret - def load(self, inputList, useQml=False, uniqueLoad=False, useInheritance=False, stylePath=None, onlyWithElements=False, geomFilterList=[], customForm=False, editingDict=None, parent=None): + def load( + self, + inputList, + useQml=False, + uniqueLoad=False, + useInheritance=False, + stylePath=None, + onlyWithElements=False, + geomFilterList=[], + customForm=False, + editingDict=None, + parent=None, + ): """ 1. Get loaded layers 2. Filter layers; @@ -174,11 +190,17 @@ def load(self, inputList, useQml=False, uniqueLoad=False, useInheritance=False, 5. Build Groups; 6. Load Layers; """ - self.iface.mapCanvas().freeze() #done to speedup things + self.iface.mapCanvas().freeze() # done to speedup things layerList, isDictList = self.preLoadStep(inputList) - #2. Filter Layers: - filteredLayerList = self.filterLayerList(layerList, False, onlyWithElements, geomFilterList) - filteredDictList = [i for i in inputList if i['tableName'] in filteredLayerList] if isDictList else filteredLayerList + # 2. Filter Layers: + filteredLayerList = self.filterLayerList( + layerList, False, onlyWithElements, geomFilterList + ) + filteredDictList = ( + [i for i in inputList if i["tableName"] in filteredLayerList] + if isDictList + else filteredLayerList + ) edgvVersion = self.abstractDb.getDatabaseVersion() isEdgv = not edgvVersion == "Non_EDGV" rootNode = QgsProject.instance().layerTreeRoot() @@ -191,41 +213,51 @@ def load(self, inputList, useQml=False, uniqueLoad=False, useInheritance=False, # loaded in any of our current use cases, this will be ignored and set to an # empty dict domLayerDict = dict() - #4. Get Aux dicts - lyrDict = self.getLyrDict(filteredDictList, isEdgv = isEdgv) - #5. Build Groups + # 4. Get Aux dicts + lyrDict = self.getLyrDict(filteredDictList, isEdgv=isEdgv) + # 5. Build Groups groupDict = self.prepareGroups(dbNode, lyrDict) - #5. load layers + # 5. load layers if parent: primNumber = 0 for prim in list(lyrDict.keys()): for cat in list(lyrDict[prim].keys()): for lyr in lyrDict[prim][cat]: primNumber += 1 - localProgress = ProgressWidget(1, primNumber-1, self.tr('Loading layers... '), parent=parent) + localProgress = ProgressWidget( + 1, primNumber - 1, self.tr("Loading layers... "), parent=parent + ) loadedDict = dict() for prim in list(lyrDict.keys()): for cat in list(lyrDict[prim].keys()): for lyr in lyrDict[prim][cat]: try: - vlayer = self.loadLayer(lyr, groupDict[prim][cat], uniqueLoad, stylePath, domLayerDict) + vlayer = self.loadLayer( + lyr, + groupDict[prim][cat], + uniqueLoad, + stylePath, + domLayerDict, + ) if vlayer: if isinstance(lyr, dict): - key = lyr['lyrName'] + key = lyr["lyrName"] else: key = lyr - loadedDict[key]=vlayer + loadedDict[key] = vlayer except Exception as e: if isinstance(lyr, dict): - key = lyr['lyrName'] + key = lyr["lyrName"] else: key = lyr - self.logErrorDict[key] = self.tr('Error for layer ')+key+': '+':'.join(e.args) + self.logErrorDict[key] = ( + self.tr("Error for layer ") + key + ": " + ":".join(e.args) + ) self.logError() if parent: localProgress.step() self.removeEmptyNodes(dbNode) - self.iface.mapCanvas().freeze(False) #done to speedup things + self.iface.mapCanvas().freeze(False) # done to speedup things return loadedDict def loadLayer(self, inputParam, parentNode, uniqueLoad, stylePath, domLayerDict): @@ -242,11 +274,13 @@ def loadLayer(self, inputParam, parentNode, uniqueLoad, stylePath, domLayerDict) lyr = self.checkLoaded(tableName) if uniqueLoad and lyr: return lyr - self.setDataSource('', '_'.join([schema,tableName]), geomColumn, '') + self.setDataSource("", "_".join([schema, tableName]), geomColumn, "") vlayer = QgsVectorLayer(self.uri.uri(), tableName, self.provider) - QgsProject.instance().addMapLayer(vlayer, addToLegend = False) - crs = QgsCoordinateReferenceSystem(int(srid), QgsCoordinateReferenceSystem.EpsgCrsId) + QgsProject.instance().addMapLayer(vlayer, addToLegend=False) + crs = QgsCoordinateReferenceSystem( + int(srid), QgsCoordinateReferenceSystem.EpsgCrsId + ) vlayer.setCrs(crs) # vlayer = self.setDomainsAndRestrictionsWithQml(vlayer) # vlayer = self.setMulti(vlayer, domLayerDict) @@ -282,11 +316,11 @@ def loadDomain(self, domainTableName, domainGroup): :param domainGroup: :return: """ - #TODO: Avaliar se o table = deve ser diferente + # TODO: Avaliar se o table = deve ser diferente uri = QgsDataSourceUri() uri.setDatabase(self.abstractDb.db.databaseName()) - uri.setDataSource('', 'dominios_'+domainTableName, None) - #TODO Load domain layer into a group + uri.setDataSource("", "dominios_" + domainTableName, None) + # TODO Load domain layer into a group domLayer = self.iface.addVectorLayer(uri.uri(), domainTableName, self.provider) self.iface.legendInterface().moveLayer(domLayer, domainGroup) return domLayer @@ -294,7 +328,9 @@ def loadDomain(self, domainTableName, domainGroup): def getStyleFromDb(self, edgvVersion, className): return None - def filterLayerList(self, layerList, useInheritance, onlyWithElements, geomFilterList): + def filterLayerList( + self, layerList, useInheritance, onlyWithElements, geomFilterList + ): """ Filters the layers to be loaded :param layerList: list of layers @@ -305,7 +341,9 @@ def filterLayerList(self, layerList, useInheritance, onlyWithElements, geomFilte """ filterList = [] if onlyWithElements: - semifinalList = self.abstractDb.getLayersWithElementsV2(layerList, useInheritance=False) + semifinalList = self.abstractDb.getLayersWithElementsV2( + layerList, useInheritance=False + ) else: semifinalList = layerList if len(geomFilterList) > 0: @@ -314,12 +352,12 @@ def filterLayerList(self, layerList, useInheritance, onlyWithElements, geomFilte if self.correspondenceDict[key] in geomFilterList: if key in self.geomTypeDict: for lyr in semifinalList: - if lyr in self.geomTypeDict[key] and lyr not in finalList: + if lyr in self.geomTypeDict[key] and lyr not in finalList: finalList.append(lyr) else: finalList = semifinalList return finalList - + def setMulti(self, vlayer, domLayerDict): """ Sets attributes with value relation @@ -327,15 +365,15 @@ def setMulti(self, vlayer, domLayerDict): :param domLayerDict: :return: """ - #sweep vlayer to find v2 + # sweep vlayer to find v2 attrList = vlayer.fields() for field in attrList: i = attrList.lookupField(field.name()) editorWidgetSetup = vlayer.editorWidgetSetup(i) - if editorWidgetSetup.type() == 'ValueRelation': + if editorWidgetSetup.type() == "ValueRelation": valueRelationDict = editorWidgetSetup.config() domLayer = domLayerDict[vlayer.name()][field.name()] - valueRelationDict['Layer'] = domLayer.id() + valueRelationDict["Layer"] = domLayer.id() vlayer.setEditorWidgetSetup(i, valueRelationDict) return vlayer @@ -343,11 +381,11 @@ def getLayerByName(self, layer): """ Return the layer layer from a given layer name. :param layer: (str) layer name. - :return: (QgsVectorLayer) vector layer. + :return: (QgsVectorLayer) vector layer. """ # parent class reimplementation - schema = layer.split('_')[0] - table = layer[len(schema) + 1:] + schema = layer.split("_")[0] + table = layer[len(schema) + 1 :] lyrName, schema, geomColumn, tableName, srid = self.getParams(table) - self.setDataSource('', layer, geomColumn, '') + self.setDataSource("", layer, geomColumn, "") return QgsVectorLayer(self.uri.uri(), table, self.provider) diff --git a/DsgTools/core/Factories/SqlFactory/geopackageSqlGenerator.py b/DsgTools/core/Factories/SqlFactory/geopackageSqlGenerator.py index bb2386d58..23cf7cac0 100644 --- a/DsgTools/core/Factories/SqlFactory/geopackageSqlGenerator.py +++ b/DsgTools/core/Factories/SqlFactory/geopackageSqlGenerator.py @@ -23,8 +23,8 @@ from .spatialiteSqlGenerator import SpatialiteSqlGenerator from DsgTools.core.dsgEnums import DsgEnums -class GeopackageSqlGenerator(SpatialiteSqlGenerator): +class GeopackageSqlGenerator(SpatialiteSqlGenerator): def getEDGVVersion(self): """ Gets the version of the data model. @@ -32,7 +32,7 @@ def getEDGVVersion(self): sql = "SELECT edgvversion FROM db_metadata LIMIT 1" return sql - def getSrid(self, parameters = dict()): + def getSrid(self, parameters=dict()): """ Gets SRID for selected database (it is assumed all tables have the same SRID). """ @@ -43,7 +43,7 @@ def getGeomTablesFromGeometryColumns(self, edgvVersion): """ Gets a dict for tables and their geometry columns. """ - sql = 'select srs_id, column_name, geometry_type_name, table_name from gpkg_geometry_columns' + sql = "select srs_id, column_name, geometry_type_name, table_name from gpkg_geometry_columns" return sql def getGeomByPrimitive(self, edgvVersion): @@ -55,11 +55,13 @@ def getGeomColumnDict(self): return sql def getFullTablesName(self, name): - sql = "SELECT table_name as name FROM gpkg_geometry_columns WHERE table_name LIKE '%{0}%' ORDER BY name".format(name) + sql = "SELECT table_name as name FROM gpkg_geometry_columns WHERE table_name LIKE '%{0}%' ORDER BY name".format( + name + ) return sql - def getGeomColumnTupleList(self, edgvVersion, showViews = False): - if edgvVersion in ('2.1.3','FTer_2a_Ed'): + def getGeomColumnTupleList(self, edgvVersion, showViews=False): + if edgvVersion in ("2.1.3", "FTer_2a_Ed"): sql = """select table_name, column_name, geometry_type_name from gpkg_geometry_columns""" else: sql = """select table_name, column_name, geometry_type_name from gpkg_geometry_columns""" @@ -69,14 +71,16 @@ def getTablesFromDatabase(self): sql = "SELECT tbl_name as name, type FROM sqlite_master WHERE type='table' ORDER BY name" return sql - def getStructure(self,edgvVersion): - sql = '' - if edgvVersion == '2.1.3': - sql = 'select tbl_name as name, sql from sqlite_master where type = \'table\' and (name like \'cb_%\' or name like \'complexos_%\' or name like \'public_%\')' - elif edgvVersion == 'FTer_2a_Ed': - sql = 'select tbl_name as name, sql from sqlite_master where type = \'table\' and (name like \'ge_%\' or name like \'pe_%\' or name like \'complexos_%\' or name like \'public_%\')' - elif edgvVersion == '3.0': - sql = sql = 'select tbl_name as name, sql from sqlite_master where type = \'table\' and (name like \'edgv_%\' or name like \'complexos_%\' or name like \'public_%\')' + def getStructure(self, edgvVersion): + sql = "" + if edgvVersion == "2.1.3": + sql = "select tbl_name as name, sql from sqlite_master where type = 'table' and (name like 'cb_%' or name like 'complexos_%' or name like 'public_%')" + elif edgvVersion == "FTer_2a_Ed": + sql = "select tbl_name as name, sql from sqlite_master where type = 'table' and (name like 'ge_%' or name like 'pe_%' or name like 'complexos_%' or name like 'public_%')" + elif edgvVersion == "3.0": + sql = ( + sql + ) = "select tbl_name as name, sql from sqlite_master where type = 'table' and (name like 'edgv_%' or name like 'complexos_%' or name like 'public_%')" return sql def getComplexTablesFromDatabase(self): diff --git a/DsgTools/core/Factories/SqlFactory/postgisSqlGenerator.py b/DsgTools/core/Factories/SqlFactory/postgisSqlGenerator.py index b9cd110e7..a6e806cfa 100644 --- a/DsgTools/core/Factories/SqlFactory/postgisSqlGenerator.py +++ b/DsgTools/core/Factories/SqlFactory/postgisSqlGenerator.py @@ -25,11 +25,16 @@ from .sqlGenerator import SqlGenerator from ...dsgEnums import DsgEnums -DB_ENCODING = 'utf-8' +DB_ENCODING = "utf-8" + + class PostGISSqlGenerator(SqlGenerator): - def getComplexLinks(self, complex): - sql = "SELECT complex_schema, complex, aggregated_schema, aggregated_class, column_name from complex_schema where complex = \'"+complex+'\'' + sql = ( + "SELECT complex_schema, complex, aggregated_schema, aggregated_class, column_name from complex_schema where complex = '" + + complex + + "'" + ) return sql def getComplexTablesFromDatabase(self): @@ -37,38 +42,76 @@ def getComplexTablesFromDatabase(self): return sql def getComplexData(self, complex_schema, complex): - sql = "SELECT id, nome from "+complex_schema+"."+complex - return sql - - def getAssociatedFeaturesData(self, aggregated_schema, aggregated_class, column_name, complex_uuid): - sql = "SELECT id from only "+aggregated_schema+"."+aggregated_class+" where "+column_name+"="+'\''+complex_uuid+'\'' + sql = "SELECT id, nome from " + complex_schema + "." + complex + return sql + + def getAssociatedFeaturesData( + self, aggregated_schema, aggregated_class, column_name, complex_uuid + ): + sql = ( + "SELECT id from only " + + aggregated_schema + + "." + + aggregated_class + + " where " + + column_name + + "=" + + "'" + + complex_uuid + + "'" + ) return sql def getLinkColumn(self, complexClass, aggregatedClass): - sql = "SELECT column_name from complex_schema where complex = \'"+complexClass+'\''+" and aggregated_class = "+'\''+aggregatedClass+'\'' + sql = ( + "SELECT column_name from complex_schema where complex = '" + + complexClass + + "'" + + " and aggregated_class = " + + "'" + + aggregatedClass + + "'" + ) return sql - def getSrid(self, parameters = dict()): + def getSrid(self, parameters=dict()): if parameters == dict(): - sql = "SELECT DISTINCT srid from geometry_columns WHERE f_table_schema <> \'tiger\' and f_table_schema <> \'topology\' LIMIT 1" + sql = "SELECT DISTINCT srid from geometry_columns WHERE f_table_schema <> 'tiger' and f_table_schema <> 'topology' LIMIT 1" else: whereClauseList = [] - if 'tableSchema' in list(parameters.keys()): - whereClauseList.append("""f_table_schema = '{0}'""".format(parameters['tableSchema'])) - if 'tableName' in list(parameters.keys()): - whereClauseList.append("""f_table_name = '{0}'""".format(parameters['tableName'])) - if 'geometryColumn' in list(parameters.keys()): - whereClauseList.append("""f_geometry_column = '{0}'""".format(parameters['geometryColumn'])) - whereClause = ' AND '.join(whereClauseList) - sql = """SELECT DISTINCT srid from geometry_columns WHERE {0} LIMIT 1""".format(whereClause) + if "tableSchema" in list(parameters.keys()): + whereClauseList.append( + """f_table_schema = '{0}'""".format(parameters["tableSchema"]) + ) + if "tableName" in list(parameters.keys()): + whereClauseList.append( + """f_table_name = '{0}'""".format(parameters["tableName"]) + ) + if "geometryColumn" in list(parameters.keys()): + whereClauseList.append( + """f_geometry_column = '{0}'""".format(parameters["geometryColumn"]) + ) + whereClause = " AND ".join(whereClauseList) + sql = """SELECT DISTINCT srid from geometry_columns WHERE {0} LIMIT 1""".format( + whereClause + ) return sql def getTablesFromDatabase(self): - sql = "select distinct table_schema, table_name from information_schema.columns where (table_schema <> \'dominios\' and table_schema <> \'topology\')" + sql = "select distinct table_schema, table_name from information_schema.columns where (table_schema <> 'dominios' and table_schema <> 'topology')" return sql def disassociateComplexFromComplex(self, aggregated_class, link_column, uuid): - sql = "UPDATE complexos."+aggregated_class+" SET "+link_column+"=NULL WHERE id = "+'\''+uuid+'\'' + sql = ( + "UPDATE complexos." + + aggregated_class + + " SET " + + link_column + + "=NULL WHERE id = " + + "'" + + uuid + + "'" + ) return sql def getTemplates(self): @@ -76,89 +119,125 @@ def getTemplates(self): return sql def allowConnections(self, name): - sql = "ALTER DATABASE "+name+" SET search_path = public, topology, cb, cc, complexos, ct;" + sql = ( + "ALTER DATABASE " + + name + + " SET search_path = public, topology, cb, cc, complexos, ct;" + ) return sql - def loadLayerFromDatabase(self, layer_name, pkColumn='id'): - layer_name = '"."'.join(layer_name.replace('"','').split('.')) - sql = '''{1} in (SELECT {1} FROM ONLY "{0}")'''.format(layer_name, pkColumn) + def loadLayerFromDatabase(self, layer_name, pkColumn="id"): + layer_name = '"."'.join(layer_name.replace('"', "").split(".")) + sql = """{1} in (SELECT {1} FROM ONLY "{0}")""".format(layer_name, pkColumn) return sql - def loadLayerFromDatabaseUsingInh(self, layer_name, pkColumn='id'): - layer_name = '"."'.join(layer_name.replace('"','').split('.')) - sql = '''{1} in (SELECT {1} FROM ONLY "{0}")'''.format(layer_name, pkColumn) + def loadLayerFromDatabaseUsingInh(self, layer_name, pkColumn="id"): + layer_name = '"."'.join(layer_name.replace('"', "").split(".")) + sql = """{1} in (SELECT {1} FROM ONLY "{0}")""".format(layer_name, pkColumn) return sql - def getCreateDatabase(self, name, dropIfExists = False): - sql = '' + def getCreateDatabase(self, name, dropIfExists=False): + sql = "" if dropIfExists: - sql+= """DROP DATABASE IF EXISTS "{0}";""".format(name) + sql += """DROP DATABASE IF EXISTS "{0}";""".format(name) sql += """CREATE DATABASE "{0}";""".format(name) return sql def insertFrameIntoTable(self, wkt): - sql = "INSERT INTO aux_moldura_a(geom) VALUES(ST_GeomFromText("+wkt+"))" + sql = "INSERT INTO aux_moldura_a(geom) VALUES(ST_GeomFromText(" + wkt + "))" return sql def getElementCountFromLayer(self, table): sql = "SELECT count(id) FROM ONLY {0} limit 1".format(table) return sql - + def getElementCountFromLayerV2(self, schema, table, useInheritance): if useInheritance == False: - sql = '''SELECT count(a) FROM ( SELECT * FROM ONLY "{0}"."{1}" ) as a'''.format(schema,table) + sql = """SELECT count(a) FROM ( SELECT * FROM ONLY "{0}"."{1}" ) as a""".format( + schema, table + ) else: - sql = '''SELECT count(a) FROM ( SELECT * FROM "{0}"."{1}" ) as a'''.format(schema,table) + sql = """SELECT count(a) FROM ( SELECT * FROM "{0}"."{1}" ) as a""".format( + schema, table + ) return sql def getElementCountFromLayerWithInh(self, layer): - sql = "SELECT count(*) FROM "+layer + sql = "SELECT count(*) FROM " + layer return sql - + def getDatabasesFromServer(self): - sql = "SELECT datname FROM pg_database where datname <> \'postgres\' and datname <> \'template\' and datname <> \'template0\' and datname <> \'template_postgis\' and datistemplate = 'f'" + sql = "SELECT datname FROM pg_database where datname <> 'postgres' and datname <> 'template' and datname <> 'template0' and datname <> 'template_postgis' and datistemplate = 'f'" return sql - + def dropDatabase(self, name): sql = """DROP DATABASE "{0}" """.format(name) return sql - + def createRole(self, roleName, mydict): sql = """CREATE ROLE "{0}" with NOLOGIN REPLICATION;\n""".format(roleName) for db in list(mydict.keys()): for schema in list(mydict[db].keys()): for cat in list(mydict[db][schema].keys()): for tableName in list(mydict[db][schema][cat].keys()): - table = '''"{0}"."{1}"'''.format(schema,tableName) + table = '''"{0}"."{1}"'''.format(schema, tableName) read = mydict[db][schema][cat][tableName]["read"] write = mydict[db][schema][cat][tableName]["write"] - if write == '2': - sql+="""GRANT ALL ON {0} TO "{1}";\n""".format(table,roleName) - elif read == '2': - sql+="""GRANT SELECT ON {0} TO "{1}";\n""".format(table,roleName) - sql += """GRANT ALL ON SCHEMA "{0}" TO "{1}";\n""".format(schema,roleName) - sql += """REVOKE CREATE ON SCHEMA "{0}" FROM "{1}";\n""".format(schema,roleName) - sql += """GRANT USAGE ON SCHEMA "{0}" TO "{1}";\n""".format(schema,roleName) - sql += """GRANT EXECUTE ON ALL FUNCTIONS IN SCHEMA "{0}" TO "{1}";\n""".format(schema,roleName) - sql += """GRANT USAGE ON ALL SEQUENCES IN SCHEMA "{0}" TO "{1}";\n""".format(schema,roleName) - + if write == "2": + sql += """GRANT ALL ON {0} TO "{1}";\n""".format( + table, roleName + ) + elif read == "2": + sql += """GRANT SELECT ON {0} TO "{1}";\n""".format( + table, roleName + ) + sql += """GRANT ALL ON SCHEMA "{0}" TO "{1}";\n""".format( + schema, roleName + ) + sql += """REVOKE CREATE ON SCHEMA "{0}" FROM "{1}";\n""".format( + schema, roleName + ) + sql += """GRANT USAGE ON SCHEMA "{0}" TO "{1}";\n""".format( + schema, roleName + ) + sql += """GRANT EXECUTE ON ALL FUNCTIONS IN SCHEMA "{0}" TO "{1}";\n""".format( + schema, roleName + ) + sql += """GRANT USAGE ON ALL SEQUENCES IN SCHEMA "{0}" TO "{1}";\n""".format( + schema, roleName + ) + # not needed anymore due to our generic approach - #sql += """GRANT SELECT ON db_metadata TO "{0}";\n""".format(roleName) - sql += """GRANT SELECT ON public.geometry_columns TO "{0}";\n""".format(roleName) - sql += """GRANT ALL ON ALL TABLES IN SCHEMA information_schema TO "{0}";\n""".format(roleName) - sql += """GRANT ALL ON ALL TABLES IN SCHEMA pg_catalog TO "{0}";\n""".format(roleName) + # sql += """GRANT SELECT ON db_metadata TO "{0}";\n""".format(roleName) + sql += """GRANT SELECT ON public.geometry_columns TO "{0}";\n""".format( + roleName + ) + sql += """GRANT ALL ON ALL TABLES IN SCHEMA information_schema TO "{0}";\n""".format( + roleName + ) + sql += """GRANT ALL ON ALL TABLES IN SCHEMA pg_catalog TO "{0}";\n""".format( + roleName + ) sql += """GRANT ALL ON SCHEMA information_schema TO "{0}";\n""".format(roleName) sql += """GRANT ALL ON SCHEMA pg_catalog TO "{0}";\n""".format(roleName) - sql += """REVOKE CREATE ON SCHEMA information_schema FROM "{0}";\n""".format(roleName) + sql += """REVOKE CREATE ON SCHEMA information_schema FROM "{0}";\n""".format( + roleName + ) sql += """REVOKE CREATE ON SCHEMA pg_catalog FROM "{0}";\n""".format(roleName) - sql += """GRANT USAGE ON SCHEMA information_schema TO "{0}";\n""".format(roleName) + sql += """GRANT USAGE ON SCHEMA information_schema TO "{0}";\n""".format( + roleName + ) sql += """GRANT USAGE ON SCHEMA pg_catalog TO "{0}";\n""".format(roleName) - sql += """GRANT USAGE ON ALL SEQUENCES IN SCHEMA information_schema TO "{0}";\n""".format(roleName) - sql += """GRANT USAGE ON ALL SEQUENCES IN SCHEMA pg_catalog TO "{0}" """.format(roleName) + sql += """GRANT USAGE ON ALL SEQUENCES IN SCHEMA information_schema TO "{0}";\n""".format( + roleName + ) + sql += """GRANT USAGE ON ALL SEQUENCES IN SCHEMA pg_catalog TO "{0}" """.format( + roleName + ) return sql def dropRole(self, role): - sql = '''CREATE OR REPLACE FUNCTION droprole(name text) RETURNS void AS $BODY$ + sql = """CREATE OR REPLACE FUNCTION droprole(name text) RETURNS void AS $BODY$ DECLARE s text; BEGIN @@ -180,119 +259,140 @@ def dropRole(self, role): END LOOP; EXECUTE 'REVOKE ALL ON db_metadata FROM '|| name; RETURN; - + END $BODY$ LANGUAGE plpgsql;# - ''' - sql += 'SELECT droprole(\''+role+'\')#' - sql += 'DROP ROLE IF EXISTS '+role + """ + sql += "SELECT droprole('" + role + "')#" + sql += "DROP ROLE IF EXISTS " + role return sql - + def grantRole(self, user, role): - sql = 'GRANT '+role+' TO '+user + sql = "GRANT " + role + " TO " + user return sql - + def revokeRole(self, user, role): - sql = 'REVOKE '+role+' FROM '+user + sql = "REVOKE " + role + " FROM " + user return sql - + def getRoles(self): - sql = 'SELECT rolname FROM pg_roles WHERE rolname <> \'postgres\' AND rolcanlogin = \'f\' AND rolname in (select split_part(unnest(nspacl)::text, \'=\', 1) from pg_namespace where nspname = \'pg_catalog\')' + sql = "SELECT rolname FROM pg_roles WHERE rolname <> 'postgres' AND rolcanlogin = 'f' AND rolname in (select split_part(unnest(nspacl)::text, '=', 1) from pg_namespace where nspname = 'pg_catalog')" return sql def getUserRelatedRoles(self, username): - sql = '''select rolname, usename from - (select * from pg_roles as r where r.rolcanlogin = \'f\' and r.rolname<>\'postgres\') as listaRoles left join - (select * from pg_auth_members as m join pg_user as u on m.member = u.usesysid and u.usename=\'%s\') + sql = ( + """select rolname, usename from + (select * from pg_roles as r where r.rolcanlogin = \'f\' and r.rolname<>\'postgres\') as listaRoles left join + (select * from pg_auth_members as m join pg_user as u on m.member = u.usesysid and u.usename=\'%s\') as euTenho on euTenho.roleid=listaRoles.oid where rolname in (select split_part(unnest(nspacl)::text, \'=\', 1) from pg_namespace where nspname = \'pg_catalog\') - ''' % username + """ + % username + ) return sql - + def getUsers(self): - sql = 'SELECT usename FROM pg_user WHERE usename <> \'postgres\'' + sql = "SELECT usename FROM pg_user WHERE usename <> 'postgres'" return sql - - def createUser(self,user,password,isSuperuser): + + def createUser(self, user, password, isSuperuser): if isSuperuser: - sql = 'CREATE ROLE '+user+' WITH SUPERUSER CREATEDB CREATEROLE REPLICATION LOGIN PASSWORD \''+password+'\';' + sql = ( + "CREATE ROLE " + + user + + " WITH SUPERUSER CREATEDB CREATEROLE REPLICATION LOGIN PASSWORD '" + + password + + "';" + ) else: - sql = 'CREATE ROLE '+user+' WITH LOGIN PASSWORD \''+password+'\';' - return sql - - def removeUser(self,user): - sql = 'DROP ROLE '+user - return sql - - def alterUserPass(self,user,newPass): - sql = 'ALTER ROLE '+user+' WITH PASSWORD \''+newPass+'\'' - return sql - - def validateWithDomain(self,schemaList): - schemas = '\''+'\',\''.join(schemaList)+'\'' - sql = '''SELECT - tc.table_schema,tc.table_name, kcu.column_name, + sql = "CREATE ROLE " + user + " WITH LOGIN PASSWORD '" + password + "';" + return sql + + def removeUser(self, user): + sql = "DROP ROLE " + user + return sql + + def alterUserPass(self, user, newPass): + sql = "ALTER ROLE " + user + " WITH PASSWORD '" + newPass + "'" + return sql + + def validateWithDomain(self, schemaList): + schemas = "'" + "','".join(schemaList) + "'" + sql = ( + """SELECT + tc.table_schema,tc.table_name, kcu.column_name, ccu.table_name AS foreign_table_name, ccu.column_name AS foreign_column_name, 'SELECT ' || ccu.column_name || ' FROM dominios.' || ccu.table_name || ' ORDER BY ' || ccu.column_name || ' ASC' - FROM - information_schema.table_constraints AS tc + FROM + information_schema.table_constraints AS tc JOIN information_schema.key_column_usage AS kcu ON tc.constraint_name = kcu.constraint_name JOIN information_schema.constraint_column_usage AS ccu ON ccu.constraint_name = tc.constraint_name - WHERE constraint_type = 'FOREIGN KEY' and tc.constraint_schema in (%s)''' % schemas + WHERE constraint_type = 'FOREIGN KEY' and tc.constraint_schema in (%s)""" + % schemas + ) return sql - - def getTableDomains(self,tableList): - schemas = '\''+'\',\''.join(tableList)+'\'' - sql = '''SELECT - tc.table_schema,tc.table_name, kcu.column_name, + + def getTableDomains(self, tableList): + schemas = "'" + "','".join(tableList) + "'" + sql = ( + """SELECT + tc.table_schema,tc.table_name, kcu.column_name, ccu.table_name AS foreign_table_name, ccu.column_name AS foreign_column_name, 'SELECT ' || ccu.column_name || ' FROM dominios.' || ccu.table_name || ' ORDER BY ' || ccu.column_name || ' ASC' - FROM - information_schema.table_constraints AS tc + FROM + information_schema.table_constraints AS tc JOIN information_schema.key_column_usage AS kcu ON tc.constraint_name = kcu.constraint_name JOIN information_schema.constraint_column_usage AS ccu ON ccu.constraint_name = tc.constraint_name - WHERE constraint_type = 'FOREIGN KEY' and tc.constraint_schema in (%s)''' % schemas - return sql - - def getNotNullFields(self,schemaList): - schemas = '\''+'\',\''.join(schemaList)+'\'' - sql = 'select table_schema, table_name, column_name from information_schema.columns where is_nullable = \'NO\' and column_name not in (\'id\',\'geom\') and table_schema in (%s)' % schemas - return sql - - def getFeaturesWithSQL(self,layer,attrList): - ls = ','.join(attrList) - sql = 'SELECT %s FROM ONLY %s' % (ls,layer) - return sql - - def getStructure(self,edgvVersion): - sql = '' - if edgvVersion == '2.1.3': - sql = 'SELECT table_schema, table_name, column_name FROM INFORMATION_SCHEMA.COLUMNS where table_schema in (\'cb\',\'complexos\',\'public\')' - elif edgvVersion == 'FTer_2a_Ed': - sql = 'SELECT table_schema, table_name, column_name FROM INFORMATION_SCHEMA.COLUMNS where table_schema in (\'ge\',\'pe\',\'complexos\',\'public\')' - elif edgvVersion == '3.0': - sql = 'SELECT table_schema, table_name, column_name FROM INFORMATION_SCHEMA.COLUMNS where table_schema in (\'edgv\',\'complexos\',\'public\')' - return sql - + WHERE constraint_type = 'FOREIGN KEY' and tc.constraint_schema in (%s)""" + % schemas + ) + return sql + + def getNotNullFields(self, schemaList): + schemas = "'" + "','".join(schemaList) + "'" + sql = ( + "select table_schema, table_name, column_name from information_schema.columns where is_nullable = 'NO' and column_name not in ('id','geom') and table_schema in (%s)" + % schemas + ) + return sql + + def getFeaturesWithSQL(self, layer, attrList): + ls = ",".join(attrList) + sql = "SELECT %s FROM ONLY %s" % (ls, layer) + return sql + + def getStructure(self, edgvVersion): + sql = "" + if edgvVersion == "2.1.3": + sql = "SELECT table_schema, table_name, column_name FROM INFORMATION_SCHEMA.COLUMNS where table_schema in ('cb','complexos','public')" + elif edgvVersion == "FTer_2a_Ed": + sql = "SELECT table_schema, table_name, column_name FROM INFORMATION_SCHEMA.COLUMNS where table_schema in ('ge','pe','complexos','public')" + elif edgvVersion == "3.0": + sql = "SELECT table_schema, table_name, column_name FROM INFORMATION_SCHEMA.COLUMNS where table_schema in ('edgv','complexos','public')" + return sql + def getAggregationColumn(self): - sql = 'SELECT DISTINCT column_name FROM public.complex_schema' + sql = "SELECT DISTINCT column_name FROM public.complex_schema" return sql - + def getAggregatorFromId(self, className, id): - sql = 'SELECT id from %s where id =\'%s\'' % (className,id) - return sql - - def getAggregatorFromComplexSchema(self,aggregated,aggregationColumn): - sql = 'SELECT complex from public.complex_schema where aggregated_class = \'%s\' and aggregationColumn = \'%s\'' % (aggregated,aggregationColumn) + sql = "SELECT id from %s where id ='%s'" % (className, id) + return sql + + def getAggregatorFromComplexSchema(self, aggregated, aggregationColumn): + sql = ( + "SELECT complex from public.complex_schema where aggregated_class = '%s' and aggregationColumn = '%s'" + % (aggregated, aggregationColumn) + ) return sql - + def createCustomSort(self): - sql = '''CREATE OR REPLACE FUNCTION + sql = """CREATE OR REPLACE FUNCTION array_sort_dsg( array_vals_to_sort anyarray ) @@ -314,23 +414,30 @@ def createCustomSort(self): END; $BODY$ LANGUAGE plpgsql; - ''' + """ return sql - + def getRolePrivileges(self, role, dbname): - sql = 'SELECT * FROM information_schema.role_table_grants where grantee = \'%s\' and table_catalog = \'%s\' ORDER BY table_name' % (role, dbname) + sql = ( + "SELECT * FROM information_schema.role_table_grants where grantee = '%s' and table_catalog = '%s' ORDER BY table_name" + % (role, dbname) + ) return sql - - def isSuperUser(self,user): - sql = 'SELECT rolsuper FROM pg_roles WHERE rolname = \'%s\'' % user + + def isSuperUser(self, user): + sql = "SELECT rolsuper FROM pg_roles WHERE rolname = '%s'" % user return sql def getInvalidGeom(self, tableSchema, tableName, geometryColumn, keyColumn): - return '''select distinct f."{3}" as "{3}",(reason(ST_IsValidDetail(f."{2}",0))), (location(ST_IsValidDetail(f."{2}",0))) as "{2}" from (select "{3}", "{2}" from only "{0}"."{1}" where ST_IsValid("{2}") = 'f') as f'''.format(tableSchema, tableName, geometryColumn, keyColumn) - + return """select distinct f."{3}" as "{3}",(reason(ST_IsValidDetail(f."{2}",0))), (location(ST_IsValidDetail(f."{2}",0))) as "{2}" from (select "{3}", "{2}" from only "{0}"."{1}" where ST_IsValid("{2}") = 'f') as f""".format( + tableSchema, tableName, geometryColumn, keyColumn + ) + def getNonSimpleGeom(self, tableSchema, tableName): - return '''select f.id as id,(reason(ST_IsValidDetail(f.geom,0))), (location(ST_IsValidDetail(f.geom,0))) as geom from (select id, geom from only "{0}"."{1}" where ST_IsSimple(geom) = 'f') as f'''.format(tableSchema,tableName) - + return """select f.id as id,(reason(ST_IsValidDetail(f.geom,0))), (location(ST_IsValidDetail(f.geom,0))) as geom from (select id, geom from only "{0}"."{1}" where ST_IsSimple(geom) = 'f') as f""".format( + tableSchema, tableName + ) + def checkValidationStructure(self): return "select count(*) from information_schema.columns where table_name = 'aux_flags_validacao'" @@ -348,22 +455,22 @@ def createValidationStructure(self, srid): CONSTRAINT aux_flags_validacao_pk PRIMARY KEY (id) WITH (FILLFACTOR = 100) )# - + CREATE TABLE validation.aux_flags_validacao_p ( geom geometry(MULTIPOINT, %s) NOT NULL, CONSTRAINT aux_flags_validacao_p_pk PRIMARY KEY (id) )INHERITS(validation.aux_flags_validacao)# - + CREATE TABLE validation.aux_flags_validacao_l ( geom geometry(MULTILINESTRING, %s) NOT NULL, CONSTRAINT aux_flags_validacao_l_pk PRIMARY KEY (id) )INHERITS(validation.aux_flags_validacao)# - + CREATE TABLE validation.aux_flags_validacao_a ( geom geometry(MULTIPOLYGON, %s) NOT NULL, CONSTRAINT aux_flags_validacao_a_pk PRIMARY KEY (id) )INHERITS(validation.aux_flags_validacao)# - + CREATE TABLE validation.status ( id smallint NOT NULL, @@ -378,7 +485,7 @@ def createValidationStructure(self, srid): finished timestamp NOT NULL default now(), CONSTRAINT process_history_pk PRIMARY KEY (id), CONSTRAINT process_history_status_fk FOREIGN KEY (status) REFERENCES validation.status (id) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION - + )# CREATE TABLE validation.settings( id serial NOT NULL, @@ -388,40 +495,75 @@ def createValidationStructure(self, srid): CONSTRAINT settings_pk PRIMARY KEY (id) )# INSERT INTO validation.settings(earthcoverage) VALUES (NULL)# - INSERT INTO validation.status(id,status) VALUES (0,'Not yet ran'), (1,'Finished'), (2,'Failed'), (3,'Running'), (4,'Finished with flags') - """ % (srid, srid, srid) + INSERT INTO validation.status(id,status) VALUES (0,'Not yet ran'), (1,'Finished'), (2,'Failed'), (3,'Running'), (4,'Finished with flags') + """ % ( + srid, + srid, + srid, + ) return sql - + def validationStatus(self, processName): - sql = "SELECT status FROM validation.process_history where process_name = '%s' ORDER BY finished DESC LIMIT 1; " % processName + sql = ( + "SELECT status FROM validation.process_history where process_name = '%s' ORDER BY finished DESC LIMIT 1; " + % processName + ) return sql - + def validationStatusText(self, processName): - sql = "SELECT sta.status FROM validation.process_history as hist left join validation.status as sta on sta.id = hist.status where hist.process_name = '%s' ORDER BY hist.finished DESC LIMIT 1 " % processName + sql = ( + "SELECT sta.status FROM validation.process_history as hist left join validation.status as sta on sta.id = hist.status where hist.process_name = '%s' ORDER BY hist.finished DESC LIMIT 1 " + % processName + ) return sql - - def setValidationStatusQuery(self, processName,log,status): - sql = "INSERT INTO validation.process_history (process_name, log, status) values ('%s','%s',%s)" % (processName,log,status) + + def setValidationStatusQuery(self, processName, log, status): + sql = ( + "INSERT INTO validation.process_history (process_name, log, status) values ('%s','%s',%s)" + % (processName, log, status) + ) return sql - - def insertFlagIntoDb(self, layer, feat_id, reason, geom, srid, processName, dimension, geometryColumn, flagSRID): + + def insertFlagIntoDb( + self, + layer, + feat_id, + reason, + geom, + srid, + processName, + dimension, + geometryColumn, + flagSRID, + ): if dimension == 0: - tableName = 'aux_flags_validacao_p' + tableName = "aux_flags_validacao_p" elif dimension == 1: - tableName = 'aux_flags_validacao_l' + tableName = "aux_flags_validacao_l" elif dimension == 2: - tableName = 'aux_flags_validacao_a' - sql = u"""INSERT INTO validation.{0} (process_name, layer, feat_id, reason, geom, dimension, geometry_column) values - ('{1}','{2}',{3},'{4}',ST_Transform(ST_SetSRID(ST_Multi('{5}'),{6}),{7}), {8}, '{9}');""".format(tableName, processName, layer, str(feat_id), reason, geom, srid, flagSRID, dimension, geometryColumn) + tableName = "aux_flags_validacao_a" + sql = """INSERT INTO validation.{0} (process_name, layer, feat_id, reason, geom, dimension, geometry_column) values + ('{1}','{2}',{3},'{4}',ST_Transform(ST_SetSRID(ST_Multi('{5}'),{6}),{7}), {8}, '{9}');""".format( + tableName, + processName, + layer, + str(feat_id), + reason, + geom, + srid, + flagSRID, + dimension, + geometryColumn, + ) return sql - + def getRunningProc(self): sql = "SELECT process_name, status FROM validation.process_history ORDER BY finished DESC LIMIT 1;" return sql - + def deleteFlags(self, processName=None, className=None, flagId=None): if not processName and not className and not flagId: - whereClause = '' + whereClause = "" else: clauseList = [] if processName: @@ -438,85 +580,162 @@ def deleteFlags(self, processName=None, className=None, flagId=None): except TypeError: flagClause = """id = {0} """.format(flagId) clauseList.append(flagClause) - whereClause = """where {0}""".format(' AND '.join(clauseList)) + whereClause = """where {0}""".format(" AND ".join(clauseList)) sql = """ - DELETE FROM validation.aux_flags_validacao_p - WHERE id in + DELETE FROM validation.aux_flags_validacao_p + WHERE id in (SELECT id FROM validation.aux_flags_validacao_p {0})# - - DELETE FROM validation.aux_flags_validacao_l - WHERE id in + + DELETE FROM validation.aux_flags_validacao_l + WHERE id in (SELECT id FROM validation.aux_flags_validacao_l {0})# - DELETE FROM validation.aux_flags_validacao_a - WHERE id in + DELETE FROM validation.aux_flags_validacao_a + WHERE id in (SELECT id FROM validation.aux_flags_validacao_a {0}) - """.format(whereClause) + """.format( + whereClause + ) return sql - - def testSpatialRule(self, class_a, necessity, predicate_function, class_b, min_card, max_card, aKeyColumn, bKeyColumn, aGeomColumn, bGeomColumn): - #TODO: Add SRIDS - class_a = '"'+'"."'.join(class_a.replace('"','').split('.'))+'"' - class_b = '"'+'"."'.join(class_b.replace('"','').split('.'))+'"' + + def testSpatialRule( + self, + class_a, + necessity, + predicate_function, + class_b, + min_card, + max_card, + aKeyColumn, + bKeyColumn, + aGeomColumn, + bGeomColumn, + ): + # TODO: Add SRIDS + class_a = '"' + '"."'.join(class_a.replace('"', "").split(".")) + '"' + class_b = '"' + '"."'.join(class_b.replace('"', "").split(".")) + '"' # checking if the rule checks the layer with itself - if class_a!=class_b: - sameClassRestriction='' + if class_a != class_b: + sameClassRestriction = "" else: - sameClassRestriction=' WHERE a.{0} <> b.{1} '.format(aKeyColumn, bKeyColumn) - - if predicate_function == 'ST_Disjoint': - if necessity == '\'f\'': + sameClassRestriction = " WHERE a.{0} <> b.{1} ".format( + aKeyColumn, bKeyColumn + ) + + if predicate_function == "ST_Disjoint": + if necessity == "'f'": sql = """SELECT DISTINCT foo.id, foo.geom FROM - (SELECT a.{4} id, SUM(CASE WHEN {0}(a.{6},b.{7}) = 'f' THEN 1 ELSE 0 END) count, a.{6} geom + (SELECT a.{4} id, SUM(CASE WHEN {0}(a.{6},b.{7}) = 'f' THEN 1 ELSE 0 END) count, a.{6} geom FROM {1} as a,{2} as b {3} GROUP BY a.{4}, a.{6}) as foo WHERE foo.count > 0 - """.format(predicate_function, class_a, class_b, sameClassRestriction, aKeyColumn, bKeyColumn, aGeomColumn, bGeomColumn) - elif necessity == '\'t\'': + """.format( + predicate_function, + class_a, + class_b, + sameClassRestriction, + aKeyColumn, + bKeyColumn, + aGeomColumn, + bGeomColumn, + ) + elif necessity == "'t'": sql = """SELECT DISTINCT foo.id, foo.geom FROM - (SELECT a.{4} id, SUM(CASE WHEN {0}(a.{6},b.{7}) = 'f' THEN 1 ELSE 0 END) count, a.{6} geom + (SELECT a.{4} id, SUM(CASE WHEN {0}(a.{6},b.{7}) = 'f' THEN 1 ELSE 0 END) count, a.{6} geom FROM {1} as a,{2} as b {3} GROUP BY a.{4}, a.{6}) as foo WHERE foo.count = 0 - """.format(predicate_function, class_a, class_b, sameClassRestriction, aKeyColumn, bKeyColumn, aGeomColumn, bGeomColumn) + """.format( + predicate_function, + class_a, + class_b, + sameClassRestriction, + aKeyColumn, + bKeyColumn, + aGeomColumn, + bGeomColumn, + ) else: - if necessity == '\'f\'':# must (be) - if max_card == '*': + if necessity == "'f'": # must (be) + if max_card == "*": sql = """SELECT DISTINCT foo.id, foo.geom FROM - (SELECT a.{4} id, SUM(CASE WHEN {0}(a.{6},b.{7}) THEN 1 ELSE 0 END) count, a.{6} geom + (SELECT a.{4} id, SUM(CASE WHEN {0}(a.{6},b.{7}) THEN 1 ELSE 0 END) count, a.{6} geom FROM {1} as a,{2} as b {3} GROUP BY a.{4}, a.{6}) as foo WHERE foo.count < {8} - """.format(predicate_function, class_a, class_b, sameClassRestriction, aKeyColumn, bKeyColumn, aGeomColumn, bGeomColumn, min_card) + """.format( + predicate_function, + class_a, + class_b, + sameClassRestriction, + aKeyColumn, + bKeyColumn, + aGeomColumn, + bGeomColumn, + min_card, + ) elif min_card is None and max_card is None: sql = """SELECT DISTINCT foo.id, foo.geom FROM - (SELECT a.{4} id, SUM(CASE WHEN {0}(a.{6},b.{7}) THEN 1 ELSE 0 END) count, a.{6} geom + (SELECT a.{4} id, SUM(CASE WHEN {0}(a.{6},b.{7}) THEN 1 ELSE 0 END) count, a.{6} geom FROM {1} as a,{2} as b {3} GROUP BY a.{4}, a.{6}) as foo WHERE foo.count != 0; - """.format(predicate_function, class_a, class_b, sameClassRestriction, aKeyColumn, bKeyColumn, aGeomColumn, bGeomColumn, min_card) + """.format( + predicate_function, + class_a, + class_b, + sameClassRestriction, + aKeyColumn, + bKeyColumn, + aGeomColumn, + bGeomColumn, + min_card, + ) else: sql = """SELECT DISTINCT foo.id, foo.geom FROM - (SELECT a.{4} id, SUM(CASE WHEN {0}(a.{6},b.{7}) THEN 1 ELSE 0 END) count, a.{6} geom + (SELECT a.{4} id, SUM(CASE WHEN {0}(a.{6},b.{7}) THEN 1 ELSE 0 END) count, a.{6} geom FROM {1} as a,{2} as b {3} GROUP BY a.{4}, a.{6}) as foo WHERE foo.count < {8} OR foo.count > {9} - """.format(predicate_function, class_a, class_b, sameClassRestriction, aKeyColumn, bKeyColumn, aGeomColumn, bGeomColumn, min_card, max_card) - elif necessity == '\'t\'':# must not (be) - if class_a!=class_b: - sameClassRestriction='' + """.format( + predicate_function, + class_a, + class_b, + sameClassRestriction, + aKeyColumn, + bKeyColumn, + aGeomColumn, + bGeomColumn, + min_card, + max_card, + ) + elif necessity == "'t'": # must not (be) + if class_a != class_b: + sameClassRestriction = "" else: - sameClassRestriction=' AND a.{0} <> b.{1} '.format(aKeyColumn, bKeyColumn) - + sameClassRestriction = " AND a.{0} <> b.{1} ".format( + aKeyColumn, bKeyColumn + ) + sql = """SELECT DISTINCT a.{5} id, (ST_Dump(ST_Intersection(a.{7}, b.{8}))).geom as geom - FROM {0} as a, {1} as b + FROM {0} as a, {1} as b WHERE {2}(a.{7},b.{8}) = {3} {4} - """.format(class_a, class_b, predicate_function, necessity, sameClassRestriction, aKeyColumn, bKeyColumn, aGeomColumn, bGeomColumn) + """.format( + class_a, + class_b, + predicate_function, + necessity, + sameClassRestriction, + aKeyColumn, + bKeyColumn, + aGeomColumn, + bGeomColumn, + ) return sql - + def getDimension(self, geom): sql = "select ST_Dimension('%s')" % geom return sql - - def getMulti(self,cl): - #TODO: get pk - cl = '"'+'"."'.join(cl.replace('"','').split('.'))+'"' + + def getMulti(self, cl): + # TODO: get pk + cl = '"' + '"."'.join(cl.replace('"', "").split(".")) + '"' sql = """select id from only {0} where ST_NumGeometries(geom) > 1""".format(cl) return sql @@ -524,26 +743,34 @@ def getDuplicatedGeom(self, schema, cl, geometryColumn, keyColumn): sql = """select * from ( SELECT "{3}", ROW_NUMBER() OVER(PARTITION BY "{2}" ORDER BY "{3}" asc) AS Row, - geom FROM ONLY "{0}"."{1}" + geom FROM ONLY "{0}"."{1}" ) dups - where - dups.Row > 1""".format(schema, cl, geometryColumn, keyColumn) + where + dups.Row > 1""".format( + schema, cl, geometryColumn, keyColumn + ) return sql - + def getSmallAreas(self, schema, cl, areaTolerance, geometryColumn, keyColumn): sql = """select foo2."{4}", foo2."{3}" from ( - select "{4}", "{3}", ST_Area("{3}") as area from "{0}"."{1}" - ) as foo2 where foo2.area < {2} order by foo2."{4}" """.format(schema, cl, areaTolerance, geometryColumn, keyColumn) + select "{4}", "{3}", ST_Area("{3}") as area from "{0}"."{1}" + ) as foo2 where foo2.area < {2} order by foo2."{4}" """.format( + schema, cl, areaTolerance, geometryColumn, keyColumn + ) return sql - + def getSmallLines(self, schema, cl, areaTolerance, geometryColumn, keyColumn): sql = """select foo2."{4}", foo2."{3}" from ( - select "{4}", "{3}", ST_Length("{3}") as len from "{0}"."{1}" - ) as foo2 where len < {2} order by foo2."{4}" """.format(schema, cl, areaTolerance, geometryColumn, keyColumn) + select "{4}", "{3}", ST_Length("{3}") as len from "{0}"."{1}" + ) as foo2 where len < {2} order by foo2."{4}" """.format( + schema, cl, areaTolerance, geometryColumn, keyColumn + ) return sql - - def prepareVertexNearEdgesStruct(self, tableSchema, tableName, geometryColumn, keyColumn, geomType): - if 'POLYGON' in geomType: + + def prepareVertexNearEdgesStruct( + self, tableSchema, tableName, geometryColumn, keyColumn, geomType + ): + if "POLYGON" in geomType: sql = """drop table if exists seg# create temp table seg as ( SELECT segments."{3}" as "{3}", ST_MakeLine(sp,ep) as "{2}" @@ -554,13 +781,15 @@ def prepareVertexNearEdgesStruct(self, tableSchema, tableName, geometryColumn, k linestrings."{3}" as "{3}" FROM (SELECT "{3}" as "{3}", (ST_Dump(ST_Boundary("{2}"))).geom - FROM only "{0}"."{1}" + FROM only "{0}"."{1}" ) AS linestrings ) AS segments)# drop table if exists pontos# create temp table pontos as select "{3}" as "{3}", (ST_DumpPoints("{2}")).geom as "{2}" from only "{0}"."{1}"# create index pontos_gist on pontos using gist ("{2}")# - create index seg_gist on seg using gist ("{2}")""".format(tableSchema, tableName, geometryColumn, keyColumn) + create index seg_gist on seg using gist ("{2}")""".format( + tableSchema, tableName, geometryColumn, keyColumn + ) else: sql = """drop table if exists seg# create temp table seg as ( @@ -572,37 +801,49 @@ def prepareVertexNearEdgesStruct(self, tableSchema, tableName, geometryColumn, k linestrings."{3}" as "{3}" FROM (SELECT "{3}" as "{3}", (ST_Dump("{2}")).geom - FROM only "{0}"."{1}" + FROM only "{0}"."{1}" ) AS linestrings ) AS segments)# drop table if exists pontos# create temp table pontos as select "{3}" as "{3}", (ST_DumpPoints("{2}")).geom as "{2}" from only "{0}"."{1}"# create index pontos_gist on pontos using gist ("{2}")# - create index seg_gist on seg using gist ("{2}")""".format(tableSchema, tableName, geometryColumn, keyColumn) + create index seg_gist on seg using gist ("{2}")""".format( + tableSchema, tableName, geometryColumn, keyColumn + ) return sql def getVertexNearEdgesStruct(self, epsg, tol, geometryColumn, keyColumn): - sql = """select pontos."{3}", ST_SetSRID(pontos."{2}",{0}) as "{2}" from pontos, seg where ST_DWithin(seg."{2}", pontos."{2}", {1}) and ST_Distance(seg."{2}", pontos."{2}") > 0""".format(epsg, tol, geometryColumn, keyColumn) + sql = """select pontos."{3}", ST_SetSRID(pontos."{2}",{0}) as "{2}" from pontos, seg where ST_DWithin(seg."{2}", pontos."{2}", {1}) and ST_Distance(seg."{2}", pontos."{2}") > 0""".format( + epsg, tol, geometryColumn, keyColumn + ) return sql - + def deleteFeatures(self, schema, table, idList, keyColumn): - sql = """DELETE FROM "{0}"."{1}" - WHERE "{3}" in ({2})""".format(schema, table, ','.join(idList), keyColumn) - return sql - - def deleteFeaturesNotIn(self,schema,table,idList): - sql = """DELETE FROM "{0}"."{1}" - WHERE id not in ({2})""" .format(schema,table,','.join(map(str,idList))) - return sql - + sql = """DELETE FROM "{0}"."{1}" + WHERE "{3}" in ({2})""".format( + schema, table, ",".join(idList), keyColumn + ) + return sql + + def deleteFeaturesNotIn(self, schema, table, idList): + sql = """DELETE FROM "{0}"."{1}" + WHERE id not in ({2})""".format( + schema, table, ",".join(map(str, idList)) + ) + return sql + def getNotSimple(self, tableSchema, tableName, geometryColumn, keyColumn): sql = """select foo."{3}" as "{3}", ST_MULTI(st_startpoint(foo."{2}")) as "{2}" from ( - select "{3}" as "{3}", (ST_Dump(ST_Node(ST_SetSRID(ST_MakeValid("{2}"),ST_SRID("{2}"))))).geom as "{2}" from "{0}"."{1}" - where ST_IsSimple("{2}") = 'f') as foo where st_equals(st_startpoint(foo."{2}"),st_endpoint(foo."{2}"))""".format(tableSchema, tableName, geometryColumn, keyColumn) + select "{3}" as "{3}", (ST_Dump(ST_Node(ST_SetSRID(ST_MakeValid("{2}"),ST_SRID("{2}"))))).geom as "{2}" from "{0}"."{1}" + where ST_IsSimple("{2}") = 'f') as foo where st_equals(st_startpoint(foo."{2}"),st_endpoint(foo."{2}"))""".format( + tableSchema, tableName, geometryColumn, keyColumn + ) return sql - def getOutofBoundsAngles(self, tableSchema, tableName, angle, geometryColumn, geomType, keyColumn): - if 'LINESTRING' in geomType: + def getOutofBoundsAngles( + self, tableSchema, tableName, angle, geometryColumn, geomType, keyColumn + ): + if "LINESTRING" in geomType: sql = """ WITH result AS (SELECT points."{4}", points.anchor, (degrees ( @@ -618,8 +859,10 @@ def getOutofBoundsAngles(self, tableSchema, tableName, angle, geometryColumn, ge (SELECT "{4}" as "{4}", (ST_Dump("{3}")).geom as "{3}" FROM only "{0}"."{1}" ) AS linestrings WHERE ST_NPoints(linestrings."{3}") > 2 ) as points) - select distinct "{4}", anchor, angle from result where (result.angle % 360) < {2} or result.angle > (360.0 - ({2} % 360.0))""".format(tableSchema, tableName, angle, geometryColumn, keyColumn) - elif 'POLYGON' in geomType: + select distinct "{4}", anchor, angle from result where (result.angle % 360) < {2} or result.angle > (360.0 - ({2} % 360.0))""".format( + tableSchema, tableName, angle, geometryColumn, keyColumn + ) + elif "POLYGON" in geomType: sql = """ WITH result AS (SELECT points."{4}", points.anchor, (degrees ( @@ -635,30 +878,41 @@ def getOutofBoundsAngles(self, tableSchema, tableName, angle, geometryColumn, ge (SELECT "{4}" as "{4}", (ST_Dump(ST_Boundary(ST_ForceRHR((ST_Dump("{3}")).geom)))).geom as "{3}" FROM only "{0}"."{1}" ) AS linestrings WHERE ST_NPoints(linestrings."{3}") > 2 ) as points) - select distinct "{4}", anchor, angle from result where (result.angle % 360) < {2} or result.angle > (360.0 - ({2} % 360.0))""".format(tableSchema, tableName, angle, geometryColumn, keyColumn) + select distinct "{4}", anchor, angle from result where (result.angle % 360) < {2} or result.angle > (360.0 - ({2} % 360.0))""".format( + tableSchema, tableName, angle, geometryColumn, keyColumn + ) return sql - + def getFlagsByProcess(self, processName): - sql = """select layer, feat_id, geometry_column from validation.aux_flags_validacao where process_name = '%s'""" % processName + sql = ( + """select layer, feat_id, geometry_column from validation.aux_flags_validacao where process_name = '%s'""" + % processName + ) return sql - - def forceValidity(self, tableSchema, tableName, idList, srid, keyColumn, geometryColumn): + + def forceValidity( + self, tableSchema, tableName, idList, srid, keyColumn, geometryColumn + ): sql = """update "{0}"."{1}" set "{5}" = ST_Multi(result."{5}") from ( - select distinct parts."{4}", ST_Union(parts."{5}") as "{5}" from "{0}"."{1}" as source, - (select "{4}" as "{4}", ST_Multi(((ST_Dump(ST_SetSRID(ST_MakeValid("{5}"), {3}))).geom)) as "{5}" from + select distinct parts."{4}", ST_Union(parts."{5}") as "{5}" from "{0}"."{1}" as source, + (select "{4}" as "{4}", ST_Multi(((ST_Dump(ST_SetSRID(ST_MakeValid("{5}"), {3}))).geom)) as "{5}" from "{0}"."{1}" where "{4}" in ({2})) as parts where ST_GeometryType(parts."{5}") = ST_GeometryType(source."{5}") group by parts."{4}" - ) as result where result."{4}" = "{0}"."{1}"."{4}" """.format(tableSchema, tableName, ','.join(idList), srid, keyColumn, geometryColumn) + ) as result where result."{4}" = "{0}"."{1}"."{4}" """.format( + tableSchema, tableName, ",".join(idList), srid, keyColumn, geometryColumn + ) return sql - + def getTableExtent(self, tableSchema, tableName): - #TODO: put geometry column + # TODO: put geometry column sql = """ SELECT ST_XMin(ST_Extent(geom)), ST_XMax(ST_Extent(geom)), ST_YMin(ST_Extent(geom)), ST_YMax(ST_Extent(geom)) AS extent FROM "{0}"."{1}" - """.format(tableSchema, tableName) + """.format( + tableSchema, tableName + ) return sql - - def getOrphanGeomTablesWithElements(self,loading = False): - #TODO: Avaliate if deprecated + + def getOrphanGeomTablesWithElements(self, loading=False): + # TODO: Avaliate if deprecated if not loading: sql = """ select pgcl2.n as tb from pg_class as pgcl @@ -667,16 +921,16 @@ def getOrphanGeomTablesWithElements(self,loading = False): left join pg_inherits as pginh on pginh.inhparent = pgcl.oid join (select pgcl.oid, pgmsp.nspname as sc, pgcl.relname as n from pg_class as pgcl join (select * from pg_attribute where attname = 'geom') as pgatt on pgatt.attrelid = pgcl.oid - left join pg_namespace pgmsp on pgcl.relnamespace = pgmsp.oid) + left join pg_namespace pgmsp on pgcl.relnamespace = pgmsp.oid) as pgcl2 on pgcl2.oid = pginh.inhrelid where pgnsp.nspname in ('ge','pe', 'cb') and pgatt.attname IS NULL and pgcl.relkind = 'r' - union + union select distinct p.relname as tb from pg_class as p - left join pg_inherits as inh on inh.inhrelid = p.oid + left join pg_inherits as inh on inh.inhrelid = p.oid left join geometry_columns as gc on gc.f_table_name = p.relname - where (inh.inhrelid IS NULL) and + where (inh.inhrelid IS NULL) and gc.f_table_schema in ('cb', 'pe', 'ge') - + order by tb """ else: @@ -687,61 +941,67 @@ def getOrphanGeomTablesWithElements(self,loading = False): left join pg_inherits as pginh on pginh.inhparent = pgcl.oid join (select pgcl.oid, pgmsp.nspname as sc, pgcl.relname as n from pg_class as pgcl join (select * from pg_attribute where attname = 'geom') as pgatt on pgatt.attrelid = pgcl.oid - left join pg_namespace pgmsp on pgcl.relnamespace = pgmsp.oid) + left join pg_namespace pgmsp on pgcl.relnamespace = pgmsp.oid) as pgcl2 on pgcl2.oid = pginh.inhrelid where pgnsp.nspname in ('ge','pe', 'cb', 'public') and pgatt.attname IS NULL and pgcl.relkind = 'r' - union + union select distinct p.relname as tb from pg_class as p - left join pg_inherits as inh on inh.inhrelid = p.oid + left join pg_inherits as inh on inh.inhrelid = p.oid left join geometry_columns as gc on gc.f_table_name = p.relname - where (inh.inhrelid IS NULL) and + where (inh.inhrelid IS NULL) and gc.f_table_schema in ('cb', 'pe', 'ge', 'public') - + order by tb """ return sql - + def updateOriginalTable(self, tableSchema, tableName, result, epsg): - #TODO: Put original id + # TODO: Put original id sqls = [] for key in list(result.keys()): geoms = [] for wkb in result[key]: geoms.append("ST_SetSRID(ST_Multi('{0}'), {1})".format(wkb, epsg)) - array = ','.join(geoms) - union = 'ST_Union(ARRAY[{}])'.format(array) + array = ",".join(geoms) + union = "ST_Union(ARRAY[{}])".format(array) sql = """ UPDATE "{0}"."{1}" SET geom = ST_Multi({2}) WHERE id = {3} - """.format(tableSchema, tableName, union, key) + """.format( + tableSchema, tableName, union, key + ) sqls.append(sql) return sqls - + def getOrphanTableElementCount(self, orphan): - orphan = '"'+'"."'.join(orphan.replace('"','').split('.'))+'"' + orphan = '"' + '"."'.join(orphan.replace('"', "").split(".")) + '"' sql = "select id from %s limit 1" % orphan return sql - + def checkCentroidAuxStruct(self): sql = "select distinct count(column_name) from information_schema.columns where column_name = 'centroid' group by column_name" return sql - + def dropCentroid(self, table): - table = '"'+'"."'.join(table.replace('"','').split('.'))+'"' + table = '"' + '"."'.join(table.replace('"', "").split(".")) + '"' sql = "alter table %s drop column if exists centroid" % table return sql - + def createCentroidColumn(self, table_schema, table_name, srid): sql = """alter table "{1}"."{2}" add column centroid geometry('POINT',{0})# alter table "{1}"."{2}" alter column geom drop not null# - CREATE INDEX {3} ON "{1}"."{2}" USING gist(centroid)""".format(srid,table_schema, table_name,table_name[:-2]+'_c_gist') + CREATE INDEX {3} ON "{1}"."{2}" USING gist(centroid)""".format( + srid, table_schema, table_name, table_name[:-2] + "_c_gist" + ) return sql - + def createCentroidGist(self, table_schema, table_name): - gistName = table_name[:-2]+'_c_gist' - sql = '''CREATE INDEX {0} ON "{1}"."{2}" USING gist(centroid)'''.format(gistName,table_schema,table_name) + gistName = table_name[:-2] + "_c_gist" + sql = """CREATE INDEX {0} ON "{1}"."{2}" USING gist(centroid)""".format( + gistName, table_schema, table_name + ) return sql - + def getEarthCoverageClasses(self): sql = "select distinct table_schema || '.' || table_name from information_schema.columns where column_name = 'centroid'" return sql @@ -750,29 +1010,35 @@ def getEarthCoverageDict(self): sql = "select earthcoverage from validation.settings limit 1" return sql - def setEarthCoverageDict(self,earthDict): + def setEarthCoverageDict(self, earthDict): if earthDict: sql = "update validation.settings set earthcoverage = '%s'" % earthDict else: sql = "update validation.settings set earthcoverage = NULL" return sql - - + def makeRelationDict(self, table, codes): - sql = """select code, code_name from dominios.%s where code in %s""" % (table, codes) + sql = """select code, code_name from dominios.%s where code in %s""" % ( + table, + codes, + ) return sql def getEarthCoverageCentroids(self): sql = "select distinct table_name from information_schema.columns where column_name = 'centroid'" return sql - + def getWhoAmI(self, cl, id): - sql = "select p.relname from {0} as c, pg_class as p where c.tableoid = p.oid and c.id = {1}".format(cl,id) + sql = "select p.relname from {0} as c, pg_class as p where c.tableoid = p.oid and c.id = {1}".format( + cl, id + ) return sql - - def snapLinesToFrame(self, cl, frameTable, tol, geometryColumn, keyColumn, frameGeometryColumn): - schema, table = cl.split('.') - frameSchema, frameTable = frameTable.split('.') + + def snapLinesToFrame( + self, cl, frameTable, tol, geometryColumn, keyColumn, frameGeometryColumn + ): + schema, table = cl.split(".") + frameSchema, frameTable = frameTable.split(".") sql = """ update "{0}"."{1}" as classe set "{5}" = ST_Multi(agrupado."{5}") from @@ -780,11 +1046,11 @@ def snapLinesToFrame(self, cl, frameTable, tol, geometryColumn, keyColumn, frame select simplelines."{6}" as "{6}", ST_Union(simplelines.newline) as "{5}" from ( - select short."{6}", St_SetPoint((ST_Dump(short."{5}")).geom, 0, + select short."{6}", St_SetPoint((ST_Dump(short."{5}")).geom, 0, ST_EndPoint(from_start)) as newline from ( select a."{6}" as "{6}", a."{5}" as "{5}", - ST_ShortestLine(st_startpoint((ST_Dump(a."{5}")).geom), + ST_ShortestLine(st_startpoint((ST_Dump(a."{5}")).geom), ST_Boundary(m."{7}")) as from_start from "{0}"."{1}" a, "{3}"."{4}" m ) as short @@ -798,11 +1064,11 @@ def snapLinesToFrame(self, cl, frameTable, tol, geometryColumn, keyColumn, frame select simplelines."{6}" as "{6}", ST_Union(simplelines.newline) as "{5}" from ( - select short."{6}", St_SetPoint((ST_Dump(short."{5}")).geom, + select short."{6}", St_SetPoint((ST_Dump(short."{5}")).geom, short.index - 1, ST_EndPoint(from_start)) as newline from ( select a."{6}" as "{6}", a."{5}" as "{5}", - ST_ShortestLine(st_endpoint((ST_Dump(a."{5}")).geom), + ST_ShortestLine(st_endpoint((ST_Dump(a."{5}")).geom), ST_Boundary(m."{7}")) as from_start, ST_NPoints((ST_Dump(a."{5}")).geom) as index from "{0}"."{1}" a, "{3}"."{4}" m @@ -810,93 +1076,116 @@ def snapLinesToFrame(self, cl, frameTable, tol, geometryColumn, keyColumn, frame where ST_Length(from_start) < {2} ) as simplelines group by simplelines."{6}" ) as agrupado - where classe."{6}" = agrupado."{6}" - """.format(schema, table, str(tol), frameSchema, frameTable, geometryColumn, keyColumn, frameGeometryColumn) + where classe."{6}" = agrupado."{6}" + """.format( + schema, + table, + str(tol), + frameSchema, + frameTable, + geometryColumn, + keyColumn, + frameGeometryColumn, + ) return sql - - def densifyFrame(self, cl, frameTable, snapTolerance, geometryColumn, frameGeometryColumn): - cl = '"'+'"."'.join(cl.replace('"','').split('.'))+'"' - frameTable = '"'+'"."'.join(frameTable.replace('"','').split('.'))+'"' + + def densifyFrame( + self, cl, frameTable, snapTolerance, geometryColumn, frameGeometryColumn + ): + cl = '"' + '"."'.join(cl.replace('"', "").split(".")) + '"' + frameTable = '"' + '"."'.join(frameTable.replace('"', "").split(".")) + '"' sql = """ - update {2} m set {4} = st_multi(st_snap(m.{4}, + update {2} m set {4} = st_multi(st_snap(m.{4}, foo.vertices, {1})) from ( - select st_union(st_boundary(a.{3})) as vertices from + select st_union(st_boundary(a.{3})) as vertices from {0} a - ) as foo - """.format(cl, snapTolerance, frameTable, geometryColumn, frameGeometryColumn) + ) as foo + """.format( + cl, snapTolerance, frameTable, geometryColumn, frameGeometryColumn + ) return sql def snapToGrid(self, cl, precision, srid, geometryColumn): - schema, table = cl.split('.') - sql = 'update "{0}"."{1}" set "{4}" = ST_SetSRID(ST_SnapToGrid("{4}",{2}),{3})'.format(schema, table, precision, srid, geometryColumn) + schema, table = cl.split(".") + sql = 'update "{0}"."{1}" set "{4}" = ST_SetSRID(ST_SnapToGrid("{4}",{2}),{3})'.format( + schema, table, precision, srid, geometryColumn + ) return sql - + def makeRecursiveSnapFunction(self, geometryColumn, keyColumn): sql = """ - CREATE OR REPLACE FUNCTION dsgsnap(tabela text, snap float) RETURNS void AS + CREATE OR REPLACE FUNCTION dsgsnap(tabela text, snap float) RETURNS void AS $BODY$ DECLARE id int; BEGIN FOR id in execute('select "{1}" from '||tabela) LOOP - EXECUTE - 'update '||tabela||' as classe set "{0}" = st_multi(res."{0}") - from + EXECUTE + 'update '||tabela||' as classe set "{0}" = st_multi(res."{0}") + from ( - select st_snap(a."{0}", st_collect(b."{0}"), '||snap||') as "{0}", a."{1}" as "{1}" - from '||tabela||' a, '||tabela||' b + select st_snap(a."{0}", st_collect(b."{0}"), '||snap||') as "{0}", a."{1}" as "{1}" + from '||tabela||' a, '||tabela||' b where a."{1}" != b."{1}" and st_isempty(a."{0}") = FALSE and a."{1}" = '||id||' group by a."{1}", a."{0}" - ) as res + ) as res where res."{1}" = classe."{1}" '; END LOOP; - RETURN; + RETURN; END $BODY$ LANGUAGE plpgsql; - """.format(geometryColumn, keyColumn) + """.format( + geometryColumn, keyColumn + ) return sql - + def executeRecursiveSnap(self, cl, tol): - sql = 'SELECT dsgsnap(\'{0}\', {1})'.format(cl, str(tol)) + sql = "SELECT dsgsnap('{0}', {1})".format(cl, str(tol)) return sql - + def createTempTable(self, layerName): - schema, tableName = layerName.split('.') - sql = ''' + schema, tableName = layerName.split(".") + sql = """ DROP TABLE IF EXISTS "{0}"."{1}_temp"# CREATE TABLE "{0}"."{1}_temp" as (select * from "{0}"."{1}" where 1=2) - '''.format(schema,tableName) + """.format( + schema, tableName + ) return sql - + def dropTempTable(self, tableName): - tableName = '"'+'"."'.join(tableName.replace('"','').split('.'))+'"' - sql = '''DROP TABLE IF EXISTS {0}'''.format(tableName) + tableName = '"' + '"."'.join(tableName.replace('"', "").split(".")) + '"' + sql = """DROP TABLE IF EXISTS {0}""".format(tableName) return sql - + def populateTempTable(self, tableName, attributes, prepareValues): - tableName = '"'+'"."'.join(tableName.split('.')) - columnTupleString = '"'+'","'.join(map(str,attributes))+'"' - valueTuppleString = ','.join(map(str,prepareValues)) - sql = """INSERT INTO {0}_temp"({1}) VALUES ({2})""".format(tableName, columnTupleString, valueTuppleString) + tableName = '"' + '"."'.join(tableName.split(".")) + columnTupleString = '"' + '","'.join(map(str, attributes)) + '"' + valueTuppleString = ",".join(map(str, prepareValues)) + sql = """INSERT INTO {0}_temp"({1}) VALUES ({2})""".format( + tableName, columnTupleString, valueTuppleString + ) return sql - - def createSpatialIndex(self, tableName, geomColumnName='geom'): - tableName = '"'+'"."'.join(tableName.replace('"','').split('.')) - sql = 'create index "{0}_temp_gist" on {1}_temp" using gist ({2})'.format(tableName.split('.')[-1].replace('"',''), tableName, geomColumnName) + + def createSpatialIndex(self, tableName, geomColumnName="geom"): + tableName = '"' + '"."'.join(tableName.replace('"', "").split(".")) + sql = 'create index "{0}_temp_gist" on {1}_temp" using gist ({2})'.format( + tableName.split(".")[-1].replace('"', ""), tableName, geomColumnName + ) return sql - + def getStyles(self): - sql = 'select description, f_table_schema, f_table_name, stylename from public.layer_styles where f_table_catalog = current_database()' + sql = "select description, f_table_schema, f_table_name, stylename from public.layer_styles where f_table_catalog = current_database()" return sql def checkStyleTable(self): sql = "select relname from pg_class where relname = 'layer_styles' limit 1" return sql - + def createStyleTable(self): sql = """ CREATE TABLE public.layer_styles @@ -918,7 +1207,7 @@ def createStyleTable(self): ) """ return sql - + def getStylesFromDb(self, dbVersion): """ Returns the stylenames of the database. @@ -926,44 +1215,63 @@ def getStylesFromDb(self, dbVersion): with previous DSGTools behaviour. """ sql = """ - select distinct replace(stylename,'/' || f_table_name, '') - from public.layer_styles + select distinct replace(stylename,'/' || f_table_name, '') + from public.layer_styles where f_table_catalog = current_database() """ return sql - + def getStyle(self, styleName, table_name): - sql = """SELECT styleqml from public.layer_styles where f_table_name = '{0}' and (stylename = '{1}' or stylename like '{1}/%')and f_table_catalog = current_database()""".format(table_name, styleName) + sql = """SELECT styleqml from public.layer_styles where f_table_name = '{0}' and (stylename = '{1}' or stylename like '{1}/%')and f_table_catalog = current_database()""".format( + table_name, styleName + ) return sql - + def updateStyle(self, styleName, table_name, parsedQml, tableSchema): - sql = """UPDATE public.layer_styles SET styleqml = '{0}', update_time = now() where f_table_name = '{1}' and description = '{2}'""".format(parsedQml.replace("'","''"),table_name, styleName) + sql = """UPDATE public.layer_styles SET styleqml = '{0}', update_time = now() where f_table_name = '{1}' and description = '{2}'""".format( + parsedQml.replace("'", "''"), table_name, styleName + ) return sql - + def importStyle(self, styleName, table_name, parsedQml, tableSchema, dbName): - #TODO:REDO it - if table_name[-1] == 'c': - geomColumn = 'centroid' + # TODO:REDO it + if table_name[-1] == "c": + geomColumn = "centroid" else: - geomColumn = 'geom' - sql = """INSERT INTO public.layer_styles (styleqml, f_table_name, description, f_geometry_column, stylename, f_table_schema, f_table_catalog, useasdefault) VALUES ('"""+parsedQml.replace("'","''")+"""','{0}','{1}','{2}','{3}','{4}','{5}',FALSE)""".format(table_name, styleName, geomColumn, styleName.split('/')[-1]+'/'+table_name, tableSchema, dbName) + geomColumn = "geom" + sql = ( + """INSERT INTO public.layer_styles (styleqml, f_table_name, description, f_geometry_column, stylename, f_table_schema, f_table_catalog, useasdefault) VALUES ('""" + + parsedQml.replace("'", "''") + + """','{0}','{1}','{2}','{3}','{4}','{5}',FALSE)""".format( + table_name, + styleName, + geomColumn, + styleName.split("/")[-1] + "/" + table_name, + tableSchema, + dbName, + ) + ) return sql - + def getTableSchemaFromDb(self, table): - sql = """select distinct table_schema from information_schema.columns where table_name = '{0}' and table_schema not in ('validation','views')""".format(table) + sql = """select distinct table_schema from information_schema.columns where table_name = '{0}' and table_schema not in ('validation','views')""".format( + table + ) return sql - + def getAllStylesFromDb(self): sql = """SELECT DISTINCT f_table_catalog, description, f_table_name, update_time from public.layer_styles order by f_table_catalog, description, f_table_name asc """ return sql - + def deleteStyle(self, styleName): - sql = """delete from public.layer_styles where description = '{0}'""".format(styleName) + sql = """delete from public.layer_styles where description = '{0}'""".format( + styleName + ) return sql - + # Atentar que a coluna consrc foi descontinuada no pg 12+ (issue #521) # def getConstraints(self, schemaList): - # sql = """select sch.nspname, cl.relname, c.conname, c.consrc from + # sql = """select sch.nspname, cl.relname, c.conname, c.consrc from # ( # select * from pg_constraint where contype = 'c' # ) as c join ( @@ -972,72 +1280,82 @@ def deleteStyle(self, styleName): # left join pg_class as cl on c.conrelid = cl.oid # """.format(','.schemaList) # return sql - + def getGeometricSchemas(self): - sql = 'select distinct f_table_schema from public.geometry_columns' + sql = "select distinct f_table_schema from public.geometry_columns" return sql - + def getGeomTablesFromGeometryColumns(self): - sql = 'select srid, f_geometry_column, type, f_table_schema, f_table_name from public.geometry_columns' + sql = "select srid, f_geometry_column, type, f_table_schema, f_table_name from public.geometry_columns" return sql - - def getGeomTablesDomains(self, layerFilter = None): - inClause = """'{text}'""".format( - text='","'.join(layerFilter) - ) if layerFilter \ + + def getGeomTablesDomains(self, layerFilter=None): + inClause = ( + """'{text}'""".format(text='","'.join(layerFilter)) + if layerFilter else """select f_table_name from public.geometry_columns where f_table_schema <> 'views'""" - sql = """select distinct case + ) + sql = """select distinct case when split_part(conrelid::regclass::text,'.',2) = '' then replace(split_part(conrelid::regclass::text,'.',1),'"','') else replace(split_part(conrelid::regclass::text,'.',2),'"','') - end as cl, pg_get_constraintdef(oid) FROM - pg_constraint WHERE contype = 'f' and case + end as cl, pg_get_constraintdef(oid) FROM + pg_constraint WHERE contype = 'f' and case when replace(split_part(conrelid::regclass::text,'.',2),'"','') = '' then replace(split_part(conrelid::regclass::text,'.',1),'"','') else replace(split_part(conrelid::regclass::text,'.',2),'"','') end in ({in_clause}) - """.format(in_clause=inClause) + """.format( + in_clause=inClause + ) return sql - - def getGeomTableConstraints(self, layerFilter = None): - inClause = """'{text}'""".format( - text='","'.join(layerFilter) - ) if layerFilter \ + + def getGeomTableConstraints(self, layerFilter=None): + inClause = ( + """'{text}'""".format(text='","'.join(layerFilter)) + if layerFilter else """select f_table_name from public.geometry_columns where f_table_schema <> 'views'""" - sql = """select distinct case + ) + sql = """select distinct case when split_part(conrelid::regclass::text,'.',2) = '' then split_part(conrelid::regclass::text,'.',1) else split_part(conrelid::regclass::text,'.',2) - end as cl, pg_get_constraintdef(oid) FROM - pg_constraint WHERE contype = 'c' and case + end as cl, pg_get_constraintdef(oid) FROM + pg_constraint WHERE contype = 'c' and case when split_part(conrelid::regclass::text,'.',2) = '' then split_part(conrelid::regclass::text,'.',1) else split_part(conrelid::regclass::text,'.',2) end in ({in_clause}) order by cl - """.format(in_clause=inClause) + """.format( + in_clause=inClause + ) return sql - + def getMultiColumns(self, schemaList): sql = """select row_to_json(a) from ( - select t.table_name, array_agg(t.column_name::text) as attributes from - (select table_name, column_name from information_schema.columns - where data_type = 'ARRAY' and table_schema in ({0}) + select t.table_name, array_agg(t.column_name::text) as attributes from + (select table_name, column_name from information_schema.columns + where data_type = 'ARRAY' and table_schema in ({0}) ) as t group by t.table_name ) as a - """.format("'"+"','".join(schemaList)+"'") + """.format( + "'" + "','".join(schemaList) + "'" + ) return sql - + def getMultiColumnsFromTableList(self, tableList): sql = """select row_to_json(a) from ( - select t.table_name, array_agg(t.column_name::text) as attributes from - (select table_name, column_name from information_schema.columns - where data_type = 'ARRAY' and table_name in ({0}) + select t.table_name, array_agg(t.column_name::text) as attributes from + (select table_name, column_name from information_schema.columns + where data_type = 'ARRAY' and table_name in ({0}) ) as t group by t.table_name ) as a - """.format("'"+"','".join(tableList)+"'") + """.format( + "'" + "','".join(tableList) + "'" + ) return sql - + def getGeomByPrimitive(self): sql = """select row_to_json(a) from (select type as geomtype, array_agg(f_table_name) as classlist from public.geometry_columns where f_table_schema not in ('views','topology') group by type) as a""" return sql - + def getTablesJsonList(self): sql = """select row_to_json(a) from (select table_schema::text, table_name::text from information_schema.tables where table_schema not in ('pg_catalog', 'information_schema') order by table_schema, table_name) as a""" return sql @@ -1046,159 +1364,212 @@ def getGeomColumnDict(self): sql = """select row_to_json(row(f_table_name, f_geometry_column)) from public.geometry_columns where f_table_schema not in ('views','topology')""" return sql - def getGeomColumnTupleList(self, showViews = False, filterList = None): - filterLayersClause = 'AND f_table_name in ({table_name_list})'.format( - table_name_list=','.join(filterList) - ) if filterList else """ """ - showViewsClause = """ AND table_type = 'BASE TABLE'""" if not showViews else """ """ + def getGeomColumnTupleList(self, showViews=False, filterList=None): + filterLayersClause = ( + "AND f_table_name in ({table_name_list})".format( + table_name_list=",".join(filterList) + ) + if filterList + else """ """ + ) + showViewsClause = ( + """ AND table_type = 'BASE TABLE'""" if not showViews else """ """ + ) sql = """select f_table_schema, f_table_name, f_geometry_column, type, table_type from (select distinct f_table_schema, f_table_name, f_geometry_column, type, f_table_schema || '.' || f_table_name as jc from public.geometry_columns as gc) as inn left join (select table_schema || '.' || table_name as jc, table_type from information_schema.tables) as infs on inn.jc = infs.jc where inn.type <> 'GEOMETRY' {where_layer_filter} {where_show_views}""".format( - where_layer_filter=filterLayersClause, - where_show_views=showViewsClause - ) + where_layer_filter=filterLayersClause, where_show_views=showViewsClause + ) return sql - + def getNotNullDict(self, layerFilter=None): - tableNameClause = """'{text}'""".format( - text='","'.join(layerFilter) - ) if layerFilter \ + tableNameClause = ( + """'{text}'""".format(text='","'.join(layerFilter)) + if layerFilter else """select distinct f_table_name from public.geometry_columns """ + ) sql = """select row_to_json(row(table_name, table_schema, array_agg(column_name::text))) - from information_schema.columns - where table_name in ({table_name_clause}) + from information_schema.columns + where table_name in ({table_name_clause}) and is_nullable = 'NO' and data_type = 'smallint' group by table_name, table_schema - """.format(table_name_clause=tableNameClause) + """.format( + table_name_clause=tableNameClause + ) return sql - + def getTableMetadataDict(self, layerFilter=None): sql = """select row_to_json(a) from ( select table_schema, table_name, column_name as attr_name, is_nullable::boolean as nullable, data_type as column_type, gc.f_geometry_column as geometry_column, gc.type as geometry_type - from information_schema.columns as c - left join public.geometry_columns as gc + from information_schema.columns as c + left join public.geometry_columns as gc on c.table_name = gc.f_table_name and c.table_schema = gc.f_table_schema ) as a where a.table_name in ({filter}) """.format( - filter= """'{text}'""".format( - text='","'.join(layerFilter) - ) if layerFilter \ + filter="""'{text}'""".format(text='","'.join(layerFilter)) + if layerFilter else """select f_table_name from public.geometry_columns where f_table_schema <> 'views'""" ) return sql - + def getDomainDict(self, domainTable): - sql = """select row_to_json(row(code, code_name)) from {0}""".format(domainTable) + sql = """select row_to_json(row(code, code_name)) from {0}""".format( + domainTable + ) return sql def getDomainCodeDict(self, domainTable): - sql = """select row_to_json(a) from (select * from {0}) as a""".format(domainTable) + sql = """select row_to_json(a) from (select * from {0}) as a""".format( + domainTable + ) return sql - + def getDomainCodeDictWithColumns(self, domainTable, refPk, otherKey): sql = """select row_to_json(a) from (select {pk}, {fk} from {table}) as a""".format( - table=domainTable, - pk=refPk, - fk=otherKey - ) + table=domainTable, pk=refPk, fk=otherKey + ) return sql def getGeomStructDict(self): sql = """select row_to_json(a) from ( - select table_name, array_agg(row_to_json(row(column_name::text, is_nullable))) from information_schema.columns where - table_name in (select f_table_name from public.geometry_columns) - and column_name not like 'id_%' - and column_name not in ('id','geom') + select table_name, array_agg(row_to_json(row(column_name::text, is_nullable))) from information_schema.columns where + table_name in (select f_table_name from public.geometry_columns) + and column_name not like 'id_%' + and column_name not in ('id','geom') and table_schema not in ('validation','views') group by table_name ) as a """ return sql - - def insertFrame(self,scale,mi,inom,frame,srid,geoSrid, paramDict = dict()): + + def insertFrame(self, scale, mi, inom, frame, srid, geoSrid, paramDict=dict()): paramKeys = list(paramDict.keys()) - if 'tableSchema' not in paramKeys: - tableSchema = 'public' + if "tableSchema" not in paramKeys: + tableSchema = "public" else: - tableSchema = paramDict['tableSchema'] - if 'tableName' not in paramKeys: - tableName = 'aux_moldura_a' + tableSchema = paramDict["tableSchema"] + if "tableName" not in paramKeys: + tableName = "aux_moldura_a" else: - tableName = paramDict['tableName'] - if 'miAttr' not in paramKeys: - miAttr = 'mi' + tableName = paramDict["tableName"] + if "miAttr" not in paramKeys: + miAttr = "mi" else: - miAttr = paramDict['miAttr'] - if 'inomAttr' not in paramKeys: - inomAttr = 'inom' + miAttr = paramDict["miAttr"] + if "inomAttr" not in paramKeys: + inomAttr = "inom" else: - inomAttr = paramDict['inomAttr'] - if 'geom' not in paramKeys: - geometryColumn = 'geom' + inomAttr = paramDict["inomAttr"] + if "geom" not in paramKeys: + geometryColumn = "geom" else: - geometryColumn = paramDict['geom'] - if 'geomType' not in paramKeys: - geomType = 'MULTIPOLYGON' + geometryColumn = paramDict["geom"] + if "geomType" not in paramKeys: + geomType = "MULTIPOLYGON" else: - geomType = paramDict['geomType'] - - if geomType == 'MULTIPOLYGON': - sql = """INSERT INTO "{5}"."{6}" ({7},{8},{9}) VALUES ('{0}','{1}',ST_Transform(ST_Multi(ST_GeomFromWKB({2},{3})), {4}))""".format(mi, inom, frame, geoSrid, srid, tableSchema, tableName, miAttr, inomAttr, geometryColumn) + geomType = paramDict["geomType"] + + if geomType == "MULTIPOLYGON": + sql = """INSERT INTO "{5}"."{6}" ({7},{8},{9}) VALUES ('{0}','{1}',ST_Transform(ST_Multi(ST_GeomFromWKB({2},{3})), {4}))""".format( + mi, + inom, + frame, + geoSrid, + srid, + tableSchema, + tableName, + miAttr, + inomAttr, + geometryColumn, + ) else: - sql = """INSERT INTO "{5}"."{6}" ({7},{8},{9}) VALUES ('{0}','{1}',ST_Transform((ST_SetSRID( (ST_Dump('{2}')).geom,{3})), {4}))""".format(mi, inom, frame, geoSrid, srid, tableSchema, tableName, miAttr, inomAttr, geometryColumn) + sql = """INSERT INTO "{5}"."{6}" ({7},{8},{9}) VALUES ('{0}','{1}',ST_Transform((ST_SetSRID( (ST_Dump('{2}')).geom,{3})), {4}))""".format( + mi, + inom, + frame, + geoSrid, + srid, + tableSchema, + tableName, + miAttr, + inomAttr, + geometryColumn, + ) return sql - - def createFromTemplate(self,dbName, templateName): - sql = """CREATE DATABASE "{0}" with template = "{1}";""".format(dbName,templateName) + + def createFromTemplate(self, dbName, templateName): + sql = """CREATE DATABASE "{0}" with template = "{1}";""".format( + dbName, templateName + ) return sql - + def updateDbSRID(self, tableDict, srid): - sql = """select UpdateGeometrySRID('{0}', '{1}', '{2}',{3})""".format(tableDict['tableSchema'], tableDict['tableName'], tableDict['geom'],srid) + sql = """select UpdateGeometrySRID('{0}', '{1}', '{2}',{3})""".format( + tableDict["tableSchema"], tableDict["tableName"], tableDict["geom"], srid + ) return sql - - def setDbAsTemplate(self, dbName, setTemplate = True): + + def setDbAsTemplate(self, dbName, setTemplate=True): if setTemplate: - sql = """UPDATE pg_database set datistemplate = 't' where datname = '{0}';""".format(dbName) + sql = """UPDATE pg_database set datistemplate = 't' where datname = '{0}';""".format( + dbName + ) else: - sql = """UPDATE pg_database set datistemplate = 'f' where datname = '{0}';""".format(dbName) + sql = """UPDATE pg_database set datistemplate = 'f' where datname = '{0}';""".format( + dbName + ) return sql - + def checkTemplate(self): sql = """select datname from pg_database where datistemplate = 't'""" return sql - + def checkIfTemplate(self, dbName): - sql = """select datistemplate from pg_database where datname = '{0}'""".format(dbName) + sql = """select datistemplate from pg_database where datname = '{0}'""".format( + dbName + ) return sql - + def alterSearchPath(self, dbName, version): - if version == '2.1.3': - sql = 'ALTER DATABASE "{0}" SET search_path = "$user", public, topology,\'cb\',\'complexos\',\'dominios\';'.format(dbName) - elif version == '2.1.3 Pro': - sql = 'ALTER DATABASE "{0}" SET search_path = "$user", public, topology,\'edgv\',\'dominios\';'.format(dbName) - elif version == '3.0': - sql = 'ALTER DATABASE "{0}" SET search_path = "$user", public, topology,\'edgv\',\'complexos\',\'dominios\';'.format(dbName) - elif version == 'FTer_2a_Ed': - sql = 'ALTER DATABASE "{0}" SET search_path = "$user", public, topology,\'pe\',\'ge\',\'complexos\',\'dominios\';'.format(dbName) - return sql - + if version == "2.1.3": + sql = "ALTER DATABASE \"{0}\" SET search_path = \"$user\", public, topology,'cb','complexos','dominios';".format( + dbName + ) + elif version == "2.1.3 Pro": + sql = "ALTER DATABASE \"{0}\" SET search_path = \"$user\", public, topology,'edgv','dominios';".format( + dbName + ) + elif version == "3.0": + sql = "ALTER DATABASE \"{0}\" SET search_path = \"$user\", public, topology,'edgv','complexos','dominios';".format( + dbName + ) + elif version == "FTer_2a_Ed": + sql = "ALTER DATABASE \"{0}\" SET search_path = \"$user\", public, topology,'pe','ge','complexos','dominios';".format( + dbName + ) + return sql + def getUsersFromServer(self): sql = """SELECT usename, usesuper FROM pg_user WHERE usename <> 'postgres' order by usename""" return sql - + def reasignAndDropUser(self, user): sql = """REASSIGN OWNED BY {0} to postgres; DROP USER {0};""".format(user) return sql def deleteFeatureFlagsFromDb(self, layer, feat_id, processName): - sql = "DELETE FROM validation.aux_flags_validacao WHERE process_name = '{0}' AND layer = '{1}' AND feat_id = {2}".format(processName, layer, feat_id) + sql = "DELETE FROM validation.aux_flags_validacao WHERE process_name = '{0}' AND layer = '{1}' AND feat_id = {2}".format( + processName, layer, feat_id + ) return sql - + def removeEmptyGeomtriesFromDb(self, layer, geometryColumn): - schema, table = layer.split('.') - sql = """DELETE FROM "{0}"."{1}" WHERE st_isempty("{2}") = TRUE""".format(schema, table, geometryColumn) + schema, table = layer.split(".") + sql = """DELETE FROM "{0}"."{1}" WHERE st_isempty("{2}") = TRUE""".format( + schema, table, geometryColumn + ) return sql - + def hasAdminDb(self): sql = """SELECT datname from pg_database where datname = 'dsgtools_admindb';""" return sql @@ -1211,163 +1582,188 @@ def getRolesDict(self): return sql def getSettingTable(self, settingType): - if settingType == 'Permission': - tableName = 'permission_profile' - elif settingType == 'Customization': - tableName = 'customization' - elif settingType == 'EarthCoverage': - tableName = 'earth_coverage' - elif settingType == 'Style': - tableName = 'style' - elif settingType == 'FieldToolBoxConfig': - tableName = 'field_toolbox_config' - elif settingType == 'ValidationConfig': - tableName = 'validation_config' - elif settingType == 'AttributeRules': - tableName = 'attribute_rules' - elif settingType == 'SpatialRules': - tableName = 'spatial_rules' - elif settingType == 'ValidationWorkflow': - tableName = 'validation_workflow' + if settingType == "Permission": + tableName = "permission_profile" + elif settingType == "Customization": + tableName = "customization" + elif settingType == "EarthCoverage": + tableName = "earth_coverage" + elif settingType == "Style": + tableName = "style" + elif settingType == "FieldToolBoxConfig": + tableName = "field_toolbox_config" + elif settingType == "ValidationConfig": + tableName = "validation_config" + elif settingType == "AttributeRules": + tableName = "attribute_rules" + elif settingType == "SpatialRules": + tableName = "spatial_rules" + elif settingType == "ValidationWorkflow": + tableName = "validation_workflow" else: - raise Exception('Setting type not defined!') + raise Exception("Setting type not defined!") return tableName def insertSettingIntoAdminDb(self, settingType, name, jsondict, edgvversion): tableName = self.getSettingTable(settingType) - sql = """INSERT INTO "public"."{0}" (name, jsondict, edgvversion) VALUES ('{1}','{2}','{3}'); """.format(tableName, name, jsondict, edgvversion) + sql = """INSERT INTO "public"."{0}" (name, jsondict, edgvversion) VALUES ('{1}','{2}','{3}'); """.format( + tableName, name, jsondict, edgvversion + ) return sql - + def getSettingFromAdminDb(self, settingType, name, edgvversion): tableName = self.getSettingTable(settingType) - sql = """select jsondict as jsondict from "public"."{0}" where name = '{1}' and edgvversion = '{2}';""".format(tableName, name, edgvversion) + sql = """select jsondict as jsondict from "public"."{0}" where name = '{1}' and edgvversion = '{2}';""".format( + tableName, name, edgvversion + ) return sql - + def deleteSettingFromAdminDb(self, settingType, name, edgvversion): tableName = self.getSettingTable(settingType) - sql = """DELETE FROM "public"."{0}" where name = '{1}' and edgvversion = '{2}';""".format(tableName, name, edgvversion) + sql = """DELETE FROM "public"."{0}" where name = '{1}' and edgvversion = '{2}';""".format( + tableName, name, edgvversion + ) return sql - + def getAllSettingsFromAdminDb(self, settingType): tableName = self.getSettingTable(settingType) sql = """select row_to_json(a) from ( select edgvversion, array_agg(name) as settings from public.{0} group by edgvversion - ) as a;""".format(tableName) + ) as a;""".format( + tableName + ) return sql - + def dropRoleOnDatabase(self, roleName): sql = """drop owned by "{0}" cascade; - drop role "{0}";""".format(roleName) + drop role "{0}";""".format( + roleName + ) return sql - + def getRolesWithGrantedUsers(self): sql = """select row_to_json(a) from ( - select pgr.rolname as profile, array_agg(pgr2.rolname) as users from pg_auth_members as pgam - left join pg_roles as pgr on pgam.roleid = pgr.oid + select pgr.rolname as profile, array_agg(pgr2.rolname) as users from pg_auth_members as pgam + left join pg_roles as pgr on pgam.roleid = pgr.oid left join pg_roles as pgr2 on pgam.member = pgr2.oid group by pgr.rolname ) as a; """ return sql - def getDomainTables(self): - sql = '''select distinct table_name from information_schema.columns where table_schema = 'dominios' order by table_name asc''' + sql = """select distinct table_name from information_schema.columns where table_schema = 'dominios' order by table_name asc""" return sql - + def getGeometricSchemaList(self): - sql = '''select distinct f_table_schema from public.geometry_columns order by f_table_schema asc;''' + sql = """select distinct f_table_schema from public.geometry_columns order by f_table_schema asc;""" return sql - + def getGeometricTableListFromSchema(self, schema): if isinstance(schema, list): - sql = '''select distinct f_table_schema, f_table_name from public.geometry_columns where f_table_schema in ('{0}') and f_table_name in ( + sql = """select distinct f_table_schema, f_table_name from public.geometry_columns where f_table_schema in ('{0}') and f_table_name in ( select distinct table_name from information_schema.tables where table_type <> 'VIEW' ) - order by f_table_name asc;'''.format("','".join(schema)) + order by f_table_name asc;""".format( + "','".join(schema) + ) else: - sql = '''select distinct f_table_schema, f_table_name from public.geometry_columns where f_table_schema = '{0}' and f_table_name in ( + sql = """select distinct f_table_schema, f_table_name from public.geometry_columns where f_table_schema = '{0}' and f_table_name in ( select distinct table_name from information_schema.tables where table_type <> 'VIEW' ) - order by f_table_name asc;'''.format(schema) + order by f_table_name asc;""".format( + schema + ) return sql - + def getParentGeomTables(self, schemaList): - schemaList = [i for i in schemaList if i not in ['validation', 'views']] + schemaList = [i for i in schemaList if i not in ["validation", "views"]] sql = """select pgnsp.nspname, pgcl2.n as tb from pg_class as pgcl left join (select * from pg_attribute where attname = 'geom') as pgatt on pgatt.attrelid = pgcl.oid left join pg_namespace as pgnsp on pgcl.relnamespace = pgnsp.oid left join pg_inherits as pginh on pginh.inhparent = pgcl.oid join (select pgcl.oid, pgmsp.nspname as sc, pgcl.relname as n from pg_class as pgcl join (select * from pg_attribute where attname = 'geom') as pgatt on pgatt.attrelid = pgcl.oid - left join pg_namespace pgmsp on pgcl.relnamespace = pgmsp.oid) + left join pg_namespace pgmsp on pgcl.relnamespace = pgmsp.oid) as pgcl2 on pgcl2.oid = pginh.inhrelid where pgnsp.nspname in ('{0}') and pgatt.attname IS NULL and pgcl.relkind = 'r' - union + union select distinct gc.f_table_schema,p.relname as tb from pg_class as p - left join pg_inherits as inh on inh.inhrelid = p.oid + left join pg_inherits as inh on inh.inhrelid = p.oid left join geometry_columns as gc on gc.f_table_name = p.relname - where (inh.inhrelid IS NULL) and + where (inh.inhrelid IS NULL) and gc.f_table_schema in ('{0}') - - order by tb""".format("','".join(schemaList)) + + order by tb""".format( + "','".join(schemaList) + ) return sql - + def getInheritanceDict(self): - sql = """select row_to_json(a) from (select pgc.relname parentname, array_agg(pgc1.relname) childname - from pg_inherits as pginh - left join pg_class pgc on pginh.inhparent = pgc.oid + sql = """select row_to_json(a) from (select pgc.relname parentname, array_agg(pgc1.relname) childname + from pg_inherits as pginh + left join pg_class pgc on pginh.inhparent = pgc.oid left join pg_class as pgc1 on pginh.inhrelid = pgc1.oid group by pgc.relname ) as a""" return sql - - def getGeomTables(self, schemaList, dbPrimitiveList=[], excludeViews=True, geomColumn = False): - primitiveClause = '' - viewClause = '' + + def getGeomTables( + self, schemaList, dbPrimitiveList=[], excludeViews=True, geomColumn=False + ): + primitiveClause = "" + viewClause = "" if dbPrimitiveList != []: - primitiveClause = """and type in ('{0}')""".format("','".join(dbPrimitiveList)) + primitiveClause = """and type in ('{0}')""".format( + "','".join(dbPrimitiveList) + ) if excludeViews: viewClause = """and f_table_name in (select table_name from information_schema.tables where table_type <> 'VIEW')""" - selectClause = 'f_table_schema, f_table_name' + selectClause = "f_table_schema, f_table_name" if geomColumn: - selectClause += ',f_geometry_column' - sql = """select distinct {0} from public.geometry_columns where f_table_schema in ('{1}') {2} {3} order by f_table_name""".format(selectClause, "','".join(schemaList), primitiveClause, viewClause) + selectClause += ",f_geometry_column" + sql = """select distinct {0} from public.geometry_columns where f_table_schema in ('{1}') {2} {3} order by f_table_name""".format( + selectClause, "','".join(schemaList), primitiveClause, viewClause + ) return sql - + def getAttributeListFromTable(self, schema, tableName): sql = """select distinct column_name from information_schema.columns where table_schema = '{0}' and table_name = '{1}' and column_name not in ( select f_geometry_column from public.geometry_columns where f_table_schema = '{0}' and f_table_name = '{1}' ) - and column_name not like 'id%' order by column_name """.format(schema,tableName) + and column_name not like 'id%' order by column_name """.format( + schema, tableName + ) return sql - + def getAttributeDictFromDb(self): sql = """select row_to_json(a) from (select distinct table_schema, table_name, array_agg(column_name::text) as attributelist from information_schema.columns where table_schema not in ('views','validation') and table_schema in (select distinct f_table_schema from public.geometry_columns) and table_name in (select distinct f_table_name from public.geometry_columns) - + and column_name not in ( select f_geometry_column from public.geometry_columns where f_table_schema = table_schema and f_table_name = table_name ) and column_name not like 'id%' group by table_schema, table_name order by table_schema, table_name) as a""" return sql - + def getAttributeInfoFromTable(self, schema, tableName): - sql = """ select row_to_json(a) from (select distinct column_name, data_type, is_nullable, column_default from information_schema.columns + sql = """ select row_to_json(a) from (select distinct column_name, data_type, is_nullable, column_default from information_schema.columns where table_schema = '{0}' and table_name = '{1}' and column_name not in ( select f_geometry_column from public.geometry_columns where f_table_schema = '{0}' and f_table_name = '{1}' ) and column_name not like 'id%' order by column_name ) as a - """.format(schema,tableName) + """.format( + schema, tableName + ) return sql - + def getAttrTypeDictFromDb(self): sql = """ select row_to_json(a) from ( - select udt_name, array_agg(row_to_json(row(table_schema::text, table_name::text, column_name::text))) from information_schema.columns where - table_name in (select f_table_name from public.geometry_columns) - and column_name not like 'id_%' - and column_name <> 'id' + select udt_name, array_agg(row_to_json(row(table_schema::text, table_name::text, column_name::text))) from information_schema.columns where + table_name in (select f_table_name from public.geometry_columns) + and column_name not like 'id_%' + and column_name <> 'id' and column_name not in ( select f_geometry_column from public.geometry_columns where f_table_schema = table_schema and f_table_name = table_name ) @@ -1376,15 +1772,15 @@ def getAttrTypeDictFromDb(self): ) as a """ return sql - + def getAllDomainValues(self, domainTable): sql = """ select code from dominios.{0}""".format(domainTable) return sql - + # Atentar que a coluna consrc foi descontinuada no pg 12+ (issue #521) # def getConstraintDict(self, domainList): # sql = """select row_to_json(result) from ( - # select a.tn as tablename, array_agg(row_to_json(row(a.conname::text, a.consrc::text))) from (select sch.nspname as sch, cl.relname as tn, c.conname as conname, c.consrc as consrc from + # select a.tn as tablename, array_agg(row_to_json(row(a.conname::text, a.consrc::text))) from (select sch.nspname as sch, cl.relname as tn, c.conname as conname, c.consrc as consrc from # ( # select * from pg_constraint where contype = 'c' # ) as c join ( @@ -1396,51 +1792,55 @@ def getAllDomainValues(self, domainTable): # return sql def getDefaultFromDb(self, schema, tableName, attrName): - sql = """select column_default from information_schema.columns where table_schema = '{0}' and table_name = '{1}' and column_name = '{2}';""".format(schema, tableName, attrName) + sql = """select column_default from information_schema.columns where table_schema = '{0}' and table_name = '{1}' and column_name = '{2}';""".format( + schema, tableName, attrName + ) return sql - + def upgradePostgis(self, updateDict): - sql = '' + sql = "" for key in updateDict: - sql += """ALTER EXTENSION {0} UPDATE TO "{1}";""".format(key, updateDict[key]['defaultVersion']) + sql += """ALTER EXTENSION {0} UPDATE TO "{1}";""".format( + key, updateDict[key]["defaultVersion"] + ) return sql - + def getPostgisVersion(self): - sql = '''SELECT name, default_version,installed_version FROM pg_available_extensions WHERE name in ('postgis', 'postgis_topology')''' + sql = """SELECT name, default_version,installed_version FROM pg_available_extensions WHERE name in ('postgis', 'postgis_topology')""" return sql def getCustomizationPerspectiveDict(self, perspective): if perspective == DsgEnums.Property: - sql = '''select row_to_json(a) from ( - select name, array_agg(datname) from customization as custom + sql = """select row_to_json(a) from ( + select name, array_agg(datname) from customization as custom left join applied_customization as appcust on custom.id = appcust.id_customization left join pg_database as pgd on pgd.oid = appcust.dboid group by name - ) as a''' + ) as a""" if perspective == DsgEnums.Database: - sql = '''select row_to_json(a) from ( - select datname as name, array_agg(name) from customization as custom + sql = """select row_to_json(a) from ( + select datname as name, array_agg(name) from customization as custom left join applied_customization as appcust on custom.id = appcust.id_customization left join pg_database as pgd on pgd.oid = appcust.dboid group by datname - ) as a''' + ) as a""" return sql def getFieldToolBoxConfigPerspectiveDict(self, perspective): if perspective == DsgEnums.Property: - sql = '''select row_to_json(a) from ( - select name, array_agg(datname) from field_toolbox_config as custom + sql = """select row_to_json(a) from ( + select name, array_agg(datname) from field_toolbox_config as custom left join applied_field_toolbox_config as appcust on custom.id = appcust.id_applied_field_toolbox_config left join pg_database as pgd on pgd.oid = appcust.dboid group by name - ) as a''' + ) as a""" if perspective == DsgEnums.Database: - sql = '''select row_to_json(a) from ( - select datname as name, array_agg(name) from field_toolbox_config as custom + sql = """select row_to_json(a) from ( + select datname as name, array_agg(name) from field_toolbox_config as custom left join applied_field_toolbox_config as appcust on custom.id = appcust.id_applied_field_toolbox_config left join pg_database as pgd on pgd.oid = appcust.dboid group by datname - ) as a''' + ) as a""" return sql - + def createFieldToolBoxConfigTable(self): - sql = '''CREATE TABLE IF NOT EXISTS public.field_toolbox_config( + sql = """CREATE TABLE IF NOT EXISTS public.field_toolbox_config( id uuid NOT NULL DEFAULT uuid_generate_v4(), name text, jsondict text NOT NULL, @@ -1449,21 +1849,25 @@ def createFieldToolBoxConfigTable(self): CONSTRAINT field_toolbox_config_unique_name_and_version UNIQUE (name,edgvversion) ); - ''' + """ return sql - + def checkIfTableExists(self, schema, tableName): - sql = '''select table_name from information_schema.tables where table_schema = '{0}' and table_name = '{1}' limit 1'''.format(schema,tableName) + sql = """select table_name from information_schema.tables where table_schema = '{0}' and table_name = '{1}' limit 1""".format( + schema, tableName + ) return sql - + def getRecordFromAdminDb(self, settingType, propertyName, edgvVersion): tableName = self.getSettingTable(settingType) - sql = '''SELECT id, name, jsondict, edgvversion from public.{0} where name = '{1}' and edgvversion = '{2}' '''.format(tableName, propertyName, edgvVersion) + sql = """SELECT id, name, jsondict, edgvversion from public.{0} where name = '{1}' and edgvversion = '{2}' """.format( + tableName, propertyName, edgvVersion + ) return sql - def createPropertyTable(self, settingType, isAdminDb = False): + def createPropertyTable(self, settingType, isAdminDb=False): tableName = self.getSettingTable(settingType) - sql = '''CREATE EXTENSION IF NOT EXISTS "uuid-ossp" WITH SCHEMA public; + sql = """CREATE EXTENSION IF NOT EXISTS "uuid-ossp" WITH SCHEMA public; CREATE TABLE IF NOT EXISTS public.{0}( id uuid NOT NULL DEFAULT uuid_generate_v4(), name text, @@ -1472,9 +1876,11 @@ def createPropertyTable(self, settingType, isAdminDb = False): CONSTRAINT {0}_pk PRIMARY KEY (id), CONSTRAINT {0}_unique_name_and_version UNIQUE (name,edgvversion) ); - '''.format(tableName) + """.format( + tableName + ) if isAdminDb: - sql += '''CREATE TABLE public.applied_{0}( + sql += """CREATE TABLE public.applied_{0}( id uuid NOT NULL DEFAULT uuid_generate_v4(), id_{0} uuid NOT NULL, dboid oid NOT NULL, @@ -1482,112 +1888,150 @@ def createPropertyTable(self, settingType, isAdminDb = False): CONSTRAINT applied_{0}_id_{0}_config_fk FOREIGN KEY (id_{0}) REFERENCES public.{0} (id) MATCH SIMPLE ON UPDATE NO ACTION ON DELETE CASCADE ); ALTER TABLE public.applied_{0} OWNER TO postgres; - '''.format(tableName) + """.format( + tableName + ) return sql - def getPropertyPerspectiveDict(self, settingType, perspective, versionFilter = None): + def getPropertyPerspectiveDict(self, settingType, perspective, versionFilter=None): if versionFilter: - versionFilter = ''' where edgvversion = '{0}' '''.format(versionFilter) + versionFilter = """ where edgvversion = '{0}' """.format(versionFilter) else: - versionFilter = '' + versionFilter = "" tableName = self.getSettingTable(settingType) if perspective == DsgEnums.Property: - sql = '''select row_to_json(a) from ( - select name, array_agg(datname) from public.{0} as custom + sql = """select row_to_json(a) from ( + select name, array_agg(datname) from public.{0} as custom left join applied_{0} as appcust on custom.id = appcust.id_{0} - left join pg_database as pgd on pgd.oid = appcust.dboid + left join pg_database as pgd on pgd.oid = appcust.dboid {1} group by name - ) as a'''.format(tableName, versionFilter) + ) as a""".format( + tableName, versionFilter + ) if perspective == DsgEnums.Database: - sql = '''select row_to_json(a) from ( - select datname as name, array_agg(name) from public.{0} as custom + sql = """select row_to_json(a) from ( + select datname as name, array_agg(name) from public.{0} as custom right join applied_{0} as appcust on custom.id = appcust.id_{0} - left join pg_database as pgd on pgd.oid = appcust.dboid + left join pg_database as pgd on pgd.oid = appcust.dboid {1} group by datname - ) as a'''.format(tableName, versionFilter) + ) as a""".format( + tableName, versionFilter + ) return sql - + def insertRecordInsidePropertyTable(self, settingType, settingDict): tableName = self.getSettingTable(settingType) - sql = '''INSERT INTO public.{0} (name, jsondict, edgvversion) VALUES ('{1}','{2}','{3}')'''.format(tableName, settingDict['name'], settingDict['jsondict'], settingDict['edgvversion']) + sql = """INSERT INTO public.{0} (name, jsondict, edgvversion) VALUES ('{1}','{2}','{3}')""".format( + tableName, + settingDict["name"], + settingDict["jsondict"], + settingDict["edgvversion"], + ) return sql def insertInstalledRecordIntoAdminDb(self, settingType, recDict, dbOid): settingTable = self.getSettingTable(settingType) - tableName = 'applied_'+settingTable - idName = 'id_'+settingTable - sql = '''INSERT INTO public.{0} ({1}, dboid) VALUES ('{2}',{3})'''.format(tableName, idName, recDict['id'], dbOid) + tableName = "applied_" + settingTable + idName = "id_" + settingTable + sql = """INSERT INTO public.{0} ({1}, dboid) VALUES ('{2}',{3})""".format( + tableName, idName, recDict["id"], dbOid + ) return sql - + def getDbOID(self, dbName): - sql = '''SELECT oid from pg_database where datname = '{0}' '''.format(dbName) + sql = """SELECT oid from pg_database where datname = '{0}' """.format(dbName) return sql - + def getAllPropertiesFromDb(self, settingType): tableName = self.getSettingTable(settingType) - sql = '''select edgvversion, name, jsondict from public.{0}'''.format(tableName) + sql = """select edgvversion, name, jsondict from public.{0}""".format(tableName) return sql - + def removeRecordFromPropertyTable(self, settingType, configName, edgvVersion): tableName = self.getSettingTable(settingType) if not edgvVersion: - sql = '''DELETE FROM public.{0} where name = '{1}';'''.format(tableName, configName) + sql = """DELETE FROM public.{0} where name = '{1}';""".format( + tableName, configName + ) else: - sql = '''DELETE FROM public.{0} where name = '{1}' and edgvversion = '{2}';'''.format(tableName, configName, edgvVersion) + sql = """DELETE FROM public.{0} where name = '{1}' and edgvversion = '{2}';""".format( + tableName, configName, edgvVersion + ) return sql - def updateRecordFromPropertyTable(self, settingType, configName, edgvVersion, jsonDict): + def updateRecordFromPropertyTable( + self, settingType, configName, edgvVersion, jsonDict + ): tableName = self.getSettingTable(settingType) - sql = '''UPDATE public.{0} SET jsondict = '{1}' where name = '{2}' and edgvversion = '{3}';'''.format(tableName, jsonDict, configName, edgvVersion) + sql = """UPDATE public.{0} SET jsondict = '{1}' where name = '{2}' and edgvversion = '{3}';""".format( + tableName, jsonDict, configName, edgvVersion + ) return sql - - def uninstallPropertyOnAdminDb(self, settingType, configName, edgvVersion, dbName = None): + + def uninstallPropertyOnAdminDb( + self, settingType, configName, edgvVersion, dbName=None + ): tableName = self.getSettingTable(settingType) - dbNameFilterClause = '' + dbNameFilterClause = "" if dbName: - dbNameFilterClause = '''dboid in (select oid from pg_database where datname ='{0}') and '''.format(dbName) - sql = '''DELETE FROM public.applied_{0} where {1} id_{0} in (select id from public.{0} where name = '{2}' and edgvversion = '{3}');'''.format(tableName, dbNameFilterClause, configName, edgvVersion) + dbNameFilterClause = """dboid in (select oid from pg_database where datname ='{0}') and """.format( + dbName + ) + sql = """DELETE FROM public.applied_{0} where {1} id_{0} in (select id from public.{0} where name = '{2}' and edgvversion = '{3}');""".format( + tableName, dbNameFilterClause, configName, edgvVersion + ) return sql - + def getSettingVersion(self, settingType, settingName): tableName = self.getSettingTable(settingType) - sql = '''select edgvversion from public.{0} where name = '{1}' '''.format(tableName, settingName) + sql = """select edgvversion from public.{0} where name = '{1}' """.format( + tableName, settingName + ) return sql - + def getPrimaryKeyColumn(self, tableName): - if '.' in tableName: - tableSchema, tableName = tableName.replace("'","").replace('"','').split('.') + if "." in tableName: + tableSchema, tableName = ( + tableName.replace("'", "").replace('"', "").split(".") + ) tableName = '''"{0}"."{1}"'''.format(tableSchema, tableName) - sql = ''' + sql = """ SELECT a.attname, format_type(a.atttypid, a.atttypmod) AS data_type FROM pg_index i JOIN pg_attribute a ON a.attrelid = i.indrelid AND a.attnum = ANY(i.indkey) WHERE i.indrelid = '{}'::regclass - AND i.indisprimary; - '''.format(tableName) + AND i.indisprimary; + """.format( + tableName + ) return sql - + def getGeometryTablesCount(self): - sql = '''select count(*) from public.geometry_columns''' + sql = """select count(*) from public.geometry_columns""" return sql - + def dropAllConections(self, dbName): sql = """SELECT pg_terminate_backend(pg_stat_activity.pid) FROM pg_stat_activity WHERE pg_stat_activity.datname = '{0}' - AND pid <> pg_backend_pid();""".format(dbName) + AND pid <> pg_backend_pid();""".format( + dbName + ) return sql - def getAttributesFromTable(self, tableSchema, tableName, typeFilter = None): - whereClause = """""" if not typeFilter \ - else """ and data_type in ('{0}') """.format( - "','".join(typeFilter) - ) - sql = """select column_name, data_type from information_schema.columns where - table_schema = '{0}' and table_name = '{1}' {2} order by column_name """.format(tableSchema, tableName, whereClause) + def getAttributesFromTable(self, tableSchema, tableName, typeFilter=None): + whereClause = ( + """""" + if not typeFilter + else """ and data_type in ('{0}') """.format("','".join(typeFilter)) + ) + sql = """select column_name, data_type from information_schema.columns where + table_schema = '{0}' and table_name = '{1}' {2} order by column_name """.format( + tableSchema, tableName, whereClause + ) return sql def getViewDefinition(self, viewName): @@ -1597,8 +2041,8 @@ def getViewDefinition(self, viewName): def dropView(self, viewName): if '"' in viewName: sql = """DROP VIEW {0} """.format(viewName) - elif '.' in viewName: - schema, name = viewName.split('.') + elif "." in viewName: + schema, name = viewName.split(".") sql = """DROP VIEW "{0}"."{1}" """.format(schema, name) else: sql = """DROP VIEW "{0}" """.format(viewName) @@ -1610,8 +2054,8 @@ def createViewStatement(self, viewName, viewDef): def checkPostGISAddonsInstallation(self): sql = """SELECT COUNT(*) FROM pg_proc WHERE proname = 'st_geotablesummary' """ - return sql - + return sql + def createCoverageTempTable(self, srid): sql = """ DROP TABLE IF EXISTS validation.coverage_temp; @@ -1622,26 +2066,34 @@ def createCoverageTempTable(self, srid): geom geometry(MULTIPOLYGON, {}) NOT NULL, CONSTRAINT coverage_pk PRIMARY KEY (id) ) - """.format(srid) + """.format( + srid + ) return sql def checkCoverageForGapsWithFrame(self, frameTable, geomColumn): - frameSchema, frameTable = frameTable.split('.') + frameSchema, frameTable = frameTable.split(".") sql = """ select (ST_Dump(ST_SymDifference(a.geom, b.geom))).geom from (select ST_Union({0}) as geom from "{1}"."{2}") as a, (select ST_Union(geom) as geom from validation.coverage_temp) as b - """.format(geomColumn, frameSchema, frameTable) + """.format( + geomColumn, frameSchema, frameTable + ) return sql - def checkCoverageForOverlaps(self, table='validation.coverage_temp', geomColumn='geom', keyColumn='id'): - tableSchema, tableName = table.split('.') + def checkCoverageForOverlaps( + self, table="validation.coverage_temp", geomColumn="geom", keyColumn="id" + ): + tableSchema, tableName = table.split(".") sql = """ select (ST_Dump(foo.geom)).geom as geom from ( select (ST_GeoTableSummary('{0}', '{1}', '{2}', '{3}', 10, 'S3')).geom - ) as foo + ) as foo where ST_IsEmpty(foo.geom) = 'f' - """.format(tableSchema, tableName, geomColumn, keyColumn) + """.format( + tableSchema, tableName, geomColumn, keyColumn + ) return sql def getProcessOrClassFlags(self, filterType=None): @@ -1652,16 +2104,16 @@ def getProcessOrClassFlags(self, filterType=None): # filterType = filterType.lower() sql = "" # problemas com o Enum. - if 'process' in filterType.lower(): + if "process" in filterType.lower(): filterType = 0 elif filterType: filterType = 1 - if filterType == DsgEnums.ProcessName: + if filterType == DsgEnums.ProcessName: sql = """ - SELECT DISTINCT process_name + SELECT DISTINCT process_name FROM validation.aux_flags_validacao; """ - elif filterType == DsgEnums.ClassName: + elif filterType == DsgEnums.ClassName: sql = """ SELECT DISTINCT layer FROM validation.aux_flags_validacao; @@ -1675,7 +2127,7 @@ def getFilteredFlagsQuery(self, filterType=None, filteredElement=None): """ sql = "" # problemas com o Enum. - if 'process' in filterType.lower(): + if "process" in filterType.lower(): filterTypeEnum = 0 elif filterType: filterTypeEnum = 1 @@ -1683,45 +2135,49 @@ def getFilteredFlagsQuery(self, filterType=None, filteredElement=None): SELECT * FROM validation.aux_flags_validacao; """ whereClause = "" - if filterTypeEnum == DsgEnums.ProcessName: + if filterTypeEnum == DsgEnums.ProcessName: whereClause = " WHERE process_name = '{0}';".format(filteredElement) elif filterType == DsgEnums.ClassName: whereClause = " WHERE layer = '{0}';".format(filteredElement) - if filteredElement and filteredElement != '': + if filteredElement and filteredElement != "": sql = sql + whereClause return sql def createFilteredFlagsViewTableQuery(self, filterType=None, filteredElement=None): """ - Returns the query for creating and populating a view table of flags raised in + Returns the query for creating and populating a view table of flags raised in validation processes based on users settings. """ sql = """ - CREATE OR REPLACE VIEW validation.filtered_flags AS + CREATE OR REPLACE VIEW validation.filtered_flags AS SELECT * FROM validation.aux_flags_validacao """ whereClause = "" # problemas com o Enum. - if 'process' in filterType.lower(): + if "process" in filterType.lower(): filterTypeEnum = 0 elif filterType: - filterTypeEnum = 1 - if filterTypeEnum == DsgEnums.ProcessName: + filterTypeEnum = 1 + if filterTypeEnum == DsgEnums.ProcessName: whereClause = " WHERE process_name = '{0}';".format(filteredElement) elif filterTypeEnum == DsgEnums.ClassName: whereClause = " WHERE layer = '{0}';".format(filteredElement) - if filteredElement and filteredElement != '': + if filteredElement and filteredElement != "": sql = sql + whereClause return sql - - def checkCoverageForGaps(self, table='validation.coverage_temp', geomColumn='geom', keyColumn='id'): - tableSchema, tableName = table.split('.') + + def checkCoverageForGaps( + self, table="validation.coverage_temp", geomColumn="geom", keyColumn="id" + ): + tableSchema, tableName = table.split(".") sql = """ select (ST_Dump(foo.geom)).geom as geom from ( select (ST_GeoTableSummary('{0}', '{1}', '{2}', '{3}', 10, 'S4')).geom - ) as foo + ) as foo where ST_IsEmpty(foo.geom) = 'f' - """.format(tableSchema, tableName, geomColumn, keyColumn) + """.format( + tableSchema, tableName, geomColumn, keyColumn + ) return sql def createValidationHistoryViewTableQuery(self, idListString=None): @@ -1733,24 +2189,29 @@ def createValidationHistoryViewTableQuery(self, idListString=None): This method uses the data on compact_process_history. """ sql = """ - CREATE OR REPLACE VIEW validation.process_history_view AS + CREATE OR REPLACE VIEW validation.process_history_view AS SELECT t.process_name, t.log, s.status, t.finished FROM validation.compact_process_history AS t JOIN validation.status AS s ON t.status = s.id ORDER BY t.finished DESC; """ if idListString: - sql = sql.replace("ORDER BY t.finished DESC;", "WHERE t.id in {0} ORDER BY t.finished DESC;").format(idListString) + sql = sql.replace( + "ORDER BY t.finished DESC;", + "WHERE t.id in {0} ORDER BY t.finished DESC;", + ).format(idListString) return sql def getQmlRecords(self, layerList): - sql = """select layername, domainqml from public.domain_qml where layername in ('{0}')""".format("','".join(layerList)) + sql = """select layername, domainqml from public.domain_qml where layername in ('{0}')""".format( + "','".join(layerList) + ) return sql - + def getImplementationVersion(self): sql = """select dbimplversion from public.db_metadata limit 1""" return sql - + def getValidationLogQuery(self): """ Returns the query for a list of all logs UNIQUE registered for each @@ -1759,7 +2220,7 @@ def getValidationLogQuery(self): sql = """SELECT DISTINCT log, id FROM validation.compact_process_history;""" # ALTERAR PARA FUNÇÃO DE UPDATE DA TABELA PARA QUE INCLUA OS NOMES DE USUÁRIOS return sql - + def getValidationHistoryQuery(self, idListString=None): """ Returns the query of all validation processes available informations. @@ -1769,7 +2230,7 @@ def getValidationHistoryQuery(self, idListString=None): if idListString: sql = sql.replace(";", " WHERE id IN {};".format(idListString)) return sql - + def createCompactValidationHistoryQuery(self): """ Returns the query for compact validation history table creation. @@ -1795,18 +2256,33 @@ def populateCompactValidationHistoryQuery(self, logList): sql = "" if isinstance(logList, list): for log in logList: - sql += u"""INSERT INTO validation.compact_process_history (id, process_name, log, status, finished) VALUES ({0}, '{1}', '{2}', {3}, '{4}');\n""".\ - format(log[0], log[1], log[2].replace(r"\n", "\n"), log[3], log[4].toPyDateTime()) + sql += """INSERT INTO validation.compact_process_history (id, process_name, log, status, finished) VALUES ({0}, '{1}', '{2}', {3}, '{4}');\n""".format( + log[0], + log[1], + log[2].replace(r"\n", "\n"), + log[3], + log[4].toPyDateTime(), + ) elif logList: - sql += u"""INSERT INTO validation.compact_process_history (id, process_name, log, status, finished) VALUES ({0}, '{1}', '{2}', {3}, '{4}');\n""".\ - format(logList[0], logList[1], logList[2].replace(r"\n", "\n"), logList[3], logList[4].toPyDateTime()) + sql += """INSERT INTO validation.compact_process_history (id, process_name, log, status, finished) VALUES ({0}, '{1}', '{2}', {3}, '{4}');\n""".format( + logList[0], + logList[1], + logList[2].replace(r"\n", "\n"), + logList[3], + logList[4].toPyDateTime(), + ) return sql + def getAttrListWithFilter(self): sql = """select distinct table_name from information_schema.columns where table_schema = 'dominios' and column_name = 'filter'""" return sql - + def getFilterJsonList(self, domainName): - sql = """select row_to_json(a) from (select * from dominios.{0}) as a """.format(domainName) + sql = ( + """select row_to_json(a) from (select * from dominios.{0}) as a """.format( + domainName + ) + ) return sql def databaseInfo(self): diff --git a/DsgTools/core/Factories/SqlFactory/spatialiteSqlGenerator.py b/DsgTools/core/Factories/SqlFactory/spatialiteSqlGenerator.py index c3746e872..f4e6ec7c2 100644 --- a/DsgTools/core/Factories/SqlFactory/spatialiteSqlGenerator.py +++ b/DsgTools/core/Factories/SqlFactory/spatialiteSqlGenerator.py @@ -23,9 +23,15 @@ from .sqlGenerator import SqlGenerator from ...dsgEnums import DsgEnums + class SpatialiteSqlGenerator(SqlGenerator): def getComplexLinks(self, complex): - sql = "SELECT complex_schema, complex, aggregated_schema, aggregated_class, column_name from public_complex_schema where complex = "+'\''+complex+'\'' + sql = ( + "SELECT complex_schema, complex, aggregated_schema, aggregated_class, column_name from public_complex_schema where complex = " + + "'" + + complex + + "'" + ) return sql def getComplexTablesFromDatabase(self): @@ -33,24 +39,64 @@ def getComplexTablesFromDatabase(self): return sql def getComplexData(self, complex_schema, complex): - sql = "SELECT id, nome from "+complex_schema+"_"+complex + sql = "SELECT id, nome from " + complex_schema + "_" + complex return sql - def getAssociatedFeaturesData(self, aggregated_schema, aggregated_class, column_name, complex_uuid): - if aggregated_schema == 'complexos': - sql = "SELECT id from "+aggregated_schema+"_"+aggregated_class+" where "+column_name+"="+'\''+complex_uuid+'\'' + def getAssociatedFeaturesData( + self, aggregated_schema, aggregated_class, column_name, complex_uuid + ): + if aggregated_schema == "complexos": + sql = ( + "SELECT id from " + + aggregated_schema + + "_" + + aggregated_class + + " where " + + column_name + + "=" + + "'" + + complex_uuid + + "'" + ) else: - sql = "SELECT OGC_FID from "+aggregated_schema+"_"+aggregated_class+" where "+column_name+"="+'\''+complex_uuid+'\'' + sql = ( + "SELECT OGC_FID from " + + aggregated_schema + + "_" + + aggregated_class + + " where " + + column_name + + "=" + + "'" + + complex_uuid + + "'" + ) return sql def getLinkColumn(self, complexClass, aggregatedClass): if self.isComplexClass(aggregatedClass): - sql = 'SELECT column_name from public_complex_schema where complex = \''+complexClass+'\''+' and aggregated_class = '+'\''+aggregatedClass[10:]+'\'' + sql = ( + "SELECT column_name from public_complex_schema where complex = '" + + complexClass + + "'" + + " and aggregated_class = " + + "'" + + aggregatedClass[10:] + + "'" + ) else: - sql = 'SELECT column_name from public_complex_schema where complex = \''+complexClass+'\''+' and aggregated_class = '+'\''+aggregatedClass+'\'' + sql = ( + "SELECT column_name from public_complex_schema where complex = '" + + complexClass + + "'" + + " and aggregated_class = " + + "'" + + aggregatedClass + + "'" + ) return sql - def getSrid(self, parameters = dict()): + def getSrid(self, parameters=dict()): sql = "SELECT srid from geometry_columns" return sql @@ -59,11 +105,20 @@ def getTablesFromDatabase(self): return sql def disassociateComplexFromComplex(self, aggregated_class, link_column, uuid): - sql = "UPDATE "+aggregated_class+" SET "+link_column+"=NULL WHERE id = "+'\''+uuid+'\'' + sql = ( + "UPDATE " + + aggregated_class + + " SET " + + link_column + + "=NULL WHERE id = " + + "'" + + uuid + + "'" + ) return sql def isComplexClass(self, aggregatedClass): - size = len(aggregatedClass.split('_')[0]) + size = len(aggregatedClass.split("_")[0]) if size == 9: return True return False @@ -75,148 +130,168 @@ def getCreateDatabase(self, name): return None def insertFrameIntoTable(self, wkt): - sql = "INSERT INTO public_aux_moldura_a(GEOMETRY) VALUES(GeomFromText("+wkt+"))" + sql = ( + "INSERT INTO public_aux_moldura_a(GEOMETRY) VALUES(GeomFromText(" + + wkt + + "))" + ) return sql def getElementCountFromLayer(self, layer): - sql = "SELECT count(*) FROM "+layer + sql = "SELECT count(*) FROM " + layer return sql - + def createRole(self, mydict): return None def dropRole(self, role): return None - + def grantRole(self, user, role): return None - + def revokeRole(self, user, role): return None - + def getRoles(self): return None - + def getUserRelatedRoles(self): return None - + def getUsers(self): return None - + def createUser(self): - return None - + return None + def removeUser(self): - return None + return None def alterUserPass(self): - return None - + return None + def validateWithDomain(self): return None - + def getNotNullFields(self): return None - - def getFeaturesWithSQL(self,layer,attrList): - ls = ','.join(attrList) - sql = 'SELECT %s FROM %s' % (ls,layer) - return sql - - def getStructure(self,edgvVersion): - sql = '' - if edgvVersion == '2.1.3': - sql = 'select name, sql from sqlite_master where type = \'table\' and (name like \'cb_%\' or name like \'complexos_%\' or name like \'public_%\')' - elif edgvVersion == 'FTer_2a_Ed': - sql = 'select name, sql from sqlite_master where type = \'table\' and (name like \'ge_%\' or name like \'pe_%\' or name like \'complexos_%\' or name like \'public_%\')' - elif edgvVersion == '3.0': - sql = sql = 'select name, sql from sqlite_master where type = \'table\' and (name like \'edgv_%\' or name like \'complexos_%\' or name like \'public_%\')' - return sql - + + def getFeaturesWithSQL(self, layer, attrList): + ls = ",".join(attrList) + sql = "SELECT %s FROM %s" % (ls, layer) + return sql + + def getStructure(self, edgvVersion): + sql = "" + if edgvVersion == "2.1.3": + sql = "select name, sql from sqlite_master where type = 'table' and (name like 'cb_%' or name like 'complexos_%' or name like 'public_%')" + elif edgvVersion == "FTer_2a_Ed": + sql = "select name, sql from sqlite_master where type = 'table' and (name like 'ge_%' or name like 'pe_%' or name like 'complexos_%' or name like 'public_%')" + elif edgvVersion == "3.0": + sql = ( + sql + ) = "select name, sql from sqlite_master where type = 'table' and (name like 'edgv_%' or name like 'complexos_%' or name like 'public_%')" + return sql + def getAggregationColumn(self): - sql = 'SELECT DISTINCT column_name FROM public_complex_schema' + sql = "SELECT DISTINCT column_name FROM public_complex_schema" return sql def getAggregatorFromId(self, className, id): - sql = 'SELECT id from %s where id =\'%s\'' % (className,id) - return sql - - def getAggregatorFromComplexSchema(self,aggregated,aggregationColumn): - sql = 'SELECT complex from public_complex_schema where aggregated_class = \'%s\' and aggregationColumn = \'%s\'' % (aggregated,aggregationColumn) + sql = "SELECT id from %s where id ='%s'" % (className, id) + return sql + + def getAggregatorFromComplexSchema(self, aggregated, aggregationColumn): + sql = ( + "SELECT complex from public_complex_schema where aggregated_class = '%s' and aggregationColumn = '%s'" + % (aggregated, aggregationColumn) + ) return sql - + def createCustomSort(self): return None - + def getRolePrivileges(self, role, dbname): return None - def isSuperUser(self,user): + def isSuperUser(self, user): return None def getInvalidGeom(self, tableSchema, tableName): return None def makeRelationDict(self, table, in_clause): - sql = 'select code, code_name from dominios_%s where code in %s' % (table, in_clause) + sql = "select code, code_name from dominios_%s where code in %s" % ( + table, + in_clause, + ) return sql def checkValidationStructure(self): return None - def createValidationStructure(self,srid): + def createValidationStructure(self, srid): return None - + def getEDGVVersion(self): sql = "SELECT edgvversion FROM public_db_metadata LIMIT 1" return sql - + def getEDGVVersionAndImplementationVersion(self): sql = "SELECT edgvversion, dbimplversion FROM public_db_metadata LIMIT 1" return sql - + def getStylesFromDb(self, dbVersion): return None def getGeomTablesFromGeometryColumns(self, edgvVersion): - if edgvVersion in ('2.1.3','FTer_2a_Ed'): - sql = 'select srid, f_geometry_column, type, f_table_name from geometry_columns' + if edgvVersion in ("2.1.3", "FTer_2a_Ed"): + sql = "select srid, f_geometry_column, type, f_table_name from geometry_columns" else: - sql = 'select srid, f_geometry_column, geometry_type, f_table_name from geometry_columns' + sql = "select srid, f_geometry_column, geometry_type, f_table_name from geometry_columns" return sql def getGeomByPrimitive(self, edgvVersion): - if edgvVersion in ('2.1.3','FTer_2a_Ed'): + if edgvVersion in ("2.1.3", "FTer_2a_Ed"): sql = """select type, f_table_name from geometry_columns""" else: sql = """select geometry_type, f_table_name from geometry_columns""" return sql - + def getGeomColumnDict(self): sql = """select f_geometry_column, f_table_name from geometry_columns""" return sql - - def insertFrame(self,scale,mi,inom,frame,srid,geoSrid, paramDict = dict()): - sql = """INSERT INTO public_aux_moldura_a (mi,inom,escala,GEOMETRY) VALUES ('{0}','{1}','{2}',Transform(ST_GeomFromText('{3}',{4}), {5}))""".format(mi,inom,scale,frame,geoSrid,srid) + + def insertFrame(self, scale, mi, inom, frame, srid, geoSrid, paramDict=dict()): + sql = """INSERT INTO public_aux_moldura_a (mi,inom,escala,GEOMETRY) VALUES ('{0}','{1}','{2}',Transform(ST_GeomFromText('{3}',{4}), {5}))""".format( + mi, inom, scale, frame, geoSrid, srid + ) return sql - + def getElementCountFromLayerV2(self, schema, table, useInheritance): - layer = '_'.join([schema, table]) + layer = "_".join([schema, table]) return self.getElementCountFromLayer(layer) - + def getFullTablesName(self, name): - sql = "SELECT f_table_name as name FROM geometry_columns WHERE f_table_name LIKE '%{0}%' ORDER BY name".format(name) + sql = "SELECT f_table_name as name FROM geometry_columns WHERE f_table_name LIKE '%{0}%' ORDER BY name".format( + name + ) return sql - def getGeomColumnTupleList(self, edgvVersion, showViews = False): - if edgvVersion in ('2.1.3','FTer_2a_Ed'): - sql = """select f_table_name, f_geometry_column, type from geometry_columns""" + def getGeomColumnTupleList(self, edgvVersion, showViews=False): + if edgvVersion in ("2.1.3", "FTer_2a_Ed"): + sql = ( + """select f_table_name, f_geometry_column, type from geometry_columns""" + ) else: sql = """select f_table_name, f_geometry_column, geometry_type from geometry_columns""" return sql def getQmlRecords(self, layerList): - sql = """select layername, domainqml from public_domain_qml where layername in ('{0}')""".format("','".join(layerList)) + sql = """select layername, domainqml from public_domain_qml where layername in ('{0}')""".format( + "','".join(layerList) + ) return sql def databaseInfo(self): @@ -229,7 +304,7 @@ def databaseInfo(self): FROM geometry_columns ORDER BY f_table_name ASC""" return sql - + def implementationVersion(self): """ Query to retrieve database's implementation version, if available. diff --git a/DsgTools/core/Factories/SqlFactory/sqlGenerator.py b/DsgTools/core/Factories/SqlFactory/sqlGenerator.py index 83470e612..55d32b6c9 100644 --- a/DsgTools/core/Factories/SqlFactory/sqlGenerator.py +++ b/DsgTools/core/Factories/SqlFactory/sqlGenerator.py @@ -23,6 +23,7 @@ from builtins import object from ...dsgEnums import DsgEnums + class SqlGenerator(object): def getComplexLinks(self, complex): return None @@ -33,7 +34,9 @@ def getComplexTablesFromDatabase(self): def getComplexData(self, complex_schema, complex): return None - def getAssociatedFeaturesData(self, aggregated_schema, aggregated_class, column_name, complex_uuid): + def getAssociatedFeaturesData( + self, aggregated_schema, aggregated_class, column_name, complex_uuid + ): return None def getLinkColumn(self, complexClass, aggregatedClass): @@ -45,7 +48,7 @@ def getSrid(self): def getEDGVVersion(self): sql = "SELECT edgvversion FROM db_metadata LIMIT 1" return sql - + def getEDGVVersionAndImplementationVersion(self): sql = "SELECT edgvversion, dbimplversion FROM db_metadata LIMIT 1" return sql @@ -67,79 +70,79 @@ def insertFrameIntoTable(self, wkb): def getDatabasesFromServer(self): return None - + def dropDatabase(self, name): return None - + def createRole(self, mydict): return None def dropRole(self, role): return None - + def grantRole(self, user, role): return None - + def revokeRole(self, user, role): return None - + def getRoles(self): return None - + def getUserRelatedRoles(self): return None - + def getUsers(self): return None - + def createUser(self): return None - + def removeUser(self): - return None + return None def alterUserPass(self): return None - + def validateWithDomain(self): - return None - + return None + def getNotNullFields(self): - return None - - def getFeaturesWithSQL(self,layer,attrList): return None - def getStructure(self,edgvVersion): + def getFeaturesWithSQL(self, layer, attrList): + return None + + def getStructure(self, edgvVersion): return None def getAggregationColumn(self): return None def getAggregatorFromId(self, className, id): - return None - - def getAggregatorFromComplexSchema(self,aggregated,aggregationColumn): return None - + + def getAggregatorFromComplexSchema(self, aggregated, aggregationColumn): + return None + def createCustomSort(self): return None - + def getRolePrivileges(self, role, dbname): return None - def isSuperUser(self,user): + def isSuperUser(self, user): return None - + def getInvalidGeom(self, tableSchema, tableName): return None def checkValidationStructure(self): return None - def createValidationStructure(self,srid): + def createValidationStructure(self, srid): return None - + def getTableExtent(self, tableSchema, tableName): return None @@ -148,4 +151,4 @@ def implementationVersion(self): Query to retrieve database's implementation version, if available. :return: (str) database's implementation version (e.g. '5.2'). """ - return None \ No newline at end of file + return None diff --git a/DsgTools/core/Factories/SqlFactory/sqlGeneratorFactory.py b/DsgTools/core/Factories/SqlFactory/sqlGeneratorFactory.py index 652205e58..daea0b75e 100644 --- a/DsgTools/core/Factories/SqlFactory/sqlGeneratorFactory.py +++ b/DsgTools/core/Factories/SqlFactory/sqlGeneratorFactory.py @@ -37,8 +37,8 @@ def createSqlGenerator(self, driver): :return: """ genDict = { - DsgEnums.DriverGeopackage : lambda : GeopackageSqlGenerator(), - DsgEnums.DriverSpatiaLite : lambda : SpatialiteSqlGenerator(), - DsgEnums.DriverPostGIS : lambda : PostGISSqlGenerator() + DsgEnums.DriverGeopackage: lambda: GeopackageSqlGenerator(), + DsgEnums.DriverSpatiaLite: lambda: SpatialiteSqlGenerator(), + DsgEnums.DriverPostGIS: lambda: PostGISSqlGenerator(), } return genDict[driver]() diff --git a/DsgTools/core/Factories/ThreadFactory/dpiThread.py b/DsgTools/core/Factories/ThreadFactory/dpiThread.py index 0a0035210..1e97a9b83 100644 --- a/DsgTools/core/Factories/ThreadFactory/dpiThread.py +++ b/DsgTools/core/Factories/ThreadFactory/dpiThread.py @@ -36,6 +36,7 @@ from .genericThread import GenericThread + class DpiMessages(QObject): def __init__(self, thread): super(DpiMessages, self).__init__() @@ -43,13 +44,13 @@ def __init__(self, thread): self.thread = thread def getProblemMessage(self): - return self.tr('Problem processing image: ') + return self.tr("Problem processing image: ") def getProblemFeedbackMessage(self): - return self.tr('Problem processing images. Check log for details.') + return self.tr("Problem processing images. Check log for details.") def getUserCanceledFeedbackMessage(self): - return self.tr('User canceled image processing!') + return self.tr("User canceled image processing!") def getSuccessFeedbackMessage(self): return self.tr("Successful image processing.") @@ -61,6 +62,7 @@ def getSuccessfullFileCreation(self): def progressCanceled(self): self.thread.stopped[0] = True + class DpiThread(GenericThread): def __init__(self): """ @@ -70,7 +72,18 @@ def __init__(self): self.messenger = DpiMessages(self) - def setParameters(self, filesList, rasterType, minOutValue, maxOutValue, outDir, percent, epsg, stopped, bands = []): + def setParameters( + self, + filesList, + rasterType, + minOutValue, + maxOutValue, + outDir, + percent, + epsg, + stopped, + bands=[], + ): """ Sets thread parameters filesList: files processed @@ -111,7 +124,7 @@ def processImages(self, filesList): steps = 0 for file in self.filesList: - #Open image + # Open image imgIn = osgeo.gdal.Open(file) if not imgIn: continue @@ -125,7 +138,9 @@ def processImages(self, filesList): problemOcurred = False for file in self.filesList: - ret = self.stretchImage(file, self.outDir, self.percent, self.epsg, self.bands) + ret = self.stretchImage( + file, self.outDir, self.percent, self.epsg, self.bands + ) if ret == 1: pass elif ret == 0: @@ -143,74 +158,89 @@ def stretchImage(self, inFile, outDir, percent, epsg, bands): Method that applies a specific histogram stretching to a group of images. The method also performs a conversion changing the raster type. """ - #Getting the output raster type - (rasterType, minOutValue, maxOutValue) = (self.rasterType, self.minOutValue, self.maxOutValue) - - #Open image + # Getting the output raster type + (rasterType, minOutValue, maxOutValue) = ( + self.rasterType, + self.minOutValue, + self.maxOutValue, + ) + + # Open image imgIn = osgeo.gdal.Open(inFile) if not imgIn: - QgsMessageLog.logMessage(self.messenger.getProblemMessage() + inFile, "DSGTools Plugin", QgsMessageLog.INFO) + QgsMessageLog.logMessage( + self.messenger.getProblemMessage() + inFile, + "DSGTools Plugin", + QgsMessageLog.INFO, + ) return 0 - #Setting the output file name + # Setting the output file name fileName = inFile.split("/")[-1] split = fileName.split(".") baseName = split[0] - extension = '.' + split[-1] + extension = "." + split[-1] - #Defining the output driver + # Defining the output driver outDriver = imgIn.GetDriver() - createOptions = ['PHOTOMETRIC=RGB', 'ALPHA=NO'] + createOptions = ["PHOTOMETRIC=RGB", "ALPHA=NO"] - #creating temp file for contrast stretch - outFileTmp = os.path.join(outDir, baseName+'_tmp'+extension) - #creating output file for contrast stretch - outFile = os.path.join(outDir, baseName+'_stretch'+extension) + # creating temp file for contrast stretch + outFileTmp = os.path.join(outDir, baseName + "_tmp" + extension) + # creating output file for contrast stretch + outFile = os.path.join(outDir, baseName + "_stretch" + extension) - #if bands is empty, make a new file with the same band size + # if bands is empty, make a new file with the same band size if bands == []: bands = list(range(0, imgIn.RasterCount)) - #Creating a temp image, with the same input parameters, to store the converted input image to 8 bits - imgOut = outDriver.Create(outFileTmp, imgIn.RasterXSize, imgIn.RasterYSize, len(bands), rasterType, options=createOptions) + # Creating a temp image, with the same input parameters, to store the converted input image to 8 bits + imgOut = outDriver.Create( + outFileTmp, + imgIn.RasterXSize, + imgIn.RasterYSize, + len(bands), + rasterType, + options=createOptions, + ) imgOut.SetProjection(imgIn.GetProjection()) imgOut.SetGeoTransform(imgIn.GetGeoTransform()) - #Linear stretching - topPercent = 1.-percent/200. - bottomPercent = percent/200. + # Linear stretching + topPercent = 1.0 - percent / 200.0 + bottomPercent = percent / 200.0 outBandNumber = 1 for bandNumber in bands: if not self.stopped[0]: - b1 = imgIn.GetRasterBand(bandNumber+1) + b1 = imgIn.GetRasterBand(bandNumber + 1) arr = b1.ReadAsArray() # Updating progress self.signals.stepProcessed.emit(self.getId()) - #computing percentile + # computing percentile newArr = arr.flatten() newArr.sort() total = len(newArr) if percent == 0: minValue = float(newArr[0]) - maxValue = float(newArr[total-1]) + maxValue = float(newArr[total - 1]) else: - minValue = float(newArr[int(bottomPercent*total)]) - maxValue = float(newArr[int(math.ceil(topPercent*total))]) + minValue = float(newArr[int(bottomPercent * total)]) + maxValue = float(newArr[int(math.ceil(topPercent * total))]) del newArr # Updating progress self.signals.stepProcessed.emit(self.getId()) - #Transformation parameters - #Rouding the values out of bounds + # Transformation parameters + # Rouding the values out of bounds numpy.putmask(arr, arr > maxValue, maxValue) numpy.putmask(arr, arr < minValue, minValue) # Updating progress self.signals.stepProcessed.emit(self.getId()) - #The maxOutValue and the minOutValue must be set according to the convertion that will be applied (e.g. 8 bits, 16 bits, 32 bits) - a = (maxOutValue-minOutValue)/(maxValue-minValue) - newArr = (arr-minValue)*a+minOutValue + # The maxOutValue and the minOutValue must be set according to the convertion that will be applied (e.g. 8 bits, 16 bits, 32 bits) + a = (maxOutValue - minOutValue) / (maxValue - minValue) + newArr = (arr - minValue) * a + minOutValue # Updating progress self.signals.stepProcessed.emit(self.getId()) @@ -221,31 +251,54 @@ def stretchImage(self, inFile, outDir, percent, epsg, bands): # Updating progress self.signals.stepProcessed.emit(self.getId()) - QgsMessageLog.logMessage("Band " + str(bandNumber) + ": "+str(minValue)+" , "+str(maxValue), "DSGTools Plugin", QgsMessageLog.INFO) + QgsMessageLog.logMessage( + "Band " + + str(bandNumber) + + ": " + + str(minValue) + + " , " + + str(maxValue), + "DSGTools Plugin", + QgsMessageLog.INFO, + ) else: - QgsMessageLog.logMessage(self.messenger.getUserCanceledFeedbackMessage(), "DSGTools Plugin", QgsMessageLog.INFO) + QgsMessageLog.logMessage( + self.messenger.getUserCanceledFeedbackMessage(), + "DSGTools Plugin", + QgsMessageLog.INFO, + ) return -1 - #creating final image for reprojection + # creating final image for reprojection outRasterSRS = osgeo.osr.SpatialReference() outRasterSRS.ImportFromEPSG(epsg) - #this code uses virtual raster to compute the parameters of the output image - vrt = osgeo.gdal.AutoCreateWarpedVRT(imgOut, None, outRasterSRS.ExportToWkt(), osgeo.gdal.GRA_NearestNeighbour, 0.0) - imgWGS = outDriver.CreateCopy(outFile, vrt, options = createOptions) - - #Checking if the output file was created with success + # this code uses virtual raster to compute the parameters of the output image + vrt = osgeo.gdal.AutoCreateWarpedVRT( + imgOut, + None, + outRasterSRS.ExportToWkt(), + osgeo.gdal.GRA_NearestNeighbour, + 0.0, + ) + imgWGS = outDriver.CreateCopy(outFile, vrt, options=createOptions) + + # Checking if the output file was created with success if os.path.exists(outFile): - QgsMessageLog.logMessage(self.messenger.getSuccessfullFileCreation() + outFile, "DSGTools Plugin", QgsMessageLog.INFO) + QgsMessageLog.logMessage( + self.messenger.getSuccessfullFileCreation() + outFile, + "DSGTools Plugin", + QgsMessageLog.INFO, + ) # Updating progress self.signals.stepProcessed.emit(self.getId()) - #Deleting the objects + # Deleting the objects imgWGS = None imgOut = None imgIn = None - #Unlinking the temp file + # Unlinking the temp file osgeo.gdal.Unlink(outFileTmp) return 1 diff --git a/DsgTools/core/Factories/ThreadFactory/genericThread.py b/DsgTools/core/Factories/ThreadFactory/genericThread.py index 4bf0fb241..faabeb8b8 100644 --- a/DsgTools/core/Factories/ThreadFactory/genericThread.py +++ b/DsgTools/core/Factories/ThreadFactory/genericThread.py @@ -25,12 +25,14 @@ from uuid import uuid4 + class ProcessSignals(QObject): rangeCalculated = pyqtSignal(int, str) stepProcessed = pyqtSignal(str) processingFinished = pyqtSignal(int, str, str) loadFile = pyqtSignal(str, bool) + class GenericThread(QRunnable): def __init__(self): """ @@ -39,7 +41,7 @@ def __init__(self): super(GenericThread, self).__init__() self.id = str(uuid4()) - + self.signals = ProcessSignals() def run(self): diff --git a/DsgTools/core/Factories/ThreadFactory/inventoryThread.py b/DsgTools/core/Factories/ThreadFactory/inventoryThread.py index aeab93910..8c82a4eb6 100644 --- a/DsgTools/core/Factories/ThreadFactory/inventoryThread.py +++ b/DsgTools/core/Factories/ThreadFactory/inventoryThread.py @@ -31,13 +31,24 @@ from qgis.PyQt.QtCore import pyqtSlot # Import the PyQt and QGIS libraries -from qgis.core import QgsMessageLog, QgsVectorFileWriter, QgsVectorLayer, \ - QgsCoordinateReferenceSystem, QgsCoordinateTransform, \ - QgsGeometry, QgsField, QgsPointXY, QgsProcessingMultiStepFeedback,\ - QgsFeature, QgsProject, QgsFields +from qgis.core import ( + QgsMessageLog, + QgsVectorFileWriter, + QgsVectorLayer, + QgsCoordinateReferenceSystem, + QgsCoordinateTransform, + QgsGeometry, + QgsField, + QgsPointXY, + QgsProcessingMultiStepFeedback, + QgsFeature, + QgsProject, + QgsFields, +) from .genericThread import GenericThread + class InventoryMessages(QObject): def __init__(self, thread): """ @@ -47,40 +58,41 @@ def __init__(self, thread): super(InventoryMessages, self).__init__() self.thread = thread - + def getInventoryErrorMessage(self): """ Returns generic error message """ - return self.tr('An error occurred while searching for files.') - + return self.tr("An error occurred while searching for files.") + def getCopyErrorMessage(self): """ Returns copy error message """ - return self.tr('An error occurred while copying the files.') - + return self.tr("An error occurred while copying the files.") + def getSuccessInventoryMessage(self): """ Returns success message """ - return self.tr('Inventory successfully created!') - + return self.tr("Inventory successfully created!") + def getSuccessInventoryAndCopyMessage(self): """ Returns successful copy message """ - return self.tr('Inventory and copy performed successfully!') + return self.tr("Inventory and copy performed successfully!") def getUserCanceledFeedbackMessage(self): """ Returns user canceled message """ - return self.tr('User canceled inventory processing!') - + return self.tr("User canceled inventory processing!") + @pyqtSlot() def progressCanceled(self): - self.thread.stopped[0] = True + self.thread.stopped[0] = True + class InventoryThread(GenericThread): def __init__(self): @@ -94,17 +106,26 @@ def __init__(self): gdal.DontUseExceptions() ogr.DontUseExceptions() self.layer_attributes = [ - QgsField('filename', QVariant.String), - QgsField('date', QVariant.String), - QgsField('size', QVariant.String), - QgsField('extension', QVariant.String) - ] + QgsField("filename", QVariant.String), + QgsField("date", QVariant.String), + QgsField("size", QVariant.String), + QgsField("extension", QVariant.String), + ] self.qgsattr = QgsFields() for i in self.layer_attributes: self.qgsattr.append(i) - - - def setParameters(self, parentFolder, outputFile, makeCopy, destinationFolder, formatsList, isWhitelist, isOnlyGeo, stopped): + + def setParameters( + self, + parentFolder, + outputFile, + makeCopy, + destinationFolder, + formatsList, + isWhitelist, + isOnlyGeo, + stopped, + ): self.parentFolder = parentFolder self.outputFile = outputFile self.makeCopy = makeCopy @@ -113,48 +134,62 @@ def setParameters(self, parentFolder, outputFile, makeCopy, destinationFolder, f self.stopped = stopped self.isWhitelist = isWhitelist self.isOnlyGeo = isOnlyGeo - + def run(self): """ Runs the thread """ # Actual process - (ret, msg) = self.makeInventory(self.parentFolder, self.outputFile, self.destinationFolder) - + (ret, msg) = self.makeInventory( + self.parentFolder, self.outputFile, self.destinationFolder + ) + if ret == 1: self.signals.loadFile.emit(self.outputFile, self.isOnlyGeo) - + self.signals.processingFinished.emit(ret, msg, self.getId()) - + def get_format_set(self, format_list): - if 'shp' in format_list: - return set(format_list + ['prj']) + if "shp" in format_list: + return set(format_list + ["prj"]) else: return set(format_list) - - def make_inventory_from_processing(self, parent_folder, format_list, destination_folder=None, make_copy=False, onlyGeo=True, feedback=None): + + def make_inventory_from_processing( + self, + parent_folder, + format_list, + destination_folder=None, + make_copy=False, + onlyGeo=True, + feedback=None, + ): featList = [] fileList = [] format_set = self.get_format_set(format_list) tuple_list = [i for i in os.walk(parent_folder)] nSteps = len(tuple_list) if make_copy else len(tuple_list) - 1 - multiStepFeedback = QgsProcessingMultiStepFeedback(nSteps, feedback) if feedback else None + multiStepFeedback = ( + QgsProcessingMultiStepFeedback(nSteps, feedback) if feedback else None + ) for current_step, [root, dirs, files] in enumerate(tuple_list): if feedback is not None: if feedback.isCanceled(): return [] multiStepFeedback.setCurrentStep(current_step) n_files = len(files) - files_progress = 100/n_files if n_files else 0 + files_progress = 100 / n_files if n_files else 0 for current, current_file in enumerate(files): if multiStepFeedback is not None and multiStepFeedback.isCanceled(): break - extension = current_file.split('.')[-1] + extension = current_file.split(".")[-1] if extension not in format_set: continue full_path = self.get_full_path(current_file, root) if gdal.Open(full_path) or ogr.Open(full_path): - bbox_geom, attributes = self.computeBoxAndAttributes(None, full_path, extension, insertIntoMemory=False) + bbox_geom, attributes = self.computeBoxAndAttributes( + None, full_path, extension, insertIntoMemory=False + ) new_feat = self.get_new_feat(bbox_geom, attributes) featList.append(new_feat) fileList.append(full_path) @@ -171,26 +206,22 @@ def make_inventory_from_processing(self, parent_folder, format_list, destination self.copy_single_file(file_, destination_folder) if multiStepFeedback is not None: multiStepFeedback.pushInfo( - self.tr('File {file} copied to {destination}').format( - file=file_, - destination=destination_folder + self.tr("File {file} copied to {destination}").format( + file=file_, destination=destination_folder ) ) except Exception as e: if multiStepFeedback is not None: multiStepFeedback.pushInfo( - self.tr('Error copying file {file}: {exception}\n').format( - file=file_, - exception='\n'.join(e.args) + self.tr("Error copying file {file}: {exception}\n").format( + file=file_, exception="\n".join(e.args) ) ) return featList - - def get_full_path(self, file_name, root): - line = os.path.join(root,file_name) - line = line.encode(encoding='UTF-8') + line = os.path.join(root, file_name) + line = line.encode(encoding="UTF-8") return line def get_new_feat(self, geom, attributes): @@ -199,22 +230,25 @@ def get_new_feat(self, geom, attributes): new_feat.setGeometry(geom) return new_feat - def makeInventory(self, parentFolder, outputFile, destinationFolder): """ Makes the inventory """ # creating a csv file try: - csvfile = open(outputFile, 'wb') + csvfile = open(outputFile, "wb") except IOError as e: - QgsMessageLog.logMessage(self.messenger.getInventoryErrorMessage()+'\n'+e.strerror, "DSGTools Plugin", QgsMessageLog.INFO) - return (0, self.messenger.getInventoryErrorMessage()+'\n'+e.strerror) + QgsMessageLog.logMessage( + self.messenger.getInventoryErrorMessage() + "\n" + e.strerror, + "DSGTools Plugin", + QgsMessageLog.INFO, + ) + return (0, self.messenger.getInventoryErrorMessage() + "\n" + e.strerror) try: outwriter = csv.writer(csvfile) # defining the first row - outwriter.writerow(['fileName', 'date', 'size (KB)', 'extension']) + outwriter.writerow(["fileName", "date", "size (KB)", "extension"]) # creating the memory layer used in only geo mode layer = self.createMemoryLayer() # iterating over the parent folder recursively @@ -224,24 +258,24 @@ def makeInventory(self, parentFolder, outputFile, destinationFolder): for file in files: # check if the user stopped the operation if not self.stopped[0]: - extension = file.split('.')[-1] + extension = file.split(".")[-1] # check if the file should be skipped if not self.inventoryFile(extension): continue # making the full path - line = os.path.join(root,file) - line = line.encode(encoding='UTF-8') + line = os.path.join(root, file) + line = line.encode(encoding="UTF-8") # changing the separator, it will be changed later - line = line.replace(os.sep, '/') + line = line.replace(os.sep, "/") # forcing the inventory of .prj files - if extension == 'prj': + if extension == "prj": self.writeLine(outwriter, line, extension) else: # check if GDAL/OGR recognizes the file gdalSrc = gdal.Open(line) ogrSrc = ogr.Open(line) if gdalSrc or ogrSrc: - #if only geo mode + # if only geo mode if self.isOnlyGeo: self.computeBoxAndAttributes(layer, line, extension) else: @@ -249,35 +283,57 @@ def makeInventory(self, parentFolder, outputFile, destinationFolder): self.files.append(line) gdalSrc = None ogrSrc = None - + self.signals.stepProcessed.emit(self.getId()) else: - QgsMessageLog.logMessage(self.messenger.getUserCanceledFeedbackMessage(), "DSGTools Plugin", QgsMessageLog.INFO) + QgsMessageLog.logMessage( + self.messenger.getUserCanceledFeedbackMessage(), + "DSGTools Plugin", + QgsMessageLog.INFO, + ) return (-1, self.messenger.getUserCanceledFeedbackMessage()) except csv.Error as e: csvfile.close() - QgsMessageLog.logMessage(self.messenger.getInventoryErrorMessage()+'\n'+e, "DSGTools Plugin", QgsMessageLog.INFO) - return (0, self.messenger.getInventoryErrorMessage()+'\n'+e) + QgsMessageLog.logMessage( + self.messenger.getInventoryErrorMessage() + "\n" + e, + "DSGTools Plugin", + QgsMessageLog.INFO, + ) + return (0, self.messenger.getInventoryErrorMessage() + "\n" + e) except OSError as e: csvfile.close() - QgsMessageLog.logMessage(self.messenger.getInventoryErrorMessage()+'\n'+e.strerror, "DSGTools Plugin", QgsMessageLog.INFO) - return (0, self.messenger.getInventoryErrorMessage()+'\n'+e.strerror) + QgsMessageLog.logMessage( + self.messenger.getInventoryErrorMessage() + "\n" + e.strerror, + "DSGTools Plugin", + QgsMessageLog.INFO, + ) + return (0, self.messenger.getInventoryErrorMessage() + "\n" + e.strerror) except Exception as e: csvfile.close() - QgsMessageLog.logMessage(self.messenger.getInventoryErrorMessage()+'\n'+':'.join(e.args), "DSGTools Plugin", QgsMessageLog.INFO) + QgsMessageLog.logMessage( + self.messenger.getInventoryErrorMessage() + "\n" + ":".join(e.args), + "DSGTools Plugin", + QgsMessageLog.INFO, + ) return (0, self.messenger.getInventoryErrorMessage()) csvfile.close() - + if self.isOnlyGeo: - error = QgsVectorFileWriter.writeAsVectorFormat(layer, self.outputFile, "utf-8", None, "ESRI Shapefile") - + error = QgsVectorFileWriter.writeAsVectorFormat( + layer, self.outputFile, "utf-8", None, "ESRI Shapefile" + ) + if self.makeCopy: # return self.copyFiles(destinationFolder) return self.copy(destinationFolder) else: - QgsMessageLog.logMessage(self.messenger.getSuccessInventoryMessage(), "DSGTools Plugin", QgsMessageLog.INFO) + QgsMessageLog.logMessage( + self.messenger.getSuccessInventoryMessage(), + "DSGTools Plugin", + QgsMessageLog.INFO, + ) return (1, self.messenger.getSuccessInventoryMessage()) - + def computeBoxAndAttributes(self, layer, line, extension, insertIntoMemory=True): """ Computes bounding box and inventory attributes @@ -297,7 +353,7 @@ def computeBoxAndAttributes(self, layer, line, extension, insertIntoMemory=True) if not insertIntoMemory: return qgsPolygon, attributes self.insertIntoMemoryLayer(layer, qgsPolygon, attributes) - + def copyFiles(self, destinationFolder): """ Copy inventoried files to the destination folder @@ -305,22 +361,34 @@ def copyFiles(self, destinationFolder): for fileName in self.files: if not self.stopped[0]: # adjusting the separators according to the OS - fileName = fileName.replace('/', os.sep) + fileName = fileName.replace("/", os.sep) file = fileName.split(os.sep)[-1] newFileName = os.path.join(destinationFolder, file) - newFileName = newFileName.replace('/', os.sep) + newFileName = newFileName.replace("/", os.sep) # making tha actual copy try: shutil.copy2(fileName, newFileName) except IOError as e: - QgsMessageLog.logMessage(self.messenger.getCopyErrorMessage()+'\n'+e.strerror, "DSGTools Plugin", QgsMessageLog.INFO) - return (0, self.messenger.getCopyErrorMessage()+'\n'+e.strerror) + QgsMessageLog.logMessage( + self.messenger.getCopyErrorMessage() + "\n" + e.strerror, + "DSGTools Plugin", + QgsMessageLog.INFO, + ) + return (0, self.messenger.getCopyErrorMessage() + "\n" + e.strerror) else: - QgsMessageLog.logMessage(self.messenger.getUserCanceledFeedbackMessage(), "DSGTools Plugin", QgsMessageLog.INFO) + QgsMessageLog.logMessage( + self.messenger.getUserCanceledFeedbackMessage(), + "DSGTools Plugin", + QgsMessageLog.INFO, + ) return (-1, self.messenger.getUserCanceledFeedbackMessage()) - QgsMessageLog.logMessage(self.messenger.getSuccessInventoryAndCopyMessage(), "DSGTools Plugin", QgsMessageLog.INFO) + QgsMessageLog.logMessage( + self.messenger.getSuccessInventoryAndCopyMessage(), + "DSGTools Plugin", + QgsMessageLog.INFO, + ) return (1, self.messenger.getSuccessInventoryAndCopyMessage()) def copy(self, destinationFolder): @@ -330,10 +398,10 @@ def copy(self, destinationFolder): """ for fileName in self.files: # adjusting the separators according to the OS - fileName = fileName.replace('/', os.sep) + fileName = fileName.replace("/", os.sep) file = fileName.split(os.sep)[-1] newFileName = os.path.join(destinationFolder, file) - newFileName = newFileName.replace('/', os.sep) + newFileName = newFileName.replace("/", os.sep) try: gdalSrc = gdal.Open(fileName) @@ -343,17 +411,28 @@ def copy(self, destinationFolder): elif gdalSrc: self.copyGDALDataSource(gdalSrc, newFileName) except Exception as e: - QgsMessageLog.logMessage(self.messenger.getCopyErrorMessage()+'\n'+':'.join(e.args), "DSGTools Plugin", QgsMessageLog.INFO) - return (0, self.messenger.getCopyErrorMessage()+'\n'+':'.join(e.args)) - - QgsMessageLog.logMessage(self.messenger.getSuccessInventoryAndCopyMessage(), "DSGTools Plugin", QgsMessageLog.INFO) + QgsMessageLog.logMessage( + self.messenger.getCopyErrorMessage() + "\n" + ":".join(e.args), + "DSGTools Plugin", + QgsMessageLog.INFO, + ) + return ( + 0, + self.messenger.getCopyErrorMessage() + "\n" + ":".join(e.args), + ) + + QgsMessageLog.logMessage( + self.messenger.getSuccessInventoryAndCopyMessage(), + "DSGTools Plugin", + QgsMessageLog.INFO, + ) return (1, self.messenger.getSuccessInventoryAndCopyMessage()) - + def copy_single_file(self, file_name, destination_folder): - file_name = file_name.replace('/', os.sep) + file_name = file_name.replace("/", os.sep) file_ = file_name.split(os.sep)[-1] newFileName = os.path.join(destination_folder, file_) - newFileName = newFileName.replace('/', os.sep) + newFileName = newFileName.replace("/", os.sep) gdalSrc = gdal.Open(fileName) ogrSrc = ogr.Open(fileName) if ogrSrc: @@ -371,7 +450,7 @@ def copyGDALDataSource(self, gdalSrc, newFileName): dst_ds = driver.CreateCopy(newFileName, gdalSrc) ogrSrc = None dst_ds = None - + def copyOGRDataSource(self, ogrSrc, newFileName): """ Copies a OGR datasource @@ -389,9 +468,9 @@ def isInFormatsList(self, ext): ext: file extension """ if ext in self.formatsList: - return True + return True return False - + def inventoryFile(self, ext): """ Check is the extension should be analyzed @@ -401,7 +480,7 @@ def inventoryFile(self, ext): return self.isInFormatsList(ext) else: return not self.isInFormatsList(ext) - + def writeLine(self, outwriter, line, extension): """ Write CSV line @@ -411,7 +490,7 @@ def writeLine(self, outwriter, line, extension): """ row = self.makeAttributes(line, extension) outwriter.writerow(row) - + def makeAttributes(self, line, extension): """ Make the attributes array @@ -419,29 +498,29 @@ def makeAttributes(self, line, extension): extension: file extension """ creationDate = time.ctime(os.path.getctime(line)) - size = os.path.getsize(line)/1000. - + size = os.path.getsize(line) / 1000.0 + return [str(line), creationDate, size, extension] - + def getRasterExtent(self, gt, cols, rows): - """ + """ Return list of corner coordinates from a geotransform @param gt: geotransform @param cols: number of columns in the dataset @param rows: number of rows in the dataset @return: coordinates of each corner """ - ext=[] - xarr=[0,cols] - yarr=[0,rows] - + ext = [] + xarr = [0, cols] + yarr = [0, rows] + for px in xarr: for py in yarr: - x=gt[0]+(px*gt[1])+(py*gt[2]) - y=gt[3]+(px*gt[4])+(py*gt[5]) - ext.append([x,y]) + x = gt[0] + (px * gt[1]) + (py * gt[2]) + y = gt[3] + (px * gt[4]) + (py * gt[5]) + ext.append([x, y]) yarr.reverse() - return ext + return ext def getExtent(self, filename): """ @@ -457,7 +536,7 @@ def getExtent(self, filename): layer = ogrSrc.GetLayer(id) extent = layer.GetExtent() spatialRef = layer.GetSpatialRef() - + # Create a Polygon from the extent tuple ring = ogr.Geometry(ogr.wkbLinearRing) ring.AddPoint(extent[0], extent[2]) @@ -467,9 +546,9 @@ def getExtent(self, filename): ring.AddPoint(extent[0], extent[2]) box = ogr.Geometry(ogr.wkbPolygon) box.AddGeometry(ring) - + poly = poly.Union(box) - + ogrSrc = None if not spatialRef: return (None, None) @@ -483,30 +562,30 @@ def getExtent(self, filename): ring = ogr.Geometry(ogr.wkbLinearRing) for pt in ext: - ring.AddPoint(pt[0],pt[1]) + ring.AddPoint(pt[0], pt[1]) ring.AddPoint(ext[0][0], ext[0][1]) box = ogr.Geometry(ogr.wkbPolygon) box.AddGeometry(ring) - + prjWkt = gdalSrc.GetProjectionRef() gdalSrc = None return (box, prjWkt) else: return (None, None) - + def createMemoryLayer(self): """ Creates a memory layer """ - layer = QgsVectorLayer('Polygon?crs=4326', 'Inventory', 'memory') + layer = QgsVectorLayer("Polygon?crs=4326", "Inventory", "memory") if not layer.isValid(): return None provider = layer.dataProvider() provider.addAttributes(self.layer_attributes) layer.updateFields() return layer - + def reprojectBoundingBox(self, crsSrc, ogrPoly): """ Reprojects the bounding box @@ -514,8 +593,10 @@ def reprojectBoundingBox(self, crsSrc, ogrPoly): ogrPoly: ogr polygon """ crsDest = QgsCoordinateReferenceSystem(4326) - coordinateTransformer = QgsCoordinateTransform(crsSrc, crsDest, QgsProject.instance()) - + coordinateTransformer = QgsCoordinateTransform( + crsSrc, crsDest, QgsProject.instance() + ) + newPolyline = [] ring = ogrPoly.GetGeometryRef(0) for i in range(ring.GetPointCount()): @@ -525,7 +606,7 @@ def reprojectBoundingBox(self, crsSrc, ogrPoly): qgsPolygon = QgsGeometry.fromPolygonXY([newPolyline]) qgsPolygon.transform(coordinateTransformer) return qgsPolygon - + def insertIntoMemoryLayer(self, layer, poly, attributes): """ Inserts the poly into memory layer @@ -535,7 +616,7 @@ def insertIntoMemoryLayer(self, layer, poly, attributes): """ provider = layer.dataProvider() - #Creating the feature + # Creating the feature feature = QgsFeature() feature.setGeometry(poly) feature.setAttributes(attributes) diff --git a/DsgTools/core/Factories/ThreadFactory/postgisDbThread.py b/DsgTools/core/Factories/ThreadFactory/postgisDbThread.py index 20bf098c1..44bab6c93 100644 --- a/DsgTools/core/Factories/ThreadFactory/postgisDbThread.py +++ b/DsgTools/core/Factories/ThreadFactory/postgisDbThread.py @@ -34,11 +34,12 @@ from ..DbFactory.dbFactory import DbFactory from DsgTools.core.dsgEnums import DsgEnums + class PostgisDbMessages(QObject): def __init__(self, thread): """ PostGIS database creation messages constructor - :param thread: + :param thread: """ super(PostgisDbMessages, self).__init__() @@ -48,19 +49,28 @@ def getProblemMessage(self, command, query): """ Returns database structure creation error message """ - return self.tr("Problem on database structure creation: ")+'SQL: '+command+'\n'+query.lastError().text()+'\n' + return ( + self.tr("Problem on database structure creation: ") + + "SQL: " + + command + + "\n" + + query.lastError().text() + + "\n" + ) def getProblemFeedbackMessage(self): """ Returns database creation error message """ - return self.tr('Problem creating the database structure!\n Check the Log terminal for details.') + return self.tr( + "Problem creating the database structure!\n Check the Log terminal for details." + ) def getUserCanceledFeedbackMessage(self): """ Returns user canceled error message """ - return self.tr('User canceled the database structure creation!') + return self.tr("User canceled the database structure creation!") def getSuccessFeedbackMessage(self): """ @@ -72,15 +82,16 @@ def getSuccessFeedbackMessage(self): def progressCanceled(self): self.thread.stopped[0] = True + class PostgisDbThread(GenericThread): - def __init__(self, parent = None): + def __init__(self, parent=None): """ Constructor. """ super(PostgisDbThread, self).__init__() self.factory = SqlGeneratorFactory() - #setting the sql generator + # setting the sql generator self.gen = self.factory.createSqlGenerator(driver=DsgEnums.DriverPostGIS) self.messenger = PostgisDbMessages(self) self.dbFactory = DbFactory() @@ -90,9 +101,9 @@ def setParameters(self, abstractDb, dbName, version, epsg, stopped): """ Sets thread parameters """ - self.abstractDb = abstractDb #database = postgis + self.abstractDb = abstractDb # database = postgis self.dbName = dbName - self.db = None + self.db = None self.version = version self.epsg = epsg self.stopped = stopped @@ -105,7 +116,7 @@ def run(self): (ret, msg) = self.createDatabaseStructure() self.signals.processingFinished.emit(ret, msg, self.getId()) - def connectToTemplate(self, setInnerDb = True): + def connectToTemplate(self, setInnerDb=True): """ Connects to the template database to speed up database creation :return: @@ -127,15 +138,15 @@ def createDatabaseStructure(self): Creates database structure according to the selected edgv version """ currentPath = os.path.dirname(__file__) - currentPath = os.path.join(currentPath, '..', '..', 'DbTools', 'PostGISTool') - if self.version == '2.1.3': - edgvPath = os.path.join(currentPath, 'sqls', '213', 'edgv213.sql') - elif self.version == '2.1.3 Pro': - edgvPath = os.path.join(currentPath, 'sqls', '213_Pro', 'edgv213_pro.sql') - elif self.version == '3.0': - edgvPath = os.path.join(currentPath, 'sqls', '3', 'edgv3.sql') + currentPath = os.path.join(currentPath, "..", "..", "DbTools", "PostGISTool") + if self.version == "2.1.3": + edgvPath = os.path.join(currentPath, "sqls", "213", "edgv213.sql") + elif self.version == "2.1.3 Pro": + edgvPath = os.path.join(currentPath, "sqls", "213_Pro", "edgv213_pro.sql") + elif self.version == "3.0": + edgvPath = os.path.join(currentPath, "sqls", "3", "edgv3.sql") else: - edgvPath = '' + edgvPath = "" return self.loadDatabaseStructure(edgvPath) def loadDatabaseStructure(self, edgvPath): @@ -146,22 +157,22 @@ def loadDatabaseStructure(self, edgvPath): commands = [] hasTemplate = self.abstractDb.checkTemplate(self.version) if hasTemplate: - templateDb = self.connectToTemplate(setInnerDb = False) + templateDb = self.connectToTemplate(setInnerDb=False) mustUpdateTemplate = templateDb.checkTemplateImplementationVersion() if mustUpdateTemplate: templateName = templateDb.db.databaseName() templateDb.__del__() - self.abstractDb.dropDatabase(templateName, dropTemplate = True) + self.abstractDb.dropDatabase(templateName, dropTemplate=True) hasTemplate = False if not hasTemplate: - file = codecs.open(edgvPath, encoding='utf-8', mode="r") + file = codecs.open(edgvPath, encoding="utf-8", mode="r") sql = file.read() - sql = sql.replace('[epsg]', '4674') + sql = sql.replace("[epsg]", "4674") file.close() - commands = [i for i in sql.split('#') if i != ''] + commands = [i for i in sql.split("#") if i != ""] # Progress bar steps calculated - self.signals.rangeCalculated.emit(len(commands)+4, self.getId()) - + self.signals.rangeCalculated.emit(len(commands) + 4, self.getId()) + if not hasTemplate: try: self.abstractDb.createTemplateDatabase(self.version) @@ -169,68 +180,117 @@ def loadDatabaseStructure(self, edgvPath): self.connectToTemplate() self.signals.stepProcessed.emit(self.getId()) except Exception as e: - return (0, self.messenger.getProblemFeedbackMessage()+'\n'+':'.join(e.args)) + return ( + 0, + self.messenger.getProblemFeedbackMessage() + + "\n" + + ":".join(e.args), + ) self.db.open() self.db.transaction() query = QSqlQuery(self.db) - + for command in commands: if not self.stopped[0]: if not query.exec_(command): - QgsMessageLog.logMessage(self.messenger.getProblemMessage(command, query), "DSGTools Plugin", Qgis.Critical) + QgsMessageLog.logMessage( + self.messenger.getProblemMessage(command, query), + "DSGTools Plugin", + Qgis.Critical, + ) self.db.rollback() self.db.close() self.dropDatabase(self.db) return (0, self.messenger.getProblemFeedbackMessage()) - + # Updating progress self.signals.stepProcessed.emit(self.getId()) else: self.db.rollback() self.db.close() - self.dropDatabase(self.db) - QgsMessageLog.logMessage(self.messenger.getUserCanceledFeedbackMessage(), "DSGTools Plugin", Qgis.Info) + self.dropDatabase(self.db) + QgsMessageLog.logMessage( + self.messenger.getUserCanceledFeedbackMessage(), + "DSGTools Plugin", + Qgis.Info, + ) return (-1, self.messenger.getUserCanceledFeedbackMessage()) - + self.db.commit() - if self.version == '2.1.3': - sql = 'ALTER DATABASE %s SET search_path = "$user", public, topology,\'cb\',\'complexos\',\'dominios\';' % self.db.databaseName() - elif self.version == '2.1.3 Pro': - sql = 'ALTER DATABASE %s SET search_path = "$user", public, topology,\'edgv\',\'dominios\';' % self.db.databaseName() - elif self.version == 'FTer_2a_Ed': - sql = 'ALTER DATABASE %s SET search_path = "$user", public, topology,\'pe\',\'ge\',\'complexos\',\'dominios\';' % self.db.databaseName() - elif self.version == '3.0': - sql = 'ALTER DATABASE %s SET search_path = "$user", public, topology,\'edgv\',\'complexos\',\'dominios\';' % self.db.databaseName() - + if self.version == "2.1.3": + sql = ( + "ALTER DATABASE %s SET search_path = \"$user\", public, topology,'cb','complexos','dominios';" + % self.db.databaseName() + ) + elif self.version == "2.1.3 Pro": + sql = ( + "ALTER DATABASE %s SET search_path = \"$user\", public, topology,'edgv','dominios';" + % self.db.databaseName() + ) + elif self.version == "FTer_2a_Ed": + sql = ( + "ALTER DATABASE %s SET search_path = \"$user\", public, topology,'pe','ge','complexos','dominios';" + % self.db.databaseName() + ) + elif self.version == "3.0": + sql = ( + "ALTER DATABASE %s SET search_path = \"$user\", public, topology,'edgv','complexos','dominios';" + % self.db.databaseName() + ) + if sql: if not query.exec_(sql): - QgsMessageLog.logMessage(self.messenger.getProblemMessage(command, query), "DSGTools Plugin", Qgis.Critical) + QgsMessageLog.logMessage( + self.messenger.getProblemMessage(command, query), + "DSGTools Plugin", + Qgis.Critical, + ) return (0, self.messenger.getProblemFeedbackMessage()) - #this commit was missing, so alter database statement was not commited. + # this commit was missing, so alter database statement was not commited. self.db.commit() self.db.close() self.abstractDb.setDbAsTemplate(self.version) - #creates from template + # creates from template if not self.stopped[0]: templateName = self.abstractDb.getTemplateName(self.version) - self.abstractDb.createDbFromTemplate(self.dbName, templateName, parentWidget = self.parent) + self.abstractDb.createDbFromTemplate( + self.dbName, templateName, parentWidget=self.parent + ) self.signals.stepProcessed.emit(self.getId()) - #5. alter spatial structure + # 5. alter spatial structure createdDb = self.dbFactory.createDbFactory(DsgEnums.DriverPostGIS) - createdDb.connectDatabaseWithParameters(self.abstractDb.db.hostName(), self.abstractDb.db.port(), self.dbName, self.abstractDb.db.userName(), self.abstractDb.db.password()) - errorTuple = createdDb.updateDbSRID(self.epsg, parentWidget = self.parent, threading = True) + createdDb.connectDatabaseWithParameters( + self.abstractDb.db.hostName(), + self.abstractDb.db.port(), + self.dbName, + self.abstractDb.db.userName(), + self.abstractDb.db.password(), + ) + errorTuple = createdDb.updateDbSRID( + self.epsg, parentWidget=self.parent, threading=True + ) # if an error occur during the thread we should pass the message to the main thread if errorTuple: - QgsMessageLog.logMessage(self.messenger.getProblemMessage(errorTuple[0], errorTuple[1]), "DSGTools Plugin", Qgis.Critical) - return (0, self.messenger.getProblemFeedbackMessage()) + QgsMessageLog.logMessage( + self.messenger.getProblemMessage(errorTuple[0], errorTuple[1]), + "DSGTools Plugin", + Qgis.Critical, + ) + return (0, self.messenger.getProblemFeedbackMessage()) self.signals.stepProcessed.emit(self.getId()) else: - QgsMessageLog.logMessage(self.messenger.getUserCanceledFeedbackMessage(), "DSGTools Plugin", Qgis.Info) + QgsMessageLog.logMessage( + self.messenger.getUserCanceledFeedbackMessage(), + "DSGTools Plugin", + Qgis.Info, + ) return (-1, self.messenger.getUserCanceledFeedbackMessage()) - QgsMessageLog.logMessage(self.messenger.getSuccessFeedbackMessage(), "DSGTools Plugin", Qgis.Info) + QgsMessageLog.logMessage( + self.messenger.getSuccessFeedbackMessage(), "DSGTools Plugin", Qgis.Info + ) return (1, self.messenger.getSuccessFeedbackMessage()) - def dropDatabase(self,db): + def dropDatabase(self, db): """ Drops the created database case a problem occurs during database creation db: QSqlDatabase to be dropped @@ -239,8 +299,8 @@ def dropDatabase(self,db): port = db.port() user = db.userName() password = db.password() - database = 'postgres' - pgDB = QSqlDatabase('QPSQL') + database = "postgres" + pgDB = QSqlDatabase("QPSQL") pgDB.setHostName(host) pgDB.setPort(port) pgDB.setUserName(user) @@ -250,4 +310,4 @@ def dropDatabase(self,db): return False sql = self.gen.dropDatabase(db.databaseName()) query = QSqlQuery(pgDB) - return query.exec_(sql) \ No newline at end of file + return query.exec_(sql) diff --git a/DsgTools/core/Factories/ThreadFactory/threadFactory.py b/DsgTools/core/Factories/ThreadFactory/threadFactory.py index 8119983d0..d662fa8d1 100644 --- a/DsgTools/core/Factories/ThreadFactory/threadFactory.py +++ b/DsgTools/core/Factories/ThreadFactory/threadFactory.py @@ -25,6 +25,7 @@ from .dpiThread import DpiThread from .inventoryThread import InventoryThread + class ThreadFactory(object): def makeProcess(self, name): """ @@ -32,11 +33,11 @@ def makeProcess(self, name): :param name: :return: """ - if name == 'pgdb': + if name == "pgdb": return PostgisDbThread() - elif name == 'dpi': + elif name == "dpi": return DpiThread() - elif name == 'inventory': + elif name == "inventory": return InventoryThread() else: return None diff --git a/DsgTools/core/GeometricTools/attributeHandler.py b/DsgTools/core/GeometricTools/attributeHandler.py index 21ee1f3b0..a742dfe2b 100644 --- a/DsgTools/core/GeometricTools/attributeHandler.py +++ b/DsgTools/core/GeometricTools/attributeHandler.py @@ -22,25 +22,38 @@ """ from __future__ import absolute_import from builtins import range -from qgis.core import QgsMessageLog, QgsVectorLayer, QgsGeometry, QgsField, \ - QgsVectorDataProvider, QgsFeatureRequest, QgsExpression, \ - QgsFeature, QgsSpatialIndex, Qgis, QgsCoordinateTransform, \ - QgsWkbTypes +from qgis.core import ( + QgsMessageLog, + QgsVectorLayer, + QgsGeometry, + QgsField, + QgsVectorDataProvider, + QgsFeatureRequest, + QgsExpression, + QgsFeature, + QgsSpatialIndex, + Qgis, + QgsCoordinateTransform, + QgsWkbTypes, +) from qgis.PyQt.Qt import QObject + class AttributeHandler(QObject): - def __init__(self, iface, parent = None): + def __init__(self, iface, parent=None): super(AttributeHandler, self).__init__() self.parent = parent self.iface = iface - def setFeatureAttributes(self, newFeature, attributeDict, editBuffer=None, oldFeat=None): + def setFeatureAttributes( + self, newFeature, attributeDict, editBuffer=None, oldFeat=None + ): """ Changes attribute values according to the reclassification dict using the edit buffer newFeature: newly added editBuffer: layer edit buffer """ - #setting the attributes using the reclassification dictionary + # setting the attributes using the reclassification dictionary fields = newFeature.fields() for attribute in attributeDict: idx = fields.lookupField(attribute) @@ -49,22 +62,22 @@ def setFeatureAttributes(self, newFeature, attributeDict, editBuffer=None, oldFe continue reclass = attributeDict[attribute] if isinstance(reclass, dict): - value = reclass['value'] - if reclass['ignored']: #ignore clause + value = reclass["value"] + if reclass["ignored"]: # ignore clause if oldFeat: value = oldFeat[attribute] else: value = None else: value = reclass - if value == '': + if value == "": continue - #actual attribute change + # actual attribute change if editBuffer: - #this way we are working with the edit buffer + # this way we are working with the edit buffer editBuffer.changeAttributeValue(newFeature.id(), idx, value) else: - #this way are working with selected features and inserting a new one in the layer + # this way are working with selected features and inserting a new one in the layer newFeature.setAttribute(idx, value) # if not editBuffer: # # we should return when under the normal behavior @@ -72,7 +85,15 @@ def setFeatureAttributes(self, newFeature, attributeDict, editBuffer=None, oldFe def getTuppleAttribute(self, feature, unifiedLyr, bList=None): bList = [] if bList is None else bList - attributes = [field.name() for idx, field in enumerate(feature.fields()) if (field.type() != 6 and idx not in unifiedLyr.primaryKeyAttributes() and field.name() not in bList)] + attributes = [ + field.name() + for idx, field in enumerate(feature.fields()) + if ( + field.type() != 6 + and idx not in unifiedLyr.primaryKeyAttributes() + and field.name() not in bList + ) + ] attributes.sort() - attributeList = [u'{0}'.format(feature[attribute]) for attribute in attributes] - return ','.join(attributeList) + attributeList = ["{0}".format(feature[attribute]) for attribute in attributes] + return ",".join(attributeList) diff --git a/DsgTools/core/GeometricTools/featureHandler.py b/DsgTools/core/GeometricTools/featureHandler.py index a19515e55..786dba0a3 100644 --- a/DsgTools/core/GeometricTools/featureHandler.py +++ b/DsgTools/core/GeometricTools/featureHandler.py @@ -25,10 +25,24 @@ import itertools import sys import os -from qgis.core import QgsMessageLog, QgsVectorLayer, QgsGeometry, QgsField, QgsVectorDataProvider, \ - QgsFeatureRequest, QgsExpression, QgsFeature, QgsSpatialIndex, Qgis, \ - QgsCoordinateTransform, QgsWkbTypes, QgsProcessingMultiStepFeedback,\ - QgsVectorLayerUtils, QgsCoordinateReferenceSystem, QgsProject +from qgis.core import ( + QgsMessageLog, + QgsVectorLayer, + QgsGeometry, + QgsField, + QgsVectorDataProvider, + QgsFeatureRequest, + QgsExpression, + QgsFeature, + QgsSpatialIndex, + Qgis, + QgsCoordinateTransform, + QgsWkbTypes, + QgsProcessingMultiStepFeedback, + QgsVectorLayerUtils, + QgsCoordinateReferenceSystem, + QgsProject, +) from qgis.PyQt.Qt import QObject, QVariant from .geometryHandler import GeometryHandler @@ -49,19 +63,30 @@ def __init__(self, iface=None, parent=None): self.utmGrid = UtmGrid() self.stepsTotal = 0 - def reclassifyFeatures(self, featureList, destinationLayer, reclassificationDict, coordinateTransformer, parameterDict): + def reclassifyFeatures( + self, + featureList, + destinationLayer, + reclassificationDict, + coordinateTransformer, + parameterDict, + ): newFeatList = [] deleteList = [] for feat in featureList: geom = self.geometryHandler.reprojectWithCoordinateTransformer( - feat.geometry(), coordinateTransformer) + feat.geometry(), coordinateTransformer + ) geomList = self.geometryHandler.adjustGeometry(geom, parameterDict) newFeatList += self.createFeaturesWithAttributeDict( - geomList, feat, reclassificationDict, destinationLayer) + geomList, feat, reclassificationDict, destinationLayer + ) deleteList.append(feat.id()) return newFeatList, deleteList - def createFeaturesWithAttributeDict(self, geomList, originalFeat, attributeDict, destinationLayer): + def createFeaturesWithAttributeDict( + self, geomList, originalFeat, attributeDict, destinationLayer + ): """ Creates a newFeatureList using each geom from geomList. attributeDict is used to set attributes """ @@ -71,7 +96,8 @@ def createFeaturesWithAttributeDict(self, geomList, originalFeat, attributeDict, newFeature = QgsFeature(fields) newFeature.setGeometry(geom) newFeature = self.attributeHandler.setFeatureAttributes( - newFeature, attributeDict, oldFeat=originalFeat) + newFeature, attributeDict, oldFeat=originalFeat + ) newFeatureList.append(newFeature) return newFeatureList @@ -92,21 +118,36 @@ def createFeatureFromLayer(self, layer, attributes=None, geom=None, fields=None) newFeature.setGeometry(geom) if attributes: newFeature = self.attributeHandler.setFeatureAttributes( - newFeature, attributes) + newFeature, attributes + ) return newFeature - def createUnifiedFeature(self, unifiedLyr, feature, classname, bList=None, attributeTupple=False, coordinateTransformer=None, parameterDict=None): + def createUnifiedFeature( + self, + unifiedLyr, + feature, + classname, + bList=None, + attributeTupple=False, + coordinateTransformer=None, + parameterDict=None, + ): parameterDict = {} if parameterDict is None else parameterDict bList = [] if bList is None else bList newFeats = [] - for geom in self.geometryHandler.handleGeometry(feature.geometry(), parameterDict=parameterDict, coordinateTransformer=coordinateTransformer): + for geom in self.geometryHandler.handleGeometry( + feature.geometry(), + parameterDict=parameterDict, + coordinateTransformer=coordinateTransformer, + ): newfeat = QgsFeature(unifiedLyr.fields()) newfeat.setGeometry(feature.geometry()) - newfeat['featid'] = feature.id() - newfeat['layer'] = classname + newfeat["featid"] = feature.id() + newfeat["layer"] = classname if attributeTupple: - newfeat['tupple'] = self.attributeHandler.getTuppleAttribute( - feature, unifiedLyr, bList=bList) + newfeat["tupple"] = self.attributeHandler.getTuppleAttribute( + feature, unifiedLyr, bList=bList + ) newFeats.append(newfeat) return newFeats @@ -130,13 +171,17 @@ def newFeature(self, geom=None, fields=None, attributeMap=None): if geom: feat.setGeometry(geom) if attributeMap: - feat = self.attributeHandler.setFeatureAttributes( - feat, attributeMap) + feat = self.attributeHandler.setFeatureAttributes(feat, attributeMap) return feat - def handleFeature(self, featList, featureWithoutGeom, lyr, - parameterDict=None, - coordinateTransformer=None): + def handleFeature( + self, + featList, + featureWithoutGeom, + lyr, + parameterDict=None, + coordinateTransformer=None, + ): """ Handles a feature list to return geometries to update and a new feature list. @@ -153,7 +198,8 @@ def handleFeature(self, featList, featureWithoutGeom, lyr, geomList = [] for feat in featList: geomList += self.geometryHandler.handleGeometry( - feat.geometry(), parameterDict, coordinateTransformer) + feat.geometry(), parameterDict, coordinateTransformer + ) geomToUpdate = None newFeatList = [] if not geomList: @@ -163,16 +209,18 @@ def handleFeature(self, featList, featureWithoutGeom, lyr, geomToUpdate = geom continue else: - newFeat = self.getNewFeatureWithoutGeom( - featureWithoutGeom, lyr) + newFeat = self.getNewFeatureWithoutGeom(featureWithoutGeom, lyr) newFeat.setGeometry(geom) newFeatList.append(newFeat) return geomToUpdate, newFeatList, False - def handleConvertedFeature(self, feat, lyr, parameterDict=None, coordinateTransformer=None): + def handleConvertedFeature( + self, feat, lyr, parameterDict=None, coordinateTransformer=None + ): parameterDict = {} if parameterDict is None else parameterDict geomList = self.geometryHandler.handleGeometry( - feat.geometry(), parameterDict, coordinateTransformer) + feat.geometry(), parameterDict, coordinateTransformer + ) newFeatSet = set() for geom in geomList: newFeat = QgsVectorLayerUtils.createFeature(lyr, geom) @@ -190,7 +238,8 @@ def getFeatureOuterShellAndHoles(self, feat, isMulti): geom = feat.geometry() outershells, donutholes = self.geometryHandler.getOuterShellAndHoles( - geom, isMulti) + geom, isMulti + ) outershellList = [] for shell in outershells: outerShellFeat = QgsFeature(feat) @@ -204,7 +253,9 @@ def getFeatureOuterShellAndHoles(self, feat, isMulti): donutHoleList.append(newFeat) return outershellList, donutHoleList - def mergeLineFeatures(self, featList, lyr, idsToRemove, networkDict, parameterDict=None, feedback=None): + def mergeLineFeatures( + self, featList, lyr, idsToRemove, networkDict, parameterDict=None, feedback=None + ): parameterDict = {} if parameterDict is None else parameterDict changeDict = dict() size = 100 / len(featList) @@ -228,22 +279,25 @@ def mergeLineFeatures(self, featList, lyr, idsToRemove, networkDict, parameterDi intersectionPoint = geom_a.intersection(geom_b) for pointPart in intersectionPoint.asGeometryCollection(): point = pointPart.asPoint() - if (point in networkDict and len(networkDict[point]) == 2): - newGeom = self.geometryHandler.handleGeometry(geom_a.combine(geom_b).mergeLines( - ), parameterDict)[0] # only one candidate is possible because features are touching + if point in networkDict and len(networkDict[point]) == 2: + newGeom = self.geometryHandler.handleGeometry( + geom_a.combine(geom_b).mergeLines(), parameterDict + )[ + 0 + ] # only one candidate is possible because features are touching feat_a.setGeometry(newGeom) lyr.updateFeature(feat_a) idsToRemove.append(id_b) # changeDict[id_a] = newGeom if feedback: - feedback.setProgress(size*current) + feedback.setProgress(size * current) # for id, geom in changeDict.items(): # lyr.changeGeometry(id, geom) def getNewGridFeat(self, index, geom, fields): feat = QgsFeature(fields) - feat['inom'] = index - feat['mi'] = self.utmGrid.get_MI_MIR_from_inom(index) + feat["inom"] = index + feat["mi"] = self.utmGrid.get_MI_MIR_from_inom(index) feat.setGeometry(geom) return feat @@ -257,7 +311,7 @@ def getSystematicGridFeatures( xSubdivisions=3, ySubdivisions=3, constraintDict=None, - feedback=None + feedback=None, ): if feedback is not None and feedback.isCanceled(): return @@ -268,7 +322,7 @@ def getSystematicGridFeatures( coordinateTransformer, constraintDict, xSubdivisions=xSubdivisions, - ySubdivisions=ySubdivisions + ySubdivisions=ySubdivisions, ) if frameGeom is None: return @@ -278,7 +332,7 @@ def getSystematicGridFeatures( scaleId = self.utmGrid.getScaleIdFromiNomen(index) sufixIterator = list( itertools.chain.from_iterable( - self.utmGrid.scaleText[scaleId+1] + self.utmGrid.scaleText[scaleId + 1] ) # flatten list into one single list ) # localMultiStepFeedback = QgsProcessingMultiStepFeedback( @@ -289,17 +343,18 @@ def getSystematicGridFeatures( if feedback is not None and feedback.isCanceled(): break # localMultiStepFeedback.setCurrentStep(i) - inomen2 = '{oldInomem}-{newPart}'.format( - oldInomem=index, - newPart=line) - if constraintDict is not None \ - and self.createGridItem( - inomen2, - coordinateTransformer, - constraintDict, - xSubdivisions=xSubdivisions, - ySubdivisions=ySubdivisions - ) is None: + inomen2 = "{oldInomem}-{newPart}".format(oldInomem=index, newPart=line) + if ( + constraintDict is not None + and self.createGridItem( + inomen2, + coordinateTransformer, + constraintDict, + xSubdivisions=xSubdivisions, + ySubdivisions=ySubdivisions, + ) + is None + ): continue self.getSystematicGridFeatures( featureList, @@ -310,66 +365,69 @@ def getSystematicGridFeatures( xSubdivisions=xSubdivisions, ySubdivisions=ySubdivisions, constraintDict=constraintDict, - feedback=feedback + feedback=feedback, ) - def createGridItem(self, index, coordinateTransformer, constraintDict, xSubdivisions=3, ySubdivisions=3): - frameGeom = self.utmGrid.getQgsPolygonFrame(index, xSubdivisions=xSubdivisions, ySubdivisions=ySubdivisions) + def createGridItem( + self, + index, + coordinateTransformer, + constraintDict, + xSubdivisions=3, + ySubdivisions=3, + ): + frameGeom = self.utmGrid.getQgsPolygonFrame( + index, xSubdivisions=xSubdivisions, ySubdivisions=ySubdivisions + ) frameGeom.transform(coordinateTransformer) if constraintDict is None: return frameGeom frameBB = frameGeom.boundingBox() engine = QgsGeometry.createGeometryEngine(frameGeom.constGet()) engine.prepareGeometry() - for fid in constraintDict['spatialIdx'].intersects(frameBB): - if getattr(engine, constraintDict['predicate'])( - constraintDict['idDict'][fid].geometry().constGet() + for fid in constraintDict["spatialIdx"].intersects(frameBB): + if getattr(engine, constraintDict["predicate"])( + constraintDict["idDict"][fid].geometry().constGet() ): return frameGeom return None def getSystematicGridFeaturesWithConstraint( - self, - featureList, - inputLyr, - stopScale, - coordinateTransformer, - fields, - xSubdivisions=3, - ySubdivisions=3, - feedback=None, - predicate=None - ): + self, + featureList, + inputLyr, + stopScale, + coordinateTransformer, + fields, + xSubdivisions=3, + ySubdivisions=3, + feedback=None, + predicate=None, + ): """ TODO: Progress """ if feedback is not None and feedback.isCanceled(): return - predicate = 'intersects' if predicate is None else predicate + predicate = "intersects" if predicate is None else predicate multiStepFeedback = QgsProcessingMultiStepFeedback(2, feedback) multiStepFeedback.setCurrentStep(0) - multiStepFeedback.pushInfo(self.tr('Creating spatial index')) + multiStepFeedback.pushInfo(self.tr("Creating spatial index")) spatialIdx, idDict = self.buildSpatialIndexAndIdDict( - inputLyr, - feedback=multiStepFeedback - ) - multiStepFeedback.pushInfo(self.tr('Getting candidate start indexes')) - xmin, ymin, xmax, ymax = self.getLyrUnprojectedGeographicBounds( - inputLyr - ) - inomenList = self.utmGrid.get_INOM_range_from_BB( - xmin, ymin, xmax, ymax + inputLyr, feedback=multiStepFeedback ) + multiStepFeedback.pushInfo(self.tr("Getting candidate start indexes")) + xmin, ymin, xmax, ymax = self.getLyrUnprojectedGeographicBounds(inputLyr) + inomenList = self.utmGrid.get_INOM_range_from_BB(xmin, ymin, xmax, ymax) multiStepFeedback.setCurrentStep(1) - multiStepFeedback.pushInfo(self.tr('Building grid')) + multiStepFeedback.pushInfo(self.tr("Building grid")) gridMultistepFeedback = QgsProcessingMultiStepFeedback( - len(inomenList), - multiStepFeedback + len(inomenList), multiStepFeedback ) constraintDict = { - 'spatialIdx': spatialIdx, - 'idDict': idDict, - 'predicate': predicate + "spatialIdx": spatialIdx, + "idDict": idDict, + "predicate": predicate, } sys.setrecursionlimit(10**7) @@ -383,8 +441,9 @@ def compute(x): xSubdivisions=xSubdivisions, ySubdivisions=ySubdivisions, constraintDict=constraintDict, - feedback=gridMultistepFeedback + feedback=gridMultistepFeedback, ) + pool = concurrent.futures.ThreadPoolExecutor(os.cpu_count()) futures = [] current_idx = 0 @@ -392,9 +451,7 @@ def compute(x): # gridMultistepFeedback.setCurrentStep(i) if gridMultistepFeedback.isCanceled(): break - futures.append( - pool.submit(compute, inomen) - ) + futures.append(pool.submit(compute, inomen)) for x in concurrent.futures.as_completed(futures): if gridMultistepFeedback.isCanceled(): @@ -402,8 +459,7 @@ def compute(x): gridMultistepFeedback.setCurrentStep(current_idx) current_idx += 1 - def buildSpatialIndexAndIdDict(self, inputLyr, feedback=None, - featureRequest=None): + def buildSpatialIndexAndIdDict(self, inputLyr, feedback=None, featureRequest=None): """ creates a spatial index for the input layer :param inputLyr: (QgsVectorLayer) input layer; @@ -413,23 +469,29 @@ def buildSpatialIndexAndIdDict(self, inputLyr, feedback=None, spatialIdx = QgsSpatialIndex() idDict = {} featCount = inputLyr.featureCount() - size = 100/featCount if featCount else 0 - iterator = inputLyr.getFeatures() if featureRequest is None\ + size = 100 / featCount if featCount else 0 + iterator = ( + inputLyr.getFeatures() + if featureRequest is None else inputLyr.getFeatures(featureRequest) - - def addFeatureAlias(x): return self.addFeatureToSpatialIndex( - current=x[0], - feat=x[1], - spatialIdx=spatialIdx, - idDict=idDict, - size=size, - feedback=feedback ) + + def addFeatureAlias(x): + return self.addFeatureToSpatialIndex( + current=x[0], + feat=x[1], + spatialIdx=spatialIdx, + idDict=idDict, + size=size, + feedback=feedback, + ) + list(map(addFeatureAlias, enumerate(iterator))) return spatialIdx, idDict - def addFeatureToSpatialIndex(self, current, feat, spatialIdx, - idDict, size, feedback): + def addFeatureToSpatialIndex( + self, current, feat, spatialIdx, idDict, size, feedback + ): """ Adds feature to spatial index. Used along side with a python map operator to improve performance. @@ -454,7 +516,7 @@ def getLyrUnprojectedGeographicBounds(self, inputLyr): coordinateTransformer = QgsCoordinateTransform( crs, QgsCoordinateReferenceSystem(crs.geographicCrsAuthId()), - QgsProject.instance() + QgsProject.instance(), ) reprojectedGeographicBB = coordinateTransformer.transformBoundingBox( inputLyr.extent() diff --git a/DsgTools/core/GeometricTools/geometryHandler.py b/DsgTools/core/GeometricTools/geometryHandler.py index b3fd64980..8799e24ab 100644 --- a/DsgTools/core/GeometricTools/geometryHandler.py +++ b/DsgTools/core/GeometricTools/geometryHandler.py @@ -27,9 +27,17 @@ from functools import partial from itertools import combinations -from qgis.core import (Qgis, QgsCoordinateReferenceSystem, - QgsCoordinateTransform, QgsGeometry, QgsPoint, - QgsPointXY, QgsProject, QgsVectorLayer, QgsWkbTypes) +from qgis.core import ( + Qgis, + QgsCoordinateReferenceSystem, + QgsCoordinateTransform, + QgsGeometry, + QgsPoint, + QgsPointXY, + QgsProject, + QgsVectorLayer, + QgsWkbTypes, +) from qgis.PyQt.Qt import QObject @@ -40,58 +48,67 @@ def __init__(self, iface=None, parent=None): self.iface = iface if self.iface: self.canvas = iface.mapCanvas() - + def getClockWiseList(self, pointList): pointSum = 0 for i in range(len(pointList) - 1): - pointSum += (pointList[i+1].x() - pointList[i].x())*(pointList[i+1].y() + pointList[i].y()) + pointSum += (pointList[i + 1].x() - pointList[i].x()) * ( + pointList[i + 1].y() + pointList[i].y() + ) if pointSum > 0: return pointList else: return pointList[::-1] - + def reprojectWithCoordinateTransformer(self, geom, coordinateTransformer): if coordinateTransformer: geom.transform(coordinateTransformer) return geom - + def adjustGeometry(self, geom, parameterDict): geomList = [] if geom is not None: - if 'geometry' in dir(geom): - if not parameterDict['hasMValues']: + if "geometry" in dir(geom): + if not parameterDict["hasMValues"]: geom.geometry().dropMValue() - if not parameterDict['hasZValues']: + if not parameterDict["hasZValues"]: geom.geometry().dropZValue() if geom.isMultipart(): parts = geom.asGeometryCollection() for part in parts: - if parameterDict['isMulti']: + if parameterDict["isMulti"]: part.convertToMultiType() geomList.append(part) else: - if parameterDict['isMulti']: + if parameterDict["isMulti"]: geom.convertToMultiType() geomList.append(geom) return geomList - - def reprojectFeature(self, geom, referenceCrs, destinationCrs=None, coordinateTransformer=None, debugging=False): + + def reprojectFeature( + self, geom, referenceCrs, destinationCrs=None, coordinateTransformer=None + ): """ Reprojects geom from the canvas crs to the reference crs. :param geom: geometry to be reprojected - :param referenceCrs: reference CRS (coordinate reference system). + :param referenceCrs: reference CRS (coordinate reference system). :param canvasCrs: canvas CRS. If not given, it'll be evaluated on runtime execution. :param coordinateTransformer: the coordinate transformer for canvas to reference CRS - :param debbuging: if True, method returns the the list [geometry, canvasCrs, referenceCrs, coordinateTransformer] """ if not destinationCrs: destinationCrs = QgsProject.instance().crs() - if destinationCrs.authid() != referenceCrs.authid(): - if not coordinateTransformer: - coordinateTransformer = QgsCoordinateTransform(destinationCrs, referenceCrs, QgsProject.instance()) - geom.transform(coordinateTransformer) - if debugging: - return [geom, canvasCrs, referenceCrs, coordinateTransformer] + if destinationCrs.authid() == referenceCrs.authid(): + return + coordinateTransformer = ( + QgsCoordinateTransform( + QgsCoordinateReferenceSystem(destinationCrs), + QgsCoordinateReferenceSystem(referenceCrs), + QgsProject.instance(), + ) + if not coordinateTransformer + else coordinateTransformer + ) + geom.transform(coordinateTransformer) def reprojectSearchArea(self, layer, geom): """ @@ -100,16 +117,18 @@ def reprojectSearchArea(self, layer, geom): :param geom: (QgsRectangle) rectangle representing search area. :return: (QgsRectangle) rectangle representing reprojected search area. """ - #geom always have canvas coordinates + # geom always have canvas coordinates epsg = self.canvas.mapSettings().destinationCrs().authid() - #getting srid from something like 'EPSG:31983' + # getting srid from something like 'EPSG:31983' srid = layer.crs().authid() if epsg == srid: return geom crsSrc = QgsCoordinateReferenceSystem(epsg) crsDest = QgsCoordinateReferenceSystem(srid) # Creating a transformer - coordinateTransformer = QgsCoordinateTransform(crsSrc, crsDest, QgsProject.instance()) # here we have to put authid, not srid + coordinateTransformer = QgsCoordinateTransform( + crsSrc, crsDest, QgsProject.instance() + ) # here we have to put authid, not srid auxGeom = QgsGeometry.fromRect(geom) auxGeom.transform(coordinateTransformer) return auxGeom.boundingBox() @@ -128,7 +147,7 @@ def flipFeature(self, layer, feature, geomType=None, refreshCanvas=False): geomType = layer.geometryType() # getting whether geometry is multipart or not # features not yet commited to layer always have SINGLE geometry - isMulti = QgsWkbTypes.isMultiType(int(layer.wkbType())) and feature.id() > 0 + isMulti = QgsWkbTypes.isMultiType(layer.wkbType()) and feature.id() > 0 geom = feature.geometry() if geomType == 0: if isMulti: @@ -137,12 +156,12 @@ def flipFeature(self, layer, feature, geomType=None, refreshCanvas=False): for idx, part in enumerate(nodes): nodes[idx] = part[::-1] # setting flipped geometry - flippedFeatureGeom = QgsGeometry.fromMultiPointXY(nodes) + flippedFeatureGeom = QgsGeometry.fromMultiPointXY(nodes) else: # inverting the point list nodes = geom.asPoint() nodes = nodes[::-1] - flippedFeatureGeom = QgsGeometry.fromPoint(nodes) + flippedFeatureGeom = QgsGeometry.fromPoint(nodes) elif geomType == 1: if isMulti: nodes = geom.asMultiPolyline() @@ -155,10 +174,10 @@ def flipFeature(self, layer, feature, geomType=None, refreshCanvas=False): flippedFeatureGeom = QgsGeometry.fromPolylineXY(nodes) elif geomType == 2: if isMulti: - nodes = geom.asMultiPolygon() + nodes = geom.asMultiPolygon() for idx, part in enumerate(nodes): nodes[idx] = part[::-1] - flippedFeatureGeom = QgsGeometry.fromMultiPolygonXY(nodes) + flippedFeatureGeom = QgsGeometry.fromMultiPolygonXY(nodes) else: nodes = geom.asPolygon() nodes = nodes[::-1] @@ -170,14 +189,14 @@ def flipFeature(self, layer, feature, geomType=None, refreshCanvas=False): if refreshCanvas: self.iface.mapCanvas().refresh() return [layer, feature, geomType] - + # MISSING REPROJECTION def flipFeatureList(self, featureList, debugging=False, refreshCanvas=True): """ Inverts the flow from all features of a given list. ALL GIVEN FEATURES ARE ALTERED. :param featureList: list of features to be flipped ([layer, feature[, geometry_type]). :param debugging: optional parameter to indicate whether or not a list of features that failed - to be reversed should be returner. + to be reversed should be returner. :returns: list of flipped features. """ reversedFeatureList = [] @@ -215,57 +234,105 @@ def isclose(self, a, b, rel_tol=None, abs_tol=None): rel_tol = 1e-09 if rel_tol is None else rel_tol abs_tol = 0.0 if abs_tol is None else abs_tol return abs(a - b) <= max(rel_tol * max(abs(a), abs(b)), abs_tol) - - def getOutOfBoundsAngleInPolygon(self, feat, part, angle, outOfBoundsList, exactAngleMatch=False, angTol=None, invalidRange=None): + + def getOutOfBoundsAngleInPolygon( + self, + feat, + part, + angle, + outOfBoundsList, + exactAngleMatch=False, + angTol=None, + invalidRange=None, + ): angTol = 0.1 if angTol is None else angTol if invalidRange is not None: minAngle, maxAngle = invalidRange for linearRing in part.asPolygon(): linearRing = self.getClockWiseList(linearRing) - nVertex = len(linearRing)-1 + nVertex = len(linearRing) - 1 + def clause(x): - return x < angle if not exactAngleMatch \ + return ( + x < angle + if not exactAngleMatch else not self.isclose(x, angle, abs_tol=angTol) + ) + clauseLambda = partial(clause) for i in range(nVertex): if i == 0: - vertexAngle = (linearRing[i].azimuth(linearRing[-2]) - linearRing[i].azimuth(linearRing[i+1]) + 360) + vertexAngle = ( + linearRing[i].azimuth(linearRing[-2]) + - linearRing[i].azimuth(linearRing[i + 1]) + + 360 + ) else: - vertexAngle = (linearRing[i].azimuth(linearRing[i-1]) - linearRing[i].azimuth(linearRing[i+1]) + 360) + vertexAngle = ( + linearRing[i].azimuth(linearRing[i - 1]) + - linearRing[i].azimuth(linearRing[i + 1]) + + 360 + ) vertexAngle = math.fmod(vertexAngle, 360) if vertexAngle > 180: # if angle calculated is the outter one vertexAngle = 360 - vertexAngle - if invalidRange is not None and (vertexAngle >= minAngle and vertexAngle <= maxAngle): - geomDict = {'angle':vertexAngle, 'feat_id':feat.id(), 'geom':QgsGeometry.fromPointXY(linearRing[i])} + if invalidRange is not None and ( + vertexAngle >= minAngle and vertexAngle <= maxAngle + ): + geomDict = { + "angle": vertexAngle, + "feat_id": feat.id(), + "geom": QgsGeometry.fromPointXY(linearRing[i]), + } outOfBoundsList.append(geomDict) continue if clauseLambda(vertexAngle): - geomDict = {'angle':vertexAngle, 'feat_id':feat.id(), 'geom':QgsGeometry.fromPointXY(linearRing[i])} + geomDict = { + "angle": vertexAngle, + "feat_id": feat.id(), + "geom": QgsGeometry.fromPointXY(linearRing[i]), + } outOfBoundsList.append(geomDict) - - def getOutOfBoundsAngleInLine(self, feat, part, angle, outOfBoundsList, invalidRange=None): + + def getOutOfBoundsAngleInLine( + self, feat, part, angle, outOfBoundsList, invalidRange=None + ): if invalidRange is not None: minAngle, maxAngle = invalidRange line = part.asPolyline() - nVertex = len(line)-1 - for i in range(1,nVertex): - vertexAngle = (line[i].azimuth(line[i-1]) - line[i].azimuth(line[i+1]) + 360) + nVertex = len(line) - 1 + for i in range(1, nVertex): + vertexAngle = ( + line[i].azimuth(line[i - 1]) - line[i].azimuth(line[i + 1]) + 360 + ) vertexAngle = math.fmod(vertexAngle, 360) if vertexAngle > 180: vertexAngle = 360 - vertexAngle - if invalidRange is not None and (vertexAngle >= minAngle and vertexAngle <= maxAngle): - geomDict = {'angle':vertexAngle, 'feat_id':feat.id(), 'geom':QgsGeometry.fromPointXY(line[i])} + if invalidRange is not None and ( + vertexAngle >= minAngle and vertexAngle <= maxAngle + ): + geomDict = { + "angle": vertexAngle, + "feat_id": feat.id(), + "geom": QgsGeometry.fromPointXY(line[i]), + } outOfBoundsList.append(geomDict) continue if vertexAngle < angle: - geomDict = {'angle':vertexAngle, 'feat_id':feat.id(), 'geom':QgsGeometry.fromPointXY(line[i])} + geomDict = { + "angle": vertexAngle, + "feat_id": feat.id(), + "geom": QgsGeometry.fromPointXY(line[i]), + } outOfBoundsList.append(geomDict) - + def getInvalidBuildingAngle(self, feat, angTol): return self.getOutOfBoundsAngle(feat, 90, exactAngleMatch=True, angTol=angTol) - - def getOutOfBoundsAngle(self, feat, angle, exactAngleMatch=False, angTol=0.1, invalidRange=None): + + def getOutOfBoundsAngle( + self, feat, angle, exactAngleMatch=False, angTol=0.1, invalidRange=None + ): outOfBoundsList = [] geom = feat.geometry() for part in geom.asGeometryCollection(): @@ -277,20 +344,17 @@ def getOutOfBoundsAngle(self, feat, angle, exactAngleMatch=False, angTol=0.1, in outOfBoundsList, exactAngleMatch=exactAngleMatch, angTol=angTol, - invalidRange=invalidRange + invalidRange=invalidRange, ) if part.type() == QgsWkbTypes.LineGeometry: - self.getOutOfBoundsAngleInLine(feat, - part, - angle, - outOfBoundsList, - invalidRange=invalidRange - ) + self.getOutOfBoundsAngleInLine( + feat, part, angle, outOfBoundsList, invalidRange=invalidRange + ) return outOfBoundsList def getAngleBetweenSegments(self, part): line = part.asPolyline() - vertexAngle = (line[1].azimuth(line[0]) - line[1].azimuth(line[2]) + 360) + vertexAngle = line[1].azimuth(line[0]) - line[1].azimuth(line[2]) + 360 vertexAngle = math.fmod(vertexAngle, 360) if vertexAngle > 180: vertexAngle = 360 - vertexAngle @@ -310,10 +374,16 @@ def getSegmentDict(self, lineLyr): segmentDict = dict() geomList = [] if lineLyr.featureCount() > 0: - toLineAlias = lambda geom : geom.asMultiPolyline()[0] if next(lineLyr.getFeatures()).geometry().isMultipart() \ - else geom.asPolyline() - fromLineAlias = lambda x : QgsGeometry.fromMultiPolylineXY([x]) if next(lineLyr.getFeatures()).geometry().isMultipart() \ - else QgsGeometry.fromPolyline(x[0], x[1]) + toLineAlias = ( + lambda geom: geom.asMultiPolyline()[0] + if next(lineLyr.getFeatures()).geometry().isMultipart() + else geom.asPolyline() + ) + fromLineAlias = ( + lambda x: QgsGeometry.fromMultiPolylineXY([x]) + if next(lineLyr.getFeatures()).geometry().isMultipart() + else QgsGeometry.fromPolyline(x[0], x[1]) + ) for feat in lineLyr.getFeatures(): geom = feat.geometry() if geom not in geomList: @@ -321,18 +391,24 @@ def getSegmentDict(self, lineLyr): lineList = toLineAlias(geom) if lineList[0] not in segmentDict: segmentDict[lineList[0]] = [] - segmentDict[lineList[0]].append(fromLineAlias([lineList[0], lineList[1]])) + segmentDict[lineList[0]].append( + fromLineAlias([lineList[0], lineList[1]]) + ) if lineList[-1] not in segmentDict: segmentDict[lineList[-1]] = [] - segmentDict[lineList[-1]].append(fromLineAlias([lineList[-1], lineList[-2]])) + segmentDict[lineList[-1]].append( + fromLineAlias([lineList[-1], lineList[-2]]) + ) return segmentDict - - def handleGeometry(self, geom, parameterDict = {}, coordinateTransformer = None): + + def handleGeometry(self, geom, parameterDict={}, coordinateTransformer=None): outputList = [] for geom in self.adjustGeometry(geom, parameterDict): - outputList += [self.reprojectWithCoordinateTransformer(geom, coordinateTransformer)] + outputList += [ + self.reprojectWithCoordinateTransformer(geom, coordinateTransformer) + ] return outputList - + def getOuterShellAndHoles(self, geom, isMulti): outershells, donutholes = [], [] for part in geom.asGeometryCollection(): @@ -345,11 +421,11 @@ def getOuterShellAndHoles(self, geom, isMulti): else: donutholes.append(newGeom) return outershells, donutholes - + def getStartAndEndPointOnLine(self, geom): lineList = geom.asMultiPolyline() if geom.isMultipart() else [geom.asPolyline()] return lineList[0], lineList[len(lineList) - 1] - + def deaggregateGeometry(self, multiGeom): """ Deaggregates a multi-part geometry into a its parts and returns all found parts. If no part is found, @@ -364,7 +440,7 @@ def deaggregateGeometry(self, multiGeom): parts = multiGeom.asGeometryCollection() for part in parts: if part: - # asGeometryCollection() reads every part as single-part type geometry + # asGeometryCollection() reads every part as single-part type geometry part.convertToMultiType() geomList.append(part) return geomList @@ -381,28 +457,28 @@ def getFeatureNodes(self, layer, feature, geomType=None): if not geomType: geomType = layer.geometryType() # getting whether geometry is multipart or not - isMulti = QgsWkbTypes.isMultiType(int(layer.wkbType())) + isMulti = QgsWkbTypes.isMultiType(layer.wkbType()) geom = feature.geometry() return self.getGeomNodes(geom, geomType, isMulti) - + def getGeomNodes(self, geom, geomType, isMulti): if geomType == 0: if isMulti: - nodes = geom.asMultiPoint() + nodes = geom.asMultiPoint() else: - nodes = geom.asPoint() + nodes = geom.asPoint() elif geomType == 1: if isMulti: nodes = geom.asMultiPolyline() else: - nodes = geom.asPolyline() + nodes = geom.asPolyline() elif geomType == 2: if isMulti: - nodes = geom.asMultiPolygon() + nodes = geom.asMultiPolygon() else: nodes = geom.asPolygon() return nodes - + def getFirstNode(self, lyr, feat, geomType=None): """ Returns the starting node of a line. @@ -412,7 +488,7 @@ def getFirstNode(self, lyr, feat, geomType=None): :return: starting node point (QgsPoint). """ n = self.getFeatureNodes(layer=lyr, feature=feat, geomType=geomType) - isMulti = QgsWkbTypes.isMultiType(int(lyr.wkbType())) + isMulti = QgsWkbTypes.isMultiType(lyr.wkbType()) if isMulti: if len(n) > 1: return @@ -429,7 +505,7 @@ def getSecondNode(self, lyr, feat, geomType=None): :return: starting node point (QgsPoint). """ n = self.getFeatureNodes(layer=lyr, feature=feat, geomType=geomType) - isMulti = QgsWkbTypes.isMultiType(int(lyr.wkbType())) + isMulti = QgsWkbTypes.isMultiType(lyr.wkbType()) if isMulti: if len(n) > 1: # process doesn't treat multipart features that does have more than 1 part @@ -447,7 +523,7 @@ def getPenultNode(self, lyr, feat, geomType=None): :return: ending node point (QgsPoint). """ n = self.getFeatureNodes(layer=lyr, feature=feat, geomType=geomType) - isMulti = QgsWkbTypes.isMultiType(int(lyr.wkbType())) + isMulti = QgsWkbTypes.isMultiType(lyr.wkbType()) if isMulti: if len(n) > 1: return @@ -464,7 +540,7 @@ def getLastNode(self, lyr, feat, geomType=None): :return: ending node point (QgsPoint). """ n = self.getFeatureNodes(layer=lyr, feature=feat, geomType=geomType) - isMulti = QgsWkbTypes.isMultiType(int(lyr.wkbType())) + isMulti = QgsWkbTypes.isMultiType(lyr.wkbType()) if isMulti: if len(n) > 1: return @@ -481,7 +557,7 @@ def getFirstAndLastNode(self, lyr, feat, geomType=None): :return: starting node point (QgsPoint). """ n = self.getFeatureNodes(layer=lyr, feature=feat, geomType=geomType) - isMulti = QgsWkbTypes.isMultiType(int(lyr.wkbType())) + isMulti = QgsWkbTypes.isMultiType(lyr.wkbType()) if isMulti: if len(n) > 1: return @@ -491,15 +567,17 @@ def getFirstAndLastNode(self, lyr, feat, geomType=None): def calculateAngleDifferences(self, startNode, endNode): """ - Calculates the angle in degrees formed between line direction ('startNode' -> 'endNode') and vertical passing over + Calculates the angle in degrees formed between line direction ('startNode' -> 'endNode') and vertical passing over starting node. :param startNode: node (QgsPoint) reference for line and angle calculation. :param endNode: ending node (QgsPoint) for (segment of) line of which angle is required. :return: (float) angle in degrees formed between line direction ('startNode' -> 'endNode') and vertical passing over 'startNode' """ # the returned angle is measured regarding 'y-axis', with + counter clockwise and -, clockwise. - # Then angle is ALWAYS 180 - ang - return 180 - math.degrees(math.atan2(endNode.x() - startNode.x(), endNode.y() - startNode.y())) + # Then angle is ALWAYS 180 - ang + return 180 - math.degrees( + math.atan2(endNode.x() - startNode.x(), endNode.y() - startNode.y()) + ) def calculateAzimuthFromNode(self, node, networkLayer, geomType=None): """ @@ -513,17 +591,19 @@ def calculateAzimuthFromNode(self, node, networkLayer, geomType=None): geomType = networkLayer.geometryType() nodePointDict = self.nodeDict[node] azimuthDict = dict() - for line in nodePointDict['start']: + for line in nodePointDict["start"]: # if line starts at node, then angle calculate is already azimuth endNode = self.getSecondNode(lyr=networkLayer, feat=line, geomType=geomType) azimuthDict[line] = node.azimuth(endNode) - for line in nodePointDict['end']: + for line in nodePointDict["end"]: # if line ends at node, angle must be adapted in order to get azimuth endNode = self.getPenultNode(lyr=networkLayer, feat=line, geomType=geomType) azimuthDict[line] = node.azimuth(endNode) return azimuthDict - def checkLineDirectionConcordance(self, line_a, line_b, networkLayer, geomType=None): + def checkLineDirectionConcordance( + self, line_a, line_b, networkLayer, geomType=None + ): """ Given two lines, this method checks whether lines flow to/from the same node or not. If they do not have a common node, method returns false. @@ -540,9 +620,11 @@ def checkLineDirectionConcordance(self, line_a, line_b, networkLayer, geomType=N fn_b = self.getFirstNode(lyr=networkLayer, feat=line_b, geomType=geomType) ln_b = self.getLastNode(lyr=networkLayer, feat=line_b, geomType=geomType) # if lines are flowing to/from the same node (they are flowing the same way) - return (fn_a == fn_b or ln_a == ln_b) + return fn_a == fn_b or ln_a == ln_b - def validateDeltaLinesAngV2(self, node, networkLayer, connectedValidLines, geomType=None): + def validateDeltaLinesAngV2( + self, node, networkLayer, connectedValidLines, geomType=None + ): """ Validates a set of lines connected to a node as for the angle formed between them. :param node: (QgsPoint) hidrography node to be validated. @@ -555,7 +637,9 @@ def validateDeltaLinesAngV2(self, node, networkLayer, connectedValidLines, geomT val, inval, reason = dict(), dict(), "" if not geomType: geomType = networkLayer.geometryType() - azimuthDict = self.calculateAzimuthFromNode(node=node, networkLayer=networkLayer, geomType=None) + azimuthDict = self.calculateAzimuthFromNode( + node=node, networkLayer=networkLayer, geomType=None + ) lines = azimuthDict.keys() for idx1, key1 in enumerate(lines): if idx1 == len(lines): @@ -565,14 +649,23 @@ def validateDeltaLinesAngV2(self, node, networkLayer, connectedValidLines, geomT if idx1 >= idx2: # in order to calculate only f1 - f2, f1 - f3, f2 - f3 (for 3 features, for instance) continue - absAzimuthDifference = math.fmod((azimuthDict[key1] - azimuthDict[key2] + 360), 360) + absAzimuthDifference = math.fmod( + (azimuthDict[key1] - azimuthDict[key2] + 360), 360 + ) if absAzimuthDifference > 180: # the lesser angle should always be the one to be analyzed - absAzimuthDifference = (360 - absAzimuthDifference) + absAzimuthDifference = 360 - absAzimuthDifference if absAzimuthDifference < 90: # if it's a 'beak', lines cannot have opposing directions (e.g. cannot flow to/from the same node) - if not self.checkLineDirectionConcordance(line_a=key1, line_b=key2, networkLayer=networkLayer, geomType=geomType): - reason = self.tr('Lines id={0} and id={1} have conflicting directions ({2:.2f} deg).').format(key1.id(), key2.id(), absAzimuthDifference) + if not self.checkLineDirectionConcordance( + line_a=key1, + line_b=key2, + networkLayer=networkLayer, + geomType=geomType, + ): + reason = self.tr( + "Lines id={0} and id={1} have conflicting directions ({2:.2f} deg)." + ).format(key1.id(), key2.id(), absAzimuthDifference) # checks if any of connected lines are already validated by any previous iteration if key1 not in connectedValidLines: inval[key1.id()] = key1 @@ -584,24 +677,26 @@ def validateDeltaLinesAngV2(self, node, networkLayer, connectedValidLines, geomT continue else: # if lines touch each other at a right angle, then it is impossible to infer waterway direction - reason = self.tr('Cannot infer directions for lines {0} and {1} (Right Angle)').format(key1.id(), key2.id()) + reason = self.tr( + "Cannot infer directions for lines {0} and {1} (Right Angle)" + ).format(key1.id(), key2.id()) if key1 not in connectedValidLines: - inval[key1.id()] = key1 + inval[key1.id()] = key1 if key2 not in connectedValidLines: inval[key2.id()] = key2 return val, inval, reason if not inval: - val = {k.id() : k for k in lines} + val = {k.id(): k for k in lines} return val, inval, reason - - def identifyAllNodes(self, networkLayer, onlySelected = False): + + def identifyAllNodes(self, networkLayer, onlySelected=False): """ Identifies all nodes from a given layer (or selected features of it). The result is returned as a dict of dict. :param networkLayer: target layer to which nodes identification is required. :return: { node_id : { start : [feature_which_starts_with_node], end : feature_which_ends_with_node } }. """ nodeDict = dict() - isMulti = QgsWkbTypes.isMultiType(int(networkLayer.wkbType())) + isMulti = QgsWkbTypes.isMultiType(networkLayer.wkbType()) if onlySelected: features = [feat for feat in networkLayer.getSelectedFeatures()] else: @@ -612,60 +707,60 @@ def identifyAllNodes(self, networkLayer, onlySelected = False): if isMulti: if len(nodes) > 1: # if feat is multipart and has more than one part, a flag should be raised - continue # CHANGE TO RAISE FLAG + continue # CHANGE TO RAISE FLAG elif len(nodes) == 0: # if no part is found, skip feature continue else: # if feat is multipart, "nodes" is a list of list - nodes = nodes[0] + nodes = nodes[0] # initial node pInit, pEnd = nodes[0], nodes[-1] # filling starting node information into dictionary if pInit not in nodeDict: # if the point is not already started into dictionary, it creates a new item - nodeDict[pInit] = { 'start' : [], 'end' : [] } - if feat not in nodeDict[pInit]['start']: - nodeDict[pInit]['start'].append(feat) + nodeDict[pInit] = {"start": [], "end": []} + if feat not in nodeDict[pInit]["start"]: + nodeDict[pInit]["start"].append(feat) # filling ending node information into dictionary if pEnd not in nodeDict: - nodeDict[pEnd] = { 'start' : [], 'end' : [] } - if feat not in nodeDict[pEnd]['end']: - nodeDict[pEnd]['end'].append(feat) + nodeDict[pEnd] = {"start": [], "end": []} + if feat not in nodeDict[pEnd]["end"]: + nodeDict[pEnd]["end"].append(feat) return nodeDict - + def makeQgsPolygonFromBounds(self, xmin, ymin, xmax, ymax, isMulti=True): """ Creating a polygon for the given coordinates """ - dx = (xmax - xmin)/3 - dy = (ymax - ymin)/3 - + dx = (xmax - xmin) / 3 + dy = (ymax - ymin) / 3 + polyline = [] point = QgsPointXY(xmin, ymin) polyline.append(point) - point = QgsPointXY(xmin+dx, ymin) + point = QgsPointXY(xmin + dx, ymin) polyline.append(point) - point = QgsPointXY(xmax-dx, ymin) + point = QgsPointXY(xmax - dx, ymin) polyline.append(point) point = QgsPointXY(xmax, ymin) polyline.append(point) - point = QgsPointXY(xmax, ymin+dy) + point = QgsPointXY(xmax, ymin + dy) polyline.append(point) - point = QgsPointXY(xmax, ymax-dy) + point = QgsPointXY(xmax, ymax - dy) polyline.append(point) point = QgsPointXY(xmax, ymax) polyline.append(point) - point = QgsPointXY(xmax-dx, ymax) + point = QgsPointXY(xmax - dx, ymax) polyline.append(point) - point = QgsPointXY(xmin+dx, ymax) + point = QgsPointXY(xmin + dx, ymax) polyline.append(point) point = QgsPointXY(xmin, ymax) polyline.append(point) - point = QgsPointXY(xmin, ymax-dy) + point = QgsPointXY(xmin, ymax - dy) polyline.append(point) - point = QgsPointXY(xmin, ymin+dy) + point = QgsPointXY(xmin, ymin + dy) polyline.append(point) point = QgsPointXY(xmin, ymin) polyline.append(point) @@ -675,17 +770,23 @@ def makeQgsPolygonFromBounds(self, xmin, ymin, xmax, ymax, isMulti=True): else: qgsPolygon = QgsGeometry.fromPolygonXY([polyline]) return qgsPolygon - - def handleGeometryCollection(self, geom, geometryType, parameterDict=None, coordinateTransformer=None): + + def handleGeometryCollection( + self, geom, geometryType, parameterDict=None, coordinateTransformer=None + ): parameterDict = {} if parameterDict is None else parameterDict outputSet = set() for part in geom.asGeometryCollection(): if part.type() == geometryType: - handledList = self.handleGeometry(part, parameterDict=parameterDict, coordinateTransformer=coordinateTransformer) + handledList = self.handleGeometry( + part, + parameterDict=parameterDict, + coordinateTransformer=coordinateTransformer, + ) for item in handledList: outputSet.add(item) return list(outputSet) - + def getFirstAndLastNodeFromGeom(self, geom): isMulti = geom.isMultipart() geomType = geom.type() @@ -704,7 +805,7 @@ def multiToSinglePart(self, geom): :return: (list-of-QgsGeometry) list of single part geometries found. """ return [part for part in geom.asGeometryCollection()] - + @staticmethod def calcAzimuth(p1: QgsPoint, p2: QgsPoint) -> float: dx = p2.x() - p1.x() @@ -716,15 +817,15 @@ def calcAzimuth(p1: QgsPoint, p2: QgsPoint) -> float: else: return 180.0 - theta = math.atan(dy/dx) + theta = math.atan(dy / dx) if dx < 0: theta += math.pi - + azimuth = 90.0 - math.degrees(theta) if azimuth < 0: azimuth += 360.0 return azimuth - + @staticmethod def addVertex(vertex: QgsPoint, geom: QgsGeometry) -> QgsGeometry: distance, p, after, orient = geom.closestSegmentWithContext(QgsPointXY(vertex)) @@ -733,7 +834,7 @@ def addVertex(vertex: QgsPoint, geom: QgsGeometry) -> QgsGeometry: def addVertexesToGeometry(self, vertexSet: set, geom: QgsGeometry) -> QgsGeometry: geomVertexSet = set(QgsGeometry(i) for i in geom.vertices()) - changedGeom = QgsGeometry(geom) # deep copy + changedGeom = QgsGeometry(geom) # deep copy for vertex in vertexSet: vertexPoint = QgsPoint(vertex.asPoint()) closestVertexes = geom.closestVertex(vertex.asPoint()) @@ -743,4 +844,3 @@ def addVertexesToGeometry(self, vertexSet: set, geom: QgsGeometry) -> QgsGeometr changedGeom = self.addVertex(vertexPoint, changedGeom) changedGeom.removeDuplicateNodes() return changedGeom - diff --git a/DsgTools/core/GeometricTools/graphHandler.py b/DsgTools/core/GeometricTools/graphHandler.py new file mode 100644 index 000000000..47612656d --- /dev/null +++ b/DsgTools/core/GeometricTools/graphHandler.py @@ -0,0 +1,166 @@ +# -*- coding: utf-8 -*- +""" +/*************************************************************************** + DsgTools + A QGIS plugin + Brazilian Army Cartographic Production Tools + ------------------- + begin : 2023-03-29 + git sha : $Format:%H$ + copyright : (C) 2023 by Philipe Borba - Cartographic Engineer @ Brazilian Army + email : borba.philipe@eb.mil.br + ***************************************************************************/ +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ +""" + +from collections import defaultdict +from itertools import tee +from typing import Iterable +from itertools import chain +from itertools import product +from itertools import starmap +from functools import partial + +from qgis.core import QgsGeometry, QgsFeature, QgsProcessingMultiStepFeedback + +def fetch_connected_nodes(G, node, max_degree, seen=None, feedback=None): + if seen == None: + seen = [node] + for neighbor in G.neighbors(node): + if feedback is not None and feedback.isCanceled(): + break + if G.degree(neighbor) > max_degree: + continue + if neighbor not in seen: + seen.append(neighbor) + fetch_connected_nodes(G, neighbor, max_degree, seen) + return seen + + +def pairwise(iterable: Iterable) -> Iterable: + "s -> (s0,s1), (s1,s2), (s2, s3), ..." + a, b = tee(iterable) + next(b, None) + return zip(a, b) + +def flipLine(edgeDict: dict, edgeId: int) -> QgsFeature: + edgeFeat = edgeDict[edgeId] + edgeGeomAsQgsLine = edgeFeat.geometry().constGet() + reversedGeom = QgsGeometry(edgeGeomAsQgsLine.reversed()) + newFeat = QgsFeature(edgeFeat) + newFeat.setGeometry(reversedGeom) + return newFeat + +def buildGraph(nx, hashDict, nodeDict, feedback=None, directed=False): + G = nx.Graph() if not directed else nx.DiGraph() + progressStep = 100 / len(hashDict) + for current, (edgeId, (wkb_1, wkb_2)) in enumerate(hashDict.items()): + if feedback is not None and feedback.isCanceled(): + break + G.add_edge(nodeDict[wkb_1], nodeDict[wkb_2]) + G[nodeDict[wkb_1]][nodeDict[wkb_2]]["featid"] = edgeId + if feedback is not None: + feedback.setProgress(current * progressStep) + return G + +def buildAuxStructures(nx, nodesLayer, edgesLayer, feedback=None, directed=False): + multiStepFeedback = QgsProcessingMultiStepFeedback(3, feedback) if feedback is not None else None + if multiStepFeedback is not None: + multiStepFeedback.setCurrentStep(0) + edgeDict = {feat["featid"]: feat for feat in edgesLayer.getFeatures()} + if multiStepFeedback is not None: + multiStepFeedback.setCurrentStep(1) + nodeDict = defaultdict(list) + nodeIdDict = defaultdict(list) + nodeCount = nodesLayer.featureCount() + stepSize = 100 / nodeCount + auxId = 0 + hashDict = defaultdict(lambda: [[], []]) + for current, nodeFeat in enumerate(nodesLayer.getFeatures()): + if multiStepFeedback is not None and multiStepFeedback.isCanceled(): + break + geom = nodeFeat.geometry() + geomWkb = geom.asWkb() + if geomWkb not in nodeDict: + nodeDict[geomWkb] = auxId + nodeIdDict[auxId] = geomWkb + auxId += 1 + hashDict[nodeFeat["featid"]][nodeFeat["vertex_pos"]] = geomWkb + if multiStepFeedback is not None: + multiStepFeedback.setProgress(current * stepSize) + + if multiStepFeedback is not None: + multiStepFeedback.setCurrentStep(2) + networkBidirectionalGraph = buildGraph( + nx, hashDict, nodeDict, feedback=multiStepFeedback, directed=directed + ) + return nodeDict, nodeIdDict, edgeDict, hashDict, networkBidirectionalGraph + +def evaluateStreamOrder(G, feedback=None): + G = G.copy() + firstOrderNodes = set(node for node in G.nodes if G.degree(node) == 1 and len(list(G.successors(node))) > 0) + stepSize = 100 / len(G.edges) + current = 0 + G_copy = G.copy() + visitedNodes = set() + for n0, n1 in G_copy.edges: + G_copy[n0][n1]["stream_order"] = 0 + while len(firstOrderNodes) > 0: + if feedback is not None and feedback.isCanceled(): + return G_copy + for node in firstOrderNodes: + if node in visitedNodes: + continue + connectedNodes = fetch_connected_nodes(G, node, 2) + pairs = [(a,b) for i in connectedNodes for a,b in G.out_edges(i)] + predOrderValueList = [G_copy[n0][node]["stream_order"] for n0 in G_copy.predecessors(node)] + startIdx = max(predOrderValueList) + 1 if len(predOrderValueList) > 0 else 1 + for idx, (n0, n1) in enumerate(pairs, start=startIdx): + current += 1 + if feedback is not None and feedback.isCanceled(): + return G_copy + G_copy[n0][n1]["stream_order"] = idx if G_copy.degree(n0) <= 2 else max( + [idx] + [G_copy[i][n0]["stream_order"] + 1 for i in G_copy.predecessors(n0)] + ) + G.remove_edge(n0, n1) + succList = list(G_copy.successors(n1)) + if len(succList) > 1: + for i in G_copy.successors(n1): + G_copy[n1][i]["stream_order"] = idx + 1 + G.remove_edge(n1, succList[0]) + if feedback is not None: + feedback.setProgress(current * stepSize) + for n in connectedNodes: + G.remove_node(n) + visitedNodes.add(n) + # visitedNodes.add(node) + firstOrderNodes = set(node for node in G.nodes if G.degree(node) == 1 and len(list(G.successors(node))) > 0) - visitedNodes + # firstOrderNodes = [node for node in G.nodes if G.degree(node) == 1 and node not in visitedNodes] + return G_copy + + +# def evaluateStreamOrder(nx, G, feedback=None): +# G = G.copy() +# firstOrderNodes = set(node for node in G.nodes if G.degree(node) == 1 and len(list(G.successors(node))) > 0) +# stepSize = 100 / len(G.edges) +# current = 0 +# G_copy = G.copy() +# visitedNodes = set() +# for n0, n1 in G_copy.edges: +# G_copy[n0][n1]["stream_order"] = 0 +# roots = (v for v, d in G.in_degree() if d == 0) +# leaves = (v for v, d in G.out_degree() if d == 0) +# all_paths = partial(nx.all_simple_paths, G) +# pathDict = defaultdict(list) +# for path in sorted(chain.from_iterable(starmap(all_paths, product(roots, leaves))), key=lambda x: len(x), reverse=True): +# pathDict[path[0]].append(path) + + + diff --git a/DsgTools/core/GeometricTools/layerHandler.py b/DsgTools/core/GeometricTools/layerHandler.py index 79be2d40d..99c3311f2 100644 --- a/DsgTools/core/GeometricTools/layerHandler.py +++ b/DsgTools/core/GeometricTools/layerHandler.py @@ -28,6 +28,7 @@ from itertools import combinations import os from typing import List +from uuid import uuid4 from processing.tools import dataobjects @@ -36,11 +37,30 @@ from DsgTools.core.DSGToolsProcessingAlgs.algRunner import AlgRunner from DsgTools.core.Utils.FrameTools.map_index import UtmGrid from qgis.analysis import QgsGeometrySnapper, QgsInternalGeometrySnapper -from qgis.core import (edit, Qgis, QgsCoordinateReferenceSystem, QgsCoordinateTransform, - QgsExpression, QgsFeature, QgsFeatureRequest, QgsField, QgsFields, QgsGeometry, QgsMessageLog, - QgsProcessingContext, QgsProcessingMultiStepFeedback, QgsProcessingUtils, QgsProject, - QgsSpatialIndex, QgsVectorDataProvider, QgsVectorLayer, QgsVectorLayerUtils, QgsWkbTypes, - QgsProcessingFeatureSourceDefinition, QgsFeatureSink) +from qgis.core import ( + edit, + Qgis, + QgsCoordinateReferenceSystem, + QgsCoordinateTransform, + QgsExpression, + QgsFeature, + QgsFeatureRequest, + QgsField, + QgsFields, + QgsGeometry, + QgsMessageLog, + QgsProcessingContext, + QgsProcessingMultiStepFeedback, + QgsProcessingUtils, + QgsProject, + QgsSpatialIndex, + QgsVectorDataProvider, + QgsVectorLayer, + QgsVectorLayerUtils, + QgsWkbTypes, + QgsProcessingFeatureSourceDefinition, + QgsFeatureSink, +) from qgis.PyQt.Qt import QObject, QVariant from .featureHandler import FeatureHandler @@ -58,7 +78,9 @@ def __init__(self, iface=None, parent=None): self.geometryHandler = GeometryHandler(iface) self.algRunner = AlgRunner() - def getFeatureList(self, lyr, onlySelected=False, returnIterator=True, returnSize=True): + def getFeatureList( + self, lyr, onlySelected=False, returnIterator=True, returnSize=True + ): """ Gets the features from lyr acording to parameters. :param (QgsVectorLayer) lyr: layer; @@ -67,12 +89,16 @@ def getFeatureList(self, lyr, onlySelected=False, returnIterator=True, returnSiz :param (bool) returnSize: if true, return the featureList and size. """ if onlySelected: - featureList = lyr.getSelectedFeatures() if returnIterator else [ - i for i in lyr.getSelectedFeatures()] + featureList = ( + lyr.getSelectedFeatures() + if returnIterator + else [i for i in lyr.getSelectedFeatures()] + ) size = lyr.selectedFeatureCount() else: - featureList = lyr.getFeatures() if returnIterator else [ - i for i in lyr.getFeatures()] + featureList = ( + lyr.getFeatures() if returnIterator else [i for i in lyr.getFeatures()] + ) size = lyr.featureCount() if returnSize: return featureList, size @@ -91,7 +117,8 @@ def getSelectedFeaturesFromCanvasLayers(self): if not isinstance(lyr, QgsVectorLayer): continue featureList = self.getFeatureList( - lyr, onlySelected=True, returnIterator=False) + lyr, onlySelected=True, returnIterator=False + ) if featureList: selectedDict[lyr] = featureList return selectedDict @@ -104,14 +131,21 @@ def reclassifySelectedFeatures(self, destinationLayer, reclassificationDict): parameterDict = self.getDestinationParameters(destinationLayer) reclassifyCount = 0 destinationLayer.startEditing() - destinationLayer.beginEditCommand(self.tr('DsgTools reclassification')) - for lyr, featureList in [(k, v) for k, v in selectedDict.items() if len(v[0]) > 0]: - featureList = featureList[0] if isinstance( - featureList, tuple) else featureList - coordinateTransformer = self.getCoordinateTransformer( - lyr, destinationLayer) + destinationLayer.beginEditCommand(self.tr("DsgTools reclassification")) + for lyr, featureList in [ + (k, v) for k, v in selectedDict.items() if len(v[0]) > 0 + ]: + featureList = ( + featureList[0] if isinstance(featureList, tuple) else featureList + ) + coordinateTransformer = self.getCoordinateTransformer(lyr, destinationLayer) newFeatList, deleteList = self.featureHandler.reclassifyFeatures( - featureList, lyr, reclassificationDict, coordinateTransformer, parameterDict) + featureList, + lyr, + reclassificationDict, + coordinateTransformer, + parameterDict, + ) featuresAdded = destinationLayer.addFeatures(newFeatList) if featuresAdded: lyr.startEditing() @@ -126,14 +160,11 @@ def getDestinationParameters(self, destinationLayer): if it is a multi-geometry (isMulti) """ parameterDict = dict() - parameterDict['geomType'] = destinationLayer.geometryType() + parameterDict["geomType"] = destinationLayer.geometryType() # generic check (not every database is implemented as ours) - parameterDict['hasMValues'] = QgsWkbTypes.hasM( - int(destinationLayer.wkbType())) - parameterDict['hasZValues'] = QgsWkbTypes.hasZ( - int(destinationLayer.wkbType())) # - parameterDict['isMulti'] = QgsWkbTypes.isMultiType( - int(destinationLayer.wkbType())) + parameterDict["hasMValues"] = QgsWkbTypes.hasM(destinationLayer.wkbType()) + parameterDict["hasZValues"] = QgsWkbTypes.hasZ(destinationLayer.wkbType()) # + parameterDict["isMulti"] = QgsWkbTypes.isMultiType(destinationLayer.wkbType()) return parameterDict def getCoordinateTransformer(self, inputLyr, outputLyr): @@ -148,33 +179,46 @@ def getCoordinateTransformer(self, inputLyr, outputLyr): inputSrc = QgsCoordinateReferenceSystem(inputAuthId) outputSrc = QgsCoordinateReferenceSystem(outputAuthId) coordinateTransformer = QgsCoordinateTransform( - inputSrc, outputSrc, QgsProject.instance()) + inputSrc, outputSrc, QgsProject.instance() + ) return coordinateTransformer - def createAndPopulateUnifiedVectorLayer(self, layerList, geomType=None, epsg=None, attributeTupple=False, attributeBlackList='', onlySelected=False, feedback=None): + def createAndPopulateUnifiedVectorLayer( + self, + layerList, + geomType=None, + epsg=None, + attributeTupple=False, + attributeBlackList="", + onlySelected=False, + feedback=None, + ): if not epsg: - epsg = layerList[0].crs().authid().split(':')[-1] + epsg = layerList[0].crs().authid().split(":")[-1] if not geomType: geomType = None for layer in layerList: if layer.featureCount() > 0: - geomType = int(next(layer.getFeatures())\ - .geometry().wkbType()) + geomType = next(layer.getFeatures()).geometry().wkbType() break else: raise ValueError( - self.tr("No layers were provided or they are all empty.")) - unified_layer = self.createUnifiedVectorLayer(geomType, epsg, - attributeTupple=attributeTupple) + self.tr("No layers were provided or they are all empty.") + ) + unified_layer = self.createUnifiedVectorLayer( + geomType, epsg, attributeTupple=attributeTupple + ) parameterDict = self.getDestinationParameters(unified_layer) - featList = self.getUnifiedLayerFeatures(unified_layer, layerList, - attributeTupple=attributeTupple, - attributeBlackList=attributeBlackList, - onlySelected=onlySelected, - parameterDict=parameterDict, - feedback=feedback) - self.addFeaturesToLayer(unified_layer, featList, - msg='Populating unified layer') + featList = self.getUnifiedLayerFeatures( + unified_layer, + layerList, + attributeTupple=attributeTupple, + attributeBlackList=attributeBlackList, + onlySelected=onlySelected, + parameterDict=parameterDict, + feedback=feedback, + ) + self.addFeaturesToLayer(unified_layer, featList, msg="Populating unified layer") return unified_layer def createUnifiedVectorLayer(self, geomType, srid, attributeTupple=False): @@ -182,8 +226,7 @@ def createUnifiedVectorLayer(self, geomType, srid, attributeTupple=False): Creates a unified vector layer for validation purposes. """ fields = self.getUnifiedVectorFields(attributeTupple=attributeTupple) - lyrUri = "{0}?crs=epsg:{1}".format( - QgsWkbTypes.displayString(int(geomType)), srid) + lyrUri = "{0}?crs=epsg:{1}".format(QgsWkbTypes.displayString(geomType), srid) lyr = QgsVectorLayer(lyrUri, "unified_layer", "memory") lyr.startEditing() fields = self.getUnifiedVectorFields(attributeTupple=attributeTupple) @@ -193,25 +236,38 @@ def createUnifiedVectorLayer(self, geomType, srid, attributeTupple=False): def getUnifiedVectorFields(self, attributeTupple=False): if not attributeTupple: - fields = [QgsField('featid', QVariant.Int), - QgsField('layer', QVariant.String) - ] + fields = [ + QgsField("featid", QVariant.Int), + QgsField("layer", QVariant.String), + ] else: - fields = [QgsField('featid', QVariant.Int), - QgsField('layer', QVariant.String), - QgsField('tupple', QVariant.String), - QgsField('blacklist', QVariant.String) - ] + fields = [ + QgsField("featid", QVariant.Int), + QgsField("layer", QVariant.String), + QgsField("tupple", QVariant.String), + QgsField("blacklist", QVariant.String), + ] return fields - def getUnifiedLayerFeatures(self, unifiedLyr, layerList, attributeTupple=False, attributeBlackList=None, onlySelected=False, parameterDict=None, feedback=None): + def getUnifiedLayerFeatures( + self, + unifiedLyr, + layerList, + attributeTupple=False, + attributeBlackList=None, + onlySelected=False, + parameterDict=None, + feedback=None, + ): parameterDict = {} if parameterDict is None else parameterDict featList = [] - blackList = attributeBlackList.split( - ',') if attributeBlackList is not None and ',' in attributeBlackList else [] + blackList = ( + attributeBlackList.split(",") + if attributeBlackList is not None and "," in attributeBlackList + else [] + ) if feedback: - multiStepFeedback = QgsProcessingMultiStepFeedback( - len(layerList), feedback) + multiStepFeedback = QgsProcessingMultiStepFeedback(len(layerList), feedback) for i, layer in enumerate(layerList): if feedback: if feedback.isCanceled(): @@ -219,26 +275,30 @@ def getUnifiedLayerFeatures(self, unifiedLyr, layerList, attributeTupple=False, multiStepFeedback.setCurrentStep(i) # recording class name layername = layer.name() - coordinateTransformer = self.getCoordinateTransformer( - unifiedLyr, layer) + coordinateTransformer = self.getCoordinateTransformer(unifiedLyr, layer) iterator, size = self.getFeatureList( - layer, onlySelected=onlySelected, returnSize=True) + layer, onlySelected=onlySelected, returnSize=True + ) for current, feature in enumerate(iterator): if feedback: if multiStepFeedback.isCanceled(): break - newFeats = self.featureHandler.createUnifiedFeature(unifiedLyr, feature, layername, - bList=blackList, - attributeTupple=attributeTupple, - parameterDict=parameterDict, - coordinateTransformer=coordinateTransformer) + newFeats = self.featureHandler.createUnifiedFeature( + unifiedLyr, + feature, + layername, + bList=blackList, + attributeTupple=attributeTupple, + parameterDict=parameterDict, + coordinateTransformer=coordinateTransformer, + ) featList += newFeats if feedback: - multiStepFeedback.setProgress(current*size) + multiStepFeedback.setProgress(current * size) return featList def addFeaturesToLayer(self, lyr, featList, commitChanges=True, msg=None): - msg = '' if msg is None else msg + msg = "" if msg is None else msg lyr.startEditing() lyr.beginEditCommand(msg) res = lyr.addFeatures(featList) @@ -263,97 +323,144 @@ def buildInputDict(self, inputLyr, pk=None, feedback=None, onlySelected=False): if onlySelected: iterator = inputLyr.getSelectedFeatures() if feedback is not None: - localTotal = 100/inputLyr.selectedFeatureCount() if inputLyr.selectedFeatureCount() else 0 + localTotal = ( + 100 / inputLyr.selectedFeatureCount() + if inputLyr.selectedFeatureCount() + else 0 + ) else: request = QgsFeatureRequest() iterator = inputLyr.getFeatures(request) if feedback is not None: - localTotal = 100/inputLyr.featureCount() if inputLyr.featureCount() else 0 + localTotal = ( + 100 / inputLyr.featureCount() if inputLyr.featureCount() else 0 + ) for current, feature in enumerate(iterator): if feedback and feedback.isCanceled(): break key = feature[pk] if pk else feature.id() inputDict[key] = { - 'featList': [], - 'originalFeat': feature, + "featList": [], + "originalFeat": feature, } if feedback is not None: - feedback.setProgress(localTotal*current) + feedback.setProgress(localTotal * current) return inputDict - def populateInputDictFeatList(self, lyr, inputDict, pk=None, request=None, feedback=None): + def populateInputDictFeatList( + self, lyr, inputDict, pk=None, request=None, feedback=None + ): iterator = lyr.getFeatures(request) if request else lyr.getFeatures() - localTotal = 100/lyr.featureCount() if lyr.featureCount() else 0 + localTotal = 100 / lyr.featureCount() if lyr.featureCount() else 0 for current, feat in enumerate(iterator): if feedback: if feedback.isCanceled(): break fid = feat[pk] if pk else feat.id() if fid in inputDict: - inputDict[fid]['featList'].append(feat) + inputDict[fid]["featList"].append(feat) if feedback: - feedback.setProgress(localTotal*current) - - def updateOriginalLayer(self, originalLayer, resultLayer, field=None, feedback=None, keepFeatures=False, onlySelected=True): - multiStepFeedback = QgsProcessingMultiStepFeedback( - 3, feedback) if feedback else None + feedback.setProgress(localTotal * current) + + def updateOriginalLayer( + self, + originalLayer, + resultLayer, + field=None, + feedback=None, + keepFeatures=False, + onlySelected=True, + ): + multiStepFeedback = ( + QgsProcessingMultiStepFeedback(3, feedback) if feedback else None + ) # 1- build inputDict structure to store the original state of the layer if feedback: multiStepFeedback.setCurrentStep(0) inputDict = self.buildInputDict( - originalLayer, pk=field, feedback=multiStepFeedback, onlySelected=onlySelected) + originalLayer, + pk=field, + feedback=multiStepFeedback, + onlySelected=onlySelected, + ) # 2- populate the inputDict with the features from the resultLayer if feedback: multiStepFeedback.setCurrentStep(1) self.populateInputDictFeatList( - resultLayer, inputDict, pk=field, feedback=multiStepFeedback) + resultLayer, inputDict, pk=field, feedback=multiStepFeedback + ) # 3- get information from originalLayer and resultLayer if feedback: multiStepFeedback.setCurrentStep(2) parameterDict = self.getDestinationParameters(originalLayer) coordinateTransformer = self.getCoordinateTransformer( - resultLayer, originalLayer) + resultLayer, originalLayer + ) # 4- run update original layer - self.updateOriginalLayerFeatures(originalLayer, inputDict, parameterDict=parameterDict, - coordinateTransformer=coordinateTransformer, keepFeatures=keepFeatures, feedback=multiStepFeedback) + self.updateOriginalLayerFeatures( + originalLayer, + inputDict, + parameterDict=parameterDict, + coordinateTransformer=coordinateTransformer, + keepFeatures=keepFeatures, + feedback=multiStepFeedback, + ) - def updateOriginalLayersFromUnifiedLayer(self, lyrList, unifiedLyr, feedback=None, onlySelected=False): + def updateOriginalLayersFromUnifiedLayer( + self, lyrList, unifiedLyr, feedback=None, onlySelected=False + ): """ Updates original layers from the unified layers """ lenList = len(lyrList) parameterDict = self.getDestinationParameters(unifiedLyr) - multiStepFeedback = QgsProcessingMultiStepFeedback( - 3*lenList, feedback) if feedback else None + multiStepFeedback = ( + QgsProcessingMultiStepFeedback(3 * lenList, feedback) if feedback else None + ) for i, lyr in enumerate(lyrList): if feedback is not None and multiStepFeedback.isCanceled(): break - multiStepFeedback.setCurrentStep(3*i) + multiStepFeedback.setCurrentStep(3 * i) multiStepFeedback.pushInfo(self.tr(f"Building {lyr.name()} input dict")) inputDict = self.buildInputDict( - lyr, onlySelected=onlySelected, feedback=multiStepFeedback) + lyr, onlySelected=onlySelected, feedback=multiStepFeedback + ) if multiStepFeedback is not None and multiStepFeedback.isCanceled(): break - request = QgsFeatureRequest(QgsExpression( - "layer = '{0}'".format(lyr.name()))) - multiStepFeedback.setCurrentStep(3*i+1) + request = QgsFeatureRequest( + QgsExpression("layer = '{0}'".format(lyr.name())) + ) + multiStepFeedback.setCurrentStep(3 * i + 1) multiStepFeedback.pushInfo(self.tr(f"Populating {lyr.name()} input dict")) self.populateInputDictFeatList( - unifiedLyr, inputDict, pk='featid', request=request, feedback=multiStepFeedback) + unifiedLyr, + inputDict, + pk="featid", + request=request, + feedback=multiStepFeedback, + ) if multiStepFeedback is not None and multiStepFeedback.isCanceled(): break - coordinateTransformer = self.getCoordinateTransformer( - unifiedLyr, lyr) - multiStepFeedback.setCurrentStep(3*i+2) + coordinateTransformer = self.getCoordinateTransformer(unifiedLyr, lyr) + multiStepFeedback.setCurrentStep(3 * i + 2) multiStepFeedback.pushInfo(self.tr(f"Updating {lyr.name()} features")) - self.updateOriginalLayerFeatures(lyr, inputDict, parameterDict=parameterDict, - coordinateTransformer=coordinateTransformer, feedback=multiStepFeedback) + self.updateOriginalLayerFeatures( + lyr, + inputDict, + parameterDict=parameterDict, + coordinateTransformer=coordinateTransformer, + feedback=multiStepFeedback, + ) - def updateOriginalLayerFeatures(self, lyr, inputDict, - parameterDict=None, - coordinateTransformer=None, - keepFeatures=False, - feedback=None): + def updateOriginalLayerFeatures( + self, + lyr, + inputDict, + parameterDict=None, + coordinateTransformer=None, + keepFeatures=False, + feedback=None, + ): """ Updates the layer list using the given inputDict :param lyr: (QgsVectorLayer) layer container of features from featList. @@ -368,27 +475,33 @@ def updateOriginalLayerFeatures(self, lyr, inputDict, parameterDict = {} if parameterDict is None else parameterDict idsToRemove, featuresToAdd = set(), set() lyr.startEditing() - lyr.beginEditCommand('Updating layer {0}'.format(lyr.name())) - localTotal = 100/len(inputDict) if inputDict else 0 + lyr.beginEditCommand("Updating layer {0}".format(lyr.name())) + nSteps = len(inputDict) + if nSteps == 0 or feedback.isCanceled(): + return + localTotal = 100 / len(inputDict) if inputDict else 0 futures = set() - pool = concurrent.futures.ThreadPoolExecutor(max_workers=os.cpu_count()-1) + pool = concurrent.futures.ThreadPoolExecutor(max_workers=os.cpu_count() - 1) multiStepFeedback = QgsProcessingMultiStepFeedback(2, feedback) + def evaluate(id_, featDict): idsToRemove, featuresToAdd, geometriesToChange = set(), set(), set() if multiStepFeedback.isCanceled(): return idsToRemove, featuresToAdd, geometriesToChange - outFeats = featDict['featList'] + outFeats = featDict["featList"] if len(outFeats) == 0: idsToRemove.add(id_) return idsToRemove, featuresToAdd, geometriesToChange geomToUpdate, addedFeatures, deleteId = self.featureHandler.handleFeature( outFeats, - featDict['originalFeat'], + featDict["originalFeat"], lyr, parameterDict=parameterDict, - coordinateTransformer=coordinateTransformer + coordinateTransformer=coordinateTransformer, ) - if geomToUpdate is not None and not geomToUpdate.equals(inputDict[id_]['originalFeat'].geometry()): + if geomToUpdate is not None and not geomToUpdate.equals( + inputDict[id_]["originalFeat"].geometry() + ): geometriesToChange.add((id_, geomToUpdate)) if deleteId: idsToRemove.add(id_) @@ -402,10 +515,12 @@ def evaluate(id_, featDict): return futures.add(pool.submit(evaluate, id_, featDict)) if feedback is not None: - feedback.setProgress(localTotal*current) + feedback.setProgress(localTotal * current) multiStepFeedback.setCurrentStep(1) multiStepFeedback.pushInfo(self.tr("Evaluating results...")) - changeGeometryLambda = lambda x: lyr.changeGeometry(x[0], x[1], skipDefaultValue=True) + changeGeometryLambda = lambda x: lyr.changeGeometry( + x[0], x[1], skipDefaultValue=True + ) for current, future in enumerate(concurrent.futures.as_completed(futures)): if feedback is not None and feedback.isCanceled(): return @@ -413,39 +528,58 @@ def evaluate(id_, featDict): list(map(changeGeometryLambda, geometriesToChange)) featuresToAdd = featuresToAdd.union(addedFeatures) idsToRemove = idsToRemove.union(deletedIds) + if current % 1000 == 0: + multiStepFeedback.pushInfo( + self.tr(f"Evaluated {current}/{nSteps} results.") + ) if feedback is not None: - feedback.setProgress(localTotal*current) + feedback.setProgress(localTotal * current) lyr.addFeatures(list(featuresToAdd)) if not keepFeatures: lyr.deleteFeatures(list(idsToRemove)) lyr.endEditCommand() - def mergeLinesOnLayer(self, lyr, onlySelected=False, feedback=None, ignoreVirtualFields=True, attributeBlackList=None, excludePrimaryKeys=True): + def mergeLinesOnLayer( + self, + lyr, + onlySelected=False, + feedback=None, + ignoreVirtualFields=True, + attributeBlackList=None, + excludePrimaryKeys=True, + ): attributeBlackList = [] if attributeBlackList is None else attributeBlackList if feedback: localFeedback = QgsProcessingMultiStepFeedback(3, feedback) localFeedback.setCurrentStep(0) # build attribute dict attributeFeatDict = self.buildAttributeFeatureDict( - lyr, onlySelected=onlySelected, feedback=localFeedback, attributeBlackList=attributeBlackList) + lyr, + onlySelected=onlySelected, + feedback=localFeedback, + attributeBlackList=attributeBlackList, + ) # build network dict if feedback: localFeedback.setCurrentStep(1) networkDict = self.buildInitialAndEndPointDict( - lyr, onlySelected=onlySelected, feedback=localFeedback) + lyr, onlySelected=onlySelected, feedback=localFeedback + ) parameterDict = self.getDestinationParameters(lyr) idsToRemove = [] if feedback: localFeedback.setCurrentStep(2) - localTotal = 100/(len(attributeFeatDict) - ) if len(attributeFeatDict) != 0 else 0 + localTotal = ( + 100 / (len(attributeFeatDict)) if len(attributeFeatDict) != 0 else 0 + ) mergeFeedback = QgsProcessingMultiStepFeedback( - len(attributeFeatDict), localFeedback) + len(attributeFeatDict), localFeedback + ) lyr.startEditing() - lyr.beginEditCommand(self.tr('Merging Lines')) + lyr.beginEditCommand(self.tr("Merging Lines")) for current, (key, featList) in enumerate(attributeFeatDict.items()): if feedback: @@ -458,41 +592,71 @@ def mergeLinesOnLayer(self, lyr, onlySelected=False, feedback=None, ignoreVirtua idsToRemove=idsToRemove, parameterDict=parameterDict, feedback=mergeFeedback, - networkDict=networkDict + networkDict=networkDict, ) lyr.deleteFeatures(idsToRemove) lyr.endEditCommand() - def buildAttributeFeatureDict(self, lyr, onlySelected=False, feedback=None, ignoreVirtualFields=True, attributeBlackList=None, excludePrimaryKeys=True): + def buildAttributeFeatureDict( + self, + lyr, + onlySelected=False, + feedback=None, + ignoreVirtualFields=True, + attributeBlackList=None, + excludePrimaryKeys=True, + ): iterator, size = self.getFeatureList(lyr, onlySelected=onlySelected) - localTotal = 100/size if size != 0 else 0 + localTotal = 100 / size if size != 0 else 0 attributeFeatDict = dict() columns = self.getAttributesFromBlackList( - lyr, attributeBlackList=attributeBlackList, ignoreVirtualFields=ignoreVirtualFields, excludePrimaryKeys=excludePrimaryKeys) + lyr, + attributeBlackList=attributeBlackList, + ignoreVirtualFields=ignoreVirtualFields, + excludePrimaryKeys=excludePrimaryKeys, + ) for current, feat in enumerate(iterator): if feedback: if feedback.isCanceled(): break self.appendFeatOnAttrsDict(attributeFeatDict, feat, columns) if feedback: - feedback.setProgress(localTotal*current) + feedback.setProgress(localTotal * current) return attributeFeatDict - def getAttributesFromBlackList(self, lyr, attributeBlackList=None, ignoreVirtualFields=True, excludePrimaryKeys=True): + def getAttributesFromBlackList( + self, + lyr, + attributeBlackList=None, + ignoreVirtualFields=True, + excludePrimaryKeys=True, + ): attributeBlackList = [] if attributeBlackList is None else attributeBlackList pkIndexes = lyr.primaryKeyAttributes() if excludePrimaryKeys else [] typeBlackList = [6] if ignoreVirtualFields else [] - columns = [field.name() for idx, field in enumerate(lyr.fields()) if idx not in pkIndexes and field.type( - ) not in typeBlackList and field.name() not in attributeBlackList] + columns = [ + field.name() + for idx, field in enumerate(lyr.fields()) + if idx not in pkIndexes + and field.type() not in typeBlackList + and field.name() not in attributeBlackList + ] return columns def appendFeatOnAttrsDict(self, inputDict, feat, columns): - attrKey = ','.join(['{}'.format(feat[column]) for column in columns]) + attrKey = ",".join(["{}".format(feat[column]) for column in columns]) if attrKey not in inputDict: inputDict[attrKey] = [] inputDict[attrKey].append(feat) - def buildInitialAndEndPointDict(self, lyr, onlySelected=False, feedback=None, addFeatureToList=False, recordStepProgress=True): + def buildInitialAndEndPointDict( + self, + lyr, + onlySelected=False, + feedback=None, + addFeatureToList=False, + recordStepProgress=True, + ): """ Calculates initial point and end point from each line from lyr. """ @@ -501,7 +665,9 @@ def buildInitialAndEndPointDict(self, lyr, onlySelected=False, feedback=None, ad # iterating over features to store start and end points iterator = lyr.getFeatures() if not onlySelected else lyr.getSelectedFeatures() if recordStepProgress: - featCount = lyr.featureCount() if not onlySelected else lyr.selectedFeatureCount() + featCount = ( + lyr.featureCount() if not onlySelected else lyr.selectedFeatureCount() + ) if featCount == 0: return endVerticesDict size = 100 / featCount @@ -509,56 +675,77 @@ def buildInitialAndEndPointDict(self, lyr, onlySelected=False, feedback=None, ad if feedback is not None and feedback.isCanceled(): break geom = feat.geometry() - lineList = geom.asMultiPolyline() if geom.isMultipart() else [ - geom.asPolyline()] + lineList = ( + geom.asMultiPolyline() if geom.isMultipart() else [geom.asPolyline()] + ) for line in lineList: self.addFeatToDict( endVerticesDict=endVerticesDict, line=line, - item=feat if addFeatureToList else feat.id() + item=feat if addFeatureToList else feat.id(), ) if feedback is not None and recordStepProgress: - feedback.setProgress(size*current) + feedback.setProgress(size * current) return endVerticesDict - def getDuplicatedFeaturesDict(self, lyr, onlySelected=False, attributeBlackList=None, ignoreVirtualFields=True, excludePrimaryKeys=True, useAttributes=False, feedback=None): + def getDuplicatedFeaturesDict( + self, + lyr, + onlySelected=False, + attributeBlackList=None, + ignoreVirtualFields=True, + excludePrimaryKeys=True, + useAttributes=False, + feedback=None, + ): """ returns geomDict = { 'bbox_geom' : {geomKey : -list of duplicated feats-} } """ geomDict = dict() - isMulti = QgsWkbTypes.isMultiType(int(lyr.wkbType())) + isMulti = QgsWkbTypes.isMultiType(lyr.wkbType()) iterator, featCount = self.getFeatureList( - lyr, onlySelected=onlySelected, returnIterator=True) - size = 100/featCount if featCount else 0 + lyr, onlySelected=onlySelected, returnIterator=True + ) + size = 100 / featCount if featCount else 0 columns = self.getAttributesFromBlackList( - lyr, attributeBlackList=attributeBlackList, ignoreVirtualFields=ignoreVirtualFields, excludePrimaryKeys=excludePrimaryKeys) - multiStepFeedback = QgsProcessingMultiStepFeedback( - 2, feedback) if feedback else None + lyr, + attributeBlackList=attributeBlackList, + ignoreVirtualFields=ignoreVirtualFields, + excludePrimaryKeys=excludePrimaryKeys, + ) + multiStepFeedback = ( + QgsProcessingMultiStepFeedback(2, feedback) if feedback else None + ) multiStepFeedback.setCurrentStep(0) # builds bounding box dict to do a geos comparison for each feat in list bbDict = self.getFeaturesWithSameBoundingBox( - iterator, isMulti, featCount, columns=columns, feedback=feedback) + iterator, isMulti, featCount, columns=columns, feedback=feedback + ) multiStepFeedback.setCurrentStep(1) for current, (key, featList) in enumerate(bbDict.items()): if feedback is not None and feedback.isCanceled(): break if len(featList) > 1: duplicatedDict = self.searchDuplicatedFeatures( - featList, columns=columns, useAttributes=useAttributes) + featList, columns=columns, useAttributes=useAttributes + ) geomDict.update(duplicatedDict) if feedback is not None: feedback.setProgress(size * current) return geomDict - def getFeaturesWithSameBoundingBox(self, iterator, isMulti, size, columns=None, feedback=None): + def getFeaturesWithSameBoundingBox( + self, iterator, isMulti, size, columns=None, feedback=None + ): """ - Iterates over iterator and gets + Iterates over iterator and gets """ bbDict = defaultdict(list) if feedback is not None: feedback.setProgressText(self.tr("Building duplicated search structure...")) + def _buildBBDictEntry(feat, columns): if feedback.isCanceled(): return @@ -566,13 +753,21 @@ def _buildBBDictEntry(feat, columns): if isMulti and not geom.isMultipart(): geom.convertToMultiType() geomBB_key = geom.boundingBox().asWktPolygon() - attrKey = ','.join(['{}'.format(feat[column]) - for column in columns]) if columns is not None else '' - return (geomBB_key, {'geom': geom, 'feat': feat, 'attrKey': attrKey}) + attrKey = ( + ",".join(["{}".format(feat[column]) for column in columns]) + if columns is not None + else "" + ) + return (geomBB_key, {"geom": geom, "feat": feat, "attrKey": attrKey}) + futures = set() - pool = concurrent.futures.ThreadPoolExecutor(os.cpu_count()-1) + pool = concurrent.futures.ThreadPoolExecutor(os.cpu_count() - 1) func = lambda x: _buildBBDictEntry(x, columns) - multiStepFeedback = QgsProcessingMultiStepFeedback(2, feedback) if feedback is not None else None + multiStepFeedback = ( + QgsProcessingMultiStepFeedback(2, feedback) + if feedback is not None + else None + ) multiStepFeedback.setCurrentStep(0) multiStepFeedback.pushInfo(self.tr("Submitting tasks to thread")) for feat in iterator: @@ -590,7 +785,7 @@ def _buildBBDictEntry(feat, columns): multiStepFeedback.setProgress(size * current) return bbDict # """ - # Iterates over iterator and gets + # Iterates over iterator and gets # """ # bbDict = defaultdict(list) # for current, feat in enumerate(iterator): @@ -616,12 +811,12 @@ def searchDuplicatedFeatures(self, featList, columns, useAttributes=False): """ duplicatedDict = dict() if featList: - fields = [f.name() for f in featList[0]['feat'].fields()] + fields = [f.name() for f in featList[0]["feat"].fields()] for dict_feat1, dict_feat2 in combinations(featList, 2): - geom1 = dict_feat1['geom'] - geom2 = dict_feat2['geom'] - feat1 = dict_feat1['feat'] - feat2 = dict_feat2['feat'] + geom1 = dict_feat1["geom"] + geom2 = dict_feat2["geom"] + feat1 = dict_feat1["feat"] + feat2 = dict_feat2["feat"] wkb1 = geom1.asWkb() wkb2 = geom2.asWkb() if not geom1.isGeosEqual(geom2): @@ -633,7 +828,7 @@ def searchDuplicatedFeatures(self, featList, columns, useAttributes=False): if attr not in columns: continue elif feat1[attr] != feat2[attr]: - raise Exception('Skip outter loop') + raise Exception("Skip outter loop") except: continue if wkb1 in duplicatedDict: @@ -655,7 +850,7 @@ def addPointToDict(self, point, pointDict, item): def addDissolveField(self, layer, tol, feedback=None): # add temp field - idField = QgsField('d_id', QVariant.Int) + idField = QgsField("d_id", QVariant.Int) layer.dataProvider().addAttributes([idField]) layer.updateFields() # small feature list @@ -666,17 +861,20 @@ def addDissolveField(self, layer, tol, feedback=None): else: multiStepFeedback = None smallFeatureList, bigFeatureList, bigFeatIndex = self.buildSizeSearchStructure( - layer, tol, feedback=multiStepFeedback) + layer, tol, feedback=multiStepFeedback + ) if multiStepFeedback: multiStepFeedback.setCurrentStep(1) self.populateSizeSearchStructure( - layer, smallFeatureList, bigFeatIndex, feedback=multiStepFeedback) + layer, smallFeatureList, bigFeatIndex, feedback=multiStepFeedback + ) if multiStepFeedback: multiStepFeedback.setCurrentStep(2) updateDict = self.updateFeaturesWithSize( - layer, smallFeatureList, bigFeatureList, feedback=multiStepFeedback) + layer, smallFeatureList, bigFeatureList, feedback=multiStepFeedback + ) return layer def getCandidates(self, idx, bbox): @@ -699,7 +897,7 @@ def buildSizeSearchStructure(self, layer, tol, feedback=None): if feedback: if feedback.isCanceled(): break - feat['d_id'] = feat['featid'] + feat["d_id"] = feat["featid"] if feat.geometry().area() < float(tol): smallFeatureList.append(feat) else: @@ -709,7 +907,9 @@ def buildSizeSearchStructure(self, layer, tol, feedback=None): feedback.setProgress(size * current) return smallFeatureList, bigFeatureList, bigFeatIndex - def populateSizeSearchStructure(self, layer, smallFeatureList, bigFeatIndex, feedback=None): + def populateSizeSearchStructure( + self, layer, smallFeatureList, bigFeatIndex, feedback=None + ): # using spatial index to speed up the process featSize = len(smallFeatureList) size = 100 / featSize if featSize else 0 @@ -717,19 +917,28 @@ def populateSizeSearchStructure(self, layer, smallFeatureList, bigFeatIndex, fee if feedback: if feedback.isCanceled(): break - candidates = bigFeatIndex.intersects( - sfeat.geometry().boundingBox()) + candidates = bigFeatIndex.intersects(sfeat.geometry().boundingBox()) for candidate in candidates: - bfeat = [i for i in layer.dataProvider().getFeatures( - QgsFeatureRequest(candidate))][0] - if sfeat['d_id'] == sfeat['featid'] and sfeat.geometry().intersects(bfeat.geometry()) and sfeat['tupple'] == bfeat['tupple']: - sfeat['d_id'] = bfeat['featid'] + bfeat = [ + i + for i in layer.dataProvider().getFeatures( + QgsFeatureRequest(candidate) + ) + ][0] + if ( + sfeat["d_id"] == sfeat["featid"] + and sfeat.geometry().intersects(bfeat.geometry()) + and sfeat["tupple"] == bfeat["tupple"] + ): + sfeat["d_id"] = bfeat["featid"] if feedback: feedback.setProgress(size * current) - def updateFeaturesWithSize(self, layer, smallFeatureList, bigFeatureList, feedback=None): + def updateFeaturesWithSize( + self, layer, smallFeatureList, bigFeatureList, feedback=None + ): updateDict = dict() - idx = layer.fieldNameIndex('tupple') + idx = layer.fieldNameIndex("tupple") featList = smallFeatureList + bigFeatureList featSize = len(featList) size = 100 / featSize if featSize else 0 @@ -737,19 +946,19 @@ def updateFeaturesWithSize(self, layer, smallFeatureList, bigFeatureList, feedba if feedback: if feedback.isCanceled(): break - newValue = u'{0},{1}'.format(feat['tupple'], feat['d_id']) + newValue = "{0},{1}".format(feat["tupple"], feat["d_id"]) updateDict[feat.id()] = {idx: newValue} if feedback: feedback.setProgress(size * current) return updateDict - + def searchDanglesOnPointDict(self, endVerticesDict, feedback): """ Counts the number of points on each endVerticesDict's key and returns a list of QgsPoint built from key candidate. """ pointList = [] nVertexes = len(endVerticesDict) - localTotal = 100/nVertexes if nVertexes else 0 + localTotal = 100 / nVertexes if nVertexes else 0 # actual search for dangles for current, point in enumerate(endVerticesDict): if feedback.isCanceled(): @@ -757,13 +966,15 @@ def searchDanglesOnPointDict(self, endVerticesDict, feedback): # this means we only have one occurrence of point, therefore it is a dangle if len(endVerticesDict[point]) <= 1: pointList.append(point) - feedback.setProgress(localTotal*current) + feedback.setProgress(localTotal * current) return pointList - - def getSmallFirstOrderDanglesFromPointDict(self, endVerticesDict, minLength, feedback=None): + + def getSmallFirstOrderDanglesFromPointDict( + self, endVerticesDict, minLength, feedback=None + ): pointList = [] nVertexes = len(endVerticesDict) - localTotal = 100/nVertexes if nVertexes else 0 + localTotal = 100 / nVertexes if nVertexes else 0 for current, (point, featList) in enumerate(endVerticesDict.items()): if feedback is not None and feedback.isCanceled(): break @@ -772,8 +983,10 @@ def getSmallFirstOrderDanglesFromPointDict(self, endVerticesDict, minLength, fee if feedback is not None: feedback.setProgress(current * localTotal) return pointList - - def getSmallFirstOrderDangles(self, inputLyr, minLength, onlySelected=False, feedback=None): + + def getSmallFirstOrderDangles( + self, inputLyr, minLength, onlySelected=False, feedback=None + ): multiStepFeedback = QgsProcessingMultiStepFeedback(2, feedback) multiStepFeedback.setProgressText(self.tr("Building aux structure")) multiStepFeedback.setCurrentStep(0) @@ -781,12 +994,16 @@ def getSmallFirstOrderDangles(self, inputLyr, minLength, onlySelected=False, fee inputLyr, onlySelected=onlySelected, feedback=multiStepFeedback, - addFeatureToList=True + addFeatureToList=True, ) multiStepFeedback.setCurrentStep(1) - multiStepFeedback.setProgressText(self.tr("Searching small first order dangles")) + multiStepFeedback.setProgressText( + self.tr("Searching small first order dangles") + ) pointList = self.getSmallFirstOrderDanglesFromPointDict( - endVerticesDict=endVerticesDict, minLength=minLength, feedback=multiStepFeedback + endVerticesDict=endVerticesDict, + minLength=minLength, + feedback=multiStepFeedback, ) return pointList @@ -798,7 +1015,8 @@ def filterDangles(self, lyr, searchRadius, feedback=None): else: multiStepFeedback = None spatialIdx, idDict = self.buildSpatialIndexAndIdDict( - lyr, feedback=multiStepFeedback) + lyr, feedback=multiStepFeedback + ) if multiStepFeedback is not None: multiStepFeedback.setCurrentStep(1) featSize = len(idDict) @@ -812,13 +1030,17 @@ def filterDangles(self, lyr, searchRadius, feedback=None): # gets candidates from spatial index candidateIds = spatialIdx.intersects(bufferBB) for fid in candidateIds: - if fid != id and fid not in deleteSet and buffer.intersects(feat.geometry()): + if ( + fid != id + and fid not in deleteSet + and buffer.intersects(feat.geometry()) + ): deleteSet.add(fid) if feedback is not None: multiStepFeedback.setProgress(size * current) lyr.startEditing() - lyr.beginEditCommand('Filter dangles') + lyr.beginEditCommand("Filter dangles") lyr.deleteFeatures(list(deleteSet)) lyr.commitChanges() @@ -831,23 +1053,32 @@ def buildSpatialIndexAndIdDict(self, inputLyr, feedback=None, featureRequest=Non """ spatialIdx = QgsSpatialIndex() idDict = {} + if inputLyr is None: + return spatialIdx, idDict featCount = inputLyr.featureCount() - size = 100/featCount if featCount else 0 - iterator = inputLyr.getFeatures( - ) if featureRequest is None else inputLyr.getFeatures(featureRequest) - - def addFeatureAlias(x): return self.addFeatureToSpatialIndex( - current=x[0], - feat=x[1], - spatialIdx=spatialIdx, - idDict=idDict, - size=size, - feedback=feedback + size = 100 / featCount if featCount else 0 + iterator = ( + inputLyr.getFeatures() + if featureRequest is None + else inputLyr.getFeatures(featureRequest) ) + + def addFeatureAlias(x): + return self.addFeatureToSpatialIndex( + current=x[0], + feat=x[1], + spatialIdx=spatialIdx, + idDict=idDict, + size=size, + feedback=feedback, + ) + list(map(addFeatureAlias, enumerate(iterator))) return spatialIdx, idDict - def addFeatureToSpatialIndex(self, current, feat, spatialIdx, idDict, size, feedback): + def addFeatureToSpatialIndex( + self, current, feat, spatialIdx, idDict, size, feedback + ): """ Adds feature to spatial index. Used along side with a python map operator to improve performance. @@ -879,23 +1110,24 @@ def getFrameOutterBounds(self, frameLayer, algRunner, context, feedback=None): multiStepFeedback = None # dissolve every feature into a single one outputLayer = algRunner.runDissolve( - frameLayer, context, feedback=multiStepFeedback) + frameLayer, context, feedback=multiStepFeedback + ) if feedback is not None: multiStepFeedback.setCurrentStep(1) boundaryLayer = algRunner.runBoundary( - outputLayer, context, feedback=multiStepFeedback) + outputLayer, context, feedback=multiStepFeedback + ) # get all frame outter layer found if feedback is not None: multiStepFeedback.setCurrentStep(2) featCount = boundaryLayer.featureCount() - size = 100/featCount if featCount else 0 + size = 100 / featCount if featCount else 0 for current, feat in enumerate(boundaryLayer.getFeatures()): if feedback is not None and feedback.isCanceled(): break geom = feat.geometry() # deaggregate geometry, if necessary - frameGeomList += self.geometryHandler.deaggregateGeometry( - multiGeom=geom) + frameGeomList += self.geometryHandler.deaggregateGeometry(multiGeom=geom) if feedback is not None: multiStepFeedback.setProgress(size * current) return frameGeomList @@ -907,8 +1139,8 @@ def identifyAllNodes(self, networkLayer): :return: { node_id : { start : [feature_which_starts_with_node], end : feature_which_ends_with_node } }. """ nodeDict = dict() - isMulti = QgsWkbTypes.isMultiType(int(networkLayer.wkbType())) - if self.parameters['Only Selected']: + isMulti = QgsWkbTypes.isMultiType(networkLayer.wkbType()) + if self.parameters["Only Selected"]: features = networkLayer.selectedFeatures() else: features = [feat for feat in networkLayer.getFeatures()] @@ -930,30 +1162,35 @@ def identifyAllNodes(self, networkLayer): # filling starting node information into dictionary if pInit not in nodeDict: # if the point is not already started into dictionary, it creates a new item - nodeDict[pInit] = {'start': [], 'end': []} - if feat not in nodeDict[pInit]['start']: - nodeDict[pInit]['start'].append(feat) + nodeDict[pInit] = {"start": [], "end": []} + if feat not in nodeDict[pInit]["start"]: + nodeDict[pInit]["start"].append(feat) # filling ending node information into dictionary if pEnd not in nodeDict: - nodeDict[pEnd] = {'start': [], 'end': []} - if feat not in nodeDict[pEnd]['end']: - nodeDict[pEnd]['end'].append(feat) + nodeDict[pEnd] = {"start": [], "end": []} + if feat not in nodeDict[pEnd]["end"]: + nodeDict[pEnd]["end"].append(feat) return nodeDict - def snapToLayer(self, inputLyr, refLyr, tol, behavior, onlySelected=False, feedback=None): + def snapToLayer( + self, inputLyr, refLyr, tol, behavior, onlySelected=False, feedback=None + ): """ Snaps and updates inpytLyr """ - snapper = QgsGeometrySnapper( - refLyr) if inputLyr != refLyr and behavior != 7 else QgsInternalGeometrySnapper(tol, behavior) - iterator, featCount = self.getFeatureList( - inputLyr, onlySelected=onlySelected) + snapper = ( + QgsGeometrySnapper(refLyr) + if inputLyr != refLyr and behavior != 7 + else QgsInternalGeometrySnapper(tol, behavior) + ) + iterator, featCount = self.getFeatureList(inputLyr, onlySelected=onlySelected) if featCount == 0: return - size = 100/featCount + size = 100 / featCount deleteSet = set() inputLyr.startEditing() - inputLyr.beginEditCommand('Snapping Features') + inputLyr.beginEditCommand("Snapping Features") + def evaluate(feat): if feedback is not None and feedback.isCanceled(): return None @@ -967,13 +1204,17 @@ def evaluate(feat): fixedGeom = geom.makeValid() if fixedGeom.isNull(): return None - outputGeom = snapper.snapGeometry(fixedGeom, tol, behavior) \ - if inputLyr != refLyr and behavior != 7 else snapper.snapFeature(feat) + outputGeom = ( + snapper.snapGeometry(fixedGeom, tol, behavior) + if inputLyr != refLyr and behavior != 7 + else snapper.snapFeature(feat) + ) if geom is None: return featid return featid, outputGeom + futures = set() - pool = concurrent.futures.ThreadPoolExecutor(max_workers=os.cpu_count()-1) + pool = concurrent.futures.ThreadPoolExecutor(max_workers=os.cpu_count() - 1) multiStepFeedback = QgsProcessingMultiStepFeedback(2, feedback) multiStepFeedback.setCurrentStep(0) for current, feat in enumerate(iterator): @@ -998,7 +1239,9 @@ def evaluate(feat): inputLyr.deleteFeatures(list(deleteSet)) inputLyr.endEditCommand() - def getContourLineOutOfThreshold(self, contourLyr, terrainPolygonLyr, threshold, refLyr=None, feedback=None): + def getContourLineOutOfThreshold( + self, contourLyr, terrainPolygonLyr, threshold, refLyr=None, feedback=None + ): """ todo """ @@ -1017,14 +1260,20 @@ def filterByExpression(self, layer, expression, context, feedback=None): :return: (QgsVectorLayer) filtered layer. """ return AlgRunner().runFilterExpression( - inputLyr=layer, - context=context, - expression=expression, - feedback=feedback + inputLyr=layer, context=context, expression=expression, feedback=feedback ) - def prepareConversion(self, inputLyr, context, inputExpression=None, filterLyr=None, - behavior=None, bufferRadius=None, conversionMap=None, feedback=None): + def prepareConversion( + self, + inputLyr, + context, + inputExpression=None, + filterLyr=None, + behavior=None, + bufferRadius=None, + conversionMap=None, + feedback=None, + ): bufferRadius = 0 if bufferRadius is None else bufferRadius algRunner = AlgRunner() if feedback is not None: @@ -1042,14 +1291,14 @@ def prepareConversion(self, inputLyr, context, inputExpression=None, filterLyr=N multiStepFeedback = None localLyr = inputLyr currentStep = 0 - if inputExpression is not None and inputExpression != '': + if inputExpression is not None and inputExpression != "": if multiStepFeedback is not None: multiStepFeedback.setCurrentStep(currentStep) localLyr = algRunner.runFilterExpression( inputLyr=localLyr, context=context, expression=inputExpression, - feedback=multiStepFeedback + feedback=multiStepFeedback, ) currentStep += 1 if filterLyr is not None: @@ -1057,64 +1306,112 @@ def prepareConversion(self, inputLyr, context, inputExpression=None, filterLyr=N multiStepFeedback.setCurrentStep(currentStep) if behavior == 3: filterLyr = algRunner.runBuffer( - filterLyr, bufferRadius, context, feedback=multiStepFeedback) + filterLyr, bufferRadius, context, feedback=multiStepFeedback + ) currentStep += 1 localLyr = algRunner.runIntersection( - localLyr, context, overlayLyr=filterLyr) + localLyr, context, overlayLyr=filterLyr + ) return localLyr - def identifyAndFixInvalidGeometries(self, inputLyr, ignoreClosed=False, fixInput=False, onlySelected=False, feedback=None): - iterator, featCount = self.getFeatureList( - inputLyr, onlySelected=onlySelected) + def identifyAndFixInvalidGeometries( + self, + inputLyr, + ignoreClosed=False, + fixInput=False, + onlySelected=False, + feedback=None, + ): + iterator, featCount = self.getFeatureList(inputLyr, onlySelected=onlySelected) parameterDict = self.getDestinationParameters(inputLyr) geometryType = inputLyr.geometryType() - flagDict, newFeatSet = self.identifyInvalidGeometries(iterator, featCount, inputLyr, ignoreClosed, fixInput, parameterDict, geometryType, feedback=feedback) + flagDict, newFeatSet = self.identifyInvalidGeometries( + iterator, + featCount, + inputLyr, + ignoreClosed, + fixInput, + parameterDict, + geometryType, + feedback=feedback, + ) if fixInput: self.applyGeometryFixesOnLayer(inputLyr, newFeatSet) return flagDict - def identifyInvalidGeometries(self, iterator, featCount, inputLyr, ignoreClosed, fixInput, parameterDict, geometryType, feedback=None): + def identifyInvalidGeometries( + self, + iterator, + featCount, + inputLyr, + ignoreClosed, + fixInput, + parameterDict, + geometryType, + feedback=None, + ): flagDict = dict() newFeatSet = set() - stepSize = 100/featCount if featCount else 0 + stepSize = 100 / featCount if featCount else 0 futures = set() - pool = concurrent.futures.ThreadPoolExecutor(max_workers=os.cpu_count()-1) - multiStepFeedback = QgsProcessingMultiStepFeedback(2, feedback) if feedback is not None else None + pool = concurrent.futures.ThreadPoolExecutor(max_workers=os.cpu_count() - 1) + multiStepFeedback = ( + QgsProcessingMultiStepFeedback(2, feedback) + if feedback is not None + else None + ) if multiStepFeedback is not None: multiStepFeedback.setCurrentStep(0) multiStepFeedback.pushInfo(self.tr("Submitting tasks to thread...")) + def evaluate(feat): _newFeatSet = set() geom = feat.geometry() id = feat.id() flagDict = self.checkGeomIsValid(geom, ignoreClosed, feedback) if fixInput: - self.fixGeometryFromInput(inputLyr, parameterDict, geometryType, _newFeatSet, feat, geom, id) - return flagDict, _newFeatSet + self.fixGeometryFromInput( + inputLyr, parameterDict, geometryType, _newFeatSet, feat, geom, id + ) + return flagDict, _newFeatSet, feat + for current, feat in enumerate(iterator): if feedback is not None and feedback.isCanceled(): break futures.add(pool.submit(evaluate, feat)) if feedback is not None: - feedback.setProgress(stepSize*current) + feedback.setProgress(stepSize * current) if multiStepFeedback is not None: multiStepFeedback.setCurrentStep(1) multiStepFeedback.pushInfo(self.tr("Evaluating results...")) + pkFields = inputLyr.primaryKeyAttributes() + pkFieldNames = [ + field.name() + for idx, field in enumerate(inputLyr.fields()) + if idx in pkFields + ] for current, future in enumerate(concurrent.futures.as_completed(futures)): if feedback is not None and feedback.isCanceled(): break - output, _newFeatSet = future.result() + output, _newFeatSet, feat = future.result() if output: + featIdText = ( + f"{feat.id()}" + if pkFields == [] + else f"{','.join(feat.attribute(i) for i in pkFields)}" + ) + featIdText = featIdText.replace(",)", "").replace("(", "") for point, errorDict in output.items(): if point in flagDict: flagDict[point]["reason"] += errorDict["reason"] else: flagDict[point] = errorDict + flagDict[point]["featid"] = featIdText if _newFeatSet: newFeatSet = newFeatSet.union(_newFeatSet) if feedback is not None: - feedback.setProgress(stepSize*current) + feedback.setProgress(stepSize * current) return flagDict, newFeatSet def checkGeomIsValid(self, geom, ignoreClosed, feedback=None): @@ -1125,33 +1422,39 @@ def checkGeomIsValid(self, geom, ignoreClosed, feedback=None): }.items(): if feedback is not None and feedback.isCanceled(): break - isValid = self.check_validity(ignoreClosed, flagDict, geom, validate_type, method_parameter) + isValid = self.check_validity( + ignoreClosed, flagDict, geom, validate_type, method_parameter + ) if not isValid: break if isValid and geom.type() == QgsWkbTypes.PolygonGeometry: self.analyze_polygon_boundary_and_holes(flagDict, geom) return flagDict - def fixGeometryFromInput(self, inputLyr, parameterDict, geometryType, newFeatSet, feat, geom, id): - attrMap = {idx: feat[field.name()] for idx, field in enumerate( - feat.fields()) if idx not in inputLyr.primaryKeyAttributes()} - geom.removeDuplicateNodes( - useZValues=parameterDict['hasZValues']) + def fixGeometryFromInput( + self, inputLyr, parameterDict, geometryType, newFeatSet, feat, geom, id + ): + attrMap = { + idx: feat[field.name()] + for idx, field in enumerate(feat.fields()) + if idx not in inputLyr.primaryKeyAttributes() + } + geom.removeDuplicateNodes(useZValues=parameterDict["hasZValues"]) fixedGeom = geom.makeValid() for idx, newGeom in enumerate( - self.geometryHandler.handleGeometryCollection( - fixedGeom, geometryType, parameterDict=parameterDict) - ): + self.geometryHandler.handleGeometryCollection( + fixedGeom, geometryType, parameterDict=parameterDict + ) + ): if idx == 0: inputLyr.changeGeometry(id, newGeom) else: - newFeat = QgsVectorLayerUtils.createFeature( - inputLyr, newGeom, attrMap) + newFeat = QgsVectorLayerUtils.createFeature(inputLyr, newGeom, attrMap) newFeatSet.add(newFeat) def applyGeometryFixesOnLayer(self, inputLyr, newFeatSet): inputLyr.startEditing() - inputLyr.beginEditCommand('Fixing geometries') + inputLyr.beginEditCommand("Fixing geometries") inputLyr.addFeatures(newFeatSet) inputLyr.endEditCommand() @@ -1160,31 +1463,37 @@ def analyze_polygon_boundary_and_holes(self, flagDict, geom): for part in geom.asGeometryCollection(): if len(part.asPolygon()) <= 1: continue - boundary, *holeList = map(lambda x: QgsGeometry.fromPolylineXY(x), part.asPolygon()) + boundary, *holeList = map( + lambda x: QgsGeometry.fromPolylineXY(x), part.asPolygon() + ) for intersection in map( - lambda x: x.intersection(boundary), - filter(lambda y: y.intersects(boundary), holeList) - ): - flagWktSet = flagWktSet.union(set(vertex.asWkt() for vertex in intersection.vertices())) + lambda x: x.intersection(boundary), + filter(lambda y: y.intersects(boundary), holeList), + ): + flagWktSet = flagWktSet.union( + set(vertex.asWkt() for vertex in intersection.vertices()) + ) for flag in flagWktSet: errorPointXY = QgsGeometry.fromWkt(flag).asPoint() flagGeom = QgsGeometry.fromPointXY(errorPointXY) if errorPointXY not in flagDict: - flagDict[errorPointXY] = { - 'geom': flagGeom, - 'reason': '' - } - flagDict[errorPointXY]['reason'] += 'OGC invalid reason: {text}\n'.format( - text=self.tr("Self intersection between hole and boundary") - ) + flagDict[errorPointXY] = {"geom": flagGeom, "reason": ""} + flagDict[errorPointXY]["reason"] += "OGC invalid reason: {text}\n".format( + text=self.tr("Self intersection between hole and boundary") + ) - def check_validity(self, ignoreClosed, flagDict, geom, validate_type, method_parameter): + def check_validity( + self, ignoreClosed, flagDict, geom, validate_type, method_parameter + ): for error in geom.validateGeometry(method_parameter): if error.hasWhere(): errorPointXY = error.where() flagGeom = QgsGeometry.fromPointXY(errorPointXY) - if geom.type() == QgsWkbTypes.LineGeometry and ignoreClosed and\ - self.isClosedAndFlagIsAtStartOrEnd(geom, flagGeom): + if ( + geom.type() == QgsWkbTypes.LineGeometry + and ignoreClosed + and self.isClosedAndFlagIsAtStartOrEnd(geom, flagGeom) + ): continue self._add_flag(flagDict, validate_type, error, errorPointXY, flagGeom) return False @@ -1192,19 +1501,16 @@ def check_validity(self, ignoreClosed, flagDict, geom, validate_type, method_par def _add_flag(self, flagDict, validate_type, error, errorPointXY, flagGeom): if errorPointXY not in flagDict: - flagDict[errorPointXY] = { - 'geom': flagGeom, - 'reason': '' - } - flagDict[errorPointXY]['reason'] += '{type} invalid reason: {text}\n'.format( - type=validate_type, - text=error.what() - ) + flagDict[errorPointXY] = {"geom": flagGeom, "reason": ""} + flagDict[errorPointXY]["reason"] += "{type} invalid reason: {text}\n".format( + type=validate_type, text=error.what() + ) def isClosedAndFlagIsAtStartOrEnd(self, geom, flagGeom): for part in geom.asGeometryCollection(): startPoint, endPoint = self.geometryHandler.getFirstAndLastNodeFromGeom( - part) + part + ) startPointGeom = QgsGeometry.fromPointXY(startPoint) endPointGeom = QgsGeometry.fromPointXY(endPoint) if not startPointGeom.equals(endPointGeom): @@ -1213,7 +1519,15 @@ def isClosedAndFlagIsAtStartOrEnd(self, geom, flagGeom): return True return False - def runGrassDissolve(self, inputLyr, context, feedback=None, column=None, outputLyr=None, onFinish=None): + def runGrassDissolve( + self, + inputLyr, + context, + feedback=None, + column=None, + outputLyr=None, + onFinish=None, + ): """ Runs dissolve from GRASS algorithm provider. :param inputLyr: (QgsVectorLayer) layer to be dissolved. @@ -1224,10 +1538,20 @@ def runGrassDissolve(self, inputLyr, context, feedback=None, column=None, output :param onFinish: (list-of-str) sequence of algs to be run after dissolve is executed, in execution order. :return: (QgsVectorLayer) dissolved (output) layer. """ - return AlgRunner().runGrassDissolve(inputLyr, context, feedback=None, column=None, outputLyr=None, onFinish=None) + return AlgRunner().runGrassDissolve( + inputLyr, context, feedback=None, column=None, outputLyr=None, onFinish=None + ) - def getVertexNearEdgeDict(self, inputLyr, tol, onlySelected=False, feedback=None, - context=None, algRunner=None, ignoreErrorsOnSameFeat=False): + def getVertexNearEdgeDict( + self, + inputLyr, + tol, + onlySelected=False, + feedback=None, + context=None, + algRunner=None, + ignoreErrorsOnSameFeat=False, + ): """ Identifies vertexes that are too close to a vertex. :param inputLyr: (QgsVectorLayer) layer to run the identification. @@ -1236,31 +1560,32 @@ def getVertexNearEdgeDict(self, inputLyr, tol, onlySelected=False, feedback=None :param feedback (QgsProcessingFeedback) QGIS object to keep track of progress/cancelling option. """ if inputLyr.geometryType() == QgsWkbTypes.PointGeometry: - raise Exception('Vertex near edge not defined for point geometry') + raise Exception("Vertex near edge not defined for point geometry") algRunner = AlgRunner() if algRunner is None else algRunner - context = dataobjects.createContext( - feedback=feedback) if context is None else context + context = ( + dataobjects.createContext(feedback=feedback) if context is None else context + ) multiStepFeedback = QgsProcessingMultiStepFeedback(3, feedback) multiStepFeedback.setCurrentStep(0) - multiStepFeedback.pushInfo(self.tr('Creating index')) - usedInput = inputLyr if not onlySelected else QgsProcessingFeatureSourceDefinition( - inputLyr.id(), True) + multiStepFeedback.pushInfo(self.tr("Creating index")) + usedInput = ( + inputLyr + if not onlySelected + else QgsProcessingFeatureSourceDefinition(inputLyr.id(), True) + ) incrementedLayer = algRunner.runAddAutoIncrementalField( - usedInput, - context, - feedback=multiStepFeedback + usedInput, context, feedback=multiStepFeedback ) multiStepFeedback.setCurrentStep(1) - multiStepFeedback.pushInfo( - self.tr('Building auxiliar search structures')) + multiStepFeedback.pushInfo(self.tr("Building auxiliar search structures")) edgeSpatialIdx, edgeIdDict = self.buildEdgesAuxStructure( incrementedLayer, feedback=multiStepFeedback, algRunner=algRunner, - context=context + context=context, ) multiStepFeedback.setCurrentStep(2) - multiStepFeedback.pushInfo(self.tr('Getting flags')) + multiStepFeedback.pushInfo(self.tr("Getting flags")) vertexNearEdgeFlagDict = self.getVertexNearEdgeFlagDict( incrementedLayer, edgeSpatialIdx, @@ -1269,11 +1594,13 @@ def getVertexNearEdgeDict(self, inputLyr, tol, onlySelected=False, feedback=None feedback=multiStepFeedback, algRunner=algRunner, context=context, - ignoreErrorsOnSameFeat=ignoreErrorsOnSameFeat + ignoreErrorsOnSameFeat=ignoreErrorsOnSameFeat, ) return vertexNearEdgeFlagDict - def buildEdgesAuxStructure(self, inputLyr, algRunner=None, feedback=None, context=None): + def buildEdgesAuxStructure( + self, inputLyr, algRunner=None, feedback=None, context=None + ): """ returns a spatialIndex of lines and a dict of the features :param inputLyr: (QgsVectorLayer) layer to run build the aux structure. @@ -1281,34 +1608,42 @@ def buildEdgesAuxStructure(self, inputLyr, algRunner=None, feedback=None, contex """ nSteps = 3 if inputLyr.geometryType() == QgsWkbTypes.PolygonGeometry else 2 algRunner = AlgRunner() if algRunner is None else algRunner - context = dataobjects.createContext( - feedback=feedback) if context is None else context + context = ( + dataobjects.createContext(feedback=feedback) if context is None else context + ) multiStepFeedback = QgsProcessingMultiStepFeedback(nSteps, feedback) currentStep = 0 multiStepFeedback.setCurrentStep(currentStep) - edgeLyr = inputLyr if inputLyr.geometryType() == QgsWkbTypes.LineGeometry \ + edgeLyr = ( + inputLyr + if inputLyr.geometryType() == QgsWkbTypes.LineGeometry else algRunner.runPolygonsToLines( - inputLyr, - context, - feedback=multiStepFeedback + inputLyr, context, feedback=multiStepFeedback + ) ) currentStep += 1 multiStepFeedback.setCurrentStep(currentStep) explodedEdges = algRunner.runExplodeLines( - edgeLyr, - context, - feedback=multiStepFeedback + edgeLyr, context, feedback=multiStepFeedback ) currentStep += 1 multiStepFeedback.setCurrentStep(currentStep) spatialIdx, idDict = self.buildSpatialIndexAndIdDict( - explodedEdges, - feedback=multiStepFeedback + explodedEdges, feedback=multiStepFeedback ) return spatialIdx, idDict - def getVertexNearEdgeFlagDict(self, inputLyr, edgeSpatialIdx, edgeIdDict, - searchRadius, feedback=None, algRunner=None, context=None, ignoreErrorsOnSameFeat=False): + def getVertexNearEdgeFlagDict( + self, + inputLyr, + edgeSpatialIdx, + edgeIdDict, + searchRadius, + feedback=None, + algRunner=None, + context=None, + ignoreErrorsOnSameFeat=False, + ): """ returns a dict in the following format: {'featid':{ @@ -1318,40 +1653,40 @@ def getVertexNearEdgeFlagDict(self, inputLyr, edgeSpatialIdx, edgeIdDict, } } - } + } :param inputLyr: (QgsVectorLayer) layer to run build the aux structure. :param edgeSpatialIdx: (QgsSpatialIndex) spatial index to perform the search :param edgeIdDict: (dict) dictionary in the format {featid:QgsFeature} :param searchRadius: (float) search radius :param feedback (QgsProcessingFeedback) QGIS object to keep track of progress/cancelling option. """ - flagDict = defaultdict(lambda: defaultdict(lambda: {'edges': set()})) + flagDict = defaultdict(lambda: defaultdict(lambda: {"edges": set()})) algRunner = AlgRunner() if algRunner is None else algRunner - context = dataobjects.createContext( - feedback=feedback) if context is None else context + context = ( + dataobjects.createContext(feedback=feedback) if context is None else context + ) multiStepFeedback = QgsProcessingMultiStepFeedback(2, feedback) # step 1: extract vertexes multiStepFeedback.setCurrentStep(0) vertexLyr = algRunner.runExtractVertices( - inputLyr, - context, - feedback=multiStepFeedback + inputLyr, context, feedback=multiStepFeedback ) # step 2: for each vertex, get the buffer, the buffer BoundingBox and # assess wich edge intersects the buffer. If there is any, this is a flag multiStepFeedback.setCurrentStep(1) iterator, size = self.getFeatureList( - vertexLyr, returnIterator=True, onlySelected=False) + vertexLyr, returnIterator=True, onlySelected=False + ) if size == 0: return {} - stepSize = 100/size + stepSize = 100 / size for current, pointFeat in enumerate(iterator): if multiStepFeedback.isCanceled(): break pointGeom = pointFeat.geometry() buffer = pointGeom.buffer(searchRadius, -1) bufferBB = buffer.boundingBox() - featId = pointFeat['featid'] + featId = pointFeat["featid"] # pointWkt is used as a key because it is unique and hashable pointWkt = pointGeom.asWkt() for candidateId in edgeSpatialIdx.intersects(bufferBB): @@ -1360,18 +1695,29 @@ def getVertexNearEdgeFlagDict(self, inputLyr, edgeSpatialIdx, edgeIdDict, edgeGeom = edgeIdDict[candidateId].geometry() # must ignore search within the same feature and # must be with not adjacent edges - if pointGeom.touches(edgeGeom) or \ - (ignoreErrorsOnSameFeat and featId == edgeIdDict[candidateId]['featid'] and - pointFeat['layer'] == edgeIdDict[candidateId]['layer']): + if pointGeom.touches(edgeGeom) or ( + ignoreErrorsOnSameFeat + and featId == edgeIdDict[candidateId]["featid"] + and pointFeat["layer"] == edgeIdDict[candidateId]["layer"] + ): continue if buffer.intersects(edgeGeom): - flagDict[featId][pointWkt]['flagGeom'] = pointGeom - flagDict[featId][pointWkt]['edges'].add(edgeGeom) + flagDict[featId][pointWkt]["flagGeom"] = pointGeom + flagDict[featId][pointWkt]["edges"].add(edgeGeom) # make progress multiStepFeedback.setProgress(current * stepSize) return flagDict - def getUnsharedVertexOnSharedEdgesDict(self, inputLineLyrList, inputPolygonLyrList, searchRadius, onlySelected=False, feedback=None, context=None, algRunner=None): + def getUnsharedVertexOnSharedEdgesDict( + self, + inputLineLyrList, + inputPolygonLyrList, + searchRadius, + onlySelected=False, + feedback=None, + context=None, + algRunner=None, + ): """ returns a dict in the following format: {'featid':{ @@ -1381,7 +1727,7 @@ def getUnsharedVertexOnSharedEdgesDict(self, inputLineLyrList, inputPolygonLyrLi } } - } + } :param inputLineLyrList: (list of QgsVectorLayers) line layers to run build the aux structure. :param inputPolygonLyrList: (list of QgsVectorLayers) line polygon layers to run build the aux structure. :param searchRadius: (float) search radius @@ -1389,20 +1735,21 @@ def getUnsharedVertexOnSharedEdgesDict(self, inputLineLyrList, inputPolygonLyrLi """ inputList = inputLineLyrList algRunner = AlgRunner() if algRunner is None else algRunner - context = dataobjects.createContext( - feedback=feedback) if context is None else context + context = ( + dataobjects.createContext(feedback=feedback) if context is None else context + ) multiStepFeedback = QgsProcessingMultiStepFeedback(3, feedback) multiStepFeedback.setCurrentStep(0) - multiStepFeedback.pushInfo(self.tr('Getting lines')) + multiStepFeedback.pushInfo(self.tr("Getting lines")) linesLyr = self.getLinesLayerFromPolygonsAndLinesLayers( inputLineLyrList, inputPolygonLyrList, onlySelected=onlySelected, feedback=multiStepFeedback, - context=context + context=context, ) multiStepFeedback.setCurrentStep(1) - multiStepFeedback.pushInfo(self.tr('Building vertex near edge dict')) + multiStepFeedback.pushInfo(self.tr("Building vertex near edge dict")) # only selected should not be filled because it was already used to build the line lyr return self.getVertexNearEdgeDict( linesLyr, @@ -1410,11 +1757,19 @@ def getUnsharedVertexOnSharedEdgesDict(self, inputLineLyrList, inputPolygonLyrLi algRunner=algRunner, feedback=multiStepFeedback, context=context, - ignoreErrorsOnSameFeat=True + ignoreErrorsOnSameFeat=True, ) - def getUnsharedVertexOnIntersections(self, pointLineLyrList, inputLineLyrList, inputPolygonLyrList, - onlySelected=False, feedback=None, context=None, algRunner=None): + def getUnsharedVertexOnIntersections( + self, + pointLineLyrList, + inputLineLyrList, + inputPolygonLyrList, + onlySelected=False, + feedback=None, + context=None, + algRunner=None, + ): """ returns a dict in the following format: { @@ -1422,37 +1777,47 @@ def getUnsharedVertexOnIntersections(self, pointLineLyrList, inputLineLyrList, i 'layer1' : --layer 1 name--', 'layer2' : --layer 2 name--' } - } + } :param inputLineLyrList: (list of QgsVectorLayers) line layers to run build the aux structure. :param inputPolygonLyrList: (list of QgsVectorLayers) line polygon layers to run build the aux structure. :param searchRadius: (float) search radius :param feedback (QgsProcessingFeedback) QGIS object to keep track of progress/cancelling option. """ algRunner = AlgRunner() if algRunner is None else algRunner - context = dataobjects.createContext( - feedback=feedback) if context is None else context + context = ( + dataobjects.createContext(feedback=feedback) if context is None else context + ) stepCount = 6 if pointLineLyrList else 5 multiStepFeedback = QgsProcessingMultiStepFeedback(stepCount, feedback) currentStep = 0 multiStepFeedback.setCurrentStep(currentStep) - multiStepFeedback.pushInfo(self.tr('Getting lines')) + multiStepFeedback.pushInfo(self.tr("Getting lines")) linesLyr = self.getLinesLayerFromPolygonsAndLinesLayers( inputLineLyrList, inputPolygonLyrList, onlySelected=onlySelected, feedback=multiStepFeedback, - context=context + context=context, ) currentStep += 1 multiStepFeedback.setCurrentStep(currentStep) - multiStepFeedback.pushInfo(self.tr('Building point merged layer')) - pointsLyr = algRunner.runMergeVectorLayers(pointLineLyrList, context, feedback=multiStepFeedback) if pointLineLyrList else None + multiStepFeedback.pushInfo(self.tr("Building point merged layer")) + pointsLyr = ( + algRunner.runMergeVectorLayers( + pointLineLyrList, context, feedback=multiStepFeedback + ) + if pointLineLyrList + else None + ) currentStep += 1 if pointsLyr is not None: multiStepFeedback.setCurrentStep(currentStep) pointsLyr = algRunner.runMultipartToSingleParts( - inputLayer=pointsLyr, context=context, feedback=multiStepFeedback, outputLyr='TEMPORARY_OUTPUT' + inputLayer=pointsLyr, + context=context, + feedback=multiStepFeedback, + outputLyr="TEMPORARY_OUTPUT", ) pointsSet = set([i for i in pointsLyr.getFeatures()]) currentStep += 1 @@ -1460,43 +1825,42 @@ def getUnsharedVertexOnIntersections(self, pointLineLyrList, inputLineLyrList, i pointsSet = set() multiStepFeedback.setCurrentStep(currentStep) - multiStepFeedback.pushInfo(self.tr('Building intersections')) + multiStepFeedback.pushInfo(self.tr("Building intersections")) intersectionLyr = algRunner.runLineIntersections( - linesLyr, - linesLyr, - feedback=multiStepFeedback, - context=context + linesLyr, linesLyr, feedback=multiStepFeedback, context=context ) currentStep += 1 multiStepFeedback.setCurrentStep(currentStep) - multiStepFeedback.pushInfo(self.tr('Finding vertexes')) + multiStepFeedback.pushInfo(self.tr("Finding vertexes")) vertexLyr = algRunner.runExtractVertices( - linesLyr, - feedback=multiStepFeedback, - context=context + linesLyr, feedback=multiStepFeedback, context=context ) currentStep += 1 multiStepFeedback.setCurrentStep(currentStep) - multiStepFeedback.pushInfo(self.tr('Finding unshared vertexes')) + multiStepFeedback.pushInfo(self.tr("Finding unshared vertexes")) intersectionDict = { feat.geometry().asWkb(): feat for feat in intersectionLyr.getFeatures() } unsharedPointsSet = self.getUnsharedPointsSetFromPointsLyr( - algRunner, pointsSet, linesLyr, context, multiStepFeedback) - vertexSet = set( - feat.geometry().asWkb() for feat in vertexLyr.getFeatures() + algRunner, pointsSet, linesLyr, context, multiStepFeedback ) - return set(intersectionDict.keys()).difference(vertexSet) | unsharedPointsSet.difference(vertexSet) - - def getUnsharedPointsSetFromPointsLyr(self, algRunner, pointsSet, linesLyr, context, feedback): + vertexSet = set(feat.geometry().asWkb() for feat in vertexLyr.getFeatures()) + return set(intersectionDict.keys()).difference( + vertexSet + ) | unsharedPointsSet.difference(vertexSet) + + def getUnsharedPointsSetFromPointsLyr( + self, algRunner, pointsSet, linesLyr, context, feedback + ): if pointsSet == set(): return set() multiStepFeedback = QgsProcessingMultiStepFeedback(2, feedback) multiStepFeedback.setCurrentStep(0) algRunner.runCreateSpatialIndex(linesLyr, context, feedback=multiStepFeedback) multiStepFeedback.setCurrentStep(1) + def compute(feat): geom = feat.geometry() geomWkb = geom.asWkb() @@ -1511,7 +1875,8 @@ def compute(feat): if geom.equals(v): return geomWkb return None - pool = concurrent.futures.ThreadPoolExecutor(max_workers=os.cpu_count()-1) + + pool = concurrent.futures.ThreadPoolExecutor(max_workers=os.cpu_count() - 1) futures = set() vertexSet = set() for feat in pointsSet: @@ -1520,13 +1885,21 @@ def compute(feat): # if result is not None: # vertexSet.add(result) vertexSet = set( - future.result() for future in concurrent.futures.as_completed( - futures - ) if future.result() is not None + future.result() + for future in concurrent.futures.as_completed(futures) + if future.result() is not None ) return vertexSet - def getLinesLayerFromPolygonsAndLinesLayers(self, inputLineLyrList, inputPolygonLyrList, algRunner=None, onlySelected=False, feedback=None, context=None): + def getLinesLayerFromPolygonsAndLinesLayers( + self, + inputLineLyrList, + inputPolygonLyrList, + algRunner=None, + onlySelected=False, + feedback=None, + context=None, + ): """ returns a merged line lyr :param inputLineLyrList: (list of QgsVectorLayers) line layers to run build the aux structure. @@ -1535,49 +1908,52 @@ def getLinesLayerFromPolygonsAndLinesLayers(self, inputLineLyrList, inputPolygon """ lineList = [] algRunner = AlgRunner() if algRunner is None else algRunner - context = dataobjects.createContext( - feedback=feedback) if context is None else context - nSteps = 2*len(inputLineLyrList) + 3*len(inputPolygonLyrList) + 1 + context = ( + dataobjects.createContext(feedback=feedback) if context is None else context + ) + nSteps = 2 * len(inputLineLyrList) + 3 * len(inputPolygonLyrList) + 1 multiStepFeedback = QgsProcessingMultiStepFeedback( - nSteps, feedback) # set number of steps + nSteps, feedback + ) # set number of steps currentStep = 0 - multiStepFeedback.pushInfo(self.tr('Converting lines to single part and exploding lines')) + multiStepFeedback.pushInfo( + self.tr("Converting lines to single part and exploding lines") + ) for lineLyr in inputLineLyrList: multiStepFeedback.setCurrentStep(currentStep) singlePartLyr = algRunner.runMultipartToSingleParts( - inputLayer=lineLyr if not onlySelected \ + inputLayer=lineLyr + if not onlySelected else QgsProcessingFeatureSourceDefinition(lineLyr.id(), True), context=context, feedback=multiStepFeedback, - is_child_algorithm=True + is_child_algorithm=True, ) currentStep += 1 explodedLines = algRunner.runExplodeLines( singlePartLyr, context, feedback=multiStepFeedback, - is_child_algorithm=True - ) - lineList.append( - explodedLines + is_child_algorithm=True, ) + lineList.append(explodedLines) currentStep += 1 - multiStepFeedback.pushInfo(self.tr('Converting polygons to single part and exploding lines')) + multiStepFeedback.pushInfo( + self.tr("Converting polygons to single part and exploding lines") + ) for polygonLyr in inputPolygonLyrList: multiStepFeedback.setCurrentStep(currentStep) usedInput = algRunner.runMultipartToSingleParts( - inputLayer=polygonLyr if not onlySelected \ + inputLayer=polygonLyr + if not onlySelected else QgsProcessingFeatureSourceDefinition(polygonLyr.id(), True), context=context, feedback=multiStepFeedback, - is_child_algorithm=True + is_child_algorithm=True, ) currentStep += 1 convertedPolygons = algRunner.runPolygonsToLines( - usedInput, - context, - feedback=multiStepFeedback, - is_child_algorithm=True + usedInput, context, feedback=multiStepFeedback, is_child_algorithm=True ) currentStep += 1 multiStepFeedback.setCurrentStep(currentStep) @@ -1585,17 +1961,21 @@ def getLinesLayerFromPolygonsAndLinesLayers(self, inputLineLyrList, inputPolygon convertedPolygons, context, feedback=multiStepFeedback, - is_child_algorithm=True + is_child_algorithm=True, ) currentStep += 1 lineList.append(explodedLines) # merge layers multiStepFeedback.setCurrentStep(currentStep) - multiStepFeedback.pushInfo(self.tr('Adding exploded lines to one single layer.')) - mergedLayer = algRunner.runMergeVectorLayers( - lineList, - context, - feedback=multiStepFeedback + multiStepFeedback.pushInfo( + self.tr("Adding exploded lines to one single layer.") + ) + mergedLayer = ( + algRunner.runMergeVectorLayers( + lineList, context, feedback=multiStepFeedback + ) + if lineList != [] + else None ) return mergedLayer @@ -1610,7 +1990,14 @@ def reprojectLayer(self, layer, targetEpsg, output=None): """ return AlgRunner().runReprojectLayer(layer, targetEpsg, output) - def getMergedLayer(self, inputLayerList, onlySelected=False, feedback=None, context=None, algRunner=None): + def getMergedLayer( + self, + inputLayerList, + onlySelected=False, + feedback=None, + context=None, + algRunner=None, + ): """ This does almost the same of createAndPopulateUnifiedVectorLayer, but it is much faster. Maybe the implementation of createAndPopulateUnifiedVectorLayer @@ -1618,77 +2005,84 @@ def getMergedLayer(self, inputLayerList, onlySelected=False, feedback=None, cont """ lyrList = [] algRunner = AlgRunner() if algRunner is None else algRunner - context = dataobjects.createContext( - feedback=feedback) if context is None else context + context = ( + dataobjects.createContext(feedback=feedback) if context is None else context + ) nSteps = len(inputLayerList) + 1 multiStepFeedback = QgsProcessingMultiStepFeedback( - nSteps, feedback) # set number of steps + nSteps, feedback + ) # set number of steps currentStep = 0 for lyr in inputLayerList: multiStepFeedback.setCurrentStep(currentStep) lyrList.append( - lyr if not onlySelected else algRunner.runSaveSelectedFeatures( - lineLyr, - context, - feedback=multiStepFeedback + lyr + if not onlySelected + else algRunner.runSaveSelectedFeatures( + lyr, context, feedback=multiStepFeedback ) ) currentStep += 1 multiStepFeedback.setCurrentStep(currentStep) return algRunner.runMergeVectorLayers( - lyrList, - context, - feedback=multiStepFeedback + lyrList, context, feedback=multiStepFeedback ) - def getCentroidsAndBoundariesFromPolygons(self, inputLyr, outputCenterPointSink, outputBoundarySink, - constraintLineLyrList=None, constraintPolygonLyrList=None, context=None, feedback=None, algRunner=None): + def getCentroidsAndBoundariesFromPolygons( + self, + inputLyr, + outputCenterPointSink, + outputBoundarySink, + constraintLineLyrList=None, + constraintPolygonLyrList=None, + context=None, + feedback=None, + algRunner=None, + ): """ FILL out """ - constraintLineLyrList = [] if constraintLineLyrList is None else constraintLineLyrList - constraintPolygonLyrList = [ - ] if constraintPolygonLyrList is None else constraintPolygonLyrList + constraintLineLyrList = ( + [] if constraintLineLyrList is None else constraintLineLyrList + ) + constraintPolygonLyrList = ( + [] if constraintPolygonLyrList is None else constraintPolygonLyrList + ) algRunner = AlgRunner() if algRunner is None else algRunner - context = dataobjects.createContext( - feedback=feedback) if context is None else context - multiStepFeedback = QgsProcessingMultiStepFeedback(7, feedback) + context = ( + dataobjects.createContext(feedback=feedback) if context is None else context + ) + multiStepFeedback = QgsProcessingMultiStepFeedback(8, feedback) multiStepFeedback.setCurrentStep(0) - multiStepFeedback.pushInfo(self.tr('Getting constraint lines')) + multiStepFeedback.pushInfo(self.tr("Getting constraint lines")) linesLyr = self.getLinesLayerFromPolygonsAndLinesLayers( constraintLineLyrList, constraintPolygonLyrList, onlySelected=False, feedback=multiStepFeedback, context=context, - algRunner=algRunner + algRunner=algRunner, ) multiStepFeedback.setCurrentStep(1) - multiStepFeedback.pushInfo( - self.tr('Building auxiliar search structures')) + multiStepFeedback.pushInfo(self.tr("Building auxiliar search structures")) constraintSpatialIdx, constraintIdDict = self.buildSpatialIndexAndIdDict( - linesLyr, - feedback=multiStepFeedback + linesLyr, feedback=multiStepFeedback ) multiStepFeedback.setCurrentStep(2) edgeLyr = algRunner.runPolygonsToLines( - inputLyr, - context, - feedback=multiStepFeedback + inputLyr, context, feedback=multiStepFeedback ) multiStepFeedback.setCurrentStep(3) + algRunner.runCreateSpatialIndex(edgeLyr, context, feedback=multiStepFeedback) + multiStepFeedback.setCurrentStep(4) explodedEdges = algRunner.runExplodeLines( - edgeLyr, - context, - feedback=multiStepFeedback + edgeLyr, context, feedback=multiStepFeedback ) - multiStepFeedback.setCurrentStep(4) + multiStepFeedback.setCurrentStep(5) explodedWithoutDuplicates = algRunner.runRemoveDuplicatedGeometries( - explodedEdges, - context, - feedback=multiStepFeedback + explodedEdges, context, feedback=multiStepFeedback ) - multiStepFeedback.setCurrentStep(5) + multiStepFeedback.setCurrentStep(6) self.buildCenterPoints( inputLyr, outputCenterPointSink, @@ -1696,104 +2090,231 @@ def getCentroidsAndBoundariesFromPolygons(self, inputLyr, outputCenterPointSink, linesLyr, feedback=multiStepFeedback, context=context, - algRunner=algRunner + algRunner=algRunner, ) - multiStepFeedback.setCurrentStep(6) + multiStepFeedback.setCurrentStep(7) self.filterEdges( explodedWithoutDuplicates, constraintSpatialIdx, constraintIdDict, outputBoundarySink, feedback=multiStepFeedback, - context=context + context=context, ) - def buildCenterPoints(self, inputLyr, outputCenterPointSink, polygonBoundaryLyr, - constraintLineLyr=None, context=None, feedback=None, algRunner=None): - """ - - """ + def buildCenterPoints( + self, + inputLyr, + outputCenterPointSink, + context=None, + feedback=None, + algRunner=None, + ): + """ """ # 1- Merge line layers # 2- Build polygons # 3- Get center points from built polygons # 4- Make spatial join of center points with original polygons to get attributes algRunner = AlgRunner() if algRunner is None else algRunner - context = dataobjects.createContext( - feedback=feedback) if context is None else context - multiStepFeedback = QgsProcessingMultiStepFeedback(6, feedback) - multiStepFeedback.setCurrentStep(0) - mergedLineLyr = polygonBoundaryLyr if constraintLineLyr is None\ - else algRunner.runMergeVectorLayers( - [polygonBoundaryLyr, constraintLineLyr], - context, - feedback=multiStepFeedback - ) - multiStepFeedback.setCurrentStep(1) - splitSegmentsLyr = algRunner.runExplodeLines( - mergedLineLyr, - context, - feedback=multiStepFeedback + context = ( + dataobjects.createContext(feedback=feedback) if context is None else context ) - multiStepFeedback.setCurrentStep(2) - segmentsWithoutDuplicates = algRunner.runRemoveDuplicatedGeometries( - splitSegmentsLyr, - context, - feedback=multiStepFeedback - ) - multiStepFeedback.setCurrentStep(3) + multiStepFeedback = QgsProcessingMultiStepFeedback(3, feedback) + multiStepFeedback.setCurrentStep(0) outputPolygonLyr = algRunner.runPolygonize( - segmentsWithoutDuplicates, - context, - feedback=multiStepFeedback + inputLyr, context, feedback=multiStepFeedback ) - multiStepFeedback.setCurrentStep(4) + multiStepFeedback.setCurrentStep(1) centroidLyr = algRunner.runPointOnSurface( - outputPolygonLyr, - context, - feedback=multiStepFeedback + outputPolygonLyr, context, feedback=multiStepFeedback ) - multiStepFeedback.setCurrentStep(5) + multiStepFeedback.setCurrentStep(2) centroidsWithAttributes = algRunner.runJoinAttributesByLocation( - centroidLyr, - inputLyr, - context, - feedback=multiStepFeedback + centroidLyr, inputLyr, context, feedback=multiStepFeedback ) for feat in centroidsWithAttributes.getFeatures(): outputCenterPointSink.addFeature(feat, QgsFeatureSink.FastInsert) - def filterEdges(self, inputLyr, constraintSpatialIdx, constraintIdDict, - outputBoundarySink, context=None, feedback=None, algRunner=None): - """ - """ + def filterEdges( + self, + inputLyr, + constraintSpatialIdx, + constraintIdDict, + outputBoundarySink, + context=None, + feedback=None, + algRunner=None, + ): + """ """ notBoundarySet = set() - stepSize = 100/inputLyr.featureCount() - featList = [i for i in inputLyr.getFeatures()] - for current, feat in enumerate(featList): - if feedback is not None and feedback.isCanceled(): - break + nFeats = inputLyr.featureCount() + if nFeats == 0: + return + stepSize = 100 / nFeats + pool = concurrent.futures.ThreadPoolExecutor(max_workers=os.cpu_count() - 1) + futures = set() + + def evaluate(feat): + outputSet = set() featGeom = feat.geometry() featBB = featGeom.boundingBox() for candidateId in constraintSpatialIdx.intersects(featBB): if featGeom.within(constraintIdDict[candidateId].geometry()): - notBoundarySet.add(feat) - break - if feedback is not None: - feedback.setProgress(current*stepSize) - for feat in featList: - if feat not in notBoundarySet: + outputSet.add(feat) + return outputSet + return outputSet + + multiStepFeedback = ( + QgsProcessingMultiStepFeedback(2, feedback) + if feedback is not None + else None + ) + if multiStepFeedback is not None: + multiStepFeedback.setCurrentStep(0) + multiStepFeedback.setProgressText(self.tr("Submitting tasks to thread")) + + for current, feat in enumerate(inputLyr.getFeatures()): + if multiStepFeedback is not None and multiStepFeedback.isCanceled(): + break + futures.add(pool.submit(evaluate, feat)) + if multiStepFeedback is not None: + multiStepFeedback.setProgress(current * stepSize) + if multiStepFeedback is not None: + multiStepFeedback.setCurrentStep(1) + multiStepFeedback.setProgressText(self.tr("Evaluating results")) + for current, future in enumerate(concurrent.futures.as_completed(futures)): + outputSet = future.result() + if outputSet == {}: + continue + for feat in outputSet: + if feat in notBoundarySet: + continue outputBoundarySink.addFeature(feat, QgsFeatureSink.FastInsert) + if multiStepFeedback is not None: + multiStepFeedback.setProgress(current * stepSize) + + def getPolygonsFromCenterPointsAndBoundariesAlt( + self, + inputCenterPointLyr, + constraintLineLyrList=None, + constraintPolygonLyrList=None, + attributeBlackList=None, + geographicBoundaryLyr=None, + onlySelected=False, + suppressPolygonWithoutCenterPointFlag=False, + context=None, + feedback=None, + algRunner=None, + ): + algRunner = AlgRunner() if algRunner is None else algRunner + constraintLineLyrList = ( + [] if constraintLineLyrList is None else constraintLineLyrList + ) + constraintPolygonList = ( + [] if constraintPolygonLyrList is None else constraintPolygonLyrList + ) + attributeBlackList = [] if attributeBlackList is None else attributeBlackList + constraintPolygonListWithGeoBounds = ( + constraintPolygonList + [geographicBoundaryLyr] + if geographicBoundaryLyr is not None + else constraintPolygonList + ) + multiStepFeedback = ( + QgsProcessingMultiStepFeedback(8, feedback) + if feedback is not None + else None + ) + currentStep = 0 + if multiStepFeedback is not None: + multiStepFeedback.setProgressText(self.tr("Merging all into one layer...")) + if multiStepFeedback is not None: + multiStepFeedback.setCurrentStep(currentStep) + constraintPolygonsAsPolygonsLyr = ( + algRunner.runMergeVectorLayers( + inputList=constraintPolygonListWithGeoBounds, + context=context, + feedback=multiStepFeedback, + ) + if len(constraintPolygonListWithGeoBounds) > 0 + else None + ) + currentStep += 1 + constraintPolygonsAsLinesLyr = ( + algRunner.runPolygonsToLines( + inputLyr=constraintPolygonsAsPolygonsLyr, + context=context, + feedback=multiStepFeedback, + ) + if constraintPolygonsAsPolygonsLyr is not None + else None + ) + if multiStepFeedback is not None: + multiStepFeedback.setCurrentStep(currentStep) + allLinesLyr = algRunner.runMergeVectorLayers( + inputList=constraintLineLyrList + [constraintPolygonsAsLinesLyr] + if constraintPolygonsAsLinesLyr is not None + else constraintLineLyrList, + context=context, + feedback=multiStepFeedback, + ) + currentStep += 1 + if multiStepFeedback is not None: + multiStepFeedback.setCurrentStep(currentStep) + multiStepFeedback.setProgressText(self.tr("Exploding lines...")) + explodedLines = algRunner.runExplodeLines( + inputLyr=allLinesLyr, context=context, feedback=multiStepFeedback + ) + if multiStepFeedback is not None: + multiStepFeedback.setCurrentStep(currentStep) + algRunner.runCreateSpatialIndex(explodedLines, context, multiStepFeedback) + currentStep += 1 + if multiStepFeedback is not None: + multiStepFeedback.setCurrentStep(currentStep) + multiStepFeedback.setProgressText(self.tr("Splitting lines...")) + splitLines = algRunner.runSplitLinesWithLines( + inputLyr=explodedLines, + linesLyr=explodedLines, + context=context, + feedback=multiStepFeedback, + ) + if multiStepFeedback is not None: + multiStepFeedback.setCurrentStep(currentStep) + multiStepFeedback.setProgressText( + self.tr("Starting the process of building polygons...") + ) + builtPolygonLyr = algRunner.runPolygonize( + splitLines, context, feedback=multiStepFeedback + ) + currentStep += 1 + if multiStepFeedback is not None: + multiStepFeedback.setCurrentStep(currentStep) + multiStepFeedback.setProgressText( + self.tr("Relating center points with built polygons...") + ) + return self.relateCenterPointsWithPolygons( + inputCenterPointLyr, + builtPolygonLyr, + constraintPolygonList=constraintPolygonList, + geomBoundary=geographicBoundaryLyr, + attributeBlackList=attributeBlackList, + suppressPolygonWithoutCenterPointFlag=suppressPolygonWithoutCenterPointFlag, + context=context, + feedback=multiStepFeedback, + ) - def getPolygonsFromCenterPointsAndBoundaries(self, inputCenterPointLyr, - constraintLineLyrList=None, - constraintPolygonLyrList=None, - attributeBlackList=None, - geographicBoundaryLyr=None, - onlySelected=False, - suppressPolygonWithoutCenterPointFlag=False, - context=None, - feedback=None, - algRunner=None): + def getPolygonsFromCenterPointsAndBoundaries( + self, + inputCenterPointLyr, + constraintLineLyrList=None, + constraintPolygonLyrList=None, + attributeBlackList=None, + geographicBoundaryLyr=None, + onlySelected=False, + suppressPolygonWithoutCenterPointFlag=False, + context=None, + feedback=None, + algRunner=None, + ): """ 1. Merge Polygon lyrs into one and coerce polygons to lines @@ -1813,12 +2334,13 @@ def getPolygonsFromCenterPointsAndBoundaries(self, inputCenterPointLyr, :return polygonList, flagList: list of polygons (QgsFeature) """ algRunner = AlgRunner() if algRunner is None else algRunner - constraintLineLyrList = [] if constraintLineLyrList is None else \ - constraintLineLyrList - constraintPolygonList = [] if constraintPolygonLyrList is None else \ - constraintPolygonLyrList - attributeBlackList = [] if attributeBlackList is None else \ - attributeBlackList + constraintLineLyrList = ( + [] if constraintLineLyrList is None else constraintLineLyrList + ) + constraintPolygonList = ( + [] if constraintPolygonLyrList is None else constraintPolygonLyrList + ) + attributeBlackList = [] if attributeBlackList is None else attributeBlackList # Clip Points, Lines and Polygons according to geographicBoundaryLyr # Buffer because sometimes the line stops before the boundary itself, # making the whole algorithmn not work properly @@ -1828,28 +2350,30 @@ def getPolygonsFromCenterPointsAndBoundaries(self, inputCenterPointLyr, # for camada in constraintLineLyrList] # constraintPolygonList = [algRunner.runClip(camada, limit, context) # for camada in constraintPolygonLyrList] - # inputCenterPointLyr = algRunner.runClip(inputCenterPointLyr, limit, + # inputCenterPointLyr = algRunner.runClip(inputCenterPointLyr, limit, # context) - constraintPolygonListWithGeoBounds = constraintPolygonList + \ - [geographicBoundaryLyr] if geographicBoundaryLyr is not None else \ - constraintPolygonList - multiStepFeedback = QgsProcessingMultiStepFeedback(7, feedback) + constraintPolygonListWithGeoBounds = ( + constraintPolygonList + [geographicBoundaryLyr] + if geographicBoundaryLyr is not None + else constraintPolygonList + ) + multiStepFeedback = QgsProcessingMultiStepFeedback(8, feedback) # 1. Merge Polygon lyrs into one currentStep = 0 multiStepFeedback.setCurrentStep(currentStep) - multiStepFeedback.setProgressText(self.tr('Getting constraint lines...')) + multiStepFeedback.setProgressText(self.tr("Getting constraint lines...")) linesLyr = self.getLinesLayerFromPolygonsAndLinesLayers( constraintLineLyrList, - constraintPolygonListWithGeoBounds, + constraintPolygonListWithGeoBounds, onlySelected=onlySelected, feedback=multiStepFeedback, context=context, - algRunner=algRunner + algRunner=algRunner, ) currentStep += 1 multiStepFeedback.setCurrentStep(currentStep) - multiStepFeedback.setProgressText(self.tr('Exploding lines...')) + multiStepFeedback.setProgressText(self.tr("Exploding lines...")) algRunner.runCreateSpatialIndex(linesLyr, context, feedback=multiStepFeedback) currentStep += 1 @@ -1858,60 +2382,62 @@ def getPolygonsFromCenterPointsAndBoundaries(self, inputCenterPointLyr, inputLyr=linesLyr, linesLyr=linesLyr, context=context, - feedback=multiStepFeedback + feedback=multiStepFeedback, ) currentStep += 1 multiStepFeedback.setCurrentStep(currentStep) splitSegmentsLyr = algRunner.runExplodeLines( - linesLyr, - context, - feedback=multiStepFeedback + linesLyr, context, feedback=multiStepFeedback ) currentStep += 1 multiStepFeedback.setCurrentStep(currentStep) - multiStepFeedback.setProgressText(self.tr('Removing duplicated features...')) + multiStepFeedback.setProgressText(self.tr("Removing duplicated features...")) segmentsWithoutDuplicates = algRunner.runRemoveDuplicatedGeometries( - splitSegmentsLyr, - context, - feedback=multiStepFeedback + splitSegmentsLyr, context, feedback=multiStepFeedback ) currentStep += 1 multiStepFeedback.setCurrentStep(currentStep) - multiStepFeedback.setProgressText(self.tr('Starting the process of building polygons...')) + multiStepFeedback.setProgressText( + self.tr("Starting the process of building polygons...") + ) builtPolygonLyr = algRunner.runPolygonize( - segmentsWithoutDuplicates, - context, - feedback=multiStepFeedback + segmentsWithoutDuplicates, context, feedback=multiStepFeedback ) currentStep += 1 multiStepFeedback.setCurrentStep(currentStep) - multiStepFeedback.setProgressText(self.tr('Relating center points with built polygons...')) + multiStepFeedback.setProgressText( + self.tr("Relating center points with built polygons...") + ) return self.relateCenterPointsWithPolygons( inputCenterPointLyr, builtPolygonLyr, constraintPolygonList=constraintPolygonList, - geomBoundary = geographicBoundaryLyr, + geomBoundary=geographicBoundaryLyr, attributeBlackList=attributeBlackList, suppressPolygonWithoutCenterPointFlag=suppressPolygonWithoutCenterPointFlag, context=context, - feedback=multiStepFeedback + feedback=multiStepFeedback, ) - def relateCenterPointsWithPolygons(self,inputCenterPointLyr, - builtPolygonLyr,context=None, - constraintPolygonList=None, - attributeBlackList=None, - geomBoundary=None, - suppressPolygonWithoutCenterPointFlag=False, - feedback=None): + def relateCenterPointsWithPolygons( + self, + inputCenterPointLyr, + builtPolygonLyr, + context=None, + constraintPolygonList=None, + attributeBlackList=None, + geomBoundary=None, + suppressPolygonWithoutCenterPointFlag=False, + feedback=None, + ): """ 1. Merge constraint polygon list; 2. Build search structure into constraint polygon list 3. Build structure relating center points to built polygons 4. Get built polygons with attributes and flags - :params inputCenterPointLyr: (QgsVectorLayer) with Point which you + :params inputCenterPointLyr: (QgsVectorLayer) with Point which you want to take the attr :params builtPolygonLyr: (QgsVectorLayer) with the polygons :params constraintPolygonList: (list) with the polygons, which area @@ -1921,55 +2447,70 @@ def relateCenterPointsWithPolygons(self,inputCenterPointLyr, :return polygonList, flagList: list of polygons (QgsFeature) """ nSteps = 4 if constraintPolygonList else 2 - multiStepFeedback = QgsProcessingMultiStepFeedback(nSteps, feedback) + multiStepFeedback = ( + QgsProcessingMultiStepFeedback(nSteps, feedback) + if feedback is not None + else None + ) currentStep = 0 - multiStepFeedback.setCurrentStep(currentStep) - - # If there were no polygon list, it was breaking the method. - # tried to solve it with this if else + algRunner = AlgRunner() + if multiStepFeedback is not None: + multiStepFeedback.setCurrentStep(currentStep) + + # If there were no polygon list, it was breaking the method. + # tried to solve it with this if else if constraintPolygonList: - constraintPolygonLyr = self.algRunner.runMergeVectorLayers( - constraintPolygonList, - context, - feedback=multiStepFeedback + constraintPolygonLyr = algRunner.runMergeVectorLayers( + constraintPolygonList, context, feedback=multiStepFeedback ) currentStep += 1 - multiStepFeedback.setCurrentStep(currentStep) - constraintPolygonLyrSpatialIdx, constraintPolygonLyrIdDict = \ - self.buildSpatialIndexAndIdDict( - constraintPolygonLyr, - feedback=multiStepFeedback + if multiStepFeedback is not None: + multiStepFeedback.setCurrentStep(currentStep) + ( + constraintPolygonLyrSpatialIdx, + constraintPolygonLyrIdDict, + ) = self.buildSpatialIndexAndIdDict( + constraintPolygonLyr, feedback=multiStepFeedback ) currentStep += 1 - else: - constraintPolygonLyrSpatialIdx, constraintPolygonLyrIdDict = \ - QgsSpatialIndex(), {} - multiStepFeedback.setCurrentStep(currentStep) + else: + constraintPolygonLyrSpatialIdx, constraintPolygonLyrIdDict = ( + QgsSpatialIndex(), + {}, + ) + if multiStepFeedback is not None: + multiStepFeedback.setCurrentStep(currentStep) builtPolygonToCenterPointDict = self.buildCenterPolygonToCenterPointDict( inputCenterPointLyr, builtPolygonLyr, attributeBlackList, - feedback=multiStepFeedback + feedback=multiStepFeedback, ) currentStep += 1 - multiStepFeedback.setCurrentStep(currentStep) - polygonList, flagList = \ - self.getPolygonListAndFlagDictFromBuiltPolygonToCenterPointDict( + if multiStepFeedback is not None: + multiStepFeedback.setCurrentStep(currentStep) + ( + polygonList, + flagList, + ) = self.getPolygonListAndFlagDictFromBuiltPolygonToCenterPointDict( builtPolygonToCenterPointDict, constraintPolygonLyrSpatialIdx, constraintPolygonLyrIdDict, - geomBoundary = geomBoundary, + geomBoundary=geomBoundary, suppressPolygonWithoutCenterPointFlag=suppressPolygonWithoutCenterPointFlag, - feedback=multiStepFeedback + feedback=multiStepFeedback, ) return polygonList, flagList - def buildCenterPolygonToCenterPointDict(self, inputCenterPointLyr, - builtPolygonLyr, - attributeBlackList=None, - feedback=None): + def buildCenterPolygonToCenterPointDict( + self, + inputCenterPointLyr, + builtPolygonLyr, + attributeBlackList=None, + feedback=None, + ): """ - + :params inputCenterPointLyr: (QgsVectorLayer) with Point which you want to take the attr :params builtPolygonLyr: (QgsVectorLayer) with the polygons @@ -1982,13 +2523,14 @@ def buildCenterPolygonToCenterPointDict(self, inputCenterPointLyr, } """ builtPolygonToCenterPointDict = dict() - iterator, featCount = self.getFeatureList( - builtPolygonLyr, onlySelected=False) - size = 100/featCount if featCount else 0 + iterator, featCount = self.getFeatureList(builtPolygonLyr, onlySelected=False) + size = 100 / featCount if featCount else 0 columns = self.getAttributesFromBlackList( - inputCenterPointLyr, attributeBlackList=attributeBlackList) + inputCenterPointLyr, attributeBlackList=attributeBlackList + ) fields = self.getFieldsFromAttributeBlackList( - inputCenterPointLyr, attributeBlackList) + inputCenterPointLyr, attributeBlackList + ) for current, feat in enumerate(builtPolygonLyr.getFeatures()): if feedback is not None and feedback.isCanceled(): break @@ -2001,11 +2543,11 @@ def buildCenterPolygonToCenterPointDict(self, inputCenterPointLyr, request = QgsFeatureRequest().setFilterRect(featBB) engine = QgsGeometry.createGeometryEngine(featGeom.constGet()) engine.prepareGeometry() - + # for each point inside the polygon, extract attrkey and attr - # attrkey is basically attr but in an string. therefore, if + # attrkey is basically attr but in an string. therefore, if # if there two point with different attr, it will make two columns - # with two attrkey different + # with two attrkey different for pointFeat in inputCenterPointLyr.getFeatures(request): if feedback is not None and feedback.isCanceled(): break @@ -2019,18 +2561,16 @@ def buildCenterPolygonToCenterPointDict(self, inputCenterPointLyr, feedback.setCurrentStep(current * size) return builtPolygonToCenterPointDict - def getFieldsFromAttributeBlackList(self, originalLayer, - attributeBlackList): + def getFieldsFromAttributeBlackList(self, originalLayer, attributeBlackList): """ Create a QgsFields with only columns that are not at attributeBlackList :params originalLayer: Layer from where will be taken the fields - :params attributeBlackList: (list) which attr/fields should not + :params attributeBlackList: (list) which attr/fields should not be considered - :return fields: (QgsFields) with the fields necessary + :return fields: (QgsFields) with the fields necessary """ columns = self.getAttributesFromBlackList( - originalLayer, - attributeBlackList=attributeBlackList + originalLayer, attributeBlackList=attributeBlackList ) fields = QgsFields() for f in originalLayer.fields(): @@ -2046,15 +2586,19 @@ def getListIndexFromFields(self, originalLayer, columns): :return listColumnAttr: (list) list of indexes """ listColumnAttr = [] - for column in columns: - listColumnAttr.append(originalLayer.fields()\ - .indexFromName(column)) + for column in columns: + listColumnAttr.append(originalLayer.fields().indexFromName(column)) return listColumnAttr def getPolygonListAndFlagDictFromBuiltPolygonToCenterPointDict( - self, builtPolygonToCenterPointDict, - constraintPolygonLyrSpatialIdx, constraintPolygonLyrIdDict, - geomBoundary=False, suppressPolygonWithoutCenterPointFlag=True, feedback=None): + self, + builtPolygonToCenterPointDict, + constraintPolygonLyrSpatialIdx, + constraintPolygonLyrIdDict, + geomBoundary=False, + suppressPolygonWithoutCenterPointFlag=True, + feedback=None, + ): """ :params builtPolygonToCenterPointDict: (dict) in the following format: { @@ -2062,17 +2606,17 @@ def getPolygonListAndFlagDictFromBuiltPolygonToCenterPointDict( (attrKey) : [--QgsFields--] } } - :params constraintPolygonLyrSpatialIdx :QgsSpatialIndex() of the + :params constraintPolygonLyrSpatialIdx :QgsSpatialIndex() of the constraint polygons - :params constraintPolygonLyrIdDict: + :params constraintPolygonLyrIdDict: :params geomBoundary: (QgsVectorLayer) which delimitates the processing :return polygonList, flagList: *list) of polygons (QgsFeature) """ keyCount = len(builtPolygonToCenterPointDict) - size = 100/keyCount if keyCount else 0 + size = 100 / keyCount if keyCount else 0 polygonList = [] flagDict = dict() - # Create a list with geomBoundary polygons geometry + # Create a list with geomBoundary polygons geometry if geomBoundary: geoms = [f.geometry() for f in geomBoundary.getFeatures()] for current, geomKey in enumerate(builtPolygonToCenterPointDict): @@ -2085,15 +2629,14 @@ def getPolygonListAndFlagDictFromBuiltPolygonToCenterPointDict( pointOnSurfaceGeom = geom.pointOnSurface() # only situation when boundary makes a difference is when it is # provided and the polygon is not within any of its polygons - isOffBoundary = geomBoundary is not None \ - and not any( - (pointOnSurfaceGeom.intersects(boundaryGeom) \ - for boundaryGeom in geoms) - ) + isOffBoundary = geomBoundary is not None and not any( + (pointOnSurfaceGeom.intersects(boundaryGeom) for boundaryGeom in geoms) + ) if isOffBoundary: continue for candidateId in constraintPolygonLyrSpatialIdx.intersects( - geom.boundingBox()): + geom.boundingBox() + ): # this loop is broken by either user canceling it or built # polygon overlapping any of the polygon constraints, which # means that it will have its geometry ignored on the next @@ -2103,15 +2646,16 @@ def getPolygonListAndFlagDictFromBuiltPolygonToCenterPointDict( break isNotFlag = geomKey not in flagDict isConstraintPol = pointOnSurfaceGeom.intersects( - constraintPolygonLyrIdDict[candidateId].geometry()) + constraintPolygonLyrIdDict[candidateId].geometry() + ) if isNotFlag and isConstraintPol: break else: - # because builtPolygonToCenterPointDict[geomKey] is an + # because builtPolygonToCenterPointDict[geomKey] is an # defaultdict, everytime that it appends a different set of - # attr, it creates a new column. Therefore, when + # attr, it creates a new column. Therefore, when # structureLen is 0, there is no attr, when is more than 1 - # it had two points with differents attr. + # it had two points with differents attr. if structureLen == 1: fields = list(builtPolygonToCenterPointDict[geomKey].values()) attr = list(builtPolygonToCenterPointDict[geomKey].keys()) @@ -2122,12 +2666,14 @@ def getPolygonListAndFlagDictFromBuiltPolygonToCenterPointDict( else: if structureLen == 0 and suppressPolygonWithoutCenterPointFlag: continue - flagText = self.tr("Polygon without center point.") \ - if structureLen == 0 \ + flagText = ( + self.tr("Polygon without center point.") + if structureLen == 0 else self.tr( "Polygon with more than one center point with " "conflicting attributes." ) + ) flagDict[geomKey] = flagText if feedback is not None: feedback.setCurrentStep(current * size) @@ -2144,15 +2690,16 @@ def valueMaps(self, layer): for field in layer.fields(): fieldName = field.name() fieldConfig = field.editorWidgetSetup().config() - if 'map' not in fieldConfig or fieldName in ('UseHtml', 'IsMultiline'): + if "map" not in fieldConfig or fieldName in ("UseHtml", "IsMultiline"): continue - if isinstance(fieldConfig['map'], list): - for map_ in fieldConfig['map']: + if isinstance(fieldConfig["map"], list): + for map_ in fieldConfig["map"]: if fieldName not in classFieldMap: classFieldMap[fieldName] = map_ else: classFieldMap[fieldName].update(map_) else: + def intify(i): try: return int(i) @@ -2161,10 +2708,10 @@ def intify(i): def sortingMethod(item): return intify(item[1]) + classFieldMap[fieldName] = { - k: intify(v) for k, v in sorted( - fieldConfig['map'].items(), key=sortingMethod - ) + k: intify(v) + for k, v in sorted(fieldConfig["map"].items(), key=sortingMethod) } return classFieldMap @@ -2186,7 +2733,8 @@ def getDefaultValues(self, layer): return defaultValues def getPolygonSlivers( - self, layer, ratio, selected=False, silent=False, feedback=None): + self, layer, ratio, selected=False, silent=False, feedback=None + ): """ Identifies the polygon slivers for a given ratio area-perimeter of a layer. @@ -2204,18 +2752,16 @@ def getPolygonSlivers( if not layer.geometryType() != QgsWkbTypes.PolygonGeometry: Exception(self.tr("Input layer is not polygon.")) slivers = list() - feats = list(layer.getSelectedFeatures() if selected \ - else layer.getFeatures()) + feats = list(layer.getSelectedFeatures() if selected else layer.getFeatures()) stepSize = 100 / len(feats) if feats else 0 for step, f in enumerate(feats): geom = f.geometry() if geom.length() == 0 or not geom.isGeosValid(): if not silent: - raise Exception( - self.tr("Invalid or empty geometry found!")) + raise Exception(self.tr("Invalid or empty geometry found!")) feedback.setProgress((step + 1) * stepSize) continue - if geom.area() / (geom.length())**2 < ratio: + if geom.area() / (geom.length()) ** 2 < ratio: slivers.append(f) if feedback is not None: if feedback.isCanceled(): @@ -2223,7 +2769,13 @@ def getPolygonSlivers( feedback.setProgress((step + 1) * stepSize) return slivers - def addVertexesToLayers(self, vertexLyr: QgsVectorLayer, layerList: List[QgsVectorLayer], searchRadius, feedback=None) -> None: + def addVertexesToLayers( + self, + vertexLyr: QgsVectorLayer, + layerList: List[QgsVectorLayer], + searchRadius, + feedback=None, + ) -> None: nLayers = len(layerList) if nLayers == 0: return @@ -2237,12 +2789,23 @@ def addVertexesToLayers(self, vertexLyr: QgsVectorLayer, layerList: List[QgsVect multiStepFeedback.setCurrentStep(current) if not vertexLyrExtent.intersects(lyr.extent()): continue - self.addVertexesToLayer(vertexLyr, lyr, searchRadius, feedback=multiStepFeedback) + self.addVertexesToLayer( + vertexLyr, lyr, searchRadius, feedback=multiStepFeedback + ) return - def addVertexesToLayer(self, vertexLyr: QgsVectorLayer, layer: QgsVectorLayer, searchRadius, feedback=None) -> None: - geomLambda = lambda x: self.geometryHandler.addVertexesToGeometry(vertexSet=x[0], geom=x[1]) + def addVertexesToLayer( + self, + vertexLyr: QgsVectorLayer, + layer: QgsVectorLayer, + searchRadius, + feedback=None, + ) -> None: + geomLambda = lambda x: self.geometryHandler.addVertexesToGeometry( + vertexSet=x[0], geom=x[1] + ) changeGeometryLambda = lambda x: layer.changeGeometry(x.id(), x.geometry()) + def evaluateAddVertex(feat): if feedback.isCanceled(): return None @@ -2260,12 +2823,13 @@ def evaluateAddVertex(feat): newGeom = geomLambda([vertexSet, geom]) feat.setGeometry(newGeom) return feat + featCount = layer.featureCount() if featCount == 0: return - stepSize = 100/featCount + stepSize = 100 / featCount futures = set() - pool = concurrent.futures.ThreadPoolExecutor(max_workers=os.cpu_count()-1) + pool = concurrent.futures.ThreadPoolExecutor(max_workers=os.cpu_count() - 1) multiStepFeedback = QgsProcessingMultiStepFeedback(2, feedback) multiStepFeedback.setCurrentStep(0) multiStepFeedback.setCurrentStep(1) @@ -2273,15 +2837,15 @@ def evaluateAddVertex(feat): for current, feat in enumerate(layer.getFeatures()): if multiStepFeedback.isCanceled(): return - # futures.add(pool.submit(evaluateAddVertex, feat)) - # multiStepFeedback.setProgress(current * stepSize) - # multiStepFeedback.setCurrentStep(1) - - # updateSet = set() - # for current, future in enumerate(concurrent.futures.as_completed(futures)): - # if multiStepFeedback.isCanceled(): - # return - # outputFeat = future.result() + # futures.add(pool.submit(evaluateAddVertex, feat)) + # multiStepFeedback.setProgress(current * stepSize) + # multiStepFeedback.setCurrentStep(1) + + # updateSet = set() + # for current, future in enumerate(concurrent.futures.as_completed(futures)): + # if multiStepFeedback.isCanceled(): + # return + # outputFeat = future.result() outputFeat = evaluateAddVertex(feat) if outputFeat is not None: updateSet.add(outputFeat) @@ -2290,6 +2854,45 @@ def evaluateAddVertex(feat): if updateSet == set(): return layer.startEditing() - layer.beginEditCommand(self.tr('DsgTools adding missing vertexes')) + layer.beginEditCommand(self.tr("DsgTools adding missing vertexes")) list(map(changeGeometryLambda, updateSet)) layer.endEditCommand() + + def createMemoryLayerForEachFeature( + self, layer, context, returnFeature=False, feedback=None + ): + layerList = [] + nFeats = layer.featureCount() + if nFeats == 0: + return layerList + stepSize = 100 / nFeats + for current, feat in enumerate(layer.getFeatures()): + if feedback is not None and feedback.isCanceled(): + return layerList + temp = self.createMemoryLayerWithFeature(layer, feat, context) + item = (feat, temp) if returnFeature else temp + layerList.append(item) + if feedback is not None: + feedback.setProgress(current * stepSize) + return layerList + + def createMemoryLayerWithFeature(self, layer, feat, context=None, isSource=False): + context = QgsProcessingContext() if context is None else context + crs = layer.crs() if not isSource else layer.sourceCrs() + temp_name = ( + f"{layer.name()}-{str(uuid4())}" if not isSource else f"{str(uuid4())}" + ) + temp = QgsVectorLayer( + f"{QgsWkbTypes.displayString(layer.wkbType())}?crs={crs.authid()}", + temp_name, + "memory", + ) + temp_data = temp.dataProvider() + fields = layer.dataProvider().fields() if not isSource else layer.fields() + temp_data.addAttributes(fields.toList()) + temp.updateFields() + temp_data.addFeature(feat) + self.algRunner.runCreateSpatialIndex( + inputLyr=temp, context=context, is_child_algorithm=True + ) + return temp diff --git a/DsgTools/core/GeometricTools/networkHandler.py b/DsgTools/core/GeometricTools/networkHandler.py index c02d813eb..375a86884 100644 --- a/DsgTools/core/GeometricTools/networkHandler.py +++ b/DsgTools/core/GeometricTools/networkHandler.py @@ -27,20 +27,49 @@ from math import pi from .geometryHandler import GeometryHandler from .layerHandler import LayerHandler -from qgis.core import QgsMessageLog, QgsVectorLayer, QgsGeometry, QgsField, \ - QgsVectorDataProvider, QgsFeatureRequest, QgsExpression, \ - QgsFeature, QgsSpatialIndex, Qgis, QgsCoordinateTransform, \ - QgsWkbTypes, QgsProject, QgsVertexId, Qgis, QgsCoordinateReferenceSystem,\ - QgsDataSourceUri, QgsFields, QgsProcessingMultiStepFeedback +from qgis.core import ( + QgsMessageLog, + QgsVectorLayer, + QgsGeometry, + QgsField, + QgsVectorDataProvider, + QgsFeatureRequest, + QgsExpression, + QgsFeature, + QgsSpatialIndex, + Qgis, + QgsCoordinateTransform, + QgsWkbTypes, + QgsProject, + QgsVertexId, + Qgis, + QgsCoordinateReferenceSystem, + QgsDataSourceUri, + QgsFields, + QgsProcessingMultiStepFeedback, +) from qgis.PyQt.Qt import QObject from qgis.PyQt.QtCore import QVariant + class NetworkHandler(QObject): - Flag, Sink, WaterwayBegin, UpHillNode, \ - DownHillNode, Confluence, Ramification, \ - AttributeChange, NodeNextToWaterBody, \ - AttributeChangeFlag, NodeOverload, DisconnectedLine, \ - DitchNode, SpillwayNode = list(range(14)) + ( + Flag, + Sink, + WaterwayBegin, + UpHillNode, + DownHillNode, + Confluence, + Ramification, + AttributeChange, + NodeNextToWaterBody, + AttributeChangeFlag, + NodeOverload, + DisconnectedLine, + DitchNode, + SpillwayNode, + ) = list(range(14)) + def __init__(self): super(NetworkHandler, self).__init__() self.geometryHandler = GeometryHandler() @@ -48,28 +77,32 @@ def __init__(self): self.nodeDict = None self.nodeTypeDict = None self.nodeTypeNameDict = { - NetworkHandler.Flag : self.tr("Flag"),#0 - NetworkHandler.Sink : self.tr("Sink"),#1 - NetworkHandler.WaterwayBegin : self.tr("Waterway Beginning"),#2 - NetworkHandler.UpHillNode : self.tr("Up Hill Node"),#3 - NetworkHandler.DownHillNode : self.tr("Down Hill Node"),#4 - NetworkHandler.Confluence : self.tr("Confluence"),#5 - NetworkHandler.Ramification : self.tr("Ramification"),#6 - NetworkHandler.AttributeChange : self.tr("Attribute Change Node"),#7 - NetworkHandler.NodeNextToWaterBody : self.tr("Node Next to Water Body"),#8 - NetworkHandler.AttributeChangeFlag : self.tr("Attribute Change Flag"),#9 - NetworkHandler.NodeOverload : self.tr("Overloaded Node"),#10 - NetworkHandler.DisconnectedLine : self.tr("Disconnected From Network"),#11 - NetworkHandler.DitchNode : self.tr("Node next to ditch"),#12 - NetworkHandler.SpillwayNode : self.tr("Spillway") + NetworkHandler.Flag: self.tr("Flag"), # 0 + NetworkHandler.Sink: self.tr("Sink"), # 1 + NetworkHandler.WaterwayBegin: self.tr("Waterway Beginning"), # 2 + NetworkHandler.UpHillNode: self.tr("Up Hill Node"), # 3 + NetworkHandler.DownHillNode: self.tr("Down Hill Node"), # 4 + NetworkHandler.Confluence: self.tr("Confluence"), # 5 + NetworkHandler.Ramification: self.tr("Ramification"), # 6 + NetworkHandler.AttributeChange: self.tr("Attribute Change Node"), # 7 + NetworkHandler.NodeNextToWaterBody: self.tr("Node Next to Water Body"), # 8 + NetworkHandler.AttributeChangeFlag: self.tr("Attribute Change Flag"), # 9 + NetworkHandler.NodeOverload: self.tr("Overloaded Node"), # 10 + NetworkHandler.DisconnectedLine: self.tr("Disconnected From Network"), # 11 + NetworkHandler.DitchNode: self.tr("Node next to ditch"), # 12 + NetworkHandler.SpillwayNode: self.tr("Spillway"), } self.flagTextDict = { - NetworkHandler.Flag : self.tr('Segments must be connected and with correct flow.'), - NetworkHandler.AttributeChangeFlag : self.tr('Segments with same attribute set must be merged.'), - NetworkHandler.DisconnectedLine : self.tr("Line disconnected From Network"), - NetworkHandler.NodeOverload : self.tr("Node with flow problem") + NetworkHandler.Flag: self.tr( + "Segments must be connected and with correct flow." + ), + NetworkHandler.AttributeChangeFlag: self.tr( + "Segments with same attribute set must be merged." + ), + NetworkHandler.DisconnectedLine: self.tr("Line disconnected From Network"), + NetworkHandler.NodeOverload: self.tr("Node with flow problem"), } - + def identifyAllNodes(self, networkLayer, onlySelected=False, feedback=None): """ Identifies all nodes from a given layer (or selected features of it). @@ -83,10 +116,18 @@ def identifyAllNodes(self, networkLayer, onlySelected=False, feedback=None): } """ nodeDict = dict() - isMulti = QgsWkbTypes.isMultiType(int(networkLayer.wkbType())) - iterator = networkLayer.getFeatures() if not onlySelected else networkLayer.getSelectedFeatures() - featCount = networkLayer.featureCount() if not onlySelected else networkLayer.selectedFeatureCount() - size = 100/featCount if featCount else 0 + isMulti = QgsWkbTypes.isMultiType(networkLayer.wkbType()) + iterator = ( + networkLayer.getFeatures() + if not onlySelected + else networkLayer.getSelectedFeatures() + ) + featCount = ( + networkLayer.featureCount() + if not onlySelected + else networkLayer.selectedFeatureCount() + ) + size = 100 / featCount if featCount else 0 for current, feat in enumerate(iterator): if feedback is not None and feedback.isCanceled(): break @@ -95,26 +136,26 @@ def identifyAllNodes(self, networkLayer, onlySelected=False, feedback=None): if isMulti: if len(nodes) > 1: # if feat is multipart and has more than one part, a flag should be raised - continue # CHANGE TO RAISE FLAG + continue # CHANGE TO RAISE FLAG elif len(nodes) == 0: # if no part is found, skip feature continue else: # if feat is multipart, "nodes" is a list of list - nodes = nodes[0] + nodes = nodes[0] # initial node pInit, pEnd = nodes[0], nodes[-1] # filling starting node information into dictionary if pInit not in nodeDict: # if the point is not already started into dictionary, it creates a new item - nodeDict[pInit] = { 'start' : [], 'end' : [] } - if feat not in nodeDict[pInit]['start']: - nodeDict[pInit]['start'].append(feat) + nodeDict[pInit] = {"start": [], "end": []} + if feat not in nodeDict[pInit]["start"]: + nodeDict[pInit]["start"].append(feat) # filling ending node information into dictionary if pEnd not in nodeDict: - nodeDict[pEnd] = { 'start' : [], 'end' : [] } - if feat not in nodeDict[pEnd]['end']: - nodeDict[pEnd]['end'].append(feat) + nodeDict[pEnd] = {"start": [], "end": []} + if feat not in nodeDict[pEnd]["end"]: + nodeDict[pEnd]["end"].append(feat) if feedback is not None: feedback.setProgress(size * current) return nodeDict @@ -125,12 +166,12 @@ def changeLineDict(self, nodeList, line): identification is too costy. :param nodeList: (list-of-QgsPoint) the list of nodes connected to have given line relation dictionary changed. :param line: (QgsFeature) line to be flipped. - :return: whether changing was successful for each node + :return: whether changing was successful for each node """ for node in nodeList: # node's dicts - startDict = self.nodeDict[node]['start'] - endDict = self.nodeDict[node]['end'] + startDict = self.nodeDict[node]["start"] + endDict = self.nodeDict[node]["end"] if line in startDict: startDict.remove(line) endDict.append(line) @@ -161,24 +202,26 @@ def nodeOnFrame(self, node, frameLyrContourList, searchRadius): return True return False - def nodeNextToWaterBodies(self, node, waterBodiesLayers, searchRadius, auxIndexStructure=None): + def nodeNextToWaterBodies( + self, node, waterBodiesLayers, searchRadius, auxIndexStructure=None + ): """ Identify whether or not node is next to a water body feature. :param node: (QgsPoint) node to be identified as next to a water body feature. :param waterBodiesLayers: (list-of-QgsVectorLayer) list of layers composing the water bodies on map. :param searchRadius: (float) maximum distance to frame layer such that the feature is considered touching it. :return: (bool) whether node is as close as searchRaius to a water body element. - """ + """ qgisPoint = QgsGeometry.fromPointXY(node) # building a buffer around node with search radius for intersection with Layer Frame buf = qgisPoint.buffer(searchRadius, -1) # building bounding box around node for feature requesting bbRect = buf.boundingBox() # use aux spatial index if provided - if auxIndexStructure is not None and 'waterBodiesLayers' in auxIndexStructure: - for auxDict in auxIndexStructure['waterBodiesLayers']: - for featid in auxDict['spatialIdx'].intersects(bbRect): - if buf.intersects(auxDict['idDict'][featid].geometry()): + if auxIndexStructure is not None and "waterBodiesLayers" in auxIndexStructure: + for auxDict in auxIndexStructure["waterBodiesLayers"]: + for featid in auxDict["spatialIdx"].intersects(bbRect): + if buf.intersects(auxDict["idDict"][featid].geometry()): # any feature component of a water body intersected is enough return True else: @@ -192,7 +235,9 @@ def nodeNextToWaterBodies(self, node, waterBodiesLayers, searchRadius, auxIndexS return True return False - def nodeIsWaterSink(self, node, waterSinkLayer, searchRadius, auxIndexStructure=None): + def nodeIsWaterSink( + self, node, waterSinkLayer, searchRadius, auxIndexStructure=None + ): """ Identify whether or not node is next to a water body feature. If no water sink layer is given, method returns False :param node: (QgsPoint) node to be identified as coincident with a water sink feature. @@ -205,9 +250,16 @@ def nodeIsWaterSink(self, node, waterSinkLayer, searchRadius, auxIndexStructure= qgisPoint = QgsGeometry.fromPointXY(node) # building bounding box around node for feature requesting bbRect = qgisPoint.buffer(searchRadius, -1).boundingBox() - if auxIndexStructure is not None and 'waterSinkLayer' in auxIndexStructure: - for featid in auxIndexStructure['waterSinkLayer']['spatialIdx'].intersects(bbRect): - if qgisPoint.distance(auxIndexStructure['waterSinkLayer']['idDict'][featid].geometry()) <= searchRadius: + if auxIndexStructure is not None and "waterSinkLayer" in auxIndexStructure: + for featid in auxIndexStructure["waterSinkLayer"]["spatialIdx"].intersects( + bbRect + ): + if ( + qgisPoint.distance( + auxIndexStructure["waterSinkLayer"]["idDict"][featid].geometry() + ) + <= searchRadius + ): # any feature component of a water body intersected is enough return True else: @@ -217,7 +269,7 @@ def nodeIsWaterSink(self, node, waterSinkLayer, searchRadius, auxIndexStructure= # any feature component of a water body intersected is enough return True return False - + def nodeIsSpillway(self, node, spillwayLayer, searchRadius, auxIndexStructure=None): """ Identify whether or not node is next to a water body feature. If no water sink layer is given, method returns False @@ -231,9 +283,16 @@ def nodeIsSpillway(self, node, spillwayLayer, searchRadius, auxIndexStructure=No qgisPoint = QgsGeometry.fromPointXY(node) # building bounding box around node for feature requesting bbRect = qgisPoint.buffer(searchRadius, -1).boundingBox() - if auxIndexStructure is not None and 'spillwayLayer' in auxIndexStructure: - for featid in auxIndexStructure['spillwayLayer']['spatialIdx'].intersects(bbRect): - if qgisPoint.distance(auxIndexStructure['spillwayLayer']['idDict'][featid].geometry()) <= searchRadius: + if auxIndexStructure is not None and "spillwayLayer" in auxIndexStructure: + for featid in auxIndexStructure["spillwayLayer"]["spatialIdx"].intersects( + bbRect + ): + if ( + qgisPoint.distance( + auxIndexStructure["spillwayLayer"]["idDict"][featid].geometry() + ) + <= searchRadius + ): # any feature component of a water body intersected is enough return True else: @@ -258,7 +317,7 @@ def checkIfHasLineInsideWaterBody(self, node, waterBodiesLayers, searchRadius=No # building bounding box around node for feature requesting bbRect = buf.boundingBox() # check if any wb feature inside of buffer area contains any ending line - for line in self.nodeDict[node]['end']: + for line in self.nodeDict[node]["end"]: for lyr in waterBodiesLayers: for feat in lyr.getFeatures(QgsFeatureRequest(bbRect)): if feat.geometry().contains(line.geometry()): @@ -279,7 +338,7 @@ def getAttributesFromFeature(self, feature, layer, fieldList=None): """ # fields to be ignored fieldList = [] if fieldList is None else fieldList - return {field : feature[field] for field in fieldList} + return {field: feature[field] for field in fieldList} def attributeChangeCheck(self, node, networkLayer, fieldList=None): """ @@ -289,14 +348,20 @@ def attributeChangeCheck(self, node, networkLayer, fieldList=None): :return: (bool) if lines connected to node do change attributes. """ # assuming that attribute change nodes have only 1-in 1-out lines - lineIn = self.nodeDict[node]['end'][0] - atrLineIn = self.getAttributesFromFeature(feature=lineIn, layer=networkLayer, fieldList=fieldList) - lineOut = self.nodeDict[node]['start'][0] - atrLineOut = self.getAttributesFromFeature(feature=lineOut, layer=networkLayer, fieldList=fieldList) + lineIn = self.nodeDict[node]["end"][0] + atrLineIn = self.getAttributesFromFeature( + feature=lineIn, layer=networkLayer, fieldList=fieldList + ) + lineOut = self.nodeDict[node]["start"][0] + atrLineOut = self.getAttributesFromFeature( + feature=lineOut, layer=networkLayer, fieldList=fieldList + ) # comparing their dictionary of attributes, it is decided whether they share the exact same set of attributes (fields and values) return atrLineIn != atrLineOut - def isFirstOrderDangle(self, node, networkLayer, searchRadius, auxIndexStructure=None): + def isFirstOrderDangle( + self, node, networkLayer, searchRadius, auxIndexStructure=None + ): """ Checks whether node is a dangle into network (connected to a first order line). :param node: (QgsPoint) node to be validated. @@ -309,13 +374,17 @@ def isFirstOrderDangle(self, node, networkLayer, searchRadius, auxIndexStructure buf = qgisPoint.buffer(searchRadius, -1) # building bounding box around node for feature requesting bbRect = buf.boundingBox() - if auxIndexStructure is not None and 'networkLayer' in auxIndexStructure: + if auxIndexStructure is not None and "networkLayer" in auxIndexStructure: # check if buffer intersects features from water bodies layers count = 0 - for featid in auxIndexStructure['networkLayer']['spatialIdx'].intersects(bbRect): - if buf.intersects(auxIndexStructure['networkLayer']['idDict'][featid].geometry()): + for featid in auxIndexStructure["networkLayer"]["spatialIdx"].intersects( + bbRect + ): + if buf.intersects( + auxIndexStructure["networkLayer"]["idDict"][featid].geometry() + ): count += 1 - res = (count > 1) + res = count > 1 if res: # to avoid as many iterations as possible return False @@ -325,20 +394,22 @@ def isFirstOrderDangle(self, node, networkLayer, searchRadius, auxIndexStructure for feat in networkLayer.getFeatures(QgsFeatureRequest(bbRect)): if buf.intersects(feat.geometry()): count += 1 - res = (count > 1) + res = count > 1 if res: # to avoid as many iterations as possible return False return True - def checkIfLineIsDisconnected(self, node, networkLayer, nodeTypeDict, geomType=None): + def checkIfLineIsDisconnected( + self, node, networkLayer, nodeTypeDict, geomType=None + ): """ Checks whether a waterway beginning node connected to a line disconnected from network. :param node: (QgsPoint) point to be classified. :param networkLayer: (QgsVectorLayer) network lines layer. :param nodeTypeDict: (dict) all current classified nodes and theirs types. :param geomType: (int) network layer geometry type code. - :return: (bool) whether node is connected to a disconnected line + :return: (bool) whether node is connected to a disconnected line """ if not nodeTypeDict: # if there are no classified nodes, method is ineffective @@ -349,22 +420,24 @@ def checkIfLineIsDisconnected(self, node, networkLayer, nodeTypeDict, geomType=N nextNodes = [] # to reduce calculation time nodePointDict = self.nodeDict[node] - isMulti = QgsWkbTypes.isMultiType(int(networkLayer.wkbType())) + isMulti = QgsWkbTypes.isMultiType(networkLayer.wkbType()) # get all other nodes connected to lines connected to "node" - lines = nodePointDict['start'] + nodePointDict['end'] + lines = nodePointDict["start"] + nodePointDict["end"] if len(lines) > 1: # if there is at least one more line connected to node, line is not disconnected return False # get line nodes - n = self.geometryHandler.getFeatureNodes(layer=networkLayer, feature=lines[0], geomType=geomType) - if nodePointDict['start']: + n = self.geometryHandler.getFeatureNodes( + layer=networkLayer, feature=lines[0], geomType=geomType + ) + if nodePointDict["start"]: # if line starts at target node, the other extremity is a final node if isMulti: if n is not None: n = n[0][-1] elif n is not None: n = n[-1] - elif nodePointDict['end']: + elif nodePointDict["end"]: # if line starts at target node, the other extremity is a initial node if isMulti: if n is not None: @@ -375,15 +448,20 @@ def checkIfLineIsDisconnected(self, node, networkLayer, nodeTypeDict, geomType=N # validEnds = [NetworkHandler.Sink, NetworkHandler.DownHillNode, NetworkHandler.NodeNextToWaterBody] if n in nodeTypeDict: # if both ends are classified as waterway beginning, then both ends are 1st order dangles and line is disconnected. - return nodeTypeDict[n] in [NetworkHandler.WaterwayBegin, NetworkHandler.DownHillNode, NetworkHandler.UpHillNode, NetworkHandler.NodeNextToWaterBody] + return nodeTypeDict[n] in [ + NetworkHandler.WaterwayBegin, + NetworkHandler.DownHillNode, + NetworkHandler.UpHillNode, + NetworkHandler.NodeNextToWaterBody, + ] # if nodeTypeDict[n] not in validEnds: # if self.isFirstOrderDangle(node=n, networkLayer=networkLayer, searchRadius=self.parameters[self.tr('Search Radius')]): - # # if next node is not a valid network ending node and is a dangle, line is disconnected from network + # # if next node is not a valid network ending node and is a dangle, line is disconnected from network # return False # return True # in case next node is not yet classified, method is ineffective return False - + def isNodeNextToDitch(self, node, ditchLayer, searchRadius, auxIndexStructure=None): """ Checks if node is next to a ditch. @@ -399,9 +477,13 @@ def isNodeNextToDitch(self, node, ditchLayer, searchRadius, auxIndexStructure=No buf = qgisPoint.buffer(searchRadius, -1) # building bounding box around node for feature requesting bbRect = buf.boundingBox() - if auxIndexStructure is not None and 'ditchLayer' in auxIndexStructure: - for featid in auxIndexStructure['ditchLayer']['spatialIdx'].intersects(bbRect): - if buf.intersects(auxIndexStructure['ditchLayer']['idDict'][featid].geometry()): + if auxIndexStructure is not None and "ditchLayer" in auxIndexStructure: + for featid in auxIndexStructure["ditchLayer"]["spatialIdx"].intersects( + bbRect + ): + if buf.intersects( + auxIndexStructure["ditchLayer"]["idDict"][featid].geometry() + ): # any feature component of a water body intersected is enough return True else: @@ -412,9 +494,21 @@ def isNodeNextToDitch(self, node, ditchLayer, searchRadius, auxIndexStructure=No return True return False - def nodeType(self, nodePoint, networkLayer, frameLyrContourList, waterBodiesLayers,\ - searchRadius, nodeTypeDict, waterSinkLayer=None, spillwayLayer=None,\ - networkLayerGeomType=None, fieldList=None, ditchLayer=None, auxIndexStructure=None): + def nodeType( + self, + nodePoint, + networkLayer, + frameLyrContourList, + waterBodiesLayers, + searchRadius, + nodeTypeDict, + waterSinkLayer=None, + spillwayLayer=None, + networkLayerGeomType=None, + fieldList=None, + ditchLayer=None, + auxIndexStructure=None, + ): """ Get the node type given all lines that flows from/to it. :param nodePoint: (QgsPoint) point to be classified. @@ -431,21 +525,25 @@ def nodeType(self, nodePoint, networkLayer, frameLyrContourList, waterBodiesLaye auxIndexStructure = {} if auxIndexStructure is None else auxIndexStructure # to reduce calculation time in expense of memory, which is cheap nodePointDict = self.nodeDict[nodePoint] - sizeFlowOut = len(nodePointDict['start']) - sizeFlowIn = len(nodePointDict['end']) + sizeFlowOut = len(nodePointDict["start"]) + sizeFlowIn = len(nodePointDict["end"]) hasStartLine = bool(sizeFlowOut) hasEndLine = bool(sizeFlowIn) if not networkLayerGeomType: networkLayerGeomType = networkLayer.geometryType() # "exclusive or" - startXORendLine = (hasStartLine != hasEndLine) + startXORendLine = hasStartLine != hasEndLine # # case 5: more than 3 lines flowing through one network line (it is forbidden as of Brazilian mapping norm EDGV) # if sizeFlowIn + sizeFlowOut > 3: # return NetworkHandler.NodeOverload - # case 1: all lines either flow in or out + # case 1: all lines either flow in or out if startXORendLine: # case 1.a: point is over the frame - if self.nodeOnFrame(node=nodePoint, frameLyrContourList=frameLyrContourList, searchRadius=searchRadius): + if self.nodeOnFrame( + node=nodePoint, + frameLyrContourList=frameLyrContourList, + searchRadius=searchRadius, + ): # case 1.a.i: waterway is flowing away from mapped area (point over the frame has one line ending line) if hasEndLine: return NetworkHandler.DownHillNode @@ -455,41 +553,96 @@ def nodeType(self, nodePoint, networkLayer, frameLyrContourList, waterBodiesLaye # case 1.b: point that legitimately only flows from elif hasEndLine: # case 1.b.i - if self.nodeNextToWaterBodies(node=nodePoint, waterBodiesLayers=waterBodiesLayers, searchRadius=searchRadius, auxIndexStructure=auxIndexStructure): + if self.nodeNextToWaterBodies( + node=nodePoint, + waterBodiesLayers=waterBodiesLayers, + searchRadius=searchRadius, + auxIndexStructure=auxIndexStructure, + ): # it is considered that every free node on map is a starting node. The only valid exceptions are nodes that are # next to water bodies and water sink holes. if sizeFlowIn == 1: # a node next to water has to be a lose end return NetworkHandler.NodeNextToWaterBody # force all lose ends to be waterway beginnings if they're not dangles (which are flags) - elif self.isFirstOrderDangle(node=nodePoint, networkLayer=networkLayer, searchRadius=searchRadius, auxIndexStructure=auxIndexStructure): - if self.isNodeNextToDitch(node=nodePoint, ditchLayer=ditchLayer, searchRadius=searchRadius, auxIndexStructure=auxIndexStructure): + elif self.isFirstOrderDangle( + node=nodePoint, + networkLayer=networkLayer, + searchRadius=searchRadius, + auxIndexStructure=auxIndexStructure, + ): + if self.isNodeNextToDitch( + node=nodePoint, + ditchLayer=ditchLayer, + searchRadius=searchRadius, + auxIndexStructure=auxIndexStructure, + ): # if point is not disconnected and is connected to a ditch return NetworkHandler.DitchNode # check if node is connected to a disconnected line - elif self.checkIfLineIsDisconnected(node=nodePoint, networkLayer=networkLayer, nodeTypeDict=nodeTypeDict, geomType=networkLayerGeomType): + elif self.checkIfLineIsDisconnected( + node=nodePoint, + networkLayer=networkLayer, + nodeTypeDict=nodeTypeDict, + geomType=networkLayerGeomType, + ): return NetworkHandler.DisconnectedLine # case 1.b.ii: node is in fact a water sink and should be able to take an 'in' flow - elif self.nodeIsWaterSink(node=nodePoint, waterSinkLayer=waterSinkLayer, searchRadius=searchRadius, auxIndexStructure=auxIndexStructure): + elif self.nodeIsWaterSink( + node=nodePoint, + waterSinkLayer=waterSinkLayer, + searchRadius=searchRadius, + auxIndexStructure=auxIndexStructure, + ): # if a node is indeed a water sink (operator has set it to a sink) return NetworkHandler.Sink - elif self.nodeIsSpillway(node=nodePoint, spillwayLayer=spillwayLayer, searchRadius=searchRadius, auxIndexStructure=auxIndexStructure): + elif self.nodeIsSpillway( + node=nodePoint, + spillwayLayer=spillwayLayer, + searchRadius=searchRadius, + auxIndexStructure=auxIndexStructure, + ): # if node is a spillway return NetworkHandler.SpillwayNode return NetworkHandler.WaterwayBegin # case 1.c: point that legitimately only flows out - elif hasStartLine and self.isFirstOrderDangle(node=nodePoint, networkLayer=networkLayer, searchRadius=searchRadius, auxIndexStructure=auxIndexStructure): - if self.isNodeNextToDitch(node=nodePoint, ditchLayer=ditchLayer, searchRadius=searchRadius, auxIndexStructure=auxIndexStructure): + elif hasStartLine and self.isFirstOrderDangle( + node=nodePoint, + networkLayer=networkLayer, + searchRadius=searchRadius, + auxIndexStructure=auxIndexStructure, + ): + if self.isNodeNextToDitch( + node=nodePoint, + ditchLayer=ditchLayer, + searchRadius=searchRadius, + auxIndexStructure=auxIndexStructure, + ): # if point is not disconnected and is connected to a ditch return NetworkHandler.DitchNode - elif self.checkIfLineIsDisconnected(node=nodePoint, networkLayer=networkLayer, nodeTypeDict=nodeTypeDict, geomType=networkLayerGeomType): + elif self.checkIfLineIsDisconnected( + node=nodePoint, + networkLayer=networkLayer, + nodeTypeDict=nodeTypeDict, + geomType=networkLayerGeomType, + ): return NetworkHandler.DisconnectedLine - elif self.nodeIsWaterSink(node=nodePoint, waterSinkLayer=waterSinkLayer, searchRadius=searchRadius, auxIndexStructure=auxIndexStructure): + elif self.nodeIsWaterSink( + node=nodePoint, + waterSinkLayer=waterSinkLayer, + searchRadius=searchRadius, + auxIndexStructure=auxIndexStructure, + ): # in case there's a wrongly acquired line connected to a water sink return NetworkHandler.Sink - elif self.nodeIsSpillway(node=nodePoint, spillwayLayer=spillwayLayer, searchRadius=searchRadius, auxIndexStructure=auxIndexStructure): - # if node is a spillway - return NetworkHandler.SpillwayNode + elif self.nodeIsSpillway( + node=nodePoint, + spillwayLayer=spillwayLayer, + searchRadius=searchRadius, + auxIndexStructure=auxIndexStructure, + ): + # if node is a spillway + return NetworkHandler.SpillwayNode return NetworkHandler.WaterwayBegin # case 1.d: points that are not supposed to have one way flow (flags) return NetworkHandler.Flag @@ -500,10 +653,17 @@ def nodeType(self, nodePoint, networkLayer, frameLyrContourList, waterBodiesLaye if sizeFlowIn > 1: # case 4.a: there's a constant flow through node, but there are more than 1 line return NetworkHandler.NodeOverload - elif self.attributeChangeCheck(node=nodePoint, networkLayer=networkLayer, fieldList=fieldList): + elif self.attributeChangeCheck( + node=nodePoint, networkLayer=networkLayer, fieldList=fieldList + ): # case 4.b: lines do change their attribute set. Must use fieldList due to black list items. return NetworkHandler.AttributeChange - elif self.isNodeNextToDitch(node=nodePoint, ditchLayer=ditchLayer, searchRadius=searchRadius, auxIndexStructure=auxIndexStructure): + elif self.isNodeNextToDitch( + node=nodePoint, + ditchLayer=ditchLayer, + searchRadius=searchRadius, + auxIndexStructure=auxIndexStructure, + ): # case 4.c: lines next to ditches. return NetworkHandler.DitchNode else: @@ -514,26 +674,42 @@ def nodeType(self, nodePoint, networkLayer, frameLyrContourList, waterBodiesLaye # case 3 "ramification" return NetworkHandler.Ramification - def classifyAllNodes(self, networkLayer, frameLyrContourList, waterBodiesLayers, searchRadius, waterSinkLayer=None, spillwayLayer=None, nodeList=None, feedback=None, attributeBlackList=None, ignoreVirtualFields=True, excludePrimaryKeys=True, ditchLayer=None): + def classifyAllNodes( + self, + networkLayer, + frameLyrContourList, + waterBodiesLayers, + searchRadius, + waterSinkLayer=None, + spillwayLayer=None, + nodeList=None, + feedback=None, + attributeBlackList=None, + ignoreVirtualFields=True, + excludePrimaryKeys=True, + ditchLayer=None, + ): """ Classifies all identified nodes from the hidrography line layer. :param networkLayer: (QgsVectorLayer) network lines layer. :param frameLyrContourList: (list-of-QgsFeature) border line for the frame layer. :param waterBodiesLayers: (list-of-QgsVectorLayer) list of all classes with water bodies to be compared to. :param searchRadius: (float) maximum distance to frame layer such that the feature is considered touching it. - :param nodeList: a list of nodes (QgsPoint) to be classified. If not given, whole dict is going + :param nodeList: a list of nodes (QgsPoint) to be classified. If not given, whole dict is going to be classified. Node MUST be in dict given, if not, it'll be ignored. :param waterSinkLayer: (QgsVectorLayer) water sink layer. :param ditchLayer: (QgsVectorLayer) ditch layer. - :return: a (dict) dictionary of node and its node type ( { (QgsPoint)node : (int)nodeType } ). + :return: a (dict) dictionary of node and its node type ( { (QgsPoint)node : (int)nodeType } ). """ networkLayerGeomType = networkLayer.geometryType() nodeTypeDict = dict() flagNodeDict = dict() - fieldList = self.layerHandler.getAttributesFromBlackList(networkLayer, \ - attributeBlackList=attributeBlackList,\ - ignoreVirtualFields=ignoreVirtualFields,\ - excludePrimaryKeys=excludePrimaryKeys) + fieldList = self.layerHandler.getAttributesFromBlackList( + networkLayer, + attributeBlackList=attributeBlackList, + ignoreVirtualFields=ignoreVirtualFields, + excludePrimaryKeys=excludePrimaryKeys, + ) if feedback is not None: multiStepFeedback = QgsProcessingMultiStepFeedback(2, feedback) multiStepFeedback.setCurrentStep(0) @@ -543,9 +719,10 @@ def classifyAllNodes(self, networkLayer, frameLyrContourList, waterBodiesLayers, spillwayLayer=spillwayLayer, waterSinkLayer=waterSinkLayer, ditchLayer=ditchLayer, - feedback=multiStepFeedback) + feedback=multiStepFeedback, + ) nodeCount = len(self.nodeDict) - size = 100/nodeCount if nodeCount else 0 + size = 100 / nodeCount if nodeCount else 0 if feedback is not None: multiStepFeedback.setCurrentStep(1) for current, node in enumerate(self.nodeDict): @@ -566,16 +743,24 @@ def classifyAllNodes(self, networkLayer, frameLyrContourList, waterBodiesLayers, networkLayerGeomType=networkLayerGeomType, fieldList=fieldList, ditchLayer=ditchLayer, - auxIndexStructure=auxIndexStructure - ) + auxIndexStructure=auxIndexStructure, + ) nodeTypeDict[node] = nodeClassification if nodeClassification in self.flagTextDict: flagNodeDict[node] = self.flagTextDict[nodeClassification] if multiStepFeedback is not None: multiStepFeedback.setProgress(size * current) return nodeTypeDict, flagNodeDict - - def getAuxIndexStructure(self, networkLayer, waterBodiesLayers=None, waterSinkLayer=None, spillwayLayer=None, ditchLayer=None, feedback=None): + + def getAuxIndexStructure( + self, + networkLayer, + waterBodiesLayers=None, + waterSinkLayer=None, + spillwayLayer=None, + ditchLayer=None, + feedback=None, + ): auxStructDict = dict() steps = 1 if waterBodiesLayers is not None: @@ -587,30 +772,48 @@ def getAuxIndexStructure(self, networkLayer, waterBodiesLayers=None, waterSinkLa multiStepFeedback = QgsProcessingMultiStepFeedback(steps, feedback) currStep = 0 multiStepFeedback.setCurrentStep(currStep) - spatialIdx, idDict = self.layerHandler.buildSpatialIndexAndIdDict(networkLayer, feedback=multiStepFeedback) - auxStructDict['networkLayer']={'spatialIdx':spatialIdx, 'idDict':idDict} + spatialIdx, idDict = self.layerHandler.buildSpatialIndexAndIdDict( + networkLayer, feedback=multiStepFeedback + ) + auxStructDict["networkLayer"] = {"spatialIdx": spatialIdx, "idDict": idDict} currStep += 1 if waterBodiesLayers is not None: - auxStructDict['waterBodies'] = [] + auxStructDict["waterBodies"] = [] multiStepFeedback.setCurrentStep(currStep) for lyr in waterBodiesLayers: - spatialIdx, idDict = self.layerHandler.buildSpatialIndexAndIdDict(lyr, feedback=multiStepFeedback) - auxStructDict['waterBodies'].append({'spatialIdx':spatialIdx, 'idDict':idDict}) + spatialIdx, idDict = self.layerHandler.buildSpatialIndexAndIdDict( + lyr, feedback=multiStepFeedback + ) + auxStructDict["waterBodies"].append( + {"spatialIdx": spatialIdx, "idDict": idDict} + ) currStep += 1 if waterSinkLayer is not None: multiStepFeedback.setCurrentStep(currStep) - spatialIdx, idDict = self.layerHandler.buildSpatialIndexAndIdDict(waterSinkLayer, feedback=multiStepFeedback) - auxStructDict['waterSinkLayer'] = {'spatialIdx':spatialIdx, 'idDict':idDict} + spatialIdx, idDict = self.layerHandler.buildSpatialIndexAndIdDict( + waterSinkLayer, feedback=multiStepFeedback + ) + auxStructDict["waterSinkLayer"] = { + "spatialIdx": spatialIdx, + "idDict": idDict, + } currStep += 1 if spillwayLayer is not None: multiStepFeedback.setCurrentStep(currStep) - spatialIdx, idDict = self.layerHandler.buildSpatialIndexAndIdDict(spillwayLayer, feedback=multiStepFeedback) - auxStructDict['spillwayLayer'] = {'spatialIdx':spatialIdx, 'idDict':idDict} + spatialIdx, idDict = self.layerHandler.buildSpatialIndexAndIdDict( + spillwayLayer, feedback=multiStepFeedback + ) + auxStructDict["spillwayLayer"] = { + "spatialIdx": spatialIdx, + "idDict": idDict, + } currStep += 1 if ditchLayer is not None: multiStepFeedback.setCurrentStep(currStep) - spatialIdx, idDict = self.layerHandler.buildSpatialIndexAndIdDict(ditchLayer, feedback=multiStepFeedback) - auxStructDict['ditchLayer'] = {'spatialIdx':spatialIdx, 'idDict':idDict} + spatialIdx, idDict = self.layerHandler.buildSpatialIndexAndIdDict( + ditchLayer, feedback=multiStepFeedback + ) + auxStructDict["ditchLayer"] = {"spatialIdx": spatialIdx, "idDict": idDict} currStep += 1 return auxStructDict @@ -621,7 +824,7 @@ def clearHidNodeLayer(self, nodeLayer, nodeIdList=None, commitToLayer=False): :param nodeIdList: (list-of-int) list of node IDs to be cleared from layer. :param commitToLayer: (bool) indicates whether changes should be commited to layer. """ - nodeLayer.beginEditCommand('Clear Nodes') + nodeLayer.beginEditCommand("Clear Nodes") if not nodeIdList: nodeIdList = [feat.id() for feat in nodeLayer.getFeatures()] nodeLayer.deleteFeatures(nodeIdList) @@ -641,7 +844,7 @@ def fillNodeLayer(self, nodeLayer, networkLineLayerName, commitToLayer=False): self.clearHidNodeLayer(nodeLayer=nodeLayer, commitToLayer=commitToLayer) # get fields from layer in order to create new feature with the same attribute map fields = nodeLayer.fields() - nodeLayer.beginEditCommand('Create Nodes') + nodeLayer.beginEditCommand("Create Nodes") # to avoid unnecessary calculation inside loop nodeTypeKeys = self.nodeTypeDict.keys() # initiate new features list @@ -651,8 +854,10 @@ def fillNodeLayer(self, nodeLayer, networkLineLayerName, commitToLayer=False): feat = QgsFeature(fields) # set geometry feat.setGeometry(QgsGeometry.fromMultiPointXY([node])) - feat['node_type'] = self.nodeTypeDict[node] if node in nodeTypeKeys else None - feat['layer'] = networkLineLayerName + feat["node_type"] = ( + self.nodeTypeDict[node] if node in nodeTypeKeys else None + ) + feat["layer"] = networkLineLayerName featList.append(feat) nodeLayer.addFeatures(featList) nodeLayer.endEditCommand() @@ -667,8 +872,10 @@ def getFirstNode(self, lyr, feat, geomType=None): :param geomType: (int) layer geometry type (1 for lines). :return: starting node point (QgsPoint). """ - n = self.geometryHandler.getFeatureNodes(layer=lyr, feature=feat, geomType=geomType) - isMulti = QgsWkbTypes.isMultiType(int(lyr.wkbType())) + n = self.geometryHandler.getFeatureNodes( + layer=lyr, feature=feat, geomType=geomType + ) + isMulti = QgsWkbTypes.isMultiType(lyr.wkbType()) if isMulti: if len(n) > 1: return @@ -684,8 +891,10 @@ def getSecondNode(self, lyr, feat, geomType=None): :param geomType: (int) layer geometry type (1 for lines). :return: starting node point (QgsPoint). """ - n = self.geometryHandler.getFeatureNodes(layer=lyr, feature=feat, geomType=geomType) - isMulti = QgsWkbTypes.isMultiType(int(lyr.wkbType())) + n = self.geometryHandler.getFeatureNodes( + layer=lyr, feature=feat, geomType=geomType + ) + isMulti = QgsWkbTypes.isMultiType(lyr.wkbType()) if isMulti: if len(n) > 1: # process doesn't treat multipart features that does have more than 1 part @@ -702,8 +911,10 @@ def getPenultNode(self, lyr, feat, geomType=None): :param geomType: (int) layer geometry type (1 for lines). :return: ending node point (QgsPoint). """ - n = self.geometryHandler.getFeatureNodes(layer=lyr, feature=feat, geomType=geomType) - isMulti = QgsWkbTypes.isMultiType(int(lyr.wkbType())) + n = self.geometryHandler.getFeatureNodes( + layer=lyr, feature=feat, geomType=geomType + ) + isMulti = QgsWkbTypes.isMultiType(lyr.wkbType()) if isMulti: if len(n) > 1: return @@ -719,8 +930,10 @@ def getLastNode(self, lyr, feat, geomType=None): :param geomType: (int) layer geometry type (1 for lines). :return: ending node point (QgsPoint). """ - n = self.geometryHandler.getFeatureNodes(layer=lyr, feature=feat, geomType=geomType) - isMulti = QgsWkbTypes.isMultiType(int(lyr.wkbType())) + n = self.geometryHandler.getFeatureNodes( + layer=lyr, feature=feat, geomType=geomType + ) + isMulti = QgsWkbTypes.isMultiType(lyr.wkbType()) if isMulti: if len(n) > 1: return @@ -730,15 +943,17 @@ def getLastNode(self, lyr, feat, geomType=None): def calculateAngleDifferences(self, startNode, endNode): """ - Calculates the angle in degrees formed between line direction ('startNode' -> 'endNode') and vertical passing over + Calculates the angle in degrees formed between line direction ('startNode' -> 'endNode') and vertical passing over starting node. :param startNode: node (QgsPoint) reference for line and angle calculation. :param endNode: ending node (QgsPoint) for (segment of) line of which angle is required. :return: (float) angle in degrees formed between line direction ('startNode' -> 'endNode') and vertical passing over 'startNode' """ # the returned angle is measured regarding 'y-axis', with + counter clockwise and -, clockwise. - # Then angle is ALWAYS 180 - ang - return 180 - math.degrees(math.atan2(endNode.x() - startNode.x(), endNode.y() - startNode.y())) + # Then angle is ALWAYS 180 - ang + return 180 - math.degrees( + math.atan2(endNode.x() - startNode.x(), endNode.y() - startNode.y()) + ) def calculateAzimuthFromNode(self, node, networkLayer, geomType=None): """ @@ -752,17 +967,19 @@ def calculateAzimuthFromNode(self, node, networkLayer, geomType=None): geomType = networkLayer.geometryType() nodePointDict = self.nodeDict[node] azimuthDict = dict() - for line in nodePointDict['start']: + for line in nodePointDict["start"]: # if line starts at node, then angle calculate is already azimuth endNode = self.getSecondNode(lyr=networkLayer, feat=line, geomType=geomType) azimuthDict[line] = node.azimuth(endNode) - for line in nodePointDict['end']: + for line in nodePointDict["end"]: # if line ends at node, angle must be adapted in order to get azimuth endNode = self.getPenultNode(lyr=networkLayer, feat=line, geomType=geomType) azimuthDict[line] = node.azimuth(endNode) return azimuthDict - def checkLineDirectionConcordance(self, line_a, line_b, networkLayer, geomType=None): + def checkLineDirectionConcordance( + self, line_a, line_b, networkLayer, geomType=None + ): """ Given two lines, this method checks whether lines flow to/from the same node or not. If they do not have a common node, method returns false. @@ -779,9 +996,11 @@ def checkLineDirectionConcordance(self, line_a, line_b, networkLayer, geomType=N fn_b = self.getFirstNode(lyr=networkLayer, feat=line_b, geomType=geomType) ln_b = self.getLastNode(lyr=networkLayer, feat=line_b, geomType=geomType) # if lines are flowing to/from the same node (they are flowing the same way) - return (fn_a == fn_b or ln_a == ln_b) + return fn_a == fn_b or ln_a == ln_b - def validateDeltaLinesAngV2(self, node, networkLayer, connectedValidLines, geomType=None): + def validateDeltaLinesAngV2( + self, node, networkLayer, connectedValidLines, geomType=None + ): """ Validates a set of lines connected to a node as for the angle formed between them. :param node: (QgsPoint) hidrography node to be validated. @@ -794,7 +1013,9 @@ def validateDeltaLinesAngV2(self, node, networkLayer, connectedValidLines, geomT val, inval, reason = dict(), dict(), "" if not geomType: geomType = networkLayer.geometryType() - azimuthDict = self.calculateAzimuthFromNode(node=node, networkLayer=networkLayer, geomType=None) + azimuthDict = self.calculateAzimuthFromNode( + node=node, networkLayer=networkLayer, geomType=None + ) lines = azimuthDict.keys() for idx1, key1 in enumerate(lines): if idx1 == len(lines): @@ -804,14 +1025,23 @@ def validateDeltaLinesAngV2(self, node, networkLayer, connectedValidLines, geomT if idx1 >= idx2: # in order to calculate only f1 - f2, f1 - f3, f2 - f3 (for 3 features, for instance) continue - absAzimuthDifference = math.fmod((azimuthDict[key1] - azimuthDict[key2] + 360), 360) + absAzimuthDifference = math.fmod( + (azimuthDict[key1] - azimuthDict[key2] + 360), 360 + ) if absAzimuthDifference > 180: # the lesser angle should always be the one to be analyzed - absAzimuthDifference = (360 - absAzimuthDifference) + absAzimuthDifference = 360 - absAzimuthDifference if absAzimuthDifference < 90: # if it's a 'beak', lines cannot have opposing directions (e.g. cannot flow to/from the same node) - if not self.checkLineDirectionConcordance(line_a=key1, line_b=key2, networkLayer=networkLayer, geomType=geomType): - reason = self.tr('Lines id={0} and id={1} have conflicting directions ({2:.2f} deg).').format(key1.id(), key2.id(), absAzimuthDifference) + if not self.checkLineDirectionConcordance( + line_a=key1, + line_b=key2, + networkLayer=networkLayer, + geomType=geomType, + ): + reason = self.tr( + "Lines id={0} and id={1} have conflicting directions ({2:.2f} deg)." + ).format(key1.id(), key2.id(), absAzimuthDifference) # checks if any of connected lines are already validated by any previous iteration if key1 not in connectedValidLines: inval[key1.id()] = key1 @@ -823,17 +1053,21 @@ def validateDeltaLinesAngV2(self, node, networkLayer, connectedValidLines, geomT continue else: # if lines touch each other at a right angle, then it is impossible to infer waterway direction - reason = self.tr('Cannot infer directions for lines {0} and {1} (Right Angle)').format(key1.id(), key2.id()) + reason = self.tr( + "Cannot infer directions for lines {0} and {1} (Right Angle)" + ).format(key1.id(), key2.id()) if key1 not in connectedValidLines: - inval[key1.id()] = key1 + inval[key1.id()] = key1 if key2 not in connectedValidLines: inval[key2.id()] = key2 return val, inval, reason if not inval: - val = {k.id() : k for k in lines} + val = {k.id(): k for k in lines} return val, inval, reason - def checkNodeTypeValidity(self, node, connectedValidLines, networkLayer, geomType=None): + def checkNodeTypeValidity( + self, node, connectedValidLines, networkLayer, geomType=None + ): """ Checks if lines connected to a node have their flows compatible to node type and valid lines connected to it. @@ -847,45 +1081,57 @@ def checkNodeTypeValidity(self, node, connectedValidLines, networkLayer, geomTyp # getting flow permitions based on node type # reference is the node (e.g. 'in' = lines are ENDING at analyzed node) flowType = { - NetworkHandler.Flag : None, # 0 - Flag (fim de trecho sem 'justificativa espacial') - NetworkHandler.Sink : 'in', # 1 - Sumidouro - NetworkHandler.WaterwayBegin : 'out', # 2 - Fonte D'Água - NetworkHandler.DownHillNode : 'in', # 3 - Interrupção à Jusante - NetworkHandler.UpHillNode : 'out', # 4 - Interrupção à Montante - NetworkHandler.Confluence : 'in and out', # 5 - Confluência - NetworkHandler.Ramification : 'in and out', # 6 - Ramificação - NetworkHandler.AttributeChange : 'in and out', # 7 - Mudança de Atributo - NetworkHandler.NodeNextToWaterBody : 'in or out', # 8 - Nó próximo a corpo d'água - NetworkHandler.AttributeChangeFlag : None, # 9 - Nó de mudança de atributos conectado em linhas que não mudam de atributos - NetworkHandler.NodeOverload : None, # 10 - Há igual número de linhas (>1 para cada fluxo) entrando e saindo do nó - NetworkHandler.DisconnectedLine : None, # 11 - Nó conectado a uma linha perdida na rede (teria dois inícios de rede) - NetworkHandler.DitchNode : 'in and out', # 12 - Nó de vala - NetworkHandler.SpillwayNode : 'out' # 13 - Vertedouro - } + NetworkHandler.Flag: None, # 0 - Flag (fim de trecho sem 'justificativa espacial') + NetworkHandler.Sink: "in", # 1 - Sumidouro + NetworkHandler.WaterwayBegin: "out", # 2 - Fonte D'Água + NetworkHandler.DownHillNode: "in", # 3 - Interrupção à Jusante + NetworkHandler.UpHillNode: "out", # 4 - Interrupção à Montante + NetworkHandler.Confluence: "in and out", # 5 - Confluência + NetworkHandler.Ramification: "in and out", # 6 - Ramificação + NetworkHandler.AttributeChange: "in and out", # 7 - Mudança de Atributo + NetworkHandler.NodeNextToWaterBody: "in or out", # 8 - Nó próximo a corpo d'água + NetworkHandler.AttributeChangeFlag: None, # 9 - Nó de mudança de atributos conectado em linhas que não mudam de atributos + NetworkHandler.NodeOverload: None, # 10 - Há igual número de linhas (>1 para cada fluxo) entrando e saindo do nó + NetworkHandler.DisconnectedLine: None, # 11 - Nó conectado a uma linha perdida na rede (teria dois inícios de rede) + NetworkHandler.DitchNode: "in and out", # 12 - Nó de vala + NetworkHandler.SpillwayNode: "out", # 13 - Vertedouro + } # to avoid calculations in expense of memory nodeType = self.nodeTypeDict[node] # if node is introduced by operator's modification, it won't be saved to the layer if node not in self.nodeTypeDict.keys() and not self.unclassifiedNodes: self.unclassifiedNodes = True - QMessageBox.warning(self.iface.mainWindow(), self.tr('Error!'), self.tr('There are unclassified nodes! Node (re)creation process is recommended before this process.')) + QMessageBox.warning( + self.iface.mainWindow(), + self.tr("Error!"), + self.tr( + "There are unclassified nodes! Node (re)creation process is recommended before this process." + ), + ) return None, None, None flow = flowType[int(nodeType)] nodePointDict = self.nodeDict[node] # getting all connected lines to node that are not already validated - linesNotValidated = set( nodePointDict['start'] + nodePointDict['end'] ) - set(connectedValidLines) + linesNotValidated = set(nodePointDict["start"] + nodePointDict["end"]) - set( + connectedValidLines + ) # starting dicts of valid and invalid lines validLines, invalidLines = dict(), dict() if not flow: # flags have all lines flagged if nodeType == NetworkHandler.Flag: - reason = self.tr('Node was flagged upon classification (probably cannot be an ending hidrography node).') - invalidLines = { line.id() : line for line in linesNotValidated } + reason = self.tr( + "Node was flagged upon classification (probably cannot be an ending hidrography node)." + ) + invalidLines = {line.id(): line for line in linesNotValidated} elif nodeType == NetworkHandler.AttributeChangeFlag: - if nodePointDict['start'] and nodePointDict['end']: + if nodePointDict["start"] and nodePointDict["end"]: # in case manual error is inserted, this would raise an exception - line1, line2 = nodePointDict['start'][0], nodePointDict['end'][0] + line1, line2 = nodePointDict["start"][0], nodePointDict["end"][0] id1, id2 = line1.id(), line2.id() - reason = self.tr('Redundant node. Connected lines ({0}, {1}) share the same set of attributes.').format(id1, id2) + reason = self.tr( + "Redundant node. Connected lines ({0}, {1}) share the same set of attributes." + ).format(id1, id2) if line1 in linesNotValidated: il = line1 else: @@ -896,54 +1142,76 @@ def checkNodeTypeValidity(self, node, connectedValidLines, networkLayer, geomTyp self.nodeTypeDict[node] = NetworkHandler.Flag # reclassify node type into layer self.reclassifyNodeType[node] = NetworkHandler.Flag - reason = self.tr('Node was flagged upon classification (probably cannot be an ending hidrography node).') + reason = self.tr( + "Node was flagged upon classification (probably cannot be an ending hidrography node)." + ) elif nodeType == NetworkHandler.DisconnectedLine: # get line connected to node - lines = nodePointDict['start'] + nodePointDict['end'] + lines = nodePointDict["start"] + nodePointDict["end"] # just in case there's a node wrong manual reclassification so code doesn't raise an error ids = [str(line.id()) for line in lines] - invalidLines = { line.id() : line for line in lines } - reason = self.tr('Line {0} disconnected from network.').format(", ".join(ids)) + invalidLines = {line.id(): line for line in lines} + reason = self.tr("Line {0} disconnected from network.").format( + ", ".join(ids) + ) elif nodeType == NetworkHandler.NodeOverload: - reason = self.tr('Node is overloaded - 4 or more lines are flowing in (>= 2 lines) and out (>= 2 lines).') - invalidLines = { line.id() : line for line in linesNotValidated } + reason = self.tr( + "Node is overloaded - 4 or more lines are flowing in (>= 2 lines) and out (>= 2 lines)." + ) + invalidLines = {line.id(): line for line in linesNotValidated} return validLines, invalidLines, reason if not linesNotValidated: # if there are no lines to be validated, method returns None - return validLines, invalidLines, '' + return validLines, invalidLines, "" # if 'geomType' is not given, it must be evaluated if not geomType: geomType = networkLayer.geometryType() # reason message in case of invalidity - reason = '' + reason = "" for line in linesNotValidated: # getting last and initial node from analyzed line finalNode = self.getLastNode(lyr=networkLayer, feat=line, geomType=geomType) - initialNode = self.getFirstNode(lyr=networkLayer, feat=line, geomType=geomType) + initialNode = self.getFirstNode( + lyr=networkLayer, feat=line, geomType=geomType + ) # line ID lineID = line.id() # comparing extreme nodes to find out if flow is compatible to node type - if flow == 'in': + if flow == "in": if node == finalNode: if lineID not in validLines.keys(): validLines[lineID] = line elif lineID not in invalidLines.keys(): invalidLines[lineID] = line - reason = "".join([reason, self.tr('Line id={0} does not end at a node with IN flow type (node type is {1}). ').format(lineID, nodeType)]) - elif flow == 'out': + reason = "".join( + [ + reason, + self.tr( + "Line id={0} does not end at a node with IN flow type (node type is {1}). " + ).format(lineID, nodeType), + ] + ) + elif flow == "out": if node == initialNode: if lineID not in validLines.keys(): validLines[lineID] = line elif lineID not in invalidLines.keys(): invalidLines[lineID] = line - reason = "".join([reason, self.tr('Line id={0} does not start at a node with OUT flow type (node type is {1}). ')\ - .format(lineID, self.nodeTypeNameDict[nodeType])]) - elif flow == 'in and out': - if bool(len(nodePointDict['start'])) != bool(len(nodePointDict['end'])): + reason = "".join( + [ + reason, + self.tr( + "Line id={0} does not start at a node with OUT flow type (node type is {1}). " + ).format(lineID, self.nodeTypeNameDict[nodeType]), + ] + ) + elif flow == "in and out": + if bool(len(nodePointDict["start"])) != bool(len(nodePointDict["end"])): # if it's an 'in and out' flow and only one of dicts is filled, then there's an inconsistency invalidLines[lineID] = line - thisReason = self.tr('Lines are either flowing only in or out of node. Node classification is {0}.')\ - .format(self.nodeTypeNameDict[nodeType]) + thisReason = self.tr( + "Lines are either flowing only in or out of node. Node classification is {0}." + ).format(self.nodeTypeNameDict[nodeType]) if thisReason not in reason: reason = "".join([reason, thisReason]) elif node in [initialNode, finalNode]: @@ -951,15 +1219,29 @@ def checkNodeTypeValidity(self, node, connectedValidLines, networkLayer, geomTyp validLines[lineID] = line elif lineID not in invalidLines: invalidLines[lineID] = line - reason = "".join([reason, self.tr('Line {0} seems to be invalid (unable to point specific reason).').format(lineID)]) - elif flow == 'in or out': + reason = "".join( + [ + reason, + self.tr( + "Line {0} seems to be invalid (unable to point specific reason)." + ).format(lineID), + ] + ) + elif flow == "in or out": # these nodes can either be a waterway beginning or end # No invalidation reasons were thought at this point... if lineID not in validLines: validLines[lineID] = line - return validLines, invalidLines, reason + return validLines, invalidLines, reason - def checkNodeValidity(self, node, connectedValidLines, networkLayer, geomType=None, deltaLinesCheckList=None): + def checkNodeValidity( + self, + node, + connectedValidLines, + networkLayer, + geomType=None, + deltaLinesCheckList=None, + ): """ Checks whether a node is valid or not. :param node: (QgsPoint) node which lines connected to it are going to be verified. @@ -969,23 +1251,35 @@ def checkNodeValidity(self, node, connectedValidLines, networkLayer, geomType=No :param deltaLinesCheckList: (list-of-int) node types that must be checked for their connected lines angles. :return: (str) if node is invalid, returns the invalidation reason string. """ - + if not deltaLinesCheckList: - deltaLinesCheckList = [NetworkHandler.Confluence, NetworkHandler.Ramification] # nodes that have an unbalaced number ratio of flow in/out + deltaLinesCheckList = [ + NetworkHandler.Confluence, + NetworkHandler.Ramification, + ] # nodes that have an unbalaced number ratio of flow in/out # check coherence to node type and waterway flow - val, inval, reason = self.checkNodeTypeValidity(node=node, connectedValidLines=connectedValidLines,\ - networkLayer=networkLayer, geomType=geomType) + val, inval, reason = self.checkNodeTypeValidity( + node=node, + connectedValidLines=connectedValidLines, + networkLayer=networkLayer, + geomType=geomType, + ) # checking angle validity if self.nodeTypeDict[node] in deltaLinesCheckList: # check for connected lines angles coherence - val2, inval2, reason2 = self.validateDeltaLinesAngV2(node=node, networkLayer=networkLayer, connectedValidLines=connectedValidLines, geomType=geomType) + val2, inval2, reason2 = self.validateDeltaLinesAngV2( + node=node, + networkLayer=networkLayer, + connectedValidLines=connectedValidLines, + geomType=geomType, + ) # if any invalid line was validated on because of node type, it shall be moved to invalid dict if reason2: # updates reason if reason: reason = "; ".join([reason, reason2]) else: - reason = reason2 + reason = reason2 # remove any validated line in this iteration for lineId in inval2: val.pop(lineId, None) @@ -996,7 +1290,7 @@ def checkNodeValidity(self, node, connectedValidLines, networkLayer, geomType=No def getNextNodes(self, node, networkLayer, geomType=None): """ It returns a list of all other nodes for each line connected to target node. - :param node: (QgsPoint) node based on which next nodes will be gathered from. + :param node: (QgsPoint) node based on which next nodes will be gathered from. :param networkLayer: (QgsVectorLayer) hidrography line layer. :return: (list-of-QgsPoint) a list of the other node of lines connected to given hidrography node. """ @@ -1004,15 +1298,21 @@ def getNextNodes(self, node, networkLayer, geomType=None): geomType = networkLayer.geometryType() nextNodes = [] nodePointDict = self.nodeDict[node] - for line in nodePointDict['start']: + for line in nodePointDict["start"]: # if line starts at target node, the other extremity is a final node - nextNodes.append(self.getLastNode(lyr=networkLayer, feat=line, geomType=geomType)) - for line in nodePointDict['end']: + nextNodes.append( + self.getLastNode(lyr=networkLayer, feat=line, geomType=geomType) + ) + for line in nodePointDict["end"]: # if line ends at target node, the other extremity is a initial node - nextNodes.append(self.getFirstNode(lyr=networkLayer, feat=line, geomType=geomType)) + nextNodes.append( + self.getFirstNode(lyr=networkLayer, feat=line, geomType=geomType) + ) return nextNodes - def checkForStartConditions(self, node, validLines, networkLayer, nodeLayer, geomType=None): + def checkForStartConditions( + self, node, validLines, networkLayer, nodeLayer, geomType=None + ): """ Checks if any of next nodes is a contour condition to directioning process. :param node: (QgsPoint) node which needs to have its next nodes checked. @@ -1024,11 +1324,17 @@ def checkForStartConditions(self, node, validLines, networkLayer, nodeLayer, geo """ # node type granted as right as start conditions inContourConditionTypes = [NetworkHandler.DownHillNode, NetworkHandler.Sink] - outContourConditionTypes = [NetworkHandler.UpHillNode, NetworkHandler.WaterwayBegin, NetworkHandler.SpillwayNode] + outContourConditionTypes = [ + NetworkHandler.UpHillNode, + NetworkHandler.WaterwayBegin, + NetworkHandler.SpillwayNode, + ] if node in inContourConditionTypes + outContourConditionTypes: # if node IS a starting condition, method is not necessary - return False, '' - nodes = self.getNextNodes(node=node, networkLayer=networkLayer, geomType=geomType) + return False, "" + nodes = self.getNextNodes( + node=node, networkLayer=networkLayer, geomType=geomType + ) # for faster calculation nodeTypeDictAlias = self.nodeTypeDict nodeDictAlias = self.nodeDict @@ -1049,45 +1355,73 @@ def checkForStartConditions(self, node, validLines, networkLayer, nodeLayer, geo self.reclassifyNodeType[nn] = nodeType if nodeType in inContourConditionTypes: # if next node is a confirmed IN-flowing lines, no lines should start on it - line = nodeDictAlias[nn]['start'][0] if nodeDictAlias[nn]['start'] else None + line = ( + nodeDictAlias[nn]["start"][0] + if nodeDictAlias[nn]["start"] + else None + ) hasStartCondition = True elif nodeType in outContourConditionTypes: # if next node is a confirmed OUT-flowing lines, no lines should end on it - line = nodeDictAlias[nn]['end'][0] if nodeDictAlias[nn]['end'] else None + line = nodeDictAlias[nn]["end"][0] if nodeDictAlias[nn]["end"] else None hasStartCondition = True if line: # if line is given, then flipping it is necessary self.flipSingleLine(line=line, layer=networkLayer, geomType=geomType) # if a line is flipped it must be changed in self.nodeDict - self.updateNodeDict(node=node, line=line, networkLayer=networkLayer, geomType=geomType) + self.updateNodeDict( + node=node, line=line, networkLayer=networkLayer, geomType=geomType + ) flippedLines.append(line) flippedLinesIds.append(str(line.id())) # validLines.append(line) # for speed-up - initialNode = lambda x : self.getFirstNode(lyr=networkLayer, feat=x, geomType=geomType) - lastNode = lambda x : self.getLastNode(lyr=networkLayer, feat=x, geomType=geomType) + initialNode = lambda x: self.getFirstNode( + lyr=networkLayer, feat=x, geomType=geomType + ) + lastNode = lambda x: self.getLastNode( + lyr=networkLayer, feat=x, geomType=geomType + ) if flippedLines: # map is a for-loop in C - reclassifyNodeAlias = lambda x : nodeLayer.changeAttributeValue(self.nodeIdDict[x], 2, int(self.reclassifyNodeType[x])) \ - if self.reclassifyNode(node=x, nodeLayer=nodeLayer) \ - else False - map(reclassifyNodeAlias, chain(map(initialNode, flippedLines), map(lastNode, flippedLines))) + reclassifyNodeAlias = ( + lambda x: nodeLayer.changeAttributeValue( + self.nodeIdDict[x], 2, int(self.reclassifyNodeType[x]) + ) + if self.reclassifyNode(node=x, nodeLayer=nodeLayer) + else False + ) + map( + reclassifyNodeAlias, + chain(map(initialNode, flippedLines), map(lastNode, flippedLines)), + ) return hasStartCondition, flippedLinesIds def directNetwork(self, networkLayer, nodeLayer, nodeList=None): """ For every node over the frame [or set as a line beginning], checks for network coherence regarding - to previous node classification and its current direction. Method considers bordering points as + to previous node classification and its current direction. Method considers bordering points as correctly classified. :param networkLayer: (QgsVectorLayer) hidrography lines layer from which node are created from. :param nodeList: a list of target node points (QgsPoint). If not given, all nodeDict will be read. :return: (dict) flag dictionary ( { (QgsPoint) node : (str) reason } ), (dict) dictionaries ( { (int)feat_id : (QgsFeature)feat } ) of invalid and valid lines. """ - startingNodeTypes = [NetworkHandler.UpHillNode, NetworkHandler.WaterwayBegin, NetworkHandler.SpillwayNode] # node types that are over the frame contour and line BEGINNINGS - deltaLinesCheckList = [NetworkHandler.Confluence, NetworkHandler.Ramification] # nodes that have an unbalaced number ratio of flow in/out + startingNodeTypes = [ + NetworkHandler.UpHillNode, + NetworkHandler.WaterwayBegin, + NetworkHandler.SpillwayNode, + ] # node types that are over the frame contour and line BEGINNINGS + deltaLinesCheckList = [ + NetworkHandler.Confluence, + NetworkHandler.Ramification, + ] # nodes that have an unbalaced number ratio of flow in/out if not nodeList: # 'nodeList' must start with all nodes that are on the frame (assumed to be well directed) - nodeList = [node for node, nodeType in self.nodeTypeDict.items() if nodeType in startingNodeTypes] + nodeList = [ + node + for node, nodeType in self.nodeTypeDict.items() + if nodeType in startingNodeTypes + ] # if no node to start the process is found, process ends here if not nodeList: return None, None, self.tr("No network starting point was found") @@ -1104,8 +1438,8 @@ def directNetwork(self, networkLayer, nodeLayer, nodeList=None): for node in nodeList: # first thing to be done: check if there are more than one non-validated line (hence, enough information for a decision) if node in self.nodeDict: - startLines = self.nodeDict[node]['start'] - endLines = self.nodeDict[node]['end'] + startLines = self.nodeDict[node]["start"] + endLines = self.nodeDict[node]["end"] if node not in self.nodeTypeDict: # in case node is not classified self.nodeTypeDict[node] = self.classifyNode([node, nodeLayer]) @@ -1117,33 +1451,57 @@ def directNetwork(self, networkLayer, nodeLayer, nodeList=None): nodeLines = startLines + endLines validLinesList = validLines.values() if len(set(nodeLines) - set(validLinesList)) > 1: - hasStartCondition, flippedLines = self.checkForStartConditions(node=node, validLines=validLinesList, networkLayer=networkLayer, nodeLayer=nodeLayer, geomType=geomType) + hasStartCondition, flippedLines = self.checkForStartConditions( + node=node, + validLines=validLinesList, + networkLayer=networkLayer, + nodeLayer=nodeLayer, + geomType=geomType, + ) if hasStartCondition: flippedLinesIds |= set(flippedLines) else: # if it is not connected to a start condition, check if node has a valid line connected to it - if (set(nodeLines) & set(validLinesList)): + if set(nodeLines) & set(validLinesList): # if it does and, check if it is a valid node - val, inval, reason = self.checkNodeValidity(node=node, connectedValidLines=validLinesList,\ - networkLayer=networkLayer, deltaLinesCheckList=deltaLinesCheckList, geomType=geomType) + val, inval, reason = self.checkNodeValidity( + node=node, + connectedValidLines=validLinesList, + networkLayer=networkLayer, + deltaLinesCheckList=deltaLinesCheckList, + geomType=geomType, + ) # if node has a valid line connected to it and it is valid, then non-validated lines are proven to be in conformity to # start conditions, then they should be validated and node should be set as visited if reason: - # if there are more than 1 line not validated yet and no start conditions around it, - # node will neither be checked nor marked as visited + # if there are more than 1 line not validated yet and no start conditions around it, + # node will neither be checked nor marked as visited continue # check coherence to node type and waterway flow - val, inval, reason = self.checkNodeValidity(node=node, connectedValidLines=validLinesList,\ - networkLayer=networkLayer, deltaLinesCheckList=deltaLinesCheckList, geomType=geomType) + val, inval, reason = self.checkNodeValidity( + node=node, + connectedValidLines=validLinesList, + networkLayer=networkLayer, + deltaLinesCheckList=deltaLinesCheckList, + geomType=geomType, + ) # nodes to be removed from next nodes removeNode = [] # if a reason is given, then node is invalid (even if there are no invalid lines connected to it). if reason: # try to fix node issues # note that val, inval and reason MAY BE MODIFIED - and there is no problem... - flippedLinesIds_, mergedLinesString_ = self.fixNodeFlagsNew(node=node, valDict=val, invalidDict=inval, reason=reason, \ - connectedValidLines=validLinesList, networkLayer=networkLayer, \ - nodeLayer=nodeLayer, geomType=geomType, deltaLinesCheckList=deltaLinesCheckList) + flippedLinesIds_, mergedLinesString_ = self.fixNodeFlagsNew( + node=node, + valDict=val, + invalidDict=inval, + reason=reason, + connectedValidLines=validLinesList, + networkLayer=networkLayer, + nodeLayer=nodeLayer, + geomType=geomType, + deltaLinesCheckList=deltaLinesCheckList, + ) # keep track of all modifications made if flippedLinesIds_: # IDs not registered yet will be added to final list @@ -1155,16 +1513,20 @@ def directNetwork(self, networkLayer, nodeLayer, nodeList=None): if not mergedLinesString: mergedLinesString = mergedLinesString_ else: - ", ".join([mergedLinesString, mergedLinesString_]) + ", ".join([mergedLinesString, mergedLinesString_]) # if node is still invalid, add to nodeFlagList and add/update its reason if reason: nodeFlags[node] = reason # get next nodes connected to invalid lines for line in inval.values(): if line in endLines: - removeNode.append(self.getFirstNode(lyr=networkLayer, feat=line)) + removeNode.append( + self.getFirstNode(lyr=networkLayer, feat=line) + ) else: - removeNode.append(self.getLastNode(lyr=networkLayer, feat=line)) + removeNode.append( + self.getLastNode(lyr=networkLayer, feat=line) + ) # set node as visited if node not in visitedNodes: visitedNodes.append(node) @@ -1172,17 +1534,21 @@ def directNetwork(self, networkLayer, nodeLayer, nodeList=None): validLines.update(val) invalidLines.update(inval) # get next iteration nodes - newNextNodes += self.getNextNodes(node=node, networkLayer=networkLayer, geomType=geomType) + newNextNodes += self.getNextNodes( + node=node, networkLayer=networkLayer, geomType=geomType + ) # remove next nodes connected to invalid lines if removeNode: - newNextNodes = list( set(newNextNodes) - set(removeNode) ) + newNextNodes = list(set(newNextNodes) - set(removeNode)) # remove nodes that were already visited - newNextNodes = list( set(newNextNodes) - set(visitedNodes) ) + newNextNodes = list(set(newNextNodes) - set(visitedNodes)) # if new nodes are detected, repeat for those nodeList = newNextNodes newNextNodes = [] # log all features that were merged and/or flipped - self.logAlteredFeatures(flippedLines=flippedLinesIds, mergedLinesString=mergedLinesString) + self.logAlteredFeatures( + flippedLines=flippedLinesIds, mergedLinesString=mergedLinesString + ) return nodeFlags, invalidLines, validLines # method for automatic fix @@ -1193,12 +1559,12 @@ def getReasonType(self, reason): :return: (int) reason type. """ fixableReasonExcertsDict = { - self.tr("does not end at a node with IN flow type") : 1, - self.tr("does not start at a node with OUT flow type") : 2, - self.tr("have conflicting directions") : 3, - self.tr('Redundant node.') : 4, - self.tr('Node was flagged upon classification') : 5 - } + self.tr("does not end at a node with IN flow type"): 1, + self.tr("does not start at a node with OUT flow type"): 2, + self.tr("have conflicting directions"): 3, + self.tr("Redundant node."): 4, + self.tr("Node was flagged upon classification"): 5, + } for r in fixableReasonExcertsDict: if r in reason: return fixableReasonExcertsDict[r] @@ -1251,10 +1617,10 @@ def flipInvalidLine(self, node, networkLayer, validLines, geomType=None): :return: (QgsFeature) flipped line. """ # get dictionaries for speed-up - endDict = self.nodeDict[node]['end'] - startDict = self.nodeDict[node]['start'] + endDict = self.nodeDict[node]["end"] + startDict = self.nodeDict[node]["start"] amountLines = len(endDict + startDict) - # it is considered that + # it is considered that if endDict: # get invalid line connected to node invalidLine = list(set(endDict) - set(validLines)) @@ -1279,20 +1645,20 @@ def fixAttributeChangeFlag(self, node, networkLayer): :param networkLayer: (QgsVectorLayer) network lines layer. :return: (str) string containing which line was line the other. """ - line_a = self.nodeDict[node]['end'][0] - line_b = self.nodeDict[node]['start'][0] + line_a = self.nodeDict[node]["end"][0] + line_b = self.nodeDict[node]["start"][0] # lines have their order changed so that the deleted line is the intial one self.mergeNetworkLines(line_a=line_b, line_b=line_a, layer=networkLayer) # the updated feature should be updated into node dict for the NEXT NODE! nn = self.getLastNode(lyr=networkLayer, feat=line_b, geomType=1) - if nn in self.nodeDict: # TODO: @jpesperidiao verifica isso por favor - for line in self.nodeDict[nn]['end']: + if nn in self.nodeDict: # TODO: @jpesperidiao verifica isso por favor + for line in self.nodeDict[nn]["end"]: if line.id() == line_b.id(): - self.nodeDict[nn]['end'].remove(line) - self.nodeDict[nn]['end'].append(line_b) + self.nodeDict[nn]["end"].remove(line) + self.nodeDict[nn]["end"].append(line_b) # remove attribute change flag node (there are no lines connected to it anymore) self.nodesToPop.append(node) - return self.tr('{0} to {1}').format(line_a.id(), line_b.id()) + return self.tr("{0} to {1}").format(line_a.id(), line_b.id()) def updateNodeDict(self, node, line, networkLayer, geomType=None): """ @@ -1310,7 +1676,12 @@ def reclassifyNode(self, node, nodeLayer): :param node: (QgsPoint) node to be reclassified. :return: (bool) whether point was modified. """ - immutableTypes = [NetworkHandler.UpHillNode, NetworkHandler.DownHillNode, NetworkHandler.WaterwayBegin, NetworkHandler.SpillwayNode] + immutableTypes = [ + NetworkHandler.UpHillNode, + NetworkHandler.DownHillNode, + NetworkHandler.WaterwayBegin, + NetworkHandler.SpillwayNode, + ] if self.nodeTypeDict[node] in immutableTypes: # if node type is immutable, reclassification is not possible return False @@ -1325,7 +1696,9 @@ def reclassifyNode(self, node, nodeLayer): self.reclassifyNodeType[node] = newType return True - def fixDeltaFlag(self, node, networkLayer, validLines, reason, reasonType=3, geomType=None): + def fixDeltaFlag( + self, node, networkLayer, validLines, reason, reasonType=3, geomType=None + ): """ Tries to fix nodes flagged because of their delta angles. :param node: (QgsPoint) invalid node. @@ -1337,7 +1710,7 @@ def fixDeltaFlag(self, node, networkLayer, validLines, reason, reasonType=3, geo :return: (QgsFeature) line to be flipped. If no line is identified as flippable, None is returned. """ flipCandidates = self.getLineIdFromReason(reason=reason, reasonType=reasonType) - for line in self.nodeDict[node]['start'] + self.nodeDict[node]['end']: + for line in self.nodeDict[node]["start"] + self.nodeDict[node]["end"]: lineId = str(line.id()) if lineId in flipCandidates and line not in validLines: # flip line that is exposed in invalidation reason and is not previously validated @@ -1346,7 +1719,18 @@ def fixDeltaFlag(self, node, networkLayer, validLines, reason, reasonType=3, geo # if no line attend necessary requirements for flipping return None - def fixNodeFlagsNew(self, node, valDict, invalidDict, reason, connectedValidLines, networkLayer, nodeLayer, geomType=None, deltaLinesCheckList=None): + def fixNodeFlagsNew( + self, + node, + valDict, + invalidDict, + reason, + connectedValidLines, + networkLayer, + nodeLayer, + geomType=None, + deltaLinesCheckList=None, + ): """ Tries to fix issues flagged on node """ @@ -1364,53 +1748,85 @@ def fixNodeFlagsNew(self, node, valDict, invalidDict, reason, connectedValidLine # original message: self.tr('Line {0} does not end at a node with IN flow type (node type is {1}). ') # original message: self.tr('Line {0} does not start at a node with OUT flow type (node type is {1}). ') # get flipping candidates - featIdFlipCandidates = self.getLineIdFromReason(reason=reason, reasonType=reasonType) + featIdFlipCandidates = self.getLineIdFromReason( + reason=reason, reasonType=reasonType + ) for lineId in featIdFlipCandidates: line = invalidDict[int(lineId)] if line not in connectedValidLines: # only non-valid lines may be modified - self.flipSingleLine(line=line, layer=networkLayer, geomType=geomType) + self.flipSingleLine( + line=line, layer=networkLayer, geomType=geomType + ) flippedLinesIds.append(lineId) flippedLines.append(line) elif reasonType == 3: # original message: self.tr('Lines {0} and {1} have conflicting directions ({2:.2f} deg).') - line = self.fixDeltaFlag(node=node, networkLayer=networkLayer, reason=reason, validLines=connectedValidLines, reasonType=reasonType) + line = self.fixDeltaFlag( + node=node, + networkLayer=networkLayer, + reason=reason, + validLines=connectedValidLines, + reasonType=reasonType, + ) if line: # if a line is flipped it must be changed in self.nodeDict - self.updateNodeDict(node=node, line=line, networkLayer=networkLayer, geomType=geomType) + self.updateNodeDict( + node=node, line=line, networkLayer=networkLayer, geomType=geomType + ) elif reasonType == 4: # original message: self.tr('Redundant node. Connected lines ({0}, {1}) share the same set of attributes.') - mergedLinesString = self.fixAttributeChangeFlag(node=node, networkLayer=networkLayer) + mergedLinesString = self.fixAttributeChangeFlag( + node=node, networkLayer=networkLayer + ) elif reasonType == 5: # original message: self.tr('Node was flagged upon classification (probably cannot be an ending hidrography node).') - line = self.flipInvalidLine(node=node, networkLayer=networkLayer, validLines=connectedValidLines, geomType=geomType) + line = self.flipInvalidLine( + node=node, + networkLayer=networkLayer, + validLines=connectedValidLines, + geomType=geomType, + ) if line: flippedLinesIds.append(str(line.id())) flippedLines.append(line) # if a line is flipped it must be changed in self.nodeDict - self.updateNodeDict(node=node, line=line, networkLayer=networkLayer, geomType=geomType) + self.updateNodeDict( + node=node, line=line, networkLayer=networkLayer, geomType=geomType + ) else: # in case, for some reason, a strange value is given to reasonType - return [], '' + return [], "" # for speed-up - initialNode = lambda x : self.getFirstNode(lyr=networkLayer, feat=x, geomType=geomType) - lastNode = lambda x : self.getLastNode(lyr=networkLayer, feat=x, geomType=geomType) + initialNode = lambda x: self.getFirstNode( + lyr=networkLayer, feat=x, geomType=geomType + ) + lastNode = lambda x: self.getLastNode( + lyr=networkLayer, feat=x, geomType=geomType + ) # reclassification re-evalution is only needed if lines were flipped if flippedLinesIds: # re-classify nodes connected to flipped lines before re-checking # map is a for-loop in C - reclassifyNodeAlias = lambda x : nodeLayer.changeAttributeValue(self.nodeIdDict[x], 2, int(self.reclassifyNodeType[x])) \ - if self.reclassifyNode(node=x, nodeLayer=nodeLayer) \ - else None - map(reclassifyNodeAlias, chain(map(initialNode, flippedLines), map(lastNode, flippedLines))) + reclassifyNodeAlias = ( + lambda x: nodeLayer.changeAttributeValue( + self.nodeIdDict[x], 2, int(self.reclassifyNodeType[x]) + ) + if self.reclassifyNode(node=x, nodeLayer=nodeLayer) + else None + ) + map( + reclassifyNodeAlias, + chain(map(initialNode, flippedLines), map(lastNode, flippedLines)), + ) # check if node is fixed and update its dictionaries and invalidation reason valDict, invalidDict, reason = self.checkNodeValidity( node=node, connectedValidLines=connectedValidLines, networkLayer=networkLayer, geomType=geomType, - deltaLinesCheckList=deltaLinesCheckList - ) + deltaLinesCheckList=deltaLinesCheckList, + ) return flippedLinesIds, mergedLinesString def logAlteredFeatures(self, flippedLines, mergedLinesString, feedback=None): @@ -1421,15 +1837,36 @@ def logAlteredFeatures(self, flippedLines, mergedLinesString, feedback=None): :return: (bool) whether or not a message was shown. """ # building warning message - warning = '' + warning = "" if flippedLines: - warning = "".join([warning, self.tr("Lines that were flipped while directioning hidrography lines: {0}\n\n").format(", ".join(flippedLines))]) + warning = "".join( + [ + warning, + self.tr( + "Lines that were flipped while directioning hidrography lines: {0}\n\n" + ).format(", ".join(flippedLines)), + ] + ) elif mergedLinesString: - warning = "".join([warning, self.tr("Lines that were merged while directioning hidrography lines: {0}\n\n").format(mergedLinesString)]) + warning = "".join( + [ + warning, + self.tr( + "Lines that were merged while directioning hidrography lines: {0}\n\n" + ).format(mergedLinesString), + ] + ) if warning: # warning is only raised when there were flags fixed if feedback is not None: - warning = "".join([self.tr('\nVerify Network Directioning: Flipped/Merged Lines\n'), warning]) + warning = "".join( + [ + self.tr( + "\nVerify Network Directioning: Flipped/Merged Lines\n" + ), + warning, + ] + ) feedback.pushInfo(warning) return True return False @@ -1441,23 +1878,25 @@ def getNodeTypeDictFromNodeLayer(self, networkNodeLayer, feedback=None): :return: (tuple-of-dict) node type dict and node id dict, respectively """ nodeTypeDict, nodeIdDict = dict(), dict() - isMulti = QgsWkbTypes.isMultiType(int(networkNodeLayer.wkbType())) + isMulti = QgsWkbTypes.isMultiType(networkNodeLayer.wkbType()) featCount = networkNodeLayer.featureCount() - size = 100/featCount if featCount else 0 + size = 100 / featCount if featCount else 0 for current, feat in enumerate(networkNodeLayer.getFeatures()): if feedback is not None and feedback.isCanceled(): break if isMulti: - node = feat.geometry().asMultiPoint()[0] + node = feat.geometry().asMultiPoint()[0] else: node = feat.geometry().asPoint() - nodeTypeDict[node] = int(feat['node_type']) + nodeTypeDict[node] = int(feat["node_type"]) nodeIdDict[node] = feat.id() if feedback is not None: feedback.setProgress(size * current) return nodeTypeDict, nodeIdDict - def clearAuxiliaryLinesLayer(self, invalidLinesLayer, lineIdList=None, commitToLayer=False): + def clearAuxiliaryLinesLayer( + self, invalidLinesLayer, lineIdList=None, commitToLayer=False + ): """ Clears all (or a given list of points) invalid lines from auxiliary lines layer. :param invalidLinesLayer: (QgsVectorLayer) invalid lines layer. @@ -1465,14 +1904,20 @@ def clearAuxiliaryLinesLayer(self, invalidLinesLayer, lineIdList=None, commitToL :param commitToLayer: (bool) indicates whether changes should be commited to layer. """ # invalid reason texts - invalidReason = self.tr('Connected to invalid hidrography node.') - nonVisitedReason = self.tr('Line not yet visited.') - invalidLinesLayer.beginEditCommand('Clear Invalid Lines') + invalidReason = self.tr("Connected to invalid hidrography node.") + nonVisitedReason = self.tr("Line not yet visited.") + invalidLinesLayer.beginEditCommand("Clear Invalid Lines") if lineIdList is None: # define a function to get only feature ids for invalid lines registered in invalidLinesLayer and use it in map, for speed-up - getInvalidLineFunc = lambda feat : feat.id() if feat['reason'] in [invalidReason, nonVisitedReason] else -9999 + getInvalidLineFunc = ( + lambda feat: feat.id() + if feat["reason"] in [invalidReason, nonVisitedReason] + else -9999 + ) # list/set combination to remove possible duplicates of -9999 and avoid unnecessary calculation - lineIdList = list(set(map(getInvalidLineFunc, invalidLinesLayer.getFeatures()))) + lineIdList = list( + set(map(getInvalidLineFunc, invalidLinesLayer.getFeatures())) + ) if -9999 in lineIdList: lineIdList.remove(-9999) invalidLinesLayer.deleteFeatures(lineIdList) @@ -1481,7 +1926,9 @@ def clearAuxiliaryLinesLayer(self, invalidLinesLayer, lineIdList=None, commitToL if commitToLayer: invalidLinesLayer.commitChanges() - def getAuxiliaryLines(self, fields, invalidLinesDict, nonValidatedLines, networkLayerName): + def getAuxiliaryLines( + self, fields, invalidLinesDict, nonValidatedLines, networkLayerName + ): """ Populate from auxiliary lines layer with all invalid lines. :param invalidLinesDict: (dict) dictionary containing all invalid lines to be displayed. @@ -1489,13 +1936,17 @@ def getAuxiliaryLines(self, fields, invalidLinesDict, nonValidatedLines, network :param commitToLayer: (bool) indicates whether changes should be commited to layer. """ # prepare generic variables that will be reused - invalidReason = self.tr('Connected to invalid hidrography node.') - nonVisitedReason = self.tr('Line not yet visited.') + invalidReason = self.tr("Connected to invalid hidrography node.") + nonVisitedReason = self.tr("Line not yet visited.") # initiate new features list featList = [] # pre-declaring method to make it faster - newInvalidFeatFunc = lambda x : self.createNewInvalidLineFeature(feat_geom=x[0], reason=invalidReason, fields=fields) - newNonVisitedFeatFunc = lambda x : self.createNewInvalidLineFeature(feat_geom=x[0], reason=nonVisitedReason, fields=fields) + newInvalidFeatFunc = lambda x: self.createNewInvalidLineFeature( + feat_geom=x[0], reason=invalidReason, fields=fields + ) + newNonVisitedFeatFunc = lambda x: self.createNewInvalidLineFeature( + feat_geom=x[0], reason=nonVisitedReason, fields=fields + ) # add all non-validated features for line in nonValidatedLines: # create new feture @@ -1503,35 +1954,57 @@ def getAuxiliaryLines(self, fields, invalidLinesDict, nonValidatedLines, network # add it to new features list featList.append(feat) # add invalid lines - for lineId, line in invalidLinesDict.items(): + for lineId, line in invalidLinesDict.items(): # create new feture feat = newInvalidFeatFunc([line.geometry(), lineId]) # add it to new features list featList.append(feat) return featList - - def verifyNetworkDirectioning(self, networkLayer, networkNodeLayer, frame, searchRadius, waterBodyClasses=None, waterSinkLayer=None, spillwayLayer=None, ditchLayer=None, max_amount_cycles=1, attributeBlackList=None, feedback=None, selectValid=False, excludePrimaryKeys=True, ignoreVirtualFields=True): - fieldList = self.layerHandler.getAttributesFromBlackList(networkLayer, \ - attributeBlackList=attributeBlackList,\ - ignoreVirtualFields=ignoreVirtualFields,\ - excludePrimaryKeys=excludePrimaryKeys) + + def verifyNetworkDirectioning( + self, + networkLayer, + networkNodeLayer, + frame, + searchRadius, + waterBodyClasses=None, + waterSinkLayer=None, + spillwayLayer=None, + ditchLayer=None, + max_amount_cycles=1, + attributeBlackList=None, + feedback=None, + selectValid=False, + excludePrimaryKeys=True, + ignoreVirtualFields=True, + ): + fieldList = self.layerHandler.getAttributesFromBlackList( + networkLayer, + attributeBlackList=attributeBlackList, + ignoreVirtualFields=ignoreVirtualFields, + excludePrimaryKeys=excludePrimaryKeys, + ) waterBodyClasses = [] if waterBodyClasses is None else waterBodyClasses # update createNetworkNodesProcess object node dictionary stepCount = 0 if feedback is not None: - multiStepFeedback = QgsProcessingMultiStepFeedback(max_amount_cycles, feedback) + multiStepFeedback = QgsProcessingMultiStepFeedback( + max_amount_cycles, feedback + ) multiStepFeedback.setCurrentStep(stepCount) else: multiStepFeedback = None self.nodesToPop = [] self.reclassifyNodeType = dict() if feedback is not None: - multiStepFeedback.pushInfo('Identifying nodes...') + multiStepFeedback.pushInfo("Identifying nodes...") multiStepFeedback.setCurrentStep(stepCount) stepCount += 1 - self.nodeDict = self.identifyAllNodes(networkLayer=networkLayer, feedback=multiStepFeedback) + self.nodeDict = self.identifyAllNodes( + networkLayer=networkLayer, feedback=multiStepFeedback + ) if feedback is not None: - multiStepFeedback.pushInfo('Getting auxiliar spatial indexes...') + multiStepFeedback.pushInfo("Getting auxiliar spatial indexes...") multiStepFeedback.setCurrentStep(stepCount) stepCount += 1 auxIndexStructure = self.getAuxIndexStructure( @@ -1540,13 +2013,13 @@ def verifyNetworkDirectioning(self, networkLayer, networkNodeLayer, frame, searc waterSinkLayer=waterSinkLayer, spillwayLayer=spillwayLayer, ditchLayer=ditchLayer, - feedback=multiStepFeedback + feedback=multiStepFeedback, ) networkLayerGeomType = networkLayer.geometryType() networkLayer.startEditing() networkNodeLayer.startEditing() - # declare reclassification function from createNetworkNodesProcess object - parameter is [node, nodeTypeDict] - self.classifyNode = lambda x : self.nodeType( + # declare reclassification function from createNetworkNodesProcess object - parameter is [node, nodeTypeDict] + self.classifyNode = lambda x: self.nodeType( nodePoint=x[0], networkLayer=networkLayer, frameLyrContourList=frame, @@ -1558,13 +2031,15 @@ def verifyNetworkDirectioning(self, networkLayer, networkNodeLayer, frame, searc networkLayerGeomType=networkLayerGeomType, ditchLayer=ditchLayer, fieldList=fieldList, - auxIndexStructure=auxIndexStructure - ) + auxIndexStructure=auxIndexStructure, + ) if feedback is not None: - multiStepFeedback.pushInfo('Getting node type dictionary...') + multiStepFeedback.pushInfo("Getting node type dictionary...") multiStepFeedback.setCurrentStep(stepCount) stepCount += 1 - self.nodeTypeDict, self.nodeIdDict = self.getNodeTypeDictFromNodeLayer(networkNodeLayer=networkNodeLayer, feedback=multiStepFeedback) + self.nodeTypeDict, self.nodeIdDict = self.getNodeTypeDictFromNodeLayer( + networkNodeLayer=networkNodeLayer, feedback=multiStepFeedback + ) # initiate nodes, invalid/valid lines dictionaries nodeFlags, inval, val = dict(), dict(), dict() # cycle count start @@ -1572,26 +2047,33 @@ def verifyNetworkDirectioning(self, networkLayer, networkNodeLayer, frame, searc max_amount_cycles = max_amount_cycles if max_amount_cycles > 0 else 1 # validation method FINALLY starts... # to speed up modifications made to layers - networkNodeLayer.beginEditCommand('Reclassify Nodes') - networkLayer.beginEditCommand('Flip/Merge Lines') + networkNodeLayer.beginEditCommand("Reclassify Nodes") + networkLayer.beginEditCommand("Flip/Merge Lines") cycleCount = 0 while True: if feedback is not None: - multiStepFeedback.pushInfo('Starting cycle {0}...'.format(cycleCount)) + multiStepFeedback.pushInfo("Starting cycle {0}...".format(cycleCount)) multiStepFeedback.setCurrentStep(stepCount) stepCount += 1 - nodeFlags_, inval_, val_ = self.directNetwork(networkLayer=networkLayer, nodeLayer=networkNodeLayer) + nodeFlags_, inval_, val_ = self.directNetwork( + networkLayer=networkLayer, nodeLayer=networkNodeLayer + ) cycleCount += 1 # Log amount of cycles completed - cycleCountLog = self.tr("Cycle {0}/{1} completed.").format(cycleCount, max_amount_cycles) + cycleCountLog = self.tr("Cycle {0}/{1} completed.").format( + cycleCount, max_amount_cycles + ) if feedback is not None: multiStepFeedback.pushInfo(cycleCountLog) multiStepFeedback.setCurrentStep(cycleCount) self.reclassifyNodeType = dict() # stop conditions: max amount of cycles exceeded, new flags is the same as previous flags (there are no new issues) and no change # change to valid lines list was made (meaning that the algorithm did not change network state) or no flags found - if (cycleCount == max_amount_cycles) or (not nodeFlags_) or \ - (set(nodeFlags.keys()) == set(nodeFlags_.keys()) and val == val_): + if ( + (cycleCount == max_amount_cycles) + or (not nodeFlags_) + or (set(nodeFlags.keys()) == set(nodeFlags_.keys()) and val == val_) + ): # copy values to final dict nodeFlags, inval, val = nodeFlags_, inval_, val_ # no more modifications to those layers will be done @@ -1599,7 +2081,9 @@ def verifyNetworkDirectioning(self, networkLayer, networkNodeLayer, frame, searc networkNodeLayer.endEditCommand() # try to load auxiliary line layer to fill it with invalid lines featList = self.getFlagLines(networkLayer, val, inval) - invalidLinesLog = self.tr("Invalid lines were exposed in line flags layer.") + invalidLinesLog = self.tr( + "Invalid lines were exposed in line flags layer." + ) if feedback is not None: multiStepFeedback.pushInfo(invalidLinesLog) multiStepFeedback.setCurrentStep(max_amount_cycles) @@ -1622,16 +2106,23 @@ def verifyNetworkDirectioning(self, networkLayer, networkNodeLayer, frame, searc if selectValid: networkLayer.selectByIds(list(val.keys())) if feedback is not None: - percValid = float(len(val))*100.0/float(networkLayer.featureCount()) if networkLayer.featureCount() else 0 + percValid = ( + float(len(val)) * 100.0 / float(networkLayer.featureCount()) + if networkLayer.featureCount() + else 0 + ) if nodeFlags: - msg = self.tr('{0} nodes may be invalid ({1:.2f}' + '% of network is well directed). Check flags.')\ - .format(len(nodeFlags), percValid) + msg = self.tr( + "{0} nodes may be invalid ({1:.2f}" + + "% of network is well directed). Check flags." + ).format(len(nodeFlags), percValid) else: - msg = self.tr('{1:.2f}' + '% of network is well directed.')\ - .format(len(nodeFlags), percValid) + msg = self.tr("{1:.2f}" + "% of network is well directed.").format( + len(nodeFlags), percValid + ) multiStepFeedback.pushInfo(msg) return nodeFlags, featList, self.nodeIdDict - + def getFlagLines(self, networkLayer, val, inval): # get non-validated lines and add it to invalid lines layer as well nonValidatedLines = set() @@ -1641,10 +2132,14 @@ def getFlagLines(self, networkLayer, val, inval): # ignore if line are validated continue nonValidatedLines.add(line) - featList = self.getAuxiliaryLines(fields=self.getFlagFields(), invalidLinesDict=inval,\ - nonValidatedLines=nonValidatedLines, networkLayerName=networkLayer.name()) + featList = self.getAuxiliaryLines( + fields=self.getFlagFields(), + invalidLinesDict=inval, + nonValidatedLines=nonValidatedLines, + networkLayerName=networkLayer.name(), + ) return featList - + def mergeNetworkLines(self, line_a, line_b, layer): """ Merge 2 lines of the same layer (it is assumed that they share the same set od attributes - except for ID and geometry). @@ -1655,7 +2150,7 @@ def mergeNetworkLines(self, line_a, line_b, layer): :return: (bool) True if method runs OK or False, if lines do not touch. """ # check if original layer is a multipart - isMulti = QgsWkbTypes.isMultiType(int(layer.wkbType())) + isMulti = QgsWkbTypes.isMultiType(layer.wkbType()) # retrieve lines geometries geometry_a = line_a.geometry() geometry_b = line_b.geometry() @@ -1676,16 +2171,16 @@ def mergeNetworkLines(self, line_a, line_b, layer): layer.updateFeature(line_a) return True return False - + def getFlagFields(self): fields = QgsFields() - fields.append(QgsField('reason',QVariant.String)) + fields.append(QgsField("reason", QVariant.String)) return fields def createNewInvalidLineFeature(self, feat_geom, reason, fields): """ Creates a new feature to be added to invalid lines layer. - :param feat_geom: (QgsGeometry) + :param feat_geom: (QgsGeometry) :param reason: (str) reason of line invalidation. :param fields: (QgsFields) object containing all fields from layer. :return: (QgsFeature) new feature. @@ -1694,4 +2189,4 @@ def createNewInvalidLineFeature(self, feat_geom, reason, fields): feat = QgsFeature(fields) # set geometry feat.setGeometry(feat_geom) - return feat \ No newline at end of file + return feat diff --git a/DsgTools/core/GeometricTools/spatialRelationsHandler.py b/DsgTools/core/GeometricTools/spatialRelationsHandler.py index 87da0168e..537b1b9da 100644 --- a/DsgTools/core/GeometricTools/spatialRelationsHandler.py +++ b/DsgTools/core/GeometricTools/spatialRelationsHandler.py @@ -20,23 +20,24 @@ * * ***************************************************************************/ """ -from __future__ import absolute_import + +import concurrent.futures from itertools import tee, combinations from collections import defaultdict, OrderedDict - -from qgis.core import (Qgis, - QgsFeature, - QgsProject, - QgsGeometry, - QgsExpression, - QgsVectorLayer, - QgsSpatialIndex, - QgsFeatureRequest, - QgsProcessingContext, - QgsProcessingFeedback, - QgsProcessingMultiStepFeedback) -from qgis.analysis import QgsGeometrySnapper, QgsInternalGeometrySnapper +import os + +from qgis.core import ( + QgsProject, + QgsGeometry, + QgsExpression, + QgsVectorLayer, + QgsSpatialIndex, + QgsProcessingContext, + QgsProcessingFeedback, + QgsProcessingMultiStepFeedback, + QgsFeatureRequest, +) from qgis.PyQt.Qt import QObject from qgis.PyQt.QtCore import QRegExp, QCoreApplication from qgis.PyQt.QtGui import QRegExpValidator @@ -46,29 +47,48 @@ from .layerHandler import LayerHandler from DsgTools.core.DSGToolsProcessingAlgs.algRunner import AlgRunner + class SpatialRelationsHandler(QObject): __predicates = ( - QCoreApplication.translate("EnforceSpatialRulesAlgorithm", "equals"), - QCoreApplication.translate("EnforceSpatialRulesAlgorithm", "is not equals"), - QCoreApplication.translate("EnforceSpatialRulesAlgorithm", "disjoint"), - QCoreApplication.translate("EnforceSpatialRulesAlgorithm", "intersects"), - QCoreApplication.translate("EnforceSpatialRulesAlgorithm", "does not intersect"), - QCoreApplication.translate("EnforceSpatialRulesAlgorithm", "touches"), - QCoreApplication.translate("EnforceSpatialRulesAlgorithm", "does not touch"), - QCoreApplication.translate("EnforceSpatialRulesAlgorithm", "crosses"), - QCoreApplication.translate("EnforceSpatialRulesAlgorithm", "does not cross"), - QCoreApplication.translate("EnforceSpatialRulesAlgorithm", "within"), - QCoreApplication.translate("EnforceSpatialRulesAlgorithm", "is not within"), - QCoreApplication.translate("EnforceSpatialRulesAlgorithm", "overlaps"), - QCoreApplication.translate("EnforceSpatialRulesAlgorithm", "does not overlap"), - QCoreApplication.translate("EnforceSpatialRulesAlgorithm", "contains"), - QCoreApplication.translate("EnforceSpatialRulesAlgorithm", "does not contain") - ) - EQUALS, NOTEQUALS, DISJOINT, INTERSECTS, NOTINTERSECTS, \ - TOUCHES, NOTTOUCHES, CROSSES, NOTCROSSES, WITHIN, NOTWITHIN, OVERLAPS, \ - NOTOVERLAPS, CONTAINS, NOTCONTAINS = range(len(__predicates)) - - def __init__(self, iface = None, parent = None): + QCoreApplication.translate("EnforceSpatialRulesAlgorithm", "equals"), + QCoreApplication.translate("EnforceSpatialRulesAlgorithm", "is not equals"), + QCoreApplication.translate("EnforceSpatialRulesAlgorithm", "disjoint"), + QCoreApplication.translate("EnforceSpatialRulesAlgorithm", "intersects"), + QCoreApplication.translate( + "EnforceSpatialRulesAlgorithm", "does not intersect" + ), + QCoreApplication.translate("EnforceSpatialRulesAlgorithm", "touches"), + QCoreApplication.translate("EnforceSpatialRulesAlgorithm", "does not touch"), + QCoreApplication.translate("EnforceSpatialRulesAlgorithm", "crosses"), + QCoreApplication.translate("EnforceSpatialRulesAlgorithm", "does not cross"), + QCoreApplication.translate("EnforceSpatialRulesAlgorithm", "within"), + QCoreApplication.translate("EnforceSpatialRulesAlgorithm", "is not within"), + QCoreApplication.translate("EnforceSpatialRulesAlgorithm", "overlaps"), + QCoreApplication.translate("EnforceSpatialRulesAlgorithm", "does not overlap"), + QCoreApplication.translate("EnforceSpatialRulesAlgorithm", "contains"), + QCoreApplication.translate("EnforceSpatialRulesAlgorithm", "does not contain"), + QCoreApplication.translate("EnforceSpatialRulesAlgorithm", "de9im"), + ) + ( + EQUALS, + NOTEQUALS, + DISJOINT, + INTERSECTS, + NOTINTERSECTS, + TOUCHES, + NOTTOUCHES, + CROSSES, + NOTCROSSES, + WITHIN, + NOTWITHIN, + OVERLAPS, + NOTOVERLAPS, + CONTAINS, + NOTCONTAINS, + DE9IM, + ) = range(len(__predicates)) + + def __init__(self, iface=None, parent=None): super(SpatialRelationsHandler, self).__init__() self.parent = parent self.iface = iface @@ -79,75 +99,94 @@ def __init__(self, iface = None, parent = None): self.geometryHandler = GeometryHandler(iface) self.algRunner = AlgRunner() - def validateTerrainModel(self, contourLyr, heightFieldName, threshold,\ - onlySelected=False, geoBoundsLyr=None, context=None, feedback=None): + def validateTerrainModel( + self, + contourLyr, + heightFieldName, + threshold, + onlySelected=False, + geoBoundsLyr=None, + context=None, + feedback=None, + ): """ Does several validation procedures with terrain elements. """ invalidDict = OrderedDict() - multiStepFeedback = QgsProcessingMultiStepFeedback(7, feedback) #ajustar depois - multiStepFeedback.setCurrentStep(0) - multiStepFeedback.setProgressText(self.tr("Splitting lines...")) + multiStepFeedback = ( + QgsProcessingMultiStepFeedback(7, feedback) + if feedback is not None + else None + ) # ajustar depois + if multiStepFeedback is not None: + multiStepFeedback.setCurrentStep(0) + multiStepFeedback.setProgressText(self.tr("Splitting lines...")) splitLinesLyr = self.algRunner.runSplitLinesWithLines( - contourLyr, - contourLyr, - context=context, - feedback=multiStepFeedback + contourLyr, contourLyr, context=context, feedback=multiStepFeedback ) - multiStepFeedback.setCurrentStep(1) - multiStepFeedback.setProgressText(self.tr("Building aux structure...")) + if multiStepFeedback is not None: + multiStepFeedback.setCurrentStep(1) + multiStepFeedback.setProgressText(self.tr("Building aux structure...")) ( - contourSpatialIdx, contourIdDict, contourNodeDict, heightsDict + contourSpatialIdx, + contourIdDict, + contourNodeDict, + heightsDict, ) = self.buildSpatialIndexAndIdDictRelateNodesAndAttributeGroupDict( inputLyr=splitLinesLyr, attributeName=heightFieldName, - feedback=multiStepFeedback + feedback=multiStepFeedback, ) - multiStepFeedback.setCurrentStep(2) - geoBoundsGeomEngine, geoBoundsPolygonEngine = (None, None) if geoBoundsLyr is None\ + if multiStepFeedback is not None: + multiStepFeedback.setCurrentStep(2) + geoBoundsGeomEngine, geoBoundsPolygonEngine = ( + (None, None) + if geoBoundsLyr is None else self.getGeoBoundsGeomEngine( - geoBoundsLyr, - context=context, - feedback=multiStepFeedback + geoBoundsLyr, context=context, feedback=multiStepFeedback + ) + ) + if multiStepFeedback is not None: + multiStepFeedback.setCurrentStep(3) + multiStepFeedback.setProgressText( + self.tr("Validating contour relations...") ) - multiStepFeedback.setCurrentStep(3) - multiStepFeedback.setProgressText(self.tr("Validating contour relations...")) contourFlags = self.validateContourRelations( contourNodeDict, heightFieldName, geoBoundsGeomEngine=geoBoundsGeomEngine, - geoBoundsPolygonEngine=geoBoundsPolygonEngine + geoBoundsPolygonEngine=geoBoundsPolygonEngine, ) invalidDict.update(contourFlags) - multiStepFeedback.setCurrentStep(4) - multiStepFeedback.setProgressText(self.tr("Finding contour out of threshold...")) + if multiStepFeedback is not None: + multiStepFeedback.setCurrentStep(4) + multiStepFeedback.setProgressText( + self.tr("Finding contour out of threshold...") + ) contourOutOfThresholdDict = self.findContourOutOfThreshold( - heightsDict, - threshold, - feedback=multiStepFeedback + heightsDict, threshold, feedback=multiStepFeedback ) invalidDict.update(contourOutOfThresholdDict) if len(invalidDict) > 0: return invalidDict - multiStepFeedback.setCurrentStep(5) - multiStepFeedback.setProgressText(self.tr("Building contour area dict..")) + if multiStepFeedback is not None: + multiStepFeedback.setCurrentStep(5) + multiStepFeedback.setProgressText(self.tr("Building contour area dict..")) contourAreaDict = self.buildContourAreaDict( inputLyr=splitLinesLyr, geoBoundsLyr=geoBoundsLyr, attributeName=heightFieldName, contourSpatialIdx=contourSpatialIdx, contourIdDict=contourIdDict, - depressionExpression=None,#TODO + depressionExpression=None, # TODO context=context, - feedback=multiStepFeedback + feedback=multiStepFeedback, ) - multiStepFeedback.setCurrentStep(6) - multiStepFeedback.setProgressText(self.tr("Finding missing contours...")) + if multiStepFeedback is not None: + multiStepFeedback.setCurrentStep(6) + multiStepFeedback.setProgressText(self.tr("Finding missing contours...")) misingContourDict = self.findMissingContours( - contourAreaDict, - threshold, - context=context, - feedback=multiStepFeedback + contourAreaDict, threshold, context=context, feedback=multiStepFeedback ) invalidDict.update(misingContourDict) return invalidDict @@ -158,25 +197,33 @@ def getGeoBoundsGeomEngine(self, geoBoundsLyr, context=None, feedback=None): """ if geoBoundsLyr is None: return None, None - multiStepFeedback = QgsProcessingMultiStepFeedback(2, feedback) - multiStepFeedback.setCurrentStep(0) + multiStepFeedback = ( + QgsProcessingMultiStepFeedback(2, feedback) + if feedback is not None + else None + ) + if multiStepFeedback is not None: + multiStepFeedback.setCurrentStep(0) mergedPolygonLyr = self.algRunner.runAggregate( - geoBoundsLyr, - context=context, - feedback=multiStepFeedback + geoBoundsLyr, context=context, feedback=multiStepFeedback + ) + if multiStepFeedback is not None: + multiStepFeedback.setCurrentStep(1) + mergedPolygonGeom = ( + [i for i in mergedPolygonLyr.getFeatures()][0].geometry() + if mergedPolygonLyr.featureCount() != 0 + else None ) - multiStepFeedback.setCurrentStep(1) - mergedPolygonGeom = [i for i in mergedPolygonLyr.getFeatures()][0].geometry() \ - if mergedPolygonLyr.featureCount() != 0 else None if mergedPolygonGeom is None: return None, None polygonBoundary = self.algRunner.runBoundary( - mergedPolygonLyr, - context=context, - feedback=multiStepFeedback + mergedPolygonLyr, context=context, feedback=multiStepFeedback + ) + mergedGeom = ( + [i for i in polygonBoundary.getFeatures()][0].geometry() + if polygonBoundary.featureCount() != 0 + else None ) - mergedGeom = [i for i in polygonBoundary.getFeatures()][0].geometry()\ - if polygonBoundary.featureCount() != 0 else None if mergedGeom is None: return None, None polygonEngine = QgsGeometry.createGeometryEngine(mergedPolygonGeom.constGet()) @@ -185,9 +232,17 @@ def getGeoBoundsGeomEngine(self, geoBoundsLyr, context=None, feedback=None): engine.prepareGeometry() return engine, polygonEngine - def buildContourAreaDict(self, inputLyr, geoBoundsLyr, attributeName,\ - contourSpatialIdx, contourIdDict, depressionExpression=None,\ - context=None, feedback=None): + def buildContourAreaDict( + self, + inputLyr, + geoBoundsLyr, + attributeName, + contourSpatialIdx, + contourIdDict, + depressionExpression=None, + context=None, + feedback=None, + ): """ Builds a dict in the following format: { @@ -197,29 +252,37 @@ def buildContourAreaDict(self, inputLyr, geoBoundsLyr, attributeName,\ } """ contourAreaDict = { - 'areaSpatialIdx' : QgsSpatialIndex(), - 'areaIdDict' : {}, - 'areaContourRelations' : {} + "areaSpatialIdx": QgsSpatialIndex(), + "areaIdDict": {}, + "areaContourRelations": {}, } - multiStepFeedback = QgsProcessingMultiStepFeedback(4, feedback) - multiStepFeedback.setCurrentStep(0) - boundsLineLyr = self.algRunner.runPolygonsToLines( - geoBoundsLyr, context, feedback=multiStepFeedback - ) if geoBoundsLyr is not None else None + multiStepFeedback = ( + QgsProcessingMultiStepFeedback(4, feedback) + if feedback is not None + else None + ) + if multiStepFeedback is not None: + multiStepFeedback.setCurrentStep(0) + boundsLineLyr = ( + self.algRunner.runPolygonsToLines( + geoBoundsLyr, context, feedback=multiStepFeedback + ) + if geoBoundsLyr is not None + else None + ) lineLyrList = [inputLyr] if boundsLineLyr is None else [inputLyr, boundsLineLyr] - multiStepFeedback.setCurrentStep(1) + if multiStepFeedback is not None: + multiStepFeedback.setCurrentStep(1) linesLyr = self.algRunner.runMergeVectorLayers( - lineLyrList, - context, - feedback=multiStepFeedback + lineLyrList, context, feedback=multiStepFeedback ) - multiStepFeedback.setCurrentStep(2) + if multiStepFeedback is not None: + multiStepFeedback.setCurrentStep(2) polygonLyr = self.algRunner.runPolygonize( - linesLyr, - context, - feedback=multiStepFeedback + linesLyr, context, feedback=multiStepFeedback ) - multiStepFeedback.setCurrentStep(3) + if multiStepFeedback is not None: + multiStepFeedback.setCurrentStep(3) self.populateContourAreaDict( polygonLyr, geoBoundsLyr, @@ -227,80 +290,104 @@ def buildContourAreaDict(self, inputLyr, geoBoundsLyr, attributeName,\ contourAreaDict, contourSpatialIdx, contourIdDict, - feedback=multiStepFeedback + feedback=multiStepFeedback, ) return contourAreaDict - - def populateContourAreaDict(self, polygonLyr, geoBoundsLyr, attributeName, - contourAreaDict, contourSpatialIdx, contourIdDict, feedback=None): - boundsGeom = [i for i in geoBoundsLyr.getFeatures()][0].geometry() if geoBoundsLyr is not None else None + + def populateContourAreaDict( + self, + polygonLyr, + geoBoundsLyr, + attributeName, + contourAreaDict, + contourSpatialIdx, + contourIdDict, + feedback=None, + ): + boundsGeom = ( + [i for i in geoBoundsLyr.getFeatures()][0].geometry() + if geoBoundsLyr is not None + else None + ) nPolygons = polygonLyr.featureCount() - size = 100/nPolygons if nPolygons else 0 + size = 100 / nPolygons if nPolygons else 0 for current, feat in enumerate(polygonLyr.getFeatures()): if feedback is not None and feedback.isCanceled(): break featId = feat.id() geom = feat.geometry() featBB = geom.boundingBox() - contourAreaDict['areaSpatialIdx'].addFeature(feat) - contourAreaDict['areaIdDict'][featId] = feat - if featId not in contourAreaDict['areaContourRelations']: - contourAreaDict['areaContourRelations'][featId] = defaultdict(list) + contourAreaDict["areaSpatialIdx"].addFeature(feat) + contourAreaDict["areaIdDict"][featId] = feat + if featId not in contourAreaDict["areaContourRelations"]: + contourAreaDict["areaContourRelations"][featId] = defaultdict(list) for contourId in contourSpatialIdx.intersects(featBB): if feedback is not None and feedback.isCanceled(): break candidateContourFeat = contourIdDict[contourId] if candidateContourFeat.geometry().intersects(geom): contourValue = candidateContourFeat[attributeName] - candidateContourGeom = candidateContourFeat.geometry()\ - if boundsGeom is not None and\ - not candidateContourFeat.geometry().intersects(boundsGeom)\ + candidateContourGeom = ( + candidateContourFeat.geometry() + if boundsGeom is not None + and not candidateContourFeat.geometry().intersects(boundsGeom) else candidateContourFeat.geometry().intersection(boundsGeom) - contourAreaDict['areaContourRelations'][featId][contourValue].append(candidateContourGeom) + ) + contourAreaDict["areaContourRelations"][featId][ + contourValue + ].append(candidateContourGeom) if feedback is not None: feedback.setProgress(current * size) def findContourOutOfThreshold(self, heightsDict, threshold, feedback=None): contourOutOfThresholdDict = OrderedDict() - size = 100/len(heightsDict) if len(heightsDict) else 0 - for current, (k,valueSet) in enumerate(heightsDict.items()): + size = 100 / len(heightsDict) if len(heightsDict) else 0 + for current, (k, valueSet) in enumerate(heightsDict.items()): if feedback is not None and feedback.isCanceled(): break for i in valueSet: if feedback is not None and feedback.isCanceled(): break if k % threshold != 0: - contourOutOfThresholdDict[i.asWkb()] = self.tr('Contour out of threshold.') + contourOutOfThresholdDict[i.asWkb()] = self.tr( + "Contour out of threshold." + ) if feedback is not None: feedback.setProgress(current * size) return contourOutOfThresholdDict - def findMissingContours(self, contourAreaDict, threshold, context=None, feedback=None): + def findMissingContours( + self, contourAreaDict, threshold, context=None, feedback=None + ): """ Can be more efficient, the first draft will be of several for inside for. """ - relationCount = len(contourAreaDict['areaContourRelations']) + relationCount = len(contourAreaDict["areaContourRelations"]) size = 100 / relationCount if relationCount else 0 missingContourFlagDict = dict() - for current, (areaId, heightDict) in enumerate(contourAreaDict['areaContourRelations'].items()): + for current, (areaId, heightDict) in enumerate( + contourAreaDict["areaContourRelations"].items() + ): if feedback is not None and feedback.isCanceled(): break if len(heightDict) < 2: continue for h1, h2 in combinations(heightDict.keys(), 2): - if abs(h1-h2) <= threshold: + if abs(h1 - h2) <= threshold: continue - min_h12 = min(h1, h2) #done to fix the way flags are built. + min_h12 = min(h1, h2) # done to fix the way flags are built. max_h12 = max(h1, h2) for geom in heightDict[h1]: if feedback is not None and feedback.isCanceled(): break - shortestLineGeomList = [geom.shortestLine(i) for i in heightDict[h2]] + shortestLineGeomList = [ + geom.shortestLine(i) for i in heightDict[h2] + ] shortestLine = min(shortestLineGeomList, key=lambda x: x.length()) missingContourFlagDict.update( { - shortestLine.asWkb() : self.tr( - 'Missing contour between contour lines of values {v1} and {v2}' + shortestLine.asWkb(): self.tr( + "Missing contour between contour lines of values {v1} and {v2}" ).format(v1=min_h12, v2=max_h12) } ) @@ -308,7 +395,16 @@ def findMissingContours(self, contourAreaDict, threshold, context=None, feedback feedback.setProgress(current * size) return missingContourFlagDict - def relateDrainagesWithContours(self, drainageLyr, contourLyr, frameLinesLyr, heightFieldName, threshold, topologyRadius, feedback=None): + def relateDrainagesWithContours( + self, + drainageLyr, + contourLyr, + frameLinesLyr, + heightFieldName, + threshold, + topologyRadius, + feedback=None, + ): """ Checks the conformity between directed drainages and contours. Drainages must be propperly directed. @@ -331,20 +427,27 @@ def relateDrainagesWithContours(self, drainageLyr, contourLyr, frameLinesLyr, he 4- After relating everything, """ maxSteps = 4 - multiStepFeedback = QgsProcessingMultiStepFeedback(maxSteps, feedback) if feedback is not None else None + multiStepFeedback = ( + QgsProcessingMultiStepFeedback(maxSteps, feedback) + if feedback is not None + else None + ) currentStep = 0 if multiStepFeedback is not None: if multiStepFeedback.isCanceled(): return [] multiStepFeedback.setCurrentStep(currentStep) currentStep += 1 - multiStepFeedback.pushInfo( - self.tr('Building contour structures...') - ) - contourSpatialIdx, contourIdDict, contourNodeDict, heightsDict = self.buildSpatialIndexAndIdDictRelateNodesAndAttributeGroupDict( + multiStepFeedback.pushInfo(self.tr("Building contour structures...")) + ( + contourSpatialIdx, + contourIdDict, + contourNodeDict, + heightsDict, + ) = self.buildSpatialIndexAndIdDictRelateNodesAndAttributeGroupDict( inputLyr=contourLyr, attributeName=heightFieldName, - feedback=multiStepFeedback + feedback=multiStepFeedback, ) if multiStepFeedback is not None: if multiStepFeedback.isCanceled(): @@ -352,14 +455,13 @@ def relateDrainagesWithContours(self, drainageLyr, contourLyr, frameLinesLyr, he multiStepFeedback.setCurrentStep(currentStep) currentStep += 1 multiStepFeedback.pushInfo( - self.tr('Validating contour structures. Check 1/4...') - ) - invalidDict = self.validateContourRelations( - contourNodeDict, - feedback=multiStepFeedback + self.tr("Validating contour structures. Check 1/4...") ) + invalidDict = self.validateContourRelations( + contourNodeDict, feedback=multiStepFeedback + ) if invalidDict: - multiStepFeedback.setCurrentStep(maxSteps-1) + multiStepFeedback.setCurrentStep(maxSteps - 1) return invalidDict if multiStepFeedback is not None: @@ -367,31 +469,31 @@ def relateDrainagesWithContours(self, drainageLyr, contourLyr, frameLinesLyr, he return [] multiStepFeedback.setCurrentStep(currentStep) currentStep += 1 - multiStepFeedback.pushInfo( - self.tr('Building drainage spatial index...') - ) - drainageSpatialIdx, drainageIdDict, drainageNodeDict = self.buildSpatialIndexAndIdDictAndRelateNodes( - inputLyr=drainageLyr, - feedback=multiStepFeedback + multiStepFeedback.pushInfo(self.tr("Building drainage spatial index...")) + ( + drainageSpatialIdx, + drainageIdDict, + drainageNodeDict, + ) = self.buildSpatialIndexAndIdDictAndRelateNodes( + inputLyr=drainageLyr, feedback=multiStepFeedback ) if multiStepFeedback is not None: if multiStepFeedback.isCanceled(): return [] multiStepFeedback.setCurrentStep(currentStep) currentStep += 1 - multiStepFeedback.pushInfo( - self.tr('Relating contours with drainages...') - ) + multiStepFeedback.pushInfo(self.tr("Relating contours with drainages...")) intersectionDict = self.buildIntersectionDict( drainageLyr, drainageIdDict, drainageSpatialIdx, contourIdDict, - contourIdDict - ) + contourIdDict, + ) - def buildSpatialIndexAndIdDictAndRelateNodes(self, inputLyr, feedback=None,\ - featureRequest=None): + def buildSpatialIndexAndIdDictAndRelateNodes( + self, inputLyr, feedback=None, featureRequest=None + ): """ creates a spatial index for the input layer :param inputLyr: (QgsVectorLayer) input layer; @@ -402,13 +504,16 @@ def buildSpatialIndexAndIdDictAndRelateNodes(self, inputLyr, feedback=None,\ idDict = {} nodeDict = defaultdict(list) featCount = inputLyr.featureCount() - size = 100/featCount if featCount else 0 - iterator = inputLyr.getFeatures() if featureRequest is None \ + size = 100 / featCount if featCount else 0 + iterator = ( + inputLyr.getFeatures() + if featureRequest is None else inputLyr.getFeatures(featureRequest) - firstAndLastNode = lambda x:self.geometryHandler.getFirstAndLastNode( + ) + firstAndLastNode = lambda x: self.geometryHandler.getFirstAndLastNode( inputLyr, x ) - addFeatureAlias = lambda x : self.addFeatureToSpatialIndexAndNodeDict( + addFeatureAlias = lambda x: self.addFeatureToSpatialIndexAndNodeDict( current=x[0], feat=x[1], spatialIdx=spatialIdx, @@ -416,13 +521,14 @@ def buildSpatialIndexAndIdDictAndRelateNodes(self, inputLyr, feedback=None,\ nodeDict=nodeDict, size=size, firstAndLastNode=firstAndLastNode, - feedback=feedback + feedback=feedback, ) list(map(addFeatureAlias, enumerate(iterator))) return spatialIdx, idDict, nodeDict - def addFeatureToSpatialIndexAndNodeDict(self, current, feat, spatialIdx,\ - idDict, nodeDict, size, feedback): + def addFeatureToSpatialIndexAndNodeDict( + self, current, feat, spatialIdx, idDict, nodeDict, size, feedback + ): """ Adds feature to spatial index. Used along side with a python map operator to improve performance. @@ -445,43 +551,52 @@ def addFeatureToSpatialIndexAndNodeDict(self, current, feat, spatialIdx,\ nodeDict[firstNode] += [feat] nodeDict[lastNode] += [feat] self.layerHandler.addFeatureToSpatialIndex( - current, - feat, - spatialIdx, - idDict, - size, - feedback + current, feat, spatialIdx, idDict, size, feedback ) - def buildSpatialIndexAndIdDictRelateNodesAndAttributeGroupDict(self, inputLyr,\ - attributeName, feedback=None, featureRequest=None): - """ - - """ + def buildSpatialIndexAndIdDictRelateNodesAndAttributeGroupDict( + self, inputLyr, attributeName, feedback=None, featureRequest=None + ): + """ """ spatialIdx = QgsSpatialIndex() idDict = {} nodeDict = defaultdict(list) attributeGroupDict = {} featCount = inputLyr.featureCount() - size = 100/featCount if featCount else 0 - iterator = inputLyr.getFeatures() if featureRequest is None else inputLyr.getFeatures(featureRequest) - addFeatureAlias = lambda x : self.addFeatureToSpatialIndexNodeDictAndAttributeGroupDict( - current=x[0], - feat=x[1], - spatialIdx=spatialIdx, - idDict=idDict, - nodeDict=nodeDict, - size=size, - attributeGroupDict=attributeGroupDict, - attributeName=attributeName, - feedback=feedback + size = 100 / featCount if featCount else 0 + iterator = ( + inputLyr.getFeatures() + if featureRequest is None + else inputLyr.getFeatures(featureRequest) + ) + addFeatureAlias = ( + lambda x: self.addFeatureToSpatialIndexNodeDictAndAttributeGroupDict( + current=x[0], + feat=x[1], + spatialIdx=spatialIdx, + idDict=idDict, + nodeDict=nodeDict, + size=size, + attributeGroupDict=attributeGroupDict, + attributeName=attributeName, + feedback=feedback, + ) ) list(map(addFeatureAlias, enumerate(iterator))) return spatialIdx, idDict, nodeDict, attributeGroupDict - - def addFeatureToSpatialIndexNodeDictAndAttributeGroupDict(self, current, feat,\ - spatialIdx, idDict, nodeDict, size, attributeGroupDict,\ - attributeName, feedback): + + def addFeatureToSpatialIndexNodeDictAndAttributeGroupDict( + self, + current, + feat, + spatialIdx, + idDict, + nodeDict, + size, + attributeGroupDict, + attributeName, + feedback, + ): """ Adds feature to spatial index. Used along side with a python map operator to improve performance. @@ -498,17 +613,17 @@ def addFeatureToSpatialIndexNodeDictAndAttributeGroupDict(self, current, feat,\ attributeGroupDict[attrValue] = set() attributeGroupDict[attrValue].add(feat.geometry()) self.addFeatureToSpatialIndexAndNodeDict( - current, - feat, - spatialIdx, - idDict, - nodeDict, - size, - feedback + current, feat, spatialIdx, idDict, nodeDict, size, feedback ) - - def validateContourRelations(self, contourNodeDict, heightFieldName,\ - geoBoundsGeomEngine=None, geoBoundsPolygonEngine=None, feedback=None): + + def validateContourRelations( + self, + contourNodeDict, + heightFieldName, + geoBoundsGeomEngine=None, + geoBoundsPolygonEngine=None, + feedback=None, + ): """ param: contourNodeDict: (dict) dictionary with contour nodes Invalid contours: @@ -518,35 +633,42 @@ def validateContourRelations(self, contourNodeDict, heightFieldName,\ """ invalidDict = dict() contoursNumber = len(contourNodeDict) - step = 100/contoursNumber if contoursNumber else 0 + step = 100 / contoursNumber if contoursNumber else 0 for current, (node, contourList) in enumerate(contourNodeDict.items()): nodeGeom = QgsGeometry.fromPointXY(node) nodeWkb = nodeGeom.asWkb() if feedback is not None and feedback.isCanceled(): break - if geoBoundsPolygonEngine is not None and \ - not geoBoundsPolygonEngine.intersects(nodeGeom.constGet()): + if ( + geoBoundsPolygonEngine is not None + and not geoBoundsPolygonEngine.intersects(nodeGeom.constGet()) + ): continue - if len(contourList) == 1 and \ - (geoBoundsGeomEngine is not None and not ( - geoBoundsGeomEngine.intersects(nodeGeom.constGet()) or \ - geoBoundsGeomEngine.distance(nodeGeom.constGet()) < 10**-9 - )): + if len(contourList) == 1 and ( + geoBoundsGeomEngine is not None + and not ( + geoBoundsGeomEngine.intersects(nodeGeom.constGet()) + or geoBoundsGeomEngine.distance(nodeGeom.constGet()) < 10**-9 + ) + ): invalidDict[nodeWkb] = self.tr( - 'Contour lines must be closed or intersect the geographic boundary.' - ) - if len(contourList) == 2 and contourList[0][heightFieldName] != contourList[1][heightFieldName]: + "Contour lines must be closed or intersect the geographic boundary." + ) + if ( + len(contourList) == 2 + and contourList[0][heightFieldName] != contourList[1][heightFieldName] + ): invalidDict[nodeWkb] = self.tr( - 'Contour lines touch each other and have different height values.' - ) + "Contour lines touch each other and have different height values." + ) if len(contourList) > 2: invalidDict[nodeWkb] = self.tr( - 'Contour lines intersect each other. Contour lines must touch itself or only one other with same height value.' - ) + "Contour lines intersect each other. Contour lines must touch itself or only one other with same height value." + ) if feedback is not None: feedback.setProgress(step * current) return invalidDict - + def isDangle(self, point, featureDict, spatialIdx, searchRadius=10**-15): """ :param point: (QgsPointXY) node tested as dangle; @@ -559,75 +681,105 @@ def isDangle(self, point, featureDict, spatialIdx, searchRadius=10**-15): buffer = qgisPoint.buffer(searchRadius, -1) bufferBB = buffer.boundingBox() for featid in spatialIdx.intersects(bufferBB): - if buffer.intersects(featureDict[featid].geometry()) and \ - qgisPoint.distance(featureDict[featid].geometry()) < 10**-9: + if ( + buffer.intersects(featureDict[featid].geometry()) + and qgisPoint.distance(featureDict[featid].geometry()) < 10**-9 + ): return True return False - def buildIntersectionDict(self, drainageLyr, drainageIdDict, drainageSpatialIdx, contourIdDict, contourSpatialIdx, feedback=None): + def buildIntersectionDict( + self, + drainageLyr, + drainageIdDict, + drainageSpatialIdx, + contourIdDict, + contourSpatialIdx, + feedback=None, + ): intersectionDict = dict() flagDict = dict() - firstNode = lambda x:self.geometryHandler.getFirstNode(drainageLyr, x) - lastNode = lambda x:self.geometryHandler.getLastNode(drainageLyr, x) - addItemsToIntersectionDict = lambda x:self.addItemsToIntersectionDict( + firstNode = lambda x: self.geometryHandler.getFirstNode(drainageLyr, x) + lastNode = lambda x: self.geometryHandler.getLastNode(drainageLyr, x) + addItemsToIntersectionDict = lambda x: self.addItemsToIntersectionDict( dictItem=x, contourSpatialIdx=contourSpatialIdx, contourIdDict=contourIdDict, intersectionDict=intersectionDict, firstNode=firstNode, lastNode=lastNode, - flagDict=flagDict + flagDict=flagDict, ) # map for, this means: for item in drainageIdDict.items() ... list(map(addItemsToIntersectionDict, drainageIdDict.items())) return intersectionDict - - def addItemsToIntersectionDict(self, dictItem, contourSpatialIdx, contourIdDict, intersectionDict, firstNode, lastNode, flagDict): + + def addItemsToIntersectionDict( + self, + dictItem, + contourSpatialIdx, + contourIdDict, + intersectionDict, + firstNode, + lastNode, + flagDict, + ): gid, feat = dictItem featBB = feat.geometry().boundingBox() featid = feat.id() featGeom = feat.geometry() intersectionDict[featid] = { - 'start_point':firstNode(featGeom), - 'end_point':lastNode(featGeom), - 'intersection_list':[] - } + "start_point": firstNode(featGeom), + "end_point": lastNode(featGeom), + "intersection_list": [], + } for candidateId in contourSpatialIdx.intersects(featBB): candidate = contourIdDict[candidateId] candidateGeom = candidate.geometry() - if candidateGeom.intersects(featGeom): #add intersection + if candidateGeom.intersects(featGeom): # add intersection intersectionGeom = candidateGeom.intersection(featGeom) - intersectionList += [intersectionGeom.asPoint()] if not intersectionGeom.asMultiPoint() else intersectionGeom.asMultiPoint() + intersectionList += ( + [intersectionGeom.asPoint()] + if not intersectionGeom.asMultiPoint() + else intersectionGeom.asMultiPoint() + ) flagFeature = True if len(intersectionList) > 1 else False for inter in intersectionList: if flagFeature: - flagDict[inter] = self.tr('Contour id={c_id} intersects drainage id={d_id} in more than one point').format( - c_id=candidateId, - d_id=gid - ) + flagDict[inter] = self.tr( + "Contour id={c_id} intersects drainage id={d_id} in more than one point" + ).format(c_id=candidateId, d_id=gid) newIntersection = { - 'contour_id' : candidateId, - 'intersection_point' : inter + "contour_id": candidateId, + "intersection_point": inter, } - intersectionDict[featid]['intersection_list'].append(newIntersection) - + intersectionDict[featid]["intersection_list"].append( + newIntersection + ) + def validateIntersections(self, intersectionDict, heightFieldName, threshold): """ 1- Sort list - 2- + 2- """ validatedIdsDict = dict() invalidatedIdsDict = dict() for id, values in intersectionDict.items(): - interList = values['intersection_list'] + interList = values["intersection_list"] if len(interList) <= 1: continue - #sort list by distance from start point - interList.sort(key=lambda x: x['intersection_point'].geometry().distance(values['start_point'])) + # sort list by distance from start point + interList.sort( + key=lambda x: x["intersection_point"] + .geometry() + .distance(values["start_point"]) + ) referenceElement = interList[0] for idx, elem in enumerate(interList[1::], start=1): elemen_id = elem.id() - if int(elem[heightFieldName]) != threshold*idx + int(referenceElement[heightFieldName]): + if int(elem[heightFieldName]) != threshold * idx + int( + referenceElement[heightFieldName] + ): invalidatedIdsDict[elemen_id] = elem else: if elemen_id not in invalidatedIdsDict: @@ -636,41 +788,47 @@ def validateIntersections(self, intersectionDict, heightFieldName, threshold): if id in invalidatedIdsDict: validatedIdsDict.pop(id) return validatedIdsDict, invalidatedIdsDict - - def validateContourPolygons(self, contourPolygonDict, contourPolygonIdx, threshold, heightFieldName, depressionValueDict=None): - hilltopDict = self.buildHilltopDict( - contourPolygonDict, - contourPolygonIdx - ) + + def validateContourPolygons( + self, + contourPolygonDict, + contourPolygonIdx, + threshold, + heightFieldName, + depressionValueDict=None, + ): + hilltopDict = self.buildHilltopDict(contourPolygonDict, contourPolygonIdx) invalidDict = dict() for hilltopGeom, hilltop in hilltopDict.items(): localFlagList = [] - polygonList = hilltop['downhill'] - feat = hilltop['feat'] + polygonList = hilltop["downhill"] + feat = hilltop["feat"] if len(polygonList) < 2: break # sort polygons by area, from minimum to max polygonList.sort(key=lambda x: x.geometry().area()) - #pair comparison - a, b = tee([feat]+polygonList) + # pair comparison + a, b = tee([feat] + polygonList) next(b, None) for elem1, elem2 in zip(a, b): - if abs(elem1[heightFieldName]-elem2[heightFieldName]) != threshold: + if abs(elem1[heightFieldName] - elem2[heightFieldName]) != threshold: elem1GeomKey = elem1.geometry().asWkb() if elem1GeomKey not in invalidDict: invalidDict[elem1GeomKey] = [] - invalidDict[elem1GeomKey] += [self.tr( - 'Difference between contour with values {id1} \ + invalidDict[elem1GeomKey] += [ + self.tr( + "Difference between contour with values {id1} \ and {id2} do not match equidistance {equidistance}.\ Probably one contour is \ - missing or one of the contours have wrong value.\n' - ).format( - id1=elem1[heightFieldName], - id2=elem2[heightFieldName], - equidistance=threshold - )] + missing or one of the contours have wrong value.\n" + ).format( + id1=elem1[heightFieldName], + id2=elem2[heightFieldName], + equidistance=threshold, + ) + ] return invalidDict - + def buildHilltopDict(self, contourPolygonDict, contourPolygonIdx): hilltopDict = dict() buildDictAlias = lambda x: self.initiateHilltopDict(x, hilltopDict) @@ -687,17 +845,17 @@ def buildHilltopDict(self, contourPolygonDict, contourPolygonIdx): if candId != idx and candGeom.within(geom): hilltopDict.pop(geomWkb.asWkb()) break - if candId != idx and candGeom.contains(geom) \ - and candFeat not in hilltopDict[geomWkb]['donwhill']: - hilltopDict[geomWkb]['donwhill'].append(candFeat) + if ( + candId != idx + and candGeom.contains(geom) + and candFeat not in hilltopDict[geomWkb]["donwhill"] + ): + hilltopDict[geomWkb]["donwhill"].append(candFeat) return hilltopDict - + def initiateHilltopDict(self, feat, hilltopDict): - hilltopDict[feat.geometry().asWkb()] = { - 'feat' : feat, - 'downhill': [] - } - + hilltopDict[feat.geometry().asWkb()] = {"feat": feat, "downhill": []} + def buildTerrainPolygons(self, featList): pass @@ -709,30 +867,42 @@ def validateContourLines(self, contourLyr, contourAttrName, refLyr, feedback=Non 4. Validate contours. """ pass - - def validateSpatialRelations(self, ruleList, createSpatialIndex=True, feedback=None): + + def validateSpatialRelations( + self, ruleList, createSpatialIndex=True, feedback=None + ): """ 1. iterate over rule list and get all layers. 2. build spatial index 3. test rule """ - multiStepFeedback = QgsProcessingMultiStepFeedback(4, feedback) if feedback is not None else None + multiStepFeedback = ( + QgsProcessingMultiStepFeedback(4, feedback) + if feedback is not None + else None + ) if multiStepFeedback is not None: multiStepFeedback.setCurrentStep(0) - spatialDict = self.buildSpatialDictFromRuleList(ruleList, feedback=multiStepFeedback) + spatialDict = self.buildSpatialDictFromRuleList( + ruleList, feedback=multiStepFeedback + ) if multiStepFeedback is not None: multiStepFeedback.setCurrentStep(1) - spatialRuleDict = self.buildSpatialRuleDict(ruleList, feedback=multiStepFeedback) + spatialRuleDict = self.buildSpatialRuleDict( + ruleList, feedback=multiStepFeedback + ) if multiStepFeedback is not None: multiStepFeedback.setCurrentStep(2) self.buildSpatialRelationDictOnSpatialRuleDict( spatialDict=spatialDict, spatialRuleDict=spatialRuleDict, - feedback=multiStepFeedback + feedback=multiStepFeedback, ) if multiStepFeedback is not None: multiStepFeedback.setCurrentStep(3) - flagList = self.identifyInvalidRelations(spatialDict, spatialRuleDict, feedback=multiStepFeedback) + flagList = self.identifyInvalidRelations( + spatialDict, spatialRuleDict, feedback=multiStepFeedback + ) return flagList def buildSpatialDictFromRuleList(self, ruleList, feedback=None): @@ -746,23 +916,28 @@ def buildSpatialDictFromRuleList(self, ruleList, feedback=None): } } """ - progressStep = 100/len(ruleList) if ruleList else 0 + progressStep = 100 / len(ruleList) if ruleList else 0 spatialDict = defaultdict(dict) for current, rule in enumerate(ruleList): if feedback is not None and feedback.isCanceled(): break - inputKey = '_'.join(rule['input_layer'].name(), rule['input_layer_filter']) - candidateKey = '_'.join(rule['candidate_layer'].name(), rule['candidate_layer_filter']) + inputKey = "_".join(rule["input_layer"].name(), rule["input_layer_filter"]) + candidateKey = "_".join( + rule["candidate_layer"].name(), rule["candidate_layer_filter"] + ) for key in [inputKey, candidateKey]: if key not in spatialDict: - spatialDict[key]['spatial_index'], spatialDict[key]['feature_id_dict'] = self.layerHandler.buildSpatialIndexAndIdDict( - inputLyr=rule['input_layer'], - featureRequest=rule['input_layer_filter'] + ( + spatialDict[key]["spatial_index"], + spatialDict[key]["feature_id_dict"], + ) = self.layerHandler.buildSpatialIndexAndIdDict( + inputLyr=rule["input_layer"], + featureRequest=rule["input_layer_filter"], ) if feedback is not None: feedback.setProgress(current * progressStep) return spatialDict - + def buildSpatialRuleDict(self, ruleList, feedback=None): """ ruleList comes from the ui @@ -798,27 +973,25 @@ def buildSpatialRuleDict(self, ruleList, feedback=None): } """ spatialRuleDict = defaultdict( - lambda : { - 'input_layer' : None, - 'input_layer_filter' : '', - 'rule_list' : [] - } + lambda: {"input_layer": None, "input_layer_filter": "", "rule_list": []} ) - progressStep = 100/len(ruleList) if ruleList else 0 + progressStep = 100 / len(ruleList) if ruleList else 0 for current, rule in enumerate(ruleList): if feedback is not None and feedback.isCanceled(): break - key = '_'.join(rule['input_layer'].name(), rule['input_layer_filter']) - spatialRuleDict[key]['input_layer'] = rule['input_layer'] - spatialRuleDict[key]['input_layer_filter'] = rule['input_layer_filter'] - spatialRuleDict[key]['rule_list'].append( - {k:v for k, v in rule.items() if 'input' not in k} + key = "_".join(rule["input_layer"].name(), rule["input_layer_filter"]) + spatialRuleDict[key]["input_layer"] = rule["input_layer"] + spatialRuleDict[key]["input_layer_filter"] = rule["input_layer_filter"] + spatialRuleDict[key]["rule_list"].append( + {k: v for k, v in rule.items() if "input" not in k} ) if feedback is not None: feedback.setProgress(current * progressStep) return spatialRuleDict - def buildSpatialRelationDictOnSpatialRuleDict(self, spatialDict, spatialRuleDict, feedback=None): + def buildSpatialRelationDictOnSpatialRuleDict( + self, spatialDict, spatialRuleDict, feedback=None + ): """ layerFeatureDict = { 'layer_name' = { @@ -845,41 +1018,45 @@ def buildSpatialRelationDictOnSpatialRuleDict(self, spatialDict, spatialRuleDict """ totalSteps = self.countSteps(spatialRuleDict, spatialDict) - progressStep = 100/totalSteps if totalSteps else 0 + progressStep = 100 / totalSteps if totalSteps else 0 counter = 0 for inputKey, inputDict in spatialRuleDict.items(): if feedback is not None and feedback.isCanceled(): break - keyRuleList = ['_'.join(i['candidate_layer'], i['candidate_layer_filter']) for i in inputDict['rule_list']] - for featId, feat in spatialDict[inputKey]['feature_id_dict']: + keyRuleList = [ + "_".join(i["candidate_layer"], i["candidate_layer_filter"]) + for i in inputDict["rule_list"] + ] + for featId, feat in spatialDict[inputKey]["feature_id_dict"]: if feedback is not None and feedback.isCanceled(): break - for idx, rule in enumerate(inputDict['rule_list']): + for idx, rule in enumerate(inputDict["rule_list"]): if feedback is not None and feedback.isCanceled(): break - rule['feat_relation_list'].append( + rule["feat_relation_list"].append( ( - featId, self.relateFeatureAccordingToPredicate( + featId, + self.relateFeatureAccordingToPredicate( feat=feat, rule=rule, key=keyRuleList[idx], - predicate=rule['predicate'], - spatialDict=spatialDict - ) + predicate=rule["predicate"], + spatialDict=spatialDict, + ), ) ) - counter+=1 + counter += 1 if feedback is not None: feedback.setProgress(counter * progressStep) - + def countSteps(self, spatialRuleDict, spatialDict): """ Counts the number of steps of execution. """ steps = len(spatialRuleDict) - for k,v in spatialRuleDict.items(): - steps += len(v['rule_list']) - steps += len(spatialDict[k]['feature_id_dict']) + for k, v in spatialRuleDict.items(): + steps += len(v["rule_list"]) + steps += len(spatialDict[k]["feature_id_dict"]) return steps def identifyInvalidRelations(self, spatialDict, spatialRuleDict, feedback=None): @@ -887,60 +1064,64 @@ def identifyInvalidRelations(self, spatialDict, spatialRuleDict, feedback=None): Identifies invalid spatial relations and returns a list with flags to be raised. """ totalSteps = self.countSteps(spatialRuleDict, spatialDict) - progressStep = 100/totalSteps if totalSteps else 0 + progressStep = 100 / totalSteps if totalSteps else 0 counter = 0 invalidFlagList = [] for inputKey, inputDict in spatialRuleDict: if feedback is not None and feedback.isCanceled(): - break - inputLyrName = inputDict['input_layer'] - for rule in inputDict['rule_list']: + break + inputLyrName = inputDict["input_layer"] + for rule in inputDict["rule_list"]: if feedback is not None and feedback.isCanceled(): - break - candidateLyrName = inputDict['candidate_layer'] - candidateKey = '_'.join(candidateLyrName, inputDict['candidate_layer_filter']) + break + candidateLyrName = inputDict["candidate_layer"] + candidateKey = "_".join( + candidateLyrName, inputDict["candidate_layer_filter"] + ) sameLayer = True if inputKey == candidateKey else False lambdaCompair = self.parseCardinalityAndGetLambdaToIdentifyProblems( - cardinality=rule['cardinality'], - necessity=rule['necessity'], - isSameLayer=sameLayer + cardinality=rule["cardinality"], + necessity=rule["necessity"], + isSameLayer=sameLayer, ) - for featId, relatedFeatures in rule['feat_relation_list']: + for featId, relatedFeatures in rule["feat_relation_list"]: if feedback is not None and feedback.isCanceled(): break - inputFeature=spatialDict[inputKey][featId] + inputFeature = spatialDict[inputKey][featId] if lambdaCompair(relatedFeatures): - if inputLyrName == candidateLyrName and inputFeature in relatedFeatures: + if ( + inputLyrName == candidateLyrName + and inputFeature in relatedFeatures + ): relatedFeatures.pop(inputFeature) invalidFlagList += self.buildSpatialFlags( inputFeature=inputFeature, relatedFeatures=relatedFeatures, - flagText=rule['flag_text'] + flagText=rule["flag_text"], ) if feedback is not None: feedback.setProgress(counter * progressStep) counter += 1 return invalidFlagList - - def buildSpatialFlags(self, inputLyrName, inputFeature, candidateLyrName, relatedFeatures, flagText): + + def buildSpatialFlags( + self, inputLyrName, inputFeature, candidateLyrName, relatedFeatures, flagText + ): input_id = inputFeature.id() inputGeom = inputFeature.geometry() spatialFlags = [] for feat in relatedFeatures: flagGeom = inputGeom.intersection(feat.geometry().constGet()) - flagText = self.tr('Feature from {input} with id {input_id} violates the following predicate with feature from {candidate} with id {candidate_id}: {predicate_text}').format( + flagText = self.tr( + "Feature from {input} with id {input_id} violates the following predicate with feature from {candidate} with id {candidate_id}: {predicate_text}" + ).format( input=inputLyrName, input_id=input_id, candidate=candidateLyrName, candidate_id=feat.id(), - predicate_text=flagText - ) - spatialFlags.append( - { - 'flagGeom' : flagGeom, - 'flagText' : flagText - } + predicate_text=flagText, ) + spatialFlags.append({"flagGeom": flagGeom, "flagText": flagText}) return spatialFlags def availablePredicates(self): @@ -960,14 +1141,14 @@ def getCardinalityTest(self, cardinality=None): if cardinality is None: # default is "1..*" return lambda x: len(x) > 0 - min_card, max_card = cardinality.split('..') - if max_card == '*': + min_card, max_card = cardinality.split("..") + if max_card == "*": return lambda x: len(x) >= int(min_card) elif min_card == max_card: return lambda x: len(x) == int(min_card) else: return lambda x: len(x) >= int(min_card) and len(x) <= int(max_card) - + def testPredicate(self, predicate, engine, targetGeometries): """ Applies a predicate test to a given feature from a list of features. @@ -978,20 +1159,20 @@ def testPredicate(self, predicate, engine, targetGeometries): that will be tested. :param cardinality: (str) cardinality string to be tested against. :return: (set-of-int) feature IDs for those that the geometries do - comply with given predicate/cardinality. + comply with given predicate/cardinality. """ # negatives are disregarded. method simply apply the predicate comparison positives = set() negatives = set() methods = { - self.EQUALS : "isEqual", - self.DISJOINT : "disjoint", - self.INTERSECTS : "intersects", - self.TOUCHES : "touches", - self.CROSSES : "crosses", - self.WITHIN : "within", - self.OVERLAPS : "overlaps", - self.CONTAINS : "contains" + self.EQUALS: "isEqual", + self.DISJOINT: "disjoint", + self.INTERSECTS: "intersects", + self.TOUCHES: "touches", + self.CROSSES: "crosses", + self.WITHIN: "within", + self.OVERLAPS: "overlaps", + self.CONTAINS: "contains", } if predicate not in methods: raise NotImplementedError( @@ -1003,8 +1184,9 @@ def testPredicate(self, predicate, engine, targetGeometries): positives.add(test_fid) return positives - def checkPredicate(self, layerA, layerB, predicate, cardinality, ctx=None, - feedback=None): + def checkPredicate( + self, layerA, layerB, predicate, cardinality, ctx=None, feedback=None + ): """ Checks if a duo of layers comply with a spatial predicate at a given cardinality. @@ -1033,29 +1215,31 @@ def checkPredicate(self, layerA, layerB, predicate, cardinality, ctx=None, self.NOTCROSSES, self.NOTWITHIN, self.NOTOVERLAPS, - self.NOTCONTAINS + self.NOTCONTAINS, ] if predicate in denials: - # denials always follow the "affirmitives" (contains = 14 + # denials always follow the "affirmitives" (contains = 14 # -> notcontains = 15), hence -1. # denials are ALWAYS absolute (cardinality is not applicable) predicate -= 1 cardinality = "0..0" if predicate == self.DISJOINT: - predicateFlagText = self.tr("feature ID {{fid_a}} from {layer_a} " - "id not {pred} to {{size}} features of" - " {layer_b}")\ - .format(layer_a=layerA.name(), - pred=predicates[predicate], - layer_b=layerB.name()) + predicateFlagText = self.tr( + "feature ID {{fid_a}} from {layer_a} " + "id not {pred} to {{size}} features of" + " {layer_b}" + ).format( + layer_a=layerA.name(), pred=predicates[predicate], layer_b=layerB.name() + ) cardinality = "0..0" else: - predicateFlagText = self.tr("feature ID {{fid_a}} from {layer_a} " - "{pred} {{size}} features of " - "{layer_b}")\ - .format(layer_a=layerA.name(), - pred=predicates[predicate], - layer_b=layerB.name()) + predicateFlagText = self.tr( + "feature ID {{fid_a}} from {layer_a} " + "{pred} {{size}} features of " + "{layer_b}" + ).format( + layer_a=layerA.name(), pred=predicates[predicate], layer_b=layerB.name() + ) if predicate in (self.EQUALS, self.WITHIN): getFlagGeometryMethod = lambda geom, _: geom else: @@ -1068,8 +1252,7 @@ def checkPredicate(self, layerA, layerB, predicate, cardinality, ctx=None, engine = QgsGeometry.createGeometryEngine(geomA.constGet()) engine.prepareGeometry() geometriesB = { - f.id(): f.geometry() \ - for f in layerB.getFeatures(geomA.boundingBox()) + f.id(): f.geometry() for f in layerB.getFeatures(geomA.boundingBox()) } positives = self.testPredicate(predicate, engine, geometriesB) if predicate == self.DISJOINT: @@ -1079,28 +1262,32 @@ def checkPredicate(self, layerA, layerB, predicate, cardinality, ctx=None, fidA = featA.id() size = len(positives) if not size: - flags[fidA].append({ - "text": predicateFlagText.format(fid_a=fidA, size=0), - "geom": geomA - }) + flags[fidA].append( + { + "text": predicateFlagText.format(fid_a=fidA, size=0), + "geom": geomA, + } + ) continue if size > 1: - predicateFlagText_ = "{0} (IDs {1})"\ - .format(predicateFlagText, ", ".join(map(str, positives))) + predicateFlagText_ = "{0} (IDs {1})".format( + predicateFlagText, ", ".join(map(str, positives)) + ) elif size == 1: - predicateFlagText_ = "{0} (ID {1})"\ - .format(predicateFlagText, str(set(positives).pop())) + predicateFlagText_ = "{0} (ID {1})".format( + predicateFlagText, str(set(positives).pop()) + ) for fidB in positives: - flags[fidA].append({ - "text": predicateFlagText_\ - .format(fid_a=fidA, size=size), - "geom": getFlagGeometryMethod(geomA, geometriesB[fidB]) - }) + flags[fidA].append( + { + "text": predicateFlagText_.format(fid_a=fidA, size=size), + "geom": getFlagGeometryMethod(geomA, geometriesB[fidB]), + } + ) feedback.setProgress(stepSize * (step + 1)) return {fid: flag for fid, flag in flags.items() if flag} - def checkDE9IM(self, layerA, layerB, mask, cardinality, ctx=None, - feedback=None): + def checkDE9IM(self, layerA, layerB, mask, cardinality, ctx=None, feedback=None): """ Applies a DE-9IM mask to compare the features of between and checks whether the occurrence limits are respected. @@ -1121,16 +1308,17 @@ def checkDE9IM(self, layerA, layerB, mask, cardinality, ctx=None, testingMethod = self.getCardinalityTest(cardinality) candidates = defaultdict(list) flags = defaultdict(list) - predicateFlagText = self.tr("feature ID {{fid_a}} from {layer_a} " - "has {{size}} occurrences using the " - "DE-9IM mask '{mask}' when compared to" - " layer {layer_b}")\ - .format(layer_a=layerA.name(), - mask=mask, - layer_b=layerB.name()) + predicateFlagText = self.tr( + "feature ID {{fid_a}} from {layer_a} " + "has {{size}} occurrences using the " + "DE-9IM mask '{mask}' when compared to" + " layer {layer_b}" + ).format(layer_a=layerA.name(), mask=mask, layer_b=layerB.name()) size = layerA.featureCount() stepSize = 100 / size if size else 0 - iteratorA = layerA.getFeatures() if isinstance(layerA, QgsVectorLayer) else layerA + iteratorA = ( + layerA.getFeatures() if isinstance(layerA, QgsVectorLayer) else layerA + ) for step, featA in enumerate(iteratorA): if feedback.isCanceled(): break @@ -1144,26 +1332,28 @@ def checkDE9IM(self, layerA, layerB, mask, cardinality, ctx=None, # if the mask has an 'invalid' count of occurrences, it is a flag! size = len(candidates[fidA]) if not size: - flags[fidA].append({ - "text": predicateFlagText.format(fid_a=fidA, size=0), - "geom": geomA - }) + flags[fidA].append( + { + "text": predicateFlagText.format(fid_a=fidA, size=0), + "geom": geomA, + } + ) continue if size > 1: predicateFlagText_ = "{0} (IDs {1})".format( - predicateFlagText, - ", ".join(map(str, candidates[fidA])) + predicateFlagText, ", ".join(map(str, candidates[fidA])) ) elif size == 1: predicateFlagText_ = "{0} (ID {1})".format( predicateFlagText.replace("occurrences", "occurrence"), - str(set(candidates[fidA]).pop()) + str(set(candidates[fidA]).pop()), ) - flags[fidA].append({ - "text": predicateFlagText_\ - .format(fid_a=fidA, size=size), - "geom": geomA - }) + flags[fidA].append( + { + "text": predicateFlagText_.format(fid_a=fidA, size=size), + "geom": geomA, + } + ) feedback.setProgress(stepSize * (step + 1)) return flags @@ -1181,9 +1371,7 @@ def setupLayer(self, layerName, exp, ctx=None, feedback=None): lh = LayerHandler() ctx = ctx or QgsProcessingContext() if exp: - layer = lh.filterByExpression( - layerName, exp, ctx, feedback - ) + layer = lh.filterByExpression(layerName, exp, ctx, feedback) # filter expression is an output is from another algo # it is the temp output -> its name is not the same as the input layer.setName(layerName) @@ -1246,9 +1434,9 @@ def enforceRules(self, ruleList, ctx=None, feedback=None): ) if not rule.isValid(): multiStepFeedback.pushInfo( - self.tr('Rule {0} is invalid and will be skipped. ' - 'Error: {1}').format( - ruleName, rule.validate(checkLoaded=True)) + self.tr( + "Rule {0} is invalid and will be skipped. " "Error: {1}" + ).format(ruleName, rule.validate(checkLoaded=True)) ) continue flags = self.enforceRule(rule, ctx, multiStepFeedback) @@ -1263,14 +1451,11 @@ def enforceRules(self, ruleList, ctx=None, feedback=None): else: out[ruleName] = flags multiStepFeedback.reportError( - self.tr('Rule "{0}" raised flags\n').format( - ruleName, idx + 1, size - ) + self.tr('Rule "{0}" raised flags\n').format(ruleName, idx + 1, size) ) else: multiStepFeedback.pushDebugInfo( - self.tr('Rule "{0}" did not raise any flags\n') - .format(ruleName) + self.tr('Rule "{0}" did not raise any flags\n').format(ruleName) ) multiStepFeedback.setCurrentStep(idx + 1) return out @@ -1282,17 +1467,19 @@ class SpatialRule(QObject): the attributes and verifies its validity. """ - def __init__(self, - name=None, - layer_a=None, - filter_a=None, - predicate=None, - de9im_predicate=None, - layer_b=None, - filter_b=None, - cardinality=None, - useDE9IM=False, - checkLoadedLayer=True): + def __init__( + self, + name=None, + layer_a=None, + filter_a=None, + predicate=None, + de9im_predicate=None, + layer_b=None, + filter_b=None, + cardinality=None, + useDE9IM=False, + checkLoadedLayer=True, + ): """ Initiates an instance of SpatialRule. :param name: (str) display name for the spatial rule. @@ -1432,7 +1619,7 @@ def layerA(self): :return: (str) layer A's name. """ return str(self._attr.get("layer_a", "")) - + def validateFilterExpression(self, exp): """ Checks whether a filtering expression is syntactically valid. @@ -1441,7 +1628,7 @@ def validateFilterExpression(self, exp): """ # empty filters are allowed return exp == "" or QgsExpression(exp.replace("\\", "")).isValid() - + def _setFilterExpression(self, exp, key): """ Private method used to route filter expression's updates to the correct @@ -1514,8 +1701,10 @@ def validatePredicate(self, pred, useDE9IM): if useDE9IM: regex = QRegExp("[FfTt012\*]{9}") acceptable = QRegExpValidator.Acceptable - return isinstance(pred, str) and \ - QRegExpValidator(regex).validate(pred, 9)[0] == acceptable + return ( + isinstance(pred, str) + and QRegExpValidator(regex).validate(pred, 9)[0] == acceptable + ) else: return pred in SpatialRelationsHandler().availablePredicates() @@ -1527,8 +1716,11 @@ def predicateIsValid(self): true in cases that "active" predicate is valid and the other isn't. :return: (bool) property's value validity. """ - return self.predicateDE9IMIsValid() if self.useDE9IM() \ + return ( + self.predicateDE9IMIsValid() + if self.useDE9IM() else self.predicateEnumIsValid() + ) def setPredicate(self, pred): """ @@ -1540,8 +1732,11 @@ def setPredicate(self, pred): mask to be set. :return: (bool) whether the property was updated. """ - return self.setPredicateDE9IM(pred) if self.useDE9IM() \ + return ( + self.setPredicateDE9IM(pred) + if self.useDE9IM() else self.setPredicateEnum(pred) + ) def predicate(self): """ @@ -1591,7 +1786,7 @@ def setPredicateDE9IM(self, pred): Updates the value of the DE-9IM mask set for the spatial rule. If the value is invalid, the property is not updated. :param pred: (str) the DE-9IM mask linearized as a string to be set. - :return: (bool) whether the property was updated. + :return: (bool) whether the property was updated. """ if not self.validatePredicate(pred, useDE9IM=True): return False @@ -1668,8 +1863,10 @@ def validateCardinality(self, card): """ regex = QRegExp("[0-9\*]\.\.[0-9\*]") acceptable = QRegExpValidator.Acceptable - return isinstance(card, str) and \ - QRegExpValidator(regex).validate(card, 9)[0] == acceptable + return ( + isinstance(card, str) + and QRegExpValidator(regex).validate(card, 9)[0] == acceptable + ) def cardinalityIsValid(self): """ @@ -1713,7 +1910,7 @@ def validate(self, checkLoaded=False): # "de9im_predicate": self.predicateDE9IM, "layer_b": lambda: self.layerBIsValid(checkLoaded), "filter_b": self.filterBIsValid, - "cardinality": self.cardinalityIsValid + "cardinality": self.cardinalityIsValid, } valueMethodMap = { "name": self.ruleName, @@ -1721,7 +1918,7 @@ def validate(self, checkLoaded=False): "filter_a": self.filterA, "layer_b": self.layerB, "filter_b": self.filterB, - "cardinality": self.cardinality + "cardinality": self.cardinality, } for prop, validationMethod in methodMap.items(): if not validationMethod(): @@ -1742,15 +1939,17 @@ def isValid(self, checkLoaded=False): that it is not selected to be used (either mask or enumerator). :param checkLoaded: (bool) whether canvas availability should be considered. - :return: (bool) whether spatial rule may be enforced. - """ - return self.ruleNameIsValid() \ - and self.layerAIsValid(checkLoaded) \ - and self.filterAIsValid() \ - and self.predicateIsValid() \ - and self.layerBIsValid(checkLoaded) \ - and self.filterBIsValid() \ + :return: (bool) whether spatial rule may be enforced. + """ + return ( + self.ruleNameIsValid() + and self.layerAIsValid(checkLoaded) + and self.filterAIsValid() + and self.predicateIsValid() + and self.layerBIsValid(checkLoaded) + and self.filterBIsValid() and self.cardinalityIsValid() + ) def asDict(self): """ @@ -1769,5 +1968,5 @@ def asDict(self): "layer_b": self.layerB(), "filter_b": self.filterB(), "cardinality": self.cardinality(), - "useDE9IM": self.useDE9IM() + "useDE9IM": self.useDE9IM(), } diff --git a/DsgTools/core/LayerTools/CustomFormTools/customFormGenerator.py b/DsgTools/core/LayerTools/CustomFormTools/customFormGenerator.py index c405eb011..c751277d8 100755 --- a/DsgTools/core/LayerTools/CustomFormTools/customFormGenerator.py +++ b/DsgTools/core/LayerTools/CustomFormTools/customFormGenerator.py @@ -24,16 +24,14 @@ import os from qgis import core + class CustomFormGenerator(object): def __init__(self): super(CustomFormGenerator, self).__init__() - self.lenColumnDict = { - 1 : u'length_otf', - 2 : u'area_otf' - } + self.lenColumnDict = {1: "length_otf", 2: "area_otf"} def get_form_template(self): - return u''' + return """ Dialog @@ -127,10 +125,10 @@ def get_form_template(self): - ''' + """ - def get_le_template(self, field, alias, row, readOnly=''): - return ''' + def get_le_template(self, field, alias, row, readOnly=""): + return """ {alias} @@ -142,10 +140,12 @@ def get_le_template(self, field, alias, row, readOnly=''): {readOnly} - '''.format(alias=alias, field=field, row=row, readOnly=readOnly) + """.format( + alias=alias, field=field, row=row, readOnly=readOnly + ) def get_cb_template(self, field, alias, row): - return ''' + return """ {alias} @@ -154,65 +154,52 @@ def get_cb_template(self, field, alias, row): - '''.format(alias=alias, field=field, row=row) + """.format( + alias=alias, field=field, row=row + ) def create_cb(self, field, alias, row): return self.get_cb_template(field, alias, row) def create_le(self, field, alias, row, setReadOnly=False): - """ if setReadOnly: + """if setReadOnly: readOnly =u''' true ''' - return self.get_le_template(field, row, readOnly) - else: """ + return self.get_le_template(field, row, readOnly) + else:""" return self.get_le_template(field, alias, row) def create(self, vlayer, layerData): - form_path = os.path.join( - os.path.dirname(__file__), - u"forms", - vlayer.name() - ) + form_path = os.path.join(os.path.dirname(__file__), "forms", vlayer.name()) with open(form_path, "w") as formFile: form = self.get_form_template() - layerData = layerData['layer_fields'] - all_items = u"" + layerData = layerData["layer_fields"] + all_items = "" rowAttr = 1 for field in vlayer.fields(): field_name = field.name() field_alias = field.alias() - if field in [u'id', u'controle_id', u'ultimo_usuario', u'data_modificacao']: + if field in ["id", "controle_id", "ultimo_usuario", "data_modificacao"]: all_items += self.create_le( field_name, field_alias, rowAttr, setReadOnly=True ) - elif field_name == u'tipo': - if u'filter' in layerData: - all_items += self.create_cb( - u'filter', u'filter', rowAttr - ) - all_items += self.create_cb( - field_name, field_alias, rowAttr - ) + elif field_name == "tipo": + if "filter" in layerData: + all_items += self.create_cb("filter", "filter", rowAttr) + all_items += self.create_cb(field_name, field_alias, rowAttr) rowAttr += 1 elif (field_name in layerData) and layerData[field]: - all_items += self.create_cb( - field_name, field_alias, rowAttr - ) - elif (field_name in layerData): - all_items += self.create_le( - field_name, field_alias, rowAttr - ) + all_items += self.create_cb(field_name, field_alias, rowAttr) + elif field_name in layerData: + all_items += self.create_le(field_name, field_alias, rowAttr) rowAttr += 1 if vlayer.geometryType() in self.lenColumnDict: all_items += self.create_le( self.lenColumnDict[vlayer.geometryType()], self.lenColumnDict[vlayer.geometryType()], - rowAttr + 1 + rowAttr + 1, ) - form = form.format( - items=unicode(all_items), - row_btn=rowAttr+1 - ) + form = form.format(items=unicode(all_items), row_btn=rowAttr + 1) formFile.write(form) - return form_path \ No newline at end of file + return form_path diff --git a/DsgTools/core/LayerTools/CustomFormTools/customInitCodeGenerator.py b/DsgTools/core/LayerTools/CustomFormTools/customInitCodeGenerator.py index d9ac67b41..d9a9bb3dd 100755 --- a/DsgTools/core/LayerTools/CustomFormTools/customInitCodeGenerator.py +++ b/DsgTools/core/LayerTools/CustomFormTools/customInitCodeGenerator.py @@ -24,47 +24,28 @@ import json import os + class CustomInitCodeGenerator(object): def __init__(self): # contrutor - super(CustomInitCodeGenerator, self).__init__() + super(CustomInitCodeGenerator, self).__init__() def getInitCodeWithFilter(self, tableFilter, rules): optFilter = self.formatOptionFilter(tableFilter) tableFilterFormated = self.formatTableFilter(tableFilter) initCode = self.getTemplateInitCodeWithFilter() initCode = initCode.replace( - '{optfilter}', - json.dumps( - optFilter, - ensure_ascii=False - ) - ) - initCode = initCode.replace( - '{filter}', - json.dumps( - tableFilterFormated, - ensure_ascii=False - ) + "{optfilter}", json.dumps(optFilter, ensure_ascii=False) ) initCode = initCode.replace( - '{rules}', - json.dumps( - rules, - ensure_ascii=False - ) + "{filter}", json.dumps(tableFilterFormated, ensure_ascii=False) ) + initCode = initCode.replace("{rules}", json.dumps(rules, ensure_ascii=False)) return initCode def getInitCodeWithoutFilter(self, rules): initCode = self.getTemplateInitCodeNotFilter() - initCode = initCode.replace( - '{rules}', - json.dumps( - rules, - ensure_ascii=False - ) - ) + initCode = initCode.replace("{rules}", json.dumps(rules, ensure_ascii=False)) return initCode def formatTableFilter(self, tableFilter): @@ -72,33 +53,31 @@ def formatTableFilter(self, tableFilter): for line in tableFilter: tableFilterFormated[line[1]] = line[0] return tableFilterFormated - + def formatOptionFilter(self, tableFilter): optFilter = {} for line in tableFilter: - optFilter[unicode(line[2])] = ((line[0]-(line[0]%100))/100) + optFilter[unicode(line[2])] = (line[0] - (line[0] % 100)) / 100 return optFilter def getTemplateInitCodeNotFilter(self): - initCodeTemplate = u"" + initCodeTemplate = "" pathCode = os.path.join( - os.path.dirname(__file__), - 'formInitCodeWithoutFilterTemplate.txt' + os.path.dirname(__file__), "formInitCodeWithoutFilterTemplate.txt" ) codeFile = open(pathCode, "r") for line in codeFile.readlines(): - initCodeTemplate += line#.decode("utf-8") + initCodeTemplate += line # .decode("utf-8") codeFile.close() return initCodeTemplate def getTemplateInitCodeWithFilter(self): - initCodeTemplate = u"" + initCodeTemplate = "" pathCode = os.path.join( - os.path.dirname(__file__), - 'formInitCodeWithFilterTemplate.txt' + os.path.dirname(__file__), "formInitCodeWithFilterTemplate.txt" ) codeFile = open(pathCode, "r") for line in codeFile.readlines(): - initCodeTemplate += line#.decode("utf-8") + initCodeTemplate += line # .decode("utf-8") codeFile.close() return initCodeTemplate diff --git a/DsgTools/core/LayerTools/CustomFormTools/formInitCodeWithFilterTemplate b/DsgTools/core/LayerTools/CustomFormTools/formInitCodeWithFilterTemplate index 32c039f7a..83f7cbee5 100755 --- a/DsgTools/core/LayerTools/CustomFormTools/formInitCodeWithFilterTemplate +++ b/DsgTools/core/LayerTools/CustomFormTools/formInitCodeWithFilterTemplate @@ -8,12 +8,12 @@ global a class ValidateForm: def __init__(self, layer, formValues, logBrowser): - self.layer = layer + self.layer = layer self.formValues = formValues self.rules = {rules} self.logBrowser = logBrowser self.validateForm() - + def calculateExpression(self, exp): for field in self.formValues: if field != 'filter': @@ -25,7 +25,7 @@ class ValidateForm: exp = exp.replace("'NULL'".format(field), "NULL") r = QgsExpression(exp) return r.evaluate() - + def validateForm(self): self.cleanRulesOnForm() logText = "" @@ -56,7 +56,7 @@ class ValidateForm: def cleanRulesOnForm(self): for field in self.formValues: if len(self.formValues[field]) == 3: - self.formValues[field][2].setStyleSheet("") + self.formValues[field][2].setStyleSheet("") else: self.formValues[field][1].setStyleSheet("") @@ -122,14 +122,14 @@ class ManagerForm(QtCore.QObject): le ] self.validadeForm = ValidateForm(self.lyr, formValues, self.logBrowser) - + def filterTypeField(self): value = self.filterField.currentText() itemsFiltered = self.getItemsFiltered(value) self.typeField.clear() for k, v in sorted(itemsFiltered.items()): self.typeField.addItem(k, v) - + def getItemsFiltered(self, value): result = {} if value == "Filtro": @@ -143,19 +143,19 @@ class ManagerForm(QtCore.QObject): result.update({'A SER PREENCHIDO' : '999'}) return result return result - + def finishedForm(self): idx_field = self.lyr.fields().indexOf('tipo') setup = core.QgsEditorWidgetSetup( 'ValueMap', { 'map': self.mapValue } - ) + ) self.lyr.setEditorWidgetSetup(idx_field, setup) - + def formOpen(dialog, layer, featureid): try: global a a = ManagerForm(dialog, layer, featureid) except: - pass \ No newline at end of file + pass diff --git a/DsgTools/core/LayerTools/CustomFormTools/formInitCodeWithoutFilterTemplate b/DsgTools/core/LayerTools/CustomFormTools/formInitCodeWithoutFilterTemplate index 059d4721c..26ac35af1 100755 --- a/DsgTools/core/LayerTools/CustomFormTools/formInitCodeWithoutFilterTemplate +++ b/DsgTools/core/LayerTools/CustomFormTools/formInitCodeWithoutFilterTemplate @@ -8,12 +8,12 @@ global a class ValidateForm: def __init__(self, layer, formValues, logBrowser): - self.layer = layer + self.layer = layer self.formValues = formValues self.rules = {rules} self.logBrowser = logBrowser self.validateForm() - + def calculateExpression(self, exp): for field in self.formValues: if field != 'filter': @@ -25,7 +25,7 @@ class ValidateForm: exp = exp.replace("'NULL'".format(field), "NULL") r = QgsExpression(exp) return r.evaluate() - + def validateForm(self): self.cleanRulesOnForm() logText = "" @@ -56,7 +56,7 @@ class ValidateForm: def cleanRulesOnForm(self): for field in self.formValues: if len(self.formValues[field]) == 3: - self.formValues[field][2].setStyleSheet("") + self.formValues[field][2].setStyleSheet("") else: self.formValues[field][1].setStyleSheet("") @@ -88,12 +88,12 @@ class ManagerForm(QtCore.QObject): self.logFrame.show() else: self.logFrame.hide() - + def eventFilter(self, o, event): if event.type() in [7, 10, 11, 100]: self.validateLayerByRules() return False - + def validateLayerByRules(self): formValues = {} for cb in self.myDialog.findChildren(QComboBox): @@ -109,7 +109,7 @@ class ManagerForm(QtCore.QObject): le ] self.validadeForm = ValidateForm(self.lyr, formValues, self.logBrowser) - + def finishedForm(self): pass @@ -118,4 +118,4 @@ def formOpen(dialog, layer, featureid): global a a = ManagerForm(dialog, layer, featureid) except: - pass \ No newline at end of file + pass diff --git a/DsgTools/core/Misc/QGIS_Models/enhancer.model b/DsgTools/core/Misc/QGIS_Models/enhancer.model index cea4c0c10..869898566 100644 --- a/DsgTools/core/Misc/QGIS_Models/enhancer.model +++ b/DsgTools/core/Misc/QGIS_Models/enhancer.model @@ -5,176 +5,176 @@ "values": { "pos": { "values": { - "y": 60.0, + "y": 60.0, "x": 123.0 - }, + }, "class": "point" - }, + }, "param": { "values": { - "isAdvanced": false, - "name": "RASTERLAYER_LOWERRESOLUTIONPCTIMAGE", - "showSublayersDialog": true, - "value": null, - "exported": null, - "hidden": false, - "optional": false, + "isAdvanced": false, + "name": "RASTERLAYER_LOWERRESOLUTIONPCTIMAGE", + "showSublayersDialog": true, + "value": null, + "exported": null, + "hidden": false, + "optional": false, "description": "Lower Resolution (PCT Image)" - }, + }, "class": "processing.core.parameters.ParameterRaster" } - }, + }, "class": "processing.modeler.ModelerAlgorithm.ModelerParameter" - }, + }, "RASTERLAYER_HIGHERRESOLUTION": { "values": { "pos": { "values": { - "y": 128.0, + "y": 128.0, "x": 125.0 - }, + }, "class": "point" - }, + }, "param": { "values": { - "isAdvanced": false, - "name": "RASTERLAYER_HIGHERRESOLUTION", - "showSublayersDialog": true, - "value": null, - "exported": null, - "hidden": false, - "optional": false, + "isAdvanced": false, + "name": "RASTERLAYER_HIGHERRESOLUTION", + "showSublayersDialog": true, + "value": null, + "exported": null, + "hidden": false, + "optional": false, "description": "Higher Resolution" - }, + }, "class": "processing.core.parameters.ParameterRaster" } - }, + }, "class": "processing.modeler.ModelerAlgorithm.ModelerParameter" } - }, - "helpContent": {}, - "group": "DSG", - "name": "enhancer", + }, + "helpContent": {}, + "group": "DSG", + "name": "enhancer", "algs": { "SCRIPTHSVFUSION_1": { "values": { - "name": "SCRIPTHSVFUSION_1", - "paramsFolded": true, + "name": "SCRIPTHSVFUSION_1", + "paramsFolded": true, "outputs": { "Pansharpened": { "values": { - "description": "pansharpened", + "description": "pansharpened", "pos": { "values": { - "y": 353.0, + "y": 353.0, "x": 431.0 - }, + }, "class": "point" } - }, + }, "class": "processing.modeler.ModelerAlgorithm.ModelerOutput" } - }, - "outputsFolded": true, + }, + "outputsFolded": true, "pos": { "values": { - "y": 265.0, + "y": 265.0, "x": 430.0 - }, + }, "class": "point" - }, - "dependencies": [], + }, + "dependencies": [], "params": { "RGB_Layer": { "values": { - "alg": "OTBSUPERIMPOSESENSOR_1", + "alg": "OTBSUPERIMPOSESENSOR_1", "output": "-out" - }, + }, "class": "processing.modeler.ModelerAlgorithm.ValueFromOutput" - }, + }, "Pan_Layer": { "values": { "name": "RASTERLAYER_HIGHERRESOLUTION" - }, + }, "class": "processing.modeler.ModelerAlgorithm.ValueFromInput" } - }, - "active": true, - "consoleName": "script:hsvfusion", + }, + "active": true, + "consoleName": "script:hsvfusion", "description": "HSV fusion" - }, + }, "class": "processing.modeler.ModelerAlgorithm.Algorithm" - }, + }, "OTBSUPERIMPOSESENSOR_1": { "values": { - "name": "OTBSUPERIMPOSESENSOR_1", - "paramsFolded": true, - "outputs": {}, - "outputsFolded": true, + "name": "OTBSUPERIMPOSESENSOR_1", + "paramsFolded": true, + "outputs": {}, + "outputsFolded": true, "pos": { "values": { - "y": 154.0, + "y": 154.0, "x": 425.0 - }, + }, "class": "point" - }, - "dependencies": [], + }, + "dependencies": [], "params": { - "-interpolator": 0, + "-interpolator": 0, "-inm": { "values": { - "alg": "GDALOGRPCTTORGB_1", + "alg": "GDALOGRPCTTORGB_1", "output": "OUTPUT" - }, + }, "class": "processing.modeler.ModelerAlgorithm.ValueFromOutput" - }, - "-ram": 512.0, - "-interpolator.bco.radius": 2.0, - "-lms": 4.0, + }, + "-ram": 512.0, + "-interpolator.bco.radius": 2.0, + "-lms": 4.0, "-inr": { "values": { "name": "RASTERLAYER_HIGHERRESOLUTION" - }, + }, "class": "processing.modeler.ModelerAlgorithm.ValueFromInput" - }, + }, "-elev.default": 0.0 - }, - "active": true, - "consoleName": "otb:superimposesensor", + }, + "active": true, + "consoleName": "otb:superimposesensor", "description": "Superimpose sensor" - }, + }, "class": "processing.modeler.ModelerAlgorithm.Algorithm" - }, + }, "GDALOGRPCTTORGB_1": { "values": { - "name": "GDALOGRPCTTORGB_1", - "paramsFolded": true, - "outputs": {}, - "outputsFolded": true, + "name": "GDALOGRPCTTORGB_1", + "paramsFolded": true, + "outputs": {}, + "outputsFolded": true, "pos": { "values": { - "y": 60.0, + "y": 60.0, "x": 423.0 - }, + }, "class": "point" - }, - "dependencies": [], + }, + "dependencies": [], "params": { "INPUT": { "values": { "name": "RASTERLAYER_LOWERRESOLUTIONPCTIMAGE" - }, + }, "class": "processing.modeler.ModelerAlgorithm.ValueFromInput" - }, + }, "NBAND": 0 - }, - "active": true, - "consoleName": "gdalogr:pcttorgb", + }, + "active": true, + "consoleName": "gdalogr:pcttorgb", "description": "PCT to RGB" - }, + }, "class": "processing.modeler.ModelerAlgorithm.Algorithm" } } - }, + }, "class": "processing.modeler.ModelerAlgorithm.ModelerAlgorithm" -} \ No newline at end of file +} diff --git a/DsgTools/core/Misc/QGIS_Scripts/HSV_fusion.py b/DsgTools/core/Misc/QGIS_Scripts/HSV_fusion.py index 6c77fdd87..353b5f710 100644 --- a/DsgTools/core/Misc/QGIS_Scripts/HSV_fusion.py +++ b/DsgTools/core/Misc/QGIS_Scripts/HSV_fusion.py @@ -34,6 +34,7 @@ import colorsys import numpy + class RasterProcess(object): def __init__(self): """ @@ -50,7 +51,7 @@ def openRaster(self, file): raster = gdal.Open(file) except RuntimeError as e: # fix_print_with_import - print('Unable to open image') + print("Unable to open image") # fix_print_with_import print(e) @@ -69,7 +70,7 @@ def getBandAsArray(self, raster, bandnumber): except RuntimeError as e: # for example, try GetRasterBand(10) # fix_print_with_import - print('Band ( %i ) not found' % bandnumber) + print("Band ( %i ) not found" % bandnumber) # fix_print_with_import print(e) sys.exit(1) @@ -79,7 +80,7 @@ def getBandAsArray(self, raster, bandnumber): def getGeoreferenceInfo(self, raster): """ Gets georeference information - raster: raster file + raster: raster file """ # Get raster georeference info transform = raster.GetGeoTransform() @@ -109,7 +110,7 @@ def createRasterFromRGBbands(self, srcraster, red, green, blue, destfile): destfile: destination file """ outRaster = self.createRaster(srcraster, destfile) - + outRaster.GetRasterBand(1).WriteArray(red) outRaster.GetRasterBand(2).WriteArray(green) outRaster.GetRasterBand(3).WriteArray(blue) @@ -124,16 +125,18 @@ def createRaster(self, srcraster, destfile, pixelType): cols = srcraster.RasterXSize rows = srcraster.RasterYSize - (xOrigin, yOrigin, pixelWidth, pixelHeight) = self.getGeoreferenceInfo(srcraster) + (xOrigin, yOrigin, pixelWidth, pixelHeight) = self.getGeoreferenceInfo( + srcraster + ) targetSR = self.getCRS(srcraster) - driver = gdal.GetDriverByName('GTiff') + driver = gdal.GetDriverByName("GTiff") outRaster = driver.Create(destfile, cols, rows, 3, pixelType) outRaster.SetGeoTransform((xOrigin, pixelWidth, 0, yOrigin, 0, pixelHeight)) outRaster.SetProjection(targetSR.ExportToWkt()) - + return outRaster def pansharpenImage(self, rgbfile, panfile, destfile): @@ -150,10 +153,10 @@ def pansharpenImage(self, rgbfile, panfile, destfile): panraster = self.openRaster(panfile) pan = panraster.GetRasterBand(1) - + rgb_to_hsv = numpy.vectorize(colorsys.rgb_to_hsv) hsv_to_rgb = numpy.vectorize(colorsys.hsv_to_rgb) - + if red.DataType > pan.DataType: pixelType = red.DataType else: @@ -165,7 +168,7 @@ def pansharpenImage(self, rgbfile, panfile, destfile): outB = outRaster.GetRasterBand(3) sizeX = pan.XSize - sizeY = pan.YSize + sizeY = pan.YSize p = 0 progress.setPercentage(p) @@ -188,23 +191,23 @@ def pansharpenImage(self, rgbfile, panfile, destfile): self.writeBlock(outG, g, sizeX, lines, row, pixelType) self.writeBlock(outB, b, sizeX, lines, row, pixelType) - if int(float(row)/sizeY*100) != p: - p = int(float(row)/sizeY*100) + if int(float(row) / sizeY * 100) != p: + p = int(float(row) / sizeY * 100) progress.setPercentage(p) rgb = None panraster = None outRaster = None - + def normalize(self, arr): """ Function to normalize an input array to 0-1 """ arr_min = arr.min() arr_max = arr.max() - return [(arr - arr_min) / (arr_max - arr_min)]*255 - - def readBlock(self, band, sizeX, sizeY = 1, offsetY = 0, pixelType = gdal.GDT_Byte): + return [(arr - arr_min) / (arr_max - arr_min)] * 255 + + def readBlock(self, band, sizeX, sizeY=1, offsetY=0, pixelType=gdal.GDT_Byte): """ Reads image block band: band used @@ -215,12 +218,14 @@ def readBlock(self, band, sizeX, sizeY = 1, offsetY = 0, pixelType = gdal.GDT_By """ numpytype = self.getNumpyType(pixelType) - bandscanline =band.ReadRaster( 0, offsetY, sizeX, sizeY, sizeX, sizeY, pixelType ) - pixelArray=numpy.fromstring(bandscanline, dtype=numpytype) - + bandscanline = band.ReadRaster( + 0, offsetY, sizeX, sizeY, sizeX, sizeY, pixelType + ) + pixelArray = numpy.fromstring(bandscanline, dtype=numpytype) + return pixelArray - - def getNumpyType(self, pixelType = gdal.GDT_Byte): + + def getNumpyType(self, pixelType=gdal.GDT_Byte): """ Translates the gdal raster type to numpy type pixelType: gdal raster type @@ -239,8 +244,10 @@ def getNumpyType(self, pixelType = gdal.GDT_Byte): return numpy.float32 elif pixelType == gdal.GDT_Float64: return numpy.float64 - - def writeBlock(self, band, block, sizeX, sizeY = 1, offsetY = 0, pixelType = gdal.GDT_Byte): + + def writeBlock( + self, band, block, sizeX, sizeY=1, offsetY=0, pixelType=gdal.GDT_Byte + ): """ Writes image block band: band used @@ -253,7 +260,6 @@ def writeBlock(self, band, block, sizeX, sizeY = 1, offsetY = 0, pixelType = gda band.WriteRaster(0, offsetY, sizeX, sizeY, block.astype(numpytype).tostring()) + obj = RasterProcess() -obj.pansharpenImage(RGB_Layer, - Pan_Layer, - Pansharpened) +obj.pansharpenImage(RGB_Layer, Pan_Layer, Pansharpened) diff --git a/DsgTools/core/Misc/QGIS_Scripts/Sigef.py b/DsgTools/core/Misc/QGIS_Scripts/Sigef.py index ce430f194..033c40cbf 100644 --- a/DsgTools/core/Misc/QGIS_Scripts/Sigef.py +++ b/DsgTools/core/Misc/QGIS_Scripts/Sigef.py @@ -3,10 +3,13 @@ ##Dados_SIGEF=output table from builtins import str -from processing.core.GeoAlgorithmExecutionException import GeoAlgorithmExecutionException +from processing.core.GeoAlgorithmExecutionException import ( + GeoAlgorithmExecutionException, +) from qgis.core import * import csv + def dd2dms_sigef(dd): """ Converts decimal degrees to degree, minute, second @@ -15,19 +18,20 @@ def dd2dms_sigef(dd): """ # calculos com numeros d = int(dd) - m = abs(int(60*(dd-int(dd)))) - s = abs((dd-d-m/60)*60) + m = abs(int(60 * (dd - int(dd)))) + s = abs((dd - d - m / 60) * 60) s_int = int(s) s_d = s - s_int # fazendo as strings d = str(d).zfill(2) m = str(m).zfill(2) s_int = str(s_int).zfill(2) - s_d = str(s_d).split('.')[-1] + s_d = str(s_d).split(".")[-1] # fazendo o retorno - dms_sigef = d+','+m+s_int+'%0.3s'%s_d + dms_sigef = d + "," + m + s_int + "%0.3s" % s_d return dms_sigef - + + def createCSV(input, output): """ Creates the output CSV file @@ -38,33 +42,36 @@ def createCSV(input, output): layer = processing.getObject(input) features = layer.selectedFeatures() if len(features) != 1: - raise GeoAlgorithmExecutionException('Selecione uma e somente uma geometria!') - - csvfile = open(output, 'wb') + raise GeoAlgorithmExecutionException("Selecione uma e somente uma geometria!") + + csvfile = open(output, "wb") outwriter = csv.writer(csvfile) - outwriter.writerow(['id', 'Long', 'Lat']) + outwriter.writerow(["id", "Long", "Lat"]) feature = features[0] geom = feature.geometry() polygon = geom.asPolygon() outring = polygon[0] - + crsDest = QgsCoordinateReferenceSystem(4674) coordinateTransformer = QgsCoordinateTransform(layer.crs(), crsDest) count = 0 size = len(outring) p = 0 - progress.setPercentage(p) + progress.setPercentage(p) for point in outring: sirgasPt = coordinateTransformer.transform(point) - outwriter.writerow([str(count), dd2dms_sigef(sirgasPt[0]), dd2dms_sigef(sirgasPt[1])]) + outwriter.writerow( + [str(count), dd2dms_sigef(sirgasPt[0]), dd2dms_sigef(sirgasPt[1])] + ) count += 1 - if int(float(count)/size*100) != p: - p = int(float(count)/size*100) + if int(float(count) / size * 100) != p: + p = int(float(count) / size * 100) progress.setPercentage(p) - + csvfile.close() - -createCSV(Perimetro, Dados_SIGEF) \ No newline at end of file + + +createCSV(Perimetro, Dados_SIGEF) diff --git a/DsgTools/core/Misc/QGIS_Scripts/Sigef.py.help b/DsgTools/core/Misc/QGIS_Scripts/Sigef.py.help index 87a273ed6..f894324e8 100644 --- a/DsgTools/core/Misc/QGIS_Scripts/Sigef.py.help +++ b/DsgTools/core/Misc/QGIS_Scripts/Sigef.py.help @@ -1 +1 @@ -{"ALG_DESC": "Algoritmo que cria um arquivo CSV com dados de Latitude Longitude para inser\u00e7\u00e3o na planilha do SIGEF (grau, minuto e segundo no formato decimal). Os dados de origem ser\u00e3o convertidos para SIRGAS2000 no formato grau decimal.", "ALG_CREATOR": "Luiz Claudio Oliveira de Andrade\nEngenheiro Cartogr\u00e1fo - DSG", "ALG_VERSION": "1.0", "ALG_HELP_CREATOR": "Luiz Claudio Oliveira de Andrade\nEngenheiro Cartogr\u00e1fo - DSG", "Dados_SIGEF": "CSV com dados de Latitude Longitude para inser\u00e7\u00e3o na planilha do SIGEF (grau, minuto e segundo no formato decimal)", "Perimetro": "Camada vetorial com coordenadas no CRS SIRGAS 2000."} \ No newline at end of file +{"ALG_DESC": "Algoritmo que cria um arquivo CSV com dados de Latitude Longitude para inser\u00e7\u00e3o na planilha do SIGEF (grau, minuto e segundo no formato decimal). Os dados de origem ser\u00e3o convertidos para SIRGAS2000 no formato grau decimal.", "ALG_CREATOR": "Luiz Claudio Oliveira de Andrade\nEngenheiro Cartogr\u00e1fo - DSG", "ALG_VERSION": "1.0", "ALG_HELP_CREATOR": "Luiz Claudio Oliveira de Andrade\nEngenheiro Cartogr\u00e1fo - DSG", "Dados_SIGEF": "CSV com dados de Latitude Longitude para inser\u00e7\u00e3o na planilha do SIGEF (grau, minuto e segundo no formato decimal)", "Perimetro": "Camada vetorial com coordenadas no CRS SIRGAS 2000."} diff --git a/DsgTools/core/Misc/QGIS_Scripts/edgv_checker.py b/DsgTools/core/Misc/QGIS_Scripts/edgv_checker.py index 27edeec36..cbe6a9a09 100644 --- a/DsgTools/core/Misc/QGIS_Scripts/edgv_checker.py +++ b/DsgTools/core/Misc/QGIS_Scripts/edgv_checker.py @@ -5,13 +5,14 @@ import csv, os from osgeo import ogr + def edgv_checker(folder, output): """ Checks if a spatialite is a dsgtools database """ - csvfile = open(output, 'wb') + csvfile = open(output, "wb") outwriter = csv.writer(csvfile) - outwriter.writerow(['arquivo', 'edgv']) + outwriter.writerow(["arquivo", "edgv"]) for root, dirs, files in os.walk(folder): count = 0 @@ -19,20 +20,21 @@ def edgv_checker(folder, output): p = 0 progress.setPercentage(p) for file in files: - if '.sqlite' not in file: + if ".sqlite" not in file: continue - file = os.path.join(root,file) + file = os.path.join(root, file) ogrSrc = ogr.Open(file) isEdgv = False if ogrSrc: - layer = ogrSrc.GetLayerByName('cb_adm_area_pub_civil_a') + layer = ogrSrc.GetLayerByName("cb_adm_area_pub_civil_a") isEdgv = True if layer else False outwriter.writerow([file, isEdgv]) - if int(float(count)/size*100) != p: - p = int(float(count)/size*100) + if int(float(count) / size * 100) != p: + p = int(float(count) / size * 100) progress.setPercentage(p) csvfile.close() -edgv_checker(Pasta_de_Busca, Relatorio) \ No newline at end of file + +edgv_checker(Pasta_de_Busca, Relatorio) diff --git a/DsgTools/core/Misc/QGIS_Scripts/reverse_geocode.py b/DsgTools/core/Misc/QGIS_Scripts/reverse_geocode.py index 6244971fe..d7a1b4828 100644 --- a/DsgTools/core/Misc/QGIS_Scripts/reverse_geocode.py +++ b/DsgTools/core/Misc/QGIS_Scripts/reverse_geocode.py @@ -4,47 +4,50 @@ from future import standard_library + standard_library.install_aliases() import urllib.request, urllib.error, urllib.parse, csv -from processing.core.GeoAlgorithmExecutionException import GeoAlgorithmExecutionException +from processing.core.GeoAlgorithmExecutionException import ( + GeoAlgorithmExecutionException, +) + def rev_geocode(long, lat): latitude = lat longitude = int - sensor = 'true' + sensor = "true" base = "http://maps.googleapis.com/maps/api/geocode/json?" params = "latlng={lat},{lon}&sensor={sen}".format( - lat=latitude, - lon=longitude, - sen=sensor + lat=latitude, lon=longitude, sen=sensor ) url = "{base}{params}".format(base=base, params=params) response = urllib.request.urlopen(url) return eval(response.read()) - -output = open(addresses_txt, 'wb') + + +output = open(addresses_txt, "wb") csvwriter = csv.writer(output) -with open(coordinates_csv, 'rb') as csvfile: +with open(coordinates_csv, "rb") as csvfile: coords = csv.reader(csvfile) count = 0 - size = sum(1 for row in coords) + size = sum(1 for row in coords) p = 0 progress.setPercentage(p) - + csvfile.seek(0) - csvwriter.writerow(['lat', 'long', 'address']) + csvwriter.writerow(["lat", "long", "address"]) for coord in coords: long = coord[1] lat = coord[0] address = rev_geocode(int, lat) - if address['status'] == 'OK': - csvwriter.writerow( [lat, int, address['results'][0]['formatted_address']]) + if address["status"] == "OK": + csvwriter.writerow([lat, int, address["results"][0]["formatted_address"]]) - if int(float(count)/size*100) != p: - p = int(float(count)/size*100) + if int(float(count) / size * 100) != p: + p = int(float(count) / size * 100) progress.setPercentage(p) -output.close() \ No newline at end of file +output.close() diff --git a/DsgTools/core/Misc/QGIS_Scripts/virtual_raster.py b/DsgTools/core/Misc/QGIS_Scripts/virtual_raster.py index 3767c41b3..83c11fcc7 100644 --- a/DsgTools/core/Misc/QGIS_Scripts/virtual_raster.py +++ b/DsgTools/core/Misc/QGIS_Scripts/virtual_raster.py @@ -26,27 +26,38 @@ ##Pasta=folder import processing -from processing.core.GeoAlgorithmExecutionException import GeoAlgorithmExecutionException -from qgis.core import QgsVectorLayer, QgsRasterLayer, QgsSpatialIndex, QgsFeatureRequest, QgsCoordinateTransform, QgsFeature +from processing.core.GeoAlgorithmExecutionException import ( + GeoAlgorithmExecutionException, +) +from qgis.core import ( + QgsVectorLayer, + QgsRasterLayer, + QgsSpatialIndex, + QgsFeatureRequest, + QgsCoordinateTransform, + QgsFeature, +) import os import shutil, stat -#script methods +# script methods def createReprojectedLayer(layer, crs): """ Creates a reprojected layer layer: layer used crs: crs used """ - temp = QgsVectorLayer('%s?crs=%s'% ('Multipolygon', crs.authid()), 'temp', 'memory') + temp = QgsVectorLayer( + "%s?crs=%s" % ("Multipolygon", crs.authid()), "temp", "memory" + ) if not layer.isValid(): - raise GeoAlgorithmExecutionException('Problema ao criar camada reprojetada!') + raise GeoAlgorithmExecutionException("Problema ao criar camada reprojetada!") return None - + provider = temp.dataProvider() provider.addAttributes(layer.dataProvider().fields().toList()) temp.updateFields() - + coordinateTransformer = QgsCoordinateTransform(layer.crs(), crs) features = [] for feature in layer.getFeatures(): @@ -55,11 +66,12 @@ def createReprojectedLayer(layer, crs): geom.transform(coordinateTransformer) feat.setGeometry(geom) features.append(feat) - + provider.addFeatures(features) - + return temp + def reprojectLayer(fromLayer, toLayer): """ Reprojects all features fromLayer crs to toLayer crs @@ -74,13 +86,15 @@ def reprojectLayer(fromLayer, toLayer): ret.append(f) return ret + def populateIndex(idx, layer): """ Populates the layer index """ for feat in layer.getFeatures(): idx.addFeature(feat) - + + def getCandidates(idx, layer, bbox): """ Gets candidates to be processed using the index to speedup the process @@ -90,20 +104,22 @@ def getCandidates(idx, layer, bbox): for id in ids: candidates.append(next(layer.getFeatures(QgsFeatureRequest().setFilterFid(id)))) return candidates - + + def makeVrtDict(candidates, camada): """ Makes a VRT dictionary """ vrt = dict() for candidate in candidates: - map_index = candidate['map_index'] + map_index = candidate["map_index"] vrt[map_index] = [] for feat in camada.getFeatures(): if candidate.geometry().intersects(feat.geometry()): vrt[map_index].append(feat) - return vrt - + return vrt + + def createVrt(vrt): """ Creates a VRT file @@ -111,30 +127,33 @@ def createVrt(vrt): count = 0 size = len(list(vrt.keys())) p = 0 - progress.setPercentage(p) + progress.setPercentage(p) for key in list(vrt.keys()): - vrtfilename = os.path.join(Pasta, key, key+'.vrt') + vrtfilename = os.path.join(Pasta, key, key + ".vrt") features = vrt[key] rasterList = [] for feat in features: - filename = feat['fileName'] + filename = feat["fileName"] newfilename = copyFileSet(Pasta, key, filename) raster = QgsRasterLayer(newfilename, newfilename) rasterList.append(raster) - ovr = newfilename+'.ovr' + ovr = newfilename + ".ovr" if not os.path.isfile(ovr): - progress.setText('Fazendo Pirâmides...') - #('gdalogr:overviews', input, levels=8, clean=False, resampling_method=0(nearest), format=1(Gtiff .ovr)) - processing.runalg('gdalogr:overviews', raster, '4 8 32 128', True, 0, 1) - - if int(float(count)/size*100) != p: - p = int(float(count)/size*100) - progress.setPercentage(p) + progress.setText("Fazendo Pirâmides...") + # ('gdalogr:overviews', input, levels=8, clean=False, resampling_method=0(nearest), format=1(Gtiff .ovr)) + processing.runalg("gdalogr:overviews", raster, "4 8 32 128", True, 0, 1) + + if int(float(count) / size * 100) != p: + p = int(float(count) / size * 100) + progress.setPercentage(p) count += 1 - - progress.setText('Fazendo raster virtual...') - processing.runalg('gdalogr:buildvirtualraster', rasterList, 0, False, False, vrtfilename) - + + progress.setText("Fazendo raster virtual...") + processing.runalg( + "gdalogr:buildvirtualraster", rasterList, 0, False, False, vrtfilename + ) + + def copyFileSet(parent, folder, filename): """ Copy files to the destination folder @@ -144,57 +163,58 @@ def copyFileSet(parent, folder, filename): """ path = os.path.dirname(filename) basename = os.path.basename(filename) - texto = 'Copiando %s e arquivos relacionados...' % basename + texto = "Copiando %s e arquivos relacionados..." % basename progress.setText(texto) - + destination = os.path.join(parent, folder) if not os.path.exists(destination): os.makedirs(destination) - + for root, dirs, files in os.walk(path): for file in files: - if basename.split('.')[0] in file: + if basename.split(".")[0] in file: try: - dir = os.path.join(destination, 'imagens') + dir = os.path.join(destination, "imagens") if not os.path.exists(dir): os.makedirs(dir) f = os.path.join(root, file) - newf = os.path.join(parent, folder, 'imagens', file) + newf = os.path.join(parent, folder, "imagens", file) shutil.copy2(f, newf) except: - raise GeoAlgorithmExecutionException('Problema ao copiar arquivos!') - return os.path.join(parent, folder, 'imagens', basename) - -#end of script methods - -#Making the actual work -#Camada de inventario + raise GeoAlgorithmExecutionException("Problema ao copiar arquivos!") + return os.path.join(parent, folder, "imagens", basename) + + +# end of script methods + +# Making the actual work +# Camada de inventario inventario = processing.getObject(Inventario) -#Camada de moldura +# Camada de moldura frame = processing.getObject(Moldura) -#Indice espacial +# Indice espacial frameidx = QgsSpatialIndex() -#Populating a spatial index +# Populating a spatial index populateIndex(frameidx, frame) -#checking crs's, if different, reproject +# checking crs's, if different, reproject destCrs = frame.crs() srcCrs = inventario.crs() if srcCrs.authid() != destCrs.authid(): - progress.setText('CRS diferentes, reprojetando...') + progress.setText("CRS diferentes, reprojetando...") camada = createReprojectedLayer(inventario, frame.crs()) else: camada = inventario - -#Obtaining candidates + +# Obtaining candidates candidates = getCandidates(frameidx, frame, camada.extent()) -#making vrt dict +# making vrt dict vrt = makeVrtDict(candidates, camada) -#creating vrt files +# creating vrt files createVrt(vrt) -#ending the actual work \ No newline at end of file +# ending the actual work diff --git a/DsgTools/core/Misc/QGIS_Scripts/virtual_raster_inloco.py b/DsgTools/core/Misc/QGIS_Scripts/virtual_raster_inloco.py index e1e08d463..daa627932 100644 --- a/DsgTools/core/Misc/QGIS_Scripts/virtual_raster_inloco.py +++ b/DsgTools/core/Misc/QGIS_Scripts/virtual_raster_inloco.py @@ -28,49 +28,65 @@ import processing -from processing.core.GeoAlgorithmExecutionException import GeoAlgorithmExecutionException -from qgis.core import QgsVectorLayer, QgsRasterLayer, QgsSpatialIndex, QgsFeatureRequest, QgsCoordinateTransform, QgsFeature, QgsCoordinateReferenceSystem +from processing.core.GeoAlgorithmExecutionException import ( + GeoAlgorithmExecutionException, +) +from qgis.core import ( + QgsVectorLayer, + QgsRasterLayer, + QgsSpatialIndex, + QgsFeatureRequest, + QgsCoordinateTransform, + QgsFeature, + QgsCoordinateReferenceSystem, +) from qgis.PyQt.QtCore import QSettings import os -#script methods +# script methods def createVrt(inventario, vrt): - #Camada de inventario + # Camada de inventario layer = processing.getObject(Inventario) - + count = 0 size = layer.featureCount() p = 0 - progress.setPercentage(p) + progress.setPercentage(p) rasterList = [] for feature in layer.getFeatures(): - filename = feature['fileName'] - + filename = feature["fileName"] + raster = QgsRasterLayer(filename, filename) if Override_CRS: - raster.setCrs( QgsCoordinateReferenceSystem(int(CRS.split(':')[-1]), QgsCoordinateReferenceSystem.EpsgCrsId) ) - + raster.setCrs( + QgsCoordinateReferenceSystem( + int(CRS.split(":")[-1]), QgsCoordinateReferenceSystem.EpsgCrsId + ) + ) + rasterList.append(raster) - ovr = filename+'.ovr' + ovr = filename + ".ovr" if not os.path.isfile(ovr): - progress.setText('Fazendo Pirâmides...') - #('gdalogr:overviews', input, levels=8, clean=False, resampling_method=0(nearest), format=1(Gtiff .ovr)) - processing.runalg('gdalogr:overviews', raster, '4 8 32 128', True, 0, 1) + progress.setText("Fazendo Pirâmides...") + # ('gdalogr:overviews', input, levels=8, clean=False, resampling_method=0(nearest), format=1(Gtiff .ovr)) + processing.runalg("gdalogr:overviews", raster, "4 8 32 128", True, 0, 1) - if int(float(count)/size*100) != p: - p = int(float(count)/size*100) - progress.setPercentage(p) + if int(float(count) / size * 100) != p: + p = int(float(count) / size * 100) + progress.setPercentage(p) count += 1 - progress.setText('Fazendo raster virtual...') - processing.runalg('gdalogr:buildvirtualraster', rasterList, 0, False, False, VRT) -#end of script methods - -#Making the actual work + progress.setText("Fazendo raster virtual...") + processing.runalg("gdalogr:buildvirtualraster", rasterList, 0, False, False, VRT) + + +# end of script methods + +# Making the actual work s = QSettings() -oldValidation = s.value( "/Projections/defaultBehaviour") -s.setValue( "/Projections/defaultBehaviour", "useGlobal" ) +oldValidation = s.value("/Projections/defaultBehaviour") +s.setValue("/Projections/defaultBehaviour", "useGlobal") createVrt(Inventario, VRT) -s.setValue( "/Projections/defaultBehaviour", oldValidation ) -#ending the actual work \ No newline at end of file +s.setValue("/Projections/defaultBehaviour", oldValidation) +# ending the actual work diff --git a/DsgTools/core/Misc/QmlTools/qmlParser.py b/DsgTools/core/Misc/QmlTools/qmlParser.py index 2b9263a56..f6e63745c 100644 --- a/DsgTools/core/Misc/QmlTools/qmlParser.py +++ b/DsgTools/core/Misc/QmlTools/qmlParser.py @@ -24,6 +24,7 @@ from builtins import object from qgis.PyQt.QtXml import QDomDocument + class QmlParser(object): def __init__(self, fileName): """ @@ -40,7 +41,7 @@ def loadFileContent(self): """ Loads QML data """ - qml = open(self.fileName, 'r') + qml = open(self.fileName, "r") data = qml.read() loaded = self.qml.setContent(data) qml.close() @@ -78,9 +79,9 @@ def readEdittypeElement(self, edittypeElement): for i in range(len(values)): value = values.item(i).toElement() keyText = value.attribute("key") - #print 'key: '+keyText + # print 'key: '+keyText valueText = value.attribute("value") - #print 'value: '+valueText + # print 'value: '+valueText valueMapDict[keyText] = valueText self.domainDict[name] = valueMapDict elif type == "ValueRelation": @@ -99,7 +100,13 @@ def getDomainDict(self): self.domainDict.clear() if not self.loadFileContent(): - QMessageBox.warning(self.iface.mainWindow(), self.tr("Warning!"), self.tr("QML file not loaded properly. Enum values won't be available.")) + QMessageBox.warning( + self.iface.mainWindow(), + self.tr("Warning!"), + self.tr( + "QML file not loaded properly. Enum values won't be available." + ), + ) return self.readQGISElement() diff --git a/DsgTools/core/Misc/QmlTools/qml_creator.py b/DsgTools/core/Misc/QmlTools/qml_creator.py index 727db00ea..21d33458a 100644 --- a/DsgTools/core/Misc/QmlTools/qml_creator.py +++ b/DsgTools/core/Misc/QmlTools/qml_creator.py @@ -1,92 +1,94 @@ # -*- coding: utf-8 -*- from qgis.PyQt.QtCore import QFile, QIODevice + def generateQml(filename, attrs, codelists): xmlWriter = QXmlStreamWriter() xmlFile = QFile(filename) - if (xmlFile.open(QIODevice.WriteOnly) == False): + if xmlFile.open(QIODevice.WriteOnly) == False: QMessageBox.warning(0, "Error!", "Error opening file") - else : + else: xmlWriter.setDevice(xmlFile) - #starting xml file + # starting xml file xmlWriter.writeStartDocument() - #starting QGIS element + # starting QGIS element xmlWriter.writeStartElement("qgis") - xmlWriter.writeAttribute("version","2.6.0-Brighton") - xmlWriter.writeAttribute("minimumScale","1") - xmlWriter.writeAttribute("maximumScale","1") - xmlWriter.writeAttribute("simplifyDrawingHints","0") - xmlWriter.writeAttribute("minLabelScale","0") - xmlWriter.writeAttribute("maxLabelScale","1e+08") - xmlWriter.writeAttribute("simplifyDrawingTol","1") - xmlWriter.writeAttribute("simplifyMaxScale","1") - xmlWriter.writeAttribute("hasScaleBasedVisibilityFlag","0") - xmlWriter.writeAttribute("simplifyLocal","1") - xmlWriter.writeAttribute("scaleBasedLabelVisibilityFlag","0") - - #starting edittypes element + xmlWriter.writeAttribute("version", "2.6.0-Brighton") + xmlWriter.writeAttribute("minimumScale", "1") + xmlWriter.writeAttribute("maximumScale", "1") + xmlWriter.writeAttribute("simplifyDrawingHints", "0") + xmlWriter.writeAttribute("minLabelScale", "0") + xmlWriter.writeAttribute("maxLabelScale", "1e+08") + xmlWriter.writeAttribute("simplifyDrawingTol", "1") + xmlWriter.writeAttribute("simplifyMaxScale", "1") + xmlWriter.writeAttribute("hasScaleBasedVisibilityFlag", "0") + xmlWriter.writeAttribute("simplifyLocal", "1") + xmlWriter.writeAttribute("scaleBasedLabelVisibilityFlag", "0") + + # starting edittypes element xmlWriter.writeStartElement("edittypes") - #satrting edittype elements + # satrting edittype elements for attr in attrs: - #starting edittype + # starting edittype xmlWriter.writeStartElement("edittype") - xmlWriter.writeAttribute("widgetv2type","TextEdit") - xmlWriter.writeAttribute("name",attr) + xmlWriter.writeAttribute("widgetv2type", "TextEdit") + xmlWriter.writeAttribute("name", attr) - #starting widgetv2config + # starting widgetv2config xmlWriter.writeStartElement("widgetv2config") - xmlWriter.writeAttribute("IsMultiline","0") - xmlWriter.writeAttribute("fieldEditable","0") - xmlWriter.writeAttribute("UseHtml","0") - xmlWriter.writeAttribute("labelOnTop","0") - #closing widgetv2config + xmlWriter.writeAttribute("IsMultiline", "0") + xmlWriter.writeAttribute("fieldEditable", "0") + xmlWriter.writeAttribute("UseHtml", "0") + xmlWriter.writeAttribute("labelOnTop", "0") + # closing widgetv2config xmlWriter.writeEndElement() - #closing edittype + # closing edittype xmlWriter.writeEndElement() for key in list(codelists.keys()): - #starting edittype + # starting edittype xmlWriter.writeStartElement("edittype") - xmlWriter.writeAttribute("widgetv2type","ValueMap") - xmlWriter.writeAttribute("name",key) + xmlWriter.writeAttribute("widgetv2type", "ValueMap") + xmlWriter.writeAttribute("name", key) - #starting widgetv2config + # starting widgetv2config xmlWriter.writeStartElement("widgetv2config") - xmlWriter.writeAttribute("fieldEditable","1") - xmlWriter.writeAttribute("labelOnTop","0") + xmlWriter.writeAttribute("fieldEditable", "1") + xmlWriter.writeAttribute("labelOnTop", "0") - #Writing pair key-value + # Writing pair key-value codelist = codelists[key] for codeValue in list(codelist.keys()): code = codelist[codeValue] - #starting value + # starting value xmlWriter.writeStartElement("value") - xmlWriter.writeAttribute("key",codeValue) - xmlWriter.writeAttribute("value",code) - #closing value + xmlWriter.writeAttribute("key", codeValue) + xmlWriter.writeAttribute("value", code) + # closing value xmlWriter.writeEndElement() - #closing widgetv2config + # closing widgetv2config xmlWriter.writeEndElement() - #closing edittype + # closing edittype xmlWriter.writeEndElement() - #closing edittypes + # closing edittypes xmlWriter.writeEndElement() - #closing QGIS + # closing QGIS xmlWriter.writeEndElement() - #closing xml file + # closing xml file xmlWriter.writeEndDocument() -if __name__ == '__main__': + +if __name__ == "__main__": attrs = list() attrs.append("a") attrs.append("b") @@ -101,12 +103,14 @@ def generateQml(filename, attrs, codelists): codelists["d"] = codelist generateQml("teste.qml", attrs, codelists) - + qml = open("teste.qml", "r") fileData = qml.read() - qml.close() - newData = fileData.replace("", "") + qml.close() + newData = fileData.replace( + '', + "", + ) qml = open("teste.qml", "w") qml.write(newData) qml.close() - diff --git a/DsgTools/core/NetworkTools/BDGExRequestHandler.py b/DsgTools/core/NetworkTools/BDGExRequestHandler.py index 5dcaa9603..63b227d8f 100644 --- a/DsgTools/core/NetworkTools/BDGExRequestHandler.py +++ b/DsgTools/core/NetworkTools/BDGExRequestHandler.py @@ -25,6 +25,7 @@ """ from future import standard_library + standard_library.install_aliases() import urllib.request, urllib.error, urllib.parse from xml.dom.minidom import parseString, Element @@ -35,44 +36,45 @@ from DsgTools.core.Utils.utils import MessageRaiser + class BDGExRequestHandler(QObject): - def __init__(self,parent=None): + def __init__(self, parent=None): """ Constructor """ super(BDGExRequestHandler, self).__init__() self.availableServicesDict = { - 'mapcache' : { - 'url' : 'https://bdgex.eb.mil.br/mapcache', - 'services' : { - 'WMS' : dict() - } + "mapcache": { + "url": "http://bdgex.eb.mil.br/mapcache", + "services": {"WMS": dict()}, }, - 'mapindex' : { - 'url' : 'https://bdgex.eb.mil.br/cgi-bin/mapaindice', - 'services': { - 'WMS' : dict(), - 'WFS' : dict() - } + "mapindex": { + "url": "http://bdgex.eb.mil.br/cgi-bin/mapaindice", + "services": {"WMS": dict(), "WFS": dict()}, + }, + "auxlayers": { + "url": "http://bdgex.eb.mil.br/cgi-bin/geoportal", + "services": {"WMS": dict(), "WFS": dict()}, }, - 'auxlayers' : { - 'url' : 'https://bdgex.eb.mil.br/cgi-bin/geoportal', - 'services' : { - 'WMS' : dict(), - 'WFS' : dict() - } - } } def __del__(self): pass - + def setUrllibProxy(self, url): """ Sets the proxy """ - (enabled, host, port, user, password, type, urlsList) = self.getProxyConfiguration() - if enabled == 'false' or type != 'HttpProxy': + ( + enabled, + host, + port, + user, + password, + type, + urlsList, + ) = self.getProxyConfiguration() + if enabled == "false" or type != "HttpProxy": return for address in urlsList: if address in url: @@ -80,13 +82,8 @@ def setUrllibProxy(self, url): opener = urllib.request.build_opener(proxy, urllib.request.HTTPHandler) urllib.request.install_opener(opener) return - proxyStr = 'http://'+user+':'+password+'@'+host+':'+port - proxy = urllib.request.ProxyHandler( - { - 'http': proxyStr, - 'https': proxyStr - } - ) + proxyStr = "http://" + user + ":" + password + "@" + host + ":" + port + proxy = urllib.request.ProxyHandler({"http": proxyStr, "https": proxyStr}) opener = urllib.request.build_opener(proxy, urllib.request.HTTPHandler) urllib.request.install_opener(opener) @@ -95,18 +92,18 @@ def getProxyConfiguration(self): Gets the proxy configuration from QSettings """ settings = QSettings() - settings.beginGroup('proxy') - enabled = settings.value('proxyEnabled') - host = settings.value('proxyHost') - port = settings.value('proxyPort') - user = settings.value('proxyUser') - password = settings.value('proxyPassword') - type = settings.value('proxyType') + settings.beginGroup("proxy") + enabled = settings.value("proxyEnabled") + host = settings.value("proxyHost") + port = settings.value("proxyPort") + user = settings.value("proxyUser") + password = settings.value("proxyPassword") + type = settings.value("proxyType") excludedUrls = list() - if settings.value('proxyExcludedUrls'): - excludedUrls = settings.value('proxyExcludedUrls') - if settings.value('noProxyUrls'): - excludedUrls += settings.value('noProxyUrls') + if settings.value("proxyExcludedUrls"): + excludedUrls = settings.value("proxyExcludedUrls") + if settings.value("noProxyUrls"): + excludedUrls += settings.value("noProxyUrls") # try: # urlsList = excludedUrls.split('|') # except: @@ -119,41 +116,40 @@ def get_url_string(self, service, layerList, serviceType): Returns QGIS url service string. """ if service not in self.availableServicesDict: - raise Exception('Service {service} not available'.format(service=service)) - if serviceType not in self.availableServicesDict[service]['services']: + raise Exception("Service {service} not available".format(service=service)) + if serviceType not in self.availableServicesDict[service]["services"]: raise Exception( - 'Invalid request {service_type} for service {service}'.format( - service=service, - service_type=serviceType - ) + "Invalid request {service_type} for service {service}".format( + service=service, service_type=serviceType ) - url = self.availableServicesDict[service]['url'] - if not self.availableServicesDict[service]['services'][serviceType]: - self.availableServicesDict[service]['services'][serviceType] = self.getCapabilitiesDict(service, url, service_type=serviceType) - layers = self.availableServicesDict[service]['services'][serviceType] + ) + url = self.availableServicesDict[service]["url"] + if not self.availableServicesDict[service]["services"][serviceType]: + self.availableServicesDict[service]["services"][ + serviceType + ] = self.getCapabilitiesDict(service, url, service_type=serviceType) + layers = self.availableServicesDict[service]["services"][serviceType] if layers is not None: - layer = layers.get(layerList[0], None) \ - or layers.get("ms:{0}".format(layerList[0]), None) + layer = layers.get(layerList[0], None) or layers.get( + "ms:{0}".format(layerList[0]), None + ) if layer: - return self.getRequestString( - layerList, - url, - layer, - serviceType - ) + return self.getRequestString(layerList, url, layer, serviceType) def getCapabilitiesDict(self, service, url, service_type=None): - service_type = service_type or 'WMS' - capabilities_url = "{url}?service={service_type}&request=GetCapabilities".format( - url=self.availableServicesDict[service]['url'], - service_type=service_type + service_type = service_type or "WMS" + capabilities_url = ( + "{url}?service={service_type}&request=GetCapabilities".format( + url=self.availableServicesDict[service]["url"], + service_type=service_type, + ) ) myDom = self.requestGetCapabilitiesXML(capabilities_url) if not myDom: return {} - if service_type == 'WMS': + if service_type == "WMS": return self.parseCapabilitiesXML(myDom) - elif service_type == 'WFS': + elif service_type == "WFS": return self.parse_wfs_capabilities(myDom) else: return {} @@ -163,23 +159,25 @@ def requestGetCapabilitiesXML(self, url): Gets url capabilities """ self.setUrllibProxy(url) - getCapa = urllib.request.Request(url, headers={'User-Agent' : "Magic Browser"}) + getCapa = urllib.request.Request(url, headers={"User-Agent": "Magic Browser"}) try: resp = urllib.request.urlopen(getCapa) except Exception as e: title = self.tr("BDGEx layers (DSGTools)") - msg = self.tr("Unable to provide requested layer. Please check " - "your network settings (proxy and exceptions too, if" - " necessary).") + msg = self.tr( + "Unable to provide requested layer. Please check " + "your network settings (proxy and exceptions too, if" + " necessary)." + ) MessageRaiser().raiseIfaceMessage(title, msg, Qgis.Warning, 5) return "" response = resp.read() try: myDom = parseString(response) except: - raise Exception('Parse Error') + raise Exception("Parse Error") return myDom - + def parseCapabilitiesXML(self, capabilitiesDom): """ Parses GetCapabilities to get info. @@ -202,62 +200,61 @@ def parseCapabilitiesXML(self, capabilitiesDom): tagName = tag.tagName if tag.childNodes: newItem[tagName] = tag.childNodes[0].nodeValue - jsonDict[newItem['Name']] = newItem - #parse to add format to jsonDict + jsonDict[newItem["Name"]] = newItem + # parse to add format to jsonDict for tile in capabilitiesDom.getElementsByTagName("TileSet"): - itemName = tile.getElementsByTagName('Layers')[0].childNodes[0].nodeValue - imgFormat = tile.getElementsByTagName('Format')[0].childNodes[0].nodeValue - jsonDict[itemName]['Format'] = imgFormat + itemName = tile.getElementsByTagName("Layers")[0].childNodes[0].nodeValue + imgFormat = tile.getElementsByTagName("Format")[0].childNodes[0].nodeValue + jsonDict[itemName]["Format"] = imgFormat for key, dictItem in jsonDict.items(): - if 'Format' not in dictItem: - jsonDict[key]['Format'] = 'image/png' - if 'SRS' not in dictItem: - jsonDict[key]['SRS'] = 'EPSG:4326' + if "Format" not in dictItem: + jsonDict[key]["Format"] = "image/png" + if "SRS" not in dictItem: + jsonDict[key]["SRS"] = "EPSG:4326" return jsonDict - + def parse_wfs_capabilities(self, capabilitiesDom): jsonDict = dict() - for node in capabilitiesDom.getElementsByTagName('FeatureType'): + for node in capabilitiesDom.getElementsByTagName("FeatureType"): newItem = dict() - name = node.getElementsByTagName('Name')[0].childNodes[0].nodeValue - crsNode = node.getElementsByTagName('DefaultSRS') or node.getElementsByTagName('DefaultCRS') + name = node.getElementsByTagName("Name")[0].childNodes[0].nodeValue + crsNode = node.getElementsByTagName( + "DefaultSRS" + ) or node.getElementsByTagName("DefaultCRS") epsg = crsNode[0].childNodes[0].nodeValue newItem = { - 'Name' : name, - 'SRS' : 'EPSG:{code}'.format(code=epsg.split('::')[-1]) + "Name": name, + "SRS": "EPSG:{code}".format(code=epsg.split("::")[-1]), } jsonDict[name] = newItem return jsonDict - def getRequestString(self, layerList, url, infoDict, serviceType): """ Makes the requisition to the tile cache service """ if layerList == []: - raise Exception('Invalid name request') + raise Exception("Invalid name request") elif len(layerList) > 1: # ctmList = [i for i in capabilitiesDict.keys() if 'ctm' in i] # ctmList.sort(key = lambda x : int(x.replace('ctm',''))) - layer_tag = 'layers='+'&layers='.join(layerList) - styles_tag = '&'.join(['styles']*len(layerList)) + layer_tag = "layers=" + "&layers=".join(layerList) + styles_tag = "&".join(["styles"] * len(layerList)) else: - layer_tag = 'layers={layer_name}'.format(layer_name=layerList[0]) - styles_tag = 'styles' - if serviceType == 'WMS': + layer_tag = "layers={layer_name}".format(layer_name=layerList[0]) + styles_tag = "styles" + if serviceType == "WMS": requestString = "crs={epsg}&dpiMode=7&featureCount=10&format={img_format}&{layer_tag}&{styles_tag}&url={url}".format( - epsg=infoDict['SRS'], - img_format=infoDict['Format'], + epsg=infoDict["SRS"], + img_format=infoDict["Format"], layer_tag=layer_tag, styles_tag=styles_tag, - url=url + url=url, ) - elif serviceType == 'WFS': + elif serviceType == "WFS": requestString = """pagingEnabled='true' restrictToRequestBBOX='1' srsname='{epsg}' typename='{layer_name}' url='{url}' version='auto' table="" sql=""".format( - epsg=infoDict['SRS'], - layer_name=infoDict['Name'], - url=url + epsg=infoDict["SRS"], layer_name=infoDict["Name"], url=url ) else: - requestString == '' - return requestString \ No newline at end of file + requestString == "" + return requestString diff --git a/DsgTools/core/NetworkTools/ExternalFilesHandler.py b/DsgTools/core/NetworkTools/ExternalFilesHandler.py index d6badc9e5..6c1ef28bb 100644 --- a/DsgTools/core/NetworkTools/ExternalFilesHandler.py +++ b/DsgTools/core/NetworkTools/ExternalFilesHandler.py @@ -31,54 +31,68 @@ import processing + @dataclass class ExternalFileHandlerConfig(ABC): url: str = MISSING file_name: str = MISSING output_folder: str = MISSING + class ExternalFileDownloadProcessor(QObject): - def __init__(self, parent=None): super(ExternalFileDownloadProcessor, self).__init__() self.parent = parent - + def getFullPath(self, config: ExternalFileHandlerConfig): return os.path.join(config.output_folder, config.file_name) - + def isFileDownloaded(self, config: ExternalFileHandlerConfig) -> bool: """ Checks if the file is already downloaded. """ return os.path.isfile(self.getFullPath(config)) - def promptForDownload(self, externalFileConfigList: List[ExternalFileHandlerConfig]) -> bool: + def promptForDownload( + self, externalFileConfigList: List[ExternalFileHandlerConfig] + ) -> bool: """ Prompts the user to download the file if it is not already downloaded. """ - fileName ='' + fileName = "" for file in externalFileConfigList: - if len(fileName)>100: - fileName = fileName + ' and others' - if fileName=='': - fileName=file.file_name + if len(fileName) > 100: + fileName = fileName + " and others" + if fileName == "": + fileName = file.file_name else: - fileName = fileName + ', ' + file.file_name + fileName = fileName + ", " + file.file_name reply = QMessageBox.question( self.parent, - self.tr('Download Files'), - self.tr('The following files: {} are not downloaded. Do you want to download them?'.format(fileName)), - QMessageBox.Yes | QMessageBox.No, QMessageBox.No + self.tr("Download Files"), + self.tr( + "The following files: {} are not downloaded. Do you want to download them?".format( + fileName + ) + ), + QMessageBox.Yes | QMessageBox.No, + QMessageBox.No, ) if reply == QMessageBox.No: - return False + return False return True - def process(self, fileConfigList: List[ExternalFileHandlerConfig], prompt=True) -> int: + def process( + self, fileConfigList: List[ExternalFileHandlerConfig], prompt=True + ) -> int: """ Processes the list of files. """ - downloadList = [i for i in fileConfigList if not self.isFileDownloaded(i)] if prompt else fileConfigList + downloadList = ( + [i for i in fileConfigList if not self.isFileDownloaded(i)] + if prompt + else fileConfigList + ) if len(downloadList) == 0: return 1 reply = self.promptForDownload(fileConfigList) @@ -93,15 +107,15 @@ def process(self, fileConfigList: List[ExternalFileHandlerConfig], prompt=True) processing.run( "native:filedownloader", { - 'URL': fileConfig.url, - 'OUTPUT': self.getFullPath(fileConfig), - } + "URL": fileConfig.url, + "OUTPUT": self.getFullPath(fileConfig), + }, ) except Exception as e: QMessageBox.critical( self.parent, - self.tr('Error'), - self.tr('Could not download the following files: {}'.format(e)) + self.tr("Error"), + self.tr("Could not download the following files: {}".format(e)), ) QApplication.restoreOverrideCursor() return 2 diff --git a/DsgTools/core/Qmls/qgis_26/edgv_3_pro/__init__.py b/DsgTools/core/Qmls/qgis_26/edgv_3_pro/__init__.py index 0519ecba6..e69de29bb 100644 --- a/DsgTools/core/Qmls/qgis_26/edgv_3_pro/__init__.py +++ b/DsgTools/core/Qmls/qgis_26/edgv_3_pro/__init__.py @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/DsgTools/core/Qmls/qgis_37/edgv_213_pro/aquisicao_limite_vegetacao_l.qml b/DsgTools/core/Qmls/qgis_37/edgv_213_pro/aquisicao_limite_vegetacao_l.qml index 40c468ac1..b870defda 100644 --- a/DsgTools/core/Qmls/qgis_37/edgv_213_pro/aquisicao_limite_vegetacao_l.qml +++ b/DsgTools/core/Qmls/qgis_37/edgv_213_pro/aquisicao_limite_vegetacao_l.qml @@ -240,12 +240,12 @@ global a class ValidateForm: def __init__(self, layer, formValues, logBrowser): - self.layer = layer + self.layer = layer self.formValues = formValues self.rules = [] self.logBrowser = logBrowser self.validateForm() - + def calculateExpression(self, exp): for field in self.formValues: if field != 'filter': @@ -257,7 +257,7 @@ class ValidateForm: exp = exp.replace("'NULL'".format(field), "NULL") r = QgsExpression(exp) return r.evaluate() - + def validateForm(self): self.cleanRulesOnForm() logText = "" @@ -288,7 +288,7 @@ class ValidateForm: def cleanRulesOnForm(self): for field in self.formValues: if len(self.formValues[field]) == 3: - self.formValues[field][2].setStyleSheet("") + self.formValues[field][2].setStyleSheet("") else: self.formValues[field][1].setStyleSheet("") @@ -320,12 +320,12 @@ class ManagerForm(QtCore.QObject): self.logFrame.show() else: self.logFrame.hide() - + def eventFilter(self, o, event): if event.type() in [7, 10, 11, 100]: self.validateLayerByRules() return False - + def validateLayerByRules(self): formValues = {} for cb in self.myDialog.findChildren(QComboBox): @@ -341,7 +341,7 @@ class ManagerForm(QtCore.QObject): le ] self.validadeForm = ValidateForm(self.lyr, formValues, self.logBrowser) - + def finishedForm(self): pass diff --git a/DsgTools/core/Qmls/qgis_37/edgv_213_pro/cobter_corpo_dagua_a.qml b/DsgTools/core/Qmls/qgis_37/edgv_213_pro/cobter_corpo_dagua_a.qml index cfd145834..470bb6035 100644 --- a/DsgTools/core/Qmls/qgis_37/edgv_213_pro/cobter_corpo_dagua_a.qml +++ b/DsgTools/core/Qmls/qgis_37/edgv_213_pro/cobter_corpo_dagua_a.qml @@ -327,12 +327,12 @@ global a class ValidateForm: def __init__(self, layer, formValues, logBrowser): - self.layer = layer + self.layer = layer self.formValues = formValues self.rules = [] self.logBrowser = logBrowser self.validateForm() - + def calculateExpression(self, exp): for field in self.formValues: if field != 'filter': @@ -344,7 +344,7 @@ class ValidateForm: exp = exp.replace("'NULL'".format(field), "NULL") r = QgsExpression(exp) return r.evaluate() - + def validateForm(self): self.cleanRulesOnForm() logText = "" @@ -375,7 +375,7 @@ class ValidateForm: def cleanRulesOnForm(self): for field in self.formValues: if len(self.formValues[field]) == 3: - self.formValues[field][2].setStyleSheet("") + self.formValues[field][2].setStyleSheet("") else: self.formValues[field][1].setStyleSheet("") @@ -407,12 +407,12 @@ class ManagerForm(QtCore.QObject): self.logFrame.show() else: self.logFrame.hide() - + def eventFilter(self, o, event): if event.type() in [7, 10, 11, 100]: self.validateLayerByRules() return False - + def validateLayerByRules(self): formValues = {} for cb in self.myDialog.findChildren(QComboBox): @@ -428,7 +428,7 @@ class ManagerForm(QtCore.QObject): le ] self.validadeForm = ValidateForm(self.lyr, formValues, self.logBrowser) - + def finishedForm(self): pass diff --git a/DsgTools/core/Qmls/qgis_37/edgv_213_pro/infra_via_deslocamento_l.qml b/DsgTools/core/Qmls/qgis_37/edgv_213_pro/infra_via_deslocamento_l.qml index 3c8e8be2b..904412c0e 100644 --- a/DsgTools/core/Qmls/qgis_37/edgv_213_pro/infra_via_deslocamento_l.qml +++ b/DsgTools/core/Qmls/qgis_37/edgv_213_pro/infra_via_deslocamento_l.qml @@ -1784,12 +1784,12 @@ global a class ValidateForm: def __init__(self, layer, formValues, logBrowser): - self.layer = layer + self.layer = layer self.formValues = formValues self.rules = [] self.logBrowser = logBrowser self.validateForm() - + def calculateExpression(self, exp): for field in self.formValues: if field != 'filter': @@ -1801,7 +1801,7 @@ class ValidateForm: exp = exp.replace("'NULL'".format(field), "NULL") r = QgsExpression(exp) return r.evaluate() - + def validateForm(self): self.cleanRulesOnForm() logText = "" @@ -1832,7 +1832,7 @@ class ValidateForm: def cleanRulesOnForm(self): for field in self.formValues: if len(self.formValues[field]) == 3: - self.formValues[field][2].setStyleSheet("") + self.formValues[field][2].setStyleSheet("") else: self.formValues[field][1].setStyleSheet("") @@ -1864,12 +1864,12 @@ class ManagerForm(QtCore.QObject): self.logFrame.show() else: self.logFrame.hide() - + def eventFilter(self, o, event): if event.type() in [7, 10, 11, 100]: self.validateLayerByRules() return False - + def validateLayerByRules(self): formValues = {} for cb in self.myDialog.findChildren(QComboBox): @@ -1885,7 +1885,7 @@ class ManagerForm(QtCore.QObject): le ] self.validadeForm = ValidateForm(self.lyr, formValues, self.logBrowser) - + def finishedForm(self): pass diff --git a/DsgTools/core/Qmls/qgis_37/edgv_213_pro/llp_delimitacao_fisica_l.qml b/DsgTools/core/Qmls/qgis_37/edgv_213_pro/llp_delimitacao_fisica_l.qml index 8d43a1de5..18f571220 100644 --- a/DsgTools/core/Qmls/qgis_37/edgv_213_pro/llp_delimitacao_fisica_l.qml +++ b/DsgTools/core/Qmls/qgis_37/edgv_213_pro/llp_delimitacao_fisica_l.qml @@ -280,12 +280,12 @@ global a class ValidateForm: def __init__(self, layer, formValues, logBrowser): - self.layer = layer + self.layer = layer self.formValues = formValues self.rules = [] self.logBrowser = logBrowser self.validateForm() - + def calculateExpression(self, exp): for field in self.formValues: if field != 'filter': @@ -297,7 +297,7 @@ class ValidateForm: exp = exp.replace("'NULL'".format(field), "NULL") r = QgsExpression(exp) return r.evaluate() - + def validateForm(self): self.cleanRulesOnForm() logText = "" @@ -328,7 +328,7 @@ class ValidateForm: def cleanRulesOnForm(self): for field in self.formValues: if len(self.formValues[field]) == 3: - self.formValues[field][2].setStyleSheet("") + self.formValues[field][2].setStyleSheet("") else: self.formValues[field][1].setStyleSheet("") @@ -360,12 +360,12 @@ class ManagerForm(QtCore.QObject): self.logFrame.show() else: self.logFrame.hide() - + def eventFilter(self, o, event): if event.type() in [7, 10, 11, 100]: self.validateLayerByRules() return False - + def validateLayerByRules(self): formValues = {} for cb in self.myDialog.findChildren(QComboBox): @@ -381,7 +381,7 @@ class ManagerForm(QtCore.QObject): le ] self.validadeForm = ValidateForm(self.lyr, formValues, self.logBrowser) - + def finishedForm(self): pass diff --git a/DsgTools/core/Qmls/qgis_37/edgv_213_pro/rev_hidrografia_p.qml b/DsgTools/core/Qmls/qgis_37/edgv_213_pro/rev_hidrografia_p.qml index aab7fe9a9..a243c3bb8 100644 --- a/DsgTools/core/Qmls/qgis_37/edgv_213_pro/rev_hidrografia_p.qml +++ b/DsgTools/core/Qmls/qgis_37/edgv_213_pro/rev_hidrografia_p.qml @@ -471,12 +471,12 @@ global a class ValidateForm: def __init__(self, layer, formValues, logBrowser): - self.layer = layer + self.layer = layer self.formValues = formValues self.rules = [] self.logBrowser = logBrowser self.validateForm() - + def calculateExpression(self, exp): for field in self.formValues: if field != 'filter': @@ -488,7 +488,7 @@ class ValidateForm: exp = exp.replace("'NULL'".format(field), "NULL") r = QgsExpression(exp) return r.evaluate() - + def validateForm(self): self.cleanRulesOnForm() logText = "" @@ -519,7 +519,7 @@ class ValidateForm: def cleanRulesOnForm(self): for field in self.formValues: if len(self.formValues[field]) == 3: - self.formValues[field][2].setStyleSheet("") + self.formValues[field][2].setStyleSheet("") else: self.formValues[field][1].setStyleSheet("") @@ -551,12 +551,12 @@ class ManagerForm(QtCore.QObject): self.logFrame.show() else: self.logFrame.hide() - + def eventFilter(self, o, event): if event.type() in [7, 10, 11, 100]: self.validateLayerByRules() return False - + def validateLayerByRules(self): formValues = {} for cb in self.myDialog.findChildren(QComboBox): @@ -572,7 +572,7 @@ class ManagerForm(QtCore.QObject): le ] self.validadeForm = ValidateForm(self.lyr, formValues, self.logBrowser) - + def finishedForm(self): pass diff --git a/DsgTools/core/Qmls/qgis_37/edgv_213_pro/rev_vegetacao_p.qml b/DsgTools/core/Qmls/qgis_37/edgv_213_pro/rev_vegetacao_p.qml index df4d4b088..7514a1a3b 100644 --- a/DsgTools/core/Qmls/qgis_37/edgv_213_pro/rev_vegetacao_p.qml +++ b/DsgTools/core/Qmls/qgis_37/edgv_213_pro/rev_vegetacao_p.qml @@ -471,12 +471,12 @@ global a class ValidateForm: def __init__(self, layer, formValues, logBrowser): - self.layer = layer + self.layer = layer self.formValues = formValues self.rules = [] self.logBrowser = logBrowser self.validateForm() - + def calculateExpression(self, exp): for field in self.formValues: if field != 'filter': @@ -488,7 +488,7 @@ class ValidateForm: exp = exp.replace("'NULL'".format(field), "NULL") r = QgsExpression(exp) return r.evaluate() - + def validateForm(self): self.cleanRulesOnForm() logText = "" @@ -519,7 +519,7 @@ class ValidateForm: def cleanRulesOnForm(self): for field in self.formValues: if len(self.formValues[field]) == 3: - self.formValues[field][2].setStyleSheet("") + self.formValues[field][2].setStyleSheet("") else: self.formValues[field][1].setStyleSheet("") @@ -551,12 +551,12 @@ class ManagerForm(QtCore.QObject): self.logFrame.show() else: self.logFrame.hide() - + def eventFilter(self, o, event): if event.type() in [7, 10, 11, 100]: self.validateLayerByRules() return False - + def validateLayerByRules(self): formValues = {} for cb in self.myDialog.findChildren(QComboBox): @@ -572,7 +572,7 @@ class ManagerForm(QtCore.QObject): le ] self.validadeForm = ValidateForm(self.lyr, formValues, self.logBrowser) - + def finishedForm(self): pass diff --git a/DsgTools/core/Qmls/qgis_37/edgv_213_pro/val_transportes_a.qml b/DsgTools/core/Qmls/qgis_37/edgv_213_pro/val_transportes_a.qml index 0db0a28c4..ed9423cc9 100644 --- a/DsgTools/core/Qmls/qgis_37/edgv_213_pro/val_transportes_a.qml +++ b/DsgTools/core/Qmls/qgis_37/edgv_213_pro/val_transportes_a.qml @@ -282,12 +282,12 @@ global a class ValidateForm: def __init__(self, layer, formValues, logBrowser): - self.layer = layer + self.layer = layer self.formValues = formValues self.rules = [] self.logBrowser = logBrowser self.validateForm() - + def calculateExpression(self, exp): for field in self.formValues: if field != 'filter': @@ -299,7 +299,7 @@ class ValidateForm: exp = exp.replace("'NULL'".format(field), "NULL") r = QgsExpression(exp) return r.evaluate() - + def validateForm(self): self.cleanRulesOnForm() logText = "" @@ -330,7 +330,7 @@ class ValidateForm: def cleanRulesOnForm(self): for field in self.formValues: if len(self.formValues[field]) == 3: - self.formValues[field][2].setStyleSheet("") + self.formValues[field][2].setStyleSheet("") else: self.formValues[field][1].setStyleSheet("") @@ -362,12 +362,12 @@ class ManagerForm(QtCore.QObject): self.logFrame.show() else: self.logFrame.hide() - + def eventFilter(self, o, event): if event.type() in [7, 10, 11, 100]: self.validateLayerByRules() return False - + def validateLayerByRules(self): formValues = {} for cb in self.myDialog.findChildren(QComboBox): @@ -383,7 +383,7 @@ class ManagerForm(QtCore.QObject): le ] self.validadeForm = ValidateForm(self.lyr, formValues, self.logBrowser) - + def finishedForm(self): pass diff --git a/DsgTools/core/Qmls/qgis_37/edgv_3_pro/__init__.py b/DsgTools/core/Qmls/qgis_37/edgv_3_pro/__init__.py index 0519ecba6..e69de29bb 100644 --- a/DsgTools/core/Qmls/qgis_37/edgv_3_pro/__init__.py +++ b/DsgTools/core/Qmls/qgis_37/edgv_3_pro/__init__.py @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/DsgTools/core/Qmls/qgis_37_impl_2/edgv_213_pro/aquisicao_limite_vegetacao_l.qml b/DsgTools/core/Qmls/qgis_37_impl_2/edgv_213_pro/aquisicao_limite_vegetacao_l.qml index 40c468ac1..b870defda 100644 --- a/DsgTools/core/Qmls/qgis_37_impl_2/edgv_213_pro/aquisicao_limite_vegetacao_l.qml +++ b/DsgTools/core/Qmls/qgis_37_impl_2/edgv_213_pro/aquisicao_limite_vegetacao_l.qml @@ -240,12 +240,12 @@ global a class ValidateForm: def __init__(self, layer, formValues, logBrowser): - self.layer = layer + self.layer = layer self.formValues = formValues self.rules = [] self.logBrowser = logBrowser self.validateForm() - + def calculateExpression(self, exp): for field in self.formValues: if field != 'filter': @@ -257,7 +257,7 @@ class ValidateForm: exp = exp.replace("'NULL'".format(field), "NULL") r = QgsExpression(exp) return r.evaluate() - + def validateForm(self): self.cleanRulesOnForm() logText = "" @@ -288,7 +288,7 @@ class ValidateForm: def cleanRulesOnForm(self): for field in self.formValues: if len(self.formValues[field]) == 3: - self.formValues[field][2].setStyleSheet("") + self.formValues[field][2].setStyleSheet("") else: self.formValues[field][1].setStyleSheet("") @@ -320,12 +320,12 @@ class ManagerForm(QtCore.QObject): self.logFrame.show() else: self.logFrame.hide() - + def eventFilter(self, o, event): if event.type() in [7, 10, 11, 100]: self.validateLayerByRules() return False - + def validateLayerByRules(self): formValues = {} for cb in self.myDialog.findChildren(QComboBox): @@ -341,7 +341,7 @@ class ManagerForm(QtCore.QObject): le ] self.validadeForm = ValidateForm(self.lyr, formValues, self.logBrowser) - + def finishedForm(self): pass diff --git a/DsgTools/core/Qmls/qgis_37_impl_2/edgv_213_pro/cobter_corpo_dagua_a.qml b/DsgTools/core/Qmls/qgis_37_impl_2/edgv_213_pro/cobter_corpo_dagua_a.qml index cfd145834..470bb6035 100644 --- a/DsgTools/core/Qmls/qgis_37_impl_2/edgv_213_pro/cobter_corpo_dagua_a.qml +++ b/DsgTools/core/Qmls/qgis_37_impl_2/edgv_213_pro/cobter_corpo_dagua_a.qml @@ -327,12 +327,12 @@ global a class ValidateForm: def __init__(self, layer, formValues, logBrowser): - self.layer = layer + self.layer = layer self.formValues = formValues self.rules = [] self.logBrowser = logBrowser self.validateForm() - + def calculateExpression(self, exp): for field in self.formValues: if field != 'filter': @@ -344,7 +344,7 @@ class ValidateForm: exp = exp.replace("'NULL'".format(field), "NULL") r = QgsExpression(exp) return r.evaluate() - + def validateForm(self): self.cleanRulesOnForm() logText = "" @@ -375,7 +375,7 @@ class ValidateForm: def cleanRulesOnForm(self): for field in self.formValues: if len(self.formValues[field]) == 3: - self.formValues[field][2].setStyleSheet("") + self.formValues[field][2].setStyleSheet("") else: self.formValues[field][1].setStyleSheet("") @@ -407,12 +407,12 @@ class ManagerForm(QtCore.QObject): self.logFrame.show() else: self.logFrame.hide() - + def eventFilter(self, o, event): if event.type() in [7, 10, 11, 100]: self.validateLayerByRules() return False - + def validateLayerByRules(self): formValues = {} for cb in self.myDialog.findChildren(QComboBox): @@ -428,7 +428,7 @@ class ManagerForm(QtCore.QObject): le ] self.validadeForm = ValidateForm(self.lyr, formValues, self.logBrowser) - + def finishedForm(self): pass diff --git a/DsgTools/core/Qmls/qgis_37_impl_2/edgv_213_pro/infra_via_deslocamento_l.qml b/DsgTools/core/Qmls/qgis_37_impl_2/edgv_213_pro/infra_via_deslocamento_l.qml index 3c8e8be2b..904412c0e 100644 --- a/DsgTools/core/Qmls/qgis_37_impl_2/edgv_213_pro/infra_via_deslocamento_l.qml +++ b/DsgTools/core/Qmls/qgis_37_impl_2/edgv_213_pro/infra_via_deslocamento_l.qml @@ -1784,12 +1784,12 @@ global a class ValidateForm: def __init__(self, layer, formValues, logBrowser): - self.layer = layer + self.layer = layer self.formValues = formValues self.rules = [] self.logBrowser = logBrowser self.validateForm() - + def calculateExpression(self, exp): for field in self.formValues: if field != 'filter': @@ -1801,7 +1801,7 @@ class ValidateForm: exp = exp.replace("'NULL'".format(field), "NULL") r = QgsExpression(exp) return r.evaluate() - + def validateForm(self): self.cleanRulesOnForm() logText = "" @@ -1832,7 +1832,7 @@ class ValidateForm: def cleanRulesOnForm(self): for field in self.formValues: if len(self.formValues[field]) == 3: - self.formValues[field][2].setStyleSheet("") + self.formValues[field][2].setStyleSheet("") else: self.formValues[field][1].setStyleSheet("") @@ -1864,12 +1864,12 @@ class ManagerForm(QtCore.QObject): self.logFrame.show() else: self.logFrame.hide() - + def eventFilter(self, o, event): if event.type() in [7, 10, 11, 100]: self.validateLayerByRules() return False - + def validateLayerByRules(self): formValues = {} for cb in self.myDialog.findChildren(QComboBox): @@ -1885,7 +1885,7 @@ class ManagerForm(QtCore.QObject): le ] self.validadeForm = ValidateForm(self.lyr, formValues, self.logBrowser) - + def finishedForm(self): pass diff --git a/DsgTools/core/Qmls/qgis_37_impl_2/edgv_213_pro/llp_delimitacao_fisica_l.qml b/DsgTools/core/Qmls/qgis_37_impl_2/edgv_213_pro/llp_delimitacao_fisica_l.qml index 8d43a1de5..18f571220 100644 --- a/DsgTools/core/Qmls/qgis_37_impl_2/edgv_213_pro/llp_delimitacao_fisica_l.qml +++ b/DsgTools/core/Qmls/qgis_37_impl_2/edgv_213_pro/llp_delimitacao_fisica_l.qml @@ -280,12 +280,12 @@ global a class ValidateForm: def __init__(self, layer, formValues, logBrowser): - self.layer = layer + self.layer = layer self.formValues = formValues self.rules = [] self.logBrowser = logBrowser self.validateForm() - + def calculateExpression(self, exp): for field in self.formValues: if field != 'filter': @@ -297,7 +297,7 @@ class ValidateForm: exp = exp.replace("'NULL'".format(field), "NULL") r = QgsExpression(exp) return r.evaluate() - + def validateForm(self): self.cleanRulesOnForm() logText = "" @@ -328,7 +328,7 @@ class ValidateForm: def cleanRulesOnForm(self): for field in self.formValues: if len(self.formValues[field]) == 3: - self.formValues[field][2].setStyleSheet("") + self.formValues[field][2].setStyleSheet("") else: self.formValues[field][1].setStyleSheet("") @@ -360,12 +360,12 @@ class ManagerForm(QtCore.QObject): self.logFrame.show() else: self.logFrame.hide() - + def eventFilter(self, o, event): if event.type() in [7, 10, 11, 100]: self.validateLayerByRules() return False - + def validateLayerByRules(self): formValues = {} for cb in self.myDialog.findChildren(QComboBox): @@ -381,7 +381,7 @@ class ManagerForm(QtCore.QObject): le ] self.validadeForm = ValidateForm(self.lyr, formValues, self.logBrowser) - + def finishedForm(self): pass diff --git a/DsgTools/core/Qmls/qgis_37_impl_2/edgv_213_pro/rev_hidrografia_p.qml b/DsgTools/core/Qmls/qgis_37_impl_2/edgv_213_pro/rev_hidrografia_p.qml index aab7fe9a9..a243c3bb8 100644 --- a/DsgTools/core/Qmls/qgis_37_impl_2/edgv_213_pro/rev_hidrografia_p.qml +++ b/DsgTools/core/Qmls/qgis_37_impl_2/edgv_213_pro/rev_hidrografia_p.qml @@ -471,12 +471,12 @@ global a class ValidateForm: def __init__(self, layer, formValues, logBrowser): - self.layer = layer + self.layer = layer self.formValues = formValues self.rules = [] self.logBrowser = logBrowser self.validateForm() - + def calculateExpression(self, exp): for field in self.formValues: if field != 'filter': @@ -488,7 +488,7 @@ class ValidateForm: exp = exp.replace("'NULL'".format(field), "NULL") r = QgsExpression(exp) return r.evaluate() - + def validateForm(self): self.cleanRulesOnForm() logText = "" @@ -519,7 +519,7 @@ class ValidateForm: def cleanRulesOnForm(self): for field in self.formValues: if len(self.formValues[field]) == 3: - self.formValues[field][2].setStyleSheet("") + self.formValues[field][2].setStyleSheet("") else: self.formValues[field][1].setStyleSheet("") @@ -551,12 +551,12 @@ class ManagerForm(QtCore.QObject): self.logFrame.show() else: self.logFrame.hide() - + def eventFilter(self, o, event): if event.type() in [7, 10, 11, 100]: self.validateLayerByRules() return False - + def validateLayerByRules(self): formValues = {} for cb in self.myDialog.findChildren(QComboBox): @@ -572,7 +572,7 @@ class ManagerForm(QtCore.QObject): le ] self.validadeForm = ValidateForm(self.lyr, formValues, self.logBrowser) - + def finishedForm(self): pass diff --git a/DsgTools/core/Qmls/qgis_37_impl_2/edgv_213_pro/rev_vegetacao_p.qml b/DsgTools/core/Qmls/qgis_37_impl_2/edgv_213_pro/rev_vegetacao_p.qml index df4d4b088..7514a1a3b 100644 --- a/DsgTools/core/Qmls/qgis_37_impl_2/edgv_213_pro/rev_vegetacao_p.qml +++ b/DsgTools/core/Qmls/qgis_37_impl_2/edgv_213_pro/rev_vegetacao_p.qml @@ -471,12 +471,12 @@ global a class ValidateForm: def __init__(self, layer, formValues, logBrowser): - self.layer = layer + self.layer = layer self.formValues = formValues self.rules = [] self.logBrowser = logBrowser self.validateForm() - + def calculateExpression(self, exp): for field in self.formValues: if field != 'filter': @@ -488,7 +488,7 @@ class ValidateForm: exp = exp.replace("'NULL'".format(field), "NULL") r = QgsExpression(exp) return r.evaluate() - + def validateForm(self): self.cleanRulesOnForm() logText = "" @@ -519,7 +519,7 @@ class ValidateForm: def cleanRulesOnForm(self): for field in self.formValues: if len(self.formValues[field]) == 3: - self.formValues[field][2].setStyleSheet("") + self.formValues[field][2].setStyleSheet("") else: self.formValues[field][1].setStyleSheet("") @@ -551,12 +551,12 @@ class ManagerForm(QtCore.QObject): self.logFrame.show() else: self.logFrame.hide() - + def eventFilter(self, o, event): if event.type() in [7, 10, 11, 100]: self.validateLayerByRules() return False - + def validateLayerByRules(self): formValues = {} for cb in self.myDialog.findChildren(QComboBox): @@ -572,7 +572,7 @@ class ManagerForm(QtCore.QObject): le ] self.validadeForm = ValidateForm(self.lyr, formValues, self.logBrowser) - + def finishedForm(self): pass diff --git a/DsgTools/core/Qmls/qgis_37_impl_2/edgv_213_pro/val_transportes_a.qml b/DsgTools/core/Qmls/qgis_37_impl_2/edgv_213_pro/val_transportes_a.qml index 0db0a28c4..ed9423cc9 100644 --- a/DsgTools/core/Qmls/qgis_37_impl_2/edgv_213_pro/val_transportes_a.qml +++ b/DsgTools/core/Qmls/qgis_37_impl_2/edgv_213_pro/val_transportes_a.qml @@ -282,12 +282,12 @@ global a class ValidateForm: def __init__(self, layer, formValues, logBrowser): - self.layer = layer + self.layer = layer self.formValues = formValues self.rules = [] self.logBrowser = logBrowser self.validateForm() - + def calculateExpression(self, exp): for field in self.formValues: if field != 'filter': @@ -299,7 +299,7 @@ class ValidateForm: exp = exp.replace("'NULL'".format(field), "NULL") r = QgsExpression(exp) return r.evaluate() - + def validateForm(self): self.cleanRulesOnForm() logText = "" @@ -330,7 +330,7 @@ class ValidateForm: def cleanRulesOnForm(self): for field in self.formValues: if len(self.formValues[field]) == 3: - self.formValues[field][2].setStyleSheet("") + self.formValues[field][2].setStyleSheet("") else: self.formValues[field][1].setStyleSheet("") @@ -362,12 +362,12 @@ class ManagerForm(QtCore.QObject): self.logFrame.show() else: self.logFrame.hide() - + def eventFilter(self, o, event): if event.type() in [7, 10, 11, 100]: self.validateLayerByRules() return False - + def validateLayerByRules(self): formValues = {} for cb in self.myDialog.findChildren(QComboBox): @@ -383,7 +383,7 @@ class ManagerForm(QtCore.QObject): le ] self.validadeForm = ValidateForm(self.lyr, formValues, self.logBrowser) - + def finishedForm(self): pass diff --git a/DsgTools/core/Qmls/qgis_37_impl_2/edgv_3_pro/__init__.py b/DsgTools/core/Qmls/qgis_37_impl_2/edgv_3_pro/__init__.py index 0519ecba6..e69de29bb 100644 --- a/DsgTools/core/Qmls/qgis_37_impl_2/edgv_3_pro/__init__.py +++ b/DsgTools/core/Qmls/qgis_37_impl_2/edgv_3_pro/__init__.py @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/DsgTools/core/ServerManagementTools/attributeRulesManager.py b/DsgTools/core/ServerManagementTools/attributeRulesManager.py index b3eb2b7eb..5e2aec86b 100644 --- a/DsgTools/core/ServerManagementTools/attributeRulesManager.py +++ b/DsgTools/core/ServerManagementTools/attributeRulesManager.py @@ -20,25 +20,29 @@ * * ***************************************************************************/ """ -#General imports +# General imports from osgeo import ogr from uuid import uuid4 import codecs, os, json, binascii -#DSG Tools imports -from DsgTools.core.Factories.DbFactory.dbFactory import DbFactory +# DSG Tools imports +from DsgTools.core.Factories.DbFactory.dbFactory import DbFactory from DsgTools.core.ServerManagementTools.genericDbManager import GenericDbManager from DsgTools.core.Utils.utils import Utils -#qgis.PyQt imports +# qgis.PyQt imports from qgis.PyQt.Qt import QObject + class AttributeRulesManager(GenericDbManager): """ This class manages the customizations on dsgtools databases. """ - def __init__(self, serverAbstractDb, dbDict, edgvVersion, parentWidget = None): - super(AttributeRulesManager,self).__init__(serverAbstractDb, dbDict, edgvVersion, parentWidget = None) + + def __init__(self, serverAbstractDb, dbDict, edgvVersion, parentWidget=None): + super(AttributeRulesManager, self).__init__( + serverAbstractDb, dbDict, edgvVersion, parentWidget=None + ) def validateJsonProfile(self, inputJsonDict): """ @@ -47,5 +51,5 @@ def validateJsonProfile(self, inputJsonDict): 3. If one piece of json is not valid, returns False. This validator does not validate the name of classes or names of categories. It only checks the format of dsgtools json profile. """ - #TODO + # TODO return True diff --git a/DsgTools/core/ServerManagementTools/customizationManager.py b/DsgTools/core/ServerManagementTools/customizationManager.py index 690c58b6a..8cf143b3f 100644 --- a/DsgTools/core/ServerManagementTools/customizationManager.py +++ b/DsgTools/core/ServerManagementTools/customizationManager.py @@ -20,26 +20,30 @@ * * ***************************************************************************/ """ -#General imports +# General imports from osgeo import ogr from uuid import uuid4 import codecs, os, json, binascii -#DSG Tools imports -from DsgTools.core.Factories.DbFactory.dbFactory import DbFactory +# DSG Tools imports +from DsgTools.core.Factories.DbFactory.dbFactory import DbFactory from DsgTools.core.ServerManagementTools.genericDbManager import GenericDbManager from DsgTools.core.Utils.utils import Utils -#qgis.PyQt imports +# qgis.PyQt imports from qgis.PyQt.Qt import QObject + class CustomizationManager(GenericDbManager): """ This class manages the customizations on dsgtools databases. """ - def __init__(self, serverAbstractDb, dbDict, edgvVersion, parentWidget = None): - super(self.__class__,self).__init__(serverAbstractDb, dbDict, edgvVersion, parentWidget = None) - + + def __init__(self, serverAbstractDb, dbDict, edgvVersion, parentWidget=None): + super(self.__class__, self).__init__( + serverAbstractDb, dbDict, edgvVersion, parentWidget=None + ) + def installCustomization(self, customizationName): """ 1. Get customization from dsgtools_admindb; @@ -48,7 +52,7 @@ def installCustomization(self, customizationName): 4. If custom applied, save it on customization table on db and on dsgtools_admindb; """ pass - + def removeCustomization(self, customizationName): pass @@ -62,9 +66,9 @@ def validateJsonProfile(self, inputJsonDict): 3. If one piece of json is not valid, returns False. This validator does not validate the name of classes or names of categories. It only checks the format of dsgtools json profile. """ - #TODO + # TODO return True - + def getPropertyPerspectiveDict(self, viewType): """ Gets a dict in the format: @@ -79,14 +83,16 @@ def materializeIntoDatabase(self, abstractDb, propertyDict): """ pass - def undoMaterializationFromDatabase(self, abstractDb, configName, settingType, edgvVersion): + def undoMaterializationFromDatabase( + self, abstractDb, configName, settingType, edgvVersion + ): """ Method that is reimplemented in each child when uninstalling a property involves changing any sort of database structure """ pass - + def hasStructuralChanges(self, dbNameList): """ Method that is reimplemented in each child """ - return [] \ No newline at end of file + return [] diff --git a/DsgTools/core/ServerManagementTools/earthCoverageManager.py b/DsgTools/core/ServerManagementTools/earthCoverageManager.py index 662952946..5fff03347 100644 --- a/DsgTools/core/ServerManagementTools/earthCoverageManager.py +++ b/DsgTools/core/ServerManagementTools/earthCoverageManager.py @@ -20,48 +20,66 @@ * * ***************************************************************************/ """ -#General imports +# General imports from osgeo import ogr from uuid import uuid4 import codecs, os, json, binascii -#DSG Tools imports -from DsgTools.core.Factories.DbFactory.dbFactory import DbFactory +# DSG Tools imports +from DsgTools.core.Factories.DbFactory.dbFactory import DbFactory from DsgTools.core.ServerManagementTools.genericDbManager import GenericDbManager from DsgTools.core.Utils.utils import Utils -#qgis.PyQt imports +# qgis.PyQt imports from qgis.PyQt.Qt import QObject + class EarthCoverageManager(GenericDbManager): """ This class manages the customizations on dsgtools databases. """ - def __init__(self, serverAbstractDb, dbDict, edgvVersion, parentWidget = None): - super(self.__class__,self).__init__(serverAbstractDb, dbDict, edgvVersion, parentWidget = None) + + def __init__(self, serverAbstractDb, dbDict, edgvVersion, parentWidget=None): + super(self.__class__, self).__init__( + serverAbstractDb, dbDict, edgvVersion, parentWidget=None + ) def materializeIntoDatabase(self, abstractDb, propertyDict): """ Method that is reimplemented in each child when installing a property involves changing any sort of database structure """ - jsonDict = self.utils.instantiateJsonDict(propertyDict['jsondict']) - abstractDb.createCentroidAuxStruct(list(jsonDict['earthCoverageDict'].keys()), useTransaction = False) + jsonDict = self.utils.instantiateJsonDict(propertyDict["jsondict"]) + abstractDb.createCentroidAuxStruct( + list(jsonDict["earthCoverageDict"].keys()), useTransaction=False + ) - def updateMaterializationFromDatabase(self, abstractDb, propertyDict, oldPropertyDict): + def updateMaterializationFromDatabase( + self, abstractDb, propertyDict, oldPropertyDict + ): """ Method that is reimplemented in each child when updating a property involves changing any sort of database structure """ - newJsonDict = self.utils.instantiateJsonDict(propertyDict['jsondict']) - oldJsonDict = self.utils.instantiateJsonDict(oldPropertyDict['jsondict']) - abstractDb.updateEarthCoverageDict(newJsonDict, oldJsonDict, useTransaction = True) - - def undoMaterializationFromDatabase(self, abstractDb, propertyName, settingType, edgvVersion): + newJsonDict = self.utils.instantiateJsonDict(propertyDict["jsondict"]) + oldJsonDict = self.utils.instantiateJsonDict(oldPropertyDict["jsondict"]) + abstractDb.updateEarthCoverageDict( + newJsonDict, oldJsonDict, useTransaction=True + ) + + def undoMaterializationFromDatabase( + self, abstractDb, propertyName, settingType, edgvVersion + ): """ Method that is reimplemented in each child when uninstalling a property involves changing any sort of database structure """ - jsonDict = self.utils.instantiateJsonDict(abstractDb.getRecordFromAdminDb(settingType, propertyName, edgvVersion)['jsondict']) - abstractDb.dropCentroids(list(jsonDict['earthCoverageDict'].keys()), useTransaction = False) - + jsonDict = self.utils.instantiateJsonDict( + abstractDb.getRecordFromAdminDb(settingType, propertyName, edgvVersion)[ + "jsondict" + ] + ) + abstractDb.dropCentroids( + list(jsonDict["earthCoverageDict"].keys()), useTransaction=False + ) + def hasStructuralChanges(self, dbNameList): """ Method that is reimplemented in each child diff --git a/DsgTools/core/ServerManagementTools/genericDbManager.py b/DsgTools/core/ServerManagementTools/genericDbManager.py index 914cbeef7..d6e1f6084 100644 --- a/DsgTools/core/ServerManagementTools/genericDbManager.py +++ b/DsgTools/core/ServerManagementTools/genericDbManager.py @@ -20,51 +20,62 @@ * * ***************************************************************************/ """ -#General imports +# General imports from builtins import str from osgeo import ogr from uuid import uuid4 import codecs, os, json, binascii -#DSG Tools imports -from DsgTools.core.Factories.DbFactory.dbFactory import DbFactory +# DSG Tools imports +from DsgTools.core.Factories.DbFactory.dbFactory import DbFactory from DsgTools.core.Utils.utils import Utils from DsgTools.core.dsgEnums import DsgEnums -#qgis.PyQt imports +# qgis.PyQt imports from qgis.PyQt.Qt import QObject + class GenericDbManager(QObject): """ This class manages the permissions on dsgtools databases. """ - def __init__(self, serverAbstractDb, dbDict, edgvVersion, parentWidget = None): - super(GenericDbManager,self).__init__() + + def __init__(self, serverAbstractDb, dbDict, edgvVersion, parentWidget=None): + super(GenericDbManager, self).__init__() self.parentWidget = parentWidget self.dbDict = dbDict self.serverAbstractDb = serverAbstractDb self.adminDb = self.instantiateAdminDb(serverAbstractDb) self.utils = Utils() - self.extensionDict = {'EarthCoverage':'.dsgearthcov', - 'Customization':'.dsgcustom', - 'Style':'.dsgstyle', - 'ValidationConfig':'.dsgvalidcfg', - 'Permission':'.dsgperm', - 'AttributeRules':'.dsgattrrul', - 'SpatialRules':'.dsgspatrul', - 'ValidationWorkspace':'.dsgworksp'} + self.extensionDict = { + "EarthCoverage": ".dsgearthcov", + "Customization": ".dsgcustom", + "Style": ".dsgstyle", + "ValidationConfig": ".dsgvalidcfg", + "Permission": ".dsgperm", + "AttributeRules": ".dsgattrrul", + "SpatialRules": ".dsgspatrul", + "ValidationWorkspace": ".dsgworksp", + } self.edgvVersion = edgvVersion self.createPropertyTable() def getManagerType(self): - return str(self.__class__).split('.')[-1].replace('\'>', '').replace('Manager','') + return ( + str(self.__class__).split(".")[-1].replace("'>", "").replace("Manager", "") + ) def instantiateAbstractDb(self, dbName): """ Instantiates an abstractDb. """ if dbName not in list(self.dbDict.keys()): - (host, port, user, password) = self.serverAbstractDb.getParamsFromConectedDb() + ( + host, + port, + user, + password, + ) = self.serverAbstractDb.getParamsFromConectedDb() abstractDb = DbFactory().createDbFactory(DsgEnums.DriverPostGIS) abstractDb.connectDatabaseWithParameters(host, port, dbName, user, password) else: @@ -73,22 +84,26 @@ def instantiateAbstractDb(self, dbName): def instantiateAdminDb(self, serverAbstractDb): """ - Instantiates dsgtools_admindb in the same server as serverAbstractDb. + Instantiates dsgtools_admindb in the same server as serverAbstractDb. If dsgtools_admindb does not exists, instantiateAdminDb calls createAdminDb """ (host, port, user, password) = serverAbstractDb.getParamsFromConectedDb() adminDb = DbFactory().createDbFactory(DsgEnums.DriverPostGIS) if not serverAbstractDb.hasAdminDb(): - return self.createAdminDb(serverAbstractDb, adminDb, host, port, user, password) - adminDb.connectDatabaseWithParameters(host, port, 'dsgtools_admindb', user, password) + return self.createAdminDb( + serverAbstractDb, adminDb, host, port, user, password + ) + adminDb.connectDatabaseWithParameters( + host, port, "dsgtools_admindb", user, password + ) managerType = self.getManagerType() if not adminDb.checkIfExistsConfigTable(managerType): - adminDb.createPropertyTable(managerType, isAdminDb = True) + adminDb.createPropertyTable(managerType, isAdminDb=True) return adminDb - + def instantiateTemplateDb(self, edgvVersion): """ - Instantiates a templateDb in the same server as serverAbstractDb. + Instantiates a templateDb in the same server as serverAbstractDb. If template does not exists, instantiateAdminDb calls createTemplate """ templateName = self.serverAbstractDb.getTemplateName(edgvVersion) @@ -97,7 +112,7 @@ def instantiateTemplateDb(self, edgvVersion): self.serverAbstractDb.createTemplateDatabase(edgvVersion) templateDb = self.instantiateAbstractDb(templateName) templateDb.setStructureFromSql(edgvVersion, 4674) - templateDb.setDbAsTemplate(version = edgvVersion) + templateDb.setDbAsTemplate(version=edgvVersion) else: templateDb = self.instantiateAbstractDb(templateName) return templateDb @@ -107,8 +122,10 @@ def createAdminDb(self, serverAbstractDb, adminDb, host, port, user, password): Creates dsgtools_admindb """ serverAbstractDb.createAdminDb() - adminDb.connectDatabaseWithParameters(host, port, 'dsgtools_admindb', user, password) - sqlPath = adminDb.getCreationSqlPath('admin') + adminDb.connectDatabaseWithParameters( + host, port, "dsgtools_admindb", user, password + ) + sqlPath = adminDb.getCreationSqlPath("admin") adminDb.runSqlFromFile(sqlPath) return adminDb @@ -124,9 +141,15 @@ def getSetting(self, name, edgvVersion): Get setting from corresponding table on dsgtools_admindb """ settingType = self.getManagerType() - settingDict = json.loads(self.adminDb.getSettingFromAdminDb(settingType, name, edgvVersion)) + settingDict = json.loads( + self.adminDb.getSettingFromAdminDb(settingType, name, edgvVersion) + ) if not settingDict: - raise Exception(self.tr("Setting ")+ settingType +self.tr(" not found on dsgtools_admindb!")) + raise Exception( + self.tr("Setting ") + + settingType + + self.tr(" not found on dsgtools_admindb!") + ) return settingDict def createSetting(self, settingName, edgvVersion, jsonDict): @@ -134,21 +157,25 @@ def createSetting(self, settingName, edgvVersion, jsonDict): Creates setting on dsgtools_admindb. """ settingType = self.getManagerType() - if isinstance(jsonDict,dict): - jsonDict = json.dumps(jsonDict,sort_keys=True, indent=4) - self.adminDb.insertSettingIntoAdminDb(settingType, settingName, jsonDict, edgvVersion) + if isinstance(jsonDict, dict): + jsonDict = json.dumps(jsonDict, sort_keys=True, indent=4) + self.adminDb.insertSettingIntoAdminDb( + settingType, settingName, jsonDict, edgvVersion + ) - def updateSetting(self, settingName, newJsonDict, edgvVersion = None): + def updateSetting(self, settingName, newJsonDict, edgvVersion=None): """ Generic update. Can be reimplenented in child methods. - 1. Get property dict from adminDb + 1. Get property dict from adminDb """ if not edgvVersion: edgvVersion = self.edgvVersion errorDict = dict() successList = [] settingType = self.getManagerType() - propertyDict = self.adminDb.getPropertyPerspectiveDict(settingType, DsgEnums.Property, versionFilter = edgvVersion) + propertyDict = self.adminDb.getPropertyPerspectiveDict( + settingType, DsgEnums.Property, versionFilter=edgvVersion + ) if settingName in list(propertyDict.keys()): rollbackList = [] self.adminDb.db.transaction() @@ -157,9 +184,13 @@ def updateSetting(self, settingName, newJsonDict, edgvVersion = None): abstractDb = self.instantiateAbstractDb(dbName) abstractDb.db.transaction() rollbackList.append(abstractDb) - self.updateMaterializationFromDatabase(abstractDb,propertyDict) - abstractDb.updateRecordFromPropertyTable(settingType, settingName, edgvVersion, newJsonDict) - self.adminDb.updateRecordFromPropertyTable(settingType, settingName, edgvVersion, newJsonDict) + self.updateMaterializationFromDatabase(abstractDb, propertyDict) + abstractDb.updateRecordFromPropertyTable( + settingType, settingName, edgvVersion, newJsonDict + ) + self.adminDb.updateRecordFromPropertyTable( + settingType, settingName, edgvVersion, newJsonDict + ) for abstractDb in rollbackList: abstractDb.db.commit() self.adminDb.db.commit() @@ -168,7 +199,7 @@ def updateSetting(self, settingName, newJsonDict, edgvVersion = None): for abstractDb in rollbackList: abstractDb.db.rollback() self.adminDb.db.rollback() - errorDict[dbName] = ':'.join(e.args) + errorDict[dbName] = ":".join(e.args) return (successList, errorDict) def importSetting(self, fullFilePath): @@ -178,23 +209,30 @@ def importSetting(self, fullFilePath): 2. Validates inputPermissionDict; 3. Tries to insert into database, if there is an error, abstractDb raises an error which is also raised by importProfile """ - #getting profile name - settingName = os.path.basename(fullFilePath).split('.')[0] - #getting json - inputJsonDict, inputJson = self.utils.readJsonFile(fullFilePath, returnFileAndDict = True) - #error handling and json validation + # getting profile name + settingName = os.path.basename(fullFilePath).split(".")[0] + # getting json + inputJsonDict, inputJson = self.utils.readJsonFile( + fullFilePath, returnFileAndDict=True + ) + # error handling and json validation if inputJsonDict == dict(): raise Exception(self.tr("Not valid DsgTools property file!")) if not self.validateJsonSetting(inputJsonDict): raise Exception(self.tr("Not valid DsgTools property file!")) - if 'version' in list(inputJsonDict.keys()): - edgvVersion = inputJsonDict['version'] + if "version" in list(inputJsonDict.keys()): + edgvVersion = inputJsonDict["version"] else: - edgvVersion = list(inputJsonDict.keys())[0].split('_')[-1] + edgvVersion = list(inputJsonDict.keys())[0].split("_")[-1] try: self.createSetting(settingName, edgvVersion, inputJson) except Exception as e: - raise Exception(self.tr("Error importing setting ") + settingName +': '+':'.join(e.args)) + raise Exception( + self.tr("Error importing setting ") + + settingName + + ": " + + ":".join(e.args) + ) def batchImportSettings(self, profilesDir): """ @@ -204,7 +242,7 @@ def batchImportSettings(self, profilesDir): importList = [] for profile in next(os.walk(profilesDir))[2]: if self.extensionDict[self.getManagerType()] in os.path.basename(profile): - importList.append(os.path.join(profilesDir,profile)) + importList.append(os.path.join(profilesDir, profile)) for profileFile in importList: self.importSetting(profileFile) @@ -216,10 +254,12 @@ def exportSetting(self, profileName, edgvVersion, outputPath): jsonDict = self.getSetting(profileName, edgvVersion) if not os.path.exists(outputPath): os.makedirs(outputPath) - outputFile = os.path.join(outputPath, profileName+self.extensionDict[self.getManagerType()]) - with open(outputFile, 'w') as outfile: + outputFile = os.path.join( + outputPath, profileName + self.extensionDict[self.getManagerType()] + ) + with open(outputFile, "w") as outfile: json.dump(jsonDict, outfile, sort_keys=True, indent=4) - + def batchExportSettings(self, outputDir): """ 1. Get all settings from corresponding table in dsgtools_admindb; @@ -227,40 +267,44 @@ def batchExportSettings(self, outputDir): """ settingDict = self.getSettings() for edgvVersion in list(settingDict.keys()): - outputPath = os.path.join(outputDir,edgvVersion) + outputPath = os.path.join(outputDir, edgvVersion) if not os.path.exists(outputPath): os.makedirs(outputPath) for profileName in settingDict[edgvVersion]: self.exportSetting(profileName, edgvVersion, outputPath) - def getPropertyPerspectiveDict(self, viewType = DsgEnums.Property, versionFilter = None): + def getPropertyPerspectiveDict( + self, viewType=DsgEnums.Property, versionFilter=None + ): """ Gets a dict in the format: if viewType == 'customization': {customizationName: ['-list of databases with customization']} if viewType == 'database': {databaseName: ['-list of customizations with customization']} """ settingType = self.getManagerType() - return self.adminDb.getPropertyPerspectiveDict(settingType, viewType, versionFilter = versionFilter) - + return self.adminDb.getPropertyPerspectiveDict( + settingType, viewType, versionFilter=versionFilter + ) + def getSettingVersion(self, settingName): settingType = self.getManagerType() return self.adminDb.getSettingVersion(settingType, settingName) - + def validateJsonSetting(self, inputJsonDict): """ reimplemented in each child """ return True - + def getRecordFromAdminDb(self, propertyName, edgvVersion): settingType = self.getManagerType() return self.adminDb.getRecordFromAdminDb(settingType, propertyName, edgvVersion) - def createAndInstall(self, configName, newJsonDict, edgvVersion, dbList = []): + def createAndInstall(self, configName, newJsonDict, edgvVersion, dbList=[]): self.createSetting(configName, edgvVersion, newJsonDict) - return self.installSetting(configName,dbNameList = dbList) + return self.installSetting(configName, dbNameList=dbList) - def installSetting(self, configName, dbNameList = []): + def installSetting(self, configName, dbNameList=[]): """ Generic install. Can be reimplenented in child methods. """ @@ -274,70 +318,88 @@ def installSetting(self, configName, dbNameList = []): abstractDb = self.instantiateAbstractDb(dbName) edgvVersion = abstractDb.getDatabaseVersion() if edgvVersion != configEdgvVersion: - errorDict[dbName] = self.tr('Database version missmatch.') + errorDict[dbName] = self.tr("Database version missmatch.") continue - recDict = self.adminDb.getRecordFromAdminDb(settingType, configName, edgvVersion) + recDict = self.adminDb.getRecordFromAdminDb( + settingType, configName, edgvVersion + ) try: if not abstractDb.checkIfExistsConfigTable(settingType): - abstractDb.createPropertyTable(settingType, useTransaction = True) + abstractDb.createPropertyTable(settingType, useTransaction=True) except Exception as e: - errorDict[dbName] = ':'.join(e.args) + errorDict[dbName] = ":".join(e.args) continue try: abstractDb.db.transaction() self.adminDb.db.transaction() - self.materializeIntoDatabase(abstractDb, recDict) #step done when property management involves changing database structure - abstractDb.insertRecordInsidePropertyTable(settingType, recDict, edgvVersion) + self.materializeIntoDatabase( + abstractDb, recDict + ) # step done when property management involves changing database structure + abstractDb.insertRecordInsidePropertyTable( + settingType, recDict, edgvVersion + ) dbOid = abstractDb.getDbOID() - self.adminDb.insertInstalledRecordIntoAdminDb(settingType, recDict, dbOid) + self.adminDb.insertInstalledRecordIntoAdminDb( + settingType, recDict, dbOid + ) abstractDb.db.commit() self.adminDb.db.commit() except Exception as e: abstractDb.db.rollback() self.adminDb.db.rollback() - errorDict[dbName] = ':'.join(e.args) + errorDict[dbName] = ":".join(e.args) successList.append(dbName) return (successList, errorDict) - - def deleteSetting(self, configName, dbNameList = []): + + def deleteSetting(self, configName, dbNameList=[]): """ Generic remove. Can be reimplenented in child methods. - 1. Get property dict from adminDb + 1. Get property dict from adminDb """ errorDict = dict() successList = [] settingType = self.getManagerType() - propertyDict = self.adminDb.getPropertyPerspectiveDict(settingType, DsgEnums.Property) + propertyDict = self.adminDb.getPropertyPerspectiveDict( + settingType, DsgEnums.Property + ) if configName in list(propertyDict.keys()): for dbName in propertyDict[configName]: if not dbName: try: self.adminDb.db.transaction() - self.adminDb.removeRecordFromPropertyTable(settingType, configName, None) + self.adminDb.removeRecordFromPropertyTable( + settingType, configName, None + ) self.adminDb.db.commit() successList.append(dbName) except Exception as e: self.adminDb.db.rollback() - errorDict[dbName] = ':'.join(e.args) + errorDict[dbName] = ":".join(e.args) else: abstractDb = self.instantiateAbstractDb(dbName) edgvVersion = abstractDb.getDatabaseVersion() try: abstractDb.db.transaction() self.adminDb.db.transaction() - self.undoMaterializationFromDatabase(abstractDb, configName, settingType, edgvVersion) #step done when property management involves changing database structure - abstractDb.removeRecordFromPropertyTable(settingType, configName, edgvVersion) - self.adminDb.removeRecordFromPropertyTable(settingType, configName, edgvVersion) + self.undoMaterializationFromDatabase( + abstractDb, configName, settingType, edgvVersion + ) # step done when property management involves changing database structure + abstractDb.removeRecordFromPropertyTable( + settingType, configName, edgvVersion + ) + self.adminDb.removeRecordFromPropertyTable( + settingType, configName, edgvVersion + ) abstractDb.db.commit() self.adminDb.db.commit() successList.append(dbName) except Exception as e: abstractDb.db.rollback() self.adminDb.db.rollback() - errorDict[dbName] = ':'.join(e.args) + errorDict[dbName] = ":".join(e.args) return (successList, errorDict) - def uninstallSetting(self, configName, dbNameList = []): + def uninstallSetting(self, configName, dbNameList=[]): """ Generic uninstall. Can be reimplenented in child methods. This can uninstall setting on a list of databases or in all databases (if dbNameList == []) @@ -345,11 +407,15 @@ def uninstallSetting(self, configName, dbNameList = []): errorDict = dict() successList = [] settingType = self.getManagerType() - propertyDict = self.adminDb.getPropertyPerspectiveDict(settingType, DsgEnums.Property) + propertyDict = self.adminDb.getPropertyPerspectiveDict( + settingType, DsgEnums.Property + ) if configName in list(propertyDict.keys()): - if dbNameList == []: #builds filter dbList to uninstall in all installed databases + if ( + dbNameList == [] + ): # builds filter dbList to uninstall in all installed databases dbList = propertyDict[configName] - else: #builds filter dbList to uninstall in databases in dbNameList + else: # builds filter dbList to uninstall in databases in dbNameList dbList = [i for i in propertyDict[configName] if i in dbNameList] for dbName in dbList: abstractDb = self.instantiateAbstractDb(dbName) @@ -357,42 +423,50 @@ def uninstallSetting(self, configName, dbNameList = []): try: abstractDb.db.transaction() self.adminDb.db.transaction() - self.undoMaterializationFromDatabase(abstractDb, configName, settingType, edgvVersion) #step done when property management involves changing database structure - abstractDb.removeRecordFromPropertyTable(settingType, configName, edgvVersion) - self.adminDb.uninstallPropertyOnAdminDb(settingType, configName, edgvVersion, dbName = dbName) + self.undoMaterializationFromDatabase( + abstractDb, configName, settingType, edgvVersion + ) # step done when property management involves changing database structure + abstractDb.removeRecordFromPropertyTable( + settingType, configName, edgvVersion + ) + self.adminDb.uninstallPropertyOnAdminDb( + settingType, configName, edgvVersion, dbName=dbName + ) abstractDb.db.commit() self.adminDb.db.commit() except Exception as e: abstractDb.db.rollback() self.adminDb.db.rollback() - errorDict[dbName] = ':'.join(e.args) + errorDict[dbName] = ":".join(e.args) successList.append(dbName) return (successList, errorDict) - + def materializeIntoDatabase(self, abstractDb, propertyDict): """ Method that is reimplemented in each child when installing a property involves changing any sort of database structure """ pass - def undoMaterializationFromDatabase(self, abstractDb, configName, settingType, edgvVersion): + def undoMaterializationFromDatabase( + self, abstractDb, configName, settingType, edgvVersion + ): """ Method that is reimplemented in each child when uninstalling a property involves changing any sort of database structure """ pass - + def hasStructuralChanges(self, dbNameList): """ Method that is reimplemented in each child """ return [] - + def createPropertyTable(self): settingType = self.getManagerType() for dbName in list(self.dbDict.keys()): abstractDb = self.instantiateAbstractDb(dbName) if not abstractDb.checkIfExistsConfigTable(settingType): - abstractDb.createPropertyTable(settingType, useTransaction = True) - + abstractDb.createPropertyTable(settingType, useTransaction=True) + def updateMaterializationFromDatabase(self, abstractDb, propertyDict): - pass \ No newline at end of file + pass diff --git a/DsgTools/core/ServerManagementTools/permissionManager.py b/DsgTools/core/ServerManagementTools/permissionManager.py index 0978b9869..804851cc9 100644 --- a/DsgTools/core/ServerManagementTools/permissionManager.py +++ b/DsgTools/core/ServerManagementTools/permissionManager.py @@ -20,49 +20,53 @@ * * ***************************************************************************/ """ -#General imports +# General imports from osgeo import ogr from uuid import uuid4 import codecs, os, json, binascii -#DSG Tools imports -from DsgTools.core.Factories.DbFactory.dbFactory import DbFactory +# DSG Tools imports +from DsgTools.core.Factories.DbFactory.dbFactory import DbFactory from DsgTools.core.ServerManagementTools.genericDbManager import GenericDbManager from DsgTools.core.Utils.utils import Utils -#qgis.PyQt imports +# qgis.PyQt imports from qgis.PyQt.Qt import QObject + class PermissionManager(GenericDbManager): - ''' + """ This class manages the permissions on dsgtools databases. - ''' - def __init__(self, serverAbstractDb, dbDict, edgvVersion, parentWidget = None): - super(self.__class__,self).__init__(serverAbstractDb, dbDict, edgvVersion, parentWidget = None) - + """ + + def __init__(self, serverAbstractDb, dbDict, edgvVersion, parentWidget=None): + super(self.__class__, self).__init__( + serverAbstractDb, dbDict, edgvVersion, parentWidget=None + ) + def getRolesInformation(self): - ''' + """ Builds two dicts: dbRolesDict = { 'dbname':[-list of roles-] } rolesDict = { 'profileName': { 'dbname' : [-list of roles with uuid on it-] } } - ''' + """ dbRolesDict = self.adminDb.getRolesDict() rolesDict = dict() for db in list(dbRolesDict.keys()): for role in dbRolesDict[db]: - profileName = '_'.join(role.split('_')[0:-5]) + profileName = "_".join(role.split("_")[0:-5]) if profileName not in list(rolesDict.keys()): rolesDict[profileName] = dict() if db not in list(rolesDict[profileName].keys()): rolesDict[profileName][db] = [] rolesDict[profileName][db].append(role) return dbRolesDict, rolesDict - + def getDatabasePerspectiveDict(self): - ''' + """ Gets a dict in the format: {dbName: {roleName :[-list of users-]}} - The dbs are from dbDict - ''' + The dbs are from dbDict + """ (dbRolesDict, rolesDict) = self.getRolesInformation() profiles = self.getSettings() grantedRoleDict = self.adminDb.getGrantedRolesDict() @@ -80,20 +84,25 @@ def getDatabasePerspectiveDict(self): for role in rolesDict[profile][dbName]: if role in list(grantedRoleDict.keys()): for user in grantedRoleDict[role]: - if user not in dbPerspectiveDict[dbName][profile]: - dbPerspectiveDict[dbName][profile].append(user) + if ( + user + not in dbPerspectiveDict[dbName][profile] + ): + dbPerspectiveDict[dbName][profile].append( + user + ) return dbPerspectiveDict - + def getUserPerspectiveDict(self): - ''' + """ Gets a dict in the format: {userName: {dbName : ['-list of roles']} - ''' + """ dbPerspectiveDict = self.getDatabasePerspectiveDict() userPerspectiveDict = dict() userList = [i[0] for i in self.adminDb.getUsersFromServer()] for user in userList: userPerspectiveDict[user] = dict() - + for dbName in list(dbPerspectiveDict.keys()): for profile in dbPerspectiveDict[dbName]: for user in dbPerspectiveDict[dbName][profile]: @@ -102,65 +111,87 @@ def getUserPerspectiveDict(self): if profile not in userPerspectiveDict[user][dbName]: userPerspectiveDict[user][dbName].append(profile) return userPerspectiveDict - + def grantPermission(self, dbName, permissionName, edgvVersion, userName): - ''' + """ Grants permission on a db to a user using a profile. 1. Gets profile from public.permission_profile; 2. Checks if profile exists on db, if it does not, installs it; 3. Grants profile to user on db. - ''' + """ profileDict = self.getSetting(permissionName, edgvVersion) - self.grantPermissionWithProfileDict(dbName, permissionName, userName, profileDict) - - def grantPermissionWithProfileDict(self, dbName, permissionName, userName, profileDict, updatePermission = False): - ''' + self.grantPermissionWithProfileDict( + dbName, permissionName, userName, profileDict + ) + + def grantPermissionWithProfileDict( + self, dbName, permissionName, userName, profileDict, updatePermission=False + ): + """ Grants permission on a db using profileDict - ''' + """ if updatePermission: - role = self.dbDict[dbName].createRole(permissionName, profileDict, permissionManager = True) + role = self.dbDict[dbName].createRole( + permissionName, profileDict, permissionManager=True + ) self.dbDict[dbName].grantRole(userName, role) else: - if not self.isPermissionInstalled(self.dbDict[dbName], dbName, permissionName): - self.dbDict[dbName].createRole(permissionName, profileDict) #creates profile in db - (dbRolesDict, rolesDict) = self.getRolesInformation() #done to refresh dicts due to new permission + if not self.isPermissionInstalled( + self.dbDict[dbName], dbName, permissionName + ): + self.dbDict[dbName].createRole( + permissionName, profileDict + ) # creates profile in db + ( + dbRolesDict, + rolesDict, + ) = ( + self.getRolesInformation() + ) # done to refresh dicts due to new permission for role in rolesDict[permissionName][dbName]: self.dbDict[dbName].grantRole(userName, role) - + def revokePermission(self, dbName, permissionName, userName): - ''' + """ Revokes permission on a db from permissionName. - ''' + """ (dbRolesDict, rolesDict) = self.getRolesInformation() for realRoleName in rolesDict[permissionName][dbName]: try: self.dbDict[dbName].revokeRole(userName, realRoleName) except Exception as e: - raise Exception(self.tr('Problem revoking role ') + permissionName + self.tr(' on database ') + dbName +':\n' + ':'.join(e.args)) - + raise Exception( + self.tr("Problem revoking role ") + + permissionName + + self.tr(" on database ") + + dbName + + ":\n" + + ":".join(e.args) + ) + def isPermissionInstalled(self, abstractDb, dbName, permissionName): - ''' + """ Checks if permission is already installed; Returns True if it is installed and False otherwise. - ''' + """ (dbRolesDict, rolesDict) = self.getRolesInformation() if permissionName not in list(rolesDict.keys()): return False if dbName not in list(rolesDict[permissionName].keys()): return False return True - + def updateSetting(self, settingName, edgvVersion, newProfileDict): - ''' + """ 1. Gets all roles from all databases that have the same settingName; 2. For each role, get users that are granted to them; 3. Drop role, create a new one and grant it to previous users; 4. Updates public.permission_profile on dsgtools_admindb with the newJsonDict. - ''' + """ abstractDbsToRollBack = [] try: abstractDbsToRollBack.append(self.adminDb) - self.adminDb.db.transaction() #done to rollback in case of trouble + self.adminDb.db.transaction() # done to rollback in case of trouble (dbRolesDict, rolesDict) = self.getRolesInformation() grantedRoleDict = self.adminDb.getGrantedRolesDict() if settingName in list(rolesDict.keys()): @@ -170,7 +201,7 @@ def updateSetting(self, settingName, edgvVersion, newProfileDict): abstractDb = self.instantiateAbstractDb(dbName) else: abstractDb = self.dbDict[dbName] - #prepairs to rollback in case of exception + # prepairs to rollback in case of exception abstractDbsToRollBack.append(abstractDb) abstractDb.db.transaction() usersToBeGranted = [] @@ -178,26 +209,39 @@ def updateSetting(self, settingName, edgvVersion, newProfileDict): usersToBeGranted = grantedRoleDict[roleName] abstractDb.dropRoleOnDatabase(roleName) for userName in usersToBeGranted: - self.grantPermissionWithProfileDict(dbName, settingName, userName, newProfileDict, updatePermission = True) + self.grantPermissionWithProfileDict( + dbName, + settingName, + userName, + newProfileDict, + updatePermission=True, + ) newjsonprofile = json.dumps(newProfileDict, sort_keys=True, indent=4) - self.adminDb.updatePermissionProfile(settingName, edgvVersion, newjsonprofile) + self.adminDb.updatePermissionProfile( + settingName, edgvVersion, newjsonprofile + ) for abstractDb in abstractDbsToRollBack: abstractDb.db.commit() except Exception as e: for abstractDb in abstractDbsToRollBack: abstractDb.db.rollback() - raise Exception(self.tr('Unable to update profile ') + settingName +': ' +':'.join(e.args)) - + raise Exception( + self.tr("Unable to update profile ") + + settingName + + ": " + + ":".join(e.args) + ) + def deleteSetting(self, settingName, edgvVersion): - ''' + """ 1. Get roles with the same definition of permissionName and delete them. 2. Delete permission profile from public.permission_profile on dsgtools_admindb; - ''' - #first step, delete roles with the same definition of selected profile + """ + # first step, delete roles with the same definition of selected profile abstractDbsToRollBack = [] try: abstractDbsToRollBack.append(self.adminDb) - self.adminDb.db.transaction() #done to rollback in case of trouble + self.adminDb.db.transaction() # done to rollback in case of trouble (dbRolesDict, rolesDict) = self.getRolesInformation() if settingName in list(rolesDict.keys()): for dbName in list(rolesDict[settingName].keys()): @@ -206,43 +250,55 @@ def deleteSetting(self, settingName, edgvVersion): abstractDb = self.instantiateAbstractDb(dbName) else: abstractDb = self.dbDict[dbName] - #prepairs to rollback in case of exception + # prepairs to rollback in case of exception abstractDbsToRollBack.append(abstractDb) abstractDb.db.transaction() abstractDb.dropRoleOnDatabase(roleName) - #after deletion, delete permission profile from public.permission_profile - self.adminDb.removeRecordFromPropertyTable('Permission',settingName, edgvVersion) + # after deletion, delete permission profile from public.permission_profile + self.adminDb.removeRecordFromPropertyTable( + "Permission", settingName, edgvVersion + ) for abstractDb in abstractDbsToRollBack: abstractDb.db.commit() except Exception as e: for abstractDb in abstractDbsToRollBack: abstractDb.db.rollback() - raise Exception(self.tr('Problem deleting permission: ')+':'.join(e.args)) - + raise Exception(self.tr("Problem deleting permission: ") + ":".join(e.args)) + def validateJsonProfile(self, inputJsonDict): - ''' + """ 1. Validates each key and value in inputJsonDict; 2. If input is ok, returns True; 3. If one piece of json is not valid, returns False. This validator does not validate the name of classes or names of categories. It only checks the format of dsgtools json profile. - ''' + """ for key1 in list(inputJsonDict.keys()): if not isinstance(inputJsonDict[key1], dict): return False - if key1 not in ['database_2.1.3', 'database_2.1.3_pro', 'database_3.0', 'database_FTer_2a_Ed','database_Non_EDGV']: + if key1 not in [ + "database_2.1.3", + "database_2.1.3_pro", + "database_3.0", + "database_FTer_2a_Ed", + "database_Non_EDGV", + ]: return False for key2 in list(inputJsonDict[key1].keys()): - if not isinstance(inputJsonDict[key1][key2],dict): + if not isinstance(inputJsonDict[key1][key2], dict): return False for key3 in list(inputJsonDict[key1][key2].keys()): - if not isinstance(inputJsonDict[key1][key2][key3],dict): + if not isinstance(inputJsonDict[key1][key2][key3], dict): return False for key4 in list(inputJsonDict[key1][key2][key3].keys()): - if not isinstance(inputJsonDict[key1][key2][key3][key4],dict): + if not isinstance(inputJsonDict[key1][key2][key3][key4], dict): return False for key5 in list(inputJsonDict[key1][key2][key3][key4].keys()): if key5 not in ["read", "write"]: return False - if inputJsonDict[key1][key2][key3][key4][key5] not in ["0","1","2"]: + if inputJsonDict[key1][key2][key3][key4][key5] not in [ + "0", + "1", + "2", + ]: return False return True diff --git a/DsgTools/core/ServerManagementTools/validationWorkflowManager.py b/DsgTools/core/ServerManagementTools/validationWorkflowManager.py index e94274fa0..1bc979c3c 100644 --- a/DsgTools/core/ServerManagementTools/validationWorkflowManager.py +++ b/DsgTools/core/ServerManagementTools/validationWorkflowManager.py @@ -20,25 +20,29 @@ * * ***************************************************************************/ """ -#General imports +# General imports from osgeo import ogr from uuid import uuid4 import codecs, os, json, binascii -#DSG Tools imports -from DsgTools.core.Factories.DbFactory.dbFactory import DbFactory +# DSG Tools imports +from DsgTools.core.Factories.DbFactory.dbFactory import DbFactory from DsgTools.core.ServerManagementTools.genericDbManager import GenericDbManager from DsgTools.core.Utils.utils import Utils -#qgis.PyQt imports +# qgis.PyQt imports from qgis.PyQt.Qt import QObject + class ValidationWorkflowManager(GenericDbManager): """ This class manages the customizations on dsgtools databases. """ - def __init__(self, serverAbstractDb, dbDict, edgvVersion, parentWidget = None): - super(ValidationWorkflowManager,self).__init__(serverAbstractDb, dbDict, edgvVersion, parentWidget = None) + + def __init__(self, serverAbstractDb, dbDict, edgvVersion, parentWidget=None): + super(ValidationWorkflowManager, self).__init__( + serverAbstractDb, dbDict, edgvVersion, parentWidget=None + ) def validateJsonProfile(self, inputJsonDict): """ @@ -47,5 +51,5 @@ def validateJsonProfile(self, inputJsonDict): 3. If one piece of json is not valid, returns False. This validator does not validate the name of classes or names of categories. It only checks the format of dsgtools json profile. """ - #TODO + # TODO return True diff --git a/DsgTools/core/Utils/FrameTools/map_index.py b/DsgTools/core/Utils/FrameTools/map_index.py index 40442dfb9..5cc724d61 100644 --- a/DsgTools/core/Utils/FrameTools/map_index.py +++ b/DsgTools/core/Utils/FrameTools/map_index.py @@ -28,201 +28,208 @@ import string, os, math, itertools, csv from qgis.PyQt.QtCore import QObject + class UtmGrid(QObject): def __init__(self): """Constructor.""" - super(UtmGrid,self).__init__() - self.scales=[1000,500,250,100,50,25,10,5,2,1] - nomen1000=['Nao Recorta'] - nomen500=[['V','X'],['Y','Z']] - nomen250=[['A','B'],['C','D']] - nomen100=[['I','II','III'],['IV','V','VI']] - nomen50=[['1','2'],['3','4']] - nomen25=[['NO','NE'],['SO','SE']] - nomen10=[['A','B'],['C','D'],['E','F']] - nomen5=[['I','II'],['III','IV']] - nomen2=[['1', '2', '3'], ['4', '5', '6']] - nomen1=[['A','B'],['C','D']] - self.scaleText=[nomen1000,nomen500,nomen250,nomen100,nomen50,nomen25,nomen10,nomen5,nomen2,nomen1] - self.matrizRecorte=[] - self.spacingX=[] - self.spacingY=[] - self.stepsDone=0 - self.stepsTotal=0 - self.featureBuffer=[] - self.MIdict=[] - self.MIRdict=[] - + super(UtmGrid, self).__init__() + self.scales = [1000, 500, 250, 100, 50, 25, 10, 5, 2, 1] + nomen1000 = ["Nao Recorta"] + nomen500 = [["V", "X"], ["Y", "Z"]] + nomen250 = [["A", "B"], ["C", "D"]] + nomen100 = [["I", "II", "III"], ["IV", "V", "VI"]] + nomen50 = [["1", "2"], ["3", "4"]] + nomen25 = [["NO", "NE"], ["SO", "SE"]] + nomen10 = [["A", "B"], ["C", "D"], ["E", "F"]] + nomen5 = [["I", "II"], ["III", "IV"]] + nomen2 = [["1", "2", "3"], ["4", "5", "6"]] + nomen1 = [["A", "B"], ["C", "D"]] + self.scaleText = [ + nomen1000, + nomen500, + nomen250, + nomen100, + nomen50, + nomen25, + nomen10, + nomen5, + nomen2, + nomen1, + ] + self.matrizRecorte = [] + self.spacingX = [] + self.spacingY = [] + self.stepsDone = 0 + self.stepsTotal = 0 + self.featureBuffer = [] + self.MIdict = [] + self.MIRdict = [] + def __del__(self): """Destructor.""" pass - - def findScaleText(self,scaleText,scaleId): - """Get the scale matrix for the given scaleText and scaleId - """ - j=-1 - for j,row in enumerate(self.scaleText[scaleId]): - if (scaleText in row): - i=row.index(scaleText) + + def findScaleText(self, scaleText, scaleId): + """Get the scale matrix for the given scaleText and scaleId""" + j = -1 + for j, row in enumerate(self.scaleText[scaleId]): + if scaleText in row: + i = row.index(scaleText) break - return (i,len(self.scaleText[scaleId])-j-1) - + return (i, len(self.scaleText[scaleId]) - j - 1) + def getScale(self, inomen): - """Get scale for the given map index - """ - return self.scales[ self.getScaleIdFromiNomen(inomen) ] - + """Get scale for the given map index""" + return self.scales[self.getScaleIdFromiNomen(inomen)] + def getScaleIdFromiNomen(self, inomen): - """Get scale index in self.scales object for the given map index - """ - id = len(inomen.split('-')) - 2 + """Get scale index in self.scales object for the given map index""" + id = len(inomen.split("-")) - 2 return id - + def getScaleIdFromScale(self, scale): - """Get scale if for the given scale (e.g. 1, 2, 25, 250) - """ + """Get scale if for the given scale (e.g. 1, 2, 25, 250)""" return self.scales.index(scale) - def getSpacingX(self,scale): - """Get X spacing for the given scale - """ - scaleId=self.scales.index(scale) - if (scaleId<0): return 0 - if (len(self.spacingX)==0): - dx=6 - self.spacingX=[dx] - for i in range(1,len(self.scaleText)): - subdivisions=len(self.scaleText[i][0]) - dx/=float(subdivisions) + def getSpacingX(self, scale): + """Get X spacing for the given scale""" + scaleId = self.scales.index(scale) + if scaleId < 0: + return 0 + if len(self.spacingX) == 0: + dx = 6 + self.spacingX = [dx] + for i in range(1, len(self.scaleText)): + subdivisions = len(self.scaleText[i][0]) + dx /= float(subdivisions) self.spacingX.append(dx) return self.spacingX[scaleId] - - def getSpacingY(self,scale): - """Get Y spacing for the given scale - """ - scaleId=self.scales.index(scale) - if (scaleId<0): return 0 - if (len(self.spacingY)==0): - dy=4 - self.spacingY=[dy] - for i in range(1,len(self.scaleText)): - subdivisions=len(self.scaleText[i]) - dy/=float(subdivisions) + + def getSpacingY(self, scale): + """Get Y spacing for the given scale""" + scaleId = self.scales.index(scale) + if scaleId < 0: + return 0 + if len(self.spacingY) == 0: + dy = 4 + self.spacingY = [dy] + for i in range(1, len(self.scaleText)): + subdivisions = len(self.scaleText[i]) + dy /= float(subdivisions) self.spacingY.append(dy) return self.spacingY[scaleId] - + def makeQgsPolygon(self, xmin, ymin, xmax, ymax, xSubdivisions=3, ySubdivisions=3): - """Creating a polygon for the given coordinates - """ + """Creating a polygon for the given coordinates""" polyline = [] - polyline += self.createHorizontalSegment(xmin, xmax, ymin, nSubdivisions=xSubdivisions) - polyline += self.createVerticalSegment(xmax, ymin, ymax, nSubdivisions=ySubdivisions) - polyline += self.createHorizontalSegment(xmax, xmin, ymax, nSubdivisions=xSubdivisions) - polyline += self.createVerticalSegment(xmin, ymax, ymin, nSubdivisions=ySubdivisions) + polyline += self.createHorizontalSegment( + xmin, xmax, ymin, nSubdivisions=xSubdivisions + ) + polyline += self.createVerticalSegment( + xmax, ymin, ymax, nSubdivisions=ySubdivisions + ) + polyline += self.createHorizontalSegment( + xmax, xmin, ymax, nSubdivisions=xSubdivisions + ) + polyline += self.createVerticalSegment( + xmin, ymax, ymin, nSubdivisions=ySubdivisions + ) qgsPolygon = QgsGeometry.fromMultiPolygonXY([[polyline]]) return qgsPolygon - + def createHorizontalSegment(self, xmin, xmax, y, nSubdivisions=3): - dx = (xmax-xmin)/nSubdivisions - segment = [ - QgsPointXY(xmin + i*dx, y) for i in range(nSubdivisions) - ] - segment.append(QgsPointXY(xmax,y)) + dx = (xmax - xmin) / nSubdivisions + segment = [QgsPointXY(xmin + i * dx, y) for i in range(nSubdivisions)] + segment.append(QgsPointXY(xmax, y)) return segment def createVerticalSegment(self, x, ymin, ymax, nSubdivisions=3): - dy = (ymax-ymin)/nSubdivisions - segment = [ - QgsPointXY(x, ymin + i*dy) for i in range(nSubdivisions) - ] + dy = (ymax - ymin) / nSubdivisions + segment = [QgsPointXY(x, ymin + i * dy) for i in range(nSubdivisions)] segment.append(QgsPointXY(x, ymax)) return segment - - def getHemisphereMultiplier(self,inomen): - """Check the hemisphere - """ - if (len(inomen) > 1): + + def getHemisphereMultiplier(self, inomen): + """Check the hemisphere""" + if len(inomen) > 1: h = inomen[0].upper() - if (h=='S'): + if h == "S": return -1 else: return 1 - def getLLCornerLatitude1kk(self,inomen): - """Get lower left Latitude for 1:1.000.000 scale - """ + def getLLCornerLatitude1kk(self, inomen): + """Get lower left Latitude for 1:1.000.000 scale""" try: - l=inomen[1].upper() + l = inomen[1].upper() y = 0.0 - operator=self.getHemisphereMultiplier(inomen) - verticalPosition=string.ascii_uppercase.index(l) - y=(y+4*verticalPosition)*operator - if (operator<0): y-=4 + operator = self.getHemisphereMultiplier(inomen) + verticalPosition = string.ascii_uppercase.index(l) + y = (y + 4 * verticalPosition) * operator + if operator < 0: + y -= 4 except: - raise Exception(self.tr('Invalid inomen parameter!')) + raise Exception(self.tr("Invalid inomen parameter!")) return y - def getLLCornerLongitude1kk(self,inomen): - """Get lower left Longitude for 1:1.000.000 scale - """ + def getLLCornerLongitude1kk(self, inomen): + """Get lower left Longitude for 1:1.000.000 scale""" try: - fuso=int(inomen[3:5]) - x=0 - if((fuso > 0) and (fuso <= 60)): - x = (((fuso - 30)*6.0)-6.0) + fuso = int(inomen[3:5]) + x = 0 + if (fuso > 0) and (fuso <= 60): + x = ((fuso - 30) * 6.0) - 6.0 return x except: - raise Exception(self.tr('Invalid inomen parameter!')) - - def getLLCorner(self,inomen): - """Get lower left coordinates for scale determined by the given map index - """ + raise Exception(self.tr("Invalid inomen parameter!")) + + def getLLCorner(self, inomen): + """Get lower left coordinates for scale determined by the given map index""" try: - x=self.getLLCornerLongitude1kk(inomen) - y=self.getLLCornerLatitude1kk(inomen) - inomenParts=inomen.upper().split('-') - #Escala de 500.00 - for partId in range(2,len(inomenParts)): - scaleId=partId-1 - dx=self.getSpacingX(self.scales[scaleId]) - dy=self.getSpacingY(self.scales[scaleId]) - scaleText=inomenParts[partId] - i,j=self.findScaleText(scaleText, partId-1) - x+=i*dx - y+=j*dy - return (x,y) + x = self.getLLCornerLongitude1kk(inomen) + y = self.getLLCornerLatitude1kk(inomen) + inomenParts = inomen.upper().split("-") + # Escala de 500.00 + for partId in range(2, len(inomenParts)): + scaleId = partId - 1 + dx = self.getSpacingX(self.scales[scaleId]) + dy = self.getSpacingY(self.scales[scaleId]) + scaleText = inomenParts[partId] + i, j = self.findScaleText(scaleText, partId - 1) + x += i * dx + y += j * dy + return (x, y) except: - raise Exception(self.tr('Invalid inomen parameter!')) - - def computeNumberOfSteps(self,startScaleId,stopScaleId): - """Compute the number of steps to build a progress - """ - steps=1 - for i in range(startScaleId+1,stopScaleId+1): - steps*=len(self.scaleText[i])*len(self.scaleText[i][0]) + raise Exception(self.tr("Invalid inomen parameter!")) + + def computeNumberOfSteps(self, startScaleId, stopScaleId): + """Compute the number of steps to build a progress""" + steps = 1 + for i in range(startScaleId + 1, stopScaleId + 1): + steps *= len(self.scaleText[i]) * len(self.scaleText[i][0]) return steps - + def createFrame(self, map_index, layer): stopScale = self.getScale(map_index) - + # Enter in edit mode layer.startEditing() self.populateQgsLayer(map_index, stopScale, layer) - # Commiting changes - layer.commitChanges() - + # Commiting changes + layer.commitChanges() + def createFrame(self, map_index, layer, stopScale): # Enter in edit mode layer.startEditing() self.populateQgsLayer(map_index, stopScale, layer) - # Commiting changes + # Commiting changes layer.commitChanges() - + def getQgsPolygonFrame(self, map_index, xSubdivisions, ySubdivisions): """Particular case used to create frame polygon for the given map_index @@ -237,44 +244,45 @@ def getQgsPolygonFrame(self, map_index, xSubdivisions, ySubdivisions): x + dx, y + dy, xSubdivisions=xSubdivisions, - ySubdivisions=ySubdivisions + ySubdivisions=ySubdivisions, ) return poly - + def populateQgsLayer(self, iNomen, stopScale, layer): """Generic recursive method to create frame polygon for the given stopScale within the given map index (iNomen) """ - scale = self.getScale(iNomen) - #first run - if (self.stepsTotal==0): - self.stepsTotal=self.computeNumberOfSteps(self.getScaleIdFromScale(scale), self.getScaleIdFromScale(stopScale)) - self.stepsDone=0 + scale = self.getScale(iNomen) + # first run + if self.stepsTotal == 0: + self.stepsTotal = self.computeNumberOfSteps( + self.getScaleIdFromScale(scale), self.getScaleIdFromScale(stopScale) + ) + self.stepsDone = 0 if scale == stopScale: (x, y) = self.getLLCorner(iNomen) dx = self.getSpacingX(stopScale) dy = self.getSpacingY(stopScale) poly = self.makeQgsPolygon(x, y, x + dx, y + dy) - + self.insertFrameIntoQgsLayer(layer, poly, iNomen) - - self.stepsDone+=1 + + self.stepsDone += 1 else: scaleId = self.getScaleIdFromiNomen(iNomen) - matrix = self.scaleText[ scaleId+1 ] - + matrix = self.scaleText[scaleId + 1] + for i in range(len(matrix)): line = matrix[i] for j in range(len(line)): - inomen2 = iNomen + '-' + line[j] + inomen2 = iNomen + "-" + line[j] self.populateQgsLayer(inomen2, stopScale, layer) - + def insertFrameIntoQgsLayer(self, layer, poly, map_index): - """Inserts the poly into layer - """ + """Inserts the poly into layer""" provider = layer.dataProvider() - #Creating the feature + # Creating the feature feature = QgsFeature() feature.initAttributes(1) feature.setAttribute(0, map_index) @@ -282,26 +290,26 @@ def insertFrameIntoQgsLayer(self, layer, poly, map_index): # Adding the feature into the file provider.addFeatures([feature]) - + def getMIdict(self): if not self.MIdict: self.MIdict = self.getDict("MI100.csv") return self.MIdict - + def getMIRdict(self): if not self.MIRdict: self.MIRdict = self.getDict("MIR250.csv") - return self.MIRdict - - def getDict(self, file_name): - csvFile = open(os.path.join(os.path.dirname(__file__),file_name)) + return self.MIRdict + + def getDict(self, file_name): + csvFile = open(os.path.join(os.path.dirname(__file__), file_name)) data = csvFile.readlines() csvFile.close() - l1 = [(x.strip()).split(';') for x in data] - dicionario = dict((a[1],a[0]) for a in l1) + l1 = [(x.strip()).split(";") for x in data] + dicionario = dict((a[1], a[0]) for a in l1) return dicionario - def getINomenFromMI(self,mi): + def getINomenFromMI(self, mi): mi = self.checkLeftPadding(mi, 4) inom = self.getINomen(self.getMIdict(), mi) exceptions = self.getMIexceptions() @@ -309,49 +317,49 @@ def getINomenFromMI(self,mi): return None return inom - def getINomenFromMIR(self,mir): + def getINomenFromMIR(self, mir): mir = self.checkLeftPadding(mir, 3) inom = self.getINomen(self.getMIRdict(), mir) exceptions = self.getMIexceptions() if inom in exceptions or self.checkContainedUpperLevel(inom, exceptions): return None return inom - + def getINomen(self, dict, index): - key = index.split('-')[0] - otherParts = index.split('-')[1:] - if (key in dict): - if len(otherParts)==0: + key = index.split("-")[0] + otherParts = index.split("-")[1:] + if key in dict: + if len(otherParts) == 0: return dict[key] else: - return dict[key]+'-'+'-'.join(otherParts) + return dict[key] + "-" + "-".join(otherParts) else: return None - - def getMIfromInom(self,inom): - return self.getMI(self.getMIdict(),inom) - + + def getMIfromInom(self, inom): + return self.getMI(self.getMIdict(), inom) + def getMI(self, miDict, inom): - parts = inom.split('-') - hundredInom = '-'.join(parts[0:5]) + parts = inom.split("-") + hundredInom = "-".join(parts[0:5]) remains = parts[5::] - for k,v in miDict.items(): + for k, v in miDict.items(): if v == hundredInom: - return '-'.join([k]+remains) - + return "-".join([k] + remains) + def getMIR(self, miDict, inom): - parts = inom.split('-') - hundredInom = '-'.join(parts[0:4]) + parts = inom.split("-") + hundredInom = "-".join(parts[0:4]) remains = parts[4::] - for k,v in miDict.items(): + for k, v in miDict.items(): if v == hundredInom: - return '-'.join([k]+remains) - + return "-".join([k] + remains) + def get_MI_MIR_from_inom(self, inom): exceptions = self.getMIexceptions() if inom in exceptions or self.checkContainedUpperLevel(inom, exceptions): return None - if len(inom.split('-')) > 4: + if len(inom.split("-")) > 4: return self.getMIfromInom(inom) else: return self.getMIR(self.getMIRdict(), inom) @@ -360,14 +368,14 @@ def get_INOM_from_lat_lon(self, lon, lat): """ Returns Inom with the nearest lower left lon lat. """ - INOM = 'N' if lat >= 0 else 'S' - INOM += string.ascii_uppercase[math.floor(abs(lat/4.)) % 26] + '-' - utm_zone = math.floor(31 + lon/6) - return INOM+str(utm_zone) - + INOM = "N" if lat >= 0 else "S" + INOM += string.ascii_uppercase[math.floor(abs(lat / 4.0)) % 26] + "-" + utm_zone = math.floor(31 + lon / 6) + return INOM + str(utm_zone) + def get_INOM_range_from_BB(self, xmin, ymin, xmax, ymax): """ - Returns a set of INOM that intersect bbRect formed by + Returns a set of INOM that intersect bbRect formed by xmin, xmax, ymin, ymax """ minInom = self.get_INOM_from_lat_lon(xmin, ymin) @@ -375,46 +383,52 @@ def get_INOM_range_from_BB(self, xmin, ymin, xmax, ymax): if minInom == maxInom: return list([minInom]) return self.get_INOM_range_from_min_max_inom(minInom, maxInom) - + def get_INOM_range_from_min_max_inom(self, minInom, maxInom): - minFuse = int(minInom.split('-')[-1]) - maxFuse = int(maxInom.split('-')[-1]) - fuseRange = map(str, range(minFuse,maxFuse+2,1)) + minFuse = int(minInom.split("-")[-1]) + maxFuse = int(maxInom.split("-")[-1]) + fuseRange = map(str, range(minFuse, maxFuse + 2, 1)) letterRange = self.get_letter_range(minInom, maxInom) - return list( - '-'.join(i) for i in itertools.product(letterRange, fuseRange) - ) + return list("-".join(i) for i in itertools.product(letterRange, fuseRange)) def get_letter_range(self, minInom, maxInom): - if minInom[0] == 'S' and maxInom[0] == 'N': - return self.get_letter_range('SA-XX', minInom) + self.get_letter_range('NA-XX', maxInom) + if minInom[0] == "S" and maxInom[0] == "N": + return self.get_letter_range("SA-XX", minInom) + self.get_letter_range( + "NA-XX", maxInom + ) else: startIndex = string.ascii_uppercase.index(minInom[1]) endIndex = string.ascii_uppercase.index(maxInom[1]) - multiplier = 1 if minInom[0] == 'N' else -1 + multiplier = 1 if minInom[0] == "N" else -1 return list( map( - lambda x: minInom[0]+x, - string.ascii_uppercase[min(startIndex, endIndex):max(startIndex, endIndex)+3:1] + lambda x: minInom[0] + x, + string.ascii_uppercase[ + min(startIndex, endIndex) : max(startIndex, endIndex) + 3 : 1 + ], ) )[::multiplier] - + @staticmethod def getMIexceptions(): - ''' + """ Returns a set of INOMs that don't have MI - ''' - pathCsvExceptions25k = os.path.join(os.path.dirname(__file__),'exclusionList25k.csv') - pathCsvExceptions50k = os.path.join(os.path.dirname(__file__),'exclusionList50k.csv') - with open(pathCsvExceptions25k, 'r') as file: + """ + pathCsvExceptions25k = os.path.join( + os.path.dirname(__file__), "exclusionList25k.csv" + ) + pathCsvExceptions50k = os.path.join( + os.path.dirname(__file__), "exclusionList50k.csv" + ) + with open(pathCsvExceptions25k, "r") as file: exceptions25k = [x[0] for x in csv.reader(file)] - with open(pathCsvExceptions50k, 'r') as file: + with open(pathCsvExceptions50k, "r") as file: exceptions50k = [x[0] for x in csv.reader(file)] return set((*exceptions25k, *exceptions50k)) @staticmethod def checkLeftPadding(mi, zeroes): - leftPart = mi.split('-')[0] + leftPart = mi.split("-")[0] if len(leftPart) < zeroes: return f'{"".join("0" for _ in range(zeroes-len(leftPart)))}{mi}' return mi @@ -422,13 +436,17 @@ def checkLeftPadding(mi, zeroes): @staticmethod def checkContainedUpperLevel(inom, exceptions): if isinstance(inom, str): - if '-'.join(inom.split('-')[:-1]) in exceptions: + if "-".join(inom.split("-")[:-1]) in exceptions: return True + if __name__ == "__main__": x = UtmGrid() - print(x.get_INOM_range_from_min_max_inom('SE-17','NC-22')) - print(x.get_INOM_range_from_min_max_inom('SC-17','SA-22')) + print(x.get_INOM_range_from_min_max_inom("SE-17", "NC-22")) + print(x.get_INOM_range_from_min_max_inom("SC-17", "SA-22")) print(x.get_INOM_range_from_BB(-83, -19, -49, 9)) - print(x.get_INOM_range_from_min_max_inom('SE-17','NC-22') == x.get_INOM_range_from_BB(-83, -19, -49, 9) ) - print(x.get_MI_MIR_from_inom('NB-20-Z-D-I-1')) + print( + x.get_INOM_range_from_min_max_inom("SE-17", "NC-22") + == x.get_INOM_range_from_BB(-83, -19, -49, 9) + ) + print(x.get_MI_MIR_from_inom("NB-20-Z-D-I-1")) diff --git a/DsgTools/core/Utils/threadingTools.py b/DsgTools/core/Utils/threadingTools.py new file mode 100644 index 000000000..d60c4c57d --- /dev/null +++ b/DsgTools/core/Utils/threadingTools.py @@ -0,0 +1,63 @@ +# -*- coding: utf-8 -*- +""" +/*************************************************************************** + DsgTools + A QGIS plugin + Brazilian Army Cartographic Production Tools + ------------------- + begin : 2023-04-17 + git sha : $Format:%H$ + copyright : (C) 2023 by Philipe Borba - Cartographic Engineer @ Brazilian Army + email : borba.philipe@eb.mil.br + ***************************************************************************/ +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ +""" + +import itertools + +import concurrent.futures +import itertools + + +def concurrently(handler, inputs, *, max_concurrency=5): + """ + Calls the function ``handler`` on the values ``inputs``. + + ``handler`` should be a function that takes a single input, which is the + individual values in the iterable ``inputs``. + + Generates (input, output) tuples as the calls to ``handler`` complete. + + See https://alexwlchan.net/2019/10/adventures-with-concurrent-futures/ for an explanation + of how this function works. + + """ + # Make sure we get a consistent iterator throughout, rather than + # getting the first element repeatedly. + handler_inputs = iter(inputs) + + with concurrent.futures.ThreadPoolExecutor() as executor: + futures = { + executor.submit(handler, input): input + for input in itertools.islice(handler_inputs, max_concurrency) + } + + while futures: + done, _ = concurrent.futures.wait( + futures, return_when=concurrent.futures.FIRST_COMPLETED + ) + + for fut in done: + original_input = futures.pop(fut) + yield fut.result() + + for input in itertools.islice(handler_inputs, len(done)): + fut = executor.submit(handler, input) + futures[fut] = input diff --git a/DsgTools/core/Utils/tools.py b/DsgTools/core/Utils/tools.py index 7504d5904..0ca38893a 100644 --- a/DsgTools/core/Utils/tools.py +++ b/DsgTools/core/Utils/tools.py @@ -24,7 +24,7 @@ """ Module designed to centralize the access to DSGTools tools. This module CANNOT be imported at the beginning of modules and must be called -from within methods that are NOT the __init__! +from within methods that are NOT the __init__! """ from DsgTools import dsgTools @@ -33,6 +33,7 @@ toolBoxManager = dsgTools.guiManager.productionToolsGuiManager.toolBoxesGuiManager toolBarManager = dsgTools.guiManager.productionToolsGuiManager.toolbarsGuiManager + def mapToolsNames(): """ Lists all non-i18n names for DSGTools map tools. @@ -45,9 +46,10 @@ def mapToolsNames(): "freeHandAcquisiton", "freeHandReshape", "labelTool", - "shortcutsTool" + "shortcutsTool", ] + def mapTools(): """ Lists all available map tools provided by DSGTools plugin. @@ -55,6 +57,7 @@ def mapTools(): """ return [getattr(mapToolManager, tn) for tn in mapToolsNames()] + def mapTool(name): """ Provides the map tool from DSGTools plugin through its non-i18n name. @@ -63,6 +66,7 @@ def mapTool(name): """ return getattr(mapToolManager, name) + def toolBarsNames(): """ Lists all non-i18n names for DSGTools tool bars. @@ -73,9 +77,10 @@ def toolBarsNames(): "inspectFeaturesTool", "styleManagerTool", "rasterInfoTool", - "dataValidationTool" + "dataValidationTool", ] + def toolBars(): """ Lists all available tool bars provided by DSGTools plugin. @@ -83,6 +88,7 @@ def toolBars(): """ return [getattr(toolBarManager, tn) for tn in toolBarsNames()] + def toolBar(name): """ Provides the tool bar from DSGTools plugin through its non-i18n name. @@ -91,18 +97,14 @@ def toolBar(name): """ return getattr(toolBarManager, name) + def toolBoxesNames(): """ Lists all non-i18n names for DSGTools tool boxes. :return: (list-of-str) list of non-i18n of all available tool boxes. """ - return [ - "qaToolBox", - "cfToolbox", - "calcContour", - "codeList", - "complexWindow" - ] + return ["qaToolBox", "cfToolbox", "calcContour", "codeList", "complexWindow"] + def toolBoxes(): """ @@ -111,6 +113,7 @@ def toolBoxes(): """ return [getattr(toolBoxManager, tn) for tn in toolBoxesNames()] + def toolBox(name): """ Provides the tool bar from DSGTools plugin through its non-i18n name. @@ -119,6 +122,7 @@ def toolBox(name): """ return getattr(toolBoxManager, name) + def toolsNames(): """ Lists all non-i18n names for DSGTools tools. @@ -126,6 +130,7 @@ def toolsNames(): """ return mapToolsNames() + toolBarsNames() + toolBoxesNames() + def tools(): """ List of all available DSGTools tools. @@ -133,6 +138,7 @@ def tools(): """ return mapTools() + toolBars() + toolBoxes() + def toolByName(name): """ Retrieve any of DSGTools its name. @@ -146,6 +152,7 @@ def toolByName(name): else: return toolBox(name) + def actions(): """ Retrieves all registered action on GuiManager. diff --git a/DsgTools/core/Utils/utils.py b/DsgTools/core/Utils/utils.py index 8b2ae31ed..30b24df67 100644 --- a/DsgTools/core/Utils/utils.py +++ b/DsgTools/core/Utils/utils.py @@ -36,7 +36,6 @@ class Utils(object): - def mergeDict(self, dictionary1, dictionary2): """ Merges two dictionaries @@ -55,11 +54,11 @@ def mergeDict(self, dictionary1, dictionary2): for i in value: if i not in output[item]: output[item].append(i) - output[item].extend(self.mergeDict( - value, dictionary2.pop(item))) + output[item].extend( + self.mergeDict(value, dictionary2.pop(item)) + ) else: - output[item] = self.mergeDict( - value, dictionary2.pop(item)) + output[item] = self.mergeDict(value, dictionary2.pop(item)) else: if type(value) == list: if item not in list(output.keys()): @@ -100,7 +99,8 @@ def buildOneNestedDict(self, inputDict, keyList, value): if len(list(inputDict.values())) == 0: inputDict[keyList[0]] = dict() inputDict[keyList[0]] = self.buildOneNestedDict( - inputDict[keyList[0]], keyList[1::], value) + inputDict[keyList[0]], keyList[1::], value + ) return inputDict def buildNestedDict(self, inputDict, keyList, value): @@ -118,7 +118,7 @@ def readJsonFile(self, filename, returnFileAndDict=False): Reads a json file and makes a dictionary """ try: - file = open(filename, 'r') + file = open(filename, "r") data = file.read() fileDict = json.loads(data) file.close() @@ -131,19 +131,19 @@ def readJsonFile(self, filename, returnFileAndDict=False): def parseStyle(self, qml): qml = qml.replace("''", "'") - if '.qml' in qml: + if ".qml" in qml: doc = parse(qml) else: try: doc = parseString(qml) except: - doc = parseString(qml.encode('utf-8')) - forbiddenList = doc.getElementsByTagName('edittypes') + doc = parseString(qml.encode("utf-8")) + forbiddenList = doc.getElementsByTagName("edittypes") if len(forbiddenList) > 0: forbiddenNode = forbiddenList[0] - qgisNode = doc.getElementsByTagName('qgis')[0] + qgisNode = doc.getElementsByTagName("qgis")[0] qgisNode.removeChild(forbiddenNode) - return doc.toxml().replace('', '') + return doc.toxml().replace('', "") def parseMultiQml(self, qmlPath, lyrList): """ @@ -152,14 +152,18 @@ def parseMultiQml(self, qmlPath, lyrList): refDict = dict() for lyr in lyrList: try: - qml = os.path.join(qmlPath, lyr + '.qml') + qml = os.path.join(qmlPath, lyr + ".qml") doc = parse(qml) refDict[lyr] = dict() - for node in doc.getElementsByTagName('edittype'): - if node.getAttribute('widgetv2type') in ('ValueMap', 'ValueRelation'): - attrName = node.getAttribute('name') + for node in doc.getElementsByTagName("edittype"): + if node.getAttribute("widgetv2type") in ( + "ValueMap", + "ValueRelation", + ): + attrName = node.getAttribute("name") refDict[lyr][attrName] = node.getElementsByTagName( - 'widgetv2config')[0].getAttribute('Layer') + "widgetv2config" + )[0].getAttribute("Layer") except: pass return refDict @@ -175,13 +179,14 @@ def parseMultiFromDb(self, qmlRecordDict, lyrList): try: doc = parseString(qml) except: - doc = parseString(qml.encode('utf-8')) + doc = parseString(qml.encode("utf-8")) refDict[lyr] = dict() - for node in doc.getElementsByTagName('edittype'): - if node.getAttribute('widgetv2type') == 'ValueRelation': - attrName = node.getAttribute('name') + for node in doc.getElementsByTagName("edittype"): + if node.getAttribute("widgetv2type") == "ValueRelation": + attrName = node.getAttribute("name") refDict[lyr][attrName] = node.getElementsByTagName( - 'widgetv2config')[0].getAttribute('Layer') + "widgetv2config" + )[0].getAttribute("Layer") except: pass return refDict @@ -198,8 +203,7 @@ def getRecursiveInheritanceTreeDict(self, parent, resultDict, inhDict): resultDict[parent] = dict() if parent in list(inhDict.keys()): for child in inhDict[parent]: - self.getRecursiveInheritanceTreeDict( - child, resultDict[parent], inhDict) + self.getRecursiveInheritanceTreeDict(child, resultDict[parent], inhDict) def find_all_paths(self, graph, start, end, path=[]): path = path + [start] @@ -235,21 +239,20 @@ def createWidgetItem(self, parent, text, column=None): def createTreeWidgetFromDict(self, parentNode, inputDict, treeWidget, column): for key in list(inputDict.keys()): item = self.createWidgetItem(parentNode, key, column) - self.createTreeWidgetFromDict( - item, inputDict[key], treeWidget, column) + self.createTreeWidgetFromDict(item, inputDict[key], treeWidget, column) def getTreeBranchFromNode(self, startNode, inputDict): - if 'root' not in list(inputDict.keys()): - graph = {'root': inputDict} + if "root" not in list(inputDict.keys()): + graph = {"root": inputDict} else: graph = inputDict - path = self.find_all_paths(graph, 'root', startNode)[0] + path = self.find_all_paths(graph, "root", startNode)[0] for node in path: graph = graph[node] return {startNode: graph} def getNodeLineage(self, node, inputDict): - return self.find_all_paths(inputDict, 'root', node)[0][1::] + return self.find_all_paths(inputDict, "root", node)[0][1::] def instantiateJsonDict(self, jsonDict): if isinstance(jsonDict, dict): @@ -262,7 +265,7 @@ def deleteQml(self, tempQml): Deletes a file from a given dir, if it's a QML file. """ try: - if tempQml[-4:].lower() == '.qml': + if tempQml[-4:].lower() == ".qml": try: os.remove(tempQml) except: @@ -274,7 +277,7 @@ def deleteQml(self, tempQml): return False def get_proxy_config(self): - """ Get proxy config from QSettings and builds proxy parameters + """Get proxy config from QSettings and builds proxy parameters :return: dictionary of transfer protocols mapped to addresses, also authentication if set in QSettings :rtype: (dict, requests.auth.HTTPProxyAuth) or (dict, None) """ @@ -282,31 +285,34 @@ def get_proxy_config(self): proxy_dict = {} if enabled and host: - port_str = str(port) if port else '' - for protocol in ['http', 'https', 'ftp']: - proxy_dict[protocol] = '{}://{}:{}'.format( - protocol, host, port_str) + port_str = str(port) if port else "" + for protocol in ["http", "https", "ftp"]: + proxy_dict[protocol] = "{}://{}:{}".format(protocol, host, port_str) - auth = requests.auth.HTTPProxyAuth( - user, password) if enabled and user and password else None + auth = ( + requests.auth.HTTPProxyAuth(user, password) + if enabled and user and password + else None + ) return proxy_dict, auth @staticmethod def get_proxy_from_qsettings(): - """ Gets the proxy configuration from QSettings + """Gets the proxy configuration from QSettings :return: Proxy settings: flag specifying if proxy is enabled, host, port, user and password :rtype: tuple(str) """ settings = QSettings() - settings.beginGroup('proxy') - enabled = str(settings.value('proxyEnabled')).lower( - ) == 'true' # to be compatible with QGIS 2 and 3 + settings.beginGroup("proxy") + enabled = ( + str(settings.value("proxyEnabled")).lower() == "true" + ) # to be compatible with QGIS 2 and 3 # proxy_type = settings.value("proxyType") - host = settings.value('proxyHost') - port = settings.value('proxyPort') - user = settings.value('proxyUser') - password = settings.value('proxyPassword') + host = settings.value("proxyHost") + port = settings.value("proxyPort") + user = settings.value("proxyUser") + password = settings.value("proxyPassword") settings.endGroup() return enabled, host, port, user, password @@ -375,11 +381,7 @@ def fieldIsInt(self, field): :param field: (QgsField) field to be checked. :return: (bool) if data is a whole number. """ - intTypes = [ - QVariant.Int, - QVariant.UInt, - QVariant.LongLong, - QVariant.ULongLong] + intTypes = [QVariant.Int, QVariant.UInt, QVariant.LongLong, QVariant.ULongLong] return field.type() in intTypes def fieldIsNumeric(self, field): @@ -419,8 +421,7 @@ def raiseIfaceMessage(self, title, msg, level=None, duration=None): """ level = Qgis.Info if level is None else level duration = 3 if duration is None else duration - iface.messageBar().pushMessage( - title, msg, level=level, duration=duration) + iface.messageBar().pushMessage(title, msg, level=level, duration=duration) def logMessage(self, msg, level=None): """ @@ -429,7 +430,7 @@ def logMessage(self, msg, level=None): :param level: (int) level code (warning, critical, etc). """ level = Qgis.Info if level is None else level - QgsMessageLog.logMessage(msg, 'DSGTools Plugin', level) + QgsMessageLog.logMessage(msg, "DSGTools Plugin", level) def confirmAction(self, parent, msg, title=None, showNo=True): """ @@ -441,15 +442,20 @@ def confirmAction(self, parent, msg, title=None, showNo=True): """ title = title or self.tr("Confirm action") if showNo: - return QMessageBox.question( - parent, title, msg, QMessageBox.Yes | QMessageBox.No - ) == QMessageBox.Yes + return ( + QMessageBox.question( + parent, title, msg, QMessageBox.Yes | QMessageBox.No + ) + == QMessageBox.Yes + ) else: - return QMessageBox.question( - parent, title, msg, QMessageBox.Ok) == QMessageBox.Ok + return ( + QMessageBox.question(parent, title, msg, QMessageBox.Ok) + == QMessageBox.Ok + ) -class ValidateImportedDataMethods(): +class ValidateImportedDataMethods: """ Docstring. """ @@ -462,7 +468,7 @@ def validateQColor(self, colorToEvaluate): This method receives a string and evaluate if its an valid QColor. """ - colorStrWithoutSpaces = re.sub(r'\s', '', str(colorToEvaluate)) + colorStrWithoutSpaces = re.sub(r"\s", "", str(colorToEvaluate)) hexColor = re.search(r"^#[0-9a-fA-F]{3,6}$", colorStrWithoutSpaces) listColor = re.search(r"\d{1,3},\d{1,3},\d{1,3}", colorStrWithoutSpaces) @@ -472,7 +478,7 @@ def validateQColor(self, colorToEvaluate): return True elif listColor is not None: color = listColor[0].split(",") - rgb = QColor(int(color[0]),int(color[1]),int(color[2])) + rgb = QColor(int(color[0]), int(color[1]), int(color[2])) if rgb.isValid(): return True return False @@ -518,13 +524,16 @@ def showLoadingMsg(self, lyrList=None, msgType=None): if lyrList and msgType == "invalid": msg.setIcon(QMessageBox.Critical) msg.setText("Some rules has invalid itens!") - msg.setInformativeText("If you ignore, the invalid rules may not be loaded.") + msg.setInformativeText( + "If you ignore, the invalid rules may not be loaded." + ) textLyrList = sorted(set(lyrList)) formatedLyrList = ["{}" for item in textLyrList] msgString = ",".join(formatedLyrList).replace(",", "\n") - formatedMsgString = "The following rules are not valid:\n" + \ - msgString.format(*textLyrList) + formatedMsgString = ( + "The following rules are not valid:\n" + msgString.format(*textLyrList) + ) msg.setDetailedText(formatedMsgString) msg.setStandardButtons(QMessageBox.Ignore | QMessageBox.Cancel) diff --git a/DsgTools/core/dsgEnums.py b/DsgTools/core/dsgEnums.py index 1d5542c51..959260815 100644 --- a/DsgTools/core/dsgEnums.py +++ b/DsgTools/core/dsgEnums.py @@ -22,18 +22,56 @@ """ from builtins import range from builtins import object + + class DsgEnums(object): - #generic manager and database enumerate + # generic manager and database enumerate Property, Database = list(range(2)) - #generic validation property + # generic validation property ProcessName, ClassName = list(range(2)) - #property enum - PermissionProperty, FieldToolboxProperty, EarthCoverageProperty, AttributeRuleProperty, SpatialRuleProperty, ValidationWorkflowProperty = list(range(6)) + # property enum + ( + PermissionProperty, + FieldToolboxProperty, + EarthCoverageProperty, + AttributeRuleProperty, + SpatialRuleProperty, + ValidationWorkflowProperty, + ) = list(range(6)) # datasource selection widgets enum - NoDriver, PostGIS, NewPostGIS, SpatiaLite, NewSpatiaLite, Shapefile, NewShapefile, Geopackage, NewGeopackage = list(range(9)) + ( + NoDriver, + PostGIS, + NewPostGIS, + SpatiaLite, + NewSpatiaLite, + Shapefile, + NewShapefile, + Geopackage, + NewGeopackage, + ) = list(range(9)) # node types enum - Flag, Sink, WaterwayBegin, UpHillNode, DownHillNode, Confluence, Ramification, AttributeChange, NodeNextToWaterBody, AttributeChangeFlag, NodeOverload, DisconnectedLine = list(range(12)) + ( + Flag, + Sink, + WaterwayBegin, + UpHillNode, + DownHillNode, + Confluence, + Ramification, + AttributeChange, + NodeNextToWaterBody, + AttributeChangeFlag, + NodeOverload, + DisconnectedLine, + ) = list(range(12)) # available drivers enum - DriverPostGIS, DriverSpatiaLite, DriverGeopackage, DriverShapefile, DriverOthers = list(range(5)) + ( + DriverPostGIS, + DriverSpatiaLite, + DriverGeopackage, + DriverShapefile, + DriverOthers, + ) = list(range(5)) # conversion modes available in Conversion Dataset Tool FlexibleConversion, StrictConversion = 1, 2 diff --git a/DsgTools/dsg_tools.py b/DsgTools/dsg_tools.py index a1c1e3ea4..0bafa1906 100644 --- a/DsgTools/dsg_tools.py +++ b/DsgTools/dsg_tools.py @@ -39,9 +39,12 @@ from qgis.core import QgsApplication from .gui.guiManager import GuiManager -from .core.DSGToolsProcessingAlgs.dsgtoolsProcessingAlgorithmProvider import DSGToolsProcessingAlgorithmProvider +from .core.DSGToolsProcessingAlgs.dsgtoolsProcessingAlgorithmProvider import ( + DSGToolsProcessingAlgorithmProvider, +) from .Modules.acquisitionMenu.controllers.acquisitionMenuCtrl import AcquisitionMenuCtrl + class DsgTools(object): """QGIS Plugin Implementation.""" @@ -56,25 +59,24 @@ def __init__(self, iface): # initialize plugin directory self.plugin_dir = os.path.dirname(__file__) # initialize locale - locale = QSettings().value('locale/userLocale')[0:2] + locale = QSettings().value("locale/userLocale")[0:2] locale_path = os.path.join( - self.plugin_dir, - 'i18n', - 'DsgTools_{}.qm'.format(locale)) + self.plugin_dir, "i18n", "DsgTools_{}.qm".format(locale) + ) if os.path.exists(locale_path): self.translator = QTranslator() self.translator.load(locale_path) - if qVersion() > '4.3.3': + if qVersion() > "4.3.3": QCoreApplication.installTranslator(self.translator) # Create the dialog (after translation) and keep reference # Declare instance attributes self.actions = [] - self.menu = '&DSGTools' - self.toolbar = self.iface.addToolBar(u'DsgTools') - self.toolbar.setObjectName(u'DsgTools') + self.menu = "&DSGTools" + self.toolbar = self.iface.addToolBar("DsgTools") + self.toolbar.setObjectName("DsgTools") self.dsgTools = None self.menuBar = self.iface.mainWindow().menuBar() @@ -90,7 +92,7 @@ def tr(self, message): :rtype: QString """ # noinspection PyTypeChecker,PyArgumentList,PyCallByClass - return QCoreApplication.translate('DsgTools', message) + return QCoreApplication.translate("DsgTools", message) def unload(self): """ @@ -98,9 +100,7 @@ def unload(self): """ self.guiManager.unload() for action in self.actions: - self.iface.removePluginMenu( - '&DSGTools', - action) + self.iface.removePluginMenu("&DSGTools", action) self.iface.removeToolBarIcon(action) self.iface.unregisterMainWindowAction(action) @@ -117,14 +117,18 @@ def initGui(self): """ self.dsgTools = QMenu(self.iface.mainWindow()) - self.dsgTools.setObjectName(u'DsgTools') - self.dsgTools.setTitle(u'DSGTools') - self.menuBar.insertMenu(self.iface.firstRightStandardMenu().menuAction(), self.dsgTools) - #GuiManager - self.guiManager = GuiManager(self.iface, parentMenu = self.dsgTools, toolbar = self.toolbar) + self.dsgTools.setObjectName("DsgTools") + self.dsgTools.setTitle("DSGTools") + self.menuBar.insertMenu( + self.iface.firstRightStandardMenu().menuAction(), self.dsgTools + ) + # GuiManager + self.guiManager = GuiManager( + self.iface, parentMenu=self.dsgTools, toolbar=self.toolbar + ) self.guiManager.initGui() - #provider + # provider QgsApplication.processingRegistry().addProvider(self.provider) def getAcquisitionMenu(self): - return AcquisitionMenuCtrl() \ No newline at end of file + return AcquisitionMenuCtrl() diff --git a/DsgTools/gui/AboutAndFurtherInfo/Options/options.py b/DsgTools/gui/AboutAndFurtherInfo/Options/options.py index e6bdb9e9b..983c63352 100644 --- a/DsgTools/gui/AboutAndFurtherInfo/Options/options.py +++ b/DsgTools/gui/AboutAndFurtherInfo/Options/options.py @@ -23,8 +23,13 @@ from builtins import range import os from os.path import expanduser -from DsgTools.core.DSGToolsProcessingAlgs.Algs.LayerManagementAlgs.spellChecker.datasets.ptBR import PalavrasFileConfig, WordDatasetPtBRFileConfig -from DsgTools.core.NetworkTools.ExternalFilesHandler import ExternalFileDownloadProcessor +from DsgTools.core.DSGToolsProcessingAlgs.Algs.LayerManagementAlgs.spellChecker.datasets.ptBR import ( + PalavrasFileConfig, + WordDatasetPtBRFileConfig, +) +from DsgTools.core.NetworkTools.ExternalFilesHandler import ( + ExternalFileDownloadProcessor, +) from processing.modeler.ModelerUtils import ModelerUtils from qgis.PyQt import uic @@ -33,19 +38,21 @@ from qgis.utils import iface -FORM_CLASS, _ = uic.loadUiType(os.path.join( - os.path.dirname(__file__), 'options.ui')) +FORM_CLASS, _ = uic.loadUiType(os.path.join(os.path.dirname(__file__), "options.ui")) + class Options(QDialog, FORM_CLASS): - __dsgToolsModelPath__ = os.path.abspath(os.path.join( - os.path.dirname(__file__), "..", "..", "..", "core", "Misc", "QGIS_Models" - )) + __dsgToolsModelPath__ = os.path.abspath( + os.path.join( + os.path.dirname(__file__), "..", "..", "..", "core", "Misc", "QGIS_Models" + ) + ) __qgisModelPath__ = ModelerUtils.modelsFolders()[0] # # some options signals # modelPathChanged = pyqtSignal() - def __init__(self, parent = None): + def __init__(self, parent=None): """Constructor.""" super(Options, self).__init__(parent) self.setupUi(self) @@ -57,17 +64,24 @@ def __init__(self, parent = None): @pyqtSlot(bool) def on_addPushButton_clicked(self): newValue = self.addParameterLineEdit.text() - valueList = [self.blackListWidget.itemAt(i,0).text() for i in range(self.blackListWidget.count())] - if newValue == '': - QMessageBox.warning(self, self.tr('Warning!'), self.tr('Fill in a value before adding!')) + valueList = [ + self.blackListWidget.itemAt(i, 0).text() + for i in range(self.blackListWidget.count()) + ] + if newValue == "": + QMessageBox.warning( + self, self.tr("Warning!"), self.tr("Fill in a value before adding!") + ) return if newValue in valueList: - QMessageBox.warning(self, self.tr('Warning!'), self.tr('Value already in black list!')) + QMessageBox.warning( + self, self.tr("Warning!"), self.tr("Value already in black list!") + ) return self.blackListWidget.addItem(newValue) self.blackListWidget.sortItems(order=Qt.AscendingOrder) - self.addParameterLineEdit.setText('') - + self.addParameterLineEdit.setText("") + def getParameters(self): freeHandTolerance = self.toleranceQgsDoubleSpinBox.value() freeHandSmoothIterations = self.smoothIterationsQgsSpinBox.value() @@ -75,32 +89,70 @@ def getParameters(self): algIterations = self.algIterationsQgsSpinBox.value() minSegmentDistance = self.minSegmentDistanceQgsSpinBox.value() rightAngleDecimals = self.rightAngleDecimalsQgsSpinBox.value() - valueList = [self.blackListWidget.item(i).text() for i in range(self.blackListWidget.count())] + valueList = [ + self.blackListWidget.item(i).text() + for i in range(self.blackListWidget.count()) + ] undoPoints = self.undoQgsSpinBox.value() decimals = self.decimalQgsSpinBox.value() freeHandFinalSimplifyTolerance = self.finalToleranceQgsDoubleSpinBox.value() - return (freeHandTolerance, freeHandSmoothIterations, freeHandSmoothOffset, algIterations, minSegmentDistance, rightAngleDecimals, valueList, undoPoints, decimals, freeHandFinalSimplifyTolerance) + return ( + freeHandTolerance, + freeHandSmoothIterations, + freeHandSmoothOffset, + algIterations, + minSegmentDistance, + rightAngleDecimals, + valueList, + undoPoints, + decimals, + freeHandFinalSimplifyTolerance, + ) def loadParametersFromConfig(self): settings = QSettings() - settings.beginGroup('PythonPlugins/DsgTools/Options') - freeHandTolerance = settings.value('freeHandTolerance') - freeHandSmoothIterations = settings.value('freeHandSmoothIterations') - freeHandSmoothOffset = settings.value('freeHandSmoothOffset') - algIterations = settings.value('algIterations') - minSegmentDistance = settings.value('minSegmentDistance') - rightAngleDecimals = settings.value('rightAngleDecimals') - valueList = settings.value('valueList') - undoPoints = settings.value('undoPoints') - decimals = settings.value('decimals') - freeHandFinalSimplifyTolerance = settings.value('freeHandFinalSimplifyTolerance') + settings.beginGroup("PythonPlugins/DsgTools/Options") + freeHandTolerance = settings.value("freeHandTolerance") + freeHandSmoothIterations = settings.value("freeHandSmoothIterations") + freeHandSmoothOffset = settings.value("freeHandSmoothOffset") + algIterations = settings.value("algIterations") + minSegmentDistance = settings.value("minSegmentDistance") + rightAngleDecimals = settings.value("rightAngleDecimals") + valueList = settings.value("valueList") + undoPoints = settings.value("undoPoints") + decimals = settings.value("decimals") + freeHandFinalSimplifyTolerance = settings.value( + "freeHandFinalSimplifyTolerance" + ) if valueList: - valueList = valueList.split(';') + valueList = valueList.split(";") settings.endGroup() - return (freeHandTolerance, freeHandSmoothIterations, freeHandSmoothOffset, algIterations, minSegmentDistance, rightAngleDecimals, valueList, undoPoints, decimals, freeHandFinalSimplifyTolerance) - + return ( + freeHandTolerance, + freeHandSmoothIterations, + freeHandSmoothOffset, + algIterations, + minSegmentDistance, + rightAngleDecimals, + valueList, + undoPoints, + decimals, + freeHandFinalSimplifyTolerance, + ) + def setInterfaceWithParametersFromConfig(self): - (freeHandTolerance, freeHandSmoothIterations, freeHandSmoothOffset, algIterations, minSegmentDistance, rightAngleDecimals, valueList, undoPoints, decimals, freeHandFinalSimplifyTolerance) = self.loadParametersFromConfig() + ( + freeHandTolerance, + freeHandSmoothIterations, + freeHandSmoothOffset, + algIterations, + minSegmentDistance, + rightAngleDecimals, + valueList, + undoPoints, + decimals, + freeHandFinalSimplifyTolerance, + ) = self.loadParametersFromConfig() if freeHandTolerance: self.toleranceQgsDoubleSpinBox.setValue(float(freeHandTolerance)) if freeHandSmoothIterations: @@ -116,36 +168,51 @@ def setInterfaceWithParametersFromConfig(self): if valueList: self.blackListWidget.clear() self.blackListWidget.addItems(valueList) - self.blackListWidget.sortItems(order = Qt.AscendingOrder) + self.blackListWidget.sortItems(order=Qt.AscendingOrder) if undoPoints: self.undoQgsSpinBox.setValue(int(undoPoints)) if decimals: self.decimalQgsSpinBox.setValue(int(decimals)) if freeHandFinalSimplifyTolerance: - self.finalToleranceQgsDoubleSpinBox.setValue(float(freeHandFinalSimplifyTolerance)) - + self.finalToleranceQgsDoubleSpinBox.setValue( + float(freeHandFinalSimplifyTolerance) + ) + def storeParametersInConfig(self): - (freeHandTolerance, freeHandSmoothIterations, freeHandSmoothOffset, algIterations, minSegmentDistance, rightAngleDecimals, valueList, undoPoints, decimals, freeHandFinalSimplifyTolerance) = self.getParameters() + ( + freeHandTolerance, + freeHandSmoothIterations, + freeHandSmoothOffset, + algIterations, + minSegmentDistance, + rightAngleDecimals, + valueList, + undoPoints, + decimals, + freeHandFinalSimplifyTolerance, + ) = self.getParameters() settings = QSettings() - settings.beginGroup('PythonPlugins/DsgTools/Options') - settings.setValue('freeHandTolerance', freeHandTolerance) - settings.setValue('freeHandSmoothIterations', freeHandSmoothIterations) - settings.setValue('freeHandSmoothOffset', freeHandSmoothOffset) - settings.setValue('algIterations', algIterations) - settings.setValue('minSegmentDistance', minSegmentDistance) - settings.setValue('rightAngleDecimals', rightAngleDecimals) - settings.setValue('valueList', ';'.join(valueList)) - settings.setValue('undoPoints', undoPoints) - settings.setValue('decimals', decimals) - settings.setValue('freeHandFinalSimplifyTolerance', freeHandFinalSimplifyTolerance) + settings.beginGroup("PythonPlugins/DsgTools/Options") + settings.setValue("freeHandTolerance", freeHandTolerance) + settings.setValue("freeHandSmoothIterations", freeHandSmoothIterations) + settings.setValue("freeHandSmoothOffset", freeHandSmoothOffset) + settings.setValue("algIterations", algIterations) + settings.setValue("minSegmentDistance", minSegmentDistance) + settings.setValue("rightAngleDecimals", rightAngleDecimals) + settings.setValue("valueList", ";".join(valueList)) + settings.setValue("undoPoints", undoPoints) + settings.setValue("decimals", decimals) + settings.setValue( + "freeHandFinalSimplifyTolerance", freeHandFinalSimplifyTolerance + ) settings.endGroup() - + @pyqtSlot() def on_buttonBox_accepted(self): self.storeParametersInConfig() self.updateValidationToolbarConfig() self.close() - + @pyqtSlot(bool) def on_removePushButton_clicked(self): selectedItems = self.blackListWidget.selectedItems() @@ -156,10 +223,30 @@ def on_removePushButton_clicked(self): idxList.sort(reverse=True) for i in idxList: self.blackListWidget.takeItem(i) - + def firstTimeConfig(self): - (freeHandTolerance, freeHandSmoothIterations, freeHandSmoothOffset, algIterations, minSegmentDistance, rightAngleDecimals, valueList, undoPoints, decimals, freeHandFinalSimplifyTolerance) = self.loadParametersFromConfig() - if not (freeHandTolerance and freeHandSmoothIterations and freeHandSmoothOffset and algIterations and valueList and undoPoints and decimals is not None and freeHandFinalSimplifyTolerance is not None): + ( + freeHandTolerance, + freeHandSmoothIterations, + freeHandSmoothOffset, + algIterations, + minSegmentDistance, + rightAngleDecimals, + valueList, + undoPoints, + decimals, + freeHandFinalSimplifyTolerance, + ) = self.loadParametersFromConfig() + if not ( + freeHandTolerance + and freeHandSmoothIterations + and freeHandSmoothOffset + and algIterations + and valueList + and undoPoints + and decimals is not None + and freeHandFinalSimplifyTolerance is not None + ): self.storeParametersInConfig() def setupModelPath(self): @@ -167,10 +254,9 @@ def setupModelPath(self): Clears all model paths and leaves the default options. """ self.modelPathComboBox.clear() - self.modelPathComboBox.addItems([ - self.__dsgToolsModelPath__, - self.__qgisModelPath__ - ]) + self.modelPathComboBox.addItems( + [self.__dsgToolsModelPath__, self.__qgisModelPath__] + ) def setupValidationToolbarConfig(self): """ @@ -179,26 +265,34 @@ def setupValidationToolbarConfig(self): # reset combo box to default as well self.setupModelPath() settings = QSettings() - settings.beginGroup('PythonPlugins/DsgTools/Options') - if settings.value('loadModelOutput') is None: - settings.setValue('loadModelOutput', True) - self.loadModelOutputCheckBox.setChecked(settings.value('loadModelOutput') in (True, "true")) - if settings.value('checkBeforeRunModel') is None: - settings.setValue('checkBeforeRunModel', True) - self.checkBeforeRunModelCheckBox.setChecked(settings.value('checkBeforeRunModel') in (True, "true")) - if settings.value('removeModelsOnExit') is None: - settings.setValue('', False) - self.resetModelsCheckBox.setChecked(settings.value('removeModelsOnExit') in (True, "true")) - if settings.value('removeModelsOnNewProject') is None: - settings.setValue('removeModelsOnNewProject', False) - self.removeModelsProjectCheckBox.setChecked(settings.value('removeModelsOnNewProject') in (True, "true")) - if settings.value('defaultModelPath') is None: - settings.setValue('defaultModelPath', self.modelPathComboBox.currentText()) - idx = self.modelPathComboBox.findText(settings.value('defaultModelPath')) + settings.beginGroup("PythonPlugins/DsgTools/Options") + if settings.value("loadModelOutput") is None: + settings.setValue("loadModelOutput", True) + self.loadModelOutputCheckBox.setChecked( + settings.value("loadModelOutput") in (True, "true") + ) + if settings.value("checkBeforeRunModel") is None: + settings.setValue("checkBeforeRunModel", True) + self.checkBeforeRunModelCheckBox.setChecked( + settings.value("checkBeforeRunModel") in (True, "true") + ) + if settings.value("removeModelsOnExit") is None: + settings.setValue("", False) + self.resetModelsCheckBox.setChecked( + settings.value("removeModelsOnExit") in (True, "true") + ) + if settings.value("removeModelsOnNewProject") is None: + settings.setValue("removeModelsOnNewProject", False) + self.removeModelsProjectCheckBox.setChecked( + settings.value("removeModelsOnNewProject") in (True, "true") + ) + if settings.value("defaultModelPath") is None: + settings.setValue("defaultModelPath", self.modelPathComboBox.currentText()) + idx = self.modelPathComboBox.findText(settings.value("defaultModelPath")) if idx < 0: - self.modelPathComboBox.addItem(settings.value('defaultModelPath')) - self.modelPathComboBox.setCurrentText(settings.value('defaultModelPath')) - settings.endGroup() + self.modelPathComboBox.addItem(settings.value("defaultModelPath")) + self.modelPathComboBox.setCurrentText(settings.value("defaultModelPath")) + settings.endGroup() def validationToolbarConfig(self): """ @@ -206,19 +300,19 @@ def validationToolbarConfig(self): :return: (dict) set of parameters for Validation Toolbar. """ settings = QSettings() - settings.beginGroup('PythonPlugins/DsgTools/Options') - loadModelOutput = settings.value('loadModelOutput') - checkBeforeRunModel = settings.value('checkBeforeRunModel') - removeModelsOnExit = settings.value('removeModelsOnExit') - removeModelsOnNewProject = settings.value('removeModelsOnNewProject') - defaultModelPath = settings.value('defaultModelPath') + settings.beginGroup("PythonPlugins/DsgTools/Options") + loadModelOutput = settings.value("loadModelOutput") + checkBeforeRunModel = settings.value("checkBeforeRunModel") + removeModelsOnExit = settings.value("removeModelsOnExit") + removeModelsOnNewProject = settings.value("removeModelsOnNewProject") + defaultModelPath = settings.value("defaultModelPath") settings.endGroup() return { - "loadModelOutput" : loadModelOutput in (True, "true"), - "checkBeforeRunModel" : checkBeforeRunModel in (True, "true"), - "removeModelsOnExit" : removeModelsOnExit in (True, "true"), - "removeModelsOnNewProject" : removeModelsOnNewProject in (True, "true"), - "defaultModelPath" : defaultModelPath + "loadModelOutput": loadModelOutput in (True, "true"), + "checkBeforeRunModel": checkBeforeRunModel in (True, "true"), + "removeModelsOnExit": removeModelsOnExit in (True, "true"), + "removeModelsOnNewProject": removeModelsOnNewProject in (True, "true"), + "defaultModelPath": defaultModelPath, } def updateValidationToolbarConfig(self): @@ -226,14 +320,18 @@ def updateValidationToolbarConfig(self): Updates current Validation Toolbar parameter values from GUI. """ settings = QSettings() - settings.beginGroup('PythonPlugins/DsgTools/Options') - settings.setValue('loadModelOutput', self.loadModelOutputCheckBox.isChecked()) - settings.setValue('checkBeforeRunModel', self.checkBeforeRunModelCheckBox.isChecked()) - settings.setValue('removeModelsOnExit', self.resetModelsCheckBox.isChecked()) - settings.setValue('removeModelsOnNewProject', self.removeModelsProjectCheckBox.isChecked()) + settings.beginGroup("PythonPlugins/DsgTools/Options") + settings.setValue("loadModelOutput", self.loadModelOutputCheckBox.isChecked()) + settings.setValue( + "checkBeforeRunModel", self.checkBeforeRunModelCheckBox.isChecked() + ) + settings.setValue("removeModelsOnExit", self.resetModelsCheckBox.isChecked()) + settings.setValue( + "removeModelsOnNewProject", self.removeModelsProjectCheckBox.isChecked() + ) # oldModelPath = settings.value('defaultModelPath') # newModelPath = self.modelPathComboBox.currentText() - settings.setValue('defaultModelPath', self.modelPathComboBox.currentText()) + settings.setValue("defaultModelPath", self.modelPathComboBox.currentText()) settings.endGroup() # if oldModelPath != newModelPath: # self.modelPathChanged.emit() @@ -245,7 +343,10 @@ def addNewModelPath(self, modelPath, setAsDefault=True): :param setAsDefault: (bool) whether current selection should be updated to new model path. :return: (int) index for new model path on its selection combo box. """ - if not os.path.exists(modelPath) or self.modelPathComboBox.findText(modelPath) >= 0: + if ( + not os.path.exists(modelPath) + or self.modelPathComboBox.findText(modelPath) >= 0 + ): return -1 self.modelPathComboBox.addItem(modelPath) idx = self.modelPathComboBox.findText(modelPath) @@ -260,10 +361,14 @@ def setCustomModelPath(self): """ fd = QFileDialog() newModelPath = fd.getExistingDirectory( - caption=self.tr('Select a directory for DSGTools Validation' - ' Toolbar to look for QGIS Processing models') + caption=self.tr( + "Select a directory for DSGTools Validation" + " Toolbar to look for QGIS Processing models" + ) + ) + newModelPath = ( + newModelPath[0] if isinstance(newModelPath, tuple) else newModelPath ) - newModelPath = newModelPath[0] if isinstance(newModelPath, tuple) else newModelPath if not newModelPath: return - self.addNewModelPath(newModelPath) \ No newline at end of file + self.addNewModelPath(newModelPath) diff --git a/DsgTools/gui/AboutAndFurtherInfo/aboutAndFurtherInfoGuiManager.py b/DsgTools/gui/AboutAndFurtherInfo/aboutAndFurtherInfoGuiManager.py index 9541bfa19..221499867 100644 --- a/DsgTools/gui/AboutAndFurtherInfo/aboutAndFurtherInfoGuiManager.py +++ b/DsgTools/gui/AboutAndFurtherInfo/aboutAndFurtherInfoGuiManager.py @@ -21,8 +21,13 @@ """ from __future__ import absolute_import -from DsgTools.core.DSGToolsProcessingAlgs.Algs.LayerManagementAlgs.spellChecker.datasets.ptBR import PalavrasFileConfig, WordDatasetPtBRFileConfig -from DsgTools.core.NetworkTools.ExternalFilesHandler import ExternalFileDownloadProcessor +from DsgTools.core.DSGToolsProcessingAlgs.Algs.LayerManagementAlgs.spellChecker.datasets.ptBR import ( + PalavrasFileConfig, + WordDatasetPtBRFileConfig, +) +from DsgTools.core.NetworkTools.ExternalFilesHandler import ( + ExternalFileDownloadProcessor, +) from qgis.PyQt.QtCore import QObject from qgis.PyQt.QtWidgets import QToolButton, QMenu, QAction @@ -30,9 +35,9 @@ from .Options.options import Options from .aboutdialog import AboutDialog -class AboutAndFurtherInfoGuiManager(QObject): - def __init__(self, manager, iface, parentMenu = None, toolbar = None): +class AboutAndFurtherInfoGuiManager(QObject): + def __init__(self, manager, iface, parentMenu=None, toolbar=None): """Constructor. :param iface: An interface instance that will be passed to this class which provides the hook by which you can manipulate the QGIS @@ -45,66 +50,69 @@ def __init__(self, manager, iface, parentMenu = None, toolbar = None): self.iface = iface self.parentMenu = parentMenu self.toolbar = toolbar - self.iconBasePath = ':/plugins/DsgTools/icons/' + self.iconBasePath = ":/plugins/DsgTools/icons/" self.options = Options() self.options.firstTimeConfig() - + def initGui(self): action = self.manager.add_action( - self.iconBasePath + 'custom_tools.png', + self.iconBasePath + "custom_tools.png", text=self.tr("DSGTools' Options"), callback=self.showOptions, parent=self.iface.mainWindow(), - parentMenu = self.parentMenu, + parentMenu=self.parentMenu, add_to_menu=False, add_to_toolbar=False, - withShortcut = True + withShortcut=True, ) action = self.manager.add_action( - self.iconBasePath + 'import.png', + self.iconBasePath + "import.png", text=self.tr("Download external data"), callback=self.checkExternalDownloads, parent=self.iface.mainWindow(), - parentMenu = self.parentMenu, + parentMenu=self.parentMenu, add_to_menu=False, add_to_toolbar=False, - withShortcut = False + withShortcut=False, ) # self.parentMenu.addAction(action) - icon_path = self.iconBasePath + 'bug.png' + icon_path = self.iconBasePath + "bug.png" action = self.manager.add_action( icon_path, - text=self.tr('Report bug / Suggest features'), + text=self.tr("Report bug / Suggest features"), callback=self.showBugTracker, parent=self.parentMenu, add_to_menu=True, add_to_toolbar=False, - withShortcut = True) + withShortcut=True, + ) - icon_path = self.iconBasePath + 'help.png' + icon_path = self.iconBasePath + "help.png" action = self.manager.add_action( icon_path, - text=self.tr('Help'), + text=self.tr("Help"), callback=self.showHelp, parent=self.parentMenu, add_to_menu=True, add_to_toolbar=False, - withShortcut = False) - - icon_path = self.iconBasePath + 'dsg.png' + withShortcut=False, + ) + + icon_path = self.iconBasePath + "dsg.png" self.manager.add_action( icon_path, - text=self.tr('About DSGTools'), + text=self.tr("About DSGTools"), callback=self.showAbout, parent=self.parentMenu, add_to_menu=True, add_to_toolbar=False, - withShortcut = False) - + withShortcut=False, + ) + def unload(self): pass - + def showOptions(self): """ Shows the options @@ -113,9 +121,11 @@ def showOptions(self): self.options.setInterfaceWithParametersFromConfig() self.checkExternalDownloads() result = self.options.exec_() - + def checkExternalDownloads(self): - downloadProcessor = ExternalFileDownloadProcessor(parent=self.iface.mainWindow()) + downloadProcessor = ExternalFileDownloadProcessor( + parent=self.iface.mainWindow() + ) output = downloadProcessor.process( fileConfigList=[ WordDatasetPtBRFileConfig, @@ -123,13 +133,15 @@ def checkExternalDownloads(self): ] ) if output: - message = self.tr('Everyting up to date') if output==1 else self.tr('External files updated') + message = ( + self.tr("Everyting up to date") + if output == 1 + else self.tr("External files updated") + ) self.iface.messageBar().pushMessage( - self.tr('Info'), - message, - level=Qgis.Info + self.tr("Info"), message, level=Qgis.Info ) - + def showHelp(self): """ Shows the help @@ -141,11 +153,11 @@ def showBugTracker(self): Shows the bug tracker """ self.iface.openURL("https://github.com/dsgoficial/DsgTools/issues", False) - + def showAbout(self): """ Shows the about dialog """ dlg = AboutDialog() dlg.show() - dlg.exec_() \ No newline at end of file + dlg.exec_() diff --git a/DsgTools/gui/AboutAndFurtherInfo/aboutdialog.py b/DsgTools/gui/AboutAndFurtherInfo/aboutdialog.py index a6b3e8185..791edeeed 100644 --- a/DsgTools/gui/AboutAndFurtherInfo/aboutdialog.py +++ b/DsgTools/gui/AboutAndFurtherInfo/aboutdialog.py @@ -25,9 +25,15 @@ from qgis.PyQt.QtWidgets import QDialog # replace version from metada file -with open(os.path.join(os.path.dirname(__file__), 'ui_about.ui'), 'r', encoding="utf-8") as about, \ - open(os.path.join(os.path.dirname(__file__), '..', '..', 'metadata.txt'), 'r', encoding="utf-8") as meta, \ - open(os.path.join(os.path.dirname(__file__), 'ui_about_.ui'), 'w') as filledUi: +with open( + os.path.join(os.path.dirname(__file__), "ui_about.ui"), "r", encoding="utf-8" +) as about, open( + os.path.join(os.path.dirname(__file__), "..", "..", "metadata.txt"), + "r", + encoding="utf-8", +) as meta, open( + os.path.join(os.path.dirname(__file__), "ui_about_.ui"), "w" +) as filledUi: t = Template(about.read()) for line in meta.readlines(): if line.strip().startswith("version="): @@ -36,13 +42,13 @@ t = t.safe_substitute(version=version) filledUi.write(t) -FORM_CLASS, _ = uic.loadUiType(os.path.join(os.path.dirname(__file__), 'ui_about_.ui')) +FORM_CLASS, _ = uic.loadUiType(os.path.join(os.path.dirname(__file__), "ui_about_.ui")) + class AboutDialog(QDialog, FORM_CLASS): - def __init__(self, parent = None): + def __init__(self, parent=None): """ Constructor """ super(AboutDialog, self).__init__(parent) self.setupUi(self) - diff --git a/DsgTools/gui/BDGExTools/bdgexGuiManager.py b/DsgTools/gui/BDGExTools/bdgexGuiManager.py index 08ee6faba..4bcb9c988 100644 --- a/DsgTools/gui/BDGExTools/bdgexGuiManager.py +++ b/DsgTools/gui/BDGExTools/bdgexGuiManager.py @@ -24,14 +24,14 @@ from functools import partial from qgis.core import Qgis, QgsProject, QgsVectorLayer -from qgis.PyQt.QtCore import QObject +from qgis.PyQt.QtCore import QObject from DsgTools.core.Utils.utils import MessageRaiser from DsgTools.core.NetworkTools.BDGExRequestHandler import BDGExRequestHandler -class BDGExGuiManager(QObject): - def __init__(self, manager, iface, parentMenu = None, toolbar = None): +class BDGExGuiManager(QObject): + def __init__(self, manager, iface, parentMenu=None, toolbar=None): """Constructor. :param iface: An interface instance that will be passed to this class which provides the hook by which you can manipulate the QGIS @@ -45,345 +45,325 @@ def __init__(self, manager, iface, parentMenu = None, toolbar = None): self.parentMenu = parentMenu self.toolbar = toolbar self.BDGExRequestHandler = BDGExRequestHandler() - self.menu = self.manager.addMenu(u'bdgex', self.tr('BDGEx'),'eb.png') - self.iconBasePath = ':/plugins/DsgTools/icons/' + self.menu = self.manager.addMenu("bdgex", self.tr("BDGEx"), "eb.png") + self.iconBasePath = ":/plugins/DsgTools/icons/" self.availableServices = { - 'topocharts' : [ + "topocharts": [ { - 'icon' : ':/plugins/DsgTools/icons/eb.png', - 'menu_entry' : self.tr('Multi scale mosaic'), - 'layers' : [ - 'ctm25', - 'ctm50', - 'ctm100', - 'ctm250' - ], - 'service' : 'mapcache', - 'service_type' : 'WMS', - 'separator' : True + "icon": ":/plugins/DsgTools/icons/eb.png", + "menu_entry": self.tr("Multi scale mosaic"), + "layers": ["ctm25", "ctm50", "ctm100", "ctm250"], + "service": "mapcache", + "service_type": "WMS", + "separator": True, }, { - 'icon' : ':/plugins/DsgTools/icons/eb.png', - 'menu_entry' : self.tr('1:250,000'), - 'layers' : [ - 'ctm250' - ], - 'service' : 'mapcache', - 'service_type' : 'WMS' + "icon": ":/plugins/DsgTools/icons/eb.png", + "menu_entry": self.tr("1:250,000"), + "layers": ["ctm250"], + "service": "mapcache", + "service_type": "WMS", }, { - 'icon' : ':/plugins/DsgTools/icons/eb.png', - 'menu_entry' : self.tr('1:100,000'), - 'layers' : [ - 'ctm100' - ], - 'service' : 'mapcache', - 'service_type' : 'WMS' + "icon": ":/plugins/DsgTools/icons/eb.png", + "menu_entry": self.tr("1:100,000"), + "layers": ["ctm100"], + "service": "mapcache", + "service_type": "WMS", }, { - 'icon' : ':/plugins/DsgTools/icons/eb.png', - 'menu_entry' : self.tr('1:50,000'), - 'layers' : [ - 'ctm50' - ], - 'service' : 'mapcache', - 'service_type' : 'WMS' + "icon": ":/plugins/DsgTools/icons/eb.png", + "menu_entry": self.tr("1:50,000"), + "layers": ["ctm50"], + "service": "mapcache", + "service_type": "WMS", }, { - 'icon' : ':/plugins/DsgTools/icons/eb.png', - 'menu_entry' : self.tr('1:25,000'), - 'layers' : [ - 'ctm25' - ], - 'service' : 'mapcache', - 'service_type' : 'WMS' - } + "icon": ":/plugins/DsgTools/icons/eb.png", + "menu_entry": self.tr("1:25,000"), + "layers": ["ctm25"], + "service": "mapcache", + "service_type": "WMS", + }, ], - 'coverage' : [ + "coverage": [ { - 'icon' : ':/plugins/DsgTools/icons/eb.png', - 'menu_entry' : self.tr('Rapideye Imagery (2013 mosaic)'), - 'layers' : [ - 'rapideye' - ], - 'service' : 'mapcache', - 'service_type' : 'WMS' + "icon": ":/plugins/DsgTools/icons/eb.png", + "menu_entry": self.tr("Rapideye Imagery (2013 mosaic)"), + "layers": ["rapideye"], + "service": "mapcache", + "service_type": "WMS", }, { - 'icon' : ':/plugins/DsgTools/icons/eb.png', - 'menu_entry' : self.tr('Landsat 7 Imagery (2000 mosaic)'), - 'layers' : [ - 'landsat7' - ], - 'service' : 'mapcache', - 'service_type' : 'WMS' + "icon": ":/plugins/DsgTools/icons/eb.png", + "menu_entry": self.tr("Landsat 7 Imagery (2000 mosaic)"), + "layers": ["landsat7"], + "service": "mapcache", + "service_type": "WMS", }, { - 'icon' : ':/plugins/DsgTools/icons/eb.png', - 'menu_entry' : self.tr('Orthorectified True Color Imagery compatible with 1:25,000 scale'), - 'layers' : [ - 'ortoimagem_scn25' - ], - 'service' : 'mapcache', - 'service_type' : 'WMS' + "icon": ":/plugins/DsgTools/icons/eb.png", + "menu_entry": self.tr( + "Orthorectified True Color Imagery compatible with 1:25,000 scale" + ), + "layers": ["ortoimagem_scn25"], + "service": "mapcache", + "service_type": "WMS", }, { - 'icon' : ':/plugins/DsgTools/icons/eb.png', - 'menu_entry' : self.tr('Artificial SAR Imagery compatible with 1:50,000 scale'), - 'layers' : [ - 'ram_colorimetria_50' - ], - 'service' : 'mapcache', - 'service_type' : 'WMS' + "icon": ":/plugins/DsgTools/icons/eb.png", + "menu_entry": self.tr( + "Artificial SAR Imagery compatible with 1:50,000 scale" + ), + "layers": ["ram_colorimetria_50"], + "service": "mapcache", + "service_type": "WMS", }, { - 'icon' : ':/plugins/DsgTools/icons/eb.png', - 'menu_entry' : self.tr('Artificial SAR Imagery compatible with 1:25,000 scale'), - 'layers' : [ - 'ram_colorimetria_25' - ], - 'service' : 'mapcache', - 'service_type' : 'WMS' - } + "icon": ":/plugins/DsgTools/icons/eb.png", + "menu_entry": self.tr( + "Artificial SAR Imagery compatible with 1:25,000 scale" + ), + "layers": ["ram_colorimetria_25"], + "service": "mapcache", + "service_type": "WMS", + }, ], - 'terrain' : [ + "terrain": [ { - 'icon' : ':/plugins/DsgTools/icons/eb.png', - 'menu_entry' : self.tr('Surface Digital Model compatible with scale 1:25,000'), - 'layers' : [ - 'mds25' - ], - 'service' : 'mapcache', - 'service_type' : 'WMS' + "icon": ":/plugins/DsgTools/icons/eb.png", + "menu_entry": self.tr( + "Surface Digital Model compatible with scale 1:25,000" + ), + "layers": ["mds25"], + "service": "mapcache", + "service_type": "WMS", }, { - 'icon' : ':/plugins/DsgTools/icons/eb.png', - 'menu_entry' : self.tr('Contour lines compatible with scale 1:25,000'), - 'layers' : [ - 'curva_nivel25' - ], - 'service' : 'mapcache', - 'service_type' : 'WMS', - 'separator' : True + "icon": ":/plugins/DsgTools/icons/eb.png", + "menu_entry": self.tr( + "Contour lines compatible with scale 1:25,000" + ), + "layers": ["curva_nivel25"], + "service": "mapcache", + "service_type": "WMS", + "separator": True, }, { - 'icon' : ':/plugins/DsgTools/icons/eb.png', - 'menu_entry' : self.tr('Surface Digital Model compatible with scale 1:50,000'), - 'layers' : [ - 'mds50' - ], - 'service' : 'mapcache', - 'service_type' : 'WMS' + "icon": ":/plugins/DsgTools/icons/eb.png", + "menu_entry": self.tr( + "Surface Digital Model compatible with scale 1:50,000" + ), + "layers": ["mds50"], + "service": "mapcache", + "service_type": "WMS", }, { - 'icon' : ':/plugins/DsgTools/icons/eb.png', - 'menu_entry' : self.tr('Contour lines compatible with scale 1:50,000'), - 'layers' : [ - 'curva_nivel50' - ], - 'service' : 'mapcache', - 'service_type' : 'WMS', - 'separator' : True + "icon": ":/plugins/DsgTools/icons/eb.png", + "menu_entry": self.tr( + "Contour lines compatible with scale 1:50,000" + ), + "layers": ["curva_nivel50"], + "service": "mapcache", + "service_type": "WMS", + "separator": True, }, { - 'icon' : ':/plugins/DsgTools/icons/eb.png', - 'menu_entry' : self.tr('Contour lines compatible with scale 1:100,000'), - 'layers' : [ - 'curva_nivel100' - ], - 'service' : 'mapcache', - 'service_type' : 'WMS' + "icon": ":/plugins/DsgTools/icons/eb.png", + "menu_entry": self.tr( + "Contour lines compatible with scale 1:100,000" + ), + "layers": ["curva_nivel100"], + "service": "mapcache", + "service_type": "WMS", }, { - 'icon' : ':/plugins/DsgTools/icons/eb.png', - 'menu_entry' : self.tr('Surface Digital Model compatible with scale 1:250,000 (SRTM)'), - 'layers' : [ - 'mds250' - ], - 'service' : 'mapcache', - 'service_type' : 'WMS' + "icon": ":/plugins/DsgTools/icons/eb.png", + "menu_entry": self.tr( + "Surface Digital Model compatible with scale 1:250,000 (SRTM)" + ), + "layers": ["mds250"], + "service": "mapcache", + "service_type": "WMS", }, { - 'icon' : ':/plugins/DsgTools/icons/eb.png', - 'menu_entry' : self.tr('Contour lines compatible with scale 1:250,000'), - 'layers' : [ - 'curva_nivel250' - ], - 'service' : 'mapcache', - 'service_type' : 'WMS' - } + "icon": ":/plugins/DsgTools/icons/eb.png", + "menu_entry": self.tr( + "Contour lines compatible with scale 1:250,000" + ), + "layers": ["curva_nivel250"], + "service": "mapcache", + "service_type": "WMS", + }, ], - 'aux_layers' : [ + "aux_layers": [ { - 'icon' : ':/plugins/DsgTools/icons/eb.png', - 'menu_entry' : self.tr('Brazilian Political Information'), - 'layers' : [ - 'municipios', - 'estados', - 'capitais' - ], - 'service' : 'mapcache', - 'service_type' : 'WMS', - 'separator' : True + "icon": ":/plugins/DsgTools/icons/eb.png", + "menu_entry": self.tr("Brazilian Political Information"), + "layers": ["municipios", "estados", "capitais"], + "service": "mapcache", + "service_type": "WMS", + "separator": True, }, { - 'icon' : ':/plugins/DsgTools/icons/eb.png', - 'menu_entry' : self.tr('Brazilian Cities'), - 'layers' : [ - 'municipios' - ], - 'service' : 'auxlayers', - 'service_type' : 'WFS' + "icon": ":/plugins/DsgTools/icons/eb.png", + "menu_entry": self.tr("Brazilian Cities"), + "layers": ["municipios"], + "service": "auxlayers", + "service_type": "WFS", }, { - 'icon' : ':/plugins/DsgTools/icons/eb.png', - 'menu_entry' : self.tr('Brazilian States'), - 'layers' : [ - 'estados' - ], - 'service' : 'auxlayers', - 'service_type' : 'WFS' + "icon": ":/plugins/DsgTools/icons/eb.png", + "menu_entry": self.tr("Brazilian States"), + "layers": ["estados"], + "service": "auxlayers", + "service_type": "WFS", }, { - 'icon' : ':/plugins/DsgTools/icons/eb.png', - 'menu_entry' : self.tr('Brazilian State Capitals'), - 'layers' : [ - 'capitais' - ], - 'service' : 'auxlayers', - 'service_type' : 'WFS' - } + "icon": ":/plugins/DsgTools/icons/eb.png", + "menu_entry": self.tr("Brazilian State Capitals"), + "layers": ["capitais"], + "service": "auxlayers", + "service_type": "WFS", + }, ], - 'raster_mapindex' : [ + "raster_mapindex": [ { - 'icon' : ':/plugins/DsgTools/icons/eb.png', - 'menu_entry' : self.tr('1:250,000'), - 'layers' : [ - 'F250_WGS84_MATRICIAL' - ], - 'service' : 'mapindex', - 'service_type' : 'WMS' + "icon": ":/plugins/DsgTools/icons/eb.png", + "menu_entry": self.tr("1:250,000"), + "layers": ["F250_WGS84_MATRICIAL"], + "service": "mapindex", + "service_type": "WMS", }, { - 'icon' : ':/plugins/DsgTools/icons/eb.png', - 'menu_entry' : self.tr('1:100,000'), - 'layers' : [ - 'F100_WGS84_MATRICIAL' - ], - 'service' : 'mapindex', - 'service_type' : 'WMS' + "icon": ":/plugins/DsgTools/icons/eb.png", + "menu_entry": self.tr("1:100,000"), + "layers": ["F100_WGS84_MATRICIAL"], + "service": "mapindex", + "service_type": "WMS", }, { - 'icon' : ':/plugins/DsgTools/icons/eb.png', - 'menu_entry' : self.tr('1:50,000'), - 'layers' : [ - 'F50_WGS84_MATRICIAL' - ], - 'service' : 'mapindex', - 'service_type' : 'WMS' + "icon": ":/plugins/DsgTools/icons/eb.png", + "menu_entry": self.tr("1:50,000"), + "layers": ["F50_WGS84_MATRICIAL"], + "service": "mapindex", + "service_type": "WMS", }, { - 'icon' : ':/plugins/DsgTools/icons/eb.png', - 'menu_entry' : self.tr('1:25,000'), - 'layers' : [ - 'F25_WGS84_MATRICIAL' - ], - 'service' : 'mapindex', - 'service_type' : 'WMS' - } + "icon": ":/plugins/DsgTools/icons/eb.png", + "menu_entry": self.tr("1:25,000"), + "layers": ["F25_WGS84_MATRICIAL"], + "service": "mapindex", + "service_type": "WMS", + }, ], - 'vector_mapindex' : [ + "vector_mapindex": [ { - 'icon' : ':/plugins/DsgTools/icons/eb.png', - 'menu_entry' : self.tr('1:250,000'), - 'layers' : [ - 'F250_WGS84_VETORIAL' - ], - 'service' : 'mapindex', - 'service_type' : 'WMS' + "icon": ":/plugins/DsgTools/icons/eb.png", + "menu_entry": self.tr("1:250,000"), + "layers": ["F250_WGS84_VETORIAL"], + "service": "mapindex", + "service_type": "WMS", }, { - 'icon' : ':/plugins/DsgTools/icons/eb.png', - 'menu_entry' : self.tr('1:100,000'), - 'layers' : [ - 'F100_WGS84_VETORIAL' - ], - 'service' : 'mapindex', - 'service_type' : 'WMS' + "icon": ":/plugins/DsgTools/icons/eb.png", + "menu_entry": self.tr("1:100,000"), + "layers": ["F100_WGS84_VETORIAL"], + "service": "mapindex", + "service_type": "WMS", }, { - 'icon' : ':/plugins/DsgTools/icons/eb.png', - 'menu_entry' : self.tr('1:50,000'), - 'layers' : [ - 'F50_WGS84_VETORIAL' - ], - 'service' : 'mapindex', - 'service_type' : 'WMS' + "icon": ":/plugins/DsgTools/icons/eb.png", + "menu_entry": self.tr("1:50,000"), + "layers": ["F50_WGS84_VETORIAL"], + "service": "mapindex", + "service_type": "WMS", }, { - 'icon' : ':/plugins/DsgTools/icons/eb.png', - 'menu_entry' : self.tr('1:25,000'), - 'layers' : [ - 'F25_WGS84_VETORIAL' - ], - 'service' : 'mapindex', - 'service_type' : 'WMS' - } - ] + "icon": ":/plugins/DsgTools/icons/eb.png", + "menu_entry": self.tr("1:25,000"), + "layers": ["F25_WGS84_VETORIAL"], + "service": "mapindex", + "service_type": "WMS", + }, + ], } - def initGui(self): - self.topocharts = self.manager.addMenu(u'topocharts', self.tr('Topographic Charts'),'eb.png', parentMenu = self.menu) - self.load_menus('topocharts', self.topocharts) - self.coverageLyr = self.manager.addMenu(u'coverageLyr', self.tr('Coverage Layers'),'eb.png', parentMenu = self.menu) - self.load_menus('coverage', self.coverageLyr) - self.terrainLyr = self.manager.addMenu(u'terrainLyr', self.tr('Terrain Information'),'eb.png', parentMenu = self.menu) - self.load_menus('terrain', self.terrainLyr) - self.auxLyr = self.manager.addMenu(u'auxLyr', self.tr('Auxiliar Information'),'eb.png', parentMenu = self.menu) - self.load_menus('aux_layers', self.auxLyr) - self.indexes = self.manager.addMenu(u'indexes', self.tr('Product Indexes'),'eb.png', parentMenu = self.menu) - self.rasterIndex = self.manager.addMenu(u'rasterindex', self.tr('Topographic Charts'),'eb.png', parentMenu = self.indexes) - self.load_menus('raster_mapindex', self.rasterIndex) - self.vectorIndex = self.manager.addMenu(u'vectorindex', self.tr('Vectorial Charts'),'eb.png', parentMenu = self.indexes) - self.load_menus('vector_mapindex', self.vectorIndex) + self.topocharts = self.manager.addMenu( + "topocharts", self.tr("Topographic Charts"), "eb.png", parentMenu=self.menu + ) + self.load_menus("topocharts", self.topocharts) + self.coverageLyr = self.manager.addMenu( + "coverageLyr", self.tr("Coverage Layers"), "eb.png", parentMenu=self.menu + ) + self.load_menus("coverage", self.coverageLyr) + self.terrainLyr = self.manager.addMenu( + "terrainLyr", self.tr("Terrain Information"), "eb.png", parentMenu=self.menu + ) + self.load_menus("terrain", self.terrainLyr) + self.auxLyr = self.manager.addMenu( + "auxLyr", self.tr("Auxiliar Information"), "eb.png", parentMenu=self.menu + ) + self.load_menus("aux_layers", self.auxLyr) + self.indexes = self.manager.addMenu( + "indexes", self.tr("Product Indexes"), "eb.png", parentMenu=self.menu + ) + self.rasterIndex = self.manager.addMenu( + "rasterindex", + self.tr("Topographic Charts"), + "eb.png", + parentMenu=self.indexes, + ) + self.load_menus("raster_mapindex", self.rasterIndex) + self.vectorIndex = self.manager.addMenu( + "vectorindex", + self.tr("Vectorial Charts"), + "eb.png", + parentMenu=self.indexes, + ) + self.load_menus("vector_mapindex", self.vectorIndex) - def loadServiceLayer(self, legendName, service, layerList, serviceType='WMS'): - urlWithParams = self.BDGExRequestHandler.get_url_string(service, layerList, serviceType) + def loadServiceLayer(self, legendName, service, layerList, serviceType="WMS"): + urlWithParams = self.BDGExRequestHandler.get_url_string( + service, layerList, serviceType + ) if not urlWithParams: return - if serviceType == 'WMS': + if serviceType == "WMS": self.iface.addRasterLayer(urlWithParams, legendName, serviceType.lower()) - if serviceType == 'WFS': + if serviceType == "WFS": vlayer = QgsVectorLayer(urlWithParams, legendName, serviceType) if not vlayer.isValid(): title = self.tr("BDGEx layers (DSGTools)") - msg = self.tr("Unable to provide requested layer. Please check" - " your network settings (proxy and exceptions " - "too, if necessary).") + msg = self.tr( + "Unable to provide requested layer. Please check" + " your network settings (proxy and exceptions " + "too, if necessary)." + ) MessageRaiser().raiseIfaceMessage(title, msg, Qgis.Warning, 5) else: QgsProject.instance().addMapLayer(vlayer) - + def load_menus(self, menu_type, parentMenu): for serviceDict in self.availableServices[menu_type]: callback = partial( self.loadServiceLayer, - legendName=serviceDict['menu_entry'], - service=serviceDict['service'], - layerList=serviceDict['layers'], - serviceType=serviceDict['service_type'] - ) + legendName=serviceDict["menu_entry"], + service=serviceDict["service"], + layerList=serviceDict["layers"], + serviceType=serviceDict["service_type"], + ) action = self.manager.add_action( - icon_path=serviceDict['icon'], - text=serviceDict['menu_entry'], - callback= callback, + icon_path=serviceDict["icon"], + text=serviceDict["menu_entry"], + callback=callback, parent=parentMenu, add_to_menu=False, - add_to_toolbar=False - ) + add_to_toolbar=False, + ) parentMenu.addAction(action) - if 'separator' in serviceDict and serviceDict['separator']: + if "separator" in serviceDict and serviceDict["separator"]: parentMenu.addSeparator() def unload(self): diff --git a/DsgTools/gui/CustomWidgets/AdvancedInterfaceWidgets/auxLayerSelector.py b/DsgTools/gui/CustomWidgets/AdvancedInterfaceWidgets/auxLayerSelector.py index 20f898af3..c94bbad7c 100644 --- a/DsgTools/gui/CustomWidgets/AdvancedInterfaceWidgets/auxLayerSelector.py +++ b/DsgTools/gui/CustomWidgets/AdvancedInterfaceWidgets/auxLayerSelector.py @@ -24,13 +24,16 @@ from qgis.PyQt.QtCore import Qt from qgis.PyQt.QtWidgets import QWidget, QFormLayout, QLabel -from DsgTools.gui.CustomWidgets.BasicInterfaceWidgets.dsgCustomComboBox import DsgCustomComboBox +from DsgTools.gui.CustomWidgets.BasicInterfaceWidgets.dsgCustomComboBox import ( + DsgCustomComboBox, +) + class AuxLayerSelector(QWidget): def __init__(self, parent=None): super(AuxLayerSelector, self).__init__(parent) self.layout = QFormLayout() - + def setInitialState(self, initDict): """ Sets widget interface with initDict entries. Keys are labels and values are list of items for each combobox corresponding to each key. @@ -41,14 +44,14 @@ def setInitialState(self, initDict): widget.addItems(value) self.layout.addRow(label, widget) self.setLayout(self.layout) - + def resetLayout(self): """ Resets current widget layout. """ self.layout = QFormLayout() self.setLayout(self.layout) - + def getParameters(self): """ Gets current values fom each widget as a dictionary. @@ -58,4 +61,4 @@ def getParameters(self): key = self.layout.itemAt(i, QFormLayout.LabelRole).text() value = self.layout.itemAt(i, QFormLayout.FieldRole).currentText() returnDict[key] = value - return returnDict \ No newline at end of file + return returnDict diff --git a/DsgTools/gui/CustomWidgets/AdvancedInterfaceWidgets/customFeatureForm.py b/DsgTools/gui/CustomWidgets/AdvancedInterfaceWidgets/customFeatureForm.py index dae6c7d4d..e573bea16 100644 --- a/DsgTools/gui/CustomWidgets/AdvancedInterfaceWidgets/customFeatureForm.py +++ b/DsgTools/gui/CustomWidgets/AdvancedInterfaceWidgets/customFeatureForm.py @@ -26,23 +26,27 @@ from qgis.gui import QgsMessageBar from qgis.PyQt.QtCore import Qt, QSize, pyqtSlot from qgis.PyQt.QtGui import QIcon -from qgis.PyQt.QtWidgets import (QLabel, - QDialog, - QSpinBox, - QLineEdit, - QComboBox, - QCheckBox, - QGridLayout, - QSpacerItem, - QSizePolicy, - QDoubleSpinBox) +from qgis.PyQt.QtWidgets import ( + QLabel, + QDialog, + QSpinBox, + QLineEdit, + QComboBox, + QCheckBox, + QGridLayout, + QSpacerItem, + QSizePolicy, + QDoubleSpinBox, +) from qgis.PyQt import uic, QtWidgets, QtGui from DsgTools.core.Utils.utils import Utils from DsgTools.core.GeometricTools.layerHandler import LayerHandler -FORM_CLASS, _ = uic.loadUiType(os.path.join( - os.path.dirname(__file__), 'customFeatureForm.ui')) +FORM_CLASS, _ = uic.loadUiType( + os.path.join(os.path.dirname(__file__), "customFeatureForm.ui") +) + class CustomFeatureForm(QDialog, FORM_CLASS): """ @@ -50,6 +54,7 @@ class CustomFeatureForm(QDialog, FORM_CLASS): Feature Tool Box. This form was copied from `Ferramentas de Produção` and modified for the DSGTools plugin. """ + def __init__(self, layer, layerMap, attributeMap=None, valueMaps=None): """ Class constructor. @@ -61,7 +66,7 @@ def __init__(self, layer, layerMap, attributeMap=None, valueMaps=None): (reclassified) value. :param valueMaps: (dict) map of all value/relations maps set to layer's fields. These maps will be used for domain checking - operations. + operations. """ super(CustomFeatureForm, self).__init__() self.setupUi(self) @@ -86,7 +91,7 @@ def resizeEvent(self, e): self.messageBar.resize( QSize( self.geometry().size().width(), - 40 # this felt nicer than the original height (30) + 40, # this felt nicer than the original height (30) ) ) @@ -133,17 +138,21 @@ def getFieldComboBox(self, field): inverseDomain = {v: k for k, v in domain.items()} if not domain: raise ValueError( - self.tr("Field {0} does not have a value/relations map")\ - .format(field.name()) + self.tr("Field {0} does not have a value/relations map").format( + field.name() + ) ) cb.addItems(list(domain.keys())) + def setValue(val): """val: field's real value""" if val not in domain.values(): return cb.setCurrentText(inverseDomain[val]) + def value(): return domain[cb.currentText()] + cb.setValue = setValue cb.value = value return cb @@ -162,7 +171,7 @@ def setupFields(self): map. """ utils = Utils() - row = 0 # in case no fields are provided + row = 0 # in case no fields are provided for row, f in enumerate(self.layer().fields()): fName = f.name() fMap = self.attributeMap.get(fName, None) @@ -178,8 +187,10 @@ def setupFields(self): enabled = fMap["editable"] if fMap["isPk"]: # visually identify primary key attributes - text = '

{0}

'.format(fName) + text = ( + '

{0}

'.format(fName) + ) else: text = fName else: @@ -215,10 +226,12 @@ def setupFields(self): self.widgetsLayout.addWidget(label, row, 0) self.widgetsLayout.addWidget(w, row, 1) self.widgetsLayout.addItem( - QSpacerItem( - 20, 40, QSizePolicy.Expanding, QSizePolicy.Expanding - ), row + 1, 1, 1, 2 - ) # row, col, rowSpan, colSpan + QSpacerItem(20, 40, QSizePolicy.Expanding, QSizePolicy.Expanding), + row + 1, + 1, + 1, + 2, + ) # row, col, rowSpan, colSpan def updateAttributeMap(self): """ @@ -286,8 +299,8 @@ def on_okPushButton_clicked(self): self.done(1) else: self.messageBar.pushMessage( - self.tr('Invalid layer selection'), + self.tr("Invalid layer selection"), self.tr("select at least one layer for reclassification!"), level=Qgis.Warning, - duration=5 + duration=5, ) diff --git a/DsgTools/gui/CustomWidgets/AttributeValidityWidgets/attributeConditionWidget.py b/DsgTools/gui/CustomWidgets/AttributeValidityWidgets/attributeConditionWidget.py index 2e2459f24..e01699f83 100644 --- a/DsgTools/gui/CustomWidgets/AttributeValidityWidgets/attributeConditionWidget.py +++ b/DsgTools/gui/CustomWidgets/AttributeValidityWidgets/attributeConditionWidget.py @@ -28,17 +28,24 @@ # Qt imports from qgis.PyQt import QtWidgets, uic from qgis.PyQt.QtCore import pyqtSlot, Qt, QSettings -from qgis.PyQt.QtWidgets import QListWidgetItem, QMessageBox, QMenu, QApplication, QFileDialog +from qgis.PyQt.QtWidgets import ( + QListWidgetItem, + QMessageBox, + QMenu, + QApplication, + QFileDialog, +) from qgis.PyQt.QtGui import QCursor from qgis.PyQt.QtSql import QSqlDatabase, QSqlQuery +FORM_CLASS, _ = uic.loadUiType( + os.path.join(os.path.dirname(__file__), "attributeConditionWidget.ui") +) -FORM_CLASS, _ = uic.loadUiType(os.path.join( - os.path.dirname(__file__), 'attributeConditionWidget.ui')) class AttributeConditionWidget(QtWidgets.QWidget, FORM_CLASS): - def __init__(self, parent = None): + def __init__(self, parent=None): """Constructor.""" super(self.__class__, self).__init__(parent) # Set up the user interface from Designer. @@ -47,5 +54,3 @@ def __init__(self, parent = None): # http://qt-project.org/doc/qt-4.8/designer-using-a-ui-file.html # #widgets-and-dialogs-with-auto-connect self.setupUi(self) - - diff --git a/DsgTools/gui/CustomWidgets/AttributeValidityWidgets/attributeRuleTypeWidget.py b/DsgTools/gui/CustomWidgets/AttributeValidityWidgets/attributeRuleTypeWidget.py index 2bb9239ab..2908507fe 100644 --- a/DsgTools/gui/CustomWidgets/AttributeValidityWidgets/attributeRuleTypeWidget.py +++ b/DsgTools/gui/CustomWidgets/AttributeValidityWidgets/attributeRuleTypeWidget.py @@ -29,28 +29,36 @@ # Qt imports from qgis.PyQt import QtWidgets, uic from qgis.PyQt.QtCore import pyqtSlot, Qt, QSettings -from qgis.PyQt.QtWidgets import QListWidgetItem, QMessageBox, QMenu, QApplication, QFileDialog +from qgis.PyQt.QtWidgets import ( + QListWidgetItem, + QMessageBox, + QMenu, + QApplication, + QFileDialog, +) from qgis.PyQt.QtGui import QCursor from qgis.PyQt.QtSql import QSqlDatabase, QSqlQuery -FORM_CLASS, _ = uic.loadUiType(os.path.join( - os.path.dirname(__file__), 'attributeRuleTypeWidget.ui')) +FORM_CLASS, _ = uic.loadUiType( + os.path.join(os.path.dirname(__file__), "attributeRuleTypeWidget.ui") +) + class AttributeRuleTypeWidget(QtWidgets.QWidget, FORM_CLASS): - def __init__(self, parameterDict = {}, parent = None): + def __init__(self, parameterDict={}, parent=None): """Constructor.""" - super(AttributeRuleTypeWidget, self).__init__(parent = parent) + super(AttributeRuleTypeWidget, self).__init__(parent=parent) self.setupUi(self) - self.validKeys = ['attributeRuleType', 'ruleColor', 'rank'] + self.validKeys = ["attributeRuleType", "ruleColor", "rank"] if isinstance(parameterDict, dict) and parameterDict != {}: self.populateInterface(parameterDict) - + def clearAll(self): """ Clears all widget information """ pass - + def getParameterDict(self): """ Components: @@ -62,9 +70,11 @@ def getParameterDict(self): if not self.validate(): raise Exception(self.invalidatedReason()) parameterDict = dict() - parameterDict['attributeRuleType'] = self.attributeRuleTypeLineEdit.text() - parameterDict['ruleColor'] = ','.join(map(str,self.mColorButton.color().getRgb())) - parameterDict['rank'] = self.rankSpinBox.value() + parameterDict["attributeRuleType"] = self.attributeRuleTypeLineEdit.text() + parameterDict["ruleColor"] = ",".join( + map(str, self.mColorButton.color().getRgb()) + ) + parameterDict["rank"] = self.rankSpinBox.value() return parameterDict def populateInterface(self, parameterDict): @@ -73,13 +83,17 @@ def populateInterface(self, parameterDict): """ if parameterDict: if not self.validateJson(parameterDict): - raise Exception(self.tr('Invalid Attribute Rule Type Widget json config!')) - #set layer combo - self.attributeRuleTypeLineEdit.setText(parameterDict['attributeRuleType']) - R,G,B = list(map(int,parameterDict['ruleColor'].split(','))) #QColor only accepts int values - self.mColorButton.setColor(QColor(R,G,B)) - self.rankSpinBox.setValue(parameterDict['rank']) - + raise Exception( + self.tr("Invalid Attribute Rule Type Widget json config!") + ) + # set layer combo + self.attributeRuleTypeLineEdit.setText(parameterDict["attributeRuleType"]) + R, G, B = list( + map(int, parameterDict["ruleColor"].split(",")) + ) # QColor only accepts int values + self.mColorButton.setColor(QColor(R, G, B)) + self.rankSpinBox.setValue(parameterDict["rank"]) + def validateJson(self, inputJson): """ Validates input json @@ -95,15 +109,15 @@ def validate(self): """ Validates fields. Returns True if all information are filled correctly. """ - if self.attributeRuleTypeLineEdit.text() == '': + if self.attributeRuleTypeLineEdit.text() == "": return False return True - + def invalidatedReason(self): """ Error reason """ - msg = '' - if self.attributeRuleTypeLineEdit.text() == '': - msg += self.tr('Invalid rule name!\n') - return msg \ No newline at end of file + msg = "" + if self.attributeRuleTypeLineEdit.text() == "": + msg += self.tr("Invalid rule name!\n") + return msg diff --git a/DsgTools/gui/CustomWidgets/AttributeValidityWidgets/attributeRuleWidget.py b/DsgTools/gui/CustomWidgets/AttributeValidityWidgets/attributeRuleWidget.py index eef0b72ca..72f274525 100644 --- a/DsgTools/gui/CustomWidgets/AttributeValidityWidgets/attributeRuleWidget.py +++ b/DsgTools/gui/CustomWidgets/AttributeValidityWidgets/attributeRuleWidget.py @@ -28,28 +28,36 @@ # Qt imports from qgis.PyQt import QtWidgets, uic from qgis.PyQt.QtCore import pyqtSlot, Qt, QSettings -from qgis.PyQt.QtWidgets import QListWidgetItem, QMessageBox, QMenu, QApplication, QFileDialog +from qgis.PyQt.QtWidgets import ( + QListWidgetItem, + QMessageBox, + QMenu, + QApplication, + QFileDialog, +) from qgis.PyQt.QtGui import QCursor from qgis.PyQt.QtSql import QSqlDatabase, QSqlQuery -FORM_CLASS, _ = uic.loadUiType(os.path.join( - os.path.dirname(__file__), 'attributeRuleWidget.ui')) +FORM_CLASS, _ = uic.loadUiType( + os.path.join(os.path.dirname(__file__), "attributeRuleWidget.ui") +) + class AttributeRuleWidget(QtWidgets.QWidget, FORM_CLASS): - def __init__(self, layerDict, parameterDict = {}, parent = None): + def __init__(self, layerDict, parameterDict={}, parent=None): """Constructor.""" - super(AttributeRuleWidget, self).__init__(parent = parent) + super(AttributeRuleWidget, self).__init__(parent=parent) self.setupUi(self) self.layerDict = layerDict - self.layerComboBox.addItem(self.tr('Select a layer')) + self.layerComboBox.addItem(self.tr("Select a layer")) layerNames = list(layerDict.keys()) layerNames.sort() self.layerComboBox.addItems(layerNames) self.setComponentsEnabled(False) - self.validKeys = ['attributeName', 'attributeRule', 'description', 'layerName'] + self.validKeys = ["attributeName", "attributeRule", "description", "layerName"] if parameterDict != {}: self.populateInterface(parameterDict) - + def clearAll(self): """ Clears all widget information @@ -57,7 +65,7 @@ def clearAll(self): self.attributeComboBox.clear() self.mFieldExpressionWidget.setRow(-1) self.descriptionLineEdit.clear() - + def setComponentsEnabled(self, enabled): """ Sets all components enabled. @@ -65,24 +73,24 @@ def setComponentsEnabled(self, enabled): self.attributeComboBox.setEnabled(enabled) self.mFieldExpressionWidget.setEnabled(enabled) self.descriptionLineEdit.setEnabled(enabled) - - @pyqtSlot(int, name = 'on_layerComboBox_currentIndexChanged') + + @pyqtSlot(int, name="on_layerComboBox_currentIndexChanged") def filterAttributeCombo(self, idx): self.clearAll() if idx > 0: key = self.layerComboBox.currentText() - self.attributeComboBox.addItem(self.tr('Select attribute')) - #get attribute names + self.attributeComboBox.addItem(self.tr("Select attribute")) + # get attribute names attrNames = [i.name() for i in self.layerDict[key].fields()] - #add items to combo box + # add items to combo box self.attributeComboBox.addItems(attrNames) - #after everything is ok, set components enabled + # after everything is ok, set components enabled self.setComponentsEnabled(True) - #set layer on mFieldExpressionWidget + # set layer on mFieldExpressionWidget self.mFieldExpressionWidget.setLayer(self.layerDict[key]) else: self.setComponentsEnabled(False) - + def getParameterDict(self): """ Components: @@ -94,10 +102,10 @@ def getParameterDict(self): if not self.validate(): raise Exception(self.invalidatedReason()) parameterDict = dict() - parameterDict['layerName'] = self.layerComboBox.currentText() - parameterDict['attributeName'] = self.attributeComboBox.currentText() - parameterDict['attributeRule'] = self.mFieldExpressionWidget.currentText() - parameterDict['description'] = self.descriptionLineEdit.text() + parameterDict["layerName"] = self.layerComboBox.currentText() + parameterDict["attributeName"] = self.attributeComboBox.currentText() + parameterDict["attributeRule"] = self.mFieldExpressionWidget.currentText() + parameterDict["description"] = self.descriptionLineEdit.text() return parameterDict def populateInterface(self, parameterDict): @@ -106,19 +114,23 @@ def populateInterface(self, parameterDict): """ if parameterDict: if not self.validateJson(parameterDict): - raise Exception(self.tr('Invalid Attribute Rule Widget json config!')) - #set layer combo - idx = self.layerComboBox.findText(parameterDict['layerName'], flags = Qt.MatchExactly) + raise Exception(self.tr("Invalid Attribute Rule Widget json config!")) + # set layer combo + idx = self.layerComboBox.findText( + parameterDict["layerName"], flags=Qt.MatchExactly + ) self.layerComboBox.setCurrentIndex(idx) - #set attr combo - idx = self.attributeComboBox.findText(parameterDict['attributeName'], flags = Qt.MatchExactly) + # set attr combo + idx = self.attributeComboBox.findText( + parameterDict["attributeName"], flags=Qt.MatchExactly + ) self.attributeComboBox.setCurrentIndex(idx) - #set rule - self.mFieldExpressionWidget.setExpression(parameterDict['attributeRule']) - #set description - if parameterDict['description'] != '': - self.descriptionLineEdit.setText(parameterDict['description']) - + # set rule + self.mFieldExpressionWidget.setExpression(parameterDict["attributeRule"]) + # set description + if parameterDict["description"] != "": + self.descriptionLineEdit.setText(parameterDict["description"]) + def validateJson(self, inputJson): """ Validates input json @@ -138,21 +150,29 @@ def validate(self): return False if self.attributeComboBox.currentIndex() < 1: return False - if self.mFieldExpressionWidget.currentText() == '' or \ - not self.mFieldExpressionWidget.isValidExpression(self.mFieldExpressionWidget.currentText()): + if ( + self.mFieldExpressionWidget.currentText() == "" + or not self.mFieldExpressionWidget.isValidExpression( + self.mFieldExpressionWidget.currentText() + ) + ): return False return True - + def invalidatedReason(self): """ Error reason """ - msg = '' + msg = "" if self.layerComboBox.currentIndex() < 1: - msg += self.tr('Invalid layer!\n') + msg += self.tr("Invalid layer!\n") if self.attributeComboBox.currentIndex() < 1: - msg += self.tr('Invalid attribute!\n') - if self.mFieldExpressionWidget.currentText() == '' or \ - not self.mFieldExpressionWidget.isValidExpression(self.mFieldExpressionWidget.currentText()): - msg += self.tr('Invalid rule!\n') - return msg \ No newline at end of file + msg += self.tr("Invalid attribute!\n") + if ( + self.mFieldExpressionWidget.currentText() == "" + or not self.mFieldExpressionWidget.isValidExpression( + self.mFieldExpressionWidget.currentText() + ) + ): + msg += self.tr("Invalid rule!\n") + return msg diff --git a/DsgTools/gui/CustomWidgets/AttributeValidityWidgets/listManagerWidget.py b/DsgTools/gui/CustomWidgets/AttributeValidityWidgets/listManagerWidget.py index 04db0ab25..c29d89b98 100644 --- a/DsgTools/gui/CustomWidgets/AttributeValidityWidgets/listManagerWidget.py +++ b/DsgTools/gui/CustomWidgets/AttributeValidityWidgets/listManagerWidget.py @@ -27,17 +27,24 @@ # Qt imports from qgis.PyQt import QtWidgets, uic from qgis.PyQt.QtCore import pyqtSlot, Qt, QSettings -from qgis.PyQt.QtWidgets import QListWidgetItem, QMessageBox, QMenu, QApplication, QFileDialog +from qgis.PyQt.QtWidgets import ( + QListWidgetItem, + QMessageBox, + QMenu, + QApplication, + QFileDialog, +) from qgis.PyQt.QtGui import QCursor from qgis.PyQt.QtSql import QSqlDatabase, QSqlQuery +FORM_CLASS, _ = uic.loadUiType( + os.path.join(os.path.dirname(__file__), "listManagerWidget.ui") +) -FORM_CLASS, _ = uic.loadUiType(os.path.join( - os.path.dirname(__file__), 'listManagerWidget.ui')) class ListManagerWidget(QtWidgets.QWidget, FORM_CLASS): - def __init__(self, parent = None): + def __init__(self, parent=None): """Constructor.""" super(self.__class__, self).__init__(parent) # Set up the user interface from Designer. @@ -46,5 +53,3 @@ def __init__(self, parent = None): # http://qt-project.org/doc/qt-4.8/designer-using-a-ui-file.html # #widgets-and-dialogs-with-auto-connect self.setupUi(self) - - diff --git a/DsgTools/gui/CustomWidgets/AttributeValidityWidgets/newAttributeRuleBuilderWidget.py b/DsgTools/gui/CustomWidgets/AttributeValidityWidgets/newAttributeRuleBuilderWidget.py index 6beeaddbf..4f2d770cf 100644 --- a/DsgTools/gui/CustomWidgets/AttributeValidityWidgets/newAttributeRuleBuilderWidget.py +++ b/DsgTools/gui/CustomWidgets/AttributeValidityWidgets/newAttributeRuleBuilderWidget.py @@ -28,17 +28,24 @@ # Qt imports from qgis.PyQt import QtWidgets, uic from qgis.PyQt.QtCore import pyqtSlot, Qt, QSettings -from qgis.PyQt.QtWidgets import QListWidgetItem, QMessageBox, QMenu, QApplication, QFileDialog +from qgis.PyQt.QtWidgets import ( + QListWidgetItem, + QMessageBox, + QMenu, + QApplication, + QFileDialog, +) from qgis.PyQt.QtGui import QCursor from qgis.PyQt.QtSql import QSqlDatabase, QSqlQuery +FORM_CLASS, _ = uic.loadUiType( + os.path.join(os.path.dirname(__file__), "newAttributeRuleBuilderWidget.ui") +) -FORM_CLASS, _ = uic.loadUiType(os.path.join( - os.path.dirname(__file__), 'newAttributeRuleBuilderWidget.ui')) class NewAttributeRuleBuilderWidget(QtWidgets.QWidget, FORM_CLASS): - def __init__(self, abstractDb, parent = None): + def __init__(self, abstractDb, parent=None): """Constructor.""" super(self.__class__, self).__init__(parent) # Set up the user interface from Designer. @@ -47,5 +54,3 @@ def __init__(self, abstractDb, parent = None): # http://qt-project.org/doc/qt-4.8/designer-using-a-ui-file.html # #widgets-and-dialogs-with-auto-connect self.setupUi(self) - - diff --git a/DsgTools/gui/CustomWidgets/BasicInterfaceWidgets/buttonPropWidget.py b/DsgTools/gui/CustomWidgets/BasicInterfaceWidgets/buttonPropWidget.py index 071f690fe..321f67ea6 100644 --- a/DsgTools/gui/CustomWidgets/BasicInterfaceWidgets/buttonPropWidget.py +++ b/DsgTools/gui/CustomWidgets/BasicInterfaceWidgets/buttonPropWidget.py @@ -29,29 +29,37 @@ from qgis.PyQt import uic from qgis.PyQt.QtGui import QIcon, QColor, QKeySequence from qgis.PyQt.QtCore import Qt, QSize, pyqtSlot, QSettings, pyqtSignal -from qgis.PyQt.QtWidgets import (QWidget, - QSpinBox, - QLineEdit, - QCheckBox, - QComboBox, - QPushButton, - QHBoxLayout, - QMessageBox, - QDoubleSpinBox) +from qgis.PyQt.QtWidgets import ( + QWidget, + QSpinBox, + QLineEdit, + QCheckBox, + QComboBox, + QPushButton, + QHBoxLayout, + QMessageBox, + QDoubleSpinBox, +) from DsgTools.core.Utils.utils import Utils, MessageRaiser from DsgTools.core.GeometricTools.layerHandler import LayerHandler -from DsgTools.gui.ProductionTools.Toolboxes.CustomFeatureToolBox.customButtonSetup import CustomButtonSetup, CustomFeatureButton +from DsgTools.gui.ProductionTools.Toolboxes.CustomFeatureToolBox.customButtonSetup import ( + CustomButtonSetup, + CustomFeatureButton, +) -FORM_CLASS, _ = uic.loadUiType(os.path.join( - os.path.dirname(__file__), 'buttonPropWidget.ui')) +FORM_CLASS, _ = uic.loadUiType( + os.path.join(os.path.dirname(__file__), "buttonPropWidget.ui") +) utils = Utils() + class ButtonPropWidget(QWidget, FORM_CLASS): # col enum COL_COUNT = 5 ATTR_COL, VAL_COL, PK_COL, EDIT_COL, IGNORED_COL = range(COL_COUNT) + def __init__(self, parent=None, button=None): """ Class constructor. @@ -61,8 +69,7 @@ def __init__(self, parent=None, button=None): super(ButtonPropWidget, self).__init__(parent) self.setupUi(self) self.mMapLayerComboBox.setFilters( - QgsMapLayerProxyModel.HasGeometry| - QgsMapLayerProxyModel.WritableLayer + QgsMapLayerProxyModel.HasGeometry | QgsMapLayerProxyModel.WritableLayer ) self.button = button or CustomFeatureButton() self.fillToolComboBox() @@ -72,10 +79,15 @@ def __init__(self, parent=None, button=None): self.keywordCheckBox.toggled.connect(self.keywordLineEdit.setEnabled) self.shortcutCheckBox.toggled.connect(self.shortcutWidget.setEnabled) self.mMapLayerComboBox.layerChanged.connect(self.updateFieldTable) - self.attributeTableWidget.setHorizontalHeaderLabels([ - self.tr("Attribute"), self.tr("Value"), self.tr("PK"), - self.tr("Editable"), self.tr("Ignored") - ]) + self.attributeTableWidget.setHorizontalHeaderLabels( + [ + self.tr("Attribute"), + self.tr("Value"), + self.tr("PK"), + self.tr("Editable"), + self.tr("Ignored"), + ] + ) header = self.attributeTableWidget.verticalHeader() header.setSectionResizeMode(header.ResizeToContents) self.updateFieldTable() @@ -90,12 +102,14 @@ def confirmAction(self, msg, title=None, showNo=True): mb = QMessageBox() title = title or self.tr("Confirm action") if showNo: - return QMessageBox.question( - self, title, msg, QMessageBox.Yes | QMessageBox.No - ) == QMessageBox.Yes + return ( + QMessageBox.question(self, title, msg, QMessageBox.Yes | QMessageBox.No) + == QMessageBox.Yes + ) else: - return QMessageBox.question( - self, title, msg, QMessageBox.Ok) == QMessageBox.Ok + return ( + QMessageBox.question(self, title, msg, QMessageBox.Ok) == QMessageBox.Ok + ) def fillToolComboBox(self): """ @@ -106,12 +120,15 @@ def fillToolComboBox(self): # method, from CustomFeatureButton tools = { self.tr("QGIS default feature extraction tool"): QIcon(""), - self.tr("DSGTools: Free Hand Acquisition"): \ - QIcon(':/plugins/DsgTools/icons/free_hand.png'), - self.tr("QGIS Circle extraction tool"): \ - QIcon(':/plugins/DsgTools/icons/circle.png'), - self.tr("DSGTools: Right Degree Angle Digitizing"): \ - QIcon(':/plugins/DsgTools/icons/home.png') + self.tr("DSGTools: Free Hand Acquisition"): QIcon( + ":/plugins/DsgTools/icons/free_hand.png" + ), + self.tr("QGIS Circle extraction tool"): QIcon( + ":/plugins/DsgTools/icons/circle.png" + ), + self.tr("DSGTools: Right Degree Angle Digitizing"): QIcon( + ":/plugins/DsgTools/icons/home.png" + ), } for idx, (tool, icon) in enumerate(tools.items()): self.toolComboBox.insertItem(idx, tool) @@ -131,7 +148,7 @@ def buttonName(self): :return: (str) button name read from GUI. """ return self.nameLineEdit.text().strip() - + def setDigitizingTool(self, tool): """ Sets button's digitizing tool to GUI. @@ -145,8 +162,7 @@ def digitizingTool(self): Reads current digitizing tool. :return: (str) current digitizing tool. """ - tools = {v: k for k, v in \ - CustomFeatureButton().supportedTools().items()} + tools = {v: k for k, v in CustomFeatureButton().supportedTools().items()} return tools[self.toolComboBox.currentText()] def setUseColor(self, useColor): @@ -291,8 +307,10 @@ def checkShortcut(self, s): if s == "": return "" for m in dir(iface): - if m.startswith("action") and \ - getattr(iface, m)().shortcut().toString().lower() == s.lower(): + if ( + m.startswith("action") + and getattr(iface, m)().shortcut().toString().lower() == s.lower() + ): return getattr(iface, m)().text() return "" @@ -306,8 +324,10 @@ def setShortcurt(self, s, autoReplace=True): s = s.replace(" ", "") action = self.checkShortcut(s) if not autoReplace and action != "": - txt = self.tr("Shortcut {s} is already assigned to {a}, would you " - "like to replace it?").format(s=s, a=action) + txt = self.tr( + "Shortcut {s} is already assigned to {a}, would you " + "like to replace it?" + ).format(s=s, a=action) if not self.confirmAction(txt, self.tr("Replace shortcut")): return self.shortcutWidget.setShortcut(QKeySequence.fromString(s)) @@ -339,7 +359,7 @@ def openForm(self): def setAttributeMap(self, attrMap): """ Sets the attribute value map for current button to GUI. - :param attrMap: (dict) a map from each field and its value to be set. + :param attrMap: (dict) a map from each field and its value to be set. """ self.updateFieldTable() table = self.attributeTableWidget @@ -350,18 +370,21 @@ def setAttributeMap(self, attrMap): if vl is not None: for fName, vMap in LayerHandler().valueMaps(vl).items(): valueMaps[fName] = {v: k for k, v in vMap.items()} + def setMappedValue(cb, field, value): if value is None: return if not (value in valueMaps[field]): - msg = self.tr("'{0}' is an invalid value for field {1}. (Is " - "the layer style generated from the current data" - " model?")\ - .format(value, field) + msg = self.tr( + "'{0}' is an invalid value for field {1}. (Is " + "the layer style generated from the current data" + " model?" + ).format(value, field) title = self.tr("DSGTools Custom Feature Tool Box") MessageRaiser().raiseIfaceMessage(title, msg, Qgis.Warning, 5) value = None cb.setCurrentText(valueMaps[field][value]) + pkIdxList = vl.primaryKeyAttributes() if vl else [] for row in range(table.rowCount()): attr = table.cellWidget(row, self.ATTR_COL).text().replace("&", "") @@ -371,23 +394,26 @@ def setMappedValue(cb, field, value): attrMap[attr] = { "value": None, "editable": False, - "ignored": isPk, # default is False unless it's a PK attr - "isPk": isPk + "ignored": isPk, # default is False unless it's a PK attr + "isPk": isPk, } { QWidget: lambda v: valueWidget.cb.setChecked(v or False), QLineEdit: lambda v: valueWidget.setText(v or ""), QSpinBox: lambda v: valueWidget.setValue(v or 0), QDoubleSpinBox: lambda v: valueWidget.setValue(v or 0.0), - QComboBox: lambda v: setMappedValue(valueWidget, attr, v) + QComboBox: lambda v: setMappedValue(valueWidget, attr, v), }[type(valueWidget)](attrMap[attr]["value"]) valueWidget.setEnabled(not attrMap[attr]["ignored"]) table.cellWidget(row, self.EDIT_COL).cb.setChecked( - attrMap[attr]["editable"]) + attrMap[attr]["editable"] + ) table.cellWidget(row, self.IGNORED_COL).cb.setChecked( - attrMap[attr]["ignored"]) - table.setCellWidget(row, self.PK_COL, - self.pkWidget() if isPk else QWidget()) + attrMap[attr]["ignored"] + ) + table.setCellWidget( + row, self.PK_COL, self.pkWidget() if isPk else QWidget() + ) def attributeMap(self): """ @@ -396,26 +422,30 @@ def attributeMap(self): """ attrMap = dict() table = self.attributeTableWidget - vMaps = LayerHandler().valueMaps(self.vectorLayer()) \ - if self.vectorLayer() else {} + vMaps = ( + LayerHandler().valueMaps(self.vectorLayer()) if self.vectorLayer() else {} + ) for row in range(table.rowCount()): attr = table.cellWidget(row, self.ATTR_COL).text().replace("&", "") attrMap[attr] = dict() valueWidget = table.cellWidget(row, self.VAL_COL) - attrMap[attr]["ignored"] = table.cellWidget(row, self.IGNORED_COL)\ - .cb.isChecked() + attrMap[attr]["ignored"] = table.cellWidget( + row, self.IGNORED_COL + ).cb.isChecked() # "ignored" still allows the value to be set as last priority attrMap[attr]["value"] = { QWidget: lambda: valueWidget.cb.isChecked(), QLineEdit: lambda: valueWidget.text(), QSpinBox: lambda: valueWidget.value(), QDoubleSpinBox: lambda: valueWidget.value(), - QComboBox: lambda: vMaps[attr][valueWidget.currentText()] + QComboBox: lambda: vMaps[attr][valueWidget.currentText()], }[type(valueWidget)]() attrMap[attr]["isPk"] = isinstance( - table.cellWidget(row, self.PK_COL), QPushButton) - attrMap[attr]["editable"] = table.cellWidget(row, self.EDIT_COL)\ - .cb.isChecked() + table.cellWidget(row, self.PK_COL), QPushButton + ) + attrMap[attr]["editable"] = table.cellWidget( + row, self.EDIT_COL + ).cb.isChecked() return attrMap def setLayer(self, layer): @@ -463,7 +493,7 @@ def pkWidget(self): used on rows associated with primary key attributes. """ pb = QPushButton() - pb.setIcon(QIcon(':/plugins/DsgTools/icons/key.png')) + pb.setIcon(QIcon(":/plugins/DsgTools/icons/key.png")) pb.setFlat(True) pb.blockSignals(True) pb.setObjectName("pkWidget") @@ -483,7 +513,7 @@ def attributeNameWidget(self, fieldName, isNotNull): pb.setEnabled(False) if isNotNull: pb.setStyleSheet( - "*{ color:rgb(150, 10, 25); "\ + "*{ color:rgb(150, 10, 25); " "background-color:rgba(255, 88, 116, 1.00); }" ) pb.setToolTip(self.tr("Field cannot be empty")) @@ -519,7 +549,8 @@ def valueWidget(self, field, data): else: vWidget = QLineEdit() vWidget.setPlaceholderText( - self.tr("Type the value for {0}").format(field.name())) + self.tr("Type the value for {0}").format(field.name()) + ) if data is not None: vWidget.setText(data) return vWidget @@ -551,8 +582,10 @@ def updateFieldTable(self, layer=None): if fields.fieldOrigin(idx) == fields.OriginExpression: virtualFields.append(f.name()) self.attributeTableWidget.setRowCount(len(fields) - len(virtualFields)) + def setDisabled(w, status): w.setEnabled(not status) + for row, field in enumerate(fields): fName = field.name() if fName in virtualFields: @@ -561,13 +594,14 @@ def setDisabled(w, status): isPk = row in pkIdxList notNull = not utils.fieldIsNullable(field) self.attributeTableWidget.setCellWidget( - row, self.ATTR_COL, self.attributeNameWidget(fName, notNull)) + row, self.ATTR_COL, self.attributeNameWidget(fName, notNull) + ) if fName not in attrMap: attrMap[fName] = { "value": None, "editable": False, - "ignored": isPk, # default is False unless it's a PK attr - "isPk": isPk + "ignored": isPk, # default is False unless it's a PK attr + "isPk": isPk, } value = attrMap[fName]["value"] if fName in valueMaps: @@ -583,13 +617,12 @@ def setDisabled(w, status): self.attributeTableWidget.setCellWidget(row, self.VAL_COL, vWidget) ccbEdit = self.centeredCheckBox() ccbEdit.cb.setChecked(attrMap[fName]["editable"]) - self.attributeTableWidget.setCellWidget( - row, self.EDIT_COL, ccbEdit) + self.attributeTableWidget.setCellWidget(row, self.EDIT_COL, ccbEdit) ccbIgnore = self.centeredCheckBox() ccbIgnore.cb.setChecked(attrMap[fName]["ignored"]) ccbIgnore.cb.toggled.connect(partial(setDisabled, vWidget)) - self.attributeTableWidget.setCellWidget( - row, self.IGNORED_COL, ccbIgnore) + self.attributeTableWidget.setCellWidget(row, self.IGNORED_COL, ccbIgnore) + def checkExclusiveCB(ccb1, ccb2): """ Method to make two CB to be mutually exclusive (like radio buttons. @@ -603,13 +636,15 @@ def checkExclusiveCB(ccb1, ccb2): ccb1 = cb if ccb1.cb.isChecked() and ccb2.cb.isChecked(): ccb2.cb.setChecked(False) + exclusiveCb = partial(checkExclusiveCB, ccbEdit, ccbIgnore) ccbIgnore.cb.toggled.connect(exclusiveCb) ccbEdit.cb.toggled.connect(exclusiveCb) ccbIgnore.cb.toggled.emit(ccbEdit.cb.isChecked()) # since row is from an enum of fields, field idx = row - self.attributeTableWidget.setCellWidget(row, self.PK_COL, - self.pkWidget() if isPk else QWidget()) + self.attributeTableWidget.setCellWidget( + row, self.PK_COL, self.pkWidget() if isPk else QWidget() + ) def setButton(self, button): """ @@ -665,7 +700,7 @@ def currentButtonName(self): :return: (CustomFeatureButton) button read from the setup object. """ return self.button.name() - + def currentButton(self): """ Retrieves currently SAVED button. diff --git a/DsgTools/gui/CustomWidgets/BasicInterfaceWidgets/buttonSetupWidget.py b/DsgTools/gui/CustomWidgets/BasicInterfaceWidgets/buttonSetupWidget.py index 9ce622e41..dd4bf536c 100644 --- a/DsgTools/gui/CustomWidgets/BasicInterfaceWidgets/buttonSetupWidget.py +++ b/DsgTools/gui/CustomWidgets/BasicInterfaceWidgets/buttonSetupWidget.py @@ -26,26 +26,29 @@ from qgis.core import Qgis, QgsMessageLog, QgsApplication from qgis.gui import QgsMessageBar from qgis.PyQt import uic -from qgis.PyQt.QtCore import (Qt, - QSize, - pyqtSlot, - QSettings, - pyqtSignal) +from qgis.PyQt.QtCore import Qt, QSize, pyqtSlot, QSettings, pyqtSignal from qgis.PyQt.QtGui import QColor from qgis.PyQt.QtSql import QSqlQuery -from qgis.PyQt.QtWidgets import (QDialog, - QFileDialog, - QMessageBox, - QHeaderView, - QRadioButton, - QAbstractItemView) - -from DsgTools.gui.ProductionTools.Toolboxes.CustomFeatureToolBox.customButtonSetup import CustomButtonSetup, CustomFeatureButton - -FORM_CLASS, _ = uic.loadUiType(os.path.join( - os.path.dirname(__file__), 'buttonSetupWidget.ui')) +from qgis.PyQt.QtWidgets import ( + QDialog, + QFileDialog, + QMessageBox, + QHeaderView, + QRadioButton, + QAbstractItemView, +) + +from DsgTools.gui.ProductionTools.Toolboxes.CustomFeatureToolBox.customButtonSetup import ( + CustomButtonSetup, + CustomFeatureButton, +) + +FORM_CLASS, _ = uic.loadUiType( + os.path.join(os.path.dirname(__file__), "buttonSetupWidget.ui") +) app = QgsApplication.instance() + class ButtonSetupWidget(QDialog, FORM_CLASS): def __init__(self, parent=None, buttonSetup=None): """ @@ -61,13 +64,16 @@ def __init__(self, parent=None, buttonSetup=None): if buttonSetup: self.setSetup(buttonSetup) self.buttonComboBox.addItem(self.tr("No button selected")) - self.tableWidget.itemSelectionChanged.connect( - self._setButtonFromRow) + self.tableWidget.itemSelectionChanged.connect(self._setButtonFromRow) bEnabled = self.buttonComboBox.currentIndex() > 0 - for w in ("savePushButton", "undoPushButton", "removePushButton", - "buttonPropWidget"): + for w in ( + "savePushButton", + "undoPushButton", + "removePushButton", + "buttonPropWidget", + ): getattr(self, w).setEnabled(bEnabled) - + # making the button selection to stand out a little bit if "Night Mapping" in app.activeThemePath(): ss = """QHeaderView::section:checked @@ -87,11 +93,13 @@ def raiseWarning(self, msg, title=None, lvl=None, duration=None): :param duration: (int) warning message display time. """ self.messageBar.pushMessage( - title or self.tr('Invalid workflow'), msg, - level=lvl or Qgis.Warning, duration=duration or 5 + title or self.tr("Invalid workflow"), + msg, + level=lvl or Qgis.Warning, + duration=duration or 5, ) # msg = self.tr("Buttons setup definion invalid: {m}").format(m=msg) - QgsMessageLog.logMessage(msg, 'DSGTools Plugin', Qgis.Warning) + QgsMessageLog.logMessage(msg, "DSGTools Plugin", Qgis.Warning) def resizeEvent(self, e): """ @@ -103,7 +111,7 @@ def resizeEvent(self, e): self.messageBar.resize( QSize( self.geometry().size().width(), - 40 # this felt nicer than the original height (30) + 40, # this felt nicer than the original height (30) ) ) @@ -218,7 +226,7 @@ def readSetup(self): def setSetup(self, newSetup): """ Imports buttons setup definitions from another buttons setup. - :param newSetup: (CustomButtonSetup) setup to be imported. + :param newSetup: (CustomButtonSetup) setup to be imported. """ self.buttonComboBox.blockSignals(True) self.setSetupName(newSetup.name()) @@ -439,14 +447,14 @@ def openForm(self): def setAttributeMap(self, attrMap): """ Sets the attribute value map for current button to GUI. - :param attrMap: (dict) a map from each field and its value to be set. + :param attrMap: (dict) a map from each field and its value to be set. """ self.buttonPropWidget.setAttributeMap(attrMap) def attributeMap(self): """ Reads the field map data and set it to a button attribute map format. - :return: (dict) read attribute map. + :return: (dict) read attribute map. """ return self.buttonPropWidget.attributeMap() @@ -462,7 +470,7 @@ def layer(self): Reads current layer selection from GUI. :return: (str) name for the selected layer. """ - self.buttonPropWidget.layer() + self.buttonPropWidget.layer() def currentButton(self): """ @@ -551,8 +559,12 @@ def setCurrentButton(self, button): pass self.buttonComboBox.setCurrentText(button.name()) bEnabled = self.buttonComboBox.currentIndex() > 0 - for w in ("savePushButton", "undoPushButton", "removePushButton", - "buttonPropWidget"): + for w in ( + "savePushButton", + "undoPushButton", + "removePushButton", + "buttonPropWidget", + ): getattr(self, w).setEnabled(bEnabled) self.buttonPropWidget.setButton(button) @@ -601,10 +613,10 @@ def addButton(self, button=None): if button is not None and not isinstance(button, bool): buttonName = button.name() if buttonName in self.registeredButtonNames(): - msg = self.tr("Button {b} already exists. Would you like to " - "replace it?").format(b=buttonName) - cnf = self.confirmAction(msg, - self.tr("Replace existing button")) + msg = self.tr( + "Button {b} already exists. Would you like to " "replace it?" + ).format(b=buttonName) + cnf = self.confirmAction(msg, self.tr("Replace existing button")) if not cnf: return self.getButtonByName(buttonName) self.updateButton(buttonName, button.properties()) @@ -689,11 +701,10 @@ def addButtonToTable(self, button): self.tableWidget.setCellWidget(row, 0, w) # button instances on this widget are never the same as the original # and so, modifying the properties below won't modify anything outside - # the scope of this dialog + # the scope of this dialog button.setCheckable(False) # button.setEnabled(False) - button.setCallback( - lambda: self.setCurrentButton(button), ignoreEnabled=True) + button.setCallback(lambda: self.setCurrentButton(button), ignoreEnabled=True) def removeButtonFromTable(self, button): """ @@ -721,9 +732,7 @@ def readButtonTable(self): count = self.tableWidget.rowCount() if count > 0: for row in range(count): - buttons.append( - self.buttonFromRow(row).name() - ) + buttons.append(self.buttonFromRow(row).name()) return buttons def buttonsOrder(self): @@ -759,8 +768,7 @@ def selectedColumns(self, reverseOrder=False): :return: (list-of-int) ordered list of selected columns' indexes. """ return sorted( - set(i.column() for i in self.selectedIndexes()), - reverse=reverseOrder + set(i.column() for i in self.selectedIndexes()), reverse=reverseOrder ) def selectRow(self, row): @@ -882,8 +890,10 @@ def on_okPushButton_clicked(self): msg = self.tr("Invalid input data: {r}").format(r=self.validate()) self.raiseWarning(msg) return - msg = self.tr("Current button has been modified and not saved. Would " - "you like to save it?") + msg = self.tr( + "Current button has been modified and not saved. Would " + "you like to save it?" + ) title = self.tr("Unsaved modifications") if self.buttonIsModified() and self.confirmAction(msg, title): self.updateCurrentButton() @@ -910,10 +920,7 @@ def state(self): for idx, props in enumerate(state["buttons"]): kws = props["keywords"] state["buttons"][idx]["keywords"] = tuple(kws) - return { - "state": state, - "order": self.buttonsOrder() - } + return {"state": state, "order": self.buttonsOrder()} def setState(self, state): """ @@ -930,15 +937,14 @@ def importSetup(self): fd = QFileDialog() filename = fd.getOpenFileName( caption=self.tr("Import a DSGTools Button Setup (set of buttons)"), - filter=self.tr("DSGTools Buttons Setup (*.setup)") + filter=self.tr("DSGTools Buttons Setup (*.setup)"), ) filename = filename[0] if isinstance(filename, tuple) else filename if not filename: return with open(filename, "r", encoding="utf-8") as fp: state = json.load(fp) - order = [b[0] for b in \ - sorted(state["order"].items(), key=lambda i: i[1])] + order = [b[0] for b in sorted(state["order"].items(), key=lambda i: i[1])] state = state["state"] # buttons' keywords are stored as tuple in order to be seriallizable for idx, props in enumerate(state["buttons"]): @@ -963,10 +969,10 @@ def importSetup(self): self.setSetupName(self.setup.name()) self.setDescription(self.setup.description()) self.setDynamicShortcut(self.setup.dynamicShortcut()) - msg = self.tr('Setup "{0}" imported from "{1}"')\ - .format(self.setup.name(), filename) - self.raiseWarning( - msg, title=self.tr("Imported workflow"), lvl=Qgis.Success) + msg = self.tr('Setup "{0}" imported from "{1}"').format( + self.setup.name(), filename + ) + self.raiseWarning(msg, title=self.tr("Imported workflow"), lvl=Qgis.Success) @pyqtSlot(bool, name="on_exportPushButton_clicked") def exportSetup(self): @@ -983,7 +989,7 @@ def exportSetup(self): fd = QFileDialog() filename = fd.getSaveFileName( caption=self.tr("Export setup - {0}").format(s.name()), - filter=self.tr("DSGTools Buttons Setup (*.setup)") + filter=self.tr("DSGTools Buttons Setup (*.setup)"), ) filename = filename[0] if isinstance(filename, tuple) else filename if not filename: @@ -992,8 +998,6 @@ def exportSetup(self): fp.write(json.dumps(self.state(), sort_keys=True, indent=4)) res = os.path.exists(filename) if res: - msg = self.tr('Setup "{0}" exported to "{1}"')\ - .format(s.name(), filename) - self.raiseWarning( - msg, title=self.tr("Exported workflow"), lvl=Qgis.Success) + msg = self.tr('Setup "{0}" exported to "{1}"').format(s.name(), filename) + self.raiseWarning(msg, title=self.tr("Exported workflow"), lvl=Qgis.Success) return res diff --git a/DsgTools/gui/CustomWidgets/BasicInterfaceWidgets/colorSelectorWidget.py b/DsgTools/gui/CustomWidgets/BasicInterfaceWidgets/colorSelectorWidget.py index e98d1cbd8..8cc2e6037 100644 --- a/DsgTools/gui/CustomWidgets/BasicInterfaceWidgets/colorSelectorWidget.py +++ b/DsgTools/gui/CustomWidgets/BasicInterfaceWidgets/colorSelectorWidget.py @@ -27,8 +27,9 @@ from qgis.PyQt.QtGui import QColor from qgis.PyQt.QtWidgets import QWidget, QLineEdit -FORM_CLASS, _ = uic.loadUiType(os.path.join( - os.path.dirname(__file__), "colorSelectorWidget.ui")) +FORM_CLASS, _ = uic.loadUiType( + os.path.join(os.path.dirname(__file__), "colorSelectorWidget.ui") +) class ColorSelectorWidget(QWidget, FORM_CLASS): diff --git a/DsgTools/gui/CustomWidgets/BasicInterfaceWidgets/dsgCustomComboBox.py b/DsgTools/gui/CustomWidgets/BasicInterfaceWidgets/dsgCustomComboBox.py index b60634fcf..020721052 100644 --- a/DsgTools/gui/CustomWidgets/BasicInterfaceWidgets/dsgCustomComboBox.py +++ b/DsgTools/gui/CustomWidgets/BasicInterfaceWidgets/dsgCustomComboBox.py @@ -25,9 +25,10 @@ from qgis.PyQt.QtWidgets import QCompleter, QComboBox from qgis.PyQt.QtCore import QSortFilterProxyModel + class DsgCustomComboBox(QComboBox): def __init__(self, parent=None): - super(DsgCustomComboBox, self).__init__(parent = parent) + super(DsgCustomComboBox, self).__init__(parent=parent) self.setFocusPolicy(Qt.StrongFocus) self.setEditable(True) @@ -47,23 +48,20 @@ def __init__(self, parent=None): self.lineEdit().textEdited[str].connect(self.pFilterModel.setFilterFixedString) self.completer.activated.connect(self.on_completer_activated) - - # on selection of an item from the completer, select the corresponding item from combobox + # on selection of an item from the completer, select the corresponding item from combobox def on_completer_activated(self, text): if text: index = self.findText(text) self.setCurrentIndex(index) - - # on model change, update the models of the filter and completer as well + # on model change, update the models of the filter and completer as well def setModel(self, model): super(DsgCustomComboBox, self).setModel(model) self.pFilterModel.setSourceModel(model) self.completer.setModel(self.pFilterModel) - # on model column change, update the model column of the filter and completer as well def setModelColumn(self, column): self.completer.setCompletionColumn(column) self.pFilterModel.setFilterKeyColumn(column) - super(DsgCustomComboBox, self).setModelColumn(column) \ No newline at end of file + super(DsgCustomComboBox, self).setModelColumn(column) diff --git a/DsgTools/gui/CustomWidgets/BasicInterfaceWidgets/genericDialogLayout.py b/DsgTools/gui/CustomWidgets/BasicInterfaceWidgets/genericDialogLayout.py index 520976fd2..dbdd2c013 100644 --- a/DsgTools/gui/CustomWidgets/BasicInterfaceWidgets/genericDialogLayout.py +++ b/DsgTools/gui/CustomWidgets/BasicInterfaceWidgets/genericDialogLayout.py @@ -25,13 +25,16 @@ import os -FORM_CLASS, _ = uic.loadUiType(os.path.join( - os.path.dirname(__file__), 'genericDialogLayout.ui')) +FORM_CLASS, _ = uic.loadUiType( + os.path.join(os.path.dirname(__file__), "genericDialogLayout.ui") +) + class GenericDialogLayout(QtWidgets.QDialog, FORM_CLASS): """ - Widget composed by an empty layout. It is supposed to be used as based for dynamic GUI. + Widget composed by an empty layout. It is supposed to be used as based for dynamic GUI. """ + def __init__(self, parent=None): """ Class constructor. diff --git a/DsgTools/gui/CustomWidgets/BasicInterfaceWidgets/layerAndFieldSelectorWidget.py b/DsgTools/gui/CustomWidgets/BasicInterfaceWidgets/layerAndFieldSelectorWidget.py index a091aad4d..d5c3020f3 100644 --- a/DsgTools/gui/CustomWidgets/BasicInterfaceWidgets/layerAndFieldSelectorWidget.py +++ b/DsgTools/gui/CustomWidgets/BasicInterfaceWidgets/layerAndFieldSelectorWidget.py @@ -26,8 +26,9 @@ from qgis.PyQt.QtCore import QSize from qgis.PyQt.QtWidgets import QWidget -FORM_CLASS, _ = uic.loadUiType(os.path.join( - os.path.dirname(__file__), "layerAndFieldSelectorWidget.ui")) +FORM_CLASS, _ = uic.loadUiType( + os.path.join(os.path.dirname(__file__), "layerAndFieldSelectorWidget.ui") +) class LayerAndFieldSelectorWidget(QWidget, FORM_CLASS): @@ -148,6 +149,5 @@ def resizeWidget(self): mMapLayerComboBoxSize = self.mMapLayerComboBox.size() mFieldComboBoxSize = self.mFieldComboBox.size() minW = mMapLayerComboBoxSize.width() + mFieldComboBoxSize.width() + 5 - minH = (mMapLayerComboBoxSize.height() + - mFieldComboBoxSize.height()) // 2 + minH = (mMapLayerComboBoxSize.height() + mFieldComboBoxSize.height()) // 2 self.setMinimumSize(QSize(minW, minH)) diff --git a/DsgTools/gui/CustomWidgets/BasicInterfaceWidgets/progressWidget.py b/DsgTools/gui/CustomWidgets/BasicInterfaceWidgets/progressWidget.py index 80784de34..5bac24671 100644 --- a/DsgTools/gui/CustomWidgets/BasicInterfaceWidgets/progressWidget.py +++ b/DsgTools/gui/CustomWidgets/BasicInterfaceWidgets/progressWidget.py @@ -27,8 +27,9 @@ from qgis.PyQt.QtWidgets import QProgressBar, QSizePolicy import time + class ProgressWidget(QgsMessageBar): - def __init__(self, min, max, message, parent=None, timeout = 1.5): + def __init__(self, min, max, message, parent=None, timeout=1.5): """ Constructs a progress widget """ @@ -37,24 +38,31 @@ def __init__(self, min, max, message, parent=None, timeout = 1.5): self.max = max sizePolicy = QSizePolicy(QSizePolicy.MinimumExpanding, QSizePolicy.Fixed) if parent: - self.setMinimumSize(parent.width(),40) + self.setMinimumSize(parent.width(), 40) else: - self.setMinimumSize(766,40) + self.setMinimumSize(766, 40) self.setSizePolicy(sizePolicy) self.progressBar = QProgressBar() self.progressBar.setMinimum(min) self.progressBar.setMaximum(max) self.parent = parent - self.msgBarItem = QgsMessageBarItem(self.tr("INFO: "), message, self.progressBar, level=Qgis.Info, duration=timeout, parent = self.parent) + self.msgBarItem = QgsMessageBarItem( + self.tr("INFO: "), + message, + self.progressBar, + level=Qgis.Info, + duration=timeout, + parent=self.parent, + ) self.pushItem(self.msgBarItem) self.parent.repaint() - + def initBar(self): """ Initializes the progress bar """ self.progressBar.setValue(0) - + def step(self): """ Increments the progress bar @@ -63,4 +71,4 @@ def step(self): self.progressBar.setValue(value) if value == self.max: time.sleep(1) - self.close() \ No newline at end of file + self.close() diff --git a/DsgTools/gui/CustomWidgets/BasicInterfaceWidgets/shortcutChooserWidget.py b/DsgTools/gui/CustomWidgets/BasicInterfaceWidgets/shortcutChooserWidget.py index 047c8e24b..de5d0e8b2 100644 --- a/DsgTools/gui/CustomWidgets/BasicInterfaceWidgets/shortcutChooserWidget.py +++ b/DsgTools/gui/CustomWidgets/BasicInterfaceWidgets/shortcutChooserWidget.py @@ -21,16 +21,20 @@ ***************************************************************************/ """ import os + # Qt imports from qgis.PyQt import QtWidgets, uic from qgis.PyQt.QtCore import pyqtSlot, pyqtSignal, QSettings, Qt from qgis.PyQt.QtGui import QKeySequence -FORM_CLASS, _ = uic.loadUiType(os.path.join( - os.path.dirname(__file__), 'shortcutChooserWidget.ui')) +FORM_CLASS, _ = uic.loadUiType( + os.path.join(os.path.dirname(__file__), "shortcutChooserWidget.ui") +) + class ShortcutChooserWidget(QtWidgets.QWidget, FORM_CLASS): keyPressed = pyqtSignal() + def __init__(self, parent=None): """ Initializates ShortcutChooserWidget @@ -38,14 +42,14 @@ def __init__(self, parent=None): super(ShortcutChooserWidget, self).__init__(parent) self.resetVariables() self.setupUi(self) - + @pyqtSlot(bool) def on_assignShortcutPushButton_clicked(self): """ After button is clicked, focus is needed to use keyPressEvent and keyReleaseEvent """ self.setFocus() - + @pyqtSlot(bool) def on_assignShortcutPushButton_toggled(self, toggled): """ @@ -53,17 +57,17 @@ def on_assignShortcutPushButton_toggled(self, toggled): """ if toggled: self.resetVariables() - self.assignShortcutPushButton.setText(self.tr('Enter Value')) - - @pyqtSlot(bool, name = 'on_clearPushButton_clicked') + self.assignShortcutPushButton.setText(self.tr("Enter Value")) + + @pyqtSlot(bool, name="on_clearPushButton_clicked") def clearAll(self): """ Clears push button and also resets self.modifiers and self.keys """ self.assignShortcutPushButton.setChecked(False) - self.assignShortcutPushButton.setText(self.tr('Assign Shortcut')) + self.assignShortcutPushButton.setText(self.tr("Assign Shortcut")) self.resetVariables() - + def resetVariables(self): """ Resets self.modifiers, self.key and self.keySequence to 0 @@ -73,8 +77,7 @@ def resetVariables(self): self.keySequence = 0 def keyPressEvent(self, event): - """ - """ + """ """ if not self.assignShortcutPushButton.isChecked(): super(ShortcutChooserWidget, self).keyPressEvent(event) return @@ -121,7 +124,7 @@ def keyReleaseEvent(self, event): self.assignShortcutPushButton.setChecked(False) self.updateShortcutText() self.setShortcut(self.keySequence) - + def setEnabled(self, enabled): if not enabled: self.clearAll() @@ -130,15 +133,21 @@ def setEnabled(self, enabled): def setShortcut(self, shortcut): self.keySequence = QKeySequence(shortcut) self.assignShortcutPushButton.setChecked(False) - self.assignShortcutPushButton.setText(self.keySequence.toString(format = QKeySequence.NativeText)) - - def getShortcut(self, asQKeySequence = False): + self.assignShortcutPushButton.setText( + self.keySequence.toString(format=QKeySequence.NativeText) + ) + + def getShortcut(self, asQKeySequence=False): if asQKeySequence: return self.keySequence else: return int(self.keySequence) def updateShortcutText(self): - self.keySequence = QKeySequence(self.modifiers+self.key) - #this uses QKeySequence.NativeText to show in the interface. To store data, no filter should be provided - self.assignShortcutPushButton.setText(self.tr('Input: {0}').format(self.keySequence.toString(format = QKeySequence.NativeText))) \ No newline at end of file + self.keySequence = QKeySequence(self.modifiers + self.key) + # this uses QKeySequence.NativeText to show in the interface. To store data, no filter should be provided + self.assignShortcutPushButton.setText( + self.tr("Input: {0}").format( + self.keySequence.toString(format=QKeySequence.NativeText) + ) + ) diff --git a/DsgTools/gui/CustomWidgets/BasicInterfaceWidgets/snapChooserWidget.py b/DsgTools/gui/CustomWidgets/BasicInterfaceWidgets/snapChooserWidget.py index d9f6c7117..2ee4874bb 100644 --- a/DsgTools/gui/CustomWidgets/BasicInterfaceWidgets/snapChooserWidget.py +++ b/DsgTools/gui/CustomWidgets/BasicInterfaceWidgets/snapChooserWidget.py @@ -28,29 +28,37 @@ # Qt imports from qgis.PyQt import QtWidgets, uic from qgis.PyQt.QtCore import pyqtSlot, Qt, QSettings -from qgis.PyQt.QtWidgets import QListWidgetItem, QMessageBox, QMenu, QApplication, QFileDialog +from qgis.PyQt.QtWidgets import ( + QListWidgetItem, + QMessageBox, + QMenu, + QApplication, + QFileDialog, +) from qgis.PyQt.QtGui import QCursor from qgis.PyQt.QtSql import QSqlDatabase, QSqlQuery -FORM_CLASS, _ = uic.loadUiType(os.path.join( - os.path.dirname(__file__), 'snapChooserWidget.ui')) +FORM_CLASS, _ = uic.loadUiType( + os.path.join(os.path.dirname(__file__), "snapChooserWidget.ui") +) + class SnapChooserWidget(QtWidgets.QWidget, FORM_CLASS): - def __init__(self, layerList, parameterDict = {}, parent = None): + def __init__(self, layerList, parameterDict={}, parent=None): """Constructor.""" - super(SnapChooserWidget, self).__init__(parent = parent) + super(SnapChooserWidget, self).__init__(parent=parent) self.setupUi(self) self.layerList = layerList self.layerList.sort() - self.layerComboBox.addItem(self.tr('Select a layer')) + self.layerComboBox.addItem(self.tr("Select a layer")) self.layerComboBox.addItems(self.layerList) - self.validKeys = ['layerName', 'snap'] + self.validKeys = ["layerName", "snap"] self.snapDoubleSpinBox.setDecimals(20) self.snapDoubleSpinBox.setMaximum(1000000) self.snapDoubleSpinBox.setMinimum(0.00000000000000001) if parameterDict != {}: self.populateInterface(parameterDict) - + def refresh(self, blackList): currentText = self.layerComboBox.currentText() refreshList = [i for i in self.layerList if i not in blackList] @@ -58,24 +66,24 @@ def refresh(self, blackList): refreshList.append(currentText) refreshList.sort() self.layerComboBox.clear() - self.layerComboBox.addItem(self.tr('Select a layer')) + self.layerComboBox.addItem(self.tr("Select a layer")) self.layerComboBox.addItems(refreshList) - idx = self.layerComboBox.findText(currentText, flags = Qt.MatchExactly) + idx = self.layerComboBox.findText(currentText, flags=Qt.MatchExactly) self.layerComboBox.setCurrentIndex(idx) - + def getSelectedItem(self): if self.layerComboBox.currentIndex() > 0: return self.layerComboBox.currentText() else: return None - + def clearAll(self): """ Clears all widget information """ self.layerComboBox.clear() self.snapDoubleSpinBox.setValue(1.0) - + def getParameterDict(self): """ Components: @@ -85,8 +93,8 @@ def getParameterDict(self): if not self.validate(): raise Exception(self.invalidatedReason()) parameterDict = dict() - parameterDict['layerName'] = self.layerComboBox.currentText() - parameterDict['snap'] = self.snapDoubleSpinBox.value() + parameterDict["layerName"] = self.layerComboBox.currentText() + parameterDict["snap"] = self.snapDoubleSpinBox.value() return parameterDict def populateInterface(self, parameterDict): @@ -95,14 +103,15 @@ def populateInterface(self, parameterDict): """ if parameterDict: if not self.validateJson(parameterDict): - raise Exception(self.tr('Invalid Snap Chooser Widget json config!')) - #set layer combo - idx = self.layerComboBox.findText(parameterDict['layerName'], flags = Qt.MatchExactly) + raise Exception(self.tr("Invalid Snap Chooser Widget json config!")) + # set layer combo + idx = self.layerComboBox.findText( + parameterDict["layerName"], flags=Qt.MatchExactly + ) self.layerComboBox.setCurrentIndex(idx) - #set snap double spin box - self.snapDoubleSpinBox.setValue(parameterDict['snap']) - - + # set snap double spin box + self.snapDoubleSpinBox.setValue(parameterDict["snap"]) + def validateJson(self, inputJson): """ Validates input json @@ -123,14 +132,14 @@ def validate(self): if self.snapDoubleSpinBox.value() <= 0: return False return True - + def invalidatedReason(self): """ Error reason """ - msg = '' + msg = "" if self.layerComboBox.currentIndex() < 1: - msg += self.tr('Invalid layer!\n') + msg += self.tr("Invalid layer!\n") if self.snapDoubleSpinBox.value() <= 0: - msg += self.tr('Invalid snap value!\n') - return msg \ No newline at end of file + msg += self.tr("Invalid snap value!\n") + return msg diff --git a/DsgTools/gui/CustomWidgets/BasicInterfaceWidgets/snapWithLayerChooserWidget.py b/DsgTools/gui/CustomWidgets/BasicInterfaceWidgets/snapWithLayerChooserWidget.py index 770af325e..f3e5efd19 100644 --- a/DsgTools/gui/CustomWidgets/BasicInterfaceWidgets/snapWithLayerChooserWidget.py +++ b/DsgTools/gui/CustomWidgets/BasicInterfaceWidgets/snapWithLayerChooserWidget.py @@ -31,11 +31,18 @@ from qgis.PyQt.QtCore import QSettings, Qt, pyqtSlot from qgis.PyQt.QtGui import QCursor from qgis.PyQt.QtSql import QSqlDatabase, QSqlQuery -from qgis.PyQt.QtWidgets import (QApplication, QFileDialog, QListWidgetItem, - QMenu, QMessageBox) +from qgis.PyQt.QtWidgets import ( + QApplication, + QFileDialog, + QListWidgetItem, + QMenu, + QMessageBox, +) + +FORM_CLASS, _ = uic.loadUiType( + os.path.join(os.path.dirname(__file__), "snapWithLayerChooserWidget.ui") +) -FORM_CLASS, _ = uic.loadUiType(os.path.join( - os.path.dirname(__file__), 'snapWithLayerChooserWidget.ui')) class SnapWithLayerChooserWidget(QtWidgets.QWidget, FORM_CLASS): def __init__(self, parameterDict={}, blackList=None, parent=None): @@ -44,14 +51,13 @@ def __init__(self, parameterDict={}, blackList=None, parent=None): self.parent = parent self.setupUi(self) self.project = QgsProject.instance() - self.validKeys = ['layer', 'layerName', 'snap'] + self.validKeys = ["layer", "layerName", "snap"] self.snapDoubleSpinBox.setDecimals(20) self.snapDoubleSpinBox.setMaximum(1000000) self.snapDoubleSpinBox.setMinimum(0.00000000000000001) self.layerComboBox.setFilters( - QgsMapLayerProxyModel.HasGeometry | - QgsMapLayerProxyModel.VectorLayer - ) + QgsMapLayerProxyModel.HasGeometry | QgsMapLayerProxyModel.VectorLayer + ) if blackList is not None: self.layerComboBox.setExceptedLayerList(blackList) if parameterDict != {}: @@ -82,9 +88,9 @@ def getParameterDict(self): if not self.validate(): raise Exception(self.invalidatedReason()) parameterDict = dict() - parameterDict['layer'] = self.layerComboBox.currentLayer() - parameterDict['layerName'] = self.layerComboBox.currentLayer().name() - parameterDict['snap'] = self.snapDoubleSpinBox.value() + parameterDict["layer"] = self.layerComboBox.currentLayer() + parameterDict["layerName"] = self.layerComboBox.currentLayer().name() + parameterDict["snap"] = self.snapDoubleSpinBox.value() return parameterDict def populateInterface(self, parameterDict): @@ -93,17 +99,14 @@ def populateInterface(self, parameterDict): """ if parameterDict: if not self.validateJson(parameterDict): - raise Exception( - self.tr('Invalid Snap Chooser Widget json config!') - ) - #set layer combo + raise Exception(self.tr("Invalid Snap Chooser Widget json config!")) + # set layer combo idx = self.layerComboBox.findText( - parameterDict['layerName'], - flags=Qt.MatchExactly - ) + parameterDict["layerName"], flags=Qt.MatchExactly + ) self.layerComboBox.setCurrentIndex(idx) - #set snap double spin box - self.snapDoubleSpinBox.setValue(parameterDict['snap']) + # set snap double spin box + self.snapDoubleSpinBox.setValue(parameterDict["snap"]) def validateJson(self, inputJson): """ @@ -125,14 +128,14 @@ def validate(self): # if self.snapDoubleSpinBox.value() <= 0: # return False return True - + def invalidatedReason(self): """ Error reason """ - msg = '' + msg = "" if self.layerComboBox.currentIndex() < 1: - msg += self.tr('Invalid layer!\n') + msg += self.tr("Invalid layer!\n") if self.snapDoubleSpinBox.value() <= 0: - msg += self.tr('Invalid snap value!\n') + msg += self.tr("Invalid snap value!\n") return msg diff --git a/DsgTools/gui/CustomWidgets/BasicInterfaceWidgets/switchButton.py b/DsgTools/gui/CustomWidgets/BasicInterfaceWidgets/switchButton.py index 627aa5e0e..d555fa3bc 100644 --- a/DsgTools/gui/CustomWidgets/BasicInterfaceWidgets/switchButton.py +++ b/DsgTools/gui/CustomWidgets/BasicInterfaceWidgets/switchButton.py @@ -27,12 +27,14 @@ from qgis.PyQt.QtCore import Qt, pyqtSlot, pyqtSignal from qgis.PyQt.QtWidgets import QLabel, QWidget, QSlider, QHBoxLayout -FORM_CLASS, _ = uic.loadUiType(os.path.join( - os.path.dirname(__file__), 'switchButton.ui')) +FORM_CLASS, _ = uic.loadUiType( + os.path.join(os.path.dirname(__file__), "switchButton.ui") +) + class SwitchButton(QWidget, FORM_CLASS): stateChanged = pyqtSignal(int) - + def __init__(self, parent=None, stateA=None, stateB=None): """ Class constructor. @@ -53,15 +55,15 @@ def __init__(self, parent=None, stateA=None, stateB=None): def setStateAName(self, name): """ - Updates the name for state A. + Updates the name for state A. :param name: (str) state A's name """ self.stateA = name self.stateALabel.setText(name) - + def setStateBName(self, name): """ - Updates the name for state B. + Updates the name for state B. :param name: (str) state B's name """ self.stateB = name @@ -72,7 +74,7 @@ def currentState(self): Reads state defined by current slider position - read from GUI. :return: (int) current state (0 for A, 1 for B). """ - return int(self.slider.value() >= (self.min_ + self.max_)/2) + return int(self.slider.value() >= (self.min_ + self.max_) / 2) def state(self): """ @@ -87,10 +89,7 @@ def setState(self, state): :return: (int) state to be set (0 for A, 1 for B). """ self._state = state - self.slider.setValue({ - 0: self.min_, - 1: self.max_ - }[state]) + self.slider.setValue({0: self.min_, 1: self.max_}[state]) def toggleState(self): """ @@ -98,16 +97,13 @@ def toggleState(self): """ self._state = self.state() ^ 1 self.setState(self._state) - + def stateName(self): """ Retrieves the name for current defined state. :return: (str) defined state's name (exposed text on GUI). """ - return { - 0: self.stateA, - 1: self.stateB - }[self.state()] + return {0: self.stateA, 1: self.stateB}[self.state()] @pyqtSlot() def updateState(self): @@ -120,7 +116,7 @@ def updateState(self): self.setState(newState) if prevState != newState: self.stateChanged.emit(newState) - + @pyqtSlot(int) def valueChanged(self, value): """ diff --git a/DsgTools/gui/CustomWidgets/BasicInterfaceWidgets/textBrowserDialog.py b/DsgTools/gui/CustomWidgets/BasicInterfaceWidgets/textBrowserDialog.py index 3a2192546..933980625 100644 --- a/DsgTools/gui/CustomWidgets/BasicInterfaceWidgets/textBrowserDialog.py +++ b/DsgTools/gui/CustomWidgets/BasicInterfaceWidgets/textBrowserDialog.py @@ -27,8 +27,10 @@ from qgis.PyQt.QtCore import pyqtSlot from qgis.PyQt.QtWidgets import QDialog, QFileDialog -FORM_CLASS, _ = uic.loadUiType(os.path.join( - os.path.dirname(__file__), 'textBrowserDialog.ui')) +FORM_CLASS, _ = uic.loadUiType( + os.path.join(os.path.dirname(__file__), "textBrowserDialog.ui") +) + class TextBrowserDialog(QDialog, FORM_CLASS): def __init__(self, html="", parent=None): @@ -62,7 +64,7 @@ def clearHtml(self): """ self.textBrowser.setHtml("") - @pyqtSlot(bool, name='on_savePushButton_clicked') + @pyqtSlot(bool, name="on_savePushButton_clicked") def saveHtml(self): """ Exports text. @@ -70,16 +72,19 @@ def saveHtml(self): """ html = self.textBrowser.toHtml() fd = QFileDialog() - filename = fd.getSaveFileName(caption=self.tr('Select a Path to Log'),filter=self.tr('HTML Files (*.html)')) + filename = fd.getSaveFileName( + caption=self.tr("Select a Path to Log"), + filter=self.tr("HTML Files (*.html)"), + ) filename = filename[0] if isinstance(filename, tuple) else filename if filename: - with open(filename, 'w', encoding='utf-8') as f: + with open(filename, "w", encoding="utf-8") as f: f.write(html) return filename - @pyqtSlot(bool, name='on_closePushButton_clicked') + @pyqtSlot(bool, name="on_closePushButton_clicked") def exit(self): """ Closes dialog. """ - self.close() \ No newline at end of file + self.close() diff --git a/DsgTools/gui/CustomWidgets/BasicInterfaceWidgets/toggleButton b/DsgTools/gui/CustomWidgets/BasicInterfaceWidgets/toggleButton index 6747a049f..0b9d3c04d 100644 --- a/DsgTools/gui/CustomWidgets/BasicInterfaceWidgets/toggleButton +++ b/DsgTools/gui/CustomWidgets/BasicInterfaceWidgets/toggleButton @@ -103,4 +103,4 @@ class Toggle(QCheckBox): @pulse_radius.setter def pulse_radius(self, pos): self._pulse_radius = pos - self.update() \ No newline at end of file + self.update() diff --git a/DsgTools/gui/CustomWidgets/BasicInterfaceWidgets/toggleButton.py b/DsgTools/gui/CustomWidgets/BasicInterfaceWidgets/toggleButton.py index 1b2b0a0ab..23677eff1 100644 --- a/DsgTools/gui/CustomWidgets/BasicInterfaceWidgets/toggleButton.py +++ b/DsgTools/gui/CustomWidgets/BasicInterfaceWidgets/toggleButton.py @@ -1,16 +1,19 @@ -from qgis.PyQt.QtCore import (Qt, - QSize, - QPoint, - QRectF, - QPointF, - pyqtSlot, - QEasingCurve, - pyqtProperty, - QPropertyAnimation, - QSequentialAnimationGroup) +from qgis.PyQt.QtCore import ( + Qt, + QSize, + QPoint, + QRectF, + QPointF, + pyqtSlot, + QEasingCurve, + pyqtProperty, + QPropertyAnimation, + QSequentialAnimationGroup, +) from qgis.PyQt.QtWidgets import QCheckBox from qgis.PyQt.QtGui import QPen, QColor, QBrush, QPainter, QPaintEvent + class Toggle(QCheckBox): # This widget was originally implemented by Martin Fitzpatrick # @ https://github.com/learnpyqt/python-qtwidgets @@ -18,12 +21,14 @@ class Toggle(QCheckBox): _transparent_pen = QPen(Qt.transparent) _light_grey_pen = QPen(Qt.lightGray) - def __init__(self, - parent=None, - bar_color=Qt.gray, - checked_color="#00B0FF", - handle_color=Qt.white, - labels=None): + def __init__( + self, + parent=None, + bar_color=Qt.gray, + checked_color="#00B0FF", + handle_color=Qt.white, + labels=None, + ): super().__init__(parent) self.setLabels(labels) # Save our properties on the object via self, so we can access them later @@ -62,7 +67,7 @@ def getLabel(self, state: bool): """ Gets the label to be displyed on the button accordingly to its state. :param state: (bool) whether this button is toggle (checked). - :return: (str) label to be displayed + :return: (str) label to be displayed """ if self._labels is None: return "" @@ -78,8 +83,7 @@ def paintEvent(self, e: QPaintEvent): p.setPen(self._transparent_pen) barRect = QRectF( - 0, 0, - contRect.width() - handleRadius, 0.40 * contRect.height() + 0, 0, contRect.width() - handleRadius, 0.40 * contRect.height() ) barRect.moveCenter(contRect.center()) rounding = barRect.height() / 2 @@ -100,9 +104,7 @@ def paintEvent(self, e: QPaintEvent): p.setPen(self._light_grey_pen) p.setBrush(self._handle_brush) - p.drawEllipse( - QPointF(xPos, barRect.center().y()), - handleRadius, handleRadius) + p.drawEllipse(QPointF(xPos, barRect.center().y()), handleRadius, handleRadius) p.end() diff --git a/DsgTools/gui/CustomWidgets/ConnectionWidgets/AdvancedConnectionWidgets/connectionComboBox.py b/DsgTools/gui/CustomWidgets/ConnectionWidgets/AdvancedConnectionWidgets/connectionComboBox.py index 6c2654154..2c21f5f18 100644 --- a/DsgTools/gui/CustomWidgets/ConnectionWidgets/AdvancedConnectionWidgets/connectionComboBox.py +++ b/DsgTools/gui/CustomWidgets/ConnectionWidgets/AdvancedConnectionWidgets/connectionComboBox.py @@ -27,20 +27,28 @@ from qgis.PyQt.QtGui import QCursor from qgis.core import QgsMessageLog, Qgis -from DsgTools.gui.CustomWidgets.BasicInterfaceWidgets.dsgCustomComboBox import DsgCustomComboBox +from DsgTools.gui.CustomWidgets.BasicInterfaceWidgets.dsgCustomComboBox import ( + DsgCustomComboBox, +) from DsgTools.core.Factories.DbFactory.dbFactory import DbFactory from DsgTools.core.Factories.DbFactory.abstractDb import AbstractDb -from DsgTools.gui.CustomWidgets.DatabaseConversionWidgets.datasourceInfoTable import DatasourceInfoTable +from DsgTools.gui.CustomWidgets.DatabaseConversionWidgets.datasourceInfoTable import ( + DatasourceInfoTable, +) from DsgTools.core.dsgEnums import DsgEnums import os -FORM_CLASS, _ = uic.loadUiType(os.path.join( - os.path.dirname(__file__), 'connectionComboBox.ui')) +FORM_CLASS, _ = uic.loadUiType( + os.path.join(os.path.dirname(__file__), "connectionComboBox.ui") +) + + class ConnectionComboBox(QtWidgets.QWidget, FORM_CLASS): connectionChanged = pyqtSignal() dbChanged = pyqtSignal(AbstractDb) problemOccurred = pyqtSignal(str) + def __init__(self, parent=None, isStatic=False): """ Class constructor. @@ -53,19 +61,27 @@ def __init__(self, parent=None, isStatic=False): self.abstractDb = None self.abstractDbFactory = DbFactory() self.serverAbstractDb = None - self.displayDict = {'2.1.3':'EDGV 2.1.3', '2.1.3 Pro':'EDGV 2.1.3 Pro','FTer_2a_Ed':'EDGV FTer 2a Ed', 'Non_EDGV':self.tr('Other database model'), '3.0':'EDGV 3.0'} + self.displayDict = { + "2.1.3": "EDGV 2.1.3", + "2.1.3 Pro": "EDGV 2.1.3 Pro", + "FTer_2a_Ed": "EDGV FTer 2a Ed", + "Non_EDGV": self.tr("Other database model"), + "3.0": "EDGV 3.0", + } self.instantiateAbstractDb = False self.isStatic = isStatic if self.isStatic: from DsgTools.gui.ServerTools.viewServers import ViewServersStatic + self.viewServers = ViewServersStatic() else: from DsgTools.gui.ServerTools.viewServers import ViewServers + self.viewServers = ViewServers() self.viewServers.defaultChanged.connect(self.loadServerAbstractDb) - self.connectionSelectorComboBox.addItem(self.tr('Select database')) + self.connectionSelectorComboBox.addItem(self.tr("Select database")) self.loadServerAbstractDb() - + def __del__(self): """ Destructor @@ -73,7 +89,7 @@ def __del__(self): if self.serverAbstractDb is not None: self.serverAbstractDb.closeDatabase() del self - + def loadServerAbstractDb(self): """ Checks if there is a default db in self.viewServers . If there isn't one, disables connection combo @@ -82,12 +98,22 @@ def loadServerAbstractDb(self): self.connectionSelectorComboBox.setEnabled(False) else: self.connectionSelectorComboBox.setEnabled(True) - (_, host, port, user, password) = self.viewServers.getDefaultConnectionParameters() - serverAbstractDb = self.abstractDbFactory.createDbFactory(DsgEnums.DriverPostGIS) - serverAbstractDb.connectDatabaseWithParameters(host, port, 'postgres', user, password) + ( + _, + host, + port, + user, + password, + ) = self.viewServers.getDefaultConnectionParameters() + serverAbstractDb = self.abstractDbFactory.createDbFactory( + DsgEnums.DriverPostGIS + ) + serverAbstractDb.connectDatabaseWithParameters( + host, port, "postgres", user, password + ) self.setServerDb(serverAbstractDb) serverAbstractDb.closeDatabase() - + def closeDatabase(self): if self.abstractDb is not None: self.abstractDb.closeDatabase() @@ -95,16 +121,18 @@ def closeDatabase(self): def clear(self): self.connectionSelectorComboBox.clear() self.closeDatabase() - + def setServerDb(self, serverAbstractDb): self.serverAbstractDb = serverAbstractDb QApplication.setOverrideCursor(QCursor(Qt.WaitCursor)) try: if self.serverAbstractDb: - dbList = self.serverAbstractDb.getEDGVDbsFromServer(parentWidget = self.parent, getDatabaseVersions = False) + dbList = self.serverAbstractDb.getEDGVDbsFromServer( + parentWidget=self.parent, getDatabaseVersions=False + ) dbList.sort() self.clear() - self.connectionSelectorComboBox.addItem(self.tr('Select Database')) + self.connectionSelectorComboBox.addItem(self.tr("Select Database")) self.addItems(dbList) else: self.clear() @@ -113,9 +141,9 @@ def setServerDb(self, serverAbstractDb): return except Exception as e: QApplication.restoreOverrideCursor() - QMessageBox.critical(self, self.tr('Critical!'), ':'.join(e.args)) + QMessageBox.critical(self, self.tr("Critical!"), ":".join(e.args)) QApplication.restoreOverrideCursor() - + def addItems(self, items): itemList = [] if items == []: @@ -126,19 +154,19 @@ def addItems(self, items): version = item[1] else: version = self.displayDict[item[1]] - newText = item[0] + ' ({0})'.format(version) + newText = item[0] + " ({0})".format(version) itemList.append(newText) if itemList == []: itemList = items self.connectionSelectorComboBox.addItems(itemList) - + def currentDb(self): if self.connectionSelectorComboBox.currentIndex() == 0: - return '' + return "" else: - return self.connectionSelectorComboBox.currentText().split(' (')[0] - - @pyqtSlot(int, name = 'on_connectionSelectorComboBox_currentIndexChanged') + return self.connectionSelectorComboBox.currentText().split(" (")[0] + + @pyqtSlot(int, name="on_connectionSelectorComboBox_currentIndexChanged") def loadDatabase(self, idx): """ Loads the selected database @@ -148,18 +176,31 @@ def loadDatabase(self, idx): self.closeDatabase() if self.serverAbstractDb is not None and idx > 0: if not self.instantiateAbstractDb: - self.abstractDb = self.abstractDbFactory.createDbFactory(DsgEnums.DriverPostGIS) - (host, port, user, password) = self.serverAbstractDb.getDatabaseParameters() - dbName = self.connectionSelectorComboBox.itemText(idx).split(' (')[0] - self.abstractDb.connectDatabaseWithParameters(host, port, dbName, user, password) + self.abstractDb = self.abstractDbFactory.createDbFactory( + DsgEnums.DriverPostGIS + ) + ( + host, + port, + user, + password, + ) = self.serverAbstractDb.getDatabaseParameters() + dbName = self.connectionSelectorComboBox.itemText(idx).split(" (")[ + 0 + ] + self.abstractDb.connectDatabaseWithParameters( + host, port, dbName, user, password + ) self.abstractDb.checkAndOpenDb() self.dbChanged.emit(self.abstractDb) self.connectionChanged.emit() except Exception as e: self.closeDatabase() - self.problemOccurred.emit(self.tr('A problem occurred! Check log for details.')) - QgsMessageLog.logMessage(':'.join(e.args), "DSGTools Plugin", Qgis.Critical) - + self.problemOccurred.emit( + self.tr("A problem occurred! Check log for details.") + ) + QgsMessageLog.logMessage(":".join(e.args), "DSGTools Plugin", Qgis.Critical) + @pyqtSlot(bool) def on_serverPushButton_clicked(self): self.viewServers.exec_() @@ -178,7 +219,13 @@ def databaseExists(self): """ # for files, it is only necessary to check if file exists and is not empty. if self.abstractDb: - _, host, port, user, password = self.viewServers.getDefaultConnectionParameters() + ( + _, + host, + port, + user, + password, + ) = self.viewServers.getDefaultConnectionParameters() database = self.currentDb() return self.abstractDb.testCredentials(host, port, database, user, password) return False @@ -193,23 +240,23 @@ def validate(self): # check a valid server name # check if datasource is a valid name and if it already exists into selected server if not self.currentDb() or not self.abstractDb: - return self.tr('Invalid datasource.') + return self.tr("Invalid datasource.") else: # check if the connection is a valid connection if not self.serverIsValid(): - return self.tr('Invalid connection to server.') + return self.tr("Invalid connection to server.") # check if it exists if not self.databaseExists(): - return self.tr('Database {0} does not exist.').format(self.currentDb()) + return self.tr("Database {0} does not exist.").format(self.currentDb()) # if all tests were positive, widget has a valid selection - return '' + return "" def isValid(self): """ Validates selection. :return: (bool) validation status. """ - return self.validate() == '' + return self.validate() == "" # msg = self.validate() # if msg: # # if an invalidation reason was given, warn user and nothing else. @@ -229,5 +276,5 @@ def setHost(self, hostname): Sets a hostname as selected from its name. :param serverName: (str) host to be set as selected. """ - # method needs to be ported to 'non-static' view server! + # method needs to be ported to 'non-static' view server! self.viewServers.setHost(hostname) diff --git a/DsgTools/gui/CustomWidgets/ConnectionWidgets/AdvancedConnectionWidgets/databaseFileLineEdit.py b/DsgTools/gui/CustomWidgets/ConnectionWidgets/AdvancedConnectionWidgets/databaseFileLineEdit.py index 53b00c704..dfd00186b 100644 --- a/DsgTools/gui/CustomWidgets/ConnectionWidgets/AdvancedConnectionWidgets/databaseFileLineEdit.py +++ b/DsgTools/gui/CustomWidgets/ConnectionWidgets/AdvancedConnectionWidgets/databaseFileLineEdit.py @@ -31,10 +31,14 @@ from DsgTools.core.Factories.DbFactory.dbFactory import DbFactory from DsgTools.core.Factories.DbFactory.abstractDb import AbstractDb from DsgTools.core.dsgEnums import DsgEnums -from DsgTools.gui.CustomWidgets.DatabaseConversionWidgets.datasourceInfoTable import DatasourceInfoTable +from DsgTools.gui.CustomWidgets.DatabaseConversionWidgets.datasourceInfoTable import ( + DatasourceInfoTable, +) + +FORM_CLASS, _ = uic.loadUiType( + os.path.join(os.path.dirname(__file__), "databaseFileLineEdit.ui") +) -FORM_CLASS, _ = uic.loadUiType(os.path.join( - os.path.dirname(__file__), 'databaseFileLineEdit.ui')) class DatabaseFileLineEdit(QtWidgets.QWidget, FORM_CLASS): connectionChanged = pyqtSignal() @@ -53,9 +57,15 @@ def __init__(self, parent=None): self.abstractDb = None self.abstractDbFactory = DbFactory() self.serverAbstractDb = None - self.displayDict = {'2.1.3':'EDGV 2.1.3', '2.1.3 Pro':'EDGV 2.1.3 Pro', 'FTer_2a_Ed':'EDGV FTer 2a Ed', 'Non_EDGV':self.tr('Other database model'), '3.0':'EDGV 3.0'} + self.displayDict = { + "2.1.3": "EDGV 2.1.3", + "2.1.3 Pro": "EDGV 2.1.3 Pro", + "FTer_2a_Ed": "EDGV FTer 2a Ed", + "Non_EDGV": self.tr("Other database model"), + "3.0": "EDGV 3.0", + } self.instantiateAbstractDb = False - self.connectionSelectorLineEdit.lineEdit.setText(self.tr('Select datasource')) + self.connectionSelectorLineEdit.lineEdit.setText(self.tr("Select datasource")) self.connectionSelectorLineEdit.lineEdit.setReadOnly(True) def closeDatabase(self): @@ -70,20 +80,20 @@ def clear(self): Unsets any selected database and clears db directory, if necessary. """ self.connectionSelectorLineEdit.lineEdit.clear() - self.connectionSelectorLineEdit.lineEdit.setText(self.tr('Select datasource')) + self.connectionSelectorLineEdit.lineEdit.setText(self.tr("Select datasource")) self.closeDatabase() - + def currentDb(self): """ Returns current loaded datasource name, if any. :return: (str) current loaded datasource name; an empty string if no ds is selected. """ text = self.connectionSelectorLineEdit.lineEdit.text() - if text == self.tr('Select datasource'): + if text == self.tr("Select datasource"): return None else: - dirSplit = '/' if '/' in text else '\\' - text = text.split(dirSplit)[-1].split('.')[0] if text else '' + dirSplit = "/" if "/" in text else "\\" + text = text.split(dirSplit)[-1].split(".")[0] if text else "" return text def serverIsValid(self): @@ -100,7 +110,7 @@ def databaseExists(self): # for files, it is only necessary to check if file exists and is not empty. return bool(self.abstractDb) - @pyqtSlot(str, name = 'on_lineEdit_textChanged') + @pyqtSlot(str, name="on_lineEdit_textChanged") def loadDatabase(self, currentText): """ Loads the selected database @@ -117,8 +127,10 @@ def loadDatabase(self, currentText): self.connectionChanged.emit() except Exception as e: self.closeDatabase() - self.problemOccurred.emit(self.tr('A problem occurred! Check log for details.')) - QgsMessageLog.logMessage(':'.join(e.args), "DSGTools Plugin", Qgis.Critical) + self.problemOccurred.emit( + self.tr("A problem occurred! Check log for details.") + ) + QgsMessageLog.logMessage(":".join(e.args), "DSGTools Plugin", Qgis.Critical) def validate(self): """ @@ -130,23 +142,23 @@ def validate(self): # check a valid server name # check if datasource is a valid name and if it already exists into selected server if not self.currentDb() or not self.abstractDb: - return self.tr('Invalid datasource.') + return self.tr("Invalid datasource.") else: # check if the connection is a valid connection if not self.serverIsValid(): - return self.tr('Invalid connection to server.') + return self.tr("Invalid connection to server.") # check if it exists if not self.databaseExists(): - return self.tr('Database {0} does not exist.').format(self.currentDb()) + return self.tr("Database {0} does not exist.").format(self.currentDb()) # if all tests were positive, widget has a valid selection - return '' + return "" def isValid(self): """ Validates selection. :return: (bool) validation status. """ - return self.validate() == '' + return self.validate() == "" @pyqtSlot(bool) def on_infoPushButton_clicked(self): diff --git a/DsgTools/gui/CustomWidgets/ConnectionWidgets/AdvancedConnectionWidgets/newConnectionLineEdit.py b/DsgTools/gui/CustomWidgets/ConnectionWidgets/AdvancedConnectionWidgets/newConnectionLineEdit.py index 087e248c0..82d2a1403 100644 --- a/DsgTools/gui/CustomWidgets/ConnectionWidgets/AdvancedConnectionWidgets/newConnectionLineEdit.py +++ b/DsgTools/gui/CustomWidgets/ConnectionWidgets/AdvancedConnectionWidgets/newConnectionLineEdit.py @@ -24,6 +24,7 @@ from qgis.PyQt.QtWidgets import QWidget, QFileDialog from qgis.PyQt.QtCore import pyqtSlot, pyqtSignal from qgis.PyQt import uic + # from qgis.utils import iface from qgis.core import Qgis, QgsMessageLog @@ -33,14 +34,18 @@ import os -FORM_CLASS, _ = uic.loadUiType(os.path.join(os.path.dirname(__file__), 'newConnectionLineEdit.ui')) +FORM_CLASS, _ = uic.loadUiType( + os.path.join(os.path.dirname(__file__), "newConnectionLineEdit.ui") +) + class NewConnectionLineEdit(QWidget, FORM_CLASS): """ Class designed to control generic behaviors of a widget able to retrieve parameters for a PostGIS database creation. """ - # signals to keep + + # signals to keep connectionChanged = pyqtSignal() dbChanged = pyqtSignal(AbstractDb) problemOccurred = pyqtSignal(str) @@ -56,9 +61,11 @@ def __init__(self, parent=None, isStatic=False): self.isStatic = isStatic if self.isStatic: from DsgTools.gui.ServerTools.viewServers import ViewServersStatic + self.viewServers = ViewServersStatic() else: from DsgTools.gui.ServerTools.viewServers import ViewServers + self.viewServers = ViewServers() self.fillEdgvVersions() self.reset() @@ -68,13 +75,13 @@ def connectSignals(self): Connects all signals. """ self.dsLineEdit.textChanged.connect(self.loadDatabase) - dsChangedAlias = lambda : self.dbChanged.emit(None) + dsChangedAlias = lambda: self.dbChanged.emit(None) self.edgvComboBox.currentIndexChanged.connect(dsChangedAlias) self.mQgsProjectionSelectionWidget.crsChanged.connect(dsChangedAlias) def fillEdgvVersions(self): """ - Populates EDGV combo box with available versions. + Populates EDGV combo box with available versions. """ versions = [ self.tr("EDGV Version..."), @@ -82,7 +89,7 @@ def fillEdgvVersions(self): "EDGV 2.1.3 F Ter", "EDGV 2.1.3 Pro", "EDGV 3.0", - "EDGV 3.0 Pro" + "EDGV 3.0 Pro", ] self.edgvComboBox.addItems(versions) @@ -92,7 +99,7 @@ def currentDb(self): :return: (str) datasource path. """ ds = self.dsLineEdit.text() - return ds if not ds is None and ds != self.tr("New Database") else '' + return ds if not ds is None and ds != self.tr("New Database") else "" def edgvVersion(self): """ @@ -100,7 +107,7 @@ def edgvVersion(self): :return: (str) EDGV version. """ edgv = self.edgvComboBox.currentText() - return edgv if not edgv is None and edgv != self.tr("EDGV Version...") else '' + return edgv if not edgv is None and edgv != self.tr("EDGV Version...") else "" def authId(self): """ @@ -108,7 +115,7 @@ def authId(self): :return: (str) EDGV version. """ crs = self.crs() - return crs.authid() if not crs is None and crs.isValid() else '' + return crs.authid() if not crs is None and crs.isValid() else "" def crs(self): """ @@ -120,7 +127,7 @@ def crs(self): def reset(self): """ - Clears all GUI selections. + Clears all GUI selections. """ self.dsLineEdit.setText(self.tr("New Database")) self.edgvComboBox.setCurrentIndex(0) @@ -146,7 +153,13 @@ def databaseExists(self): """ Checks if database exists. """ - _, host, port, user, password = self.viewServers.getDefaultConnectionParameters() + ( + _, + host, + port, + user, + password, + ) = self.viewServers.getDefaultConnectionParameters() database = self.currentDb() # get a PostGIS database instance to check if database exists abstractDb = DbFactory().createDbFactory(DsgEnums.DriverPostGIS) @@ -167,8 +180,10 @@ def loadDatabase(self, currentText): # if msg: # raise Exception(msg) except Exception as e: - self.problemOccurred.emit(self.tr('A problem occurred! Check log for details.')) - QgsMessageLog.logMessage(':'.join(e.args), "DSGTools Plugin", Qgis.Critical) + self.problemOccurred.emit( + self.tr("A problem occurred! Check log for details.") + ) + QgsMessageLog.logMessage(":".join(e.args), "DSGTools Plugin", Qgis.Critical) def validate(self): """ @@ -182,22 +197,24 @@ def validate(self): # check a valid server name # check if datasource is a valid name and if it already exists into selected server if not self.currentDb() or " " in self.currentDb(): - return self.tr('Invalid datasource (is there a blank space on it?).') + return self.tr("Invalid datasource (is there a blank space on it?).") else: # check if the connection is a valid connection if not self.serverIsValid(): - return self.tr('Invalid connection to server.') + return self.tr("Invalid connection to server.") # check if it exists if self.databaseExists(): - return self.tr('Database {0} already exists into selected server.').format(self.currentDb()) + return self.tr( + "Database {0} already exists into selected server." + ).format(self.currentDb()) # check if a valid EDGV version was selected if not self.edgvVersion(): - return self.tr('Invalid EDGV version.') + return self.tr("Invalid EDGV version.") # check if a valid projection was selected - if not self.crs() or 'EPSG' not in self.authId(): - return self.tr('Invalid CRS.') + if not self.crs() or "EPSG" not in self.authId(): + return self.tr("Invalid CRS.") # if all tests were positive, widget has a valid selection - return '' + return "" def isValid(self): """ @@ -209,7 +226,7 @@ def isValid(self): # if msg: # # if an invalidation reason was given, warn user and nothing else. # iface.messageBar().pushMessage(self.tr('Warning!'), msg, level=Qgis.Warning, duration=5) - return msg == '' + return msg == "" def selectDatasource(self): """ diff --git a/DsgTools/gui/CustomWidgets/ConnectionWidgets/AdvancedConnectionWidgets/newDatabaseLineEdit.py b/DsgTools/gui/CustomWidgets/ConnectionWidgets/AdvancedConnectionWidgets/newDatabaseLineEdit.py index ce4ad9c71..428cb4974 100644 --- a/DsgTools/gui/CustomWidgets/ConnectionWidgets/AdvancedConnectionWidgets/newDatabaseLineEdit.py +++ b/DsgTools/gui/CustomWidgets/ConnectionWidgets/AdvancedConnectionWidgets/newDatabaseLineEdit.py @@ -24,6 +24,7 @@ from qgis.PyQt.QtWidgets import QWidget, QFileDialog from qgis.PyQt.QtCore import pyqtSlot, pyqtSignal, QDir from qgis.PyQt import uic + # from qgis.utils import iface from qgis.core import Qgis, QgsMessageLog @@ -31,14 +32,18 @@ import os -FORM_CLASS, _ = uic.loadUiType(os.path.join(os.path.dirname(__file__), 'newDatabaseLineEdit.ui')) +FORM_CLASS, _ = uic.loadUiType( + os.path.join(os.path.dirname(__file__), "newDatabaseLineEdit.ui") +) + class NewDatabaseLineEdit(QWidget, FORM_CLASS): """ Class designed to control generic behaviors of a widget able to retrieve parameters for a PostGIS database creation. """ - # signals to keep + + # signals to keep connectionChanged = pyqtSignal() dbChanged = pyqtSignal(AbstractDb) problemOccurred = pyqtSignal(str) @@ -49,8 +54,8 @@ def __init__(self, parent=None): """ super(NewDatabaseLineEdit, self).__init__() self.setupUi(self) - self.caption = '' - self.filter = '' + self.caption = "" + self.filter = "" self.fillEdgvVersions() self.connectSignals() self.reset() @@ -64,7 +69,7 @@ def connectSignals(self): def fillEdgvVersions(self): """ - Populates EDGV combo box with available versions. + Populates EDGV combo box with available versions. """ versions = [ self.tr("EDGV Version..."), @@ -72,7 +77,7 @@ def fillEdgvVersions(self): "EDGV 2.1.3 F Ter", "EDGV 2.1.3 Pro", "EDGV 3.0", - "EDGV 3.0 Pro" + "EDGV 3.0 Pro", ] self.edgvComboBox.addItems(versions) @@ -82,7 +87,7 @@ def currentDb(self): :return: (str) datasource path. """ ds = self.dsLineEdit.text() - return ds if not ds is None and ds != self.tr("New Database") else '' + return ds if not ds is None and ds != self.tr("New Database") else "" def edgvVersion(self): """ @@ -90,7 +95,7 @@ def edgvVersion(self): :return: (str) EDGV version. """ edgv = self.edgvComboBox.currentText() - return edgv if not edgv is None and edgv != self.tr("EDGV Version...") else '' + return edgv if not edgv is None and edgv != self.tr("EDGV Version...") else "" def authId(self): """ @@ -98,7 +103,7 @@ def authId(self): :return: (str) EDGV version. """ crs = self.crs() - return crs.authid() if not crs is None and crs.isValid() else '' + return crs.authid() if not crs is None and crs.isValid() else "" def crs(self): """ @@ -110,7 +115,7 @@ def crs(self): def reset(self): """ - Clears all GUI selections. + Clears all GUI selections. """ self.dsLineEdit.setText(self.tr("New Database")) self.edgvComboBox.setCurrentIndex(0) @@ -137,7 +142,7 @@ def databaseExists(self): # for files, it is only necessary to check if file exists and is not empty. ds = self.currentDb() try: - with open(ds, 'rb') as f: + with open(ds, "rb") as f: # read paths l = f.readlines() return bool(l) @@ -149,7 +154,7 @@ def databaseExists(self): # if directory is not empty, check if there are shapefiles in it for f in os.listdir(ds): if len(f) > 4: - if '.shp' == f[-4:].lower(): + if ".shp" == f[-4:].lower(): return True return False @@ -169,8 +174,10 @@ def loadDatabase(self, currentText): # if msg: # raise Exception(msg) except Exception as e: - self.problemOccurred.emit(self.tr('A problem occurred! Check log for details.')) - QgsMessageLog.logMessage(':'.join(e.args), "DSGTools Plugin", Qgis.Critical) + self.problemOccurred.emit( + self.tr("A problem occurred! Check log for details.") + ) + QgsMessageLog.logMessage(":".join(e.args), "DSGTools Plugin", Qgis.Critical) def validate(self): """ @@ -184,23 +191,23 @@ def validate(self): # check a valid server name # check if datasource is a valid name and if it already exists into selected server if not self.currentDb(): - return self.tr('Invalid datasource.') + return self.tr("Invalid datasource.") else: # check if the connection is a valid connection if not self.serverIsValid(): - return self.tr('Invalid connection to server.') + return self.tr("Invalid connection to server.") # check if it exists if self.databaseExists(): - return self.tr('Database {0} already exists.').format(self.currentDb()) + return self.tr("Database {0} already exists.").format(self.currentDb()) pass # check if a valid EDGV version was selected if not self.edgvVersion(): - return self.tr('Invalid EDGV version.') + return self.tr("Invalid EDGV version.") # check if a valid projection was selected - if not self.crs() or 'EPSG' not in self.authId(): - return self.tr('Invalid CRS.') + if not self.crs() or "EPSG" not in self.authId(): + return self.tr("Invalid CRS.") # if all tests were positive, widget has a valid selection - return '' + return "" def isValid(self): """ @@ -212,7 +219,7 @@ def isValid(self): # if msg: # # if an invalidation reason was given, warn user and nothing else. # iface.messageBar().pushMessage(self.tr('Warning!'), msg, level=Qgis.Warning, duration=5) - return msg == '' + return msg == "" def selectDatasource(self): """ diff --git a/DsgTools/gui/CustomWidgets/ConnectionWidgets/ServerConnectionWidgets/customServerConnectionWidget.py b/DsgTools/gui/CustomWidgets/ConnectionWidgets/ServerConnectionWidgets/customServerConnectionWidget.py index 6e7ae6369..38d134f1e 100644 --- a/DsgTools/gui/CustomWidgets/ConnectionWidgets/ServerConnectionWidgets/customServerConnectionWidget.py +++ b/DsgTools/gui/CustomWidgets/ConnectionWidgets/ServerConnectionWidgets/customServerConnectionWidget.py @@ -232,7 +232,9 @@ def populateSpatialiteSelector(self): version = auxAbstractDb.getDatabaseVersion() dbimplversion = auxAbstractDb.getImplementationVersion() dbList.append((dbName, version, dbimplversion)) - self.spatialiteDict[self.getDisplayString(dbName, version, dbimplversion)] = dbPath + self.spatialiteDict[ + self.getDisplayString(dbName, version, dbimplversion) + ] = dbPath except Exception as e: QMessageBox.critical(self, self.tr("Critical!"), ":".join(e.args)) self.clearSpatialiteTab() @@ -254,6 +256,7 @@ def clearSpatialiteTab(self): self.edgvType = None self.selectedDbsDict = dict() self.resetAll.emit() + def clearPostgisTab(self): """ Clears the spatialite tab, returning it to the original state diff --git a/DsgTools/gui/CustomWidgets/ConnectionWidgets/ServerConnectionWidgets/exploreServerWidget.py b/DsgTools/gui/CustomWidgets/ConnectionWidgets/ServerConnectionWidgets/exploreServerWidget.py index 8f09bfb4a..ed51b4d80 100644 --- a/DsgTools/gui/CustomWidgets/ConnectionWidgets/ServerConnectionWidgets/exploreServerWidget.py +++ b/DsgTools/gui/CustomWidgets/ConnectionWidgets/ServerConnectionWidgets/exploreServerWidget.py @@ -38,14 +38,17 @@ from ....CustomWidgets.BasicInterfaceWidgets.progressWidget import ProgressWidget from DsgTools.core.dsgEnums import DsgEnums -FORM_CLASS, _ = uic.loadUiType(os.path.join( - os.path.dirname(__file__), 'exploreServerWidget.ui')) +FORM_CLASS, _ = uic.loadUiType( + os.path.join(os.path.dirname(__file__), "exploreServerWidget.ui") +) + class ExploreServerWidget(QtWidgets.QWidget, FORM_CLASS): abstractDbLoaded = pyqtSignal() serverAbstractDbLoaded = pyqtSignal(AbstractDb) clearWidgets = pyqtSignal() - def __init__(self, parent = None): + + def __init__(self, parent=None): """Constructor.""" super(ExploreServerWidget, self).__init__(parent) self.setupUi(self) @@ -60,26 +63,26 @@ def getServers(self): Gets server from QSettings """ settings = QSettings() - settings.beginGroup('PostgreSQL/servers') + settings.beginGroup("PostgreSQL/servers") currentConnections = settings.childGroups() settings.endGroup() return currentConnections - + def getServerConfiguration(self, name): """ Gets server configuration - name: server name + name: server name """ settings = QSettings() - settings.beginGroup('PostgreSQL/servers/'+name) - host = settings.value('host') - port = settings.value('port') - user = settings.value('username') - password = settings.value('password') + settings.beginGroup("PostgreSQL/servers/" + name) + host = settings.value("host") + port = settings.value("port") + user = settings.value("username") + password = settings.value("password") settings.endGroup() - + return (host, port, user, password) - + def browseServer(self, dbList, host, port, user, password): """ Browses server for EDGV databases @@ -96,21 +99,40 @@ def browseServer(self, dbList, host, port, user, password): if self.serverWidget.abstractDb.checkSuperUser(): canLoad = True else: - QMessageBox.warning(self, self.tr('Info!'), self.tr('Connection refused. Connect with a super user to inspect server.')) + QMessageBox.warning( + self, + self.tr("Info!"), + self.tr( + "Connection refused. Connect with a super user to inspect server." + ), + ) return [] except Exception as e: - QMessageBox.critical(self, self.tr('Critical!'), ':'.join(e.args)) + QMessageBox.critical(self, self.tr("Critical!"), ":".join(e.args)) if canLoad: - progress = ProgressWidget(1,len(dbList),self.tr('Loading databases from server... '), parent = self) + progress = ProgressWidget( + 1, + len(dbList), + self.tr("Loading databases from server... "), + parent=self, + ) progress.initBar() gen = self.factory.createSqlGenerator(driver=DsgEnums.DriverPostGIS) edvgDbList = [] for database in dbList: postgisDb = self.dbFactory.createDbFactory(DsgEnums.DriverPostGIS) - postgisDb.connectDatabaseWithParameters(host, port, database, user, password) + postgisDb.connectDatabaseWithParameters( + host, port, database, user, password + ) if not postgisDb.db.open(): - qgis.utils.iface.messageBar().pushMessage('DB :'+database+'| msg: '+postgisDb.db.lastError().databaseText(), level=Qgis.Critical) - + qgis.utils.iface.messageBar().pushMessage( + "DB :" + + database + + "| msg: " + + postgisDb.db.lastError().databaseText(), + level=Qgis.Critical, + ) + query = QSqlQuery(postgisDb.db) if query.exec_(gen.getEDGVVersion()): while query.next(): @@ -119,34 +141,44 @@ def browseServer(self, dbList, host, port, user, password): edvgDbList.append((database, version)) progress.step() return edvgDbList - + def getDbsFromServer(self, name): """ Gets server databases name: server name """ gen = self.factory.createSqlGenerator(driver=DsgEnums.DriverPostGIS) - + (host, port, user, password) = self.getServerConfiguration(name) - database = 'postgres' + database = "postgres" postgisDb = self.dbFactory.createDbFactory(DsgEnums.DriverPostGIS) postgisDb.connectDatabaseWithParameters(host, port, database, user, password) if not postgisDb.db.open(): - QgsMessageLog.logMessage(db.lastError().text(), "DSGTools Plugin", Qgis.Critical) - QMessageBox.critical(self.iface.mainWindow(), self.tr('Critical'), self.tr('A problem occurred! Check log for details.')) - + QgsMessageLog.logMessage( + db.lastError().text(), "DSGTools Plugin", Qgis.Critical + ) + QMessageBox.critical( + self.iface.mainWindow(), + self.tr("Critical"), + self.tr("A problem occurred! Check log for details."), + ) + query = QSqlQuery(gen.getDatabasesFromServer(), postgisDb.db) if not query.isActive(): - QMessageBox.critical(self.iface.mainWindow(), self.tr('Critical'), self.tr("Problem executing query: ")+query.lastError().text()) - + QMessageBox.critical( + self.iface.mainWindow(), + self.tr("Critical"), + self.tr("Problem executing query: ") + query.lastError().text(), + ) + dbList = [] while query.next(): dbList.append(query.value(0)) postgisDb.closeDatabase() return self.browseServer(dbList, host, port, user, password) - + @pyqtSlot(bool) - def on_createNewServerPushButton_clicked(self): + def on_createNewServerPushButton_clicked(self): """ Opens the View Server dialog """ @@ -159,12 +191,14 @@ def populateServersCombo(self): Populates the server name combo box """ self.serversCombo.clear() - self.serversCombo.addItem(self.tr('Select Server')) + self.serversCombo.addItem(self.tr("Select Server")) currentConnections = self.getServers() for connection in currentConnections: (host, port, user, password) = self.getServerConfiguration(connection) - self.serversCombo.addItem('{3} ({0}@{1}:{2})'.format(user, host, port, connection)) - + self.serversCombo.addItem( + "{3} ({0}@{1}:{2})".format(user, host, port, connection) + ) + @pyqtSlot(int) def on_serversCombo_currentIndexChanged(self): """ @@ -174,19 +208,35 @@ def on_serversCombo_currentIndexChanged(self): if self.serversCombo.currentIndex() > 0: self.abstractDb = self.dbFactory.createDbFactory(DsgEnums.DriverPostGIS) if not self.abstractDb: - QMessageBox.critical(self.iface.mainWindow(), self.tr('Critical'), self.tr('A problem occurred! Check log for details.')) + QMessageBox.critical( + self.iface.mainWindow(), + self.tr("Critical"), + self.tr("A problem occurred! Check log for details."), + ) return - (host, port, user, password) = self.abstractDb.getServerConfiguration(self.serversCombo.currentText().split('(')[0][0:-1]) + (host, port, user, password) = self.abstractDb.getServerConfiguration( + self.serversCombo.currentText().split("(")[0][0:-1] + ) if host or port or user: - self.abstractDb.connectDatabaseWithParameters(host, port, 'postgres', user, password) + self.abstractDb.connectDatabaseWithParameters( + host, port, "postgres", user, password + ) if self.superNeeded: try: if not self.abstractDb.checkSuperUser(): - QMessageBox.warning(self, self.tr('Info!'), self.tr('Connection refused. Connect with a super user to inspect server.')) + QMessageBox.warning( + self, + self.tr("Info!"), + self.tr( + "Connection refused. Connect with a super user to inspect server." + ), + ) self.serversCombo.setCurrentIndex(0) return except Exception as e: - QMessageBox.critical(self, self.tr('Critical!'), ':'.join(e.args)) + QMessageBox.critical( + self, self.tr("Critical!"), ":".join(e.args) + ) self.abstractDbLoaded.emit() else: try: @@ -196,16 +246,18 @@ def on_serversCombo_currentIndexChanged(self): except: pass self.serverAbstractDbLoaded.emit(self.abstractDb) - + def getServerParameters(self): """ Gets postgis server parameters """ if self.serversCombo.currentIndex() != 0: - return self.abstractDb.getServerConfiguration(self.serversCombo.currentText().split('(')[0][0:-1]) + return self.abstractDb.getServerConfiguration( + self.serversCombo.currentText().split("(")[0][0:-1] + ) else: return (None, None, None, None) - + def clearAll(self): """ Resets the widget @@ -217,4 +269,3 @@ def clearAll(self): except: pass self.serversCombo.setCurrentIndex(0) - diff --git a/DsgTools/gui/CustomWidgets/ConnectionWidgets/connectionWidget.py b/DsgTools/gui/CustomWidgets/ConnectionWidgets/connectionWidget.py index 3169f1b4a..ed5e79e32 100644 --- a/DsgTools/gui/CustomWidgets/ConnectionWidgets/connectionWidget.py +++ b/DsgTools/gui/CustomWidgets/ConnectionWidgets/connectionWidget.py @@ -22,7 +22,7 @@ """ import os -from qgis.core import QgsCoordinateReferenceSystem,QgsMessageLog +from qgis.core import QgsCoordinateReferenceSystem, QgsMessageLog from qgis.core import Qgis from qgis.PyQt import QtWidgets, uic @@ -37,15 +37,18 @@ from DsgTools.core.Factories.DbFactory.abstractDb import AbstractDb from DsgTools.core.dsgEnums import DsgEnums -FORM_CLASS, _ = uic.loadUiType(os.path.join( - os.path.dirname(__file__), 'connectionWidget.ui')) +FORM_CLASS, _ = uic.loadUiType( + os.path.join(os.path.dirname(__file__), "connectionWidget.ui") +) + class ConnectionWidget(QtWidgets.QWidget, FORM_CLASS): connectionChanged = pyqtSignal() problemOccurred = pyqtSignal(str) dbChanged = pyqtSignal(AbstractDb) styleChanged = pyqtSignal(dict) - def __init__(self, parent = None): + + def __init__(self, parent=None): """Constructor.""" super(ConnectionWidget, self).__init__(parent) # Set up the user interface from Designer. @@ -58,8 +61,7 @@ def __init__(self, parent = None): self.serverWidget.populateServersCombo() self.serverWidget.abstractDbLoaded.connect(self.getDatabasesFromServer) self.serverWidget.clearWidgets.connect(self.clearAll) - - + def __del__(self): """ Closes the database @@ -73,38 +75,38 @@ def closeDatabase(self): if self.abstractDb: del self.abstractDb self.abstractDb = None - + def clearAll(self): """ Resets the initial state """ - self.filename = '' + self.filename = "" self.dbLoaded = False self.epsg = 0 self.crs = None - + self.abstractDb = None self.isSpatialite = False self.abstractDbFactory = DbFactory() self.utils = Utils() - #populating the postgis combobox + # populating the postgis combobox self.comboBoxPostgis.clear() - self.spatialiteFileEdit.setReadOnly(True) + self.spatialiteFileEdit.setReadOnly(True) self.postGISCrsEdit.setReadOnly(True) - self.spatialiteCrsEdit.setReadOnly(True) + self.spatialiteCrsEdit.setReadOnly(True) self.edgvSpatialiteVersionEdit.setReadOnly(True) - self.edgvPostgisVersionEdit.setReadOnly(True) + self.edgvPostgisVersionEdit.setReadOnly(True) def setInitialState(self): """ Sets the initial state """ - self.filename = '' + self.filename = "" self.dbLoaded = False self.epsg = 0 self.crs = None - + self.abstractDb = None self.isSpatialite = False self.tabWidget.setCurrentIndex(0) @@ -112,13 +114,13 @@ def setInitialState(self): self.utils = Utils() self.serverWidget.serversCombo.setCurrentIndex(0) - #populating the postgis combobox + # populating the postgis combobox self.comboBoxPostgis.clear() - self.spatialiteFileEdit.setReadOnly(True) + self.spatialiteFileEdit.setReadOnly(True) self.postGISCrsEdit.setReadOnly(True) - self.spatialiteCrsEdit.setReadOnly(True) + self.spatialiteCrsEdit.setReadOnly(True) self.edgvSpatialiteVersionEdit.setReadOnly(True) - self.edgvPostgisVersionEdit.setReadOnly(True) + self.edgvPostgisVersionEdit.setReadOnly(True) @pyqtSlot(int) def on_comboBoxPostgis_currentIndexChanged(self): @@ -126,47 +128,47 @@ def on_comboBoxPostgis_currentIndexChanged(self): Updates database information when the combo box changes """ if self.comboBoxPostgis.currentIndex() > 0: - self.postGISCrsEdit.setText('') + self.postGISCrsEdit.setText("") self.postGISCrsEdit.setReadOnly(True) - self.edgvPostgisVersionEdit.setText('') - self.edgvPostgisVersionEdit.setReadOnly(True) + self.edgvPostgisVersionEdit.setText("") + self.edgvPostgisVersionEdit.setReadOnly(True) self.loadDatabase() self.connectionChanged.emit() - + @pyqtSlot(bool) - def on_pushButtonOpenFile_clicked(self): + def on_pushButtonOpenFile_clicked(self): """ Loads a spatialite database """ self.loadDatabase() if self.isDBConnected(): self.connectionChanged.emit() - + @pyqtSlot(int) def on_tabWidget_currentChanged(self): """ Changes the tab to work with spatialite or postgis databases """ - self.filename = '' + self.filename = "" self.comboBoxPostgis.clear() self.dbLoaded = False self.epsg = 0 self.crs = None - self.dbVersion = '' + self.dbVersion = "" self.serverWidget.serversCombo.setCurrentIndex(0) self.spatialiteFileEdit.setReadOnly(True) self.spatialiteFileEdit.setText(self.filename) - self.postGISCrsEdit.setText('') + self.postGISCrsEdit.setText("") self.postGISCrsEdit.setReadOnly(True) - self.spatialiteCrsEdit.setText('') - self.spatialiteCrsEdit.setReadOnly(True) - self.edgvSpatialiteVersionEdit.setText('') + self.spatialiteCrsEdit.setText("") + self.spatialiteCrsEdit.setReadOnly(True) + self.edgvSpatialiteVersionEdit.setText("") self.edgvSpatialiteVersionEdit.setReadOnly(True) - self.edgvPostgisVersionEdit.setText('') + self.edgvPostgisVersionEdit.setText("") self.edgvPostgisVersionEdit.setReadOnly(True) - self.mGroupBox.setTitle(self.tr('Database connection')) - - #Setting the database type + self.mGroupBox.setTitle(self.tr("Database connection")) + + # Setting the database type if self.tabWidget.currentIndex() == 1: self.isSpatialite = True else: @@ -179,19 +181,29 @@ def loadDatabase(self): self.closeDatabase() try: if self.isSpatialite: - self.abstractDb = self.abstractDbFactory.createDbFactory(DsgEnums.DriverSpatiaLite) + self.abstractDb = self.abstractDbFactory.createDbFactory( + DsgEnums.DriverSpatiaLite + ) self.abstractDb.connectDatabase() self.spatialiteFileEdit.setText(self.abstractDb.db.databaseName()) - self.edgvSpatialiteVersionEdit.setText(self.abstractDb.getDatabaseVersion()) - + self.edgvSpatialiteVersionEdit.setText( + self.abstractDb.getDatabaseVersion() + ) + else: - self.abstractDb = self.abstractDbFactory.createDbFactory(DsgEnums.DriverPostGIS) + self.abstractDb = self.abstractDbFactory.createDbFactory( + DsgEnums.DriverPostGIS + ) (host, port, user, password) = self.serverWidget.getServerParameters() dbName = self.comboBoxPostgis.currentText() - self.abstractDb.connectDatabaseWithParameters(host, port, dbName, user, password) - self.edgvPostgisVersionEdit.setText(self.abstractDb.getDatabaseVersion()) + self.abstractDb.connectDatabaseWithParameters( + host, port, dbName, user, password + ) + self.edgvPostgisVersionEdit.setText( + self.abstractDb.getDatabaseVersion() + ) serverName = self.serverWidget.serversCombo.currentText() - newText = dbName + self.tr(' on ') + serverName + newText = dbName + self.tr(" on ") + serverName self.mGroupBox.setToolTip(newText) # self.mGroupBox.setTitle(newText) @@ -202,13 +214,17 @@ def loadDatabase(self): self.styles = self.abstractDb.getStyleDict(self.dbVersion) self.styleChanged.emit(self.styles) self.dbChanged.emit(self.abstractDb) - if self.dbVersion == '-1': - self.problemOccurred.emit(self.tr('This is not a valid DsgTools database!')) + if self.dbVersion == "-1": + self.problemOccurred.emit( + self.tr("This is not a valid DsgTools database!") + ) else: self.setCRS() except Exception as e: - self.problemOccurred.emit(self.tr('A problem occurred! Check log for details.')) - QgsMessageLog.logMessage(':'.join(e.args), "DSGTools Plugin", Qgis.Critical) + self.problemOccurred.emit( + self.tr("A problem occurred! Check log for details.") + ) + QgsMessageLog.logMessage(":".join(e.args), "DSGTools Plugin", Qgis.Critical) def setCRS(self): """ @@ -217,9 +233,13 @@ def setCRS(self): try: self.epsg = self.abstractDb.findEPSG() if self.epsg == -1: - self.problemOccurred.emit(self.tr('Coordinate Reference System not set or invalid!')) + self.problemOccurred.emit( + self.tr("Coordinate Reference System not set or invalid!") + ) else: - self.crs = QgsCoordinateReferenceSystem(self.epsg, QgsCoordinateReferenceSystem.EpsgCrsId) + self.crs = QgsCoordinateReferenceSystem( + self.epsg, QgsCoordinateReferenceSystem.EpsgCrsId + ) if self.isSpatialite: self.spatialiteCrsEdit.setText(self.crs.description()) self.spatialiteCrsEdit.setReadOnly(True) @@ -227,60 +247,67 @@ def setCRS(self): self.postGISCrsEdit.setText(self.crs.description()) self.postGISCrsEdit.setReadOnly(True) except Exception as e: - self.problemOccurred.emit(self.tr('A problem occurred! Check log for details.')) - QgsMessageLog.logMessage(':'.join(e.args), "DSGTools Plugin", Qgis.Critical) + self.problemOccurred.emit( + self.tr("A problem occurred! Check log for details.") + ) + QgsMessageLog.logMessage(":".join(e.args), "DSGTools Plugin", Qgis.Critical) - def isDBConnected(self): """ Checks if the database is already loaded """ return self.dbLoaded - + def getDBVersion(self): """ Gets the database version """ - ret = '' + ret = "" try: ret = self.abstractDb.getDatabaseVersion() except Exception as e: - self.problemOccurred.emit(self.tr('A problem occurred! Check log for details.')) - QgsMessageLog.logMessage(':'.join(e.args), "DSGTools Plugin", Qgis.Critical) + self.problemOccurred.emit( + self.tr("A problem occurred! Check log for details.") + ) + QgsMessageLog.logMessage(":".join(e.args), "DSGTools Plugin", Qgis.Critical) return ret - + def getQmlPath(self): """ Gets the QML path """ - ret = '' + ret = "" try: ret = self.abstractDb.getQmlDir() except Exception as e: - self.problemOccurred.emit(self.tr('A problem occurred! Check log for details.')) - QgsMessageLog.logMessage(':'.join(e.args), "DSGTools Plugin", Qgis.Critical) + self.problemOccurred.emit( + self.tr("A problem occurred! Check log for details.") + ) + QgsMessageLog.logMessage(":".join(e.args), "DSGTools Plugin", Qgis.Critical) return ret - + def getDatabasesFromServer(self): """ Gets databases from server - """ + """ QApplication.setOverrideCursor(QCursor(Qt.WaitCursor)) try: if self.serverWidget.abstractDb: - dbList = self.serverWidget.abstractDb.getEDGVDbsFromServer(parentWidget = self) + dbList = self.serverWidget.abstractDb.getEDGVDbsFromServer( + parentWidget=self + ) dbList.sort() self.comboBoxPostgis.clear() - self.comboBoxPostgis.addItem(self.tr('Select Database')) + self.comboBoxPostgis.addItem(self.tr("Select Database")) for db, version in dbList: self.comboBoxPostgis.addItem(db) - + else: self.setInitialState() QApplication.restoreOverrideCursor() return except Exception as e: QApplication.restoreOverrideCursor() - QMessageBox.critical(self, self.tr('Critical!'), ':'.join(e.args)) + QMessageBox.critical(self, self.tr("Critical!"), ":".join(e.args)) self.setInitialState() - QApplication.restoreOverrideCursor() \ No newline at end of file + QApplication.restoreOverrideCursor() diff --git a/DsgTools/gui/CustomWidgets/CustomDbManagementWidgets/addAttributeWidget.py b/DsgTools/gui/CustomWidgets/CustomDbManagementWidgets/addAttributeWidget.py index 7d7f7f65d..c940faf7e 100644 --- a/DsgTools/gui/CustomWidgets/CustomDbManagementWidgets/addAttributeWidget.py +++ b/DsgTools/gui/CustomWidgets/CustomDbManagementWidgets/addAttributeWidget.py @@ -33,25 +33,31 @@ from DsgTools.gui.ServerTools.viewServers import ViewServers from DsgTools.core.Factories.SqlFactory.sqlGeneratorFactory import SqlGeneratorFactory from DsgTools.core.Factories.DbFactory.dbFactory import DbFactory -from DsgTools.gui.CustomWidgets.CustomDbManagementWidgets.domainSetter import DomainSetter -from DsgTools.gui.Misc.PostgisCustomization.CustomJSONTools.customJSONBuilder import CustomJSONBuilder +from DsgTools.gui.CustomWidgets.CustomDbManagementWidgets.domainSetter import ( + DomainSetter, +) +from DsgTools.gui.Misc.PostgisCustomization.CustomJSONTools.customJSONBuilder import ( + CustomJSONBuilder, +) + +FORM_CLASS, _ = uic.loadUiType( + os.path.join(os.path.dirname(__file__), "addAttributeWidget.ui") +) -FORM_CLASS, _ = uic.loadUiType(os.path.join( - os.path.dirname(__file__), 'addAttributeWidget.ui')) class AddAttributeWidget(QtWidgets.QWidget, FORM_CLASS): - def __init__(self, abstractDb, uiParameterJsonDict = None, parent = None): + def __init__(self, abstractDb, uiParameterJsonDict=None, parent=None): """Constructor.""" super(self.__class__, self).__init__(parent) self.abstractDb = abstractDb self.setupUi(self) - regex = QtCore.QRegExp('[a-z]*') + regex = QtCore.QRegExp("[a-z]*") validator = QtGui.QRegExpValidator(regex, self.nameLineEdit) self.nameLineEdit.setValidator(validator) self.domainSetter = None self.jsonBuilder = CustomJSONBuilder() self.populateFromUiParameterJsonDict(uiParameterJsonDict) - + def populateFromUiParameterJsonDict(self, uiParameterJsonDict): """ populates ui from uiParameterJsonDict with the following keys: @@ -64,16 +70,22 @@ def populateFromUiParameterJsonDict(self, uiParameterJsonDict): } """ if uiParameterJsonDict: - self.nameLineEdit.setText(uiParameterJsonDict['nameLineEdit']) - if uiParameterJsonDict['references']: - idx = self.typeComboBox.findText(self.tr('EDGV Domain'), flags = Qt.MatchExactly) + self.nameLineEdit.setText(uiParameterJsonDict["nameLineEdit"]) + if uiParameterJsonDict["references"]: + idx = self.typeComboBox.findText( + self.tr("EDGV Domain"), flags=Qt.MatchExactly + ) self.typeComboBox.setCurrentIndex(idx) - self.instantiateDomainSetter(uiParameterJsonDict['references']) + self.instantiateDomainSetter(uiParameterJsonDict["references"]) else: - self.typeComboBox.setCurrentIndex(int(uiParameterJsonDict['typeComboBox'])) - if uiParameterJsonDict['notNullcheckBox']: + self.typeComboBox.setCurrentIndex( + int(uiParameterJsonDict["typeComboBox"]) + ) + if uiParameterJsonDict["notNullcheckBox"]: self.notNullcheckBox.setCheckState(2) - idx = self.defaultComboBox.findText(uiParameterJsonDict['defaultComboBox'], flags = Qt.MatchExactly) + idx = self.defaultComboBox.findText( + uiParameterJsonDict["defaultComboBox"], flags=Qt.MatchExactly + ) self.defaultComboBox.setCurrentIndex(idx) def enableItems(self, enabled): @@ -82,18 +94,20 @@ def enableItems(self, enabled): self.referencesPushButton.setEnabled(enabled) self.defaultLabel.setEnabled(enabled) self.defaultComboBox.setEnabled(enabled) - + @pyqtSlot(int) def on_typeComboBox_currentIndexChanged(self, idx): - edgvDomainIdx = self.typeComboBox.findText(self.tr('EDGV Domain'), flags = Qt.MatchExactly) + edgvDomainIdx = self.typeComboBox.findText( + self.tr("EDGV Domain"), flags=Qt.MatchExactly + ) if idx == edgvDomainIdx: self.enableItems(True) else: self.enableItems(False) - self.referencesLineEdit.setText('') + self.referencesLineEdit.setText("") self.defaultComboBox.clear() self.domainSetter = None - + @pyqtSlot(bool) def on_referencesPushButton_clicked(self): if not self.domainSetter: @@ -101,7 +115,7 @@ def on_referencesPushButton_clicked(self): else: self.domainSetter.show() - def instantiateDomainSetter(self, uiParameterJsonDict = None): + def instantiateDomainSetter(self, uiParameterJsonDict=None): self.domainSetter = DomainSetter(self.abstractDb, uiParameterJsonDict) self.domainSetter.domainChanged.connect(self.populateDefaultCombo) if not uiParameterJsonDict: @@ -113,9 +127,9 @@ def instantiateDomainSetter(self, uiParameterJsonDict = None): def populateDefaultCombo(self, domainName, domainDict, filterClause): self.referencesLineEdit.setText(domainName) self.defaultComboBox.clear() - addList = [''] + addList = [""] for domain in list(domainDict.keys()): - if filterClause == dict(): + if filterClause == dict(): if domain not in addList: addList.append(domain) elif domain in list(filterClause.keys()): @@ -123,24 +137,24 @@ def populateDefaultCombo(self, domainName, domainDict, filterClause): addList.append(domain) for item in addList: self.defaultComboBox.addItem(item) - + def getChildWidgets(self): return self.domainSetter def validate(self): invalidatedList = [] - if self.nameLineEdit.text() == '': + if self.nameLineEdit.text() == "": return False if self.typeComboBox.currentIndex() == 0: return False return True - + def validateDiagnosis(self): - invalidatedReason = '' - if self.nameLineEdit.text() == '': - invalidatedReason += self.tr('Attribute must have a name.\n') + invalidatedReason = "" + if self.nameLineEdit.text() == "": + invalidatedReason += self.tr("Attribute must have a name.\n") if self.typeComboBox.currentIndex() == 0: - invalidatedReason += self.tr('Attribute must have a type.\n') + invalidatedReason += self.tr("Attribute must have a type.\n") return invalidatedReason def getJSONTag(self): @@ -148,8 +162,8 @@ def getJSONTag(self): raise Exception(self.validateDiagnosis()) attrName = self.nameLineEdit.text() attrType = self.typeComboBox.currentText() - if attrType == self.tr('EDGV Domain'): - attrType = 'smallint' + if attrType == self.tr("EDGV Domain"): + attrType = "smallint" isPk = False if self.notNullcheckBox.isChecked(): isNullable = False @@ -157,16 +171,28 @@ def getJSONTag(self): isNullable = True defaultComboCurrentText = self.defaultComboBox.currentText() if not self.domainSetter: - return self.jsonBuilder.buildAttributeElement(attrName, attrType, isPk, isNullable) + return self.jsonBuilder.buildAttributeElement( + attrName, attrType, isPk, isNullable + ) else: - if defaultComboCurrentText == '': + if defaultComboCurrentText == "": defaultValue = None else: defaultValue = self.domainSetter.domainDict[defaultComboCurrentText] references = self.domainSetter.domainName filter = list(self.domainSetter.filterClause.values()) - return [self.jsonBuilder.buildAttributeElement(attrName, attrType, isPk, isNullable, defaultValue, references, filter)] - + return [ + self.jsonBuilder.buildAttributeElement( + attrName, + attrType, + isPk, + isNullable, + defaultValue, + references, + filter, + ) + ] + def getUiParameterJsonDict(self): """ builds a dict with the following format: @@ -179,11 +205,13 @@ def getUiParameterJsonDict(self): } """ uiParameterJsonDict = dict() - uiParameterJsonDict['nameLineEdit'] = self.nameLineEdit.text() - uiParameterJsonDict['typeComboBox'] = self.typeComboBox.currentText() - uiParameterJsonDict['notNullcheckBox'] = self.notNullcheckBox.isChecked() - uiParameterJsonDict['defaultComboBox'] = self.defaultComboBox.currentText() - uiParameterJsonDict['references'] = None + uiParameterJsonDict["nameLineEdit"] = self.nameLineEdit.text() + uiParameterJsonDict["typeComboBox"] = self.typeComboBox.currentText() + uiParameterJsonDict["notNullcheckBox"] = self.notNullcheckBox.isChecked() + uiParameterJsonDict["defaultComboBox"] = self.defaultComboBox.currentText() + uiParameterJsonDict["references"] = None if self.domainSetter: - uiParameterJsonDict['references'] = self.domainSetter.getUiParameterJsonDict() - return uiParameterJsonDict \ No newline at end of file + uiParameterJsonDict[ + "references" + ] = self.domainSetter.getUiParameterJsonDict() + return uiParameterJsonDict diff --git a/DsgTools/gui/CustomWidgets/CustomDbManagementWidgets/alterDefaultWidget.py b/DsgTools/gui/CustomWidgets/CustomDbManagementWidgets/alterDefaultWidget.py index bb0694b37..622352c4f 100644 --- a/DsgTools/gui/CustomWidgets/CustomDbManagementWidgets/alterDefaultWidget.py +++ b/DsgTools/gui/CustomWidgets/CustomDbManagementWidgets/alterDefaultWidget.py @@ -30,15 +30,20 @@ from qgis.PyQt.QtCore import pyqtSlot, pyqtSignal, QSettings, Qt from qgis.PyQt.QtWidgets import QApplication from qgis.PyQt.QtGui import QCursor + # DSGTools imports -from DsgTools.gui.Misc.PostgisCustomization.CustomJSONTools.customJSONBuilder import CustomJSONBuilder +from DsgTools.gui.Misc.PostgisCustomization.CustomJSONTools.customJSONBuilder import ( + CustomJSONBuilder, +) from DsgTools.core.Utils.utils import Utils -FORM_CLASS, _ = uic.loadUiType(os.path.join( - os.path.dirname(__file__), 'alterDefaultWidget.ui')) +FORM_CLASS, _ = uic.loadUiType( + os.path.join(os.path.dirname(__file__), "alterDefaultWidget.ui") +) + class AlterDefaultWidget(QtWidgets.QWidget, FORM_CLASS): - def __init__(self, abstractDb, uiParameterJsonDict = None, parent = None): + def __init__(self, abstractDb, uiParameterJsonDict=None, parent=None): """Constructor.""" super(self.__class__, self).__init__(parent) self.abstractDb = abstractDb @@ -50,7 +55,7 @@ def __init__(self, abstractDb, uiParameterJsonDict = None, parent = None): self.domainDict = self.abstractDb.getDbDomainDict(geomDict) self.utils = Utils() self.populateFromUiParameterJsonDict(uiParameterJsonDict) - + def populateFromUiParameterJsonDict(self, uiParameterJsonDict): """ builds a dict with the following format: @@ -64,27 +69,35 @@ def populateFromUiParameterJsonDict(self, uiParameterJsonDict): } """ if uiParameterJsonDict: - if uiParameterJsonDict['allTablesCheckBox']: + if uiParameterJsonDict["allTablesCheckBox"]: self.allTablesCheckBox.setCheckState(Qt.Checked) else: - schemaIdx = self.schemaComboBox.findText(uiParameterJsonDict['schemaComboBox'], flags = Qt.MatchExactly) + schemaIdx = self.schemaComboBox.findText( + uiParameterJsonDict["schemaComboBox"], flags=Qt.MatchExactly + ) self.schemaComboBox.setCurrentIndex(schemaIdx) - tableIdx = self.tableComboBox.findText(uiParameterJsonDict['tableComboBox'], flags = Qt.MatchExactly) + tableIdx = self.tableComboBox.findText( + uiParameterJsonDict["tableComboBox"], flags=Qt.MatchExactly + ) self.tableComboBox.setCurrentIndex(tableIdx) - if uiParameterJsonDict['allAttributesCheckBox']: + if uiParameterJsonDict["allAttributesCheckBox"]: self.allAttributesCheckBox.setCheckState(Qt.Checked) else: - attributeIdx = self.attributeComboBox.findText(uiParameterJsonDict['attributeComboBox'], flags = Qt.MatchExactly) + attributeIdx = self.attributeComboBox.findText( + uiParameterJsonDict["attributeComboBox"], flags=Qt.MatchExactly + ) self.attributeComboBox.setCurrentIndex(attributeIdx) - idx = self.singleValueComboBox.findText(uiParameterJsonDict['singleValueComboBox'], flags = Qt.MatchExactly) + idx = self.singleValueComboBox.findText( + uiParameterJsonDict["singleValueComboBox"], flags=Qt.MatchExactly + ) self.singleValueComboBox.setCurrentIndex(idx) def populateSchemaCombo(self): self.schemaComboBox.clear() - self.schemaComboBox.addItem(self.tr('Select a schema')) + self.schemaComboBox.addItem(self.tr("Select a schema")) schemaList = self.abstractDb.getGeometricSchemaList() for schema in schemaList: - if schema not in ['views', 'validation']: + if schema not in ["views", "validation"]: self.schemaComboBox.addItem(schema) @pyqtSlot(int) @@ -99,7 +112,7 @@ def on_schemaComboBox_currentIndexChanged(self, idx): schema = self.schemaComboBox.currentText() self.tableComboBox.setEnabled(True) self.tableComboBox.clear() - self.tableComboBox.addItem(self.tr('Select a table')) + self.tableComboBox.addItem(self.tr("Select a table")) tableList = self.abstractDb.getGeometricTableListFromSchema(schema) for table in tableList: self.tableComboBox.addItem(table) @@ -114,22 +127,26 @@ def on_tableComboBox_currentIndexChanged(self, idx): tableName = self.tableComboBox.currentText() self.attributeComboBox.setEnabled(True) self.attributeComboBox.clear() - self.attributeComboBox.addItem(self.tr('Select an attribute')) + self.attributeComboBox.addItem(self.tr("Select an attribute")) if tableName in list(self.domainDict.keys()): - attributeList = list(self.domainDict[tableName]['columns'].keys()) + attributeList = list(self.domainDict[tableName]["columns"].keys()) for attribute in attributeList: self.attributeComboBox.addItem(attribute) self.singleValueComboBox.clear() - - @pyqtSlot(int, name='on_schemaComboBox_currentIndexChanged') - @pyqtSlot(int, name='on_tableComboBox_currentIndexChanged') + + @pyqtSlot(int, name="on_schemaComboBox_currentIndexChanged") + @pyqtSlot(int, name="on_tableComboBox_currentIndexChanged") def populateOnSelectAll(self): QApplication.setOverrideCursor(QCursor(Qt.WaitCursor)) - if self.allTablesCheckBox.checkState() == 2 or (self.allAttributesCheckBox.checkState() == 2 and self.schemaComboBox.currentIndex() != 0 and self.tableComboBox.currentIndex() != 0): + if self.allTablesCheckBox.checkState() == 2 or ( + self.allAttributesCheckBox.checkState() == 2 + and self.schemaComboBox.currentIndex() != 0 + and self.tableComboBox.currentIndex() != 0 + ): self.attributeComboBox.clear() self.attributeComboBox.setEnabled(False) self.singleValueComboBox.clear() - self.singleValueComboBox.addItem(self.tr('Select a value to alter')) + self.singleValueComboBox.addItem(self.tr("Select a value to alter")) if self.allAttributesCheckBox.checkState() == 2: tableList = [self.tableComboBox.currentText()] else: @@ -137,15 +154,23 @@ def populateOnSelectAll(self): allValueList = [] idxList = [] for tableName in tableList: - for attrName in list(self.domainDict[tableName]['columns'].keys()): - for code in self.domainDict[tableName]['columns'][attrName]['values']: - value = self.domainDict[tableName]['columns'][attrName]['values'][code] + for attrName in list(self.domainDict[tableName]["columns"].keys()): + for code in self.domainDict[tableName]["columns"][attrName][ + "values" + ]: + value = self.domainDict[tableName]["columns"][attrName][ + "values" + ][code] if value not in allValueList: allValueList.append(value) for value in allValueList: for tableName in tableList: - for attrName in list(self.domainDict[tableName]['columns'].keys()): - if value not in list(self.domainDict[tableName]['columns'][attrName]['values'].values()): + for attrName in list(self.domainDict[tableName]["columns"].keys()): + if value not in list( + self.domainDict[tableName]["columns"][attrName][ + "values" + ].values() + ): idx = allValueList.index(value) if idx not in idxList: idxList.append(idx) @@ -155,7 +180,7 @@ def populateOnSelectAll(self): for value in allValueList: self.singleValueComboBox.addItem(value) QApplication.restoreOverrideCursor() - + @pyqtSlot(int) def on_attributeComboBox_currentIndexChanged(self, idx): if idx == 0: @@ -167,23 +192,38 @@ def on_attributeComboBox_currentIndexChanged(self, idx): tableFilter = [] filterToList = [] self.singleValueComboBox.clear() - self.singleValueComboBox.addItem(self.tr('Select a value to alter')) + self.singleValueComboBox.addItem(self.tr("Select a value to alter")) tableName = self.tableComboBox.currentText() attributeName = self.attributeComboBox.currentText() if tableName in list(self.domainDict.keys()): - if attributeName in list(self.domainDict[tableName]['columns'].keys()): - attrDomainDict = self.domainDict[tableName]['columns'][attributeName]['values'] + if attributeName in list(self.domainDict[tableName]["columns"].keys()): + attrDomainDict = self.domainDict[tableName]["columns"][attributeName][ + "values" + ] for value in list(attrDomainDict.values()): self.singleValueComboBox.addItem(value) - defaultCode = self.abstractDb.getDefaultFromDb(self.schemaComboBox.currentText(),tableName,attributeName) + defaultCode = self.abstractDb.getDefaultFromDb( + self.schemaComboBox.currentText(), tableName, attributeName + ) if defaultCode: - if 'ARRAY' in defaultCode or '@' in defaultCode: - #done to extract value from multi array - defaultCodeInt = int(defaultCode.replace('ARRAY','').replace('(','').replace(')','').replace(']','').replace('[','').replace('@','').replace('<','').split(':')[0]) + if "ARRAY" in defaultCode or "@" in defaultCode: + # done to extract value from multi array + defaultCodeInt = int( + defaultCode.replace("ARRAY", "") + .replace("(", "") + .replace(")", "") + .replace("]", "") + .replace("[", "") + .replace("@", "") + .replace("<", "") + .split(":")[0] + ) else: defaultCodeInt = int(defaultCode) if defaultCodeInt in list(attrDomainDict.keys()): - comboItem = self.singleValueComboBox.findText(attrDomainDict[defaultCodeInt], flags = Qt.MatchExactly) + comboItem = self.singleValueComboBox.findText( + attrDomainDict[defaultCodeInt], flags=Qt.MatchExactly + ) self.singleValueComboBox.setCurrentIndex(comboItem) QApplication.restoreOverrideCursor() @@ -224,18 +264,18 @@ def setTitle(self, title): def validate(self): if self.allTablesCheckBox.checkState() == 2: - if self.singleValueComboBox.currentIndex() == 0: - return False + if self.singleValueComboBox.currentIndex() == 0: + return False elif self.allAttributesCheckBox.checkState() == 2: - if self.singleValueComboBox.currentIndex() == 0: - return False - if self.schemaComboBox.currentIndex() == 0: - return False - if self.tableComboBox.currentIndex() == 0: - return False + if self.singleValueComboBox.currentIndex() == 0: + return False + if self.schemaComboBox.currentIndex() == 0: + return False + if self.tableComboBox.currentIndex() == 0: + return False else: if self.singleValueComboBox.currentIndex() == 0: - return False + return False if self.schemaComboBox.currentIndex() == 0: return False if self.tableComboBox.currentIndex() == 0: @@ -245,43 +285,48 @@ def validate(self): return True def validateDiagnosis(self): - invalidatedReason = '' + invalidatedReason = "" if self.allTablesCheckBox.checkState() == 2: - if self.singleValueComboBox.currentIndex() == 0: - invalidatedReason += self.tr('A value must be chosen.\n') + if self.singleValueComboBox.currentIndex() == 0: + invalidatedReason += self.tr("A value must be chosen.\n") elif self.allAttributesCheckBox.checkState() == 2: - if self.singleValueComboBox.currentIndex() == 0: - invalidatedReason += self.tr('A value must be chosen.\n') - if self.schemaComboBox.currentIndex() == 0: - invalidatedReason += self.tr('A schema must be chosen.\n') - if self.tableComboBox.currentIndex() == 0: - invalidatedReason += self.tr('A table must be chosen.\n') - else: if self.singleValueComboBox.currentIndex() == 0: - invalidatedReason += self.tr('A value must be chosen.\n') + invalidatedReason += self.tr("A value must be chosen.\n") + if self.schemaComboBox.currentIndex() == 0: + invalidatedReason += self.tr("A schema must be chosen.\n") + if self.tableComboBox.currentIndex() == 0: + invalidatedReason += self.tr("A table must be chosen.\n") + else: + if self.singleValueComboBox.currentIndex() == 0: + invalidatedReason += self.tr("A value must be chosen.\n") if self.schemaComboBox.currentIndex() == 0: - invalidatedReason += self.tr('A schema must be chosen.\n') + invalidatedReason += self.tr("A schema must be chosen.\n") if self.tableComboBox.currentIndex() == 0: - invalidatedReason += self.tr('A table must be chosen.\n') + invalidatedReason += self.tr("A table must be chosen.\n") if self.attributeComboBox.currentIndex() == 0: - invalidatedReason += self.tr('An attribute must be chosen.\n') + invalidatedReason += self.tr("An attribute must be chosen.\n") return invalidatedReason def getJSONTag(self): if not self.validate(): - raise Exception(self.tr('Error in default customization ')+ self.title + ' : ' + self.validateDiagnosis()) + raise Exception( + self.tr("Error in default customization ") + + self.title + + " : " + + self.validateDiagnosis() + ) jsonList = [] inhConstrDict = self.abstractDb.getInheritanceConstraintDict() if self.allAttributesCheckBox.checkState() == 2: tableName = self.tableComboBox.currentText() schema = self.schemaComboBox.currentText() if tableName in list(self.domainDict.keys()): - for attrName in list(self.domainDict[tableName]['columns'].keys()): + for attrName in list(self.domainDict[tableName]["columns"].keys()): self.getJsonTagFromOneTable(schema, tableName, attrName, jsonList) elif self.allTablesCheckBox.checkState() == 2: for tableName in list(self.domainDict.keys()): schema = self.abstractDb.getTableSchemaFromDb(tableName) - for attrName in list(self.domainDict[tableName]['columns'].keys()): + for attrName in list(self.domainDict[tableName]["columns"].keys()): self.getJsonTagFromOneTable(schema, tableName, attrName, jsonList) else: tableName = self.tableComboBox.currentText() @@ -292,22 +337,43 @@ def getJSONTag(self): def getJsonTagFromOneTable(self, schema, tableName, attrName, jsonList): if tableName in list(self.domainDict.keys()): - if attrName in list(self.domainDict[tableName]['columns'].keys()): - attrDomainDict = self.domainDict[tableName]['columns'][attrName]['values'] - oldDefaultText = self.abstractDb.getDefaultFromDb(self.schemaComboBox.currentText(),tableName,attrName) + if attrName in list(self.domainDict[tableName]["columns"].keys()): + attrDomainDict = self.domainDict[tableName]["columns"][attrName][ + "values" + ] + oldDefaultText = self.abstractDb.getDefaultFromDb( + self.schemaComboBox.currentText(), tableName, attrName + ) if oldDefaultText: - if 'ARRAY' in oldDefaultText or '@' in oldDefaultText: - #done to build multi array - oldDefaultInt = int(oldDefaultText.replace('ARRAY','').replace('(','').replace(')','').replace(']','').replace('[','').replace('@','').replace('<','').split(':')[0]) + if "ARRAY" in oldDefaultText or "@" in oldDefaultText: + # done to build multi array + oldDefaultInt = int( + oldDefaultText.replace("ARRAY", "") + .replace("(", "") + .replace(")", "") + .replace("]", "") + .replace("[", "") + .replace("@", "") + .replace("<", "") + .split(":")[0] + ) else: oldDefaultInt = int(oldDefaultText) newDefaultText = self.singleValueComboBox.currentText() - newDefaultInt = [i for i in list(attrDomainDict.keys()) if attrDomainDict[i] == newDefaultText][0] + newDefaultInt = [ + i + for i in list(attrDomainDict.keys()) + if attrDomainDict[i] == newDefaultText + ][0] if oldDefaultText: - newDefault = oldDefaultText.replace(str(oldDefaultInt),str(newDefaultInt)) + newDefault = oldDefaultText.replace( + str(oldDefaultInt), str(newDefaultInt) + ) else: newDefault = str(newDefaultInt) - newElement = self.jsonBuilder.buildChangeDefaultElement(schema,tableName, attrName, oldDefaultText, newDefault) + newElement = self.jsonBuilder.buildChangeDefaultElement( + schema, tableName, attrName, oldDefaultText, newDefault + ) if newElement not in jsonList: jsonList.append(newElement) @@ -324,10 +390,14 @@ def getUiParameterJsonDict(self): } """ uiParameterJsonDict = dict() - uiParameterJsonDict['schemaComboBox'] = self.schemaComboBox.currentText() - uiParameterJsonDict['tableComboBox'] = self.tableComboBox.currentText() - uiParameterJsonDict['allAttributesCheckBox'] = self.allAttributesCheckBox.isChecked() - uiParameterJsonDict['allTablesCheckBox'] = self.allTablesCheckBox.isChecked() - uiParameterJsonDict['attributeComboBox'] = self.attributeComboBox.currentText() - uiParameterJsonDict['singleValueComboBox'] = self.singleValueComboBox.currentText() - return uiParameterJsonDict \ No newline at end of file + uiParameterJsonDict["schemaComboBox"] = self.schemaComboBox.currentText() + uiParameterJsonDict["tableComboBox"] = self.tableComboBox.currentText() + uiParameterJsonDict[ + "allAttributesCheckBox" + ] = self.allAttributesCheckBox.isChecked() + uiParameterJsonDict["allTablesCheckBox"] = self.allTablesCheckBox.isChecked() + uiParameterJsonDict["attributeComboBox"] = self.attributeComboBox.currentText() + uiParameterJsonDict[ + "singleValueComboBox" + ] = self.singleValueComboBox.currentText() + return uiParameterJsonDict diff --git a/DsgTools/gui/CustomWidgets/CustomDbManagementWidgets/changeFilterWidget.py b/DsgTools/gui/CustomWidgets/CustomDbManagementWidgets/changeFilterWidget.py index 33b41062d..096cfba0c 100644 --- a/DsgTools/gui/CustomWidgets/CustomDbManagementWidgets/changeFilterWidget.py +++ b/DsgTools/gui/CustomWidgets/CustomDbManagementWidgets/changeFilterWidget.py @@ -29,26 +29,34 @@ from qgis.PyQt.QtCore import pyqtSlot, pyqtSignal, QSettings, Qt from qgis.PyQt.QtWidgets import QApplication from qgis.PyQt.QtGui import QCursor + # DSGTools imports -from DsgTools.gui.Misc.PostgisCustomization.CustomJSONTools.customJSONBuilder import CustomJSONBuilder +from DsgTools.gui.Misc.PostgisCustomization.CustomJSONTools.customJSONBuilder import ( + CustomJSONBuilder, +) from DsgTools.core.Utils.utils import Utils -FORM_CLASS, _ = uic.loadUiType(os.path.join( - os.path.dirname(__file__), 'changeFilterWidget.ui')) +FORM_CLASS, _ = uic.loadUiType( + os.path.join(os.path.dirname(__file__), "changeFilterWidget.ui") +) + class ChangeFilterWidget(QtWidgets.QWidget, FORM_CLASS): populateSingleValue = pyqtSignal() populateListValue = pyqtSignal() - def __init__(self, abstractDb, uiParameterJsonDict = None, parent = None): + + def __init__(self, abstractDb, uiParameterJsonDict=None, parent=None): """Constructor.""" super(self.__class__, self).__init__(parent) self.abstractDb = abstractDb self.setupUi(self) self.jsonBuilder = CustomJSONBuilder() self.populateSchemaCombo() - self.hideWidgetList([self.singleValueLabel, self.singleValueComboBox, self.actionComboBox]) + self.hideWidgetList( + [self.singleValueLabel, self.singleValueComboBox, self.actionComboBox] + ) self.singleAttribute = True - self.filterCustomSelectorWidget.setTitle(self.tr('Select filter values')) + self.filterCustomSelectorWidget.setTitle(self.tr("Select filter values")) self.populateSingleValue.connect(self.populateWidgetWithSingleValue) self.populateListValue.connect(self.populateWidgetWithListValue) geomTypeDict = self.abstractDb.getGeomTypeDict() @@ -56,9 +64,13 @@ def __init__(self, abstractDb, uiParameterJsonDict = None, parent = None): self.domainDict = self.abstractDb.getDbDomainDict(geomDict) self.inhTree = self.abstractDb.getInheritanceTreeDict() self.utils = Utils() - self.actionDict = {self.tr('Add to Filter (Leave empty if filter is empty)'):'addEmpty', self.tr('Add to Filter (Add value to empty filter)'):'add',self.tr('Remove from Filter'):'remove'} + self.actionDict = { + self.tr("Add to Filter (Leave empty if filter is empty)"): "addEmpty", + self.tr("Add to Filter (Add value to empty filter)"): "add", + self.tr("Remove from Filter"): "remove", + } self.populateFromUiParameterJsonDict(uiParameterJsonDict) - + def populateFromUiParameterJsonDict(self, uiParameterJsonDict): """ { @@ -73,41 +85,68 @@ def populateFromUiParameterJsonDict(self, uiParameterJsonDict): } """ if uiParameterJsonDict: - if uiParameterJsonDict['allTablesCheckBox']: + if uiParameterJsonDict["allTablesCheckBox"]: self.allTablesCheckBox.setCheckState(Qt.Checked) - singleValueIdx = self.singleValueComboBox.findText(uiParameterJsonDict['singleValueComboBox'], flags = Qt.MatchExactly) + singleValueIdx = self.singleValueComboBox.findText( + uiParameterJsonDict["singleValueComboBox"], flags=Qt.MatchExactly + ) self.singleValueComboBox.setCurrentIndex(singleValueIdx) - self.actionComboBox.setCurrentIndex(uiParameterJsonDict['actionComboBoxIdx']) + self.actionComboBox.setCurrentIndex( + uiParameterJsonDict["actionComboBoxIdx"] + ) else: - schemaIdx = self.schemaComboBox.findText(uiParameterJsonDict['schemaComboBox'], flags = Qt.MatchExactly) + schemaIdx = self.schemaComboBox.findText( + uiParameterJsonDict["schemaComboBox"], flags=Qt.MatchExactly + ) self.schemaComboBox.setCurrentIndex(schemaIdx) - tableIdx = self.tableComboBox.findText(uiParameterJsonDict['tableComboBox'], flags = Qt.MatchExactly) + tableIdx = self.tableComboBox.findText( + uiParameterJsonDict["tableComboBox"], flags=Qt.MatchExactly + ) self.tableComboBox.setCurrentIndex(tableIdx) - if uiParameterJsonDict['allAttributesCheckBox']: + if uiParameterJsonDict["allAttributesCheckBox"]: self.allAttributesCheckBox.setCheckState(Qt.Checked) - singleValueIdx = self.singleValueComboBox.findText(uiParameterJsonDict['singleValueComboBox'], flags = Qt.MatchExactly) + singleValueIdx = self.singleValueComboBox.findText( + uiParameterJsonDict["singleValueComboBox"], + flags=Qt.MatchExactly, + ) self.singleValueComboBox.setCurrentIndex(singleValueIdx) - self.actionComboBox.setCurrentIndex(uiParameterJsonDict['actionComboBoxIdx']) + self.actionComboBox.setCurrentIndex( + uiParameterJsonDict["actionComboBoxIdx"] + ) else: - attributeIdx = self.attributeComboBox.findText(uiParameterJsonDict['attributeComboBox'], flags = Qt.MatchExactly) + attributeIdx = self.attributeComboBox.findText( + uiParameterJsonDict["attributeComboBox"], flags=Qt.MatchExactly + ) self.attributeComboBox.setCurrentIndex(attributeIdx) - self.filterCustomSelectorWidget.selectItems(True, selectedItems=uiParameterJsonDict['filterCustomSelectorWidgetToList']) + self.filterCustomSelectorWidget.selectItems( + True, + selectedItems=uiParameterJsonDict[ + "filterCustomSelectorWidgetToList" + ], + ) def populateInheritanceTree(self, nodeList): self.treeWidget.clear() rootNode = self.treeWidget.invisibleRootItem() for node in nodeList: - firstNonRootNode = self.utils.find_all_paths(self.inhTree, 'root', node)[0][1] - self.utils.createTreeWidgetFromDict(rootNode, {firstNonRootNode:self.inhTree['root'][firstNonRootNode]}, self.treeWidget, 0) + firstNonRootNode = self.utils.find_all_paths(self.inhTree, "root", node)[0][ + 1 + ] + self.utils.createTreeWidgetFromDict( + rootNode, + {firstNonRootNode: self.inhTree["root"][firstNonRootNode]}, + self.treeWidget, + 0, + ) self.treeWidget.sortItems(0, Qt.AscendingOrder) self.treeWidget.expandAll() def populateSchemaCombo(self): self.schemaComboBox.clear() - self.schemaComboBox.addItem(self.tr('Select a schema')) + self.schemaComboBox.addItem(self.tr("Select a schema")) schemaList = self.abstractDb.getGeometricSchemaList() for schema in schemaList: - if schema not in ['views', 'validation']: + if schema not in ["views", "validation"]: self.schemaComboBox.addItem(schema) def hideWidgetList(self, widgetList): @@ -129,7 +168,7 @@ def on_schemaComboBox_currentIndexChanged(self, idx): schema = self.schemaComboBox.currentText() self.tableComboBox.setEnabled(True) self.tableComboBox.clear() - self.tableComboBox.addItem(self.tr('Select a table')) + self.tableComboBox.addItem(self.tr("Select a table")) tableList = self.abstractDb.getGeometricTableListFromSchema(schema) for table in tableList: self.tableComboBox.addItem(table) @@ -144,22 +183,26 @@ def on_tableComboBox_currentIndexChanged(self, idx): tableName = self.tableComboBox.currentText() self.attributeComboBox.setEnabled(True) self.attributeComboBox.clear() - self.attributeComboBox.addItem(self.tr('Select an attribute')) + self.attributeComboBox.addItem(self.tr("Select an attribute")) if tableName in list(self.domainDict.keys()): - attributeList = list(self.domainDict[tableName]['columns'].keys()) + attributeList = list(self.domainDict[tableName]["columns"].keys()) for attribute in attributeList: self.attributeComboBox.addItem(attribute) - @pyqtSlot(int, name='on_schemaComboBox_currentIndexChanged') - @pyqtSlot(int, name='on_attributeComboBox_currentIndexChanged') - @pyqtSlot(int, name='on_tableComboBox_currentIndexChanged') + @pyqtSlot(int, name="on_schemaComboBox_currentIndexChanged") + @pyqtSlot(int, name="on_attributeComboBox_currentIndexChanged") + @pyqtSlot(int, name="on_tableComboBox_currentIndexChanged") def populateWidgetWithSingleValue(self): - if self.allTablesCheckBox.checkState() == 2 or (self.allAttributesCheckBox.checkState() == 2 and self.schemaComboBox.currentIndex() != 0 and self.tableComboBox.currentIndex() != 0): + if self.allTablesCheckBox.checkState() == 2 or ( + self.allAttributesCheckBox.checkState() == 2 + and self.schemaComboBox.currentIndex() != 0 + and self.tableComboBox.currentIndex() != 0 + ): self.attributeComboBox.clear() self.attributeComboBox.setEnabled(False) QApplication.setOverrideCursor(QCursor(Qt.WaitCursor)) self.singleValueComboBox.clear() - self.singleValueComboBox.addItem(self.tr('Select a value to alter')) + self.singleValueComboBox.addItem(self.tr("Select a value to alter")) if self.allAttributesCheckBox.checkState() == 2: tableList = [self.tableComboBox.currentText()] else: @@ -167,16 +210,24 @@ def populateWidgetWithSingleValue(self): allValueList = [] idxList = [] for tableName in tableList: - for attrName in list(self.domainDict[tableName]['columns'].keys()): - for code in self.domainDict[tableName]['columns'][attrName]['values']: - value = self.domainDict[tableName]['columns'][attrName]['values'][code] + for attrName in list(self.domainDict[tableName]["columns"].keys()): + for code in self.domainDict[tableName]["columns"][attrName][ + "values" + ]: + value = self.domainDict[tableName]["columns"][attrName][ + "values" + ][code] if value not in allValueList: allValueList.append(value) for value in allValueList: for tableName in tableList: - for attrName in list(self.domainDict[tableName]['columns'].keys()): - if value not in list(self.domainDict[tableName]['columns'][attrName]['values'].values()): + for attrName in list(self.domainDict[tableName]["columns"].keys()): + if value not in list( + self.domainDict[tableName]["columns"][attrName][ + "values" + ].values() + ): idx = allValueList.index(value) if idx not in idxList: idxList.append(idx) @@ -188,12 +239,15 @@ def populateWidgetWithSingleValue(self): self.populateInheritanceTree(tableList) QApplication.restoreOverrideCursor() - @pyqtSlot(int, name='on_schemaComboBox_currentIndexChanged') - @pyqtSlot(int, name='on_attributeComboBox_currentIndexChanged') - @pyqtSlot(int, name='on_tableComboBox_currentIndexChanged') + @pyqtSlot(int, name="on_schemaComboBox_currentIndexChanged") + @pyqtSlot(int, name="on_attributeComboBox_currentIndexChanged") + @pyqtSlot(int, name="on_tableComboBox_currentIndexChanged") def populateWidgetWithListValue(self): self.filterCustomSelectorWidget.clearAll() - if self.allTablesCheckBox.checkState() == 2 or self.allAttributesCheckBox.checkState() == 2: + if ( + self.allTablesCheckBox.checkState() == 2 + or self.allAttributesCheckBox.checkState() == 2 + ): return if self.schemaComboBox.currentIndex() == 0: return @@ -209,11 +263,17 @@ def populateWidgetWithListValue(self): tableFilter = [] filterToList = [] if tableName in list(self.domainDict.keys()): - if attributeName in list(self.domainDict[tableName]['columns'].keys()): - attrDomainDict = self.domainDict[tableName]['columns'][attributeName]['values'] - tableFilter = self.domainDict[tableName]['columns'][attributeName]['constraintList'] + if attributeName in list(self.domainDict[tableName]["columns"].keys()): + attrDomainDict = self.domainDict[tableName]["columns"][attributeName][ + "values" + ] + tableFilter = self.domainDict[tableName]["columns"][attributeName][ + "constraintList" + ] filterToList = [attrDomainDict[i] for i in tableFilter] - filterFromList = [i for i in list(attrDomainDict.values()) if i not in filterToList] + filterFromList = [ + i for i in list(attrDomainDict.values()) if i not in filterToList + ] self.filterCustomSelectorWidget.setFromList(filterFromList, unique=True) self.filterCustomSelectorWidget.setToList(filterToList) @@ -243,7 +303,10 @@ def on_allAttributesCheckBox_stateChanged(self, state): self.hideOrShowWidgets() def hideOrShowWidgets(self): - if self.allAttributesCheckBox.checkState() == 2 or self.allTablesCheckBox.checkState() == 2: + if ( + self.allAttributesCheckBox.checkState() == 2 + or self.allTablesCheckBox.checkState() == 2 + ): self.filterCustomSelectorWidget.hide() self.singleValueLabel.show() self.singleValueComboBox.show() @@ -254,7 +317,9 @@ def hideOrShowWidgets(self): self.singleValueLabel.hide() self.singleValueComboBox.hide() self.actionComboBox.hide() - self.tableComboBox.currentIndexChanged.emit(self.tableComboBox.currentIndex()) + self.tableComboBox.currentIndexChanged.emit( + self.tableComboBox.currentIndex() + ) self.populateListValue.emit() def getTitle(self): @@ -265,56 +330,61 @@ def setTitle(self, title): def validate(self): if self.allTablesCheckBox.checkState() == 2: - if self.singleValueComboBox.currentIndex() == 0: - return False - if self.actionComboBox.currentIndex() == 0: - return False + if self.singleValueComboBox.currentIndex() == 0: + return False + if self.actionComboBox.currentIndex() == 0: + return False elif self.allAttributesCheckBox.checkState() == 2: - if self.singleValueComboBox.currentIndex() == 0: - return False - if self.actionComboBox.currentIndex() == 0: - return False - if self.schemaComboBox.currentIndex() == 0: - return False - if self.tableComboBox.currentIndex() == 0: - return False + if self.singleValueComboBox.currentIndex() == 0: + return False + if self.actionComboBox.currentIndex() == 0: + return False + if self.schemaComboBox.currentIndex() == 0: + return False + if self.tableComboBox.currentIndex() == 0: + return False else: - if self.schemaComboBox.currentIndex() == 0: - return False - if self.tableComboBox.currentIndex() == 0: - return False - if self.attributeComboBox.currentIndex() == 0: - return False + if self.schemaComboBox.currentIndex() == 0: + return False + if self.tableComboBox.currentIndex() == 0: + return False + if self.attributeComboBox.currentIndex() == 0: + return False return True def validateDiagnosis(self): - invalidatedReason = '' + invalidatedReason = "" if self.allTablesCheckBox.checkState() == 2: - if self.singleValueComboBox.currentIndex() == 0: - invalidatedReason += self.tr('A value must be chosen.\n') - if self.actionComboBox.currentIndex() == 0: - invalidatedReason += self.tr('An action must be chosen.\n') + if self.singleValueComboBox.currentIndex() == 0: + invalidatedReason += self.tr("A value must be chosen.\n") + if self.actionComboBox.currentIndex() == 0: + invalidatedReason += self.tr("An action must be chosen.\n") elif self.allAttributesCheckBox.checkState() == 2: - if self.singleValueComboBox.currentIndex() == 0: - invalidatedReason += self.tr('A value must be chosen.\n') - if self.actionComboBox.currentIndex() == 0: - invalidatedReason += self.tr('An action must be chosen.\n') - if self.schemaComboBox.currentIndex() == 0: - invalidatedReason += self.tr('A schema must be chosen.\n') - if self.tableComboBox.currentIndex() == 0: - invalidatedReason += self.tr('A table must be chosen.\n') + if self.singleValueComboBox.currentIndex() == 0: + invalidatedReason += self.tr("A value must be chosen.\n") + if self.actionComboBox.currentIndex() == 0: + invalidatedReason += self.tr("An action must be chosen.\n") + if self.schemaComboBox.currentIndex() == 0: + invalidatedReason += self.tr("A schema must be chosen.\n") + if self.tableComboBox.currentIndex() == 0: + invalidatedReason += self.tr("A table must be chosen.\n") else: - if self.schemaComboBox.currentIndex() == 0: - invalidatedReason += self.tr('A schema must be chosen.\n') - if self.tableComboBox.currentIndex() == 0: - invalidatedReason += self.tr('A table must be chosen.\n') - if self.attributeComboBox.currentIndex() == 0: - invalidatedReason += self.tr('An attribute must be chosen.\n') + if self.schemaComboBox.currentIndex() == 0: + invalidatedReason += self.tr("A schema must be chosen.\n") + if self.tableComboBox.currentIndex() == 0: + invalidatedReason += self.tr("A table must be chosen.\n") + if self.attributeComboBox.currentIndex() == 0: + invalidatedReason += self.tr("An attribute must be chosen.\n") return invalidatedReason def getJSONTag(self): if not self.validate(): - raise Exception(self.tr('Error in change filter customization ')+ self.title + ' : ' + self.validateDiagnosis()) + raise Exception( + self.tr("Error in change filter customization ") + + self.title + + " : " + + self.validateDiagnosis() + ) jsonList = [] inhConstrDict = self.abstractDb.getInheritanceConstraintDict() if self.allAttributesCheckBox.checkState() == 2: @@ -322,7 +392,7 @@ def getJSONTag(self): schema = self.schemaComboBox.currentText() self.batchGetJsonTag(schema, tableName, jsonList, inhConstrDict) elif self.allTablesCheckBox.checkState() == 2: - tableList = list(self.inhTree['root'].keys()) + tableList = list(self.inhTree["root"].keys()) for tableName in tableList: schema = self.abstractDb.getTableSchemaFromDb(tableName) self.batchGetJsonTag(schema, tableName, jsonList, inhConstrDict) @@ -331,39 +401,76 @@ def getJSONTag(self): schema = self.schemaComboBox.currentText() attrName = self.attributeComboBox.currentText() if tableName in list(self.domainDict.keys()): - if attrName in list(self.domainDict[tableName]['columns'].keys()): - attrDomainDict = self.domainDict[tableName]['columns'][attrName]['values'] - isMulti = self.domainDict[tableName]['columns'][attrName]['isMulti'] - newFilter = [i for i in list(attrDomainDict.keys()) if attrDomainDict[i] in self.filterCustomSelectorWidget.toLs] - self.getJsonTagFromOneTable(schema, tableName, attrName, jsonList, inhConstrDict, newFilter, isMulti) + if attrName in list(self.domainDict[tableName]["columns"].keys()): + attrDomainDict = self.domainDict[tableName]["columns"][attrName][ + "values" + ] + isMulti = self.domainDict[tableName]["columns"][attrName]["isMulti"] + newFilter = [ + i + for i in list(attrDomainDict.keys()) + if attrDomainDict[i] in self.filterCustomSelectorWidget.toLs + ] + self.getJsonTagFromOneTable( + schema, tableName, attrName, jsonList, inhConstrDict, newFilter, isMulti + ) return jsonList def batchGetJsonTag(self, schema, tableName, jsonList, inhConstrDict): if tableName in list(self.domainDict.keys()): - for attrName in list(self.domainDict[tableName]['columns'].keys()): - attrDomainDict = self.domainDict[tableName]['columns'][attrName]['values'] - isMulti = self.domainDict[tableName]['columns'][attrName]['isMulti'] - newFilter = self.domainDict[tableName]['columns'][attrName]['constraintList'] + for attrName in list(self.domainDict[tableName]["columns"].keys()): + attrDomainDict = self.domainDict[tableName]["columns"][attrName][ + "values" + ] + isMulti = self.domainDict[tableName]["columns"][attrName]["isMulti"] + newFilter = self.domainDict[tableName]["columns"][attrName][ + "constraintList" + ] valueText = self.singleValueComboBox.currentText() - code = [i for i in list(attrDomainDict.keys()) if attrDomainDict[i] == valueText][0] - if self.actionDict[self.actionComboBox.currentText()] == 'add': - if code not in newFilter: newFilter.append(code) - elif self.actionDict[self.actionComboBox.currentText()] == 'addEmpty': + code = [ + i + for i in list(attrDomainDict.keys()) + if attrDomainDict[i] == valueText + ][0] + if self.actionDict[self.actionComboBox.currentText()] == "add": + if code not in newFilter: + newFilter.append(code) + elif self.actionDict[self.actionComboBox.currentText()] == "addEmpty": if newFilter == []: continue else: - if code in newFilter: newFilter.pop(code) - self.getJsonTagFromOneTable(schema, tableName, attrName, jsonList, inhConstrDict, newFilter, isMulti) + if code in newFilter: + newFilter.pop(code) + self.getJsonTagFromOneTable( + schema, + tableName, + attrName, + jsonList, + inhConstrDict, + newFilter, + isMulti, + ) - def getJsonTagFromOneTable(self, schema, tableName, attrName, jsonList, inhConstrDict, newFilter, isMulti): + def getJsonTagFromOneTable( + self, schema, tableName, attrName, jsonList, inhConstrDict, newFilter, isMulti + ): originalFilterList = [] if tableName in list(inhConstrDict.keys()): if attrName in list(inhConstrDict[tableName].keys()): originalFilterList = inhConstrDict[tableName][attrName] - if originalFilterList == newFilter: return + if originalFilterList == newFilter: + return elif originalFilterList != []: for item in originalFilterList: - newElement = self.jsonBuilder.alterFilterElement(item['schema'], item['tableName'], attrName, item['constraintName'], item['filter'], newFilter, isMulti) + newElement = self.jsonBuilder.alterFilterElement( + item["schema"], + item["tableName"], + attrName, + item["constraintName"], + item["filter"], + newFilter, + isMulti, + ) if newElement not in jsonList: jsonList.append(newElement) else: @@ -371,7 +478,7 @@ def getJsonTagFromOneTable(self, schema, tableName, attrName, jsonList, inhConst firstInLineage = None for node in nodeLineage: if node in list(self.domainDict.keys()): - if attrName in list(self.domainDict[node]['columns'].keys()): + if attrName in list(self.domainDict[node]["columns"].keys()): firstInLineage = node break else: @@ -379,7 +486,15 @@ def getJsonTagFromOneTable(self, schema, tableName, attrName, jsonList, inhConst if node in self.abstractDb.getAttributeListFromTable(schema, node): firstInLineage = node break - newElement = self.jsonBuilder.alterFilterElement(schema, firstInLineage, attrName, '_'.join([firstInLineage,attrName,'ks']), [], newFilter, isMulti) + newElement = self.jsonBuilder.alterFilterElement( + schema, + firstInLineage, + attrName, + "_".join([firstInLineage, attrName, "ks"]), + [], + newFilter, + isMulti, + ) if newElement not in jsonList: jsonList.append(newElement) @@ -398,13 +513,18 @@ def getUiParameterJsonDict(self): } """ uiParameterJsonDict = dict() - uiParameterJsonDict['schemaComboBox'] = self.schemaComboBox.currentText() - uiParameterJsonDict['tableComboBox'] = self.tableComboBox.currentText() - uiParameterJsonDict['attributeComboBox'] = self.attributeComboBox.currentText() - uiParameterJsonDict['allAttributesCheckBox'] = self.allAttributesCheckBox.isChecked() - uiParameterJsonDict['allTablesCheckBox'] = self.allTablesCheckBox.isChecked() - uiParameterJsonDict['filterCustomSelectorWidgetToList'] = self.filterCustomSelectorWidget.toLs - uiParameterJsonDict['singleValueComboBox'] = self.singleValueComboBox.currentText() - uiParameterJsonDict['actionComboBoxIdx'] = self.actionComboBox.currentIndex() + uiParameterJsonDict["schemaComboBox"] = self.schemaComboBox.currentText() + uiParameterJsonDict["tableComboBox"] = self.tableComboBox.currentText() + uiParameterJsonDict["attributeComboBox"] = self.attributeComboBox.currentText() + uiParameterJsonDict[ + "allAttributesCheckBox" + ] = self.allAttributesCheckBox.isChecked() + uiParameterJsonDict["allTablesCheckBox"] = self.allTablesCheckBox.isChecked() + uiParameterJsonDict[ + "filterCustomSelectorWidgetToList" + ] = self.filterCustomSelectorWidget.toLs + uiParameterJsonDict[ + "singleValueComboBox" + ] = self.singleValueComboBox.currentText() + uiParameterJsonDict["actionComboBoxIdx"] = self.actionComboBox.currentIndex() return uiParameterJsonDict - \ No newline at end of file diff --git a/DsgTools/gui/CustomWidgets/CustomDbManagementWidgets/changeNullityWidget.py b/DsgTools/gui/CustomWidgets/CustomDbManagementWidgets/changeNullityWidget.py index 4ca9c5e1e..9482d6d94 100644 --- a/DsgTools/gui/CustomWidgets/CustomDbManagementWidgets/changeNullityWidget.py +++ b/DsgTools/gui/CustomWidgets/CustomDbManagementWidgets/changeNullityWidget.py @@ -30,13 +30,17 @@ from qgis.PyQt.QtSql import QSqlQuery # DSGTools imports -from DsgTools.gui.Misc.PostgisCustomization.CustomJSONTools.customJSONBuilder import CustomJSONBuilder +from DsgTools.gui.Misc.PostgisCustomization.CustomJSONTools.customJSONBuilder import ( + CustomJSONBuilder, +) + +FORM_CLASS, _ = uic.loadUiType( + os.path.join(os.path.dirname(__file__), "changeNullityWidget.ui") +) -FORM_CLASS, _ = uic.loadUiType(os.path.join( - os.path.dirname(__file__), 'changeNullityWidget.ui')) class ChangeNullityWidget(QtWidgets.QWidget, FORM_CLASS): - def __init__(self, abstractDb, uiParameterJsonDict = None, parent = None): + def __init__(self, abstractDb, uiParameterJsonDict=None, parent=None): """Constructor.""" super(self.__class__, self).__init__(parent) self.abstractDb = abstractDb @@ -44,7 +48,7 @@ def __init__(self, abstractDb, uiParameterJsonDict = None, parent = None): self.jsonBuilder = CustomJSONBuilder() self.populateSchemaCombo() self.populateFromUiParameterJsonDict(uiParameterJsonDict) - + def populateFromUiParameterJsonDict(self, uiParameterJsonDict): """ builds a dict with the following format: @@ -58,26 +62,34 @@ def populateFromUiParameterJsonDict(self, uiParameterJsonDict): } """ if uiParameterJsonDict: - if uiParameterJsonDict['allTablesCheckBox']: + if uiParameterJsonDict["allTablesCheckBox"]: self.allTablesCheckBox.setCheckState(Qt.Checked) else: - schemaIdx = self.schemaComboBox.findText(uiParameterJsonDict['schemaComboBox'], flags = Qt.MatchExactly) + schemaIdx = self.schemaComboBox.findText( + uiParameterJsonDict["schemaComboBox"], flags=Qt.MatchExactly + ) self.schemaComboBox.setCurrentIndex(schemaIdx) - tableIdx = self.tableComboBox.findText(uiParameterJsonDict['tableComboBox'], flags = Qt.MatchExactly) + tableIdx = self.tableComboBox.findText( + uiParameterJsonDict["tableComboBox"], flags=Qt.MatchExactly + ) self.tableComboBox.setCurrentIndex(tableIdx) - if uiParameterJsonDict['allAttributesCheckBox']: + if uiParameterJsonDict["allAttributesCheckBox"]: self.allAttributesCheckBox.setCheckState(Qt.Checked) else: - attributeIdx = self.attributeComboBox.findText(uiParameterJsonDict['attributeComboBox'], flags = Qt.MatchExactly) + attributeIdx = self.attributeComboBox.findText( + uiParameterJsonDict["attributeComboBox"], flags=Qt.MatchExactly + ) self.attributeComboBox.setCurrentIndex(attributeIdx) - self.actionComboBox.setCurrentIndex(uiParameterJsonDict['actionComboBoxIdx']) - + self.actionComboBox.setCurrentIndex( + uiParameterJsonDict["actionComboBoxIdx"] + ) + def populateSchemaCombo(self): self.schemaComboBox.clear() - self.schemaComboBox.addItem(self.tr('Select a schema')) + self.schemaComboBox.addItem(self.tr("Select a schema")) schemaList = self.abstractDb.getGeometricSchemaList() for schema in schemaList: - if schema not in ['views', 'validation']: + if schema not in ["views", "validation"]: self.schemaComboBox.addItem(schema) @pyqtSlot(int) @@ -91,11 +103,11 @@ def on_schemaComboBox_currentIndexChanged(self, idx): schema = self.schemaComboBox.currentText() self.tableComboBox.setEnabled(True) self.tableComboBox.clear() - self.tableComboBox.addItem(self.tr('Select a table')) + self.tableComboBox.addItem(self.tr("Select a table")) tableList = self.abstractDb.getGeometricTableListFromSchema(schema) for table in tableList: self.tableComboBox.addItem(table) - + @pyqtSlot(int) def on_tableComboBox_currentIndexChanged(self, idx): if idx == 0: @@ -106,11 +118,11 @@ def on_tableComboBox_currentIndexChanged(self, idx): tableName = self.tableComboBox.currentText() self.attributeComboBox.setEnabled(True) self.attributeComboBox.clear() - self.attributeComboBox.addItem(self.tr('Select an attribute')) + self.attributeComboBox.addItem(self.tr("Select an attribute")) attributeList = self.abstractDb.getAttributeListFromTable(schema, tableName) for attribute in attributeList: self.attributeComboBox.addItem(attribute) - + @pyqtSlot(int) def on_allTablesCheckBox_stateChanged(self, state): if state == 0: @@ -122,8 +134,7 @@ def on_allTablesCheckBox_stateChanged(self, state): self.allAttributesCheckBox.setCheckState(0) self.schemaComboBox.setCurrentIndex(0) self.schemaComboBox.setEnabled(False) - - + @pyqtSlot(int) def on_allAttributesCheckBox_stateChanged(self, state): if state == 2: @@ -134,13 +145,13 @@ def on_allAttributesCheckBox_stateChanged(self, state): if state == 0: self.allTablesCheckBox.setEnabled(True) self.attributeComboBox.setEnabled(True) - + def getTitle(self): return self.title - + def setTitle(self, title): self.title = title - + def validate(self): if self.actionComboBox.currentIndex() == 0: return False @@ -157,20 +168,28 @@ def validate(self): return True def validateDiagnosis(self): - invalidatedReason = '' + invalidatedReason = "" if self.schemaComboBox.currentIndex() == 0: - invalidatedReason += self.tr('A schema must be chosen.\n') + invalidatedReason += self.tr("A schema must be chosen.\n") if self.tableComboBox.currentIndex() == 0: - invalidatedReason += self.tr('A table must be chosen.\n') + invalidatedReason += self.tr("A table must be chosen.\n") if self.actionComboBox.currentIndex() == 0: - invalidatedReason += self.tr('An action be chosen.\n') - if self.allAttributesCheckBox.checkState() != 2 and self.attributeComboBox.currentIndex() == 0: - invalidatedReason += self.tr('An attribute must be chosen.\n') + invalidatedReason += self.tr("An action be chosen.\n") + if ( + self.allAttributesCheckBox.checkState() != 2 + and self.attributeComboBox.currentIndex() == 0 + ): + invalidatedReason += self.tr("An attribute must be chosen.\n") return invalidatedReason - + def getJSONTag(self): if not self.validate(): - raise Exception(self.tr('Error in change nullity customization ')+ self.title + ' : ' + self.validateDiagnosis()) + raise Exception( + self.tr("Error in change nullity customization ") + + self.title + + " : " + + self.validateDiagnosis() + ) if self.actionComboBox.currentIndex() == 1: notNull = True elif self.actionComboBox.currentIndex() == 2: @@ -179,20 +198,32 @@ def getJSONTag(self): if self.allTablesCheckBox.checkState() == 2: attributeJsonList = self.abstractDb.getAttributeJsonFromDb() for attributeJson in attributeJsonList: - schema = attributeJson['table_schema'] - table = attributeJson['table_name'] - for attrName in attributeJson['attributelist']: - jsonList.append(self.jsonBuilder.buildChangeNullityElement(schema, table, attrName, notNull)) + schema = attributeJson["table_schema"] + table = attributeJson["table_name"] + for attrName in attributeJson["attributelist"]: + jsonList.append( + self.jsonBuilder.buildChangeNullityElement( + schema, table, attrName, notNull + ) + ) else: schema = self.schemaComboBox.currentText() table = self.tableComboBox.currentText() if self.allAttributesCheckBox.checkState() == 2: attrList = self.abstractDb.getAttributeListFromTable(schema, table) for attrName in attrList: - jsonList.append(self.jsonBuilder.buildChangeNullityElement(schema, table, attrName, notNull)) + jsonList.append( + self.jsonBuilder.buildChangeNullityElement( + schema, table, attrName, notNull + ) + ) else: attrName = self.attributeComboBox.currentText() - jsonList.append(self.jsonBuilder.buildChangeNullityElement(schema, table, attrName, notNull)) + jsonList.append( + self.jsonBuilder.buildChangeNullityElement( + schema, table, attrName, notNull + ) + ) return jsonList def getUiParameterJsonDict(self): @@ -208,10 +239,12 @@ def getUiParameterJsonDict(self): } """ uiParameterJsonDict = dict() - uiParameterJsonDict['schemaComboBox'] = self.schemaComboBox.currentText() - uiParameterJsonDict['tableComboBox'] = self.tableComboBox.currentText() - uiParameterJsonDict['allAttributesCheckBox'] = self.allAttributesCheckBox.isChecked() - uiParameterJsonDict['allTablesCheckBox'] = self.allTablesCheckBox.isChecked() - uiParameterJsonDict['attributeComboBox'] = self.attributeComboBox.currentText() - uiParameterJsonDict['actionComboBoxIdx'] = self.actionComboBox.currentIndex() - return uiParameterJsonDict \ No newline at end of file + uiParameterJsonDict["schemaComboBox"] = self.schemaComboBox.currentText() + uiParameterJsonDict["tableComboBox"] = self.tableComboBox.currentText() + uiParameterJsonDict[ + "allAttributesCheckBox" + ] = self.allAttributesCheckBox.isChecked() + uiParameterJsonDict["allTablesCheckBox"] = self.allTablesCheckBox.isChecked() + uiParameterJsonDict["attributeComboBox"] = self.attributeComboBox.currentText() + uiParameterJsonDict["actionComboBoxIdx"] = self.actionComboBox.currentIndex() + return uiParameterJsonDict diff --git a/DsgTools/gui/CustomWidgets/CustomDbManagementWidgets/codeNameCustomizationWidget.py b/DsgTools/gui/CustomWidgets/CustomDbManagementWidgets/codeNameCustomizationWidget.py index 6576ff32b..34f09b99c 100644 --- a/DsgTools/gui/CustomWidgets/CustomDbManagementWidgets/codeNameCustomizationWidget.py +++ b/DsgTools/gui/CustomWidgets/CustomDbManagementWidgets/codeNameCustomizationWidget.py @@ -33,13 +33,17 @@ from DsgTools.gui.ServerTools.viewServers import ViewServers from DsgTools.core.Factories.SqlFactory.sqlGeneratorFactory import SqlGeneratorFactory from DsgTools.core.Factories.DbFactory.dbFactory import DbFactory -from DsgTools.gui.Misc.PostgisCustomization.CustomJSONTools.customJSONBuilder import CustomJSONBuilder +from DsgTools.gui.Misc.PostgisCustomization.CustomJSONTools.customJSONBuilder import ( + CustomJSONBuilder, +) + +FORM_CLASS, _ = uic.loadUiType( + os.path.join(os.path.dirname(__file__), "codeNameCustomizationWidget.ui") +) -FORM_CLASS, _ = uic.loadUiType(os.path.join( - os.path.dirname(__file__), 'codeNameCustomizationWidget.ui')) class CodeNameCustomizationWidget(QtWidgets.QWidget, FORM_CLASS): - def __init__(self, abstractDb, uiParameterJsonDict = None, parent = None): + def __init__(self, abstractDb, uiParameterJsonDict=None, parent=None): """Constructor.""" super(self.__class__, self).__init__(parent) self.abstractDb = abstractDb @@ -48,7 +52,7 @@ def __init__(self, abstractDb, uiParameterJsonDict = None, parent = None): self.domainDict = dict() self.populateDomainCombo() self.populateFromUiParameterJsonDict(uiParameterJsonDict) - + def populateFromUiParameterJsonDict(self, uiParameterJsonDict): """ builds ui from uiParameterJsonDict @@ -59,33 +63,37 @@ def populateFromUiParameterJsonDict(self, uiParameterJsonDict): } """ if uiParameterJsonDict: - domainIdx = self.domainComboBox.findText(uiParameterJsonDict['domainComboBox'], flags = Qt.MatchExactly) + domainIdx = self.domainComboBox.findText( + uiParameterJsonDict["domainComboBox"], flags=Qt.MatchExactly + ) self.domainComboBox.setCurrentIndex(domainIdx) - oldIdx = self.oldCodeNameComboBox.findText(uiParameterJsonDict['oldCodeNameComboBox'], flags = Qt.MatchExactly) + oldIdx = self.oldCodeNameComboBox.findText( + uiParameterJsonDict["oldCodeNameComboBox"], flags=Qt.MatchExactly + ) self.oldCodeNameComboBox.setCurrentIndex(oldIdx) - self.newCodeNameLineEdit.setText(uiParameterJsonDict['newCodeNameLineEdit']) + self.newCodeNameLineEdit.setText(uiParameterJsonDict["newCodeNameLineEdit"]) def getTitle(self): return self.title - + def setTitle(self, title): self.title = title - + def populateDomainCombo(self): self.domainComboBox.clear() - self.domainComboBox.addItem(self.tr('Choose a domain')) + self.domainComboBox.addItem(self.tr("Choose a domain")) domainList = self.abstractDb.getDomainTables() for domain in domainList: self.domainComboBox.addItem(domain) - + @pyqtSlot(int) def on_domainComboBox_currentIndexChanged(self, idx): if idx != 0: domainName = self.domainComboBox.currentText() self.oldCodeNameComboBox.setEnabled(True) self.oldCodeNameComboBox.clear() - self.oldCodeNameComboBox.addItem('Choose a code name') - self.domainDict = self.abstractDb.getDomainDictV2('dominios.'+domainName) + self.oldCodeNameComboBox.addItem("Choose a code name") + self.domainDict = self.abstractDb.getDomainDictV2("dominios." + domainName) for codeName in list(self.domainDict.keys()): self.oldCodeNameComboBox.addItem(codeName) self.newCodeNameLineEdit.setEnabled(True) @@ -95,41 +103,50 @@ def on_domainComboBox_currentIndexChanged(self, idx): self.newCodeNameLineEdit.clear() self.oldCodeNameComboBox.setEnabled(False) self.oldCodeNameComboBox.clear() - + @pyqtSlot(int) def on_oldCodeNameComboBox_currentIndexChanged(self, idx): self.newCodeNameLineEdit.setEnabled(True) self.newCodeNameLineEdit.clear() - + def validate(self): if self.domainComboBox.currentIndex() == 0: return False if self.oldCodeNameComboBox.currentIndex() == 0: return False - if self.newCodeNameLineEdit.text() == '': + if self.newCodeNameLineEdit.text() == "": return False return True def validateDiagnosis(self): - invalidatedReason = '' + invalidatedReason = "" if self.domainComboBox.currentIndex() == 0: - invalidatedReason += self.tr('A domain table must be chosen.\n') + invalidatedReason += self.tr("A domain table must be chosen.\n") if self.oldCodeNameComboBox.currentIndex() == 0: - invalidatedReason += self.tr('An old code name value must be chosen.\n') - if self.newCodeNameLineEdit.text() == '': - invalidatedReason += self.tr('A new code name value must be chosen.\n') + invalidatedReason += self.tr("An old code name value must be chosen.\n") + if self.newCodeNameLineEdit.text() == "": + invalidatedReason += self.tr("A new code name value must be chosen.\n") invalidatedReason += self.addAttributeWidget.validateDiagnosis() return invalidatedReason - + def getJSONTag(self): if not self.validate(): - raise Exception(self.tr('Error in code name customization ')+ self.title + ' : ' + self.validateDiagnosis()) + raise Exception( + self.tr("Error in code name customization ") + + self.title + + " : " + + self.validateDiagnosis() + ) domainTable = self.domainComboBox.currentText() oldCodeName = self.oldCodeNameComboBox.currentText() newCodeName = self.newCodeNameLineEdit.text() codeValue = self.domainDict[oldCodeName] - return [self.jsonBuilder.buildCodeNameToChangeElement(domainTable, codeValue, oldCodeName, newCodeName)] - + return [ + self.jsonBuilder.buildCodeNameToChangeElement( + domainTable, codeValue, oldCodeName, newCodeName + ) + ] + def getUiParameterJsonDict(self): """ builds a dict with the following format: @@ -140,8 +157,9 @@ def getUiParameterJsonDict(self): } """ uiParameterJsonDict = dict() - uiParameterJsonDict['domainComboBox'] = self.domainComboBox.currentText() - uiParameterJsonDict['oldCodeNameComboBox'] = self.oldCodeNameComboBox.currentText() - uiParameterJsonDict['newCodeNameLineEdit'] = self.newCodeNameLineEdit.text() + uiParameterJsonDict["domainComboBox"] = self.domainComboBox.currentText() + uiParameterJsonDict[ + "oldCodeNameComboBox" + ] = self.oldCodeNameComboBox.currentText() + uiParameterJsonDict["newCodeNameLineEdit"] = self.newCodeNameLineEdit.text() return uiParameterJsonDict - \ No newline at end of file diff --git a/DsgTools/gui/CustomWidgets/CustomDbManagementWidgets/domainSetter.py b/DsgTools/gui/CustomWidgets/CustomDbManagementWidgets/domainSetter.py index 6eacfde6d..fb02e7722 100644 --- a/DsgTools/gui/CustomWidgets/CustomDbManagementWidgets/domainSetter.py +++ b/DsgTools/gui/CustomWidgets/CustomDbManagementWidgets/domainSetter.py @@ -35,14 +35,19 @@ from DsgTools.gui.ServerTools.viewServers import ViewServers from DsgTools.core.Factories.SqlFactory.sqlGeneratorFactory import SqlGeneratorFactory from DsgTools.core.Factories.DbFactory.dbFactory import DbFactory -from DsgTools.gui.Misc.PostgisCustomization.CustomJSONTools.customJSONBuilder import CustomJSONBuilder +from DsgTools.gui.Misc.PostgisCustomization.CustomJSONTools.customJSONBuilder import ( + CustomJSONBuilder, +) + +FORM_CLASS, _ = uic.loadUiType( + os.path.join(os.path.dirname(__file__), "domainSetter.ui") +) -FORM_CLASS, _ = uic.loadUiType(os.path.join( - os.path.dirname(__file__), 'domainSetter.ui')) class DomainSetter(QtWidgets.QDialog, FORM_CLASS): domainChanged = pyqtSignal(str, dict, dict) - def __init__(self, abstractDb, uiParameterJsonDict = None, parent = None): + + def __init__(self, abstractDb, uiParameterJsonDict=None, parent=None): """Constructor.""" super(self.__class__, self).__init__(parent) self.setupUi(self) @@ -53,7 +58,7 @@ def __init__(self, abstractDb, uiParameterJsonDict = None, parent = None): self.filterClause = dict() self.jsonBuilder = CustomJSONBuilder() self.populateFromUiParameterJsonDict(uiParameterJsonDict) - + def populateFromUiParameterJsonDict(self, uiParameterJsonDict): """ populates ui from uiParameterJsonDict with the following keys: @@ -64,15 +69,19 @@ def populateFromUiParameterJsonDict(self, uiParameterJsonDict): } """ if uiParameterJsonDict: - item = self.domainListWidget.findItems(uiParameterJsonDict['domainListWidget'], Qt.MatchExactly) - if isinstance(item,list): + item = self.domainListWidget.findItems( + uiParameterJsonDict["domainListWidget"], Qt.MatchExactly + ) + if isinstance(item, list): item = item[0] self.domainListWidget.setCurrentItem(item) - if uiParameterJsonDict['filterCheckBox']: + if uiParameterJsonDict["filterCheckBox"]: self.filterCheckBox.setCheckState(QtCore.Qt.Checked) - for codeName in uiParameterJsonDict['filterListWidgetCheckedItems']: - codeNameItem = self.filterListWidget.findItems(codeName, Qt.MatchExactly) - if isinstance(codeNameItem,list): + for codeName in uiParameterJsonDict["filterListWidgetCheckedItems"]: + codeNameItem = self.filterListWidget.findItems( + codeName, Qt.MatchExactly + ) + if isinstance(codeNameItem, list): codeNameItem = codeNameItem[0] else: codeNameItem = codeNameItem @@ -84,7 +93,7 @@ def populateDomainList(self): self.domainListWidget.clear() for domain in self.domainTableList: self.domainListWidget.addItem(domain) - + def clearAll(self): self.filterLineEdit.clear() self.filterListWidget.clear() @@ -96,12 +105,12 @@ def clearAll(self): def enableItems(self, enabled): self.filterListWidget.setEnabled(enabled) - + def clearCheckableItems(self): for idx in range(self.filterListWidget.__len__()): item = self.filterListWidget.item(idx) item.setCheckState(QtCore.Qt.Unchecked) - + @pyqtSlot(int) def on_filterCheckBox_stateChanged(self, idx): if idx == 2: @@ -110,49 +119,57 @@ def on_filterCheckBox_stateChanged(self, idx): state = False self.clearCheckableItems() self.enableItems(state) - + def getSelectedDomain(self): return self.domainListWidget.selectedItems()[0].data() - + @pyqtSlot(int) def on_domainListWidget_currentRowChanged(self, idx): curItem = self.domainListWidget.item(idx) self.filterListWidget.clear() if curItem: self.domainName = curItem.data(0) - self.domainDict = self.abstractDb.getDomainDictV2('dominios.'+self.domainName) + self.domainDict = self.abstractDb.getDomainDictV2( + "dominios." + self.domainName + ) for codeName in list(self.domainDict.keys()): newItem = QListWidgetItem(codeName) - newItem.setFlags(QtCore.Qt.ItemIsEnabled | QtCore.Qt.ItemIsTristate | QtCore.Qt.ItemIsUserCheckable) + newItem.setFlags( + QtCore.Qt.ItemIsEnabled + | QtCore.Qt.ItemIsTristate + | QtCore.Qt.ItemIsUserCheckable + ) newItem.setCheckState(QtCore.Qt.Unchecked) self.filterListWidget.addItem(newItem) - + def on_filterLineEdit_textChanged(self, text): - ''' + """ Filters the items to make it easier to spot and select them - ''' - classes = [edgvDomain for edgvDomain in self.domainTableList if text in edgvDomain] + """ + classes = [ + edgvDomain for edgvDomain in self.domainTableList if text in edgvDomain + ] self.domainListWidget.clear() self.domainListWidget.addItems(classes) self.domainListWidget.sortItems() - + @pyqtSlot() def on_buttonBox_rejected(self): self.clearAll() - @pyqtSlot(name='on_buttonBox_accepted') + @pyqtSlot(name="on_buttonBox_accepted") def applyChanges(self): for idx in range(self.filterListWidget.__len__()): item = self.filterListWidget.item(idx) if item.checkState() == 2: - codeName = item.data(0) + codeName = item.data(0) if codeName not in list(self.filterClause.keys()): self.filterClause[codeName] = self.domainDict[codeName] self.domainChanged.emit(self.domainName, self.domainDict, self.filterClause) - + def getChildWidgets(self): return None - + def getUiParameterJsonDict(self): """ builds a dict with the following format: @@ -163,11 +180,13 @@ def getUiParameterJsonDict(self): } """ uiParameterJsonDict = dict() - uiParameterJsonDict['domainListWidget'] = self.domainListWidget.currentItem().data(0) - uiParameterJsonDict['filterCheckBox'] = self.filterCheckBox.isChecked() - uiParameterJsonDict['filterListWidgetCheckedItems'] = [] + uiParameterJsonDict[ + "domainListWidget" + ] = self.domainListWidget.currentItem().data(0) + uiParameterJsonDict["filterCheckBox"] = self.filterCheckBox.isChecked() + uiParameterJsonDict["filterListWidgetCheckedItems"] = [] for idx in range(self.filterListWidget.__len__()): item = self.filterListWidget.item(idx) if item.checkState() == 2: - uiParameterJsonDict['filterListWidgetCheckedItems'].append(item.data(0)) - return uiParameterJsonDict \ No newline at end of file + uiParameterJsonDict["filterListWidgetCheckedItems"].append(item.data(0)) + return uiParameterJsonDict diff --git a/DsgTools/gui/CustomWidgets/CustomDbManagementWidgets/newAttributeWidget.py b/DsgTools/gui/CustomWidgets/CustomDbManagementWidgets/newAttributeWidget.py index b630dd299..4b0f4a5bf 100644 --- a/DsgTools/gui/CustomWidgets/CustomDbManagementWidgets/newAttributeWidget.py +++ b/DsgTools/gui/CustomWidgets/CustomDbManagementWidgets/newAttributeWidget.py @@ -33,13 +33,17 @@ from DsgTools.gui.ServerTools.viewServers import ViewServers from DsgTools.core.Factories.SqlFactory.sqlGeneratorFactory import SqlGeneratorFactory from DsgTools.core.Factories.DbFactory.dbFactory import DbFactory -from DsgTools.gui.Misc.PostgisCustomization.CustomJSONTools.customJSONBuilder import CustomJSONBuilder +from DsgTools.gui.Misc.PostgisCustomization.CustomJSONTools.customJSONBuilder import ( + CustomJSONBuilder, +) + +FORM_CLASS, _ = uic.loadUiType( + os.path.join(os.path.dirname(__file__), "newAttributeWidget.ui") +) -FORM_CLASS, _ = uic.loadUiType(os.path.join( - os.path.dirname(__file__), 'newAttributeWidget.ui')) class NewAttributeWidget(QtWidgets.QWidget, FORM_CLASS): - def __init__(self, abstractDb, uiParameterJsonDict = None, parent = None): + def __init__(self, abstractDb, uiParameterJsonDict=None, parent=None): """Constructor.""" super(self.__class__, self).__init__(parent) self.abstractDb = abstractDb @@ -48,7 +52,7 @@ def __init__(self, abstractDb, uiParameterJsonDict = None, parent = None): self.jsonBuilder = CustomJSONBuilder() self.populateSchemaCombo() self.populateFromUiParameterJsonDict(uiParameterJsonDict) - + def populateFromUiParameterJsonDict(self, uiParameterJsonDict): """ { @@ -59,29 +63,35 @@ def populateFromUiParameterJsonDict(self, uiParameterJsonDict): } """ if uiParameterJsonDict: - if uiParameterJsonDict['allTablesCheckBox']: + if uiParameterJsonDict["allTablesCheckBox"]: self.allTablesCheckBox.setCheckState(Qt.Checked) else: - schemaIdx = self.schemaComboBox.findText(uiParameterJsonDict['schemaComboBox'], flags = Qt.MatchExactly) + schemaIdx = self.schemaComboBox.findText( + uiParameterJsonDict["schemaComboBox"], flags=Qt.MatchExactly + ) self.schemaComboBox.setCurrentIndex(schemaIdx) - tableIdx = self.tableComboBox.findText(uiParameterJsonDict['tableComboBox'], flags = Qt.MatchExactly) + tableIdx = self.tableComboBox.findText( + uiParameterJsonDict["tableComboBox"], flags=Qt.MatchExactly + ) self.tableComboBox.setCurrentIndex(tableIdx) - self.addAttributeWidget.populateFromUiParameterJsonDict(uiParameterJsonDict['attrWidget']) - + self.addAttributeWidget.populateFromUiParameterJsonDict( + uiParameterJsonDict["attrWidget"] + ) + def getTitle(self): return self.title - + def setTitle(self, title): self.title = title - + def populateSchemaCombo(self): self.schemaComboBox.clear() - self.schemaComboBox.addItem(self.tr('Select a schema')) + self.schemaComboBox.addItem(self.tr("Select a schema")) schemaList = self.abstractDb.getGeometricSchemaList() for schema in schemaList: - if schema not in ['views', 'validation']: + if schema not in ["views", "validation"]: self.schemaComboBox.addItem(schema) - + @pyqtSlot(int) def on_schemaComboBox_currentIndexChanged(self, idx): if idx == 0: @@ -91,13 +101,13 @@ def on_schemaComboBox_currentIndexChanged(self, idx): schema = self.schemaComboBox.currentText() self.tableComboBox.setEnabled(True) self.tableComboBox.clear() - self.tableComboBox.addItem(self.tr('Select a table')) + self.tableComboBox.addItem(self.tr("Select a table")) tableList = self.abstractDb.getGeometricTableListFromSchema(schema) for table in tableList: self.tableComboBox.addItem(table) - + @pyqtSlot(int) - def on_allTablesCheckBox_stateChanged(self,idx): + def on_allTablesCheckBox_stateChanged(self, idx): if idx == 2: self.tableComboBox.clear() self.tableComboBox.setEnabled(False) @@ -106,43 +116,64 @@ def on_allTablesCheckBox_stateChanged(self,idx): else: self.schemaComboBox.setEnabled(True) self.populateSchemaCombo() - + def validate(self): if not self.allTablesCheckBox.isChecked(): - if self.tableComboBox.currentText() == '': + if self.tableComboBox.currentText() == "": return False - if self.schemaComboBox.currentText() == '': + if self.schemaComboBox.currentText() == "": return False return self.addAttributeWidget.validate() def validateDiagnosis(self): - invalidatedReason = '' + invalidatedReason = "" if self.tableComboBox.currentIndex() == 0: - invalidatedReason += self.tr('A table name must be chosen.\n') + invalidatedReason += self.tr("A table name must be chosen.\n") if self.schemaComboBox.currentIndex() == 0: - invalidatedReason += self.tr('A schema must be chosen.\n') + invalidatedReason += self.tr("A schema must be chosen.\n") invalidatedReason += self.addAttributeWidget.validateDiagnosis() return invalidatedReason - + def getJSONTag(self): if not self.validate(): - raise Exception(self.tr('Error in attribute ')+ self.title + ' : ' + self.validateDiagnosis()) + raise Exception( + self.tr("Error in attribute ") + + self.title + + " : " + + self.validateDiagnosis() + ) schema = self.schemaComboBox.currentText() tableName = self.tableComboBox.currentText() attrList = [self.addAttributeWidget.getJSONTag()] if not self.allTablesCheckBox.isChecked(): - bloodLine = [i for i in self.abstractDb.getInheritanceBloodLine(tableName) if i != tableName] - return [self.jsonBuilder.buildNewAttributeElement(schema, tableName, attrList, childrenToAlter = bloodLine)] + bloodLine = [ + i + for i in self.abstractDb.getInheritanceBloodLine(tableName) + if i != tableName + ] + return [ + self.jsonBuilder.buildNewAttributeElement( + schema, tableName, attrList, childrenToAlter=bloodLine + ) + ] else: attrModList = [] - classTuppleList = self.abstractDb.getParentGeomTables(getTupple = True) + classTuppleList = self.abstractDb.getParentGeomTables(getTupple=True) for tupple in classTuppleList: schema, tableName = tupple - if schema not in ('views', 'validation'): - bloodLine = [i for i in self.abstractDb.getInheritanceBloodLine(tableName) if i != tableName] - attrModList.append(self.jsonBuilder.buildNewAttributeElement(schema, tableName, attrList, childrenToAlter = bloodLine)) + if schema not in ("views", "validation"): + bloodLine = [ + i + for i in self.abstractDb.getInheritanceBloodLine(tableName) + if i != tableName + ] + attrModList.append( + self.jsonBuilder.buildNewAttributeElement( + schema, tableName, attrList, childrenToAlter=bloodLine + ) + ) return attrModList - + def getUiParameterJsonDict(self): """ builds a dict with the following format: @@ -154,8 +185,10 @@ def getUiParameterJsonDict(self): } """ uiParameterJsonDict = dict() - uiParameterJsonDict['schemaComboBox'] = self.schemaComboBox.currentText() - uiParameterJsonDict['tableComboBox'] = self.tableComboBox.currentText() - uiParameterJsonDict['allTablesCheckBox'] = self.allTablesCheckBox.isChecked() - uiParameterJsonDict['attrWidget'] = self.addAttributeWidget.getUiParameterJsonDict() - return uiParameterJsonDict \ No newline at end of file + uiParameterJsonDict["schemaComboBox"] = self.schemaComboBox.currentText() + uiParameterJsonDict["tableComboBox"] = self.tableComboBox.currentText() + uiParameterJsonDict["allTablesCheckBox"] = self.allTablesCheckBox.isChecked() + uiParameterJsonDict[ + "attrWidget" + ] = self.addAttributeWidget.getUiParameterJsonDict() + return uiParameterJsonDict diff --git a/DsgTools/gui/CustomWidgets/CustomDbManagementWidgets/newClassWidget.py b/DsgTools/gui/CustomWidgets/CustomDbManagementWidgets/newClassWidget.py index f91e1030b..a873affd5 100644 --- a/DsgTools/gui/CustomWidgets/CustomDbManagementWidgets/newClassWidget.py +++ b/DsgTools/gui/CustomWidgets/CustomDbManagementWidgets/newClassWidget.py @@ -34,31 +34,41 @@ from DsgTools.gui.ServerTools.viewServers import ViewServers from DsgTools.core.Factories.SqlFactory.sqlGeneratorFactory import SqlGeneratorFactory from DsgTools.core.Factories.DbFactory.dbFactory import DbFactory -from DsgTools.gui.CustomWidgets.CustomDbManagementWidgets.addAttributeWidget import AddAttributeWidget -from DsgTools.gui.Misc.PostgisCustomization.CustomJSONTools.customJSONBuilder import CustomJSONBuilder +from DsgTools.gui.CustomWidgets.CustomDbManagementWidgets.addAttributeWidget import ( + AddAttributeWidget, +) +from DsgTools.gui.Misc.PostgisCustomization.CustomJSONTools.customJSONBuilder import ( + CustomJSONBuilder, +) + +FORM_CLASS, _ = uic.loadUiType( + os.path.join(os.path.dirname(__file__), "newClassWidget.ui") +) -FORM_CLASS, _ = uic.loadUiType(os.path.join( - os.path.dirname(__file__), 'newClassWidget.ui')) class NewClassWidget(QtWidgets.QWidget, FORM_CLASS): - def __init__(self, abstractDb, uiParameterJsonDict = None, parent = None): + def __init__(self, abstractDb, uiParameterJsonDict=None, parent=None): """Constructor.""" super(self.__class__, self).__init__(parent) self.setupUi(self) - self.geomUiDict = {self.tr('Point'):{'sufix':'p','type':'MULTIPOINT([epsg])'}, self.tr('Line'):{'sufix':'l','type':'MULTILINESTRING([epsg])'}, self.tr('Area'):{'sufix':'a','type':'MULTIPOLYGON([epsg])'}} + self.geomUiDict = { + self.tr("Point"): {"sufix": "p", "type": "MULTIPOINT([epsg])"}, + self.tr("Line"): {"sufix": "l", "type": "MULTILINESTRING([epsg])"}, + self.tr("Area"): {"sufix": "a", "type": "MULTIPOLYGON([epsg])"}, + } header = self.tableWidget.horizontalHeader() header.setStretchLastSection(True) - regex = QtCore.QRegExp('[a-z][a-z\_]*') + regex = QtCore.QRegExp("[a-z][a-z\_]*") validator = QtGui.QRegExpValidator(regex, self.classNameLineEdit) self.classNameLineEdit.setValidator(validator) - regex2 = QtCore.QRegExp('[a-z]*') + regex2 = QtCore.QRegExp("[a-z]*") validator2 = QtGui.QRegExpValidator(regex2, self.categoryLineEdit) self.categoryLineEdit.setValidator(validator2) self.abstractDb = abstractDb self.populateSchemaCombo() self.jsonBuilder = CustomJSONBuilder() self.populateFromUiParameterJsonDict(uiParameterJsonDict) - + def populateFromUiParameterJsonDict(self, uiParameterJsonDict): """ populates ui from uiParameterJsonDict with the following keys: @@ -71,40 +81,46 @@ def populateFromUiParameterJsonDict(self, uiParameterJsonDict): } """ if uiParameterJsonDict: - idx = self.schemaComboBox.findText(uiParameterJsonDict['schemaComboBox'], flags = Qt.MatchExactly) + idx = self.schemaComboBox.findText( + uiParameterJsonDict["schemaComboBox"], flags=Qt.MatchExactly + ) self.schemaComboBox.setCurrentIndex(idx) - self.categoryLineEdit.setText(uiParameterJsonDict['categoryLineEdit']) - self.classNameLineEdit.setText(uiParameterJsonDict['classNameLineEdit']) - self.geomComboBox.setCurrentIndex(int(uiParameterJsonDict['geomComboBoxIdx'])) - for attr in uiParameterJsonDict['attrWidgetList']: + self.categoryLineEdit.setText(uiParameterJsonDict["categoryLineEdit"]) + self.classNameLineEdit.setText(uiParameterJsonDict["classNameLineEdit"]) + self.geomComboBox.setCurrentIndex( + int(uiParameterJsonDict["geomComboBoxIdx"]) + ) + for attr in uiParameterJsonDict["attrWidgetList"]: self.addCellWidget(uiParameterJsonDict=attr) - + def populateSchemaCombo(self): self.schemaComboBox.clear() schemaList = self.abstractDb.getGeometricSchemaList() for schema in schemaList: - if schema not in ['views', 'validation']: + if schema not in ["views", "validation"]: self.schemaComboBox.addItem(schema) - + @pyqtSlot() def on_classNameLineEdit_editingFinished(self): text = self.classNameLineEdit.text() - while text[-1] == '_': + while text[-1] == "_": self.classNameLineEdit.setText(text[0:-1]) text = text[0:-1] - + @pyqtSlot(str) def on_classNameLineEdit_textEdited(self, newText): if len(newText) > 1: - if newText[-1] == '_' and newText[-2] == '_': - self.classNameLineEdit.setText(newText[0:-1]) - - @pyqtSlot(bool, name='on_addAttributePushButton_clicked') - def addCellWidget(self, uiParameterJsonDict = None): + if newText[-1] == "_" and newText[-2] == "_": + self.classNameLineEdit.setText(newText[0:-1]) + + @pyqtSlot(bool, name="on_addAttributePushButton_clicked") + def addCellWidget(self, uiParameterJsonDict=None): index = self.tableWidget.rowCount() self.tableWidget.insertRow(index) - newAttribute = AddAttributeWidget(self.abstractDb, uiParameterJsonDict = uiParameterJsonDict) - self.tableWidget.setCellWidget(index,0,newAttribute) + newAttribute = AddAttributeWidget( + self.abstractDb, uiParameterJsonDict=uiParameterJsonDict + ) + self.tableWidget.setCellWidget(index, 0, newAttribute) @pyqtSlot(bool) def on_removePushButton_clicked(self): @@ -113,61 +129,77 @@ def on_removePushButton_clicked(self): rowList.sort(reverse=True) for row in rowList: self.tableWidget.removeRow(row) - + def getTitle(self): return self.title - + def setTitle(self, title): self.title = title - + def getChildWidgetList(self): childWidgetList = [] for i in range(self.tableWidget.rowCount()): - childWidgetList.append(self.tableWidget.cellWidget(i,0)) + childWidgetList.append(self.tableWidget.cellWidget(i, 0)) return childWidgetList - + def validate(self): - if self.categoryLineEdit.text() == '': + if self.categoryLineEdit.text() == "": return False - if self.classNameLineEdit.text() == '': + if self.classNameLineEdit.text() == "": return False if self.geomComboBox.currentIndex() == 0: return False - #TODO: validate attributes + # TODO: validate attributes return True def validateDiagnosis(self): - invalidatedReason = '' - if self.categoryLineEdit.text() == '': - invalidatedReason += self.tr('Class must have a category.\n') - if self.classNameLineEdit.text() == '': - invalidatedReason += self.tr('Class must have a name.\n') + invalidatedReason = "" + if self.categoryLineEdit.text() == "": + invalidatedReason += self.tr("Class must have a category.\n") + if self.classNameLineEdit.text() == "": + invalidatedReason += self.tr("Class must have a name.\n") if self.geomComboBox.currentIndex() == 0: - invalidatedReason += self.tr('Class must have a geometric primitive.\n') - #TODO: validate attributes + invalidatedReason += self.tr("Class must have a geometric primitive.\n") + # TODO: validate attributes return invalidatedReason def getJSONTag(self): if not self.validate(): - raise Exception(self.tr('Error in class ')+ self.title + ' : ' + self.validateDiagnosis()) + raise Exception( + self.tr("Error in class ") + + self.title + + " : " + + self.validateDiagnosis() + ) schema = self.schemaComboBox.currentText() - name = '_'.join([ self.categoryLineEdit.text(), self.classNameLineEdit.text(), self.geomUiDict[self.geomComboBox.currentText()]['sufix'] ]) + name = "_".join( + [ + self.categoryLineEdit.text(), + self.classNameLineEdit.text(), + self.geomUiDict[self.geomComboBox.currentText()]["sufix"], + ] + ) widgetList = self.getChildWidgetList() attrList = [] - #create pk attr - pkItem = self.jsonBuilder.buildAttributeElement('id', 'serial', True, False) + # create pk attr + pkItem = self.jsonBuilder.buildAttributeElement("id", "serial", True, False) attrList.append(pkItem) - #create geom attr - geomItem = self.jsonBuilder.buildAttributeElement('geom', self.geomUiDict[self.geomComboBox.currentText()]['type'], False, False) + # create geom attr + geomItem = self.jsonBuilder.buildAttributeElement( + "geom", + self.geomUiDict[self.geomComboBox.currentText()]["type"], + False, + False, + ) attrList.append(geomItem) for widget in widgetList: newAttrJson = widget.getJSONTag() - if isinstance(newAttrJson,list): + if isinstance(newAttrJson, list): for i in newAttrJson: attrList.append(i) else: attrList.append(newAttrJson) - return [self.jsonBuilder.buildClassElement(schema,name,attrList)] + return [self.jsonBuilder.buildClassElement(schema, name, attrList)] def getUiParameterJsonDict(self): """ @@ -181,14 +213,14 @@ def getUiParameterJsonDict(self): } """ uiParameterJsonDict = dict() - uiParameterJsonDict['schemaComboBox'] = self.schemaComboBox.currentText() - uiParameterJsonDict['categoryLineEdit'] = self.categoryLineEdit.text() - uiParameterJsonDict['classNameLineEdit'] = self.classNameLineEdit.text() - uiParameterJsonDict['geomComboBoxIdx'] = self.geomComboBox.currentIndex() - uiParameterJsonDict['attrWidgetList'] = [] + uiParameterJsonDict["schemaComboBox"] = self.schemaComboBox.currentText() + uiParameterJsonDict["categoryLineEdit"] = self.categoryLineEdit.text() + uiParameterJsonDict["classNameLineEdit"] = self.classNameLineEdit.text() + uiParameterJsonDict["geomComboBoxIdx"] = self.geomComboBox.currentIndex() + uiParameterJsonDict["attrWidgetList"] = [] widgetList = self.getChildWidgetList() for widget in widgetList: - uiParameterJsonDict['attrWidgetList'].append(widget.getUiParameterJsonDict()) + uiParameterJsonDict["attrWidgetList"].append( + widget.getUiParameterJsonDict() + ) return uiParameterJsonDict - - \ No newline at end of file diff --git a/DsgTools/gui/CustomWidgets/CustomDbManagementWidgets/newDomainValueWidget.py b/DsgTools/gui/CustomWidgets/CustomDbManagementWidgets/newDomainValueWidget.py index 86377a8ca..0273167da 100644 --- a/DsgTools/gui/CustomWidgets/CustomDbManagementWidgets/newDomainValueWidget.py +++ b/DsgTools/gui/CustomWidgets/CustomDbManagementWidgets/newDomainValueWidget.py @@ -33,24 +33,28 @@ from DsgTools.gui.ServerTools.viewServers import ViewServers from DsgTools.core.Factories.SqlFactory.sqlGeneratorFactory import SqlGeneratorFactory from DsgTools.core.Factories.DbFactory.dbFactory import DbFactory -from DsgTools.gui.Misc.PostgisCustomization.CustomJSONTools.customJSONBuilder import CustomJSONBuilder +from DsgTools.gui.Misc.PostgisCustomization.CustomJSONTools.customJSONBuilder import ( + CustomJSONBuilder, +) + +FORM_CLASS, _ = uic.loadUiType( + os.path.join(os.path.dirname(__file__), "newDomainValueWidget.ui") +) -FORM_CLASS, _ = uic.loadUiType(os.path.join( - os.path.dirname(__file__), 'newDomainValueWidget.ui')) class NewDomainValueWidget(QtWidgets.QWidget, FORM_CLASS): - def __init__(self, abstractDb, uiParameterJsonDict = None, parent = None): + def __init__(self, abstractDb, uiParameterJsonDict=None, parent=None): """Constructor.""" super(self.__class__, self).__init__(parent) self.abstractDb = abstractDb self.setupUi(self) self.jsonBuilder = CustomJSONBuilder() self.populateDomainCombo() - regex = QtCore.QRegExp('[0-9]*') + regex = QtCore.QRegExp("[0-9]*") validator = QtGui.QRegExpValidator(regex, self.codeLineEdit) self.codeLineEdit.setValidator(validator) self.populateFromUiParameterJsonDict(uiParameterJsonDict) - + def populateFromUiParameterJsonDict(self, uiParameterJsonDict): """ builds ui from uiParameterJsonDict @@ -62,21 +66,23 @@ def populateFromUiParameterJsonDict(self, uiParameterJsonDict): } """ if uiParameterJsonDict: - if uiParameterJsonDict['allDomainCheckBox']: + if uiParameterJsonDict["allDomainCheckBox"]: self.allDomainCheckBox.setCheckState(Qt.Checked) else: - domainIdx = self.domainComboBox.findText(uiParameterJsonDict['domainComboBox'], flags = Qt.MatchExactly) + domainIdx = self.domainComboBox.findText( + uiParameterJsonDict["domainComboBox"], flags=Qt.MatchExactly + ) self.domainComboBox.setCurrentIndex(domainIdx) - self.codeLineEdit.setText(uiParameterJsonDict['codeLineEdit']) - self.codeNameLineEdit.setText(uiParameterJsonDict['codeNameLineEdit']) - + self.codeLineEdit.setText(uiParameterJsonDict["codeLineEdit"]) + self.codeNameLineEdit.setText(uiParameterJsonDict["codeNameLineEdit"]) + def populateDomainCombo(self): self.domainTableList = self.abstractDb.getDomainTables() self.domainComboBox.clear() - self.domainComboBox.addItem(self.tr('Select a domain')) + self.domainComboBox.addItem(self.tr("Select a domain")) for domain in self.domainTableList: self.domainComboBox.addItem(domain) - + @pyqtSlot(int) def on_domainComboBox_currentIndexChanged(self, idx): if idx == 0: @@ -88,7 +94,7 @@ def on_domainComboBox_currentIndexChanged(self, idx): self.codeLineEdit.setEnabled(True) self.codeNameLineEdit.setEnabled(True) self.codeLineEdit.editingFinished.emit() - + @pyqtSlot(int) def on_allDomainCheckBox_stateChanged(self, state): if state == 2: @@ -96,38 +102,42 @@ def on_allDomainCheckBox_stateChanged(self, state): else: self.populateDomainCombo() self.codeLineEdit.editingFinished.emit() - + @pyqtSlot() def on_codeLineEdit_editingFinished(self): if self.domainComboBox.currentIndex() == 0: - self.codeLineEdit.setStyleSheet('') - self.codeLineEdit.setToolTip('') + self.codeLineEdit.setStyleSheet("") + self.codeLineEdit.setToolTip("") return if self.allDomainCheckBox.checkState() == 2: domainValues = self.abstractDb.getAllDomainValues() else: - domainValues = self.abstractDb.getAllDomainValues(domainTableList = [self.domainComboBox.currentText()]) + domainValues = self.abstractDb.getAllDomainValues( + domainTableList=[self.domainComboBox.currentText()] + ) currentValue = self.codeLineEdit.text() - if currentValue == '': - self.codeLineEdit.setStyleSheet('') - self.codeLineEdit.setToolTip('') + if currentValue == "": + self.codeLineEdit.setStyleSheet("") + self.codeLineEdit.setToolTip("") elif int(currentValue) in domainValues: self.codeLineEdit.setStyleSheet("border: 1px solid red;") - self.codeLineEdit.setToolTip(self.tr('Code value already exists, choose another.')) + self.codeLineEdit.setToolTip( + self.tr("Code value already exists, choose another.") + ) else: - self.codeLineEdit.setStyleSheet('') - self.codeLineEdit.setToolTip('') + self.codeLineEdit.setStyleSheet("") + self.codeLineEdit.setToolTip("") def getTitle(self): return self.title - + def setTitle(self, title): self.title = title def validate(self): - if self.codeLineEdit.text() == '': + if self.codeLineEdit.text() == "": return False - if self.codeNameLineEdit.text() == '': + if self.codeNameLineEdit.text() == "": return False if self.allDomainCheckBox.checkState() == 2: return True @@ -137,27 +147,39 @@ def validate(self): return True def validateDiagnosis(self): - invalidatedReason = '' - if self.codeLineEdit.text() == '': - invalidatedReason += self.tr('A code value must be entered.\n') - if self.codeNameLineEdit.text() == '': - invalidatedReason += self.tr('A code name value must be entered.\n') - if self.domainComboBox.currentIndex() == 0 and self.allDomainCheckBox.checkState() != 2: - invalidatedReason += self.tr('A domain table must be chosen.\n') + invalidatedReason = "" + if self.codeLineEdit.text() == "": + invalidatedReason += self.tr("A code value must be entered.\n") + if self.codeNameLineEdit.text() == "": + invalidatedReason += self.tr("A code name value must be entered.\n") + if ( + self.domainComboBox.currentIndex() == 0 + and self.allDomainCheckBox.checkState() != 2 + ): + invalidatedReason += self.tr("A domain table must be chosen.\n") return invalidatedReason - + def getJSONTag(self): if not self.validate(): - raise Exception(self.tr('Error in new domain value ')+ self.title + ' : ' + self.validateDiagnosis()) + raise Exception( + self.tr("Error in new domain value ") + + self.title + + " : " + + self.validateDiagnosis() + ) code = self.codeLineEdit.text() codeName = self.codeNameLineEdit.text() jsonList = [] if self.allDomainCheckBox.checkState() != 2: domainName = self.domainComboBox.currentText() - jsonList.append(self.jsonBuilder.addDomainValueElement(domainName, code, codeName)) + jsonList.append( + self.jsonBuilder.addDomainValueElement(domainName, code, codeName) + ) else: for domainName in self.domainTableList: - jsonList.append(self.jsonBuilder.addDomainValueElement(domainName, code, codeName)) + jsonList.append( + self.jsonBuilder.addDomainValueElement(domainName, code, codeName) + ) return jsonList def getUiParameterJsonDict(self): @@ -171,9 +193,8 @@ def getUiParameterJsonDict(self): } """ uiParameterJsonDict = dict() - uiParameterJsonDict['domainComboBox'] = self.domainComboBox.currentText() - uiParameterJsonDict['allDomainCheckBox'] = self.allDomainCheckBox.isChecked() - uiParameterJsonDict['codeLineEdit'] = self.codeLineEdit.text() - uiParameterJsonDict['codeNameLineEdit'] = self.codeNameLineEdit.text() + uiParameterJsonDict["domainComboBox"] = self.domainComboBox.currentText() + uiParameterJsonDict["allDomainCheckBox"] = self.allDomainCheckBox.isChecked() + uiParameterJsonDict["codeLineEdit"] = self.codeLineEdit.text() + uiParameterJsonDict["codeNameLineEdit"] = self.codeNameLineEdit.text() return uiParameterJsonDict - \ No newline at end of file diff --git a/DsgTools/gui/CustomWidgets/CustomDbManagementWidgets/newDomainWidget.py b/DsgTools/gui/CustomWidgets/CustomDbManagementWidgets/newDomainWidget.py index 9b9a22421..fee16f0cb 100644 --- a/DsgTools/gui/CustomWidgets/CustomDbManagementWidgets/newDomainWidget.py +++ b/DsgTools/gui/CustomWidgets/CustomDbManagementWidgets/newDomainWidget.py @@ -35,36 +35,43 @@ from DsgTools.gui.ServerTools.viewServers import ViewServers from DsgTools.core.Factories.SqlFactory.sqlGeneratorFactory import SqlGeneratorFactory from DsgTools.core.Factories.DbFactory.dbFactory import DbFactory -from DsgTools.gui.CustomWidgets.CustomDbManagementWidgets.addAttributeWidget import AddAttributeWidget -from DsgTools.gui.Misc.PostgisCustomization.CustomJSONTools.customJSONBuilder import CustomJSONBuilder +from DsgTools.gui.CustomWidgets.CustomDbManagementWidgets.addAttributeWidget import ( + AddAttributeWidget, +) +from DsgTools.gui.Misc.PostgisCustomization.CustomJSONTools.customJSONBuilder import ( + CustomJSONBuilder, +) -FORM_CLASS, _ = uic.loadUiType(os.path.join( - os.path.dirname(__file__), 'newDomainWidget.ui')) +FORM_CLASS, _ = uic.loadUiType( + os.path.join(os.path.dirname(__file__), "newDomainWidget.ui") +) + class ValidatedItemDelegate(QtWidgets.QStyledItemDelegate): def createEditor(self, widget, option, index): if not index.isValid(): return 0 - if index.column() == 0: #only on the cells in the first column + if index.column() == 0: # only on the cells in the first column editor = QtGui.QLineEdit(widget) validator = QtGui.QRegExpValidator(QtCore.QRegExp("[0-9]*"), editor) editor.setValidator(validator) return editor elif index.column() == 1: editor = QtGui.QLineEdit(widget) - editor.setPlaceholderText(self.tr('Enter a value.')) + editor.setPlaceholderText(self.tr("Enter a value.")) return editor return super(ValidatedItemDelegate, self).createEditor(widget, option, index) + class NewDomainWidget(QtWidgets.QWidget, FORM_CLASS): - def __init__(self, abstractDb, uiParameterJsonDict = None, parent = None): + def __init__(self, abstractDb, uiParameterJsonDict=None, parent=None): """Constructor.""" super(self.__class__, self).__init__(parent) - self.setupUi(self) + self.setupUi(self) header = self.tableWidget.horizontalHeader() header.setStretchLastSection(True) - regex = QtCore.QRegExp('[a-z][a-z\_]*') + regex = QtCore.QRegExp("[a-z][a-z\_]*") validator = QtGui.QRegExpValidator(regex, self.domainNameLineEdit) self.domainNameLineEdit.setValidator(validator) self.abstractDb = abstractDb @@ -72,7 +79,7 @@ def __init__(self, abstractDb, uiParameterJsonDict = None, parent = None): self.tableWidget.setItemDelegate(ValidatedItemDelegate()) self.oldBackground = None self.populateFromUiParameterJsonDict(uiParameterJsonDict) - + def populateFromUiParameterJsonDict(self, uiParameterJsonDict): """ populates ui from uiParameterJsonDict with the following keys: @@ -82,34 +89,36 @@ def populateFromUiParameterJsonDict(self, uiParameterJsonDict): } """ if uiParameterJsonDict: - self.domainNameLineEdit.setText(uiParameterJsonDict['domainNameLineEdit']) - for domainItem in uiParameterJsonDict['tableWidget']: - self.addItemInTableWidget(codeText = domainItem[0], valueText = domainItem[1]) - + self.domainNameLineEdit.setText(uiParameterJsonDict["domainNameLineEdit"]) + for domainItem in uiParameterJsonDict["tableWidget"]: + self.addItemInTableWidget( + codeText=domainItem[0], valueText=domainItem[1] + ) + @pyqtSlot() def on_domainNameLineEdit_editingFinished(self): text = self.domainNameLineEdit.text() - while text[-1] == '_': + while text[-1] == "_": self.domainNameLineEdit.setText(text[0:-1]) text = text[0:-1] - + @pyqtSlot(str) def on_domainNameLineEdit_textEdited(self, newText): if len(newText) > 1: - if newText[-1] == '_' and newText[-2] == '_': - self.domainNameLineEdit.setText(newText[0:-1]) - - @pyqtSlot(bool, name='on_addValuePushButton_clicked') - def addItemInTableWidget(self, codeText = '', valueText = ''): + if newText[-1] == "_" and newText[-2] == "_": + self.domainNameLineEdit.setText(newText[0:-1]) + + @pyqtSlot(bool, name="on_addValuePushButton_clicked") + def addItemInTableWidget(self, codeText="", valueText=""): index = self.tableWidget.rowCount() self.tableWidget.insertRow(index) codeItem = QtGui.QTableWidgetItem(codeText) valueItem = QtGui.QTableWidgetItem(valueText) - self.tableWidget.setItem(self.tableWidget.rowCount()-1, 0, codeItem) - self.tableWidget.setItem(self.tableWidget.rowCount()-1, 1, valueItem) + self.tableWidget.setItem(self.tableWidget.rowCount() - 1, 0, codeItem) + self.tableWidget.setItem(self.tableWidget.rowCount() - 1, 1, valueItem) if index == 0: - self.oldBackground = self.tableWidget.item(0,0).background() - + self.oldBackground = self.tableWidget.item(0, 0).background() + @pyqtSlot(bool) def on_removeValuePushButton_clicked(self): selected = self.tableWidget.selectedIndexes() @@ -117,74 +126,74 @@ def on_removeValuePushButton_clicked(self): rowList.sort(reverse=True) for row in rowList: self.tableWidget.removeRow(row) - + @pyqtSlot(QTableWidgetItem) def on_tableWidget_itemChanged(self, widgetItem): if self.checkNull(widgetItem): return if self.tableWidget.currentColumn() == 0: self.checkUnique(widgetItem) - + def checkNull(self, widgetItem): - if widgetItem.text() == '': - widgetItem.setToolTip(self.tr('Enter a value!')) + if widgetItem.text() == "": + widgetItem.setToolTip(self.tr("Enter a value!")) return True else: - widgetItem.setToolTip('') + widgetItem.setToolTip("") return False - + def checkUnique(self, widgetItem): - currentValue = widgetItem.text() + currentValue = widgetItem.text() itemList = [] for i in range(self.tableWidget.rowCount()): if i != widgetItem.row(): curItem = self.tableWidget.item(i, 0) itemList.append(curItem.text()) if currentValue in itemList: - widgetItem.setBackground(QtGui.QColor(230,124,127)) + widgetItem.setBackground(QtGui.QColor(230, 124, 127)) self.tableWidget.setCurrentCell(widgetItem.row(), 0) - widgetItem.setToolTip(self.tr('Code value already entered.')) + widgetItem.setToolTip(self.tr("Code value already entered.")) else: if self.oldBackground: widgetItem.setBackground(self.oldBackground) - widgetItem.setToolTip('') - + widgetItem.setToolTip("") + def getTitle(self): return self.title - + def setTitle(self, title): self.title = title - + def validate(self): - if self.domainNameLineEdit.text() == '': + if self.domainNameLineEdit.text() == "": return False if self.tableHasEmptyValue(): return False if self.tableHasDuplicatedCode(): - return False + return False return True def validateDiagnosis(self): - invalidatedReason = '' - if self.domainNameLineEdit.text() == '': - invalidatedReason += self.tr('A domain name must be chosen.\n') + invalidatedReason = "" + if self.domainNameLineEdit.text() == "": + invalidatedReason += self.tr("A domain name must be chosen.\n") if self.tableHasEmptyValue(): - invalidatedReason += self.tr('There must be no empty codes or values.\n') + invalidatedReason += self.tr("There must be no empty codes or values.\n") if self.tableHasEmptyValue(): - invalidatedReason += self.tr('Codes must be unique.\n') + invalidatedReason += self.tr("Codes must be unique.\n") return invalidatedReason def tableHasEmptyValue(self): for row in range(self.tableWidget.rowCount()): for column in range(self.tableWidget.columnCount()): - if self.tableWidget.item(row,column).text() == '': + if self.tableWidget.item(row, column).text() == "": return True return False - + def tableHasDuplicatedCode(self): listOfCodes = [] for row in range(self.tableWidget.rowCount()): - code = self.tableWidget.item(row,0) + code = self.tableWidget.item(row, 0) if code not in listOfCodes: listOfCodes.append(code) else: @@ -193,12 +202,17 @@ def tableHasDuplicatedCode(self): def getJSONTag(self): if not self.validate(): - raise Exception(self.tr('Error in domain ')+ self.title + ' : ' + self.validateDiagnosis()) + raise Exception( + self.tr("Error in domain ") + + self.title + + " : " + + self.validateDiagnosis() + ) domainName = self.domainNameLineEdit.text() valueDict = dict() for row in range(self.tableWidget.rowCount()): - code = self.tableWidget.item(row,0).text() - value = self.tableWidget.item(row,1).text() + code = self.tableWidget.item(row, 0).text() + value = self.tableWidget.item(row, 1).text() valueDict[code] = value return [self.jsonBuilder.addDomainTableElement(domainName, valueDict)] @@ -211,10 +225,10 @@ def getUiParameterJsonDict(self): } """ uiParameterJsonDict = dict() - uiParameterJsonDict['domainNameLineEdit'] = self.domainNameLineEdit.text() - uiParameterJsonDict['tableWidget'] = [] + uiParameterJsonDict["domainNameLineEdit"] = self.domainNameLineEdit.text() + uiParameterJsonDict["tableWidget"] = [] for row in range(self.tableWidget.rowCount()): - code = self.tableWidget.item(row,0).text() - value = self.tableWidget.item(row,1).text() - uiParameterJsonDict['tableWidget'].append((code,value)) - return uiParameterJsonDict \ No newline at end of file + code = self.tableWidget.item(row, 0).text() + value = self.tableWidget.item(row, 1).text() + uiParameterJsonDict["tableWidget"].append((code, value)) + return uiParameterJsonDict diff --git a/DsgTools/gui/CustomWidgets/DatabaseConversionWidgets/MultiDsSelectorWidgets/SupportedDrivers/__init__.py b/DsgTools/gui/CustomWidgets/DatabaseConversionWidgets/MultiDsSelectorWidgets/SupportedDrivers/__init__.py index 8d1c8b69c..e69de29bb 100644 --- a/DsgTools/gui/CustomWidgets/DatabaseConversionWidgets/MultiDsSelectorWidgets/SupportedDrivers/__init__.py +++ b/DsgTools/gui/CustomWidgets/DatabaseConversionWidgets/MultiDsSelectorWidgets/SupportedDrivers/__init__.py @@ -1 +0,0 @@ - diff --git a/DsgTools/gui/CustomWidgets/DatabaseConversionWidgets/MultiDsSelectorWidgets/SupportedDrivers/abstractMultiDsSelectorWidget.py b/DsgTools/gui/CustomWidgets/DatabaseConversionWidgets/MultiDsSelectorWidgets/SupportedDrivers/abstractMultiDsSelectorWidget.py index b5ad16451..a0377f29e 100644 --- a/DsgTools/gui/CustomWidgets/DatabaseConversionWidgets/MultiDsSelectorWidgets/SupportedDrivers/abstractMultiDsSelectorWidget.py +++ b/DsgTools/gui/CustomWidgets/DatabaseConversionWidgets/MultiDsSelectorWidgets/SupportedDrivers/abstractMultiDsSelectorWidget.py @@ -1,4 +1,3 @@ - # -*- coding: utf-8 -*- """ /*************************************************************************** @@ -24,11 +23,13 @@ from qgis.PyQt.QtCore import QObject + class AbstractMultiDsSelectorWidget(QObject): """ Class containing minimum structure for multiple datasource selection. - Particularities from each driver are settled within its own class (child from this). + Particularities from each driver are settled within its own class (child from this). """ + def __init__(self, parent=None): """ Class constructor. diff --git a/DsgTools/gui/CustomWidgets/DatabaseConversionWidgets/MultiDsSelectorWidgets/SupportedDrivers/multiGeopackageSelectorWidget.py b/DsgTools/gui/CustomWidgets/DatabaseConversionWidgets/MultiDsSelectorWidgets/SupportedDrivers/multiGeopackageSelectorWidget.py index 38fabae3a..0d164c994 100644 --- a/DsgTools/gui/CustomWidgets/DatabaseConversionWidgets/MultiDsSelectorWidgets/SupportedDrivers/multiGeopackageSelectorWidget.py +++ b/DsgTools/gui/CustomWidgets/DatabaseConversionWidgets/MultiDsSelectorWidgets/SupportedDrivers/multiGeopackageSelectorWidget.py @@ -29,10 +29,12 @@ import os + class MultiGeopackageSelectorWidget(AbstractMultiDsSelectorWidget): """ Class designed to retrieve a Geopackage database list. """ + def __init__(self, parent=None): """ Class constructor. @@ -60,8 +62,10 @@ def exec_(self): """ # clear datasources self.datasources = {} - dbList = self.selector.getOpenFileNames(caption=self.tr("Select Geopackage Databases"), \ - filter=self.tr('Geopackage Databases (*.gpkg)'))[0] + dbList = self.selector.getOpenFileNames( + caption=self.tr("Select Geopackage Databases"), + filter=self.tr("Geopackage Databases (*.gpkg)"), + )[0] for db in dbList: self.datasources[db] = os.path.dirname(db) - return int(not self.datasources) # execution code + return int(not self.datasources) # execution code diff --git a/DsgTools/gui/CustomWidgets/DatabaseConversionWidgets/MultiDsSelectorWidgets/SupportedDrivers/multiNewDsSelector.py b/DsgTools/gui/CustomWidgets/DatabaseConversionWidgets/MultiDsSelectorWidgets/SupportedDrivers/multiNewDsSelector.py index 3b0eb109a..32fa3fa74 100644 --- a/DsgTools/gui/CustomWidgets/DatabaseConversionWidgets/MultiDsSelectorWidgets/SupportedDrivers/multiNewDsSelector.py +++ b/DsgTools/gui/CustomWidgets/DatabaseConversionWidgets/MultiDsSelectorWidgets/SupportedDrivers/multiNewDsSelector.py @@ -29,19 +29,23 @@ import os -FORM_CLASS, _ = uic.loadUiType(os.path.join(os.path.dirname(__file__), 'multiNewDsSelector.ui')) +FORM_CLASS, _ = uic.loadUiType( + os.path.join(os.path.dirname(__file__), "multiNewDsSelector.ui") +) + class MultiNewDsSelector(QDialog, FORM_CLASS): """ Class designed to control multiple (new) datasource selection widget. """ + def __init__(self, parent=None): """ Class constructor """ super(MultiNewDsSelector, self).__init__(parent) self.setupUi(self) - self.edgv = '' + self.edgv = "" self.crs = None self.numberOfDs = 0 self.fillEdgvVersions() @@ -50,15 +54,14 @@ def __init__(self, parent=None): def fillEdgvVersions(self): """ - Populates EDGV combo box with available versions. + Populates EDGV combo box with available versions. """ versions = [ self.tr("EDGV Version..."), "EDGV 2.1.3", - "EDGV 2.1.3 F Ter" - "EDGV 2.1.3 Pro", + "EDGV 2.1.3 F Ter" "EDGV 2.1.3 Pro", "EDGV 3.0", - "EDGV 3.0 Pro" + "EDGV 3.0 Pro", ] self.edgvComboBox.addItems(versions) @@ -75,7 +78,7 @@ def edgvVersion(self): :return: (str) EDGV version. """ edgv = self.edgvComboBox.currentText() - return edgv if not edgv is None and edgv != self.tr("EDGV Version...") else '' + return edgv if not edgv is None and edgv != self.tr("EDGV Version...") else "" def authId(self): """ @@ -83,7 +86,7 @@ def authId(self): :return: (str) EDGV version. """ crs = self.getCrs() - return crs.authid() if not crs is None and crs.isValid() else '' + return crs.authid() if not crs is None and crs.isValid() else "" def getCrs(self): """ @@ -105,10 +108,10 @@ def on_okPushButton_clicked(self): for i in range(self.amount()): # add an entry for each desired datasource # in here, we may change for an automatic datasource name to be passed on as dict key - self.datasources[i] = { 'edgv' : self.edgvVersion(), 'crs' : self.getCrs() } + self.datasources[i] = {"edgv": self.edgvVersion(), "crs": self.getCrs()} self.close() return 0 - QMessageBox.warning(self, self.tr('Warning!'), self.validate()) + QMessageBox.warning(self, self.tr("Warning!"), self.validate()) return 1 @pyqtSlot(bool) @@ -130,15 +133,15 @@ def validate(self): """ # check amount of servers selection if self.amount() == 0: - return self.tr('Select the amount of datasources to be created.') + return self.tr("Select the amount of datasources to be created.") # check if a valid EDGV version was selected if not self.edgvVersion(): - return self.tr('Invalid EDGV version.') + return self.tr("Invalid EDGV version.") # check if a valid projection was selected - if not self.getCrs() or 'EPSG' not in self.authId(): - return self.tr('Invalid CRS.') + if not self.getCrs() or "EPSG" not in self.authId(): + return self.tr("Invalid CRS.") # if all tests were positive, widget has a valid selection - return '' + return "" def isValid(self): """ @@ -146,4 +149,4 @@ def isValid(self): :return: (bool) invalidation status. """ msg = self.validate() - return msg == '' + return msg == "" diff --git a/DsgTools/gui/CustomWidgets/DatabaseConversionWidgets/MultiDsSelectorWidgets/SupportedDrivers/multiPostgisSelectorWidget.py b/DsgTools/gui/CustomWidgets/DatabaseConversionWidgets/MultiDsSelectorWidgets/SupportedDrivers/multiPostgisSelectorWidget.py index 43c0cb272..f6e692516 100644 --- a/DsgTools/gui/CustomWidgets/DatabaseConversionWidgets/MultiDsSelectorWidgets/SupportedDrivers/multiPostgisSelectorWidget.py +++ b/DsgTools/gui/CustomWidgets/DatabaseConversionWidgets/MultiDsSelectorWidgets/SupportedDrivers/multiPostgisSelectorWidget.py @@ -1,4 +1,3 @@ - # -*- coding: utf-8 -*- """ /*************************************************************************** @@ -27,29 +26,37 @@ from qgis.PyQt.QtWidgets import QWidget, QCheckBox, QDialog from .abstractMultiDsSelectorWidget import AbstractMultiDsSelectorWidget -from DsgTools.gui.CustomWidgets.ConnectionWidgets.ServerConnectionWidgets.exploreServerWidget import ExploreServerWidget +from DsgTools.gui.CustomWidgets.ConnectionWidgets.ServerConnectionWidgets.exploreServerWidget import ( + ExploreServerWidget, +) from DsgTools.core.dsgEnums import DsgEnums import os from operator import itemgetter -FORM_CLASS, _ = uic.loadUiType(os.path.join(os.path.dirname(__file__), 'multiPostgisSelectorWidget.ui')) +FORM_CLASS, _ = uic.loadUiType( + os.path.join(os.path.dirname(__file__), "multiPostgisSelectorWidget.ui") +) + class MultiPostgisSelector(QDialog, FORM_CLASS): """ Class designed to manipulate just the driver selection behavior. Handles reading and inserting data into GUI. """ + def __init__(self, parent=None): """ Class constructor. """ super(MultiPostgisSelector, self).__init__(parent) self.setupUi(self) - self.serverName = '' + self.serverName = "" self.dbList = [] - self.exploreServerWidget.serversCombo.currentIndexChanged.connect(self.serverUpdated) + self.exploreServerWidget.serversCombo.currentIndexChanged.connect( + self.serverUpdated + ) self.updateDbList() - self.groupBox.setTitle(self.tr('Available Databases')) + self.groupBox.setTitle(self.tr("Available Databases")) def clearGridLayout(self): """ @@ -73,13 +80,17 @@ def getDbsFromServer(self, name): def updateDbList(self): """ - Fills + Fills """ # remove all present widgets self.clearGridLayout() # get selected server serverName = self.exploreServerWidget.serversCombo.currentText() - serverName = serverName.split(' ')[0] if self.exploreServerWidget.serversCombo.currentIndex() != 0 else '' + serverName = ( + serverName.split(" ")[0] + if self.exploreServerWidget.serversCombo.currentIndex() != 0 + else "" + ) # get available databases if serverName: dbList = self.getDbsFromServer(name=serverName) @@ -147,7 +158,11 @@ def on_okPushButton_clicked(self): """ # update server name attribute self.serverName = self.exploreServerWidget.serversCombo.currentText() - self.serverName = self.serverName.split(' ')[0] if self.serverName != self.tr('Select Server') else '' + self.serverName = ( + self.serverName.split(" ")[0] + if self.serverName != self.tr("Select Server") + else "" + ) for row in range(self.gridLayout.rowCount()): # get checkbox item = self.gridLayout.itemAtPosition(row, 0) @@ -155,14 +170,18 @@ def on_okPushButton_clicked(self): checkbox = self.gridLayout.itemAtPosition(row, 0).widget() # update dbList if checkbox.isChecked(): - self.dbList.append(checkbox.text().split(' ')[0].replace('&', '')) # again, no idea why an '&' got in there... + self.dbList.append( + checkbox.text().split(" ")[0].replace("&", "") + ) # again, no idea why an '&' got in there... self.close() + class MultiPostgisSelectorWidget(AbstractMultiDsSelectorWidget): """ Class designed to integrate the datasource selector widget to the abstract multi datasource selector widget. Handles data manipulation to be delivered to the next conversion step. """ + def __init__(self, parent=None): """ Class constructor. @@ -205,7 +224,7 @@ def getDbListServerInfo(self, dbList): dbList = self.getAvailableDb(serverName=self.selector.serverName) serverInfo = list(self.getDbServerInfo(serverName=self.selector.serverName)) serverInfo.insert(0, self.selector.serverName) - return { dbname : serverInfo for dbname in dbList } + return {dbname: serverInfo for dbname in dbList} def exec_(self): """ diff --git a/DsgTools/gui/CustomWidgets/DatabaseConversionWidgets/MultiDsSelectorWidgets/SupportedDrivers/multiShapefileSelectorWidget.py b/DsgTools/gui/CustomWidgets/DatabaseConversionWidgets/MultiDsSelectorWidgets/SupportedDrivers/multiShapefileSelectorWidget.py index 3ddcc42f3..3dbda5a36 100644 --- a/DsgTools/gui/CustomWidgets/DatabaseConversionWidgets/MultiDsSelectorWidgets/SupportedDrivers/multiShapefileSelectorWidget.py +++ b/DsgTools/gui/CustomWidgets/DatabaseConversionWidgets/MultiDsSelectorWidgets/SupportedDrivers/multiShapefileSelectorWidget.py @@ -29,10 +29,12 @@ import os + class MultiShapefileSelectorWidget(AbstractMultiDsSelectorWidget): """ Class designed to retrieve a Shapefile database list (list of folders containing shapefiles). """ + def __init__(self, parent=None): """ Class constructor. @@ -60,8 +62,10 @@ def exec_(self): """ # clear datasources self.datasources = {} - dbList = self.selector.getOpenFileNames(caption=self.tr("Select Folders with Shapefiles"), \ - filter=self.tr('Shapefiles (*.shp)'))[0] + dbList = self.selector.getOpenFileNames( + caption=self.tr("Select Folders with Shapefiles"), + filter=self.tr("Shapefiles (*.shp)"), + )[0] for db in dbList: self.datasources[db] = os.path.dirname(db) - return int(not self.datasources) # execution code + return int(not self.datasources) # execution code diff --git a/DsgTools/gui/CustomWidgets/DatabaseConversionWidgets/MultiDsSelectorWidgets/SupportedDrivers/multiSpatialiteSelectorWidget.py b/DsgTools/gui/CustomWidgets/DatabaseConversionWidgets/MultiDsSelectorWidgets/SupportedDrivers/multiSpatialiteSelectorWidget.py index 79909ed81..26c62ab47 100644 --- a/DsgTools/gui/CustomWidgets/DatabaseConversionWidgets/MultiDsSelectorWidgets/SupportedDrivers/multiSpatialiteSelectorWidget.py +++ b/DsgTools/gui/CustomWidgets/DatabaseConversionWidgets/MultiDsSelectorWidgets/SupportedDrivers/multiSpatialiteSelectorWidget.py @@ -29,10 +29,12 @@ import os + class MultiSpatialiteSelectorWidget(AbstractMultiDsSelectorWidget): """ Class designed to retrieve a SpatiaLite database list. """ + def __init__(self, parent=None): """ Class constructor. @@ -60,8 +62,10 @@ def exec_(self): """ # clear datasources self.datasources = {} - dbList = self.selector.getOpenFileNames(caption=self.tr("Select SpatiaLite Datasources"), \ - filter=self.tr('SpatiaLite Databases (*.sqlite)'))[0] + dbList = self.selector.getOpenFileNames( + caption=self.tr("Select SpatiaLite Datasources"), + filter=self.tr("SpatiaLite Databases (*.sqlite)"), + )[0] for db in dbList: self.datasources[self.getDatabaseName(datasourcePath=db)] = db - return int(not self.datasources) # execution code + return int(not self.datasources) # execution code diff --git a/DsgTools/gui/CustomWidgets/DatabaseConversionWidgets/MultiDsSelectorWidgets/__init__.py b/DsgTools/gui/CustomWidgets/DatabaseConversionWidgets/MultiDsSelectorWidgets/__init__.py index 8d1c8b69c..e69de29bb 100644 --- a/DsgTools/gui/CustomWidgets/DatabaseConversionWidgets/MultiDsSelectorWidgets/__init__.py +++ b/DsgTools/gui/CustomWidgets/DatabaseConversionWidgets/MultiDsSelectorWidgets/__init__.py @@ -1 +0,0 @@ - diff --git a/DsgTools/gui/CustomWidgets/DatabaseConversionWidgets/MultiDsSelectorWidgets/multiDsWidgetFactory.py b/DsgTools/gui/CustomWidgets/DatabaseConversionWidgets/MultiDsSelectorWidgets/multiDsWidgetFactory.py index b7fecbe92..9e17ed290 100644 --- a/DsgTools/gui/CustomWidgets/DatabaseConversionWidgets/MultiDsSelectorWidgets/multiDsWidgetFactory.py +++ b/DsgTools/gui/CustomWidgets/DatabaseConversionWidgets/MultiDsSelectorWidgets/multiDsWidgetFactory.py @@ -1,4 +1,3 @@ - # -*- coding: utf-8 -*- """ /*************************************************************************** @@ -23,30 +22,36 @@ """ from .SupportedDrivers.multiPostgisSelectorWidget import MultiPostgisSelectorWidget -from .SupportedDrivers.multiSpatialiteSelectorWidget import MultiSpatialiteSelectorWidget +from .SupportedDrivers.multiSpatialiteSelectorWidget import ( + MultiSpatialiteSelectorWidget, +) from .SupportedDrivers.multiShapefileSelectorWidget import MultiShapefileSelectorWidget -from .SupportedDrivers.multiGeopackageSelectorWidget import MultiGeopackageSelectorWidget +from .SupportedDrivers.multiGeopackageSelectorWidget import ( + MultiGeopackageSelectorWidget, +) from .SupportedDrivers.multiNewDsSelector import MultiNewDsSelector from DsgTools.core.dsgEnums import DsgEnums + class MultiDsWidgetFactory: """ Class to produce multiple datasource dialalogs. """ + def getMultiDsSelector(driver): """ Gets the dialog to be used for selecting multiple datasources of a given driver. - :param driver: (int) driver enum. + :param driver: (int) driver enum. """ dialogDict = { - DsgEnums.NoDriver : lambda : None, - DsgEnums.PostGIS : lambda : MultiPostgisSelectorWidget(), - DsgEnums.NewPostGIS : lambda : MultiNewDsSelector(), - DsgEnums.SpatiaLite : lambda : MultiSpatialiteSelectorWidget(), - DsgEnums.NewSpatiaLite : lambda : MultiNewDsSelector(), - DsgEnums.Shapefile : lambda : MultiShapefileSelectorWidget(), - DsgEnums.NewShapefile : lambda : MultiNewDsSelector(), - DsgEnums.Geopackage : lambda : MultiGeopackageSelectorWidget(), - DsgEnums.NewGeopackage : lambda : MultiNewDsSelector() + DsgEnums.NoDriver: lambda: None, + DsgEnums.PostGIS: lambda: MultiPostgisSelectorWidget(), + DsgEnums.NewPostGIS: lambda: MultiNewDsSelector(), + DsgEnums.SpatiaLite: lambda: MultiSpatialiteSelectorWidget(), + DsgEnums.NewSpatiaLite: lambda: MultiNewDsSelector(), + DsgEnums.Shapefile: lambda: MultiShapefileSelectorWidget(), + DsgEnums.NewShapefile: lambda: MultiNewDsSelector(), + DsgEnums.Geopackage: lambda: MultiGeopackageSelectorWidget(), + DsgEnums.NewGeopackage: lambda: MultiNewDsSelector(), } return dialogDict[driver]() diff --git a/DsgTools/gui/CustomWidgets/DatabaseConversionWidgets/SupportedDrivers/abstractSelectionWidget.py b/DsgTools/gui/CustomWidgets/DatabaseConversionWidgets/SupportedDrivers/abstractSelectionWidget.py index be827ac74..1c706a2cd 100644 --- a/DsgTools/gui/CustomWidgets/DatabaseConversionWidgets/SupportedDrivers/abstractSelectionWidget.py +++ b/DsgTools/gui/CustomWidgets/DatabaseConversionWidgets/SupportedDrivers/abstractSelectionWidget.py @@ -25,7 +25,10 @@ from qgis.utils import iface from DsgTools.core.dsgEnums import DsgEnums -from DsgTools.core.Factories.LayerLoaderFactory.layerLoaderFactory import LayerLoaderFactory +from DsgTools.core.Factories.LayerLoaderFactory.layerLoaderFactory import ( + LayerLoaderFactory, +) + class AbstractSelectionWidget(QObject): """ @@ -34,6 +37,7 @@ class AbstractSelectionWidget(QObject): 1- Define common methods to all manageable drivers 2- Set and define generic behavior method for reimplementation in all children. """ + def __init__(self, parent=None): """ Class constructor. @@ -41,13 +45,11 @@ def __init__(self, parent=None): :param source: (str) driver codename to have its widget produced. """ super(AbstractSelectionWidget, self).__init__() - self.source = '' + self.source = "" self.selectionWidget = None def __del__(self): - """ - - """ + """ """ abstractDb = self.getDatasource() if abstractDb is not None: abstractDb.closeDatabase() @@ -61,17 +63,17 @@ def getSelectionWidgetName(self, source=None): :return: (str) selection widget user-friendly name for selected driver. """ if not source: - return self.tr('No database selected.') + return self.tr("No database selected.") sourceNameDict = { - DsgEnums.NoDriver : self.tr('Select a datasource driver'), - DsgEnums.PostGIS : 'PostGIS', - DsgEnums.NewPostGIS : self.tr('PostGIS (create new database)'), - DsgEnums.SpatiaLite : 'SpatiaLite', - DsgEnums.NewSpatiaLite : self.tr('SpatiaLite (create new database)'), - DsgEnums.Shapefile : 'Shapefile', - DsgEnums.NewShapefile : self.tr('Shapefile (create new database)'), - #DsgEnums.Geopackage : 'Geopackage', - #DsgEnums.NewGeopackage : self.tr('Geopackage (create new database)') + DsgEnums.NoDriver: self.tr("Select a datasource driver"), + DsgEnums.PostGIS: "PostGIS", + DsgEnums.NewPostGIS: self.tr("PostGIS (create new database)"), + DsgEnums.SpatiaLite: "SpatiaLite", + DsgEnums.NewSpatiaLite: self.tr("SpatiaLite (create new database)"), + DsgEnums.Shapefile: "Shapefile", + DsgEnums.NewShapefile: self.tr("Shapefile (create new database)"), + # DsgEnums.Geopackage : 'Geopackage', + # DsgEnums.NewGeopackage : self.tr('Geopackage (create new database)') } return sourceNameDict[source] @@ -81,7 +83,7 @@ def getDatasourceConnectionName(self): :return: (str) datasource connection name. """ # to be reimplemented - return '' + return "" def getDatasourcePath(self): """ @@ -89,7 +91,7 @@ def getDatasourcePath(self): :return: (str) datasource path. """ # to be reimplemented - return '' + return "" def getNewSelectionWidget(self): """ @@ -106,15 +108,15 @@ def setDatasource(self, newDatasource): """ # implementation for new datasources, but may be reimplemented into ALL children classes # for new datasources, entry is always { int : { 'edgv' : (str)edgv, 'crs' : (QgsCoordinateReferenceSystem)crs } } - edgv = list(newDatasource.values())[0]['edgv'] - crs = list(newDatasource.values())[0]['crs'] + edgv = list(newDatasource.values())[0]["edgv"] + crs = list(newDatasource.values())[0]["crs"] self.selectionWidget.edgvComboBox.setCurrentText(edgv) self.selectionWidget.mQgsProjectionSelectionWidget.setCrs(crs) def getDatasource(self): """ Gets the datasource selected on current widget. - :return: (AbstractDb) the object representing the target datasource according. + :return: (AbstractDb) the object representing the target datasource according. """ # to be reimplemented pass @@ -125,7 +127,7 @@ def getDatasourceEdgvVersion(self): :return: (str) current EDGV version. """ abstracDb = self.getDatasource() - return abstracDb.getDatabaseVersion() if abstracDb else '' + return abstracDb.getDatabaseVersion() if abstracDb else "" def getLayerLoader(self): """ @@ -133,7 +135,11 @@ def getLayerLoader(self): :return: (EDGVLayerLoader) layer loader. """ abstracDb = self.getDatasource() - return LayerLoaderFactory().makeLoader(iface=iface, abstractDb=abstracDb) if abstracDb else None + return ( + LayerLoaderFactory().makeLoader(iface=iface, abstractDb=abstracDb) + if abstracDb + else None + ) def getLayerByName(self, layer): """ @@ -169,7 +175,9 @@ def getLayersCrs(self): if abstracDb: layerLoader = self.getLayerLoader() # alias for retrieving layer CRS and inserting it to out dict - getCrsAlias = lambda x : crs.update({ x : layerLoader.getLayerByName(layer=x).crs().description() }) + getCrsAlias = lambda x: crs.update( + {x: layerLoader.getLayerByName(layer=x).crs().description()} + ) # update crs dict list(map(getCrsAlias, self.getLayersDict())) return crs @@ -181,7 +189,9 @@ def getLayersDict(self): """ abstracDb = self.getDatasource() if abstracDb: - return abstracDb.listClassesWithElementsFromDatabase(useComplex=False, primitiveFilter=[]) + return abstracDb.listClassesWithElementsFromDatabase( + useComplex=False, primitiveFilter=[] + ) return {} def getComplexDict(self): @@ -200,7 +210,11 @@ def validate(self): Validates selection widgets contents. :return: (str) invalidation reason. """ - return self.selectionWidget.validate() if self.selectionWidget else self.tr('Selection widget not available.') + return ( + self.selectionWidget.validate() + if self.selectionWidget + else self.tr("Selection widget not available.") + ) def isValid(self): """ @@ -208,4 +222,4 @@ def isValid(self): :return: (bool) invalidation status. """ msg = self.validate() - return msg == '' \ No newline at end of file + return msg == "" diff --git a/DsgTools/gui/CustomWidgets/DatabaseConversionWidgets/SupportedDrivers/geopackageWidget.py b/DsgTools/gui/CustomWidgets/DatabaseConversionWidgets/SupportedDrivers/geopackageWidget.py index 0cf7e8c35..17a0452de 100644 --- a/DsgTools/gui/CustomWidgets/DatabaseConversionWidgets/SupportedDrivers/geopackageWidget.py +++ b/DsgTools/gui/CustomWidgets/DatabaseConversionWidgets/SupportedDrivers/geopackageWidget.py @@ -21,12 +21,17 @@ ***************************************************************************/ """ -from DsgTools.gui.CustomWidgets.DatabaseConversionWidgets.SupportedDrivers.abstractSelectionWidget import AbstractSelectionWidget -from DsgTools.gui.CustomWidgets.ConnectionWidgets.AdvancedConnectionWidgets.databaseFileLineEdit import DatabaseFileLineEdit +from DsgTools.gui.CustomWidgets.DatabaseConversionWidgets.SupportedDrivers.abstractSelectionWidget import ( + AbstractSelectionWidget, +) +from DsgTools.gui.CustomWidgets.ConnectionWidgets.AdvancedConnectionWidgets.databaseFileLineEdit import ( + DatabaseFileLineEdit, +) from DsgTools.core.dsgEnums import DsgEnums import os + class GeopackageWidget(AbstractSelectionWidget): """ Widget resposinble for adequating GUI to chosen data driver. @@ -43,8 +48,12 @@ def __init__(self, parent=None): # initiate new instance of actual class widget self.selectionWidget = self.getNewSelectionWidget(parent=parent) self.selectionWidget.driver = DsgEnums.DriverGeopackage - self.selectionWidget.connectionSelectorLineEdit.caption = self.tr('Select a Geopackage Database') - self.selectionWidget.connectionSelectorLineEdit.filter = self.tr('Geopackage Database (*.gpkg)') + self.selectionWidget.connectionSelectorLineEdit.caption = self.tr( + "Select a Geopackage Database" + ) + self.selectionWidget.connectionSelectorLineEdit.filter = self.tr( + "Geopackage Database (*.gpkg)" + ) def getNewSelectionWidget(self, parent=None): """ @@ -61,8 +70,8 @@ def getDatasourceConnectionName(self): """ n = self.selectionWidget.connectionSelectorLineEdit.lineEdit.text() # n is a path and so it'll be something like /PATH/TO/datasource.sqlite or C:\PATH\TO\datasource.sqlite - splitChar = '/' if '/' in n else '\\' - ret = n.split(splitChar)[-1].split('.')[0] if n else '' + splitChar = "/" if "/" in n else "\\" + ret = n.split(splitChar)[-1].split(".")[0] if n else "" return ret def getDatasourcePath(self): @@ -72,8 +81,10 @@ def getDatasourcePath(self): """ if self.getDatasource(): # just return a datasource path if a valid one was loaded - return "gpkg:{0}".format(self.selectionWidget.connectionSelectorLineEdit.lineEdit.text()) - return '' + return "gpkg:{0}".format( + self.selectionWidget.connectionSelectorLineEdit.lineEdit.text() + ) + return "" def setDatasource(self, newDatasource): """ @@ -81,11 +92,13 @@ def setDatasource(self, newDatasource): :param newDatasource: (dict) containing datasource name and its path. """ if newDatasource: - self.selectionWidget.connectionSelectorLineEdit.lineEdit.setText((list(newDatasource.values())[0])) + self.selectionWidget.connectionSelectorLineEdit.lineEdit.setText( + (list(newDatasource.values())[0]) + ) def getDatasource(self): """ Gets the datasource selected on current widget. - :return: (AbstractDb) the object representing the target datasource according to its driver. + :return: (AbstractDb) the object representing the target datasource according to its driver. """ return self.selectionWidget.abstractDb diff --git a/DsgTools/gui/CustomWidgets/DatabaseConversionWidgets/SupportedDrivers/newGeopackageWidget.py b/DsgTools/gui/CustomWidgets/DatabaseConversionWidgets/SupportedDrivers/newGeopackageWidget.py index 952e6628e..36e15f7c7 100644 --- a/DsgTools/gui/CustomWidgets/DatabaseConversionWidgets/SupportedDrivers/newGeopackageWidget.py +++ b/DsgTools/gui/CustomWidgets/DatabaseConversionWidgets/SupportedDrivers/newGeopackageWidget.py @@ -21,12 +21,17 @@ ***************************************************************************/ """ -from DsgTools.gui.CustomWidgets.DatabaseConversionWidgets.SupportedDrivers.abstractSelectionWidget import AbstractSelectionWidget -from DsgTools.gui.CustomWidgets.ConnectionWidgets.AdvancedConnectionWidgets.newDatabaseLineEdit import NewDatabaseLineEdit +from DsgTools.gui.CustomWidgets.DatabaseConversionWidgets.SupportedDrivers.abstractSelectionWidget import ( + AbstractSelectionWidget, +) +from DsgTools.gui.CustomWidgets.ConnectionWidgets.AdvancedConnectionWidgets.newDatabaseLineEdit import ( + NewDatabaseLineEdit, +) from DsgTools.core.dsgEnums import DsgEnums import os + class NewGeopackageWidget(AbstractSelectionWidget): """ Widget resposinble for adequating GUI to chosen data driver. @@ -42,8 +47,8 @@ def __init__(self, parent=None): self.source = DsgEnums.NewGeopackage # initiate new instance of actual class widget self.selectionWidget = self.getNewSelectionWidget(parent=parent) - self.selectionWidget.caption = self.tr('Create a Geopackage Database') - self.selectionWidget.filter = self.tr('Geopackage Database (*.gpkg)') + self.selectionWidget.caption = self.tr("Create a Geopackage Database") + self.selectionWidget.filter = self.tr("Geopackage Database (*.gpkg)") def getNewSelectionWidget(self, parent=None): """ @@ -60,8 +65,8 @@ def getDatasourceConnectionName(self): """ n = self.selectionWidget.dsLineEdit.text() # n is a path and so it'll be something like /PATH/TO/datasource.sqlite or C:\PATH\TO\datasource.sqlite - splitChar = '/' if '/' in n else '\\' - ret = n.split(splitChar)[-1].split('.')[0] if n else '' + splitChar = "/" if "/" in n else "\\" + ret = n.split(splitChar)[-1].split(".")[0] if n else "" return ret def getDatasourcePath(self): @@ -80,6 +85,6 @@ def getDatasourceEdgvVersion(self): def getDatasource(self): """ Gets the datasource selected on current widget. - :return: (AbstractDb) the object representing the target datasource according to its driver. + :return: (AbstractDb) the object representing the target datasource according to its driver. """ return None diff --git a/DsgTools/gui/CustomWidgets/DatabaseConversionWidgets/SupportedDrivers/newPostgisWidget.py b/DsgTools/gui/CustomWidgets/DatabaseConversionWidgets/SupportedDrivers/newPostgisWidget.py index b924c6e3d..734d72976 100644 --- a/DsgTools/gui/CustomWidgets/DatabaseConversionWidgets/SupportedDrivers/newPostgisWidget.py +++ b/DsgTools/gui/CustomWidgets/DatabaseConversionWidgets/SupportedDrivers/newPostgisWidget.py @@ -21,12 +21,17 @@ ***************************************************************************/ """ -from DsgTools.gui.CustomWidgets.DatabaseConversionWidgets.SupportedDrivers.abstractSelectionWidget import AbstractSelectionWidget -from DsgTools.gui.CustomWidgets.ConnectionWidgets.AdvancedConnectionWidgets.newConnectionLineEdit import NewConnectionLineEdit +from DsgTools.gui.CustomWidgets.DatabaseConversionWidgets.SupportedDrivers.abstractSelectionWidget import ( + AbstractSelectionWidget, +) +from DsgTools.gui.CustomWidgets.ConnectionWidgets.AdvancedConnectionWidgets.newConnectionLineEdit import ( + NewConnectionLineEdit, +) from DsgTools.core.dsgEnums import DsgEnums import os + class NewPostgisWidget(AbstractSelectionWidget): """ Widget resposinble for adequating GUI to chosen data driver. @@ -57,7 +62,7 @@ def getDatasourceConnectionName(self): Gets the datasource connection name. :return: (str) datasource connection name. """ - return self.selectionWidget.currentDb() if self.selectionWidget else '' + return self.selectionWidget.currentDb() if self.selectionWidget else "" def getDatasourcePath(self): """ @@ -65,9 +70,17 @@ def getDatasourcePath(self): :return: (str) datasource connection name. """ if self.selectionWidget: - _, host, port, user, _ = self.selectionWidget.viewServers.getDefaultConnectionParameters() - return 'pg:{2}@{0}:{1}.{3}'.format(host, port, user, self.getDatasourceConnectionName()) - return '' + ( + _, + host, + port, + user, + _, + ) = self.selectionWidget.viewServers.getDefaultConnectionParameters() + return "pg:{2}@{0}:{1}.{3}".format( + host, port, user, self.getDatasourceConnectionName() + ) + return "" def getDatasourceEdgvVersion(self): """ @@ -78,6 +91,6 @@ def getDatasourceEdgvVersion(self): def getDatasource(self): """ Gets the datasource selected on current widget. - :return: (AbstractDb) the object representing the target datasource according to its driver. + :return: (AbstractDb) the object representing the target datasource according to its driver. """ return None diff --git a/DsgTools/gui/CustomWidgets/DatabaseConversionWidgets/SupportedDrivers/newShapefileWidget.py b/DsgTools/gui/CustomWidgets/DatabaseConversionWidgets/SupportedDrivers/newShapefileWidget.py index b55ce298b..fa4ecff46 100644 --- a/DsgTools/gui/CustomWidgets/DatabaseConversionWidgets/SupportedDrivers/newShapefileWidget.py +++ b/DsgTools/gui/CustomWidgets/DatabaseConversionWidgets/SupportedDrivers/newShapefileWidget.py @@ -25,12 +25,17 @@ from qgis.PyQt.QtWidgets import QFileDialog from qgis.PyQt.QtCore import pyqtSlot -from DsgTools.gui.CustomWidgets.DatabaseConversionWidgets.SupportedDrivers.abstractSelectionWidget import AbstractSelectionWidget -from DsgTools.gui.CustomWidgets.ConnectionWidgets.AdvancedConnectionWidgets.newDatabaseLineEdit import NewDatabaseLineEdit +from DsgTools.gui.CustomWidgets.DatabaseConversionWidgets.SupportedDrivers.abstractSelectionWidget import ( + AbstractSelectionWidget, +) +from DsgTools.gui.CustomWidgets.ConnectionWidgets.AdvancedConnectionWidgets.newDatabaseLineEdit import ( + NewDatabaseLineEdit, +) from DsgTools.core.dsgEnums import DsgEnums import os + class NewShapefileWidget(AbstractSelectionWidget): """ Widget resposinble for adequating GUI to chosen data driver. @@ -46,10 +51,14 @@ def __init__(self, parent=None): self.source = DsgEnums.NewShapefile # initiate new instance of actual class widget self.selectionWidget = self.getNewSelectionWidget(parent=parent) - self.selectionWidget.caption = self.tr('Select a Directory for Shapes to be Saved At') - self.selectionWidget.filter = self.tr('Shapefile Database') + self.selectionWidget.caption = self.tr( + "Select a Directory for Shapes to be Saved At" + ) + self.selectionWidget.filter = self.tr("Shapefile Database") # connect datasource selection to this ones - self.selectionWidget.selectFilePushButton.clicked.disconnect(self.selectionWidget.selectDatasource) + self.selectionWidget.selectFilePushButton.clicked.disconnect( + self.selectionWidget.selectDatasource + ) self.selectionWidget.selectFilePushButton.clicked.connect(self.selectDatasource) def getNewSelectionWidget(self, parent=None): @@ -68,11 +77,15 @@ def getDatasourceConnectionName(self): ret = self.selectionWidget.dsLineEdit.text() if ret: # path is something like /PATH/TO/datasource/***.shp or C:\PATH\TO\datasource\***.shp - splitChar = '/' if '/' in ret else '\\' + splitChar = "/" if "/" in ret else "\\" if len(ret) > 4: # datasource connection name for a shape 'database' is its parent folder - ret = ret.split(splitChar)[-1] if ret[-4:].lower() != '.shp' else ret.split(splitChar)[:-4] - ret = ret if ret != self.tr("New Database") else '' + ret = ( + ret.split(splitChar)[-1] + if ret[-4:].lower() != ".shp" + else ret.split(splitChar)[:-4] + ) + ret = ret if ret != self.tr("New Database") else "" return ret def getDatasourcePath(self): @@ -85,7 +98,7 @@ def getDatasourcePath(self): def getDatasource(self): """ Gets the datasource selected on current widget. - :return: (AbstractDb) the object representing the target datasource according to its driver. + :return: (AbstractDb) the object representing the target datasource according to its driver. """ return None @@ -107,7 +120,9 @@ def selectDatasource(self): if directory: if len(directory) > 4: # datasource connection name for a shape 'database' is its parent folder - directory = directory if directory[-4:].lower() != '.shp' else directory[:-4] + directory = ( + directory if directory[-4:].lower() != ".shp" else directory[:-4] + ) # set only directories as line text self.selectionWidget.dsLineEdit.setText(directory) self.selectionWidget.loadDatabase(currentText=directory) diff --git a/DsgTools/gui/CustomWidgets/DatabaseConversionWidgets/SupportedDrivers/newSpatialiteWidget.py b/DsgTools/gui/CustomWidgets/DatabaseConversionWidgets/SupportedDrivers/newSpatialiteWidget.py index 40b6cab0b..92b2fb142 100644 --- a/DsgTools/gui/CustomWidgets/DatabaseConversionWidgets/SupportedDrivers/newSpatialiteWidget.py +++ b/DsgTools/gui/CustomWidgets/DatabaseConversionWidgets/SupportedDrivers/newSpatialiteWidget.py @@ -24,12 +24,17 @@ from qgis.PyQt import QtWidgets, uic from qgis.PyQt.QtCore import pyqtSignal, pyqtSlot -from DsgTools.gui.CustomWidgets.DatabaseConversionWidgets.SupportedDrivers.abstractSelectionWidget import AbstractSelectionWidget -from DsgTools.gui.CustomWidgets.ConnectionWidgets.AdvancedConnectionWidgets.newDatabaseLineEdit import NewDatabaseLineEdit +from DsgTools.gui.CustomWidgets.DatabaseConversionWidgets.SupportedDrivers.abstractSelectionWidget import ( + AbstractSelectionWidget, +) +from DsgTools.gui.CustomWidgets.ConnectionWidgets.AdvancedConnectionWidgets.newDatabaseLineEdit import ( + NewDatabaseLineEdit, +) from DsgTools.core.dsgEnums import DsgEnums import os + class NewSpatialiteWidget(AbstractSelectionWidget): """ Widget resposinble for adequating GUI to chosen data driver. @@ -45,8 +50,8 @@ def __init__(self, parent=None): self.source = DsgEnums.NewSpatiaLite # initiate new instance of actual class widget self.selectionWidget = self.getNewSelectionWidget(parent=parent) - self.selectionWidget.caption = self.tr('Create a SpatiaLite Database') - self.selectionWidget.filter = self.tr('SpatiaLite Database (*.sqlite)') + self.selectionWidget.caption = self.tr("Create a SpatiaLite Database") + self.selectionWidget.filter = self.tr("SpatiaLite Database (*.sqlite)") def getNewSelectionWidget(self, parent=None): """ @@ -63,8 +68,8 @@ def getDatasourceConnectionName(self): """ n = self.selectionWidget.dsLineEdit.text() # n is a path and so it'll be something like /PATH/TO/datasource.sqlite or C:\PATH\TO\datasource.sqlite - splitChar = '/' if '/' in n else '\\' - ret = n.split(splitChar)[-1].split('.')[0] if n else '' + splitChar = "/" if "/" in n else "\\" + ret = n.split(splitChar)[-1].split(".")[0] if n else "" return ret def getDatasourcePath(self): @@ -83,6 +88,6 @@ def getDatasourceEdgvVersion(self): def getDatasource(self): """ Gets the datasource selected on current widget. - :return: (AbstractDb) the object representing the target datasource according to its driver. + :return: (AbstractDb) the object representing the target datasource according to its driver. """ return None diff --git a/DsgTools/gui/CustomWidgets/DatabaseConversionWidgets/SupportedDrivers/postgisWidget.py b/DsgTools/gui/CustomWidgets/DatabaseConversionWidgets/SupportedDrivers/postgisWidget.py index 448034c34..fa0a207b8 100644 --- a/DsgTools/gui/CustomWidgets/DatabaseConversionWidgets/SupportedDrivers/postgisWidget.py +++ b/DsgTools/gui/CustomWidgets/DatabaseConversionWidgets/SupportedDrivers/postgisWidget.py @@ -21,12 +21,17 @@ ***************************************************************************/ """ -from DsgTools.gui.CustomWidgets.DatabaseConversionWidgets.SupportedDrivers.abstractSelectionWidget import AbstractSelectionWidget -from DsgTools.gui.CustomWidgets.ConnectionWidgets.AdvancedConnectionWidgets.connectionComboBox import ConnectionComboBox +from DsgTools.gui.CustomWidgets.DatabaseConversionWidgets.SupportedDrivers.abstractSelectionWidget import ( + AbstractSelectionWidget, +) +from DsgTools.gui.CustomWidgets.ConnectionWidgets.AdvancedConnectionWidgets.connectionComboBox import ( + ConnectionComboBox, +) from DsgTools.core.dsgEnums import DsgEnums import os + class PostgisWidget(AbstractSelectionWidget): """ Widget resposinble for adequating GUI to chosen data driver. @@ -57,7 +62,11 @@ def getDatasourceConnectionName(self): Gets the datasource connection name. :return: (str) datasource connection name. """ - return self.selectionWidget.connectionSelectorComboBox.currentText() if self.selectionWidget else '' + return ( + self.selectionWidget.connectionSelectorComboBox.currentText() + if self.selectionWidget + else "" + ) def getDatasourcePath(self): """ @@ -67,8 +76,10 @@ def getDatasourcePath(self): abstractDb = self.getDatasource() if abstractDb: host, port, username, _ = abstractDb.getDatabaseParameters() - return 'pg:{2}@{0}:{1}.{3}'.format(host, port, username, self.getDatasourceConnectionName()) - return '' + return "pg:{2}@{0}:{1}.{3}".format( + host, port, username, self.getDatasourceConnectionName() + ) + return "" def setDatasource(self, newDatasource): """ @@ -77,16 +88,22 @@ def setDatasource(self, newDatasource): """ # the input parameter is a dict due to a standard behavior on the other widgets (keep parallel) if self.selectionWidget: - for db, (serverName, host, port, username, password) in newDatasource.items(): + for db, ( + serverName, + host, + port, + username, + password, + ) in newDatasource.items(): self.selectionWidget.setHost(serverName) self.selectionWidget.connectionSelectorComboBox.setCurrentIndex( self.selectionWidget.connectionSelectorComboBox.findText(db) ) - return # first item will be set (if more than one is given) + return # first item will be set (if more than one is given) def getDatasource(self): """ Gets the datasource selected on current widget. - :return: (AbstractDb) the object representing the target datasource according to its driver. + :return: (AbstractDb) the object representing the target datasource according to its driver. """ return self.selectionWidget.abstractDb diff --git a/DsgTools/gui/CustomWidgets/DatabaseConversionWidgets/SupportedDrivers/shapefileWidget.py b/DsgTools/gui/CustomWidgets/DatabaseConversionWidgets/SupportedDrivers/shapefileWidget.py index 615448714..8b20ebe13 100644 --- a/DsgTools/gui/CustomWidgets/DatabaseConversionWidgets/SupportedDrivers/shapefileWidget.py +++ b/DsgTools/gui/CustomWidgets/DatabaseConversionWidgets/SupportedDrivers/shapefileWidget.py @@ -23,12 +23,17 @@ from qgis.PyQt.QtWidgets import QFileDialog -from DsgTools.gui.CustomWidgets.DatabaseConversionWidgets.SupportedDrivers.abstractSelectionWidget import AbstractSelectionWidget -from DsgTools.gui.CustomWidgets.ConnectionWidgets.AdvancedConnectionWidgets.databaseFileLineEdit import DatabaseFileLineEdit +from DsgTools.gui.CustomWidgets.DatabaseConversionWidgets.SupportedDrivers.abstractSelectionWidget import ( + AbstractSelectionWidget, +) +from DsgTools.gui.CustomWidgets.ConnectionWidgets.AdvancedConnectionWidgets.databaseFileLineEdit import ( + DatabaseFileLineEdit, +) from DsgTools.core.dsgEnums import DsgEnums import os + class ShapefileWidget(AbstractSelectionWidget): """ Widget resposinble for adequating GUI to chosen data driver. @@ -44,15 +49,22 @@ def __init__(self, parent=None): self.source = DsgEnums.Shapefile # initiate new instance of actual class widget self.selectionWidget = self.getNewSelectionWidget(parent=parent) - self.selectionWidget.connectionSelectorLineEdit.caption = self.tr('Select a Directory Containing Shapefiles') - self.selectionWidget.connectionSelectorLineEdit.filter = self.tr('Shapefile Database') + self.selectionWidget.connectionSelectorLineEdit.caption = self.tr( + "Select a Directory Containing Shapefiles" + ) + self.selectionWidget.connectionSelectorLineEdit.filter = self.tr( + "Shapefile Database" + ) # initiate driver for abstract db setting self.selectionWidget.driver = DsgEnums.DriverShapefile # connect datasource selection to this ones - this part is not great, sucks actually; # a refactory should be be executed in here... - self.selectionWidget.connectionSelectorLineEdit.selectFilePushButton.clicked.disconnect(\ - self.selectionWidget.connectionSelectorLineEdit.on_selectFilePushButton_clicked) - self.selectionWidget.connectionSelectorLineEdit.selectFilePushButton.clicked.connect(self.selectDatasource) + self.selectionWidget.connectionSelectorLineEdit.selectFilePushButton.clicked.disconnect( + self.selectionWidget.connectionSelectorLineEdit.on_selectFilePushButton_clicked + ) + self.selectionWidget.connectionSelectorLineEdit.selectFilePushButton.clicked.connect( + self.selectDatasource + ) def getNewSelectionWidget(self, parent=None): """ @@ -68,7 +80,7 @@ def getDatasourceConnectionName(self): :return: (str) datasource connection name. """ abstractDb = self.getDatasource() - return abstractDb.getDatabaseName() if abstractDb else '' + return abstractDb.getDatabaseName() if abstractDb else "" def setDatasource(self, newDatasource): """ @@ -81,7 +93,7 @@ def setDatasource(self, newDatasource): def getDatasource(self): """ Gets the datasource selected on current widget. - :return: (AbstractDb) the object representing the target datasource according to its driver. + :return: (AbstractDb) the object representing the target datasource according to its driver. """ return self.selectionWidget.abstractDb @@ -91,7 +103,7 @@ def getDatasourcePath(self): :return: (str) datasource connection name. """ abstractDb = self.getDatasource() - return "shp:{0}".format(abstractDb.databaseName()) if abstractDb else '' + return "shp:{0}".format(abstractDb.databaseName()) if abstractDb else "" def selectDatasource(self): """ @@ -101,11 +113,15 @@ def selectDatasource(self): fd = QFileDialog() fd.setFileMode(QFileDialog.Directory) fd.setOption(QFileDialog.ShowDirsOnly, True) - directory = fd.getExistingDirectory(caption=self.selectionWidget.connectionSelectorLineEdit.caption) + directory = fd.getExistingDirectory( + caption=self.selectionWidget.connectionSelectorLineEdit.caption + ) if directory: if len(directory) > 4: # datasource connection name for a shape 'database' is its parent folder - directory = directory if directory[-4:].lower() != '.shp' else directory[:-4] + directory = ( + directory if directory[-4:].lower() != ".shp" else directory[:-4] + ) # set only directories as line text self.selectionWidget.connectionSelectorLineEdit.lineEdit.setText(directory) self.selectionWidget.loadDatabase(currentText=directory) diff --git a/DsgTools/gui/CustomWidgets/DatabaseConversionWidgets/SupportedDrivers/spatialiteWidget.py b/DsgTools/gui/CustomWidgets/DatabaseConversionWidgets/SupportedDrivers/spatialiteWidget.py index 4e7b78042..eed685954 100644 --- a/DsgTools/gui/CustomWidgets/DatabaseConversionWidgets/SupportedDrivers/spatialiteWidget.py +++ b/DsgTools/gui/CustomWidgets/DatabaseConversionWidgets/SupportedDrivers/spatialiteWidget.py @@ -24,12 +24,17 @@ from qgis.PyQt import QtWidgets, uic from qgis.PyQt.QtCore import pyqtSignal, pyqtSlot -from DsgTools.gui.CustomWidgets.DatabaseConversionWidgets.SupportedDrivers.abstractSelectionWidget import AbstractSelectionWidget -from DsgTools.gui.CustomWidgets.ConnectionWidgets.AdvancedConnectionWidgets.databaseFileLineEdit import DatabaseFileLineEdit +from DsgTools.gui.CustomWidgets.DatabaseConversionWidgets.SupportedDrivers.abstractSelectionWidget import ( + AbstractSelectionWidget, +) +from DsgTools.gui.CustomWidgets.ConnectionWidgets.AdvancedConnectionWidgets.databaseFileLineEdit import ( + DatabaseFileLineEdit, +) from DsgTools.core.dsgEnums import DsgEnums import os + class SpatialiteWidget(AbstractSelectionWidget): """ Widget resposinble for adequating GUI to chosen data driver. @@ -46,8 +51,12 @@ def __init__(self, parent=None): # initiate new instance of actual class widget self.selectionWidget = self.getNewSelectionWidget(parent=parent) self.selectionWidget.driver = DsgEnums.DriverSpatiaLite - self.selectionWidget.connectionSelectorLineEdit.caption = self.tr('Select a SpatiaLite Database') - self.selectionWidget.connectionSelectorLineEdit.filter = self.tr('SpatiaLite Database (*.sqlite)') + self.selectionWidget.connectionSelectorLineEdit.caption = self.tr( + "Select a SpatiaLite Database" + ) + self.selectionWidget.connectionSelectorLineEdit.filter = self.tr( + "SpatiaLite Database (*.sqlite)" + ) def getNewSelectionWidget(self, parent=None): """ @@ -64,8 +73,8 @@ def getDatasourceConnectionName(self): """ n = self.selectionWidget.connectionSelectorLineEdit.lineEdit.text() # n is a path and so it'll be something like /PATH/TO/datasource.sqlite or C:\PATH\TO\datasource.sqlite - splitChar = '/' if '/' in n else '\\' - ret = n.split(splitChar)[-1].split('.')[0] if n else '' + splitChar = "/" if "/" in n else "\\" + ret = n.split(splitChar)[-1].split(".")[0] if n else "" return ret def getDatasourcePath(self): @@ -75,8 +84,10 @@ def getDatasourcePath(self): """ if self.getDatasource(): # just return a datasource path if a valid one was loaded - return "sqlite:{0}".format(self.selectionWidget.connectionSelectorLineEdit.lineEdit.text()) - return '' + return "sqlite:{0}".format( + self.selectionWidget.connectionSelectorLineEdit.lineEdit.text() + ) + return "" def setDatasource(self, newDatasource): """ @@ -84,11 +95,13 @@ def setDatasource(self, newDatasource): :param newDatasource: (dict) containing datasource name and its path. """ if newDatasource: - self.selectionWidget.connectionSelectorLineEdit.lineEdit.setText((list(newDatasource.values())[0])) + self.selectionWidget.connectionSelectorLineEdit.lineEdit.setText( + (list(newDatasource.values())[0]) + ) def getDatasource(self): """ Gets the datasource selected on current widget. - :return: (AbstractDb) the object representing the target datasource according to its driver. + :return: (AbstractDb) the object representing the target datasource according to its driver. """ return self.selectionWidget.abstractDb diff --git a/DsgTools/gui/CustomWidgets/DatabaseConversionWidgets/datasourceContainerWidget.py b/DsgTools/gui/CustomWidgets/DatabaseConversionWidgets/datasourceContainerWidget.py index d4863f285..2a5aea7f3 100755 --- a/DsgTools/gui/CustomWidgets/DatabaseConversionWidgets/datasourceContainerWidget.py +++ b/DsgTools/gui/CustomWidgets/DatabaseConversionWidgets/datasourceContainerWidget.py @@ -27,19 +27,28 @@ from qgis.utils import iface from qgis.core import QgsProject -from DsgTools.gui.CustomWidgets.BasicInterfaceWidgets.genericDialogLayout import GenericDialogLayout -from DsgTools.gui.CustomWidgets.DatabaseConversionWidgets.filterDialog import FilterDialog -from DsgTools.gui.CustomWidgets.DatabaseConversionWidgets.datasourceSelectionWidgetFactory import DatasourceSelectionWidgetFactory +from DsgTools.gui.CustomWidgets.BasicInterfaceWidgets.genericDialogLayout import ( + GenericDialogLayout, +) +from DsgTools.gui.CustomWidgets.DatabaseConversionWidgets.filterDialog import ( + FilterDialog, +) +from DsgTools.gui.CustomWidgets.DatabaseConversionWidgets.datasourceSelectionWidgetFactory import ( + DatasourceSelectionWidgetFactory, +) import os -FORM_CLASS, _ = uic.loadUiType(os.path.join( - os.path.dirname(__file__), 'datasourceContainerWidget.ui')) +FORM_CLASS, _ = uic.loadUiType( + os.path.join(os.path.dirname(__file__), "datasourceContainerWidget.ui") +) + class DatasourceContainerWidget(QtWidgets.QWidget, FORM_CLASS): """ Widget resposinble for adequating GUI to chosen data driver. """ + # signal to be emitted when deletion button is clicked - emits itself (QWidget) removeWidget = pyqtSignal(QtWidgets.QWidget) # signal emitted to advise about filtering options change @@ -61,24 +70,30 @@ def __init__(self, source, isInput, parent=None): self.filterPushButton.hide() # set filtering config self.filterDlg = None - self.filterPushButton.setToolTip(self.tr('Click to set datasource filter options')) - self.removePushButton.setToolTip(self.tr('Remove this datasource widget')) + self.filterPushButton.setToolTip( + self.tr("Click to set datasource filter options") + ) + self.removePushButton.setToolTip(self.tr("Remove this datasource widget")) def setGroupWidgetName(self, name=None): """ Sets the name to the group added. :param name: (str) name for the group. """ - self.groupBox.setTitle('{0}'.format(name)) + self.groupBox.setTitle("{0}".format(name)) def addDatasourceSelectionWidget(self): """ Adds the widget according to selected datasource on datasource combobox on first page. """ # in case a valid driver is selected, add its widget to the interface - self.connectionWidget = DatasourceSelectionWidgetFactory.getSelectionWidget(source=self.source) + self.connectionWidget = DatasourceSelectionWidgetFactory.getSelectionWidget( + source=self.source + ) self.driverLayout.addWidget(self.connectionWidget.selectionWidget) - self.connectionWidget.selectionWidget.dbChanged.connect(lambda : self.refreshFilterDialog) + self.connectionWidget.selectionWidget.dbChanged.connect( + lambda: self.refreshFilterDialog + ) def getDatasourceConnectionName(self): """ @@ -91,7 +106,7 @@ def getDatasourceConnectionName(self): def getDatasource(self): """ Gets the datasource selected on current widget. - :return: (object) the object representing the target datasource according to its driver. + :return: (object) the object representing the target datasource according to its driver. """ return self.connectionWidget.getDatasource() if self.connectionWidget else None @@ -122,16 +137,28 @@ def refreshFilterDialog(self): del self.filterDlg self.filterDlg = None self.filterDlg = FilterDialog( - {l : {'layer' : self.connectionWidget.getLayerByName(l), 'featureCount' : fc} for l, fc in self.connectionWidget.getLayersDict().items()}, - {l : {'layer' : self.connectionWidget.getComplexLayerByName(l), 'featureCount' : fc} for l, fc in self.connectionWidget.getComplexDict().items()}, - self.connectionWidget.getDatasource(), - ) + { + l: { + "layer": self.connectionWidget.getLayerByName(l), + "featureCount": fc, + } + for l, fc in self.connectionWidget.getLayersDict().items() + }, + { + l: { + "layer": self.connectionWidget.getComplexLayerByName(l), + "featureCount": fc, + } + for l, fc in self.connectionWidget.getComplexDict().items() + }, + self.connectionWidget.getDatasource(), + ) self.filterDlg.setWindowTitle( - '{0}: {2} ({1})'.format( - self.groupBox.title(), - self.connectionWidget.getDatasourcePath(), - self.connectionWidget.getDatasourceConnectionName() - ) + "{0}: {2} ({1})".format( + self.groupBox.title(), + self.connectionWidget.getDatasourcePath(), + self.connectionWidget.getDatasourceConnectionName(), + ) ) @pyqtSlot(bool) @@ -139,7 +166,7 @@ def on_filterPushButton_clicked(self): """ Opens filter dialog. Filters are updated as Ok push button on this dialog is clicked. If cancel is pressed, no update to filters contents will be made. This dialog is repopulated as filter push button from container - is pressed. + is pressed. """ # filter dialog is only built on the first execution if self.filterDlg is None: @@ -163,8 +190,11 @@ def filters(self): is returned. :return: (dict) a map to current filters applied. """ - return self.filterDlg.filters() if self.filterDlg is not None \ - else {'layer_filter' : dict(), 'spatial_filter' : dict()} + return ( + self.filterDlg.filters() + if self.filterDlg is not None + else {"layer_filter": dict(), "spatial_filter": dict()} + ) def driver(self): """ @@ -193,4 +223,4 @@ def isValid(self): Validates selection widgets contents. :return: (bool) invalidation status. """ - return self.validate() == '' + return self.validate() == "" diff --git a/DsgTools/gui/CustomWidgets/DatabaseConversionWidgets/datasourceInfoTable.py b/DsgTools/gui/CustomWidgets/DatabaseConversionWidgets/datasourceInfoTable.py index 10cdc5edf..22b4d99f0 100644 --- a/DsgTools/gui/CustomWidgets/DatabaseConversionWidgets/datasourceInfoTable.py +++ b/DsgTools/gui/CustomWidgets/DatabaseConversionWidgets/datasourceInfoTable.py @@ -26,8 +26,10 @@ import os -FORM_CLASS, _ = uic.loadUiType(os.path.join( - os.path.dirname(__file__), 'datasourceInfoTable.ui')) +FORM_CLASS, _ = uic.loadUiType( + os.path.join(os.path.dirname(__file__), "datasourceInfoTable.ui") +) + class DatasourceInfoTable(QtWidgets.QDialog, FORM_CLASS): # create enum to manipulate headers order @@ -54,14 +56,14 @@ def orderByColumn(self, col): """ # TO DO headers = { - self.Schema : self.tr("Schema"), - self.Layer : self.tr("Layer"), - self.GeomCol : self.tr("Geometry Column"), - self.GeomType : self.tr("Geometry Type"), - self.Srid : self.tr("SRID") + self.Schema: self.tr("Schema"), + self.Layer: self.tr("Layer"), + self.GeomCol: self.tr("Geometry Column"), + self.GeomType: self.tr("Geometry Type"), + self.Srid: self.tr("SRID"), } if col in headers: - print('Just consider it ordered by {0}, ok?'.format(headers[col])) + print("Just consider it ordered by {0}, ok?".format(headers[col])) @pyqtSlot(bool) def on_closePushButton_clicked(self): @@ -79,19 +81,24 @@ def createTable(self): self.tableWidget.removeRow(row) self.tableWidget.setRowCount(0) headers = { - self.Schema : self.tr("Schema"), - self.Layer : self.tr("Layer"), - self.GeomCol : self.tr("Geometry Column"), - self.GeomType : self.tr("Geometry Type"), - self.Srid : self.tr("SRID") + self.Schema: self.tr("Schema"), + self.Layer: self.tr("Layer"), + self.GeomCol: self.tr("Geometry Column"), + self.GeomType: self.tr("Geometry Type"), + self.Srid: self.tr("SRID"), } # set column count self.tableWidget.setColumnCount(self.COLUMN_COUNT) header = self.tableWidget.horizontalHeader() # set column names - makes sure the order is defined by enum's order - self.tableWidget.setHorizontalHeaderLabels([headers[i] for i in range(self.COLUMN_COUNT)]) + self.tableWidget.setHorizontalHeaderLabels( + [headers[i] for i in range(self.COLUMN_COUNT)] + ) # set resize policy for each column - [header.setSectionResizeMode(i, QtWidgets.QHeaderView.ResizeToContents) for i in range(self.COLUMN_COUNT)] + [ + header.setSectionResizeMode(i, QtWidgets.QHeaderView.ResizeToContents) + for i in range(self.COLUMN_COUNT) + ] # connect header double click signal to order by that column header.sectionDoubleClicked.connect(self.orderByColumn) @@ -105,7 +112,7 @@ def addItem(self, row, col, text): """ item = QtWidgets.QTableWidgetItem() item.setText(text) - item.setFlags(Qt.ItemIsEditable) # not editable + item.setFlags(Qt.ItemIsEditable) # not editable self.tableWidget.setItem(row, col, item) return item @@ -115,11 +122,11 @@ def addRow(self, row, content): :param row: (int) row index to be added. :param content: (dict) contents to be displayed in the selected row. """ - self.addItem(row=row, col=self.Schema, text=content['schema']) - self.addItem(row=row, col=self.Layer, text=content['layer']) - self.addItem(row=row, col=self.GeomCol, text=content['geomCol']) - self.addItem(row=row, col=self.GeomType, text=content['geomType']) - self.addItem(row=row, col=self.Srid, text=content['srid']) + self.addItem(row=row, col=self.Schema, text=content["schema"]) + self.addItem(row=row, col=self.Layer, text=content["layer"]) + self.addItem(row=row, col=self.GeomCol, text=content["geomCol"]) + self.addItem(row=row, col=self.GeomType, text=content["geomType"]) + self.addItem(row=row, col=self.Srid, text=content["srid"]) def setTable(self, contents): """ diff --git a/DsgTools/gui/CustomWidgets/DatabaseConversionWidgets/datasourceManagementWidget.py b/DsgTools/gui/CustomWidgets/DatabaseConversionWidgets/datasourceManagementWidget.py index 71285d292..833d16e48 100644 --- a/DsgTools/gui/CustomWidgets/DatabaseConversionWidgets/datasourceManagementWidget.py +++ b/DsgTools/gui/CustomWidgets/DatabaseConversionWidgets/datasourceManagementWidget.py @@ -24,16 +24,22 @@ from qgis.PyQt import QtWidgets, uic from qgis.PyQt.QtCore import pyqtSignal -from DsgTools.gui.CustomWidgets.DatabaseConversionWidgets.datasourceContainerWidget import DatasourceContainerWidget +from DsgTools.gui.CustomWidgets.DatabaseConversionWidgets.datasourceContainerWidget import ( + DatasourceContainerWidget, +) from DsgTools.core.Factories.DbFactory.abstractDb import AbstractDb from DsgTools.core.dsgEnums import DsgEnums -from DsgTools.gui.CustomWidgets.DatabaseConversionWidgets.MultiDsSelectorWidgets.multiDsWidgetFactory import MultiDsWidgetFactory +from DsgTools.gui.CustomWidgets.DatabaseConversionWidgets.MultiDsSelectorWidgets.multiDsWidgetFactory import ( + MultiDsWidgetFactory, +) import os from functools import partial -FORM_CLASS, _ = uic.loadUiType(os.path.join( - os.path.dirname(__file__), 'datasourceManagementWidget.ui')) +FORM_CLASS, _ = uic.loadUiType( + os.path.join(os.path.dirname(__file__), "datasourceManagementWidget.ui") +) + class DatasourceManagementWidget(QtWidgets.QWizardPage, FORM_CLASS): """ @@ -42,6 +48,7 @@ class DatasourceManagementWidget(QtWidgets.QWizardPage, FORM_CLASS): 2- prepare the conversion mapping structure using the table as a means to translate user's intentions; and 3- read filtering info to be applied to data. """ + # setting signal to alert conversion tool about any active widgets change activeWidgetAdded = pyqtSignal(DatasourceContainerWidget) activeWidgetRemoved = pyqtSignal(DatasourceContainerWidget) @@ -50,7 +57,7 @@ class DatasourceManagementWidget(QtWidgets.QWizardPage, FORM_CLASS): widgetUpdated = pyqtSignal(DatasourceContainerWidget) # filtering settings from widget container has changed signal containerFilterSettingsChanged = pyqtSignal(DatasourceContainerWidget) - + def __init__(self, parent=None): """ Class constructor. @@ -59,11 +66,11 @@ def __init__(self, parent=None): super(DatasourceManagementWidget, self).__init__() # define mapping from GUI to enum self.sourceNameDict = { - self.tr('Select a datasource driver') : DsgEnums.NoDriver, - 'PostGIS' : DsgEnums.PostGIS, - self.tr('PostGIS (create new database)') : DsgEnums.NewPostGIS, - 'SpatiaLite' : DsgEnums.SpatiaLite, - self.tr('SpatiaLite (create new database)') : DsgEnums.NewSpatiaLite, + self.tr("Select a datasource driver"): DsgEnums.NoDriver, + "PostGIS": DsgEnums.PostGIS, + self.tr("PostGIS (create new database)"): DsgEnums.NewPostGIS, + "SpatiaLite": DsgEnums.SpatiaLite, + self.tr("SpatiaLite (create new database)"): DsgEnums.NewSpatiaLite, # 'Shapefile' : DsgEnums.Shapefile, # self.tr('Shapefile (create new database)') : DsgEnums.NewShapefile, # 'Geopackage' : DsgEnums.Geopackage, @@ -74,8 +81,8 @@ def __init__(self, parent=None): self.fillSupportedDatasources() # keep track of all (in)active widgets on input/output GUI self.activeDrivers = dict() - self.addSourcePushButton.setToolTip(self.tr('Add single datasource')) - self.addMultiSourcePushButton.setToolTip(self.tr('Add multiple datasource')) + self.addSourcePushButton.setToolTip(self.tr("Add single datasource")) + self.addMultiSourcePushButton.setToolTip(self.tr("Add multiple datasource")) # centralize all tool signals in order to keep track of all non-standard signals used self.connectClassSignals() @@ -99,7 +106,7 @@ def fillSupportedDatasources(self, inputPage=True): # if it's an input page, items should not include the option for a new datasource items = [] for ds in self.sourceNameDict: - if self.tr('new') in ds: + if self.tr("new") in ds: continue else: items.append(ds) @@ -133,7 +140,7 @@ def addDatasourceWidget(self): # get current text on datasource techonology selection combobox currentDbSource = self.datasourceComboBox.currentText() # identify if it's an input or output page call - inputPage = (self.objectName() == 'datasourceManagementWidgetIn') + inputPage = self.objectName() == "datasourceManagementWidgetIn" if currentDbSource: # in case a valid driver is selected, add its widget to the interface source = self.sourceNameDict[currentDbSource] @@ -142,19 +149,26 @@ def addDatasourceWidget(self): # connect removal widget signal to new widget container.removeWidget.connect(self.removeWidget) # connect datasource change signal to this class datasource signal change - emitWidgetAlias = lambda newAbstract : self.datasourceChanged( - newAbstract=newAbstract, - containerWidget=container - ) - container.connectionWidget.selectionWidget.dbChanged.connect(emitWidgetAlias) + emitWidgetAlias = lambda newAbstract: self.datasourceChanged( + newAbstract=newAbstract, containerWidget=container + ) + container.connectionWidget.selectionWidget.dbChanged.connect( + emitWidgetAlias + ) # connect datasource change signal to its filters reset method - container.connectionWidget.selectionWidget.dbChanged.connect(container.clearFilters) + container.connectionWidget.selectionWidget.dbChanged.connect( + container.clearFilters + ) # connect filtering settings changed signal to this class signal on filtering settings change - container.filterSettingsChanged.connect(self.containerFilterSettingsChanged) - # add new driver container to GUI + container.filterSettingsChanged.connect( + self.containerFilterSettingsChanged + ) + # add new driver container to GUI self.datasourceLayout.addWidget(container) # update dict of active widgets - self.addElementToDict(k=currentDbSource, e=container, d=self.activeDrivers) + self.addElementToDict( + k=currentDbSource, e=container, d=self.activeDrivers + ) # reset all driver's groupboxes names self.resetWidgetsTitle() # emit active widget that has been added @@ -177,13 +191,13 @@ def addMultiDatasourceWidgets(self): # add new widget container for it container = self.addDatasourceWidget() # set datasource to it - container.setDatasource({ds : dsPath}) + container.setDatasource({ds: dsPath}) def resetWidgetsTitle(self): """ Resets all widgets containers titles. """ - hideAlias = lambda w : w.hide() + hideAlias = lambda w: w.hide() for driverName, widgetList in self.activeDrivers.items(): if not widgetList: # if there are no active widgets for current driver, there's nothing to be updated @@ -192,12 +206,12 @@ def resetWidgetsTitle(self): for idx, w in enumerate(widgetList): # if there are widgets from chosen driver, reset it's group box name w.show() - w.setGroupWidgetName(name='{0} #{1}'.format(driverName, idx + 1)) + w.setGroupWidgetName(name="{0} #{1}".format(driverName, idx + 1)) def removeWidget(self, w): """ Removes driver widget from GUI. - :param w: (QWidget) driver container widget to be removed. + :param w: (QWidget) driver container widget to be removed. """ # disconnect all widget connected signals w.blockSignals(True) @@ -229,16 +243,18 @@ def validate(self): Validates container GUI parameters. :return: (str) invalidation reason. """ - if self.objectName() == 'datasourceManagementWidgetIn': - pageError = self.tr('Input Error!') + if self.objectName() == "datasourceManagementWidgetIn": + pageError = self.tr("Input Error!") else: - pageError = self.tr('Output Error!') + pageError = self.tr("Output Error!") for containers in self.activeDrivers.values(): for container in containers: if not container.isValid(): - return '{0} {1}: {2}'.format(pageError, container.groupBox.title(), container.validate()) + return "{0} {1}: {2}".format( + pageError, container.groupBox.title(), container.validate() + ) # validate selection widget - return '' + return "" def isValid(self): """ diff --git a/DsgTools/gui/CustomWidgets/DatabaseConversionWidgets/datasourceSelectionWidgetFactory.py b/DsgTools/gui/CustomWidgets/DatabaseConversionWidgets/datasourceSelectionWidgetFactory.py index 009038f86..bf7bf2cc1 100644 --- a/DsgTools/gui/CustomWidgets/DatabaseConversionWidgets/datasourceSelectionWidgetFactory.py +++ b/DsgTools/gui/CustomWidgets/DatabaseConversionWidgets/datasourceSelectionWidgetFactory.py @@ -23,17 +23,34 @@ from qgis.PyQt.QtWidgets import QWidget -from DsgTools.gui.CustomWidgets.DatabaseConversionWidgets.SupportedDrivers.postgisWidget import PostgisWidget -from DsgTools.gui.CustomWidgets.DatabaseConversionWidgets.SupportedDrivers.newPostgisWidget import NewPostgisWidget -from DsgTools.gui.CustomWidgets.DatabaseConversionWidgets.SupportedDrivers.spatialiteWidget import SpatialiteWidget -from DsgTools.gui.CustomWidgets.DatabaseConversionWidgets.SupportedDrivers.newSpatialiteWidget import NewSpatialiteWidget -from DsgTools.gui.CustomWidgets.DatabaseConversionWidgets.SupportedDrivers.shapefileWidget import ShapefileWidget -from DsgTools.gui.CustomWidgets.DatabaseConversionWidgets.SupportedDrivers.newShapefileWidget import NewShapefileWidget -from DsgTools.gui.CustomWidgets.DatabaseConversionWidgets.SupportedDrivers.geopackageWidget import GeopackageWidget -from DsgTools.gui.CustomWidgets.DatabaseConversionWidgets.SupportedDrivers.newGeopackageWidget import NewGeopackageWidget +from DsgTools.gui.CustomWidgets.DatabaseConversionWidgets.SupportedDrivers.postgisWidget import ( + PostgisWidget, +) +from DsgTools.gui.CustomWidgets.DatabaseConversionWidgets.SupportedDrivers.newPostgisWidget import ( + NewPostgisWidget, +) +from DsgTools.gui.CustomWidgets.DatabaseConversionWidgets.SupportedDrivers.spatialiteWidget import ( + SpatialiteWidget, +) +from DsgTools.gui.CustomWidgets.DatabaseConversionWidgets.SupportedDrivers.newSpatialiteWidget import ( + NewSpatialiteWidget, +) +from DsgTools.gui.CustomWidgets.DatabaseConversionWidgets.SupportedDrivers.shapefileWidget import ( + ShapefileWidget, +) +from DsgTools.gui.CustomWidgets.DatabaseConversionWidgets.SupportedDrivers.newShapefileWidget import ( + NewShapefileWidget, +) +from DsgTools.gui.CustomWidgets.DatabaseConversionWidgets.SupportedDrivers.geopackageWidget import ( + GeopackageWidget, +) +from DsgTools.gui.CustomWidgets.DatabaseConversionWidgets.SupportedDrivers.newGeopackageWidget import ( + NewGeopackageWidget, +) from DsgTools.core.dsgEnums import DsgEnums -class DatasourceSelectionWidgetFactory(): + +class DatasourceSelectionWidgetFactory: """ Class designed to prepare each selection widget to be added to a widget container. """ @@ -46,14 +63,14 @@ def getSelectionWidget(source, parent=None): :return: (QWidget) selection widget for selected driver. """ sourceDict = { - DsgEnums.NoDriver : lambda : QWidget(), # returns a parent class empty object, to minimize standard distorsion - DsgEnums.PostGIS : lambda : PostgisWidget(parent=parent), - DsgEnums.NewPostGIS : lambda : NewPostgisWidget(parent=parent), - DsgEnums.SpatiaLite : lambda : SpatialiteWidget(parent=parent), - DsgEnums.NewSpatiaLite : lambda : NewSpatialiteWidget(parent=parent), - DsgEnums.Shapefile : lambda : ShapefileWidget(parent=parent), - DsgEnums.NewShapefile : lambda : NewShapefileWidget(parent=parent), - DsgEnums.Geopackage : lambda : GeopackageWidget(parent=parent), - DsgEnums.NewGeopackage : lambda : NewGeopackageWidget(parent=parent) + DsgEnums.NoDriver: lambda: QWidget(), # returns a parent class empty object, to minimize standard distorsion + DsgEnums.PostGIS: lambda: PostgisWidget(parent=parent), + DsgEnums.NewPostGIS: lambda: NewPostgisWidget(parent=parent), + DsgEnums.SpatiaLite: lambda: SpatialiteWidget(parent=parent), + DsgEnums.NewSpatiaLite: lambda: NewSpatialiteWidget(parent=parent), + DsgEnums.Shapefile: lambda: ShapefileWidget(parent=parent), + DsgEnums.NewShapefile: lambda: NewShapefileWidget(parent=parent), + DsgEnums.Geopackage: lambda: GeopackageWidget(parent=parent), + DsgEnums.NewGeopackage: lambda: NewGeopackageWidget(parent=parent), } return sourceDict[source]() diff --git a/DsgTools/gui/CustomWidgets/DatabaseConversionWidgets/filterDialog.py b/DsgTools/gui/CustomWidgets/DatabaseConversionWidgets/filterDialog.py index 993365406..6abb29d7c 100755 --- a/DsgTools/gui/CustomWidgets/DatabaseConversionWidgets/filterDialog.py +++ b/DsgTools/gui/CustomWidgets/DatabaseConversionWidgets/filterDialog.py @@ -31,8 +31,10 @@ from qgis.PyQt.QtCore import pyqtSlot, Qt from qgis.PyQt.QtWidgets import QDialog, QCheckBox -FORM_CLASS, _ = uic.loadUiType(os.path.join( - os.path.dirname(__file__), 'filterDialog.ui')) +FORM_CLASS, _ = uic.loadUiType( + os.path.join(os.path.dirname(__file__), "filterDialog.ui") +) + class FilterDialog(QDialog, FORM_CLASS): def __init__(self, spatialLayers, complexLayers, abstractDb, parent=None): @@ -41,7 +43,7 @@ def __init__(self, spatialLayers, complexLayers, abstractDb, parent=None): :param spatialLayers: (list-of-QgsVectorLayer) list of spatial layers. :param complexLayers: (list-of-QgsVectorLayer) list of complex layers. :param complexLayers: (AbstractDb) database object for data handling. - :param parent: (QtWidgets) any widget that should be parent to newly + :param parent: (QtWidgets) any widget that should be parent to newly instantiated object. """ super(FilterDialog, self).__init__(parent) @@ -71,7 +73,7 @@ def layerNamesFromCanvas(self): def layerFromLayerName(self, layerName): """ Gets vector layer object from its name. - :param layerName: (str) + :param layerName: (str) :return: (QgsVectorLayer) map cointaing layer name to vector layer object. """ l = QgsProject.instance().mapLayersByName(layerName) @@ -87,7 +89,7 @@ def fillSpatialFilterLayers(self): [self.tr("Select a layer...")] + self.layerNamesFromCanvas() ) - @pyqtSlot(int, name='on_spatialComboBox_currentIndexChanged') + @pyqtSlot(int, name="on_spatialComboBox_currentIndexChanged") def setSpatialFilterLayer(self): """ Sets spatial layer to its filter expression widget. @@ -102,7 +104,7 @@ def fillPredicates(self): """ self.predicateComboBox.clear() self.predicateComboBox.addItems( - sorted([self.tr('Clip'), self.tr('Buffer'), self.tr('Intersects')]) + sorted([self.tr("Clip"), self.tr("Buffer"), self.tr("Intersects")]) ) def fillClipOptions(self): @@ -110,13 +112,15 @@ def fillClipOptions(self): Clip options are given by choosing the area to be kept. """ self.comboBox.clear() - self.comboBox.addItems([ - self.tr('Choose a region...'), - self.tr('Inside Features'), - self.tr('Outside Features') - ]) + self.comboBox.addItems( + [ + self.tr("Choose a region..."), + self.tr("Inside Features"), + self.tr("Outside Features"), + ] + ) - @pyqtSlot(int, name='on_predicateComboBox_currentIndexChanged') + @pyqtSlot(int, name="on_predicateComboBox_currentIndexChanged") def setPredicateWidget(self): """ Sets the widget for capturing the topological relationship comparison parameter. @@ -150,7 +154,7 @@ def clearSelection(self): Clears the dict to its initial state. """ self._currentSelection = {} - + def setupLayerFilters(self): """ Sets all layers to GUI. @@ -170,26 +174,27 @@ def fetchSpatialParameter(self, predicate): :return: (tuple) spatial filter settings. """ return { - self.tr('Clip') : self.comboBox.currentText() if self.comboBox.currentIndex() > 0 else None, - self.tr('Buffer') : self.doubleSpinBox.value(), - self.tr('Intersects') : None, - '' : None + self.tr("Clip"): self.comboBox.currentText() + if self.comboBox.currentIndex() > 0 + else None, + self.tr("Buffer"): self.doubleSpinBox.value(), + self.tr("Intersects"): None, + "": None, }[predicate] def setPredicateParameter(self, predicate, parameter): """ Sets given parameter to the GUI. :param predicate: (str) predicate to which the parameter refers to. - :param parameter: (obj) parameter value to be filled. + :param parameter: (obj) parameter value to be filled. """ actionMap = { - self.tr('Clip') : self.comboBox.setCurrentText, - self.tr('Buffer') : self.doubleSpinBox.setValue, - self.tr('Intersects') : lambda : None + self.tr("Clip"): self.comboBox.setCurrentText, + self.tr("Buffer"): self.doubleSpinBox.setValue, + self.tr("Intersects"): lambda: None, } return actionMap[predicate](parameter) if parameter in actionMap else None - def setupGroupBoxFilters(self, isSpatial=True): """ Sets up the part the spatial/complex layers' GUI part. It does not handle selection (e.g. @@ -200,15 +205,24 @@ def setupGroupBoxFilters(self, isSpatial=True): layers = self.spatialLayers if isSpatial else self.complexLayers layout = self.spatialGridLayout if isSpatial else self.complexGridLayout for row, (layerName, layerFcMap) in enumerate(layers.items()): - checkBoxWidget, fieldExpressionWidget = QCheckBox(), QgsFieldExpressionWidget() + checkBoxWidget, fieldExpressionWidget = ( + QCheckBox(), + QgsFieldExpressionWidget(), + ) _, layer = self._abstractDb.getTableSchema(layerName) checkBoxWidget.setChecked(True) # allow filtering option only when layer is marked to be filtered checkBoxWidget.toggled.connect(fieldExpressionWidget.setEnabled) - checkBoxWidget.toggled.connect(partial(fieldExpressionWidget.setExpression, "")) - msg = self.tr('{0} ({1} features)') if layerFcMap['featureCount'] > 1 else self.tr('{0} ({1} feature)') - checkBoxWidget.setText(msg.format(layer, layerFcMap['featureCount'])) - fieldExpressionWidget.setLayer(layerFcMap['layer']) + checkBoxWidget.toggled.connect( + partial(fieldExpressionWidget.setExpression, "") + ) + msg = ( + self.tr("{0} ({1} features)") + if layerFcMap["featureCount"] > 1 + else self.tr("{0} ({1} feature)") + ) + checkBoxWidget.setText(msg.format(layer, layerFcMap["featureCount"])) + fieldExpressionWidget.setLayer(layerFcMap["layer"]) layout.addWidget(checkBoxWidget, row, 0) layout.addWidget(fieldExpressionWidget, row, 1) @@ -222,7 +236,7 @@ def validateSpatialFilter(self, layer, expression, predicate, parameter=None): :return: (bool) whether the set of spatial filter settings may be applied to the dataset. """ if predicate == self.tr("Clip"): - return parameter is not None and parameter != self.tr('Choose a region...') + return parameter is not None and parameter != self.tr("Choose a region...") elif predicate == self.tr("Buffer"): return parameter is not None return True @@ -245,25 +259,34 @@ def readFilters(self): checkBox = layout.itemAtPosition(row, 0).widget() if checkBox is None or not checkBox.isChecked(): continue - label = checkBox.text().replace('&', '') # still no idea why the '&' got in there... - layer = label.split(' (')[0] + label = checkBox.text().replace( + "&", "" + ) # still no idea why the '&' got in there... + layer = label.split(" (")[0] fieldExpressionWidget = layout.itemAtPosition(row, 1).widget() layerFilters[layer] = dict() - layerFilters[layer]['featureCount'] = int(label.split(' (')[1].split(' ')[0]) - layerFilters[layer]['expression'] = fieldExpressionWidget.currentText() + layerFilters[layer]["featureCount"] = int( + label.split(" (")[1].split(" ")[0] + ) + layerFilters[layer]["expression"] = fieldExpressionWidget.currentText() # read spatial filtering options spatialFilters = dict() - spatialFilters['layer'] = self.spatialComboBox.currentText() \ - if self.spatialComboBox.currentIndex() else "" - spatialFilters['expression'] = self.mFieldExpressionWidget.currentText() - spatialFilters['predicate'] = self.predicateComboBox.currentText() - spatialFilters['parameter'] = self.fetchSpatialParameter(spatialFilters['predicate']) - return {'layer_filter' : layerFilters, 'spatial_filter' : spatialFilters} + spatialFilters["layer"] = ( + self.spatialComboBox.currentText() + if self.spatialComboBox.currentIndex() + else "" + ) + spatialFilters["expression"] = self.mFieldExpressionWidget.currentText() + spatialFilters["predicate"] = self.predicateComboBox.currentText() + spatialFilters["parameter"] = self.fetchSpatialParameter( + spatialFilters["predicate"] + ) + return {"layer_filter": layerFilters, "spatial_filter": spatialFilters} @staticmethod def setWidgetToReadOnly(widget, readOnly): """ - Sets (or removes) a widget to read only mode. + Sets (or removes) a widget to read only mode. :param readOnly: (bool) whether widget will be read only mode. """ widget.setAttribute(Qt.WA_TransparentForMouseEvents, readOnly) @@ -287,9 +310,16 @@ def enableEdition(self, enabled): if checkBox is None: continue FilterDialog.setWidgetToReadOnly(checkBox, not enabled) - FilterDialog.setWidgetToReadOnly(layout.itemAtPosition(row, 1).widget(), not enabled) - for w in [self.spatialComboBox, self.mFieldExpressionWidget, self.predicateComboBox,\ - self.comboBox, self.doubleSpinBox]: + FilterDialog.setWidgetToReadOnly( + layout.itemAtPosition(row, 1).widget(), not enabled + ) + for w in [ + self.spatialComboBox, + self.mFieldExpressionWidget, + self.predicateComboBox, + self.comboBox, + self.doubleSpinBox, + ]: FilterDialog.setWidgetToReadOnly(w, not enabled) def resetSelection(self): @@ -297,7 +327,7 @@ def resetSelection(self): Resets layer selection to last state preserved into the private attribute holding current layer selection. """ - prevLayerFilter = self._currentSelection['layer_filter'] + prevLayerFilter = self._currentSelection["layer_filter"] for layout in [self.spatialGridLayout, self.complexGridLayout]: for row in range(layout.rowCount()): if row == 0: @@ -310,18 +340,30 @@ def resetSelection(self): if not checkBox: continue fieldExpressionWidget = layout.itemAtPosition(row, 1).widget() - label = checkBox.text().replace('&', '') # still no idea why the '&' got in there... - layer = label.split(' (')[0] + label = checkBox.text().replace( + "&", "" + ) # still no idea why the '&' got in there... + layer = label.split(" (")[0] checkBox.setChecked(layer in prevLayerFilter) - exp = prevLayerFilter[layer]['expression'] if layer in prevLayerFilter else "" + exp = ( + prevLayerFilter[layer]["expression"] + if layer in prevLayerFilter + else "" + ) fieldExpressionWidget.setExpression(exp) # reset spatial filters - self.spatialComboBox.setCurrentText(self._currentSelection['spatial_filter']['layer']) - self.mFieldExpressionWidget.setExpression(self._currentSelection['spatial_filter']['expression']) - self.predicateComboBox.setCurrentText(self._currentSelection['spatial_filter']['predicate']) + self.spatialComboBox.setCurrentText( + self._currentSelection["spatial_filter"]["layer"] + ) + self.mFieldExpressionWidget.setExpression( + self._currentSelection["spatial_filter"]["expression"] + ) + self.predicateComboBox.setCurrentText( + self._currentSelection["spatial_filter"]["predicate"] + ) self.setPredicateParameter( - self._currentSelection['spatial_filter']['predicate'], - self._currentSelection['spatial_filter']['parameter'] + self._currentSelection["spatial_filter"]["predicate"], + self._currentSelection["spatial_filter"]["parameter"], ) def on_okPushButton_clicked(self): diff --git a/DsgTools/gui/CustomWidgets/DatabaseCustomizationWidgets/customizationManagerWidget.py b/DsgTools/gui/CustomWidgets/DatabaseCustomizationWidgets/customizationManagerWidget.py index a9449e9e5..753018165 100644 --- a/DsgTools/gui/CustomWidgets/DatabaseCustomizationWidgets/customizationManagerWidget.py +++ b/DsgTools/gui/CustomWidgets/DatabaseCustomizationWidgets/customizationManagerWidget.py @@ -28,67 +28,116 @@ from qgis.PyQt.QtWidgets import QMessageBox, QApplication, QFileDialog from qgis.PyQt.QtGui import QCursor -#DsgTools imports -from DsgTools.core.ServerManagementTools.customizationManager import CustomizationManager -from DsgTools.gui.CustomWidgets.DatabasePropertiesWidgets.BasicPropertyWidgets.genericParameterSetter import GenericParameterSetter -from DsgTools.gui.Misc.PostgisCustomization.createDatabaseCustomization import CreateDatabaseCustomization -from DsgTools.gui.CustomWidgets.DatabasePropertiesWidgets.BasicPropertyWidgets.genericManagerWidget import GenericManagerWidget +# DsgTools imports +from DsgTools.core.ServerManagementTools.customizationManager import ( + CustomizationManager, +) +from DsgTools.gui.CustomWidgets.DatabasePropertiesWidgets.BasicPropertyWidgets.genericParameterSetter import ( + GenericParameterSetter, +) +from DsgTools.gui.Misc.PostgisCustomization.createDatabaseCustomization import ( + CreateDatabaseCustomization, +) +from DsgTools.gui.CustomWidgets.DatabasePropertiesWidgets.BasicPropertyWidgets.genericManagerWidget import ( + GenericManagerWidget, +) from DsgTools.core.Utils.utils import Utils from DsgTools.core.dsgEnums import DsgEnums from qgis.core import QgsMessageLog import json + class CustomizationManagerWidget(GenericManagerWidget): - def __init__(self, manager = None, parent = None): + def __init__(self, manager=None, parent=None): """ Constructor """ - super(CustomizationManagerWidget, self).__init__(genericDbManager = manager, parent = parent) + super(CustomizationManagerWidget, self).__init__( + genericDbManager=manager, parent=parent + ) - def setParameters(self, serverAbstractDb, edgvVersion, dbsDict = {}): + def setParameters(self, serverAbstractDb, edgvVersion, dbsDict={}): if serverAbstractDb: self.setComponentsEnabled(True) self.serverAbstractDb = serverAbstractDb - self.genericDbManager = CustomizationManager(serverAbstractDb, dbsDict, edgvVersion) + self.genericDbManager = CustomizationManager( + serverAbstractDb, dbsDict, edgvVersion + ) self.refresh() else: self.setComponentsEnabled(False) @pyqtSlot(bool) def on_createPushButton_clicked(self): - ''' + """ Slot that opens the create profile dialog - ''' + """ paramDlg = GenericParameterSetter() if not paramDlg.exec_(): return templateDb, propertyName, edgvVersion = paramDlg.getParameters() - if edgvVersion == self.tr('Select EDGV Version'): - QMessageBox.warning(self, self.tr('Warning!'), self.tr('Warning! Enter a EDGV Version')) + if edgvVersion == self.tr("Select EDGV Version"): + QMessageBox.warning( + self, self.tr("Warning!"), self.tr("Warning! Enter a EDGV Version") + ) return - if propertyName == '': - QMessageBox.warning(self, self.tr('Warning!'), self.tr('Warning! Enter an Earth Coverage Name!')) + if propertyName == "": + QMessageBox.warning( + self, + self.tr("Warning!"), + self.tr("Warning! Enter an Earth Coverage Name!"), + ) return - if propertyName in list(self.genericDbManager.getPropertyPerspectiveDict(viewType = DsgEnums.Property).keys()): - QMessageBox.warning(self, self.tr('Warning!'), self.tr('Warning! Earth Coverage Name already exists!')) + if propertyName in list( + self.genericDbManager.getPropertyPerspectiveDict( + viewType=DsgEnums.Property + ).keys() + ): + QMessageBox.warning( + self, + self.tr("Warning!"), + self.tr("Warning! Earth Coverage Name already exists!"), + ) return - dlg = CreateDatabaseCustomization(propertyName, templateDb, edgvVersion, self.genericDbManager) + dlg = CreateDatabaseCustomization( + propertyName, templateDb, edgvVersion, self.genericDbManager + ) dlg.exec_() - + @pyqtSlot(bool) def on_deleteCustomizationPushButton_clicked(self): - #TODO: Reimplement + # TODO: Reimplement customizationName = self.customizationListWidget.currentItem().text() edgvVersion = self.versionSelectionComboBox.currentText() - if QMessageBox.question(self, self.tr('Question'), self.tr('Do you really want to delete customization ')+customizationName+'?', QMessageBox.Ok|QMessageBox.Cancel) == QMessageBox.Cancel: + if ( + QMessageBox.question( + self, + self.tr("Question"), + self.tr("Do you really want to delete customization ") + + customizationName + + "?", + QMessageBox.Ok | QMessageBox.Cancel, + ) + == QMessageBox.Cancel + ): return try: QApplication.setOverrideCursor(QCursor(Qt.WaitCursor)) self.genericDbManager.deleteCustomization(customizationName, edgvVersion) QApplication.restoreOverrideCursor() - QMessageBox.warning(self, self.tr('Success!'), self.tr('Customization ') + customizationName + self.tr(' successfully deleted.')) + QMessageBox.warning( + self, + self.tr("Success!"), + self.tr("Customization ") + + customizationName + + self.tr(" successfully deleted."), + ) self.refreshProfileList() except Exception as e: QApplication.restoreOverrideCursor() - QMessageBox.warning(self, self.tr('Warning!'), self.tr('Error! Problem deleting customization: ') + ':'.join(e.args)) \ No newline at end of file + QMessageBox.warning( + self, + self.tr("Warning!"), + self.tr("Error! Problem deleting customization: ") + ":".join(e.args), + ) diff --git a/DsgTools/gui/CustomWidgets/DatabasePropertiesWidgets/BasicPropertyWidgets/databaseParameterWidget.py b/DsgTools/gui/CustomWidgets/DatabasePropertiesWidgets/BasicPropertyWidgets/databaseParameterWidget.py index 50f453869..a6680d1bc 100644 --- a/DsgTools/gui/CustomWidgets/DatabasePropertiesWidgets/BasicPropertyWidgets/databaseParameterWidget.py +++ b/DsgTools/gui/CustomWidgets/DatabasePropertiesWidgets/BasicPropertyWidgets/databaseParameterWidget.py @@ -33,13 +33,16 @@ from qgis.PyQt.QtWidgets import QFileDialog, QMessageBox, QRadioButton -FORM_CLASS, _ = uic.loadUiType(os.path.join( - os.path.dirname(__file__), 'databaseParameterWidget.ui')) +FORM_CLASS, _ = uic.loadUiType( + os.path.join(os.path.dirname(__file__), "databaseParameterWidget.ui") +) + class DatabaseParameterWidget(QtWidgets.QWidget, FORM_CLASS): filesSelected = pyqtSignal() changeSize = pyqtSignal() - def __init__(self, parent = None): + + def __init__(self, parent=None): """Constructor.""" super(self.__class__, self).__init__(parent) self.setupUi(self) @@ -47,36 +50,52 @@ def __init__(self, parent = None): self.selectedAbstractDb = None self.setInitialState() self.useFrame = True - - @pyqtSlot(AbstractDb, name = 'on_comboBoxPostgis_dbChanged') #check this out luiz! hahahahaha + + @pyqtSlot( + AbstractDb, name="on_comboBoxPostgis_dbChanged" + ) # check this out luiz! hahahahaha def populateSelectedAbstractDb(self, abstractDb): self.selectedAbstractDb = abstractDb if self.useFrame: self.populateFrameComboBox() - + def populateFrameComboBox(self): if self.selectedAbstractDb: - areaDict = self.selectedAbstractDb.getGeomColumnDictV2(primitiveFilter=['a'], excludeValidation = True) + areaDict = self.selectedAbstractDb.getGeomColumnDictV2( + primitiveFilter=["a"], excludeValidation=True + ) self.frameComboBox.clear() - self.frameComboBox.addItem(self.tr('Select a table from database')) + self.frameComboBox.addItem(self.tr("Select a table from database")) self.tableDict = dict() sortedKeys = list(areaDict.keys()) sortedKeys.sort() for key in sortedKeys: - tableKey = '{0}.{1}:{2}'.format(areaDict[key]['tableSchema'], areaDict[key]['tableName'], areaDict[key]['geom']) + tableKey = "{0}.{1}:{2}".format( + areaDict[key]["tableSchema"], + areaDict[key]["tableName"], + areaDict[key]["geom"], + ) self.tableDict[tableKey] = areaDict[key] self.frameComboBox.addItem(tableKey) - - @pyqtSlot(int, name = 'on_frameComboBox_currentIndexChanged') + + @pyqtSlot(int, name="on_frameComboBox_currentIndexChanged") def populateCombos(self, idx): if self.selectedAbstractDb: if idx > 0: self.indexComboBox.clear() self.inomComboBox.clear() - self.indexComboBox.addItem(self.tr('Select an attribute from selected table')) - self.inomComboBox.addItem(self.tr('Select an attribute from selected table')) + self.indexComboBox.addItem( + self.tr("Select an attribute from selected table") + ) + self.inomComboBox.addItem( + self.tr("Select an attribute from selected table") + ) selected = self.tableDict[self.frameComboBox.currentText()] - attributeList = self.selectedAbstractDb.getAttributesFromTable(selected['tableSchema'], selected['tableName'], typeFilter = ['character', 'character varying', 'text']) + attributeList = self.selectedAbstractDb.getAttributesFromTable( + selected["tableSchema"], + selected["tableName"], + typeFilter=["character", "character varying", "text"], + ) for attr in attributeList: self.indexComboBox.addItem(attr) self.inomComboBox.addItem(attr) @@ -85,7 +104,7 @@ def setServerDb(self, abstractDb): self.serverAbstractDb = abstractDb self.dbTemplateRadioButton.setEnabled(True) self.comboBoxPostgis.setServerDb(self.serverAbstractDb) - + def setInitialState(self): """ Sets the initial state @@ -96,69 +115,69 @@ def setInitialState(self): self.frameGroupBox.hide() if not self.serverAbstractDb: self.dbTemplateRadioButton.setEnabled(False) - + def setPrefixVisible(self, visible): """ Sets if the database prefix should be visible """ - if isinstance(visible,bool): + if isinstance(visible, bool): self.prefixLineEdit.setVisible(visible) self.prefixLabel.setVisible(visible) self.prefixVisible = visible - + def setSufixVisible(self, visible): """ Sets if the database sufix should be visible """ - if isinstance(visible,bool): + if isinstance(visible, bool): self.sufixLineEdit.setVisible(visible) self.sufixLabel.setVisible(visible) self.sufixVisible = visible - + def setDbNameVisible(self, visible): """ Sets if the database name should be visible """ - if isinstance(visible,bool): + if isinstance(visible, bool): self.dbNameLineEdit.setVisible(visible) self.dbNameLabel.setVisible(visible) self.dbNameVisible = visible - + def getVersion(self): """ Get the database version """ return self.versionComboBox.currentText() - + def validate(self): """ Validate database name """ - errorMsg = '' + errorMsg = "" if self.dbNameVisible: - if self.dbNameLineEdit.text() == '': - errorMsg += self.tr('Enter a database name!\n') - if self.mQgsProjectionSelectionWidget.crs().authid() == '': - errorMsg += self.tr('Select a coordinate reference system!\n') + if self.dbNameLineEdit.text() == "": + errorMsg += self.tr("Enter a database name!\n") + if self.mQgsProjectionSelectionWidget.crs().authid() == "": + errorMsg += self.tr("Select a coordinate reference system!\n") if not self.edgvTemplateRadioButton.isChecked(): if not self.comboBoxPostgis.currentDb(): - errorMsg += self.tr('Select a template database!\n') + errorMsg += self.tr("Select a template database!\n") if self.useFrame: if self.frameComboBox.currentIndex() == 0: - errorMsg += self.tr('Select a frame layer!\n') + errorMsg += self.tr("Select a frame layer!\n") if self.indexComboBox.currentIndex() == 0: - errorMsg += self.tr('Select an index attribute!\n') + errorMsg += self.tr("Select an index attribute!\n") if self.inomComboBox.currentIndex() == 0: - errorMsg += self.tr('Select an INOM attribute!\n') - - if errorMsg != '': - QMessageBox.critical(self, self.tr('Critical!'), errorMsg) + errorMsg += self.tr("Select an INOM attribute!\n") + + if errorMsg != "": + QMessageBox.critical(self, self.tr("Critical!"), errorMsg) return False else: return True - - @pyqtSlot(bool, name = 'on_edgvTemplateRadioButton_toggled') - def changeInterfaceState(self, edgvTemplateToggled, hideInterface = True): + + @pyqtSlot(bool, name="on_edgvTemplateRadioButton_toggled") + def changeInterfaceState(self, edgvTemplateToggled, hideInterface=True): if edgvTemplateToggled: self.comboBoxPostgis.setEnabled(False) self.frameComboBox.setEnabled(False) @@ -178,34 +197,33 @@ def changeInterfaceState(self, edgvTemplateToggled, hideInterface = True): else: self.comboBoxPostgis.show() self.dbTemplateRadioButton.show() - + def getTemplateName(self): if self.edgvTemplateRadioButton.isChecked(): return None else: return self.comboBoxPostgis.currentDb() - + def getTemplateParameters(self): if self.edgvTemplateRadioButton.isChecked(): paramDict = dict() if self.serverAbstractDb: - paramDict['templateName'] = self.serverAbstractDb.getTemplateName(self.versionComboBox.currentText()) - paramDict['version'] = self.versionComboBox.currentText() - paramDict['isTemplateEdgv'] = True - return paramDict + paramDict["templateName"] = self.serverAbstractDb.getTemplateName( + self.versionComboBox.currentText() + ) + paramDict["version"] = self.versionComboBox.currentText() + paramDict["isTemplateEdgv"] = True + return paramDict else: paramDict = dict() - paramDict['templateName'] = self.comboBoxPostgis.currentDb() - paramDict['isTemplateEdgv'] = False + paramDict["templateName"] = self.comboBoxPostgis.currentDb() + paramDict["isTemplateEdgv"] = False if self.useFrame: selected = self.tableDict[self.frameComboBox.currentText()] - paramDict['tableSchema'] = selected['tableSchema'] - paramDict['tableName'] = selected['tableName'] - paramDict['geom'] = selected['geom'] - paramDict['miAttr'] = self.indexComboBox.currentText() - paramDict['inomAttr'] = self.inomComboBox.currentText() - paramDict['geomType'] = selected['geomType'] + paramDict["tableSchema"] = selected["tableSchema"] + paramDict["tableName"] = selected["tableName"] + paramDict["geom"] = selected["geom"] + paramDict["miAttr"] = self.indexComboBox.currentText() + paramDict["inomAttr"] = self.inomComboBox.currentText() + paramDict["geomType"] = selected["geomType"] return paramDict - - - diff --git a/DsgTools/gui/CustomWidgets/DatabasePropertiesWidgets/BasicPropertyWidgets/earthCoverageManagerWidget.py b/DsgTools/gui/CustomWidgets/DatabasePropertiesWidgets/BasicPropertyWidgets/earthCoverageManagerWidget.py index 39595f7f3..7f52d11c2 100644 --- a/DsgTools/gui/CustomWidgets/DatabasePropertiesWidgets/BasicPropertyWidgets/earthCoverageManagerWidget.py +++ b/DsgTools/gui/CustomWidgets/DatabasePropertiesWidgets/BasicPropertyWidgets/earthCoverageManagerWidget.py @@ -28,98 +28,136 @@ from qgis.PyQt.QtWidgets import QMessageBox, QApplication, QFileDialog from qgis.PyQt.QtGui import QCursor -#DsgTools imports -from DsgTools.core.ServerManagementTools.earthCoverageManager import EarthCoverageManager -from DsgTools.gui.Misc.PostgisCustomization.createDatabaseCustomization import CreateDatabaseCustomization -from DsgTools.gui.CustomWidgets.DatabasePropertiesWidgets.BasicPropertyWidgets.genericParameterSetter import GenericParameterSetter -from DsgTools.gui.CustomWidgets.DatabasePropertiesWidgets.BasicPropertyWidgets.genericManagerWidget import GenericManagerWidget -from DsgTools.gui.CustomWidgets.DatabasePropertiesWidgets.BasicPropertyWidgets.setupEarthCoverage import SetupEarthCoverage +# DsgTools imports +from DsgTools.core.ServerManagementTools.earthCoverageManager import ( + EarthCoverageManager, +) +from DsgTools.gui.Misc.PostgisCustomization.createDatabaseCustomization import ( + CreateDatabaseCustomization, +) +from DsgTools.gui.CustomWidgets.DatabasePropertiesWidgets.BasicPropertyWidgets.genericParameterSetter import ( + GenericParameterSetter, +) +from DsgTools.gui.CustomWidgets.DatabasePropertiesWidgets.BasicPropertyWidgets.genericManagerWidget import ( + GenericManagerWidget, +) +from DsgTools.gui.CustomWidgets.DatabasePropertiesWidgets.BasicPropertyWidgets.setupEarthCoverage import ( + SetupEarthCoverage, +) from DsgTools.core.Utils.utils import Utils from DsgTools.core.dsgEnums import DsgEnums from qgis.core import QgsMessageLog import json + class EarthCoverageManagerWidget(GenericManagerWidget): - def __init__(self, manager = None, parent = None): + def __init__(self, manager=None, parent=None): """ Constructor """ - super(self.__class__, self).__init__(genericDbManager = manager, parent = parent) + super(self.__class__, self).__init__(genericDbManager=manager, parent=parent) - def setParameters(self, serverAbstractDb, edgvVersion, dbsDict = {}): + def setParameters(self, serverAbstractDb, edgvVersion, dbsDict={}): if serverAbstractDb: self.setComponentsEnabled(True) self.serverAbstractDb = serverAbstractDb - self.genericDbManager = EarthCoverageManager(serverAbstractDb, dbsDict, edgvVersion) + self.genericDbManager = EarthCoverageManager( + serverAbstractDb, dbsDict, edgvVersion + ) self.refresh() else: self.setComponentsEnabled(False) @pyqtSlot(bool) def on_createPushButton_clicked(self): - ''' + """ Slot that opens the create profile dialog - ''' + """ dlg = GenericParameterSetter() if not dlg.exec_(): return templateDb, propertyName, edgvVersion = dlg.getParameters() - if edgvVersion == self.tr('Select EDGV Version'): - QMessageBox.warning(self, self.tr('Warning!'), self.tr('Warning! Enter a EDGV Version')) + if edgvVersion == self.tr("Select EDGV Version"): + QMessageBox.warning( + self, self.tr("Warning!"), self.tr("Warning! Enter a EDGV Version") + ) return - if propertyName == '': - QMessageBox.warning(self, self.tr('Warning!'), self.tr('Warning! Enter an Earth Coverage Name!')) + if propertyName == "": + QMessageBox.warning( + self, + self.tr("Warning!"), + self.tr("Warning! Enter an Earth Coverage Name!"), + ) return - if propertyName in list(self.genericDbManager.getPropertyPerspectiveDict(viewType = DsgEnums.Property).keys()): - QMessageBox.warning(self, self.tr('Warning!'), self.tr('Warning! Earth Coverage Name already exists!')) + if propertyName in list( + self.genericDbManager.getPropertyPerspectiveDict( + viewType=DsgEnums.Property + ).keys() + ): + QMessageBox.warning( + self, + self.tr("Warning!"), + self.tr("Warning! Earth Coverage Name already exists!"), + ) return - fieldSetupDict = self.populateConfigInterface(templateDb, propertyName = propertyName) + fieldSetupDict = self.populateConfigInterface( + templateDb, propertyName=propertyName + ) if fieldSetupDict: - self.genericDbManager.createSetting(propertyName, edgvVersion, fieldSetupDict) + self.genericDbManager.createSetting( + propertyName, edgvVersion, fieldSetupDict + ) self.refresh() - QMessageBox.information(self, self.tr('Success!'), self.tr('Field Toolbox Configuration ') + propertyName + self.tr(' created successfuly!')) + QMessageBox.information( + self, + self.tr("Success!"), + self.tr("Field Toolbox Configuration ") + + propertyName + + self.tr(" created successfuly!"), + ) - - def populateConfigInterface(self, templateDb, jsonDict = None, propertyName = None): - ''' + def populateConfigInterface(self, templateDb, jsonDict=None, propertyName=None): + """ Must be reimplemented in each child - ''' - areas = templateDb.getParentGeomTables(getFullName = True, primitiveFilter = ['a']) - lines = templateDb.getParentGeomTables(getFullName = True, primitiveFilter = ['l']) + """ + areas = templateDb.getParentGeomTables(getFullName=True, primitiveFilter=["a"]) + lines = templateDb.getParentGeomTables(getFullName=True, primitiveFilter=["l"]) edgvVersion = templateDb.getDatabaseVersion() settings = self.genericDbManager.getSettings() if edgvVersion in list(settings.keys()): propertyList = settings else: propertyList = [] - dlg = SetupEarthCoverage(edgvVersion, areas, lines, jsonDict, propertyList, propertyName = propertyName) + dlg = SetupEarthCoverage( + edgvVersion, areas, lines, jsonDict, propertyList, propertyName=propertyName + ) if dlg.exec_(): return dlg.configDict else: return None - + def getUpdateSelectedSettingHeader(self): - header = self.tr('Update Earth Coverage configuration complete. \n') - operation = self.tr('earth coverage configuration') + header = self.tr("Update Earth Coverage configuration complete. \n") + operation = self.tr("earth coverage configuration") return header, operation def getUninstallSelectedSettingHeader(self): - header = self.tr('Uninstall Earth Coverage configuration complete. \n') - operation = self.tr('earth coverage configuration') + header = self.tr("Uninstall Earth Coverage configuration complete. \n") + operation = self.tr("earth coverage configuration") return header, operation def getApplyHeader(self): - header = self.tr('Install Earth Coverage configuration complete. \n') - operation = self.tr('earth coverage configurations') + header = self.tr("Install Earth Coverage configuration complete. \n") + operation = self.tr("earth coverage configurations") return header, operation - + def getDeleteHeader(self): - header = self.tr('Delete Earth Coverage configuration complete. \n') - operation = self.tr('earth coverage configurations') + header = self.tr("Delete Earth Coverage configuration complete. \n") + operation = self.tr("earth coverage configurations") return header, operation - + def getUninstallFromSelected(self): - header = self.tr('Uninstall Earth Coverage configuration complete. \n') - operation = self.tr('earth coverage configurations') - return header, operation \ No newline at end of file + header = self.tr("Uninstall Earth Coverage configuration complete. \n") + operation = self.tr("earth coverage configurations") + return header, operation diff --git a/DsgTools/gui/CustomWidgets/DatabasePropertiesWidgets/BasicPropertyWidgets/earthCoverageWidget.py b/DsgTools/gui/CustomWidgets/DatabasePropertiesWidgets/BasicPropertyWidgets/earthCoverageWidget.py index 4e62f05d8..38efa0e81 100644 --- a/DsgTools/gui/CustomWidgets/DatabasePropertiesWidgets/BasicPropertyWidgets/earthCoverageWidget.py +++ b/DsgTools/gui/CustomWidgets/DatabasePropertiesWidgets/BasicPropertyWidgets/earthCoverageWidget.py @@ -27,15 +27,19 @@ from qgis.PyQt.QtCore import pyqtSlot, pyqtSignal from qgis.PyQt.QtWidgets import QTreeWidgetItem, QMessageBox -FORM_CLASS, _ = uic.loadUiType(os.path.join( - os.path.dirname(__file__), 'earthCoverageWidget.ui')) +FORM_CLASS, _ = uic.loadUiType( + os.path.join(os.path.dirname(__file__), "earthCoverageWidget.ui") +) from DsgTools.core.Factories.DbFactory.abstractDb import AbstractDb from DsgTools.core.Factories.DbFactory.dbFactory import DbFactory from qgis.core import QgsMessageLog -from DsgTools.core.ServerManagementTools.earthCoverageManager import EarthCoverageManager +from DsgTools.core.ServerManagementTools.earthCoverageManager import ( + EarthCoverageManager, +) from DsgTools.core.dsgEnums import DsgEnums + class EarthCoverageWidget(QtWidgets.QWidget, FORM_CLASS): def __init__(self, parent=None): """Constructor.""" @@ -68,14 +72,18 @@ def clearTree(self): self.earthCoverageTreeWidget.invisibleRootItem().takeChildren() def getEarthCoverageDict(self): - if self.abstractDb.checkIfExistsConfigTable('EarthCoverage'): + if self.abstractDb.checkIfExistsConfigTable("EarthCoverage"): edgvVersion = self.abstractDb.getDatabaseVersion() - propertyDict = self.abstractDb.getAllSettingsFromAdminDb('EarthCoverage') + propertyDict = self.abstractDb.getAllSettingsFromAdminDb("EarthCoverage") if edgvVersion in list(propertyDict.keys()): propertyName = propertyDict[edgvVersion][0] dbName = self.abstractDb.db.databaseName() - self.settingDict = json.loads(self.abstractDb.getSettingFromAdminDb('EarthCoverage', propertyName, edgvVersion)) - self.earthCoverageDict = self.settingDict['earthCoverageDict'] + self.settingDict = json.loads( + self.abstractDb.getSettingFromAdminDb( + "EarthCoverage", propertyName, edgvVersion + ) + ) + self.earthCoverageDict = self.settingDict["earthCoverageDict"] def loadEarthCoverage(self): """ @@ -86,14 +94,19 @@ def loadEarthCoverage(self): if self.earthCoverageDict == dict(): self.getEarthCoverageDict() rootItem = self.earthCoverageTreeWidget.invisibleRootItem() - #database item + # database item for key in list(self.earthCoverageDict.keys()): item = QTreeWidgetItem(rootItem) - item.setText(0,key) + item.setText(0, key) item.setExpanded(True) for cl in self.earthCoverageDict[key]: covItem = QTreeWidgetItem(item) - covItem.setText(1,cl) + covItem.setText(1, cl) covItem.setExpanded(True) except Exception as e: - QgsMessageLog.logMessage(self.tr('Earth Coverage not loaded! Check log for details.')+':'.join(e.args), "DSGTools Plugin", Qgis.Critical) \ No newline at end of file + QgsMessageLog.logMessage( + self.tr("Earth Coverage not loaded! Check log for details.") + + ":".join(e.args), + "DSGTools Plugin", + Qgis.Critical, + ) diff --git a/DsgTools/gui/CustomWidgets/DatabasePropertiesWidgets/BasicPropertyWidgets/genericManagerWidget.py b/DsgTools/gui/CustomWidgets/DatabasePropertiesWidgets/BasicPropertyWidgets/genericManagerWidget.py index de535199e..a733be16b 100644 --- a/DsgTools/gui/CustomWidgets/DatabasePropertiesWidgets/BasicPropertyWidgets/genericManagerWidget.py +++ b/DsgTools/gui/CustomWidgets/DatabasePropertiesWidgets/BasicPropertyWidgets/genericManagerWidget.py @@ -27,10 +27,16 @@ # Qt imports from qgis.PyQt import QtWidgets, uic, QtCore from qgis.PyQt.QtCore import pyqtSlot, Qt, pyqtSignal -from qgis.PyQt.QtWidgets import QMessageBox, QApplication, QFileDialog, QMenu, QHeaderView +from qgis.PyQt.QtWidgets import ( + QMessageBox, + QApplication, + QFileDialog, + QMenu, + QHeaderView, +) from qgis.PyQt.QtGui import QCursor -#DsgTools imports +# DsgTools imports from DsgTools.gui.CustomWidgets.SelectionWidgets.listSelector import ListSelector from DsgTools.core.Utils.utils import Utils from DsgTools.core.dsgEnums import DsgEnums @@ -38,39 +44,54 @@ from qgis.core import QgsMessageLog, Qgis import json -FORM_CLASS, _ = uic.loadUiType(os.path.join( - os.path.dirname(__file__), 'genericManagerWidget.ui')) +FORM_CLASS, _ = uic.loadUiType( + os.path.join(os.path.dirname(__file__), "genericManagerWidget.ui") +) + class GenericManagerWidget(QtWidgets.QWidget, FORM_CLASS): Install, Delete, Uninstall, Update, Create = list(range(5)) - def __init__(self, genericDbManager = None, parent = None): + + def __init__(self, genericDbManager=None, parent=None): """ Constructor """ super(GenericManagerWidget, self).__init__(parent) self.setupUi(self) self.genericDbManager = genericDbManager - self.textDict = {'EarthCoverage':self.tr('Earth Coverage'), - 'Customization':self.tr('Customization'), - 'Style':self.tr('Style'), - 'ValidationConfig':self.tr('Validation'), - 'Permission':self.tr('Permissions'), - 'AttributeRules':self.tr('Attribute Rule Configuration'), - 'SpatialRuleConfig':self.tr('Spatial Rule Configuration')} - self.captionDict = {'EarthCoverage':self.tr('Earth Coverage'), - 'Customization':self.tr('Customization'), - 'Style':self.tr('Style'), - 'ValidationConfig':self.tr('Validation'), - 'Permission':self.tr('Select a dsgtools permission profile'), - 'AttributeRules':self.tr('Attribute Rule Configuration file'), - 'SpatialRuleConfig':self.tr('Spatial Rule Configuration file')} - self.filterDict = {'EarthCoverage':self.tr('Earth Coverage Setup File (*.dsgearthcov)'), - 'Customization':self.tr('DsgTools Customization File (*.dsgcustom)'), - 'Style':self.tr('DsgTools Styles File (*.dsgstyle)'), - 'ValidationConfig':self.tr('DsgTools Validation Configuration File (*.dsgvalidcfg)'), - 'Permission':self.tr('DsgTools Permission Profile File (*.dsgperm)'), - 'AttributeRules':self.tr('Attribute Rule Configuration file (*.dsgattrrul)'), - 'SpatialRuleConfig':self.tr('Spatial Rule Configuration file (*.dsgspatrul)')} + self.textDict = { + "EarthCoverage": self.tr("Earth Coverage"), + "Customization": self.tr("Customization"), + "Style": self.tr("Style"), + "ValidationConfig": self.tr("Validation"), + "Permission": self.tr("Permissions"), + "AttributeRules": self.tr("Attribute Rule Configuration"), + "SpatialRuleConfig": self.tr("Spatial Rule Configuration"), + } + self.captionDict = { + "EarthCoverage": self.tr("Earth Coverage"), + "Customization": self.tr("Customization"), + "Style": self.tr("Style"), + "ValidationConfig": self.tr("Validation"), + "Permission": self.tr("Select a dsgtools permission profile"), + "AttributeRules": self.tr("Attribute Rule Configuration file"), + "SpatialRuleConfig": self.tr("Spatial Rule Configuration file"), + } + self.filterDict = { + "EarthCoverage": self.tr("Earth Coverage Setup File (*.dsgearthcov)"), + "Customization": self.tr("DsgTools Customization File (*.dsgcustom)"), + "Style": self.tr("DsgTools Styles File (*.dsgstyle)"), + "ValidationConfig": self.tr( + "DsgTools Validation Configuration File (*.dsgvalidcfg)" + ), + "Permission": self.tr("DsgTools Permission Profile File (*.dsgperm)"), + "AttributeRules": self.tr( + "Attribute Rule Configuration file (*.dsgattrrul)" + ), + "SpatialRuleConfig": self.tr( + "Spatial Rule Configuration file (*.dsgspatrul)" + ), + } self.widgetName = self.textDict[self.getWhoAmI()] self.genericDict = None self.setComponentsEnabled(False) @@ -79,30 +100,39 @@ def __init__(self, genericDbManager = None, parent = None): self.setButtons() self.treeWidget.setContextMenuPolicy(Qt.CustomContextMenu) self.treeWidget.customContextMenuRequested.connect(self.createMenuAssigned) - + def setButtons(self): createText = self.createPushButton.text() - self.createPushButton.setText(createText.replace(self.tr('Setting'),self.widgetName)) + self.createPushButton.setText( + createText.replace(self.tr("Setting"), self.widgetName) + ) deleteText = self.deletePushButton.text() - self.deletePushButton.setText(deleteText.replace(self.tr('Setting'),self.widgetName)) - + self.deletePushButton.setText( + deleteText.replace(self.tr("Setting"), self.widgetName) + ) + def setHeaders(self): viewType = self.getViewType() if viewType == DsgEnums.Database: - self.treeWidget.setHeaderLabels([self.tr('Database'), self.widgetName]) + self.treeWidget.setHeaderLabels([self.tr("Database"), self.widgetName]) else: - self.treeWidget.setHeaderLabels([self.widgetName, self.tr('Database')]) + self.treeWidget.setHeaderLabels([self.widgetName, self.tr("Database")]) return viewType - + def getWhoAmI(self): - return str(self.__class__).split('.')[-1].replace('\'>', '').replace('ManagerWidget','') - + return ( + str(self.__class__) + .split(".")[-1] + .replace("'>", "") + .replace("ManagerWidget", "") + ) + def setChildParameter(self): """ Reimplement in each child """ pass - + def setComponentsEnabled(self, enabled): """ Changes states of all components of the widget, according to the boolean parameter enabled. @@ -115,17 +145,19 @@ def setComponentsEnabled(self, enabled): self.databasePerspectivePushButton.setEnabled(enabled) self.propertyPerspectivePushButton.setEnabled(enabled) - def populateConfigInterface(self, templateDb, jsonDict = None): + def populateConfigInterface(self, templateDb, jsonDict=None): """ Must be reimplemented in each child """ - pass + pass def readJsonFromDatabase(self, propertyName, edgvVersion): """ Reads the profile file, gets a dictionary of it and builds the tree widget """ - self.genericDict = self.genericDbManager.getCustomization(propertyName, edgvVersion) + self.genericDict = self.genericDbManager.getCustomization( + propertyName, edgvVersion + ) @pyqtSlot(bool) def on_importPushButton_clicked(self): @@ -134,21 +166,34 @@ def on_importPushButton_clicked(self): """ fd = QFileDialog() widgetType = self.getWhoAmI() - filename = fd.getOpenFileName(caption=self.captionDict[widgetType],filter=self.filterDict[widgetType])[0] + filename = fd.getOpenFileName( + caption=self.captionDict[widgetType], filter=self.filterDict[widgetType] + )[0] filename = filename[0] if isinstance(filename, tuple) else filename - if filename == '': + if filename == "": # QMessageBox.warning(self, self.tr('Warning!'), self.tr('Warning! Select a file to import!')) return try: QApplication.setOverrideCursor(QCursor(Qt.WaitCursor)) self.genericDbManager.importSetting(filename) QApplication.restoreOverrideCursor() - QMessageBox.information(self, self.tr('Success!'), self.widgetName + self.tr(' successfully imported.')) + QMessageBox.information( + self, + self.tr("Success!"), + self.widgetName + self.tr(" successfully imported."), + ) except Exception as e: QApplication.restoreOverrideCursor() - QMessageBox.critical(self, self.tr('Error!'), self.tr('Error! Problem importing ') +self.widgetName + ': ' + ':'.join(e.args)) + QMessageBox.critical( + self, + self.tr("Error!"), + self.tr("Error! Problem importing ") + + self.widgetName + + ": " + + ":".join(e.args), + ) self.refresh() - + @pyqtSlot(bool) def on_exportPushButton_clicked(self): """ @@ -159,12 +204,16 @@ def on_exportPushButton_clicked(self): # user cancelled return if exportPropertyList == []: - QMessageBox.warning(self, self.tr('Warning!'), self.tr('Warning! Select a profile to export!')) + QMessageBox.warning( + self, + self.tr("Warning!"), + self.tr("Warning! Select a profile to export!"), + ) return fd = QFileDialog() - folder = fd.getExistingDirectory(caption = self.tr('Select a folder to output')) + folder = fd.getExistingDirectory(caption=self.tr("Select a folder to output")) folder = folder[0] if isinstance(folder, tuple) else folder - if folder == '': + if folder == "": # QMessageBox.warning(self, self.tr('Warning!'), self.tr('Warning! Select a output!')) return edgvVersion = self.genericDbManager.edgvVersion @@ -173,55 +222,92 @@ def on_exportPushButton_clicked(self): for exportProperty in exportPropertyList: self.genericDbManager.exportSetting(exportProperty, edgvVersion, folder) QApplication.restoreOverrideCursor() - QMessageBox.information(self, self.tr('Success!'), self.widgetName + self.tr(' successfully exported.')) + QMessageBox.information( + self, + self.tr("Success!"), + self.widgetName + self.tr(" successfully exported."), + ) except Exception as e: QApplication.restoreOverrideCursor() - QMessageBox.critical(self, self.tr('Error!'), self.tr('Error! Problem exporting ') + self.widgetName + ': ' + ':'.join(e.args)) - + QMessageBox.critical( + self, + self.tr("Error!"), + self.tr("Error! Problem exporting ") + + self.widgetName + + ": " + + ":".join(e.args), + ) + @pyqtSlot(bool) def on_batchExportPushButton_clicked(self): """ Exports all configs from dsgtools_admindb. """ fd = QFileDialog() - folder = fd.getExistingDirectory(caption = self.tr('Select a folder to output')) + folder = fd.getExistingDirectory(caption=self.tr("Select a folder to output")) folder = folder[0] if isinstance(folder, tuple) else folder - if folder == '': + if folder == "": # QMessageBox.warning(self, self.tr('Warning!'), self.tr('Warning! Select a output!')) return try: QApplication.setOverrideCursor(QCursor(Qt.WaitCursor)) self.genericDbManager.batchExportSettings(folder) QApplication.restoreOverrideCursor() - QMessageBox.information(self, self.tr('Success!'), self.widgetName + self.tr(' successfully exported.')) + QMessageBox.information( + self, + self.tr("Success!"), + self.widgetName + self.tr(" successfully exported."), + ) except Exception as e: QApplication.restoreOverrideCursor() - QMessageBox.critical(self, self.tr('Error!'), self.tr('Error! Problem exporting ') + self.widgetName + ': ' + ':'.join(e.args)) - + QMessageBox.critical( + self, + self.tr("Error!"), + self.tr("Error! Problem exporting ") + + self.widgetName + + ": " + + ":".join(e.args), + ) + @pyqtSlot(bool) def on_batchImportPushButton_clicked(self): """ Imports all config files from a folder into dsgtools_admindb. It only works for a single type of config per time. """ fd = QFileDialog() - folder = fd.getExistingDirectory(caption = self.tr('Select a folder with json files: ')) - if folder == '': + folder = fd.getExistingDirectory( + caption=self.tr("Select a folder with json files: ") + ) + if folder == "": # QMessageBox.warning(self, self.tr('Warning!'), self.tr('Warning! Select a input folder!')) return try: QApplication.setOverrideCursor(QCursor(Qt.WaitCursor)) self.genericDbManager.batchImportSettings(folder) QApplication.restoreOverrideCursor() - QMessageBox.information(self, self.tr('Success!'), self.widgetName + self.tr(' successfully imported.')) + QMessageBox.information( + self, + self.tr("Success!"), + self.widgetName + self.tr(" successfully imported."), + ) except Exception as e: QApplication.restoreOverrideCursor() - QMessageBox.critical(self, self.tr('Error!'), self.tr('Error! Problem importing ') + self.widgetName + ': ' + ':'.join(e.args)) + QMessageBox.critical( + self, + self.tr("Error!"), + self.tr("Error! Problem importing ") + + self.widgetName + + ": " + + ":".join(e.args), + ) @pyqtSlot(bool) def on_applyPushButton_clicked(self): dbList = list(self.genericDbManager.dbDict.keys()) - successDict, exceptionDict = self.manageSettings(GenericManagerWidget.Install, dbList = dbList) - if successDict == {} and exceptionDict == {}: + successDict, exceptionDict = self.manageSettings( + GenericManagerWidget.Install, dbList=dbList + ) + if successDict == {} and exceptionDict == {}: return header, operation = self.getApplyHeader() self.outputMessage(operation, header, successDict, exceptionDict) @@ -229,7 +315,7 @@ def on_applyPushButton_clicked(self): @pyqtSlot(bool) def on_deletePushButton_clicked(self): successDict, exceptionDict = self.manageSettings(GenericManagerWidget.Delete) - if successDict == {} and exceptionDict == {}: + if successDict == {} and exceptionDict == {}: return header, operation = self.getDeleteHeader() self.outputMessage(operation, header, successDict, exceptionDict) @@ -237,8 +323,10 @@ def on_deletePushButton_clicked(self): @pyqtSlot(bool) def on_uninstallFromSelectedPushButton_clicked(self): dbList = [] - successDict, exceptionDict = self.manageSettings(GenericManagerWidget.Uninstall, dbList) - if successDict == {} and exceptionDict == {}: + successDict, exceptionDict = self.manageSettings( + GenericManagerWidget.Uninstall, dbList + ) + if successDict == {} and exceptionDict == {}: return header, operation = self.getUninstallFromSelected() self.outputMessage(operation, header, successDict, exceptionDict) @@ -249,11 +337,13 @@ def getViewType(self): else: return DsgEnums.Property - @pyqtSlot(bool, name='on_databasePerspectivePushButton_clicked') - @pyqtSlot(bool, name='on_propertyPerspectivePushButton_clicked') + @pyqtSlot(bool, name="on_databasePerspectivePushButton_clicked") + @pyqtSlot(bool, name="on_propertyPerspectivePushButton_clicked") def refresh(self): viewType = self.setHeaders() - propertyPerspectiveDict = self.genericDbManager.getPropertyPerspectiveDict(viewType) + propertyPerspectiveDict = self.genericDbManager.getPropertyPerspectiveDict( + viewType + ) self.treeWidget.clear() rootNode = self.treeWidget.invisibleRootItem() if viewType == DsgEnums.Database: @@ -264,13 +354,15 @@ def refresh(self): parentCustomItem = self.utils.createWidgetItem(rootNode, key, 0) if key in list(propertyPerspectiveDict.keys()): for item in propertyPerspectiveDict[key]: - if item and item != '': + if item and item != "": dbItem = self.utils.createWidgetItem(parentCustomItem, item, 1) self.treeWidget.sortItems(0, Qt.AscendingOrder) self.treeWidget.expandAll() - self.treeWidget.header().setSectionResizeMode(QtWidgets.QHeaderView.ResizeToContents) + self.treeWidget.header().setSectionResizeMode( + QtWidgets.QHeaderView.ResizeToContents + ) self.treeWidget.header().setStretchLastSection(False) - + def outputMessage(self, operation, header, successDict, exceptionDict): """ successDict = {configName: [--list of successful databases--]} @@ -281,48 +373,65 @@ def outputMessage(self, operation, header, successDict, exceptionDict): for setting in list(successDict.keys()): successList = successDict[setting] if len(successDict[setting]) > 0: - msg += self.tr('\nSuccessful ') - msg += operation + ' : ' + msg += self.tr("\nSuccessful ") + msg += operation + " : " msg += setting if successList: if len(successList) > 0: try: - msg += self.tr(' on databases ') + ', '.join(successList) - except: #none type case, just add . - msg += '.' + msg += self.tr(" on databases ") + ", ".join(successList) + except: # none type case, just add . + msg += "." msg += self.logInternalError(exceptionDict) - QMessageBox.warning(self, self.tr('Operation Complete!'), msg) - + QMessageBox.warning(self, self.tr("Operation Complete!"), msg) + def logInternalError(self, exceptionDict): """ exceptionDict = {configName: {dbName: errorText}} """ - msg = '' + msg = "" configList = list(exceptionDict.keys()) if len(configList) > 0: - msg += self.tr('\nConfig with error:') + ','.join(configList) - msg+= self.tr('\nError messages for each config and database were output in qgis log.') + msg += self.tr("\nConfig with error:") + ",".join(configList) + msg += self.tr( + "\nError messages for each config and database were output in qgis log." + ) for config in configList: for dbName in list(exceptionDict[config].keys()): if exceptionDict[config][dbName] != dict(): - QgsMessageLog.logMessage(self.tr('Error for config ')+ config + ' in database ' +dbName+' : '+exceptionDict[config][dbName], "DSGTools Plugin", Qgis.Critical) - return msg + QgsMessageLog.logMessage( + self.tr("Error for config ") + + config + + " in database " + + dbName + + " : " + + exceptionDict[config][dbName], + "DSGTools Plugin", + Qgis.Critical, + ) + return msg - def manageSetting(self, config, manageType, dbList = [], parameterDict = dict()): + def manageSetting(self, config, manageType, dbList=[], parameterDict=dict()): if manageType == GenericManagerWidget.Install: - return self.genericDbManager.installSetting(config, dbNameList = dbList) + return self.genericDbManager.installSetting(config, dbNameList=dbList) elif manageType == GenericManagerWidget.Delete: return self.genericDbManager.deleteSetting(config) elif manageType == GenericManagerWidget.Uninstall: - return self.genericDbManager.uninstallSetting(config, dbNameList = dbList) + return self.genericDbManager.uninstallSetting(config, dbNameList=dbList) elif manageType == GenericManagerWidget.Update: - return self.genericDbManager.updateSetting(config, parameterDict['newJsonDict']) + return self.genericDbManager.updateSetting( + config, parameterDict["newJsonDict"] + ) elif manageType == GenericManagerWidget.Create: - return self.genericDbManager.createSetting(config, parameterDict['newJsonDict']) - + return self.genericDbManager.createSetting( + config, parameterDict["newJsonDict"] + ) + def selectConfig(self): - availableConfig = list(self.genericDbManager.getPropertyPerspectiveDict().keys()) - dlg = ListSelector(availableConfig,[]) + availableConfig = list( + self.genericDbManager.getPropertyPerspectiveDict().keys() + ) + dlg = ListSelector(availableConfig, []) res = dlg.exec_() if res == 0: # to identify when user presses Cancel @@ -330,7 +439,9 @@ def selectConfig(self): selectedConfig = dlg.getSelected() return selectedConfig - def manageSettings(self, manageType, dbList=None, selectedConfig=None, parameterDict = dict()): + def manageSettings( + self, manageType, dbList=None, selectedConfig=None, parameterDict=dict() + ): """ Executes the setting work according to manageType successDict = {configName: [--list of successful databases--]} @@ -343,15 +454,21 @@ def manageSettings(self, manageType, dbList=None, selectedConfig=None, parameter # user cancelled return dict(), dict() if selectedConfig == []: - QMessageBox.warning(self, self.tr('Warning!'), self.tr('Select at least one configuration!')) - return (dict(),dict()) + QMessageBox.warning( + self, + self.tr("Warning!"), + self.tr("Select at least one configuration!"), + ) + return (dict(), dict()) successDict = dict() exceptionDict = dict() dbList = [] if dbList is None else dbList - if self.lookAndPromptForStructuralChanges(dbList = dbList): + if self.lookAndPromptForStructuralChanges(dbList=dbList): for config in selectedConfig: QApplication.setOverrideCursor(QCursor(Qt.WaitCursor)) - sucessList, errorDict = self.manageSetting(config, manageType, dbList = dbList, parameterDict = parameterDict) + sucessList, errorDict = self.manageSetting( + config, manageType, dbList=dbList, parameterDict=parameterDict + ) QApplication.restoreOverrideCursor() successDict[config] = sucessList if errorDict != dict(): @@ -359,9 +476,11 @@ def manageSettings(self, manageType, dbList=None, selectedConfig=None, parameter self.refresh() return successDict, exceptionDict else: - QMessageBox.warning(self, self.tr('Warning!'), self.tr('Operation canceled by user!')) - return (dict(),dict()) - + QMessageBox.warning( + self, self.tr("Warning!"), self.tr("Operation canceled by user!") + ) + return (dict(), dict()) + def createMenuAssigned(self, position): """ Creates a pop up menu @@ -376,31 +495,61 @@ def createDbPerspectiveContextMenu(self, position): menu = QMenu() item = self.treeWidget.itemAt(position) if item: - if item.text(0) != '': - menu.addAction(self.tr('Uninstall all settings from selected database'), self.uninstallSettings) - menu.addAction(self.tr('Manage settings from selected database'), self.manageDbSettings) - elif item.text(1) != '': - menu.addAction(self.tr('Update selected setting'), self.updateSelectedSetting) - menu.addAction(self.tr('Clone selected setting'), self.cloneSelectedSetting) - menu.addAction(self.tr('Uninstall selected setting'), self.uninstallSettings) - menu.addAction(self.tr('Delete selected setting'), self.deleteSelectedSetting) + if item.text(0) != "": + menu.addAction( + self.tr("Uninstall all settings from selected database"), + self.uninstallSettings, + ) + menu.addAction( + self.tr("Manage settings from selected database"), + self.manageDbSettings, + ) + elif item.text(1) != "": + menu.addAction( + self.tr("Update selected setting"), self.updateSelectedSetting + ) + menu.addAction( + self.tr("Clone selected setting"), self.cloneSelectedSetting + ) + menu.addAction( + self.tr("Uninstall selected setting"), self.uninstallSettings + ) + menu.addAction( + self.tr("Delete selected setting"), self.deleteSelectedSetting + ) menu.exec_(self.treeWidget.viewport().mapToGlobal(position)) - + def createPropertyPerspectiveContextMenu(self, position): menu = QMenu() item = self.treeWidget.itemAt(position) if item: - if item.text(0) != '': - menu.addAction(self.tr('Update selected setting'), self.updateSelectedSetting) - menu.addAction(self.tr('Clone selected setting'), self.cloneSelectedSetting) - menu.addAction(self.tr('Manage selected setting'), self.manageSelectedSetting) - menu.addAction(self.tr('Uninstall selected setting on all databases'), self.uninstallSettings) - menu.addAction(self.tr('Delete selected setting'), self.deleteSelectedSetting) - elif item.text(1) != '': - menu.addAction(self.tr('Manage Settings on database'), self.manageDbSettings) - menu.addAction(self.tr('Uninstall selected setting on selected database'), self.uninstallSettings) + if item.text(0) != "": + menu.addAction( + self.tr("Update selected setting"), self.updateSelectedSetting + ) + menu.addAction( + self.tr("Clone selected setting"), self.cloneSelectedSetting + ) + menu.addAction( + self.tr("Manage selected setting"), self.manageSelectedSetting + ) + menu.addAction( + self.tr("Uninstall selected setting on all databases"), + self.uninstallSettings, + ) + menu.addAction( + self.tr("Delete selected setting"), self.deleteSelectedSetting + ) + elif item.text(1) != "": + menu.addAction( + self.tr("Manage Settings on database"), self.manageDbSettings + ) + menu.addAction( + self.tr("Uninstall selected setting on selected database"), + self.uninstallSettings, + ) menu.exec_(self.treeWidget.viewport().mapToGlobal(position)) - + def manageDbSettings(self): """ 1. get installed profiles and available profiles @@ -409,25 +558,41 @@ def manageDbSettings(self): """ uiParameterDict = self.getParametersFromInterface() propertyPerspectiveDict = self.genericDbManager.getPropertyPerspectiveDict() - availableConfig = [i for i in list(propertyPerspectiveDict.keys()) if i not in uiParameterDict['parameterList']] - dlg = ListSelector(availableConfig,uiParameterDict['parameterList']) + availableConfig = [ + i + for i in list(propertyPerspectiveDict.keys()) + if i not in uiParameterDict["parameterList"] + ] + dlg = ListSelector(availableConfig, uiParameterDict["parameterList"]) dlg.exec_() fromLs, toLs = dlg.getInputAndOutputLists() - #build install list: elements from toLs that were not in uiParameterDict['parameterList'] - installList = [i for i in toLs if i not in uiParameterDict['parameterList']] - #build uninstall list: : elements fromLs that were not in availableConfig - uninstallList = [i for i in fromLs if i in uiParameterDict['parameterList']] - if (installList == [] and uninstallList == []): - QMessageBox.warning(self, self.tr('Error!'), self.tr('Select at least one configuration to manage!')) + # build install list: elements from toLs that were not in uiParameterDict['parameterList'] + installList = [i for i in toLs if i not in uiParameterDict["parameterList"]] + # build uninstall list: : elements fromLs that were not in availableConfig + uninstallList = [i for i in fromLs if i in uiParameterDict["parameterList"]] + if installList == [] and uninstallList == []: + QMessageBox.warning( + self, + self.tr("Error!"), + self.tr("Select at least one configuration to manage!"), + ) return if installList != []: - #install: - successDict, exceptionDict = self.manageSettings(GenericManagerWidget.Install, selectedConfig = installList, dbList = uiParameterDict['databaseList']) + # install: + successDict, exceptionDict = self.manageSettings( + GenericManagerWidget.Install, + selectedConfig=installList, + dbList=uiParameterDict["databaseList"], + ) header, operation = self.getApplyHeader() self.outputMessage(operation, header, successDict, exceptionDict) if uninstallList != []: - #uninstall: - successDict, exceptionDict = self.manageSettings(GenericManagerWidget.Uninstall, selectedConfig = uninstallList, dbList = uiParameterDict['databaseList']) + # uninstall: + successDict, exceptionDict = self.manageSettings( + GenericManagerWidget.Uninstall, + selectedConfig=uninstallList, + dbList=uiParameterDict["databaseList"], + ) header, operation = self.getUninstallSelectedSettingHeader() self.outputMessage(operation, header, successDict, exceptionDict) @@ -438,26 +603,44 @@ def manageSelectedSetting(self): 3. get final lists and uninstall items and them install items """ uiParameterDict = self.getParametersFromInterface() - propertyPerspectiveDict = self.genericDbManager.getPropertyPerspectiveDict(viewType = DsgEnums.Database) - availableDb = [i for i in list(propertyPerspectiveDict.keys()) if i not in uiParameterDict['databaseList']] - dlg = ListSelector(availableDb,uiParameterDict['databaseList']) + propertyPerspectiveDict = self.genericDbManager.getPropertyPerspectiveDict( + viewType=DsgEnums.Database + ) + availableDb = [ + i + for i in list(propertyPerspectiveDict.keys()) + if i not in uiParameterDict["databaseList"] + ] + dlg = ListSelector(availableDb, uiParameterDict["databaseList"]) dlg.exec_() fromLs, toLs = dlg.getInputAndOutputLists() - #build install list: elements from toLs that were not in uiParameterDict['parameterList'] - installList = [i for i in toLs if i not in uiParameterDict['databaseList']] - #build uninstall list: : elements fromLs that were not in availableConfig - uninstallList = [i for i in fromLs if i in uiParameterDict['databaseList']] - if (installList == [] and uninstallList == []): - QMessageBox.warning(self, self.tr('Error!'), self.tr('Select at least one configuration database to manage!')) + # build install list: elements from toLs that were not in uiParameterDict['parameterList'] + installList = [i for i in toLs if i not in uiParameterDict["databaseList"]] + # build uninstall list: : elements fromLs that were not in availableConfig + uninstallList = [i for i in fromLs if i in uiParameterDict["databaseList"]] + if installList == [] and uninstallList == []: + QMessageBox.warning( + self, + self.tr("Error!"), + self.tr("Select at least one configuration database to manage!"), + ) return if installList != []: - #install: - successDict, exceptionDict = self.manageSettings(GenericManagerWidget.Install, selectedConfig = uiParameterDict['parameterList'], dbList = installList) + # install: + successDict, exceptionDict = self.manageSettings( + GenericManagerWidget.Install, + selectedConfig=uiParameterDict["parameterList"], + dbList=installList, + ) header, operation = self.getApplyHeader() self.outputMessage(operation, header, successDict, exceptionDict) if uninstallList != []: - #uninstall: - successDict, exceptionDict = self.manageSettings(GenericManagerWidget.Uninstall, selectedConfig = uiParameterDict['parameterList'], dbList = uninstallList) + # uninstall: + successDict, exceptionDict = self.manageSettings( + GenericManagerWidget.Uninstall, + selectedConfig=uiParameterDict["parameterList"], + dbList=uninstallList, + ) header, operation = self.getUninstallSelectedSettingHeader() self.outputMessage(operation, header, successDict, exceptionDict) @@ -475,12 +658,16 @@ def updateSelectedSetting(self): edgvVersion = self.genericDbManager.edgvVersion templateDb = self.genericDbManager.instantiateTemplateDb(edgvVersion) originalDict = self.genericDbManager.getSetting(settingName, edgvVersion) - newDict = self.populateConfigInterface(templateDb, jsonDict = originalDict) + newDict = self.populateConfigInterface(templateDb, jsonDict=originalDict) if newDict: - successDict, exceptionDict = self.manageSettings(GenericManagerWidget.Update, selectedConfig = [settingName], parameterDict = {'newJsonDict':newDict}) + successDict, exceptionDict = self.manageSettings( + GenericManagerWidget.Update, + selectedConfig=[settingName], + parameterDict={"newJsonDict": newDict}, + ) header, operation = self.getUpdateSelectedSettingHeader() self.outputMessage(operation, header, successDict, exceptionDict) - + def cloneSelectedSetting(self): currItem = self.treeWidget.currentItem() if self.getViewType() == DsgEnums.Database: @@ -490,28 +677,32 @@ def cloneSelectedSetting(self): edgvVersion = self.genericDbManager.edgvVersion templateDb = self.genericDbManager.instantiateTemplateDb(edgvVersion) originalDict = self.genericDbManager.getSetting(settingName, edgvVersion) - newDict = self.populateConfigInterface(templateDb, jsonDict = originalDict) + newDict = self.populateConfigInterface(templateDb, jsonDict=originalDict) if newDict: - successDict, exceptionDict = self.manageSettings(GenericManagerWidget.Create, selectedConfig = [settingName], parameterDict = {'newJsonDict':newDict}) + successDict, exceptionDict = self.manageSettings( + GenericManagerWidget.Create, + selectedConfig=[settingName], + parameterDict={"newJsonDict": newDict}, + ) header, operation = self.getUpdateSelectedSettingHeader() self.outputMessage(operation, header, successDict, exceptionDict) def getParametersFromInterface(self): """ - Gets selected database and selected property. + Gets selected database and selected property. Returns {'databaseList':dbList, 'parameterList':parameterList} """ currItem = self.treeWidget.currentItem() if self.getViewType() == DsgEnums.Database: - #2 possibilities: leaf (if first column is '') or parent (if first column != '') - if currItem.text(0) == '': - #leaf -> must get + # 2 possibilities: leaf (if first column is '') or parent (if first column != '') + if currItem.text(0) == "": + # leaf -> must get parentNode = currItem.parent() dbName = parentNode.text(0) parameter = currItem.text(1) - return {'databaseList':[dbName], 'parameterList':[parameter]} + return {"databaseList": [dbName], "parameterList": [parameter]} else: - #parent + # parent dbName = currItem.text(0) childCount = currItem.childCount() parameterList = [] @@ -520,16 +711,16 @@ def getParametersFromInterface(self): parameterName = childNode.text(1) if parameterName not in parameterList: parameterList.append(parameterName) - return {'databaseList':[dbName], 'parameterList':parameterList} + return {"databaseList": [dbName], "parameterList": parameterList} else: - if currItem.text(0) == '': - #leaf + if currItem.text(0) == "": + # leaf parentNode = currItem.parent() parameter = parentNode.text(0) dbName = currItem.text(1) - return {'databaseList':[dbName], 'parameterList':[parameter]} + return {"databaseList": [dbName], "parameterList": [parameter]} else: - #parent + # parent parameter = currItem.text(0) childCount = currItem.childCount() dbList = [] @@ -538,33 +729,58 @@ def getParametersFromInterface(self): dbName = childNode.text(1) if dbName not in dbList: dbList.append(dbName) - return {'databaseList':dbList, 'parameterList':[parameter]} + return {"databaseList": dbList, "parameterList": [parameter]} def uninstallSettings(self): edgvVersion = self.genericDbManager.edgvVersion uiParameterDict = self.getParametersFromInterface() - successDict, exceptionDict = self.manageSettings(GenericManagerWidget.Uninstall, dbList = uiParameterDict['databaseList'], selectedConfig = uiParameterDict['parameterList']) + successDict, exceptionDict = self.manageSettings( + GenericManagerWidget.Uninstall, + dbList=uiParameterDict["databaseList"], + selectedConfig=uiParameterDict["parameterList"], + ) header, operation = self.getUninstallSelectedSettingHeader() self.outputMessage(operation, header, successDict, exceptionDict) - + def deleteSelectedSetting(self): edgvVersion = self.genericDbManager.edgvVersion uiParameterDict = self.getParametersFromInterface() - settingTextList = ', '.join(uiParameterDict['parameterList']) - if QMessageBox.question(self, self.tr('Question'), self.tr('Do you really want to delete ')+settingTextList+'?', QMessageBox.Ok|QMessageBox.Cancel) == QMessageBox.Cancel: + settingTextList = ", ".join(uiParameterDict["parameterList"]) + if ( + QMessageBox.question( + self, + self.tr("Question"), + self.tr("Do you really want to delete ") + settingTextList + "?", + QMessageBox.Ok | QMessageBox.Cancel, + ) + == QMessageBox.Cancel + ): return - successDict, exceptionDict = self.manageSettings(GenericManagerWidget.Delete, selectedConfig = uiParameterDict['parameterList']) + successDict, exceptionDict = self.manageSettings( + GenericManagerWidget.Delete, selectedConfig=uiParameterDict["parameterList"] + ) header, operation = self.getDeleteHeader() self.outputMessage(operation, header, successDict, exceptionDict) - - def lookAndPromptForStructuralChanges(self, dbList = []): - ''' + + def lookAndPromptForStructuralChanges(self, dbList=[]): + """ Returns True if user accepts the process - ''' + """ structuralChanges = self.genericDbManager.hasStructuralChanges(dbList) if structuralChanges != []: - dbChangeList = ', '.join(structuralChanges) - if QMessageBox.question(self, self.tr('Question'), self.tr('Do you really want to apply selected operation on ')+dbChangeList+'?'+self.tr(' (Data may be lost in the process)'), QMessageBox.Ok|QMessageBox.Cancel) == QMessageBox.Cancel: + dbChangeList = ", ".join(structuralChanges) + if ( + QMessageBox.question( + self, + self.tr("Question"), + self.tr("Do you really want to apply selected operation on ") + + dbChangeList + + "?" + + self.tr(" (Data may be lost in the process)"), + QMessageBox.Ok | QMessageBox.Cancel, + ) + == QMessageBox.Cancel + ): return False else: return True diff --git a/DsgTools/gui/CustomWidgets/DatabasePropertiesWidgets/BasicPropertyWidgets/genericParameterSetter.py b/DsgTools/gui/CustomWidgets/DatabasePropertiesWidgets/BasicPropertyWidgets/genericParameterSetter.py index 440809adf..1e55c3690 100644 --- a/DsgTools/gui/CustomWidgets/DatabasePropertiesWidgets/BasicPropertyWidgets/genericParameterSetter.py +++ b/DsgTools/gui/CustomWidgets/DatabasePropertiesWidgets/BasicPropertyWidgets/genericParameterSetter.py @@ -28,11 +28,13 @@ from qgis.PyQt.QtCore import pyqtSlot, pyqtSignal -FORM_CLASS, _ = uic.loadUiType(os.path.join( - os.path.dirname(__file__), 'genericParameterSetter.ui')) +FORM_CLASS, _ = uic.loadUiType( + os.path.join(os.path.dirname(__file__), "genericParameterSetter.ui") +) + class GenericParameterSetter(QtWidgets.QDialog, FORM_CLASS): - def __init__(self, parent = None, nameList = None, hideDbUi = False): + def __init__(self, parent=None, nameList=None, hideDbUi=False): """Constructor.""" super(self.__class__, self).__init__(parent) self.nameList = nameList @@ -42,12 +44,12 @@ def __init__(self, parent = None, nameList = None, hideDbUi = False): self.connectionWidget.hide() else: self.connectionWidget.tabWidget.removeTab(1) - regex = QtCore.QRegExp('[a-z][a-z\_0-9]*') + regex = QtCore.QRegExp("[a-z][a-z\_0-9]*") validator = QtGui.QRegExpValidator(regex, self.customNameLineEdit) self.customNameLineEdit.setValidator(validator) - + def validateUi(self): - if self.customNameLineEdit.text() == '': + if self.customNameLineEdit.text() == "": return False if self.nameList: if self.customNameLineEdit.text() in self.nameList: @@ -56,33 +58,39 @@ def validateUi(self): if self.connectionWidget.abstractDb == None: return False return True - + def validateUiReason(self): - validateReason = '' - if self.customNameLineEdit.text() == '': - validateReason += self.tr('Enter a parameter name!\n') + validateReason = "" + if self.customNameLineEdit.text() == "": + validateReason += self.tr("Enter a parameter name!\n") if self.nameList: if self.customNameLineEdit.text() in self.nameList: - validateReason += self.tr('Parameter already exists! Choose another name!\n') + validateReason += self.tr( + "Parameter already exists! Choose another name!\n" + ) if not self.isHidden: if self.connectionWidget.abstractDb == None: - validateReason += self.tr('Select a template database!\n') + validateReason += self.tr("Select a template database!\n") return validateReason - + @pyqtSlot(bool) def on_okPushButton_clicked(self): if not self.validateUi(): reason = self.validateUiReason() - QMessageBox.warning(self, self.tr('Warning!'), reason) + QMessageBox.warning(self, self.tr("Warning!"), reason) else: self.done(1) - + @pyqtSlot(bool) - def on_cancelPushButton_clicked(self): + def on_cancelPushButton_clicked(self): self.done(0) def getParameters(self): if self.isHidden: return self.customNameLineEdit.text() else: - return (self.connectionWidget.abstractDb , self.customNameLineEdit.text(), self.connectionWidget.abstractDb.getDatabaseVersion()) + return ( + self.connectionWidget.abstractDb, + self.customNameLineEdit.text(), + self.connectionWidget.abstractDb.getDatabaseVersion(), + ) diff --git a/DsgTools/gui/CustomWidgets/DatabasePropertiesWidgets/BasicPropertyWidgets/permissionWidget.py b/DsgTools/gui/CustomWidgets/DatabasePropertiesWidgets/BasicPropertyWidgets/permissionWidget.py index 38c38201f..21ca1ed66 100644 --- a/DsgTools/gui/CustomWidgets/DatabasePropertiesWidgets/BasicPropertyWidgets/permissionWidget.py +++ b/DsgTools/gui/CustomWidgets/DatabasePropertiesWidgets/BasicPropertyWidgets/permissionWidget.py @@ -25,23 +25,37 @@ from qgis.PyQt import QtWidgets, uic from qgis.PyQt.QtCore import pyqtSlot, pyqtSignal, Qt -from qgis.PyQt.QtWidgets import QTreeWidgetItem, QMessageBox, QMenu, QApplication, QFileDialog +from qgis.PyQt.QtWidgets import ( + QTreeWidgetItem, + QMessageBox, + QMenu, + QApplication, + QFileDialog, +) from qgis.PyQt.QtGui import QCursor from qgis.core import QgsMessageLog from DsgTools.core.Factories.DbFactory.abstractDb import AbstractDb -from DsgTools.gui.DatabaseTools.UserTools.permission_properties import PermissionProperties +from DsgTools.gui.DatabaseTools.UserTools.permission_properties import ( + PermissionProperties, +) from DsgTools.gui.DatabaseTools.UserTools.manageServerUsers import ManageServerUsers -from DsgTools.gui.DatabaseTools.UserTools.PermissionManagerWizard.permissionWizard import PermissionWizard +from DsgTools.gui.DatabaseTools.UserTools.PermissionManagerWizard.permissionWizard import ( + PermissionWizard, +) from DsgTools.gui.DatabaseTools.UserTools.profileUserManager import ProfileUserManager from DsgTools.gui.DatabaseTools.UserTools.dbProfileManager import DbProfileManager from DsgTools.core.ServerManagementTools.permissionManager import PermissionManager -from DsgTools.gui.DatabaseTools.UserTools.serverProfilesManager import ServerProfilesManager +from DsgTools.gui.DatabaseTools.UserTools.serverProfilesManager import ( + ServerProfilesManager, +) -FORM_CLASS, _ = uic.loadUiType(os.path.join( - os.path.dirname(__file__), 'permissionWidget.ui')) +FORM_CLASS, _ = uic.loadUiType( + os.path.join(os.path.dirname(__file__), "permissionWidget.ui") +) + class PermissionWidget(QtWidgets.QWidget, FORM_CLASS): def __init__(self, parent=None): @@ -57,11 +71,13 @@ def __init__(self, parent=None): self.dbDict = dict() self.permissionManager = None self.permissionTreeWidget.setContextMenuPolicy(Qt.CustomContextMenu) - self.permissionTreeWidget.customContextMenuRequested.connect(self.createMenuAssigned) + self.permissionTreeWidget.customContextMenuRequested.connect( + self.createMenuAssigned + ) # @pyqtSlot(bool, name='on_manageProfilesPushButton_clicked') - @pyqtSlot(bool, name='on_databasePerspectivePushButton_clicked') - @pyqtSlot(bool, name='on_userPerspectivePushButton_clicked') + @pyqtSlot(bool, name="on_databasePerspectivePushButton_clicked") + @pyqtSlot(bool, name="on_userPerspectivePushButton_clicked") def refresh(self): """ Refreshes permission table according to selected view type. @@ -69,14 +85,16 @@ def refresh(self): QApplication.setOverrideCursor(QCursor(Qt.WaitCursor)) viewType = self.getViewType() self.permissionTreeWidget.clear() - if viewType == 'database': + if viewType == "database": self.populateWithDatabasePerspective() - if viewType == 'user': + if viewType == "user": self.populateWithUserPerspective() QApplication.restoreOverrideCursor() - + def populateWithDatabasePerspective(self): - self.permissionTreeWidget.setHeaderLabels([self.tr('Database'), self.tr('Permission'), self.tr('User')]) + self.permissionTreeWidget.setHeaderLabels( + [self.tr("Database"), self.tr("Permission"), self.tr("User")] + ) dbPerspectiveDict = self.permissionManager.getDatabasePerspectiveDict() rootNode = self.permissionTreeWidget.invisibleRootItem() for dbName in list(dbPerspectiveDict.keys()): @@ -89,7 +107,9 @@ def populateWithDatabasePerspective(self): self.permissionTreeWidget.expandAll() def populateWithUserPerspective(self): - self.permissionTreeWidget.setHeaderLabels([self.tr('User'), self.tr('Database'), self.tr('Permission')]) + self.permissionTreeWidget.setHeaderLabels( + [self.tr("User"), self.tr("Database"), self.tr("Permission")] + ) userPerspectiveDict = self.permissionManager.getUserPerspectiveDict() rootNode = self.permissionTreeWidget.invisibleRootItem() for userName in list(userPerspectiveDict.keys()): @@ -100,22 +120,24 @@ def populateWithUserPerspective(self): permissionItem = self.createItem(dbItem, permission, 2) self.permissionTreeWidget.sortItems(0, Qt.AscendingOrder) self.permissionTreeWidget.expandAll() - + def createItem(self, parent, text, column): item = QtWidgets.QTreeWidgetItem(parent) item.setText(column, text) return item - + def getViewType(self): if self.databasePerspectivePushButton.isChecked(): - return 'database' + return "database" else: - return 'user' - + return "user" + def setParameters(self, serverAbstractDb, dbDict, edgvVersion): self.serverAbstractDb = serverAbstractDb self.dbDict = dbDict - self.permissionManager = PermissionManager(self.serverAbstractDb, self.dbDict, edgvVersion) + self.permissionManager = PermissionManager( + self.serverAbstractDb, self.dbDict, edgvVersion + ) self.refresh() @pyqtSlot(bool) @@ -124,9 +146,9 @@ def on_manageUsersPushButton_clicked(self): dlg = ManageServerUsers(self.serverAbstractDb) dlg.exec_() except: - QMessageBox.warning(self, self.tr('Error!'), self.tr('Select a server!')) + QMessageBox.warning(self, self.tr("Error!"), self.tr("Select a server!")) self.refresh() - + @pyqtSlot(bool) def on_manageProfilesPushButton_clicked(self): try: @@ -134,44 +156,53 @@ def on_manageProfilesPushButton_clicked(self): # dlg.profilesChanged.connect(self.refresh) dlg.exec_() except Exception as e: - QMessageBox.warning(self, self.tr('Error!'), ':'.join(e.args)) + QMessageBox.warning(self, self.tr("Error!"), ":".join(e.args)) self.refresh() - + def createMenuAssigned(self, position): """ Creates a pop up menu """ viewType = self.getViewType() - if viewType == 'database': + if viewType == "database": self.createDbPerspectiveContextMenu(position) - if viewType == 'user': + if viewType == "user": self.createUserPerspectiveContextMenu(position) - - + def createDbPerspectiveContextMenu(self, position): menu = QMenu() item = self.permissionTreeWidget.itemAt(position) if item: - if item.text(0) != '': - menu.addAction(self.tr('Revoke all permissions'), self.revokeAll) - elif item.text(1) != '': - menu.addAction(self.tr('Manage User Permissions'), self.manageUserPermissions) - elif item.text(2) != '': - menu.addAction(self.tr('Revoke User'), self.revokeSelectedUser) + if item.text(0) != "": + menu.addAction(self.tr("Revoke all permissions"), self.revokeAll) + elif item.text(1) != "": + menu.addAction( + self.tr("Manage User Permissions"), self.manageUserPermissions + ) + elif item.text(2) != "": + menu.addAction(self.tr("Revoke User"), self.revokeSelectedUser) menu.exec_(self.permissionTreeWidget.viewport().mapToGlobal(position)) - + def createUserPerspectiveContextMenu(self, position): menu = QMenu() item = self.permissionTreeWidget.itemAt(position) if item: - if item.text(0) != '': - menu.addAction(self.tr('Revoke permissions on all granted databases'), self.revokeAllDbs) - elif item.text(1) != '': - menu.addAction(self.tr('Manage Permissions on database'), self.managePermissionsOnDb) - elif item.text(2) != '': - menu.addAction(self.tr('Revoke Permission'), self.revokeSelectedPermission) + if item.text(0) != "": + menu.addAction( + self.tr("Revoke permissions on all granted databases"), + self.revokeAllDbs, + ) + elif item.text(1) != "": + menu.addAction( + self.tr("Manage Permissions on database"), + self.managePermissionsOnDb, + ) + elif item.text(2) != "": + menu.addAction( + self.tr("Revoke Permission"), self.revokeSelectedPermission + ) menu.exec_(self.permissionTreeWidget.viewport().mapToGlobal(position)) - + def manageUserPermissions(self): currItem = self.permissionTreeWidget.currentItem() profileName = currItem.text(1) @@ -184,12 +215,19 @@ def manageUserPermissions(self): notGrantedUserList = [i[0] for i in userList if i[0] not in grantedUserList] edgvVersion = self.dbDict[dbName].getDatabaseVersion() try: - dlg = ProfileUserManager(grantedUserList, notGrantedUserList, self.permissionManager, profileName, dbName, edgvVersion) + dlg = ProfileUserManager( + grantedUserList, + notGrantedUserList, + self.permissionManager, + profileName, + dbName, + edgvVersion, + ) dlg.exec_() except: pass self.refresh() - + def revokeSelectedUser(self): userName = self.permissionTreeWidget.currentItem().text(2) permissionName = self.permissionTreeWidget.currentItem().parent().text(1) @@ -198,10 +236,20 @@ def revokeSelectedUser(self): QApplication.setOverrideCursor(QCursor(Qt.WaitCursor)) self.permissionManager.revokePermission(dbName, permissionName, userName) QApplication.restoreOverrideCursor() - QMessageBox.warning(self, self.tr('Revoke Complete!'), self.tr('Revoke for user ') + userName + self.tr(' on profile ') + permissionName + self.tr(' of database ') + dbName + self.tr(' complete.')) + QMessageBox.warning( + self, + self.tr("Revoke Complete!"), + self.tr("Revoke for user ") + + userName + + self.tr(" on profile ") + + permissionName + + self.tr(" of database ") + + dbName + + self.tr(" complete."), + ) except Exception as e: QApplication.restoreOverrideCursor() - QMessageBox.warning(self, self.tr('Error!'), ':'.join(e.args)) + QMessageBox.warning(self, self.tr("Error!"), ":".join(e.args)) self.refresh() def revokeAll(self): @@ -214,9 +262,11 @@ def revokeAll(self): userCount = permissionNode.childCount() for j in range(userCount): userName = permissionNode.child(j).text(2) - self.permissionManager.revokePermission(dbName, permissionName, userName) + self.permissionManager.revokePermission( + dbName, permissionName, userName + ) self.refresh() - + def revokeAllDbs(self): currItem = self.permissionTreeWidget.currentItem() userName = currItem.text(0) @@ -227,9 +277,11 @@ def revokeAllDbs(self): permissionCount = dbNode.childCount() for j in range(permissionCount): permissionName = dbNode.child(j).text(2) - self.permissionManager.revokePermission(dbName, permissionName, userName) + self.permissionManager.revokePermission( + dbName, permissionName, userName + ) self.refresh() - + def managePermissionsOnDb(self): currItem = self.permissionTreeWidget.currentItem() dbName = currItem.text(1) @@ -240,14 +292,23 @@ def managePermissionsOnDb(self): grantedProfileList.append(currItem.child(i).text(2)) profileDict = self.permissionManager.getSettings() edgvVersion = self.dbDict[dbName].getDatabaseVersion() - notGrantedProfileList = [i for i in profileDict[edgvVersion] if i not in grantedProfileList] + notGrantedProfileList = [ + i for i in profileDict[edgvVersion] if i not in grantedProfileList + ] try: - dlg = DbProfileManager(grantedProfileList, notGrantedProfileList, self.permissionManager, userName, dbName, edgvVersion) + dlg = DbProfileManager( + grantedProfileList, + notGrantedProfileList, + self.permissionManager, + userName, + dbName, + edgvVersion, + ) dlg.exec_() except: pass self.refresh() - + def revokeSelectedPermission(self): permissionName = self.permissionTreeWidget.currentItem().text(2) dbName = self.permissionTreeWidget.currentItem().parent().text(1) @@ -256,39 +317,63 @@ def revokeSelectedPermission(self): QApplication.setOverrideCursor(QCursor(Qt.WaitCursor)) self.permissionManager.revokePermission(dbName, permissionName, userName) QApplication.restoreOverrideCursor() - QMessageBox.warning(self, self.tr('Revoke Complete!'), self.tr('Revoke for user ') + userName + self.tr(' on profile ') + permissionName + self.tr(' of database ') + dbName + self.tr(' complete.')) + QMessageBox.warning( + self, + self.tr("Revoke Complete!"), + self.tr("Revoke for user ") + + userName + + self.tr(" on profile ") + + permissionName + + self.tr(" of database ") + + dbName + + self.tr(" complete."), + ) except Exception as e: QApplication.restoreOverrideCursor() - QMessageBox.warning(self, self.tr('Error!'), ':'.join(e.args)) + QMessageBox.warning(self, self.tr("Error!"), ":".join(e.args)) self.refresh() @pyqtSlot(bool) def on_importPushButton_clicked(self): fd = QFileDialog() - filename = fd.getOpenFileName(caption=self.tr('Select a dsgtools profile'),filter=self.tr('json file (*.json)')) + filename = fd.getOpenFileName( + caption=self.tr("Select a dsgtools profile"), + filter=self.tr("json file (*.json)"), + ) filename = filename[0] if isinstance(filename, tuple) else filename - if filename == '': + if filename == "": # QMessageBox.warning(self, self.tr('Warning!'), self.tr('Error! Select a file to import!')) return try: QApplication.setOverrideCursor(QCursor(Qt.WaitCursor)) self.permissionManager.importSetting(filename) QApplication.restoreOverrideCursor() - QMessageBox.warning(self, self.tr('Success!'), self.tr('Permission successfully imported.')) + QMessageBox.warning( + self, self.tr("Success!"), self.tr("Permission successfully imported.") + ) except Exception as e: QApplication.restoreOverrideCursor() - QMessageBox.warning(self, self.tr('Warning!'), self.tr('Error! Problem importing permission: ') + ':'.join(e.args)) + QMessageBox.warning( + self, + self.tr("Warning!"), + self.tr("Error! Problem importing permission: ") + ":".join(e.args), + ) # self.refreshProfileList() - + @pyqtSlot(bool) def on_exportPushButton_clicked(self): - if not self.permissionTreeWidget.currentItem() or (self.permissionTreeWidget.currentItem().text(0) != '' or self.permissionTreeWidget.currentItem().text(2) != ''): - QMessageBox.warning(self, self.tr('Warning!'), self.tr('Error! Select a profile to export!')) + if not self.permissionTreeWidget.currentItem() or ( + self.permissionTreeWidget.currentItem().text(0) != "" + or self.permissionTreeWidget.currentItem().text(2) != "" + ): + QMessageBox.warning( + self, self.tr("Warning!"), self.tr("Error! Select a profile to export!") + ) return fd = QFileDialog() - folder = fd.getExistingDirectory(caption = self.tr('Select a folder to output')) - if folder == '': + folder = fd.getExistingDirectory(caption=self.tr("Select a folder to output")) + if folder == "": # QMessageBox.warning(self, self.tr('Warning!'), self.tr('Error! Select a output!')) return profileName = self.permissionTreeWidget.currentItem().text(1) @@ -298,39 +383,59 @@ def on_exportPushButton_clicked(self): QApplication.setOverrideCursor(QCursor(Qt.WaitCursor)) self.permissionManager.exportSetting(profileName, edgvVersion, folder) QApplication.restoreOverrideCursor() - QMessageBox.warning(self, self.tr('Success!'), self.tr('Permission successfully exported.')) + QMessageBox.warning( + self, self.tr("Success!"), self.tr("Permission successfully exported.") + ) except Exception as e: QApplication.restoreOverrideCursor() - QMessageBox.warning(self, self.tr('Warning!'), self.tr('Error! Problem exporting permission: ') + ':'.join(e.args)) - + QMessageBox.warning( + self, + self.tr("Warning!"), + self.tr("Error! Problem exporting permission: ") + ":".join(e.args), + ) + @pyqtSlot(bool) def on_batchExportPushButton_clicked(self): fd = QFileDialog() - folder = fd.getExistingDirectory(caption = self.tr('Select a folder to output')) - if folder == '': + folder = fd.getExistingDirectory(caption=self.tr("Select a folder to output")) + if folder == "": # QMessageBox.warning(self, self.tr('Warning!'), self.tr('Error! Select a output!')) return try: QApplication.setOverrideCursor(QCursor(Qt.WaitCursor)) self.permissionManager.batchExportSettings(folder) QApplication.restoreOverrideCursor() - QMessageBox.warning(self, self.tr('Success!'), self.tr('Permissions successfully exported.')) + QMessageBox.warning( + self, self.tr("Success!"), self.tr("Permissions successfully exported.") + ) except Exception as e: QApplication.restoreOverrideCursor() - QMessageBox.warning(self, self.tr('Warning!'), self.tr('Error! Problem exporting permission: ') + ':'.join(e.args)) - + QMessageBox.warning( + self, + self.tr("Warning!"), + self.tr("Error! Problem exporting permission: ") + ":".join(e.args), + ) + @pyqtSlot(bool) def on_batchImportPushButton_clicked(self): fd = QFileDialog() - folder = fd.getExistingDirectory(caption = self.tr('Select a folder with permissions: ')) - if folder == '': + folder = fd.getExistingDirectory( + caption=self.tr("Select a folder with permissions: ") + ) + if folder == "": # QMessageBox.warning(self, self.tr('Warning!'), self.tr('Error! Select a input folder!')) return try: QApplication.setOverrideCursor(QCursor(Qt.WaitCursor)) self.permissionManager.batchImportSettings(folder) QApplication.restoreOverrideCursor() - QMessageBox.warning(self, self.tr('Success!'), self.tr('Permissions successfully imported.')) + QMessageBox.warning( + self, self.tr("Success!"), self.tr("Permissions successfully imported.") + ) except Exception as e: QApplication.restoreOverrideCursor() - QMessageBox.warning(self, self.tr('Warning!'), self.tr('Error! Problem importing permission: ') + ':'.join(e.args)) + QMessageBox.warning( + self, + self.tr("Warning!"), + self.tr("Error! Problem importing permission: ") + ":".join(e.args), + ) diff --git a/DsgTools/gui/CustomWidgets/DatabasePropertiesWidgets/BasicPropertyWidgets/setupEarthCoverage.py b/DsgTools/gui/CustomWidgets/DatabasePropertiesWidgets/BasicPropertyWidgets/setupEarthCoverage.py index 6523070e7..a1f2218c8 100644 --- a/DsgTools/gui/CustomWidgets/DatabasePropertiesWidgets/BasicPropertyWidgets/setupEarthCoverage.py +++ b/DsgTools/gui/CustomWidgets/DatabasePropertiesWidgets/BasicPropertyWidgets/setupEarthCoverage.py @@ -29,12 +29,26 @@ from qgis.PyQt.QtWidgets import QMessageBox, QFileDialog from DsgTools.core.Utils.utils import Utils -FORM_CLASS, _ = uic.loadUiType(os.path.join( - os.path.dirname(__file__), 'setupEarthCoverage.ui')) +FORM_CLASS, _ = uic.loadUiType( + os.path.join(os.path.dirname(__file__), "setupEarthCoverage.ui") +) + class SetupEarthCoverage(QtWidgets.QWizard, FORM_CLASS): coverageChanged = pyqtSignal() - def __init__(self, edgvVersion, areas, lines, oldCoverage, propertyList, enableSetupFromFile = True, onlySetup = False, propertyName = None, parent=None): + + def __init__( + self, + edgvVersion, + areas, + lines, + oldCoverage, + propertyList, + enableSetupFromFile=True, + onlySetup=False, + propertyName=None, + parent=None, + ): """ Constructor """ @@ -45,8 +59,8 @@ def __init__(self, edgvVersion, areas, lines, oldCoverage, propertyList, enableS self.lines = lines self.propertyName = propertyName self.edgvVersion = edgvVersion - self.areasCustomSelector.setTitle(self.tr('Areas')) - self.linesCustomSelector.setTitle(self.tr('Lines')) + self.areasCustomSelector.setTitle(self.tr("Areas")) + self.linesCustomSelector.setTitle(self.tr("Lines")) self.propertyList = propertyList self.button(QtWidgets.QWizard.NextButton).clicked.connect(self.buildTree) self.button(QtWidgets.QWizard.FinishButton).clicked.connect(self.buildDict) @@ -57,9 +71,22 @@ def setupFromFile(self): """ Opens a earth coverage file """ - if QMessageBox.question(self, self.tr('Question'), self.tr('Do you want to open an earth coverage file?'), QMessageBox.Ok|QMessageBox.Cancel) == QMessageBox.Cancel: + if ( + QMessageBox.question( + self, + self.tr("Question"), + self.tr("Do you want to open an earth coverage file?"), + QMessageBox.Ok | QMessageBox.Cancel, + ) + == QMessageBox.Cancel + ): return - filename, __ = QFileDialog.getOpenFileName(self, self.tr('Open Earth Coverage Setup configuration'), '', self.tr('Earth Coverage Files (*.json)')) + filename, __ = QFileDialog.getOpenFileName( + self, + self.tr("Open Earth Coverage Setup configuration"), + "", + self.tr("Earth Coverage Files (*.json)"), + ) return filename def setupWizard(self, oldCoverage, enableSetupFromFile): @@ -85,12 +112,12 @@ def setupWizard(self, oldCoverage, enableSetupFromFile): if self.propertyName: self.nameLineEdit.setText(self.propertyName) self.nameLineEdit.setEnabled(False) - + def setupUiFromFile(self, filename): """ Populates ui from parameters of json """ - #read json + # read json jsonDict = self.utils.readJsonFile(filename) self.setupUiFromDict(jsonDict) @@ -98,19 +125,21 @@ def setupUiFromDict(self, jsonDict): """ Populates ui from parameters of json """ - #set nameLineEdit - self.nameLineEdit.setText(jsonDict['configName']) - #populate listWidget - self.populateFrameListWidget(self.areas, frame = jsonDict['frameLayer']) - linesFromList, linesToList, areasFromList, areasToList = self.populateLists(jsonDict['earthCoverageDict']) + # set nameLineEdit + self.nameLineEdit.setText(jsonDict["configName"]) + # populate listWidget + self.populateFrameListWidget(self.areas, frame=jsonDict["frameLayer"]) + linesFromList, linesToList, areasFromList, areasToList = self.populateLists( + jsonDict["earthCoverageDict"] + ) self.areasCustomSelector.setToList(areasToList) self.areasCustomSelector.setFromList(areasFromList) self.linesCustomSelector.setToList(linesToList) self.linesCustomSelector.setFromList(linesFromList) self.buildTree() - self.checkDelimiters(jsonDict['earthCoverageDict']) - - def populateFrameListWidget(self, areas, frame = None): + self.checkDelimiters(jsonDict["earthCoverageDict"]) + + def populateFrameListWidget(self, areas, frame=None): areas.sort() self.listWidget.clear() self.listWidget.addItems(areas) @@ -120,7 +149,7 @@ def populateFrameListWidget(self, areas, frame = None): self.listWidget.setCurrentItem(frameItem) except: pass - + def populateLists(self, setupDict): areasToList = list(setupDict.keys()) linesToList = [] @@ -143,13 +172,18 @@ def checkDelimiters(self, setupDict): delimiterItem = areaItem.child(j) if areaItem.text(0) in list(setupDict.keys()): if delimiterItem.text(1) not in setupDict[areaItem.text(0)]: - delimiterItem.setCheckState(1,Qt.Unchecked) + delimiterItem.setCheckState(1, Qt.Unchecked) def loadJson(self, filename): """ Loads a json file """ - filename, __ = QFileDialog.getOpenFileName(self, self.tr('Open Field Setup configuration'), self.folder, self.tr('Earth Coverage Setup File (*.dsgearthcov)')) + filename, __ = QFileDialog.getOpenFileName( + self, + self.tr("Open Field Setup configuration"), + self.folder, + self.tr("Earth Coverage Setup File (*.dsgearthcov)"), + ) if not filename: return return self.readJsonFile(filename) @@ -162,8 +196,8 @@ def populateClasses(self): selectedAreaClasses = self.areasCustomSelector.toLs for i in range(len(selectedAreaClasses)): treeItem = QtWidgets.QTreeWidgetItem() - treeItem.setText(0,selectedAreaClasses[i]) - self.treeWidget.insertTopLevelItem(0,treeItem) + treeItem.setText(0, selectedAreaClasses[i]) + self.treeWidget.insertTopLevelItem(0, treeItem) def populateDelimiters(self): """ @@ -174,10 +208,12 @@ def populateDelimiters(self): delimiterList.append(self.linesCustomSelector.toList.item(i).text()) for i in range(self.treeWidget.invisibleRootItem().childCount()): for delimiter in delimiterList: - treeItem = QtWidgets.QTreeWidgetItem(self.treeWidget.invisibleRootItem().child(i)) - treeItem.setText(1,delimiter) + treeItem = QtWidgets.QTreeWidgetItem( + self.treeWidget.invisibleRootItem().child(i) + ) + treeItem.setText(1, delimiter) treeItem.setFlags(Qt.ItemIsUserCheckable | Qt.ItemIsEnabled) - treeItem.setCheckState(1,Qt.Checked) + treeItem.setCheckState(1, Qt.Checked) self.treeWidget.invisibleRootItem().child(i).setExpanded(True) def getEarthCoverageDictFromTree(self): @@ -191,17 +227,19 @@ def getEarthCoverageDictFromTree(self): earthCoverageDict[childClass.text(0)] = [] for j in range(childClass.childCount()): if childClass.child(j).checkState(1) == Qt.Checked: - earthCoverageDict[childClass.text(0)].append(childClass.child(j).text(1)) + earthCoverageDict[childClass.text(0)].append( + childClass.child(j).text(1) + ) return earthCoverageDict - + def buildDict(self): - ''' + """ Gets earth coverage dict from interface - ''' - self.configDict['edgvVersion'] = self.edgvVersion - self.configDict['configName'] = self.nameLineEdit.text() - self.configDict['frameLayer'] = self.listWidget.currentItem().text() - self.configDict['earthCoverageDict'] = self.getEarthCoverageDictFromTree() + """ + self.configDict["edgvVersion"] = self.edgvVersion + self.configDict["configName"] = self.nameLineEdit.text() + self.configDict["frameLayer"] = self.listWidget.currentItem().text() + self.configDict["earthCoverageDict"] = self.getEarthCoverageDictFromTree() def buildTree(self): """ @@ -210,9 +248,11 @@ def buildTree(self): self.populateClasses() self.populateDelimiters() self.treeWidget.expandAll() - self.treeWidget.header().setSectionResizeMode(QtWidgets.QHeaderView.ResizeToContents) + self.treeWidget.header().setSectionResizeMode( + QtWidgets.QHeaderView.ResizeToContents + ) self.treeWidget.header().setStretchLastSection(False) - + def on_filterLineEdit_textChanged(self, text): """ Filters the items to make it easier to spot and select them @@ -221,7 +261,7 @@ def on_filterLineEdit_textChanged(self, text): self.listWidget.clear() self.listWidget.addItems(classes) self.listWidget.sortItems() - + def validateEarthCoverageTreeWidget(self): rootNode = self.treeWidget.invisibleRootItem() childCount = rootNode.childCount() @@ -240,38 +280,42 @@ def validateEarthCoverageTreeWidget(self): def validateCurrentPage(self): if self.currentId() == 0: - errorMsg = '' + errorMsg = "" isValidated = True - if self.nameLineEdit.text() == '': - errorMsg += self.tr('An Earth Coverage name must be set.\n') + if self.nameLineEdit.text() == "": + errorMsg += self.tr("An Earth Coverage name must be set.\n") isValidated = False if self.nameLineEdit.text() in self.propertyList: - errorMsg += self.tr('An Earth Coverage with this name already exists.\n') + errorMsg += self.tr( + "An Earth Coverage with this name already exists.\n" + ) isValidated = False if self.listWidget.currentRow() == -1: - errorMsg += self.tr('A frame layer must be chosen.\n') + errorMsg += self.tr("A frame layer must be chosen.\n") isValidated = False if not isValidated: - QMessageBox.warning(self, self.tr('Error!'), errorMsg) + QMessageBox.warning(self, self.tr("Error!"), errorMsg) return isValidated elif self.currentId() == 1: if self.areasCustomSelector.toLs == []: - errorMsg = self.tr('Areas must be chosen for Earth Coverage.\n') - QMessageBox.warning(self, self.tr('Error!'), errorMsg) + errorMsg = self.tr("Areas must be chosen for Earth Coverage.\n") + QMessageBox.warning(self, self.tr("Error!"), errorMsg) return False return True elif self.currentId() == 2: if self.linesCustomSelector.toLs == []: - errorMsg = self.tr('Lines must be chosen for Earth Coverage.\n') - QMessageBox.warning(self, self.tr('Error!'), errorMsg) + errorMsg = self.tr("Lines must be chosen for Earth Coverage.\n") + QMessageBox.warning(self, self.tr("Error!"), errorMsg) return False return True elif self.currentId() == 3: - #at least one line selected for each area + # at least one line selected for each area if not self.validateEarthCoverageTreeWidget(): - errorMsg = self.tr('At least one line must be chosen for each Earth Coverage area.\n') - QMessageBox.warning(self, self.tr('Error!'), errorMsg) + errorMsg = self.tr( + "At least one line must be chosen for each Earth Coverage area.\n" + ) + QMessageBox.warning(self, self.tr("Error!"), errorMsg) return False return True else: - return True \ No newline at end of file + return True diff --git a/DsgTools/gui/CustomWidgets/DatabasePropertiesWidgets/BasicPropertyWidgets/setupEarthCoverage.ui b/DsgTools/gui/CustomWidgets/DatabasePropertiesWidgets/BasicPropertyWidgets/setupEarthCoverage.ui index b0d50ff32..ad2e60c3d 100644 --- a/DsgTools/gui/CustomWidgets/DatabasePropertiesWidgets/BasicPropertyWidgets/setupEarthCoverage.ui +++ b/DsgTools/gui/CustomWidgets/DatabasePropertiesWidgets/BasicPropertyWidgets/setupEarthCoverage.ui @@ -91,7 +91,7 @@ - 4- Choose the line classes that, along with the frame, build the areas of earth coverage + 4- Choose the line classes that, along with the frame, build the areas of earth coverage (only parent classes are listed here). @@ -106,7 +106,7 @@ - 5- For each area class of earth coverage, define which lines are used to build it + 5- For each area class of earth coverage, define which lines are used to build it (note that frame is always used to close areas) diff --git a/DsgTools/gui/CustomWidgets/DatabasePropertiesWidgets/BasicPropertyWidgets/styleManagerWidget.py b/DsgTools/gui/CustomWidgets/DatabasePropertiesWidgets/BasicPropertyWidgets/styleManagerWidget.py index 6c7b23a72..9eb76b26b 100644 --- a/DsgTools/gui/CustomWidgets/DatabasePropertiesWidgets/BasicPropertyWidgets/styleManagerWidget.py +++ b/DsgTools/gui/CustomWidgets/DatabasePropertiesWidgets/BasicPropertyWidgets/styleManagerWidget.py @@ -28,24 +28,29 @@ from qgis.PyQt.QtWidgets import QMessageBox, QApplication, QFileDialog from qgis.PyQt.QtGui import QCursor -#DsgTools imports +# DsgTools imports from DsgTools.core.ServerManagementTools.styleManager import StyleManager -from DsgTools.gui.CustomWidgets.DatabasePropertiesWidgets.BasicPropertyWidgets.genericParameterSetter import GenericParameterSetter -from DsgTools.gui.CustomWidgets.DatabasePropertiesWidgets.BasicPropertyWidgets.genericManagerWidget import GenericManagerWidget +from DsgTools.gui.CustomWidgets.DatabasePropertiesWidgets.BasicPropertyWidgets.genericParameterSetter import ( + GenericParameterSetter, +) +from DsgTools.gui.CustomWidgets.DatabasePropertiesWidgets.BasicPropertyWidgets.genericManagerWidget import ( + GenericManagerWidget, +) from DsgTools.core.Utils.utils import Utils from DsgTools.core.dsgEnums import DsgEnums from qgis.core import QgsMessageLog import json + class StyleManagerWidget(GenericManagerWidget): - def __init__(self, manager = None, parent = None): + def __init__(self, manager=None, parent=None): """ Constructor """ - super(self.__class__, self).__init__(genericDbManager = manager, parent = parent) + super(self.__class__, self).__init__(genericDbManager=manager, parent=parent) - def setParameters(self, serverAbstractDb, edgvVersion, dbsDict = {}): + def setParameters(self, serverAbstractDb, edgvVersion, dbsDict={}): if serverAbstractDb: self.setComponentsEnabled(True) self.serverAbstractDb = serverAbstractDb @@ -59,37 +64,37 @@ def on_createPushButton_clicked(self): """ Slot that opens the create profile dialog """ - #TODO - pass - - def populateConfigInterface(self, templateDb, jsonDict = None): - ''' + # TODO + pass + + def populateConfigInterface(self, templateDb, jsonDict=None): + """ Must be reimplemented in each child - ''' - #TODO + """ + # TODO pass - + def getUpdateSelectedSettingHeader(self): - header = self.tr('Update Style configuration complete. \n') - operation = self.tr('style configuration') + header = self.tr("Update Style configuration complete. \n") + operation = self.tr("style configuration") return header, operation def getUninstallSelectedSettingHeader(self): - header = self.tr('Uninstall Style configuration complete. \n') - operation = self.tr('style configuration') + header = self.tr("Uninstall Style configuration complete. \n") + operation = self.tr("style configuration") return header, operation def getApplyHeader(self): - header = self.tr('Install Style configuration complete. \n') - operation = self.tr('style configurations') + header = self.tr("Install Style configuration complete. \n") + operation = self.tr("style configurations") return header, operation - + def getDeleteHeader(self): - header = self.tr('Delete Style configuration complete. \n') - operation = self.tr('style configurations') + header = self.tr("Delete Style configuration complete. \n") + operation = self.tr("style configurations") return header, operation - + def getUninstallFromSelected(self): - header = self.tr('Uninstall Style configuration complete. \n') - operation = self.tr('style configurations') - return header, operation \ No newline at end of file + header = self.tr("Uninstall Style configuration complete. \n") + operation = self.tr("style configurations") + return header, operation diff --git a/DsgTools/gui/CustomWidgets/DatabasePropertiesWidgets/CompactPropertyWidgets/attributeRulesCompactPropertyManagerWidget.py b/DsgTools/gui/CustomWidgets/DatabasePropertiesWidgets/CompactPropertyWidgets/attributeRulesCompactPropertyManagerWidget.py index 2160156ef..689fff02d 100644 --- a/DsgTools/gui/CustomWidgets/DatabasePropertiesWidgets/CompactPropertyWidgets/attributeRulesCompactPropertyManagerWidget.py +++ b/DsgTools/gui/CustomWidgets/DatabasePropertiesWidgets/CompactPropertyWidgets/attributeRulesCompactPropertyManagerWidget.py @@ -28,32 +28,39 @@ from qgis.PyQt.QtWidgets import QMessageBox, QApplication, QFileDialog from qgis.PyQt.QtGui import QCursor -#DsgTools imports -from DsgTools.core.ServerManagementTools.attributeRulesManager import AttributeRulesManager -from DsgTools.gui.CustomWidgets.DatabasePropertiesWidgets.CompactPropertyWidgets.genericCompactPropertyManagerWidget import GenericCompactPropertyManagerWidget -from DsgTools.gui.ProductionTools.Toolboxes.ValidationToolbox.attributeRulesEditor import AttributeRulesEditor +# DsgTools imports +from DsgTools.core.ServerManagementTools.attributeRulesManager import ( + AttributeRulesManager, +) +from DsgTools.gui.CustomWidgets.DatabasePropertiesWidgets.CompactPropertyWidgets.genericCompactPropertyManagerWidget import ( + GenericCompactPropertyManagerWidget, +) +from DsgTools.gui.ProductionTools.Toolboxes.ValidationToolbox.attributeRulesEditor import ( + AttributeRulesEditor, +) from DsgTools.core.Utils.utils import Utils from DsgTools.core.dsgEnums import DsgEnums from qgis.core import QgsMessageLog import json + class AttributeRulesCompactPropertyManagerWidget(GenericCompactPropertyManagerWidget): - def __init__(self, manager = None, parent = None): + def __init__(self, manager=None, parent=None): """ Constructor """ - super(AttributeRulesCompactPropertyManagerWidget, self).__init__(parent = parent) - - def populateConfigInterface(self, templateDb, jsonDict = None): - ''' + super(AttributeRulesCompactPropertyManagerWidget, self).__init__(parent=parent) + + def populateConfigInterface(self, templateDb, jsonDict=None): + """ Must be reimplemented in each child - ''' - dlg = AttributeRulesEditor(templateDb, parameterDict = jsonDict) + """ + dlg = AttributeRulesEditor(templateDb, parameterDict=jsonDict) if dlg.exec_(): return dlg.getParameterDict() else: return None - + def instantiateManagerObject(self, abstractDb, dbDict, edgvVersion): - return AttributeRulesManager(abstractDb, dbDict, edgvVersion) \ No newline at end of file + return AttributeRulesManager(abstractDb, dbDict, edgvVersion) diff --git a/DsgTools/gui/CustomWidgets/DatabasePropertiesWidgets/CompactPropertyWidgets/genericCompactPropertyManagerWidget.py b/DsgTools/gui/CustomWidgets/DatabasePropertiesWidgets/CompactPropertyWidgets/genericCompactPropertyManagerWidget.py index 69703f385..efdd58637 100644 --- a/DsgTools/gui/CustomWidgets/DatabasePropertiesWidgets/CompactPropertyWidgets/genericCompactPropertyManagerWidget.py +++ b/DsgTools/gui/CustomWidgets/DatabasePropertiesWidgets/CompactPropertyWidgets/genericCompactPropertyManagerWidget.py @@ -27,39 +27,52 @@ # Qt imports from qgis.PyQt import QtWidgets, uic, QtCore from qgis.PyQt.QtCore import pyqtSlot, Qt, pyqtSignal -from qgis.PyQt.QtWidgets import QMessageBox, QApplication, QFileDialog, QMenu, QHeaderView +from qgis.PyQt.QtWidgets import ( + QMessageBox, + QApplication, + QFileDialog, + QMenu, + QHeaderView, +) from qgis.PyQt.QtGui import QCursor -#DsgTools imports +# DsgTools imports from DsgTools.gui.CustomWidgets.SelectionWidgets.listSelector import ListSelector from DsgTools.core.Utils.utils import Utils from DsgTools.core.dsgEnums import DsgEnums -from DsgTools.gui.CustomWidgets.DatabasePropertiesWidgets.BasicPropertyWidgets.genericParameterSetter import GenericParameterSetter +from DsgTools.gui.CustomWidgets.DatabasePropertiesWidgets.BasicPropertyWidgets.genericParameterSetter import ( + GenericParameterSetter, +) from qgis.core import QgsMessageLog import json -FORM_CLASS, _ = uic.loadUiType(os.path.join( - os.path.dirname(__file__), 'genericCompactPropertyManagerWidget.ui')) +FORM_CLASS, _ = uic.loadUiType( + os.path.join(os.path.dirname(__file__), "genericCompactPropertyManagerWidget.ui") +) + class GenericCompactPropertyManagerWidget(QtWidgets.QWidget, FORM_CLASS): Add, Remove, Import, Export, Update = list(range(5)) - def __init__(self, parent = None): + + def __init__(self, parent=None): """ Constructor """ super(GenericCompactPropertyManagerWidget, self).__init__(parent) self.setupUi(self) self.genericDbManager = None - self.textDict = {'EarthCoverage':self.tr('Earth Coverage'), - 'Customization':self.tr('Customization'), - 'Style':self.tr('Style'), - 'ValidationConfig':self.tr('Validation'), - 'Permission':self.tr('Permissions'), - 'AttributeRules':self.tr('Attribute Rules Configuration'), - 'SpatialRules':self.tr('Spatial Rules Configuration'), - 'Generic':self.tr('Generic Property'), - 'ValidationWorkflow':self.tr('Validation Workflow')} + self.textDict = { + "EarthCoverage": self.tr("Earth Coverage"), + "Customization": self.tr("Customization"), + "Style": self.tr("Style"), + "ValidationConfig": self.tr("Validation"), + "Permission": self.tr("Permissions"), + "AttributeRules": self.tr("Attribute Rules Configuration"), + "SpatialRules": self.tr("Spatial Rules Configuration"), + "Generic": self.tr("Generic Property"), + "ValidationWorkflow": self.tr("Validation Workflow"), + } self.widgetName = self.textDict[self.getWhoAmI()] self.changeTooltips(self.widgetName) self.parent = parent @@ -70,38 +83,61 @@ def refresh(self): """ self.propertyComboBox.clear() if self.genericDbManager: - propertyList = list(self.genericDbManager.getPropertyPerspectiveDict(viewType = DsgEnums.Property).keys()) + propertyList = list( + self.genericDbManager.getPropertyPerspectiveDict( + viewType=DsgEnums.Property + ).keys() + ) propertyList.sort() self.propertyComboBox.addItems(propertyList) - + def getWhoAmI(self): - return str(self.__class__).split('.')[-1].replace('\'>', '').replace('CompactPropertyManagerWidget','') - + return ( + str(self.__class__) + .split(".")[-1] + .replace("'>", "") + .replace("CompactPropertyManagerWidget", "") + ) + def instantiateManagerObject(self, abstractDb, dbDict, edgvVersion): """ Reimplemented in each child. """ pass - + def setParameters(self, abstractDb): """ 1. Get abstract db 2. Instantiate manager object """ self.abstractDb = abstractDb - self.genericDbManager = self.instantiateManagerObject(abstractDb, {self.abstractDb.db.databaseName():self.abstractDb}, self.abstractDb.getDatabaseVersion()) + self.genericDbManager = self.instantiateManagerObject( + abstractDb, + {self.abstractDb.db.databaseName(): self.abstractDb}, + self.abstractDb.getDatabaseVersion(), + ) self.refresh() def changeTooltips(self, propertyName): """ Changes all buttons' tooltips according to propertyName """ - self.createPropertyPushButton.setToolTip(self.tr('Add {0}').format(propertyName)) - self.removePropertyPushButton.setToolTip(self.tr('Remove {0}').format(propertyName)) - self.importPropertyPushButton.setToolTip(self.tr('Import {0}').format(propertyName)) - self.exportPropertyPushButton.setToolTip(self.tr('Export {0}').format(propertyName)) - self.updatePropertyPushButton.setToolTip(self.tr('Update {0}').format(propertyName)) - + self.createPropertyPushButton.setToolTip( + self.tr("Add {0}").format(propertyName) + ) + self.removePropertyPushButton.setToolTip( + self.tr("Remove {0}").format(propertyName) + ) + self.importPropertyPushButton.setToolTip( + self.tr("Import {0}").format(propertyName) + ) + self.exportPropertyPushButton.setToolTip( + self.tr("Export {0}").format(propertyName) + ) + self.updatePropertyPushButton.setToolTip( + self.tr("Update {0}").format(propertyName) + ) + def enableButtons(self, enabled): """ Enables or disables all buttons according to boolean enabled @@ -113,55 +149,85 @@ def enableButtons(self, enabled): self.updatePropertyPushButton.setEnabled(enabled) def getWhoAmI(self): - return str(self.__class__).split('.')[-1].replace('\'>', '').replace('CompactPropertyManagerWidget','') + return ( + str(self.__class__) + .split(".")[-1] + .replace("'>", "") + .replace("CompactPropertyManagerWidget", "") + ) def getParameterDict(self): """ This is used to get ui state Returns a dict in the format: { - 'selectedConfig':--name of the selected config--, + 'selectedConfig':--name of the selected config--, } """ parameterDict = dict() - parameterDict['selectedConfig'] = self.propertyComboBox.currentText() + parameterDict["selectedConfig"] = self.propertyComboBox.currentText() return parameterDict - + def setInterface(self, parameterDict): """ Uses parameterDict to populate interface Sets the interface with a dict in the format: { - 'selectedConfig':--name of the selected config--, + 'selectedConfig':--name of the selected config--, } """ - if 'selectedConfig' in parameterDict: - idx = self.propertyComboBox.findText(parameterDict['selectedConfig'], flags = Qt.MatchFlags) + if "selectedConfig" in parameterDict: + idx = self.propertyComboBox.findText( + parameterDict["selectedConfig"], flags=Qt.MatchFlags + ) if idx != -1: self.propertyComboBox.setCurrentIndex(idx) - + @pyqtSlot(bool) def on_createPropertyPushButton_clicked(self): """ 1. Open custom manager according to property type; 2. Use manager to apply to database """ - dlg = GenericParameterSetter(hideDbUi = True) + dlg = GenericParameterSetter(hideDbUi=True) if not dlg.exec_(): return propertyName = dlg.getParameters() - if propertyName == '': - QMessageBox.warning(self, self.tr('Warning!'), self.tr('Warning! Enter a {0} name!').format(self.widgetName)) + if propertyName == "": + QMessageBox.warning( + self, + self.tr("Warning!"), + self.tr("Warning! Enter a {0} name!").format(self.widgetName), + ) return - if propertyName in list(self.genericDbManager.getPropertyPerspectiveDict(viewType = DsgEnums.Property).keys()): - QMessageBox.warning(self, self.tr('Warning!'), self.tr('Warning! {0} name already exists!').format(self.widgetName)) + if propertyName in list( + self.genericDbManager.getPropertyPerspectiveDict( + viewType=DsgEnums.Property + ).keys() + ): + QMessageBox.warning( + self, + self.tr("Warning!"), + self.tr("Warning! {0} name already exists!").format(self.widgetName), + ) return setupDict = self.populateConfigInterface(self.abstractDb) if setupDict: - self.genericDbManager.createAndInstall(propertyName, setupDict, self.genericDbManager.edgvVersion, dbList = [self.abstractDb.db.databaseName()]) + self.genericDbManager.createAndInstall( + propertyName, + setupDict, + self.genericDbManager.edgvVersion, + dbList=[self.abstractDb.db.databaseName()], + ) self.refresh() - QMessageBox.information(self, self.tr('Success!'), self.tr('{0} configuration {1} created successfuly!').format(self.widgetName, propertyName)) - + QMessageBox.information( + self, + self.tr("Success!"), + self.tr("{0} configuration {1} created successfuly!").format( + self.widgetName, propertyName + ), + ) + @pyqtSlot(bool) def on_removePropertyPushButton_clicked(self): """ @@ -176,22 +242,40 @@ def on_importPropertyPushButton_clicked(self): """ fd = QFileDialog() widgetType = self.getWhoAmI() - filename = fd.getOpenFileName(caption=self.captionDict[widgetType],filter=self.filterDict[widgetType]) - if filename == '': - QMessageBox.warning(self, self.tr('Warning!'), self.tr('Warning! Select a file to import!')) + filename = fd.getOpenFileName( + caption=self.captionDict[widgetType], filter=self.filterDict[widgetType] + ) + if filename == "": + QMessageBox.warning( + self, self.tr("Warning!"), self.tr("Warning! Select a file to import!") + ) return try: QApplication.setOverrideCursor(QCursor(Qt.WaitCursor)) self.genericDbManager.importSetting(filename) - settingName = os.path.basename(fullFilePath).split('.')[0] - self.genericDbManager.installSetting(settingName, dbList = [self.abstractDb.db.databaseName()]) + settingName = os.path.basename(fullFilePath).split(".")[0] + self.genericDbManager.installSetting( + settingName, dbList=[self.abstractDb.db.databaseName()] + ) QApplication.restoreOverrideCursor() - QMessageBox.information(self, self.tr('Sucess!'), self.tr('Success! {0} successfully imported and installed in {1}.').format(widgetType, settingName)) + QMessageBox.information( + self, + self.tr("Sucess!"), + self.tr( + "Success! {0} successfully imported and installed in {1}." + ).format(widgetType, settingName), + ) except Exception as e: QApplication.restoreOverrideCursor() - QMessageBox.critical(self, self.tr('Error!'), self.tr('Error! Problem importing {0}: {1}').format(widgetType, ':'.join(e.args)) ) + QMessageBox.critical( + self, + self.tr("Error!"), + self.tr("Error! Problem importing {0}: {1}").format( + widgetType, ":".join(e.args) + ), + ) self.refresh() - + @pyqtSlot(bool) def on_exportPropertyPushButton_clicked(self): """ @@ -199,12 +283,16 @@ def on_exportPropertyPushButton_clicked(self): """ exportPropertyList = [self.propertyComboBox.currentText()] if exportPropertyList == []: - QMessageBox.warning(self, self.tr('Warning!'), self.tr('Warning! Select a profile to export!')) + QMessageBox.warning( + self, + self.tr("Warning!"), + self.tr("Warning! Select a profile to export!"), + ) return fd = QFileDialog() - folder = fd.getExistingDirectory(caption = self.tr('Select a folder to output')) + folder = fd.getExistingDirectory(caption=self.tr("Select a folder to output")) folder = folder[0] if isinstance(folder, tuple) else folder - if folder == '': + if folder == "": # QMessageBox.warning(self, self.tr('Warning!'), self.tr('Warning! Select a output!')) return edgvVersion = self.genericDbManager.edgvVersion @@ -213,10 +301,20 @@ def on_exportPropertyPushButton_clicked(self): for exportProperty in exportPropertyList: self.genericDbManager.exportSetting(exportProperty, edgvVersion, folder) QApplication.restoreOverrideCursor() - QMessageBox.information(self, self.tr('Success!'), self.tr('Success! {0} successfully exported.').format(self.widgetName)) + QMessageBox.information( + self, + self.tr("Success!"), + self.tr("Success! {0} successfully exported.").format(self.widgetName), + ) except Exception as e: QApplication.restoreOverrideCursor() - QMessageBox.critical(self, self.tr('Error!'), self.tr('Error! Problem exporting {0}: {1}').format(self.widgetName, ':'.join(e.args)) ) + QMessageBox.critical( + self, + self.tr("Error!"), + self.tr("Error! Problem exporting {0}: {1}").format( + self.widgetName, ":".join(e.args) + ), + ) @pyqtSlot(bool) def on_updatePropertyPushButton_clicked(self): @@ -228,21 +326,43 @@ def on_updatePropertyPushButton_clicked(self): 4. Update property """ propertyName = self.propertyComboBox.currentText() - propertyDict = self.genericDbManager.getPropertyPerspectiveDict(viewType = DsgEnums.Property) + propertyDict = self.genericDbManager.getPropertyPerspectiveDict( + viewType=DsgEnums.Property + ) if propertyName not in list(propertyDict.keys()): - QMessageBox.critical(self, self.tr('Error!'), self.tr('Error! Problem getting {0}: Invalid property {1}').format(self.widgetName, propertyName) ) + QMessageBox.critical( + self, + self.tr("Error!"), + self.tr("Error! Problem getting {0}: Invalid property {1}").format( + self.widgetName, propertyName + ), + ) return - parameterDict = self.genericDbManager.getSetting(propertyName, self.genericDbManager.edgvVersion) - setupDict = self.populateConfigInterface(self.abstractDb, jsonDict = parameterDict) + parameterDict = self.genericDbManager.getSetting( + propertyName, self.genericDbManager.edgvVersion + ) + setupDict = self.populateConfigInterface( + self.abstractDb, jsonDict=parameterDict + ) if setupDict: try: QApplication.setOverrideCursor(QCursor(Qt.WaitCursor)) self.genericDbManager.updateSetting(propertyName, setupDict) QApplication.restoreOverrideCursor() - QMessageBox.information(self, self.tr('Success!'), self.tr('Success! Property {0} successfully updated.').format(propertyName)) + QMessageBox.information( + self, + self.tr("Success!"), + self.tr("Success! Property {0} successfully updated.").format( + propertyName + ), + ) except Exception as e: QApplication.restoreOverrideCursor() - QMessageBox.critical(self, self.tr('Error!'), self.tr('Error! Problem updating {0}').format(propertyName) ) - - def populateConfigInterface(self, abstractDb, jsonDict = None): - return None \ No newline at end of file + QMessageBox.critical( + self, + self.tr("Error!"), + self.tr("Error! Problem updating {0}").format(propertyName), + ) + + def populateConfigInterface(self, abstractDb, jsonDict=None): + return None diff --git a/DsgTools/gui/CustomWidgets/DatabasePropertiesWidgets/CompactPropertyWidgets/validationWorkflowCompactPropertyManagerWidget.py b/DsgTools/gui/CustomWidgets/DatabasePropertiesWidgets/CompactPropertyWidgets/validationWorkflowCompactPropertyManagerWidget.py index 8a6e45409..2f67e0781 100644 --- a/DsgTools/gui/CustomWidgets/DatabasePropertiesWidgets/CompactPropertyWidgets/validationWorkflowCompactPropertyManagerWidget.py +++ b/DsgTools/gui/CustomWidgets/DatabasePropertiesWidgets/CompactPropertyWidgets/validationWorkflowCompactPropertyManagerWidget.py @@ -28,36 +28,47 @@ from qgis.PyQt.QtWidgets import QMessageBox, QApplication, QFileDialog from qgis.PyQt.QtGui import QCursor -#DsgTools imports -from DsgTools.gui.CustomWidgets.DatabasePropertiesWidgets.CompactPropertyWidgets.genericCompactPropertyManagerWidget import GenericCompactPropertyManagerWidget -from DsgTools.core.ServerManagementTools.validationWorkflowManager import ValidationWorkflowManager -from DsgTools.gui.ProductionTools.Toolboxes.ValidationToolbox.validationWorkflowCreator import ValidationWorkflowCreator +# DsgTools imports +from DsgTools.gui.CustomWidgets.DatabasePropertiesWidgets.CompactPropertyWidgets.genericCompactPropertyManagerWidget import ( + GenericCompactPropertyManagerWidget, +) +from DsgTools.core.ServerManagementTools.validationWorkflowManager import ( + ValidationWorkflowManager, +) +from DsgTools.gui.ProductionTools.Toolboxes.ValidationToolbox.validationWorkflowCreator import ( + ValidationWorkflowCreator, +) from DsgTools.core.Utils.utils import Utils from DsgTools.core.dsgEnums import DsgEnums from qgis.core import QgsMessageLog import json -class ValidationWorkflowCompactPropertyManagerWidget(GenericCompactPropertyManagerWidget): - def __init__(self, manager = None, parent = None): + +class ValidationWorkflowCompactPropertyManagerWidget( + GenericCompactPropertyManagerWidget +): + def __init__(self, manager=None, parent=None): """ Constructor """ - super(ValidationWorkflowCompactPropertyManagerWidget, self).__init__(parent = parent) - - def populateConfigInterface(self, validationManager, jsonDict = None): - ''' + super(ValidationWorkflowCompactPropertyManagerWidget, self).__init__( + parent=parent + ) + + def populateConfigInterface(self, validationManager, jsonDict=None): + """ Must be reimplemented in each child - ''' - dlg = ValidationWorkflowCreator(validationManager, parameterDict = jsonDict) + """ + dlg = ValidationWorkflowCreator(validationManager, parameterDict=jsonDict) if dlg.exec_(): return dlg.getParameterDict() else: return None - + def instantiateManagerObject(self, abstractDb, dbDict, edgvVersion): return ValidationWorkflowManager(abstractDb, dbDict, edgvVersion) - + @pyqtSlot(bool) def on_createPropertyPushButton_clicked(self): """ @@ -66,7 +77,17 @@ def on_createPropertyPushButton_clicked(self): """ setupDict = self.populateConfigInterface(self.parent.validationManager) if setupDict: - self.genericDbManager.createAndInstall(propertyName, setupDict, self.genericDbManager.edgvVersion, dbList = [self.abstractDb.db.databaseName()]) + self.genericDbManager.createAndInstall( + propertyName, + setupDict, + self.genericDbManager.edgvVersion, + dbList=[self.abstractDb.db.databaseName()], + ) self.refresh() - QMessageBox.information(self, self.tr('Success!'), self.tr('{0} configuration {1} created successfuly!').format(self.widgetName, propertyName)) - \ No newline at end of file + QMessageBox.information( + self, + self.tr("Success!"), + self.tr("{0} configuration {1} created successfuly!").format( + self.widgetName, propertyName + ), + ) diff --git a/DsgTools/gui/CustomWidgets/OrderedPropertyWidgets/orderedAttributeRuleTypesWidget.py b/DsgTools/gui/CustomWidgets/OrderedPropertyWidgets/orderedAttributeRuleTypesWidget.py index 91e57bf1a..14ee99b3d 100644 --- a/DsgTools/gui/CustomWidgets/OrderedPropertyWidgets/orderedAttributeRuleTypesWidget.py +++ b/DsgTools/gui/CustomWidgets/OrderedPropertyWidgets/orderedAttributeRuleTypesWidget.py @@ -22,26 +22,29 @@ """ import os from collections import OrderedDict + # Qt imports from qgis.PyQt import QtGui, uic from qgis.PyQt.QtCore import pyqtSlot, pyqtSignal, QSettings, Qt from qgis.PyQt.QtWidgets import QTableWidgetItem -from DsgTools.gui.CustomWidgets.OrderedPropertyWidgets.orderedStructureWidget import OrderedStructureWidget -from DsgTools.gui.CustomWidgets.AttributeValidityWidgets.attributeRuleTypeWidget import AttributeRuleTypeWidget +from DsgTools.gui.CustomWidgets.OrderedPropertyWidgets.orderedStructureWidget import ( + OrderedStructureWidget, +) +from DsgTools.gui.CustomWidgets.AttributeValidityWidgets.attributeRuleTypeWidget import ( + AttributeRuleTypeWidget, +) -class OrderedAttributeRuleTypesWidget(OrderedStructureWidget): +class OrderedAttributeRuleTypesWidget(OrderedStructureWidget): def __init__(self, parent=None): """ Initializates OrderedAttributeRulesWidget """ super(OrderedAttributeRuleTypesWidget, self).__init__(parent) self.args = None - self.tableWidget.setHorizontalHeaderLabels([self.tr('Attribute Rule Types')]) - self.widgetKey = 'attributeRuleTypeWidgetList' - + self.tableWidget.setHorizontalHeaderLabels([self.tr("Attribute Rule Types")]) + self.widgetKey = "attributeRuleTypeWidgetList" + def instantiateWidgetItem(self): return AttributeRuleTypeWidget() - - diff --git a/DsgTools/gui/CustomWidgets/OrderedPropertyWidgets/orderedAttributeRulesWidget.py b/DsgTools/gui/CustomWidgets/OrderedPropertyWidgets/orderedAttributeRulesWidget.py index 9223bd45f..ae230eb6f 100644 --- a/DsgTools/gui/CustomWidgets/OrderedPropertyWidgets/orderedAttributeRulesWidget.py +++ b/DsgTools/gui/CustomWidgets/OrderedPropertyWidgets/orderedAttributeRulesWidget.py @@ -22,26 +22,29 @@ """ import os from collections import OrderedDict + # Qt imports from qgis.PyQt import QtGui, uic from qgis.PyQt.QtCore import pyqtSlot, pyqtSignal, QSettings, Qt from qgis.PyQt.QtWidgets import QTableWidgetItem -from DsgTools.gui.CustomWidgets.OrderedPropertyWidgets.orderedStructureWidget import OrderedStructureWidget -from DsgTools.gui.CustomWidgets.AttributeValidityWidgets.attributeRuleWidget import AttributeRuleWidget +from DsgTools.gui.CustomWidgets.OrderedPropertyWidgets.orderedStructureWidget import ( + OrderedStructureWidget, +) +from DsgTools.gui.CustomWidgets.AttributeValidityWidgets.attributeRuleWidget import ( + AttributeRuleWidget, +) -class OrderedAttributeRulesWidget(OrderedStructureWidget): +class OrderedAttributeRulesWidget(OrderedStructureWidget): def __init__(self, parent=None): """ Initializates OrderedAttributeRulesWidget """ super(OrderedAttributeRulesWidget, self).__init__(parent) self.args = None - self.tableWidget.setHorizontalHeaderLabels([self.tr('Attribute Rules')]) - self.widgetKey = 'attributeRuleWidgetList' - + self.tableWidget.setHorizontalHeaderLabels([self.tr("Attribute Rules")]) + self.widgetKey = "attributeRuleWidgetList" + def instantiateWidgetItem(self): return AttributeRuleWidget(*self.args) - - diff --git a/DsgTools/gui/CustomWidgets/OrderedPropertyWidgets/orderedRecursiveSnapWidget.py b/DsgTools/gui/CustomWidgets/OrderedPropertyWidgets/orderedRecursiveSnapWidget.py index 7c0fd8fc4..6ab083b30 100644 --- a/DsgTools/gui/CustomWidgets/OrderedPropertyWidgets/orderedRecursiveSnapWidget.py +++ b/DsgTools/gui/CustomWidgets/OrderedPropertyWidgets/orderedRecursiveSnapWidget.py @@ -23,55 +23,64 @@ from builtins import range import os from collections import OrderedDict + # Qt imports from qgis.PyQt import QtGui, uic from qgis.PyQt.QtCore import pyqtSlot, pyqtSignal, QSettings, Qt from qgis.PyQt.QtWidgets import QTableWidgetItem -from DsgTools.gui.CustomWidgets.OrderedPropertyWidgets.orderedStructureWidget import OrderedStructureWidget -from DsgTools.gui.CustomWidgets.BasicInterfaceWidgets.snapChooserWidget import SnapChooserWidget +from DsgTools.gui.CustomWidgets.OrderedPropertyWidgets.orderedStructureWidget import ( + OrderedStructureWidget, +) +from DsgTools.gui.CustomWidgets.BasicInterfaceWidgets.snapChooserWidget import ( + SnapChooserWidget, +) -class OrderedRecursiveSnapWidget(OrderedStructureWidget): +class OrderedRecursiveSnapWidget(OrderedStructureWidget): def __init__(self, parent=None): """ Initializates OrderedRecursiveSnapWidget """ super(OrderedRecursiveSnapWidget, self).__init__(parent) self.args = None - self.tableWidget.setHorizontalHeaderLabels([self.tr('Snap Order')]) - self.widgetKey = 'snapChooserWidgetList' - + self.tableWidget.setHorizontalHeaderLabels([self.tr("Snap Order")]) + self.widgetKey = "snapChooserWidgetList" + def instantiateWidgetItem(self): return SnapChooserWidget(*self.args) - + def setInitialState(self, layerList): self.args = layerList - + def getHierarchicalSnapDict(self): snapList = self.getParameterDict()[self.widgetKey] snapDictList = [] - for i in range(len(snapList)-1): + for i in range(len(snapList) - 1): snapItemDict = dict() - snapItemDict['referenceLayer'] = snapList[i]['layerName'] - snapItemDict['snap'] = snapList[i]['snap'] - snapItemDict['snapLayerList'] = [i['layerName'] for i in snapList[(i+1)::]] + snapItemDict["referenceLayer"] = snapList[i]["layerName"] + snapItemDict["snap"] = snapList[i]["snap"] + snapItemDict["snapLayerList"] = [ + i["layerName"] for i in snapList[(i + 1) : :] + ] snapDictList.append(snapItemDict) return snapDictList - - @pyqtSlot(bool, name = 'on_addRulePushButton_clicked') - def addItem(self, parameterDict = None): + + @pyqtSlot(bool, name="on_addRulePushButton_clicked") + def addItem(self, parameterDict=None): """ 1. Use super to instantiate parent's add item 2. Connect new item's layerComboBox.currentIndexChanged signal to self.componentsRefresher """ - super(OrderedRecursiveSnapWidget, self).addItem(parameterDict = parameterDict) + super(OrderedRecursiveSnapWidget, self).addItem(parameterDict=parameterDict) row = self.tableWidget.rowCount() - 1 - newItemWidget = self.tableWidget.cellWidget(row,0) - newItemWidget.layerComboBox.currentIndexChanged.connect(self.componentsRefresher) + newItemWidget = self.tableWidget.cellWidget(row, 0) + newItemWidget.layerComboBox.currentIndexChanged.connect( + self.componentsRefresher + ) newItemWidget.layerComboBox.currentIndexChanged.emit(-1) - - @pyqtSlot(bool, name = 'on_removeRulePushButton_clicked') + + @pyqtSlot(bool, name="on_removeRulePushButton_clicked") def removeItem(self): """ 1. Get selected row @@ -79,9 +88,9 @@ def removeItem(self): 3. Update control list """ super(OrderedRecursiveSnapWidget, self).removeItem() - self.componentsRefresher(onDelete = True) - - def componentsRefresher(self, onDelete = False): + self.componentsRefresher(onDelete=True) + + def componentsRefresher(self, onDelete=False): """ 1. Get all widgets 2. Iterate over widgets and build black list from selected texts @@ -89,23 +98,31 @@ def componentsRefresher(self, onDelete = False): 4. Refresh all combos with remaining values plus selected one 5. Reconnect signals """ - #1. get widgetList and blackList: - widgetList = [self.tableWidget.cellWidget(i,0) for i in range(self.tableWidget.rowCount())] - blackList = [i.layerComboBox.currentText() for i in widgetList if i.layerComboBox.currentIndex() > 0] + # 1. get widgetList and blackList: + widgetList = [ + self.tableWidget.cellWidget(i, 0) + for i in range(self.tableWidget.rowCount()) + ] + blackList = [ + i.layerComboBox.currentText() + for i in widgetList + if i.layerComboBox.currentIndex() > 0 + ] if not onDelete: currentText = self.sender().currentText() if currentText not in blackList: blackList.append(currentText) - #3. disconect signals + # 3. disconect signals for widget in widgetList: try: - widget.layerComboBox.currentIndexChanged.disconnect(self.componentsRefresher) + widget.layerComboBox.currentIndexChanged.disconnect( + self.componentsRefresher + ) except: pass - #4. refresh combos + # 4. refresh combos for widget in widgetList: widget.refresh(blackList) - #5. reconnect signals + # 5. reconnect signals for widget in widgetList: widget.layerComboBox.currentIndexChanged.connect(self.componentsRefresher) - diff --git a/DsgTools/gui/CustomWidgets/OrderedPropertyWidgets/orderedStructureWidget.py b/DsgTools/gui/CustomWidgets/OrderedPropertyWidgets/orderedStructureWidget.py index 2f83eabfb..dd6e69f64 100644 --- a/DsgTools/gui/CustomWidgets/OrderedPropertyWidgets/orderedStructureWidget.py +++ b/DsgTools/gui/CustomWidgets/OrderedPropertyWidgets/orderedStructureWidget.py @@ -23,16 +23,18 @@ from builtins import range import os, importlib from collections import OrderedDict + # Qt imports from qgis.PyQt import QtWidgets, uic from qgis.PyQt.QtCore import pyqtSlot, pyqtSignal, QSettings, Qt from qgis.PyQt.QtWidgets import QTableWidgetItem, QTableWidgetSelectionRange -FORM_CLASS, _ = uic.loadUiType(os.path.join( - os.path.dirname(__file__), 'orderedStructureWidget.ui')) +FORM_CLASS, _ = uic.loadUiType( + os.path.join(os.path.dirname(__file__), "orderedStructureWidget.ui") +) -class OrderedStructureWidget(QtWidgets.QWidget, FORM_CLASS): +class OrderedStructureWidget(QtWidgets.QWidget, FORM_CLASS): def __init__(self, parent=None): """ Initializates OrderedStructureWidget @@ -40,7 +42,7 @@ def __init__(self, parent=None): super(OrderedStructureWidget, self).__init__(parent) self.setupUi(self) self.args = None - + def setArgs(self, args): self.args = args @@ -49,9 +51,9 @@ def instantiateWidgetItem(self): Must be reimplemented in each child. """ pass - - @pyqtSlot(bool, name = 'on_addRulePushButton_clicked') - def addItem(self, parameterDict = None): + + @pyqtSlot(bool, name="on_addRulePushButton_clicked") + def addItem(self, parameterDict=None): """ 1. Instantiate new line 2. Add new line in the end @@ -63,8 +65,8 @@ def addItem(self, parameterDict = None): widget.populateInterface(parameterDict) self.tableWidget.setCellWidget(rowCount, 0, widget) self.tableWidget.resizeRowToContents(rowCount) - - @pyqtSlot(bool, name = 'on_removeRulePushButton_clicked') + + @pyqtSlot(bool, name="on_removeRulePushButton_clicked") def removeItem(self): """ 1. Get selected row @@ -87,63 +89,76 @@ def on_moveRuleUpPushButton_clicked(self): if selected == []: return firstItemIdx = selected[0].row() - 1 - if firstItemIdx < 0: #first item in selection, do nothing + if firstItemIdx < 0: # first item in selection, do nothing return for idx in selected: self.moveUp(self.tableWidget, idx.row(), 0) - self.tableWidget.setRangeSelected(QTableWidgetSelectionRange(firstItemIdx, 0, selected[-1].row()-1, 0), True) + self.tableWidget.setRangeSelected( + QTableWidgetSelectionRange(firstItemIdx, 0, selected[-1].row() - 1, 0), True + ) - @pyqtSlot(bool) def on_moveRuleDownPushButton_clicked(self): selected = self.tableWidget.selectedIndexes() if selected == []: return firstItemIdx = selected[-1].row() + 1 - if firstItemIdx > self.tableWidget.rowCount(): #last item in selection, do nothing + if ( + firstItemIdx > self.tableWidget.rowCount() + ): # last item in selection, do nothing return for idx in selected[::-1]: self.moveDown(self.tableWidget, idx.row(), 0) - self.tableWidget.setRangeSelected(QTableWidgetSelectionRange(firstItemIdx-1, 0, selected[-1].row()+1, 0), True) - + self.tableWidget.setRangeSelected( + QTableWidgetSelectionRange(firstItemIdx - 1, 0, selected[-1].row() + 1, 0), + True, + ) + def moveDown(self, tableWidget, rowIdx, columnIdx): """ Moves item down """ - tableWidget.insertRow(rowIdx+2) + tableWidget.insertRow(rowIdx + 2) tableWidget.takeItem(rowIdx, columnIdx) - tableWidget.setCellWidget(rowIdx+2, columnIdx, tableWidget.cellWidget(rowIdx, columnIdx)) + tableWidget.setCellWidget( + rowIdx + 2, columnIdx, tableWidget.cellWidget(rowIdx, columnIdx) + ) tableWidget.removeRow(rowIdx) def moveUp(self, tableWidget, rowIdx, columnIdx): """ Moves item up """ - tableWidget.insertRow(rowIdx-1) - tableWidget.takeItem(rowIdx+1, columnIdx) - tableWidget.setCellWidget(rowIdx-1, columnIdx, tableWidget.cellWidget(rowIdx+1, columnIdx)) - tableWidget.removeRow(rowIdx+1) + tableWidget.insertRow(rowIdx - 1) + tableWidget.takeItem(rowIdx + 1, columnIdx) + tableWidget.setCellWidget( + rowIdx - 1, columnIdx, tableWidget.cellWidget(rowIdx + 1, columnIdx) + ) + tableWidget.removeRow(rowIdx + 1) def validate(self): for i in range(self.tableWidget.rowCount()): if not self.tableWidget.cellWidget(i, 0).validate(): return False return True - + def invalidatedReason(self): - msg = '' + msg = "" for i in range(self.tableWidget.rowCount()): if not self.tableWidget.cellWidget(i, 0).validate(): - msg += self.tr('Error for rule #{0}:\n'.format(i+1))+self.tableWidget.cellWidget(i, 0).invalidatedReason() + msg += ( + self.tr("Error for rule #{0}:\n".format(i + 1)) + + self.tableWidget.cellWidget(i, 0).invalidatedReason() + ) return msg - + def populateInterface(self, parameterDict): """ Populates interface with parameters from parameterDict. """ for ruleDict in parameterDict[self.widgetKey]: - self.addItem(parameterDict = ruleDict) - + self.addItem(parameterDict=ruleDict) + def getParameterDict(self): """ Returns an OrderedDict with the number of the rule and the rule json @@ -151,7 +166,7 @@ def getParameterDict(self): parameterList = [] for i in range(self.tableWidget.rowCount()): parameterList.append(self.tableWidget.cellWidget(i, 0).getParameterDict()) - return {self.widgetKey:parameterList} #outputs list of widgets parameters + return {self.widgetKey: parameterList} # outputs list of widgets parameters def validateJson(self, inputJson): """ @@ -165,6 +180,8 @@ def validateJson(self, inputJson): if [self.widgetKey] != list(inputJson.keys()): return False for i in range(self.tableWidget.rowCount()): - if not self.tableWidget.cellWidget(i, 0).validateJson(inputJson[self.widgetKey][i]): + if not self.tableWidget.cellWidget(i, 0).validateJson( + inputJson[self.widgetKey][i] + ): return False return True diff --git a/DsgTools/gui/CustomWidgets/OrderedPropertyWidgets/orderedTableWidget.py b/DsgTools/gui/CustomWidgets/OrderedPropertyWidgets/orderedTableWidget.py index 92cee538b..c2af5cd98 100644 --- a/DsgTools/gui/CustomWidgets/OrderedPropertyWidgets/orderedTableWidget.py +++ b/DsgTools/gui/CustomWidgets/OrderedPropertyWidgets/orderedTableWidget.py @@ -27,18 +27,21 @@ from qgis.PyQt import uic from qgis.utils import iface from qgis.PyQt.QtCore import Qt, pyqtSlot, pyqtSignal -from qgis.PyQt.QtWidgets import (QWidget, - QFileDialog, - QHeaderView, - QMessageBox, - QTableWidgetItem, - QAbstractItemView, - QDoubleSpinBox) +from qgis.PyQt.QtWidgets import ( + QWidget, + QFileDialog, + QHeaderView, + QMessageBox, + QTableWidgetItem, + QAbstractItemView, + QDoubleSpinBox, +) FORM_CLASS, _ = uic.loadUiType( - os.path.join(os.path.dirname(__file__), 'orderedTableWidget.ui') + os.path.join(os.path.dirname(__file__), "orderedTableWidget.ui") ) + class OrderedTableWidget(QWidget, FORM_CLASS): rowAdded = pyqtSignal(int) rowRemoved = pyqtSignal(int) @@ -48,15 +51,21 @@ class OrderedTableWidget(QWidget, FORM_CLASS): ORDER_MODE_COUNT = 2 ASC_ORDER, DESC_ORDER = range(ORDER_MODE_COUNT) - def __init__(self, parent=None, headerMap=None, showButtons=False, - fileType=None, extension=None): + def __init__( + self, + parent=None, + headerMap=None, + showButtons=False, + fileType=None, + extension=None, + ): """ Class constructor. :param headerMap: (dict) a map from each header to be shown and type of cell content (e.g. widget or item). :param parent: (QtWidgets.*) any widget parent to current instance. :param showButtons: (bool) whether buttons are visible. - :param fileType: (str) ex/import file type extension name (e.g. JSON + :param fileType: (str) ex/import file type extension name (e.g. JSON file). :param fileType: (str) ex/import file type extension (e.g. .json). """ @@ -99,13 +108,13 @@ def setHeaders(self, headerMap): self.clear() self.headers = headerMap self.tableWidget.setColumnCount(len(self.headers)) - self.tableWidget.setHorizontalHeaderLabels([ - p["header"] for p in self.headers.values() - ]) + self.tableWidget.setHorizontalHeaderLabels( + [p["header"] for p in self.headers.values()] + ) def replicateColumnValue(self, col): """ - Replicates the value from the first cell of a colums based on column + Replicates the value from the first cell of a colums based on column filled values. :param col: (int) column to have its first value replicated to the other rows. @@ -131,14 +140,15 @@ def orderColumn(self, col): self.currentRowOrder[col] = self.ASC_ORDER else: # get next mode - self.currentRowOrder[col] = (self.currentRowOrder[col] + 1) % \ - self.ORDER_MODE_COUNT + self.currentRowOrder[col] = ( + self.currentRowOrder[col] + 1 + ) % self.ORDER_MODE_COUNT contents = [] for row in range(self.rowCount()): contents.append(self.row(row)) self.clear() rev = self.currentRowOrder[col] == self.DESC_ORDER - for content in sorted(contents, key = lambda i: i[col], reverse=rev): + for content in sorted(contents, key=lambda i: i[col], reverse=rev): self.addRow(content) def setHeaderDoubleClickBehaviour(self, mode=None, cols=None): @@ -151,13 +161,11 @@ def setHeaderDoubleClickBehaviour(self, mode=None, cols=None): """ self.unsetHeaderDoubleClickBehaviour() self.headerDoubleClicked = { - "replicate" : self.replicateColumnValue, - "order" : self.orderColumn, - "none" : lambda col : None + "replicate": self.replicateColumnValue, + "order": self.orderColumn, + "none": lambda col: None, }[mode or "none"] - self.horizontalHeader().sectionDoubleClicked.connect( - self.headerDoubleClicked - ) + self.horizontalHeader().sectionDoubleClicked.connect(self.headerDoubleClicked) def unsetHeaderDoubleClickBehaviour(self): """ @@ -179,7 +187,7 @@ def clear(self): for row in range(self.rowCount()): self.tableWidget.removeRow(row) self.tableWidget.setRowCount(0) - + def getValue(self, row, column): """ Gets the value from a table cell. It uses column definitions from @@ -211,14 +219,14 @@ def setValue(self, row, column, value): writeable data (int, float, str, dict, etc). Depends on input widget. """ - if self.headers[column]['type'] == 'item': + if self.headers[column]["type"] == "item": self.tableWidget.item(row, column).setText(value) else: - setter = self.headers[column]['setter'] + setter = self.headers[column]["setter"] widget = self.tableWidget.cellWidget(row, column) if not setter: raise Exception( - self.tr('Setter method must be defined for widget type.') + self.tr("Setter method must be defined for widget type.") ) getattr(widget, setter)(value) @@ -250,10 +258,10 @@ def setSectionResizeMode(self, col, mode): :param mode: (str) resize policy identifier. """ policies = { - "interactive" : QHeaderView.Interactive, - "stretch" : QHeaderView.Stretch, - "fixed" : QHeaderView.Fixed, - "resizetocontents" : QHeaderView.ResizeToContents, + "interactive": QHeaderView.Interactive, + "stretch": QHeaderView.Stretch, + "fixed": QHeaderView.Fixed, + "resizetocontents": QHeaderView.ResizeToContents, } if col < 0 or col >= self.rowCount() or mode not in policies: return @@ -283,9 +291,15 @@ def addNewRow(self, row=None): Adds a new row of items and fill it into table. :param row: (int) position to add the new row. """ - row = self.rowCount() if row is None else \ - 0 if row < 0 else \ - row if row <= self.rowCount() else self.rowCount() + row = ( + self.rowCount() + if row is None + else 0 + if row < 0 + else row + if row <= self.rowCount() + else self.rowCount() + ) # row = row if row is not None else self.rowCount() self.tableWidget.insertRow(row) for col, properties in self.headers.items(): @@ -296,9 +310,7 @@ def addNewRow(self, row=None): item.setFlags(Qt.ItemIsEditable) self.tableWidget.setItem(row, col, item) else: - self.tableWidget.setCellWidget( - row, col, properties["widget"]() - ) + self.tableWidget.setCellWidget(row, col, properties["widget"]()) self.rowAdded.emit(row) def addRow(self, contents, row=None): @@ -307,9 +319,15 @@ def addRow(self, contents, row=None): :param row: (int) position to add the new row. :param contents: (dict) a map to items to be filled. """ - row = self.rowCount() if row is None else \ - 0 if row < 0 else \ - row if row <= self.rowCount() else self.rowCount() + row = ( + self.rowCount() + if row is None + else 0 + if row < 0 + else row + if row <= self.rowCount() + else self.rowCount() + ) self.tableWidget.insertRow(row) for col, properties in self.headers.items(): value = contents[col] if col in contents else None @@ -359,8 +377,7 @@ def itemAt(self, row, col): :param col: (int) item's column to be read. :return: (QTableWIdgetItem/QWidget) cell contents. """ - if row >= self.rowCount() or col >= self.columnCount() \ - or row < 0 or col < 0: + if row >= self.rowCount() or col >= self.columnCount() or row < 0 or col < 0: return None if self.headers[col]["type"] == "item": return self.tableWidget.item(row, col) @@ -391,7 +408,7 @@ def selectedRows(self, reverseOrder=False): """ return sorted( set(i.row() for i in self.tableWidget.selectionModel().selectedRows()), - reverse=reverseOrder + reverse=reverseOrder, ) def selectedColumns(self, reverseOrder=False): @@ -401,8 +418,7 @@ def selectedColumns(self, reverseOrder=False): :return: (list-of-int) ordered list of selected columns' indexes. """ return sorted( - set(i.column() for i in self.selectedIndexes()), - reverse=reverseOrder + set(i.column() for i in self.selectedIndexes()), reverse=reverseOrder ) def selectRow(self, row): @@ -564,7 +580,7 @@ def load(self, filepath): QMessageBox.warning( iface.mainWindow(), self.tr("Unable to import {0}").format(filepath), - "Check file {0}:\n{1}".format(filepath, "\n".join(e.args)) + "Check file {0}:\n{1}".format(filepath, "\n".join(e.args)), ) self.setHeaders(self.headers) @@ -581,7 +597,7 @@ def save(self, filepath): QMessageBox.warning( iface.mainWindow(), self.tr("Unable to export {0}").format(filepath), - "Check file {0}:\n{1}".format(filepath, "\n".join(e.args)) + "Check file {0}:\n{1}".format(filepath, "\n".join(e.args)), ) @pyqtSlot() @@ -592,10 +608,8 @@ def on_loadPushButton_clicked(self): fd = QFileDialog() # fd.setDirectory(QDir.homePath()) filepath = fd.getOpenFileName( - caption=self.tr("Select a {0} to export data from")\ - .format(self.fileType), - filter=self.tr("{0} (*{1})")\ - .format(self.fileType, self.extension), + caption=self.tr("Select a {0} to export data from").format(self.fileType), + filter=self.tr("{0} (*{1})").format(self.fileType, self.extension), ) filepath = filepath[0] if isinstance(filepath, tuple) else filepath if filepath: @@ -606,7 +620,7 @@ def now(self): Gets time and date from the system. Format: "dd/mm/yyyy HH:MM:SS". :return: (str) current's date and time """ - paddle = lambda n : str(n) if n > 9 else "0{0}".format(n) + paddle = lambda n: str(n) if n > 9 else "0{0}".format(n) now = datetime.now() return "{day}/{month}/{year} {hour}:{minute}:{second}".format( year=now.year, @@ -614,7 +628,7 @@ def now(self): day=paddle(now.day), hour=paddle(now.hour), minute=paddle(now.minute), - second=paddle(now.second) + second=paddle(now.second), ) def metadata(self, updated=False): @@ -624,9 +638,7 @@ def metadata(self, updated=False): modification history. """ if not hasattr(self, "_metadata"): - self._metadata = { - "lastModified": self.now() - } + self._metadata = {"lastModified": self.now()} elif updated: self._metadata["lastModified"] = self.now() return dict(self._metadata) @@ -643,15 +655,13 @@ def setMetadata(self, metadata, updated=True): @pyqtSlot() def on_savePushButton_clicked(self): """ - Collects filepath and + Collects filepath and """ fd = QFileDialog() # fd.setDirectory(QDir.homePath()) filepath = fd.getSaveFileName( - caption=self.tr("Select a {0} to export data to")\ - .format(self.fileType), - filter=self.tr("{0} (*{1})")\ - .format(self.fileType, self.extension), + caption=self.tr("Select a {0} to export data to").format(self.fileType), + filter=self.tr("{0} (*{1})").format(self.fileType, self.extension), ) filepath = filepath[0] if isinstance(filepath, tuple) else filepath if filepath: diff --git a/DsgTools/gui/CustomWidgets/OrderedPropertyWidgets/orderedValidationProcessesWidget.py b/DsgTools/gui/CustomWidgets/OrderedPropertyWidgets/orderedValidationProcessesWidget.py index 01b8bbffa..0100c7bf3 100644 --- a/DsgTools/gui/CustomWidgets/OrderedPropertyWidgets/orderedValidationProcessesWidget.py +++ b/DsgTools/gui/CustomWidgets/OrderedPropertyWidgets/orderedValidationProcessesWidget.py @@ -22,27 +22,32 @@ """ import os from collections import OrderedDict + # Qt imports from qgis.PyQt import QtGui, uic from qgis.PyQt.QtCore import pyqtSlot, pyqtSignal, QSettings, Qt from qgis.PyQt.QtWidgets import QTableWidgetItem -from DsgTools.gui.CustomWidgets.OrderedPropertyWidgets.orderedStructureWidget import OrderedStructureWidget -from DsgTools.gui.CustomWidgets.ValidationWidgets.validationProcessWidget import ValidationProcessWidget +from DsgTools.gui.CustomWidgets.OrderedPropertyWidgets.orderedStructureWidget import ( + OrderedStructureWidget, +) +from DsgTools.gui.CustomWidgets.ValidationWidgets.validationProcessWidget import ( + ValidationProcessWidget, +) -class OrderedValidationProcessesWidget(OrderedStructureWidget): +class OrderedValidationProcessesWidget(OrderedStructureWidget): def __init__(self, parent=None): """ Initializates OrderedAttributeRulesWidget """ super(OrderedValidationProcessesWidget, self).__init__(parent) self.args = None - self.tableWidget.setHorizontalHeaderLabels([self.tr('QGIS Processing Models')]) - self.widgetKey = 'validationProcessWidgetList' + self.tableWidget.setHorizontalHeaderLabels([self.tr("QGIS Processing Models")]) + self.widgetKey = "validationProcessWidgetList" self.parent = parent if self.parent: self.validationManager = self.parent.parent().parent().validationManager - + def instantiateWidgetItem(self): - return ValidationProcessWidget(parent = self) \ No newline at end of file + return ValidationProcessWidget(parent=self) diff --git a/DsgTools/gui/CustomWidgets/ProcessingParameterWidgets/fmeManagerWidget.py b/DsgTools/gui/CustomWidgets/ProcessingParameterWidgets/fmeManagerWidget.py index 808fe6a89..9847d9e51 100644 --- a/DsgTools/gui/CustomWidgets/ProcessingParameterWidgets/fmeManagerWidget.py +++ b/DsgTools/gui/CustomWidgets/ProcessingParameterWidgets/fmeManagerWidget.py @@ -33,8 +33,9 @@ from DsgTools.core.Utils.utils import Utils -FORM_CLASS, _ = uic.loadUiType(os.path.join( - os.path.dirname(__file__), "fmeManagerWidget.ui")) +FORM_CLASS, _ = uic.loadUiType( + os.path.join(os.path.dirname(__file__), "fmeManagerWidget.ui") +) class FMEManagerWidget(QWidget, FORM_CLASS): @@ -51,7 +52,7 @@ def clearLayout(self): """ Removes all inserted widgets from workspace's parameters from GUI. """ - for i in range(self.verticalLayout_2.count()-1, -1, -1): + for i in range(self.verticalLayout_2.count() - 1, -1, -1): self.verticalLayout_2.itemAt(i).widget().setParent(None) @pyqtSlot(int) @@ -63,7 +64,7 @@ def on_workspaceComboBox_currentIndexChanged(self): self.clearLayout() workspace = self.getCurrentWorkspace() key = "parameters" if self.version() == "v1" else "parametros" - _parameters = workspace.get(key, list()) + _parameters = workspace.get(key, list()) parameters = filter(lambda x: x != "LOG_FILE", _parameters) for parameter in parameters: newLabel = QLabel(parameter) @@ -76,12 +77,7 @@ def resizeEvent(self, e): """ Resize QgsMessageBar to widget's width """ - self.messageBar.resize( - QSize( - self.geometry().size().width(), - 30 - ) - ) + self.messageBar.resize(QSize(self.geometry().size().width(), 30)) def getProxyInfo(self): """ @@ -139,41 +135,37 @@ def getWorkspacesFromServer(self): jsonKey = "dados" try: if not self.useProxy(): - workspaceList = requests.get( - url, - verify=useSsl, - timeout=15 - ).json()[jsonKey] + workspaceList = requests.get(url, verify=useSsl, timeout=15).json()[ + jsonKey + ] else: proxyInfo, proxyAuth = self.getProxyInfo() workspaceList = requests.get( - url, - proxies=proxyInfo, - auth=proxyAuth, - verify=useSsl, - timeout=15 + url, proxies=proxyInfo, auth=proxyAuth, verify=useSsl, timeout=15 ).json()[jsonKey] except ReadTimeout: self.messageBar.pushMessage( - self.tr("Connection timed out."), level=Qgis.Warning) + self.tr("Connection timed out."), level=Qgis.Warning + ) workspaceList = list() except ConnectTimeout: self.messageBar.pushMessage( - self.tr("Connection timed out (max attempts)."), - level=Qgis.Warning + self.tr("Connection timed out (max attempts)."), level=Qgis.Warning ) workspaceList = list() except InvalidSchema: self.messageBar.pushMessage( self.tr("Missing connection schema (e.g.'http', etc)."), - level=Qgis.Warning + level=Qgis.Warning, ) workspaceList = list() except BaseException as e: self.messageBar.pushMessage( - self.tr("Unexpected error while trying to reach server. " - "Check your parameters. Error message: {}".format(e)), - level=Qgis.Warning + self.tr( + "Unexpected error while trying to reach server. " + "Check your parameters. Error message: {}".format(e) + ), + level=Qgis.Warning, ) workspaceList = list() return workspaceList @@ -181,7 +173,7 @@ def getWorkspacesFromServer(self): def setWorkspaces(self, workspaces): """ Sets a list of workspaces to the GUI. - :param workspaces: (list-of-str) + :param workspaces: (list-of-str) """ self.workspaceComboBox.clear() if workspaces: @@ -216,7 +208,7 @@ def on_loadPushButton_clicked(self): self.workspaceComboBox.addItem( "{name} ({description})".format( name=workspace[workspaceNameKey], - description=workspace[workspaceDescKey] + description=workspace[workspaceDescKey], ) ) @@ -231,16 +223,17 @@ def validate(self, pushAlert=False): if self.useProxy() and not proxyInfo: if pushAlert: self.messageBar.pushMessage( - self.tr("Proxy usage is set but no QGIS proxy settings " - "was found."), - level=Qgis.Warning + self.tr( + "Proxy usage is set but no QGIS proxy settings " "was found." + ), + level=Qgis.Warning, ) return False if self.server() == "": if pushAlert: self.messageBar.pushMessage( self.tr("URL to FME Manager server was not provided."), - level=Qgis.Warning + level=Qgis.Warning, ) return False return True @@ -253,7 +246,9 @@ def getParameters(self): workspaceId = workspace.get("id", None) version = self.version() parameters = { - "parameters" if version == "v1" else "parametros": { + "parameters" + if version == "v1" + else "parametros": { key: value.text() for key, value in self.paramWidgetMap.items() } } @@ -266,5 +261,5 @@ def getParameters(self): "auth": proxyAuth, "proxy_dict": proxyInfo, "use_ssl": self.useSsl(), - "use_proxy": self.useProxy() + "use_proxy": self.useProxy(), } diff --git a/DsgTools/gui/CustomWidgets/ProcessingParameterWidgets/fmeManagerWidget.ui b/DsgTools/gui/CustomWidgets/ProcessingParameterWidgets/fmeManagerWidget.ui index 92ef97131..014265008 100644 --- a/DsgTools/gui/CustomWidgets/ProcessingParameterWidgets/fmeManagerWidget.ui +++ b/DsgTools/gui/CustomWidgets/ProcessingParameterWidgets/fmeManagerWidget.ui @@ -97,4 +97,4 @@ - \ No newline at end of file + diff --git a/DsgTools/gui/CustomWidgets/SelectionWidgets/customReferenceAndLayersParameterSelector.py b/DsgTools/gui/CustomWidgets/SelectionWidgets/customReferenceAndLayersParameterSelector.py index f2943cc36..a53d32ba2 100644 --- a/DsgTools/gui/CustomWidgets/SelectionWidgets/customReferenceAndLayersParameterSelector.py +++ b/DsgTools/gui/CustomWidgets/SelectionWidgets/customReferenceAndLayersParameterSelector.py @@ -28,83 +28,106 @@ from qgis.PyQt.QtCore import pyqtSlot, pyqtSignal -FORM_CLASS, _ = uic.loadUiType(os.path.join( - os.path.dirname(__file__), 'customReferenceAndLayersParameterSelector.ui')) +FORM_CLASS, _ = uic.loadUiType( + os.path.join( + os.path.dirname(__file__), "customReferenceAndLayersParameterSelector.ui" + ) +) -class CustomReferenceAndLayersParameterSelector(QtWidgets.QWidget, FORM_CLASS): - def __init__(self, parent = None): +class CustomReferenceAndLayersParameterSelector(QtWidgets.QWidget, FORM_CLASS): + def __init__(self, parent=None): """Constructor.""" super(CustomReferenceAndLayersParameterSelector, self).__init__(parent) self.referenceLayerKey = None self.selectedLayersItems = [] self.setupUi(self) - + def setTitle(self, title): self.customTableSelectorWidget.setTitle(title) - + @pyqtSlot(int) def on_referenceComboBox_currentIndexChanged(self, idx): if idx == 0: if self.referenceLayerKey and self.unifiedList: - self.customTableSelectorWidget.addItemsToWidget([self.layersTextDict[self.referenceLayerKey]], unique = True) + self.customTableSelectorWidget.addItemsToWidget( + [self.layersTextDict[self.referenceLayerKey]], unique=True + ) self.referenceLayerKey = None self.customTableSelectorWidget.setEnabled(False) else: if self.referenceLayerKey: if self.unifiedList: - self.customTableSelectorWidget.addItemsToWidget([self.layersTextDict[self.referenceLayerKey]], unique = True) + self.customTableSelectorWidget.addItemsToWidget( + [self.layersTextDict[self.referenceLayerKey]], unique=True + ) else: - self.customTableSelectorWidget.addItemsToWidget([self.referenceTextDict[self.referenceLayerKey]], unique = True) + self.customTableSelectorWidget.addItemsToWidget( + [self.referenceTextDict[self.referenceLayerKey]], unique=True + ) self.customTableSelectorWidget.setEnabled(True) self.referenceLayerKey = self.referenceComboBox.currentText() if self.unifiedList: - self.customTableSelectorWidget.removeItemsFromWidget([self.layersTextDict[self.referenceLayerKey]]) + self.customTableSelectorWidget.removeItemsFromWidget( + [self.layersTextDict[self.referenceLayerKey]] + ) else: - self.customTableSelectorWidget.removeItemsFromWidget([self.referenceTextDict[self.referenceLayerKey]]) - + self.customTableSelectorWidget.removeItemsFromWidget( + [self.referenceTextDict[self.referenceLayerKey]] + ) + def setInitialState(self, inputOrderedDict, unique=True): """ Sets the initial state referenceDict: {'cat,lyrName,geom,geomType,tableType':{'tableSchema':tableSchema, 'tableName':tableName, 'geom':geom, 'geomType':geomType, 'tableType':tableType, 'lyrName':lyrName, 'cat':cat}} - referenceDictList: interface ready dict like + referenceDictList: interface ready dict like { - self.tr('Category'):cat, - self.tr('Layer Name'):lyrName, - self.tr('Geometry\nColumn'):geom, - self.tr('Geometry\nType'):geomType, + self.tr('Category'):cat, + self.tr('Layer Name'):lyrName, + self.tr('Geometry\nColumn'):geom, + self.tr('Geometry\nType'):geomType, self.tr('Layer\nType'):tableType } """ - self.referenceDictList = inputOrderedDict['referenceDictList'] - self.layersDictList = inputOrderedDict['layersDictList'] - - #makes referenceTextDict + self.referenceDictList = inputOrderedDict["referenceDictList"] + self.layersDictList = inputOrderedDict["layersDictList"] + + # makes referenceTextDict self.referenceTextDict = OrderedDict() - self.referenceTextDict[self.tr('Select a layer')] = None + self.referenceTextDict[self.tr("Select a layer")] = None sortedRefKeys = list(self.referenceDictList.keys()) sortedRefKeys.sort() for key in sortedRefKeys: - cat, lyrName, geom, geomType, tableType = key.split(',') - textItem = """{0}.{1} ({2}, {3}, {4})""".format(cat, lyrName, geom, geomType, tableType) + cat, lyrName, geom, geomType, tableType = key.split(",") + textItem = """{0}.{1} ({2}, {3}, {4})""".format( + cat, lyrName, geom, geomType, tableType + ) self.referenceTextDict[textItem] = self.referenceDictList[key] - #makes referenceTextDict + # makes referenceTextDict self.layersTextDict = OrderedDict() - self.layersTextDict[self.tr('Select a layer')] = None + self.layersTextDict[self.tr("Select a layer")] = None sortedLyrsKeys = list(self.layersDictList.keys()) sortedLyrsKeys.sort() for key in sortedLyrsKeys: - cat, lyrName, geom, geomType, tableType = key.split(',') - textItem = """{0}.{1} ({2}, {3}, {4})""".format(cat, lyrName, geom, geomType, tableType) + cat, lyrName, geom, geomType, tableType = key.split(",") + textItem = """{0}.{1} ({2}, {3}, {4})""".format( + cat, lyrName, geom, geomType, tableType + ) self.layersTextDict[textItem] = self.layersDictList[key] if len(list(self.referenceTextDict.keys())) == 1: self.unifiedList = True - self.referenceComboBox.addItems(list(self.layersTextDict.keys())) #uses all layers to populate ref combo + self.referenceComboBox.addItems( + list(self.layersTextDict.keys()) + ) # uses all layers to populate ref combo else: self.unifiedList = False - self.referenceComboBox.addItems(list(self.referenceTextDict.keys())) #uses only some layers to populate ref combo - self.customTableSelectorWidget.setInitialState(list(self.layersDictList.values())) - + self.referenceComboBox.addItems( + list(self.referenceTextDict.keys()) + ) # uses only some layers to populate ref combo + self.customTableSelectorWidget.setInitialState( + list(self.layersDictList.values()) + ) + def getParameters(self): """ Gets parameters @@ -116,7 +139,7 @@ def getParameters(self): refItem = self.referenceTextDict[self.referenceLayerKey] originalRefDict = self.referenceDictList try: - referenceKey = [k for (k,v) in originalRefDict.items() if v == refItem][0] + referenceKey = [k for (k, v) in originalRefDict.items() if v == refItem][0] except: referenceKey = None - return referenceKey, self.customTableSelectorWidget.getSelectedNodes() \ No newline at end of file + return referenceKey, self.customTableSelectorWidget.getSelectedNodes() diff --git a/DsgTools/gui/CustomWidgets/SelectionWidgets/customSelector.py b/DsgTools/gui/CustomWidgets/SelectionWidgets/customSelector.py index cf56c7ba9..3482f98ff 100644 --- a/DsgTools/gui/CustomWidgets/SelectionWidgets/customSelector.py +++ b/DsgTools/gui/CustomWidgets/SelectionWidgets/customSelector.py @@ -28,13 +28,15 @@ from qgis.PyQt.QtCore import pyqtSlot, pyqtSignal -FORM_CLASS, _ = uic.loadUiType(os.path.join( - os.path.dirname(__file__), 'customSelector.ui')) +FORM_CLASS, _ = uic.loadUiType( + os.path.join(os.path.dirname(__file__), "customSelector.ui") +) + class CustomSelector(QtWidgets.QWidget, FORM_CLASS): - selectionChanged = pyqtSignal(list,str) + selectionChanged = pyqtSignal(list, str) - def __init__(self, parent = None): + def __init__(self, parent=None): """Constructor.""" super(self.__class__, self).__init__(parent) # Set up the user interface from Designer. @@ -45,7 +47,7 @@ def __init__(self, parent = None): self.fromLs = [] self.toLs = [] self.setupUi(self) - + def clearAll(self): """ Clears everything to return to the initial state @@ -55,7 +57,7 @@ def clearAll(self): self.fromList.clear() self.toList.clear() self.filterLineEdit.clear() - + def setInitialState(self, fromList, unique=False): """ Sets the initial state @@ -63,7 +65,7 @@ def setInitialState(self, fromList, unique=False): self.clearAll() if not isinstance(fromList, int): self.setFromList(fromList, unique) - + def setFromList(self, fromList, unique=False): """ Setting the "from" items (QListWidget and python list) @@ -78,7 +80,7 @@ def setFromList(self, fromList, unique=False): self.fromLs.sort() self.fromList.addItems(fromList) self.fromList.sortItems() - + def addItems(self, addList, unique=False): """ Adding "from" items (QListWidget and python list) @@ -95,7 +97,7 @@ def addItems(self, addList, unique=False): self.fromList.addItems(toAddList) self.fromList.sortItems() self.fromLs.sort() - + def removeItem(self, removeItem): """ Removing items (QListWidget and python list) @@ -113,7 +115,6 @@ def removeItem(self, removeItem): self.toLs.remove(toItem.text()) item = self.toList.takeItem(i) - def setToList(self, toList): """ Setting the "to" items (QListWidget and python list) @@ -121,14 +122,14 @@ def setToList(self, toList): self.toLs = list(toList) self.toList.addItems(self.toLs) self.toList.sortItems() - - def setTitle(self,title): + + def setTitle(self, title): """ Setting the title """ self.groupBox.setTitle(title) - @pyqtSlot(bool, name='on_pushButtonSelectOne_clicked') + @pyqtSlot(bool, name="on_pushButtonSelectOne_clicked") def selectItems(self, isSelected, selectedItems=None): """ Adds the selected items to the "to" list @@ -154,10 +155,10 @@ def selectItems(self, isSelected, selectedItems=None): self.fromLs.remove(item.text()) added.append(item.text()) self.toList.sortItems() - #emits added items + # emits added items if len(added) > 0: - self.selectionChanged.emit(added,'added') - + self.selectionChanged.emit(added, "added") + @pyqtSlot(bool) def on_pushButtonSelectAll_clicked(self): """ @@ -165,16 +166,16 @@ def on_pushButtonSelectAll_clicked(self): """ tam = self.fromList.__len__() added = [] - for i in range(tam+1,1,-1): - item = self.fromList.takeItem(i-2) + for i in range(tam + 1, 1, -1): + item = self.fromList.takeItem(i - 2) self.toList.addItem(item) self.toLs.append(item.text()) added.append(item.text()) self.fromLs.remove(item.text()) self.toList.sortItems() - #emits added items + # emits added items if len(added) > 0: - self.selectionChanged.emit(added,'added') + self.selectionChanged.emit(added, "added") @pyqtSlot(bool) def on_pushButtonDeselectOne_clicked(self): @@ -190,9 +191,9 @@ def on_pushButtonDeselectOne_clicked(self): removed.append(item.text()) self.fromList.addItem(item) self.fromList.sortItems() - #emits removed items + # emits removed items if len(removed) > 0: - self.selectionChanged.emit(removed,'removed') + self.selectionChanged.emit(removed, "removed") @pyqtSlot(bool) def on_pushButtonDeselectAll_clicked(self): @@ -201,23 +202,27 @@ def on_pushButtonDeselectAll_clicked(self): """ tam = self.toList.__len__() removed = [] - for i in range(tam+1,1,-1): - item = self.toList.takeItem(i-2) + for i in range(tam + 1, 1, -1): + item = self.toList.takeItem(i - 2) self.fromLs.append(item.text()) self.toLs.remove(item.text()) self.fromList.addItem(item) removed.append(item.text()) self.fromList.sortItems() - #emits removed items + # emits removed items if len(removed) > 0: - self.selectionChanged.emit(removed,'removed') - + self.selectionChanged.emit(removed, "removed") + def on_filterLineEdit_textChanged(self, text): """ Filters the items to make it easier to spot and select them """ - classes = [edgvClass for edgvClass in self.fromLs if text.lower() in edgvClass.lower()] - filteredClasses = [i for i in classes if i.lower() not in [j.lower() for j in self.toLs]] + classes = [ + edgvClass for edgvClass in self.fromLs if text.lower() in edgvClass.lower() + ] + filteredClasses = [ + i for i in classes if i.lower() not in [j.lower() for j in self.toLs] + ] self.fromList.clear() self.fromList.addItems(classes) self.fromList.sortItems() @@ -234,8 +239,8 @@ def resetSelections(self): and avoid losing items. """ tam = self.toList.__len__() - for i in range(tam+1,1,-1): - item = self.toList.takeItem(i-2) + for i in range(tam + 1, 1, -1): + item = self.toList.takeItem(i - 2) self.fromLs.append(item.text()) self.toLs.remove(item.text()) self.fromLs.sort() diff --git a/DsgTools/gui/CustomWidgets/SelectionWidgets/customSnaperParameterSelector.py b/DsgTools/gui/CustomWidgets/SelectionWidgets/customSnaperParameterSelector.py index a4d9e00f3..ebe83571e 100644 --- a/DsgTools/gui/CustomWidgets/SelectionWidgets/customSnaperParameterSelector.py +++ b/DsgTools/gui/CustomWidgets/SelectionWidgets/customSnaperParameterSelector.py @@ -27,22 +27,24 @@ from qgis.PyQt.QtCore import pyqtSlot, pyqtSignal -FORM_CLASS, _ = uic.loadUiType(os.path.join( - os.path.dirname(__file__), 'customSnaperParameterSelector.ui')) +FORM_CLASS, _ = uic.loadUiType( + os.path.join(os.path.dirname(__file__), "customSnaperParameterSelector.ui") +) + class CustomSnaperParameterSelector(QtWidgets.QWidget, FORM_CLASS): - selectionChanged = pyqtSignal(list,str) + selectionChanged = pyqtSignal(list, str) - def __init__(self, parent = None): + def __init__(self, parent=None): """Constructor.""" super(self.__class__, self).__init__(parent) self.referenceLayer = None self.selectedLayers = [] self.setupUi(self) - + def setTitle(self, title): self.customSelectorWidget.setTitle(title) - + @pyqtSlot(int) def on_referenceComboBox_currentIndexChanged(self, idx): if idx == 0: @@ -58,14 +60,16 @@ def on_referenceComboBox_currentIndexChanged(self, idx): self.referenceLayer = self.referenceComboBox.currentText() if self.unifiedList: self.customSelectorWidget.removeItem(self.referenceLayer) - - def setInitialState(self, referenceList, originalList, unique=False, parameterDict = {}): + + def setInitialState( + self, referenceList, originalList, unique=False, parameterDict={} + ): """ Sets the initial state """ self.originalList = originalList self.customSelectorWidget.addItems(originalList) - self.referenceComboBox.addItem(self.tr('Select a layer')) + self.referenceComboBox.addItem(self.tr("Select a layer")) originalList.sort() if len(referenceList) == 0: self.unifiedList = True @@ -75,7 +79,7 @@ def setInitialState(self, referenceList, originalList, unique=False, parameterDi self.referenceComboBox.addItems(referenceList) if parameterDict: self.populateInterface(parameterDict) - + def getParameters(self): """ Gets parameters @@ -83,10 +87,12 @@ def getParameters(self): return self.referenceLayer, self.customSelectorWidget.toLs def getParameterDict(self): - return OrderedDict({'referenceDictList':interfaceLineDict, 'layersDictList':interfaceDict}) - + return OrderedDict( + {"referenceDictList": interfaceLineDict, "layersDictList": interfaceDict} + ) + def populateInterface(self, parameterDict): """ Sets saved state """ - pass \ No newline at end of file + pass diff --git a/DsgTools/gui/CustomWidgets/SelectionWidgets/customTableSelector.py b/DsgTools/gui/CustomWidgets/SelectionWidgets/customTableSelector.py index d56fb9c11..a74e82e4b 100644 --- a/DsgTools/gui/CustomWidgets/SelectionWidgets/customTableSelector.py +++ b/DsgTools/gui/CustomWidgets/SelectionWidgets/customTableSelector.py @@ -31,31 +31,37 @@ from ....core.Utils.utils import Utils -FORM_CLASS, _ = uic.loadUiType(os.path.join( - os.path.dirname(__file__), 'customTableSelector.ui')) +FORM_CLASS, _ = uic.loadUiType( + os.path.join(os.path.dirname(__file__), "customTableSelector.ui") +) + class CustomTableSelector(QtWidgets.QWidget, FORM_CLASS): - selectionChanged = pyqtSignal(list,str) + selectionChanged = pyqtSignal(list, str) - def __init__(self, customNumber = None, parent = None): + def __init__(self, customNumber=None, parent=None): """Constructor.""" super(self.__class__, self).__init__(parent) self.fromLs = [] self.toLs = [] self.utils = Utils() self.setupUi(self) - + def resizeTrees(self): """ Expands headers """ self.fromTreeWidget.expandAll() - self.fromTreeWidget.header().setSectionResizeMode(QtWidgets.QHeaderView.ResizeToContents) + self.fromTreeWidget.header().setSectionResizeMode( + QtWidgets.QHeaderView.ResizeToContents + ) self.fromTreeWidget.header().setStretchLastSection(False) self.toTreeWidget.expandAll() - self.toTreeWidget.header().setSectionResizeMode(QtWidgets.QHeaderView.ResizeToContents) + self.toTreeWidget.header().setSectionResizeMode( + QtWidgets.QHeaderView.ResizeToContents + ) self.toTreeWidget.header().setStretchLastSection(False) - + def sortItems(self, treeWidget): """ Sorts items from input treeWidget @@ -64,14 +70,14 @@ def sortItems(self, treeWidget): rootNode.sortChildren(0, Qt.AscendingOrder) for i in range(rootNode.childCount()): rootNode.child(i).sortChildren(1, Qt.AscendingOrder) - - def setTitle(self,title): + + def setTitle(self, title): """ Setting the title """ self.groupBox.setTitle(title) - - def setFilterColumn(self, customNumber = None): + + def setFilterColumn(self, customNumber=None): """ Chooses which column is going to be used in the filter """ @@ -81,23 +87,23 @@ def setFilterColumn(self, customNumber = None): self.filterColumnKey = self.headerList[1] else: self.filterColumnKey = self.headerList[0] - + def clearAll(self): """ Clears everything to return to the initial state """ self.filterLineEdit.clear() - - def setHeaders(self, headerList, customNumber = None): + + def setHeaders(self, headerList, customNumber=None): """ Sets fromTreeWidget and toTreeWidget headers """ self.headerList = headerList self.fromTreeWidget.setHeaderLabels(headerList) self.toTreeWidget.setHeaderLabels(headerList) - self.setFilterColumn(customNumber = customNumber) - - def setInitialState(self, fromDictList, unique=False, selectedDictList = []): + self.setFilterColumn(customNumber=customNumber) + + def setInitialState(self, fromDictList, unique=False, selectedDictList=[]): """ Sets the initial state """ @@ -106,10 +112,16 @@ def setInitialState(self, fromDictList, unique=False, selectedDictList = []): self.fromTreeWidget.clear() self.fromTreeWidget.clear() if not isinstance(fromDictList, int): - self.addItemsToTree(self.fromTreeWidget, fromDictList, self.fromLs, unique = unique, selectedDictList = selectedDictList) + self.addItemsToTree( + self.fromTreeWidget, + fromDictList, + self.fromLs, + unique=unique, + selectedDictList=selectedDictList, + ) if selectedDictList: self.pushButtonSelectOne.clicked.emit() - + def getChildNode(self, parentNode, textList): """ Returns child node with columns equals to textList items. If no node is found, return None @@ -125,35 +137,49 @@ def getChildNode(self, parentNode, textList): return childNode return None - def addItemsToTree(self, treeWidget, addItemDictList, controlList, unique = False, selectedDictList = []): + def addItemsToTree( + self, + treeWidget, + addItemDictList, + controlList, + unique=False, + selectedDictList=[], + ): """ Adds items from addItemDictList in treeWidget. addItemDictList = [-list of dicts with keys corresponding to header list texts-] unique: only adds item if it is not in already in tree """ - rootNode = treeWidget.invisibleRootItem() #invisible root item + rootNode = treeWidget.invisibleRootItem() # invisible root item for dictItem in addItemDictList: - firstColumnChild = self.getChildNode(rootNode, [dictItem[self.headerList[0]]]+['']*(len(self.headerList)-1)) #looks for a item in the format ['first column text', '','',...,''] + firstColumnChild = self.getChildNode( + rootNode, + [dictItem[self.headerList[0]]] + [""] * (len(self.headerList) - 1), + ) # looks for a item in the format ['first column text', '','',...,''] if not firstColumnChild: - firstColumnChild = self.utils.createWidgetItem(rootNode,dictItem[self.headerList[0]],0) - textList = [dictItem[self.headerList[i]] for i in range(len(self.headerList))] + firstColumnChild = self.utils.createWidgetItem( + rootNode, dictItem[self.headerList[0]], 0 + ) + textList = [ + dictItem[self.headerList[i]] for i in range(len(self.headerList)) + ] if unique: childNode = self.getChildNode(firstColumnChild, textList) if not childNode: - item = self.utils.createWidgetItem(firstColumnChild,textList) + item = self.utils.createWidgetItem(firstColumnChild, textList) if selectedDictList: item.setSelected(True) itemList = self.getItemList(item) if itemList not in controlList: controlList.append(itemList) else: - item = self.utils.createWidgetItem(firstColumnChild,textList) + item = self.utils.createWidgetItem(firstColumnChild, textList) itemList = self.getItemList(item) controlList.append(itemList) self.resizeTrees() self.sortItems(treeWidget) - - def getItemList(self, item, returnAsDict = False): + + def getItemList(self, item, returnAsDict=False): """ Gets item as a list """ @@ -173,35 +199,41 @@ def getLists(self, sender): Returns a list composed by (originTreeWidget, --list that controls previous originTreeWidget--, destinationTreeWidget, --list that controls previous destinationTreeWidget--) """ text = sender.text() - if text == '>': + if text == ">": return self.fromTreeWidget, self.fromLs, self.toTreeWidget, self.toLs, False - if text == '>>': + if text == ">>": return self.fromTreeWidget, self.fromLs, self.toTreeWidget, self.toLs, True - if text == '<': + if text == "<": return self.toTreeWidget, self.toLs, self.fromTreeWidget, self.fromLs, False - if text == '<<': + if text == "<<": return self.toTreeWidget, self.toLs, self.fromTreeWidget, self.fromLs, True - @pyqtSlot(bool, name='on_pushButtonSelectOne_clicked') - @pyqtSlot(bool, name='on_pushButtonDeselectOne_clicked') - @pyqtSlot(bool, name='on_pushButtonSelectAll_clicked') - @pyqtSlot(bool, name='on_pushButtonDeselectAll_clicked') + @pyqtSlot(bool, name="on_pushButtonSelectOne_clicked") + @pyqtSlot(bool, name="on_pushButtonDeselectOne_clicked") + @pyqtSlot(bool, name="on_pushButtonSelectAll_clicked") + @pyqtSlot(bool, name="on_pushButtonDeselectAll_clicked") def selectItems(self, isSelected, selectedItems=[]): """ Adds the selected items to the "to" list """ - #gets lists - originTreeWidget, originControlLs, destinationTreeWidget, destinationControlLs, allItems = self.getLists(self.sender()) - #root nodes + # gets lists + ( + originTreeWidget, + originControlLs, + destinationTreeWidget, + destinationControlLs, + allItems, + ) = self.getLists(self.sender()) + # root nodes originRoot = originTreeWidget.invisibleRootItem() destinationRoot = destinationTreeWidget.invisibleRootItem() selectedItemList = [] self.getSelectedItems(originRoot, selectedItemList) for i in range(originRoot.childCount())[::-1]: catChild = originRoot.child(i) - #if son of originRootNode is selected, adds it to destinationRootNode + # if son of originRootNode is selected, adds it to destinationRootNode moveNode = allItems or (catChild in selectedItemList) - #get destination parent, creates one in destination if not exists + # get destination parent, creates one in destination if not exists destinationCatChild = self.getDestinationNode(destinationRoot, catChild) for j in range(catChild.childCount())[::-1]: nodeChild = catChild.child(j) @@ -230,7 +262,7 @@ def getSelectedItems(self, treeWidgetNode, itemList): itemList.append(childItem) for j in range(childItem.childCount()): self.getSelectedItems(childItem, itemList) - + def moveChild(self, parentNode, idx, destinationNode, isSelected): """ If node is selected, removes node from parentNode and adds it to destinationNode @@ -242,13 +274,13 @@ def moveChild(self, parentNode, idx, destinationNode, isSelected): else: return False - def getDestinationNode(self, destinationRoot, catChild, returnNew = True): + def getDestinationNode(self, destinationRoot, catChild, returnNew=True): """ Looks for node in destination and returns it. If none is found, creates one and returns it """ - #get destination parent, creates one in destination if not exists + # get destination parent, creates one in destination if not exists destinationCatChild = None - if isinstance(catChild,list): + if isinstance(catChild, list): comparisonText = catChild[0] if returnNew: itemTextList = [catChild[i] for i in range(len(catChild))] @@ -260,42 +292,48 @@ def getDestinationNode(self, destinationRoot, catChild, returnNew = True): for i in range(destinationRoot.childCount()): candidate = destinationRoot.child(i) if candidate.text(0) == comparisonText: - #if candidate is found, returns candidate + # if candidate is found, returns candidate return candidate - #if candidate is not found, creates one and returns it + # if candidate is not found, creates one and returns it if returnNew: if not destinationCatChild: - return QTreeWidgetItem(destinationRoot,itemTextList) + return QTreeWidgetItem(destinationRoot, itemTextList) else: return None - + def on_filterLineEdit_textChanged(self, text): """ Filters the items to make it easier to spot and select them """ - classes = [node[1].lower() for node in self.fromLs if text.lower() in node[1].lower()] #text list - filteredClasses = [i for i in classes if i.lower() not in [j[1].lower() for j in self.toLs]] #text list + classes = [ + node[1].lower() for node in self.fromLs if text.lower() in node[1].lower() + ] # text list + filteredClasses = [ + i for i in classes if i.lower() not in [j[1].lower() for j in self.toLs] + ] # text list self.filterTree(self.fromTreeWidget, self.fromLs, filteredClasses, 1) self.resizeTrees() - + def filterTree(self, treeWidget, controlList, filterList, columnIdx): - ''' + """ Actual filter - ''' + """ treeWidget.clear() rootNode = treeWidget.invisibleRootItem() - #remove items that are not in filterList + # remove items that are not in filterList for item in controlList: if item[columnIdx].lower() in filterList: - firstColumnChild = self.getChildNode(rootNode, [item[0]]+['']*(len(item)-1)) #looks for a item in the format ['first column text', '','',...,''] + firstColumnChild = self.getChildNode( + rootNode, [item[0]] + [""] * (len(item) - 1) + ) # looks for a item in the format ['first column text', '','',...,''] if not firstColumnChild: firstColumnChild = self.utils.createWidgetItem(rootNode, item[0], 0) QTreeWidgetItem(firstColumnChild, item) rootNode.sortChildren(0, Qt.AscendingOrder) for i in range(rootNode.childCount()): rootNode.child(i).sortChildren(1, Qt.AscendingOrder) - - def getSelectedNodes(self, concatenated = True): + + def getSelectedNodes(self, concatenated=True): """ Returns a list of selected nodes converted into a string separated by ',' """ @@ -307,28 +345,28 @@ def getSelectedNodes(self, concatenated = True): item = catNode.child(j) if concatenated: catList = [item.text(i) for i in range(item.columnCount())] - selected.append(','.join(catList)) + selected.append(",".join(catList)) else: selected.append(item) return selected - def addItemsToWidget(self, itemList, unique = False): + def addItemsToWidget(self, itemList, unique=False): """ Adds items to tree that is already built. """ - self.addItemsToTree(self.fromTreeWidget, itemList, self.fromLs, unique = unique) - + self.addItemsToTree(self.fromTreeWidget, itemList, self.fromLs, unique=unique) + def removeItemsFromWidget(self, removeList): """ Searches both lists and removes items that are in removeList """ self.removeItemsFromTree(removeList, self.fromTreeWidget, self.fromLs) self.removeItemsFromTree(removeList, self.toTreeWidget, self.toLs) - + def removeItemsFromTree(self, dictItemList, treeWidget, controlList): """ Searches treeWidget and removes items that are in removeList and updates controlList - """ + """ treeRoot = treeWidget.invisibleRootItem() catList = [i[self.headerList[0]] for i in dictItemList] returnList = [] @@ -337,7 +375,7 @@ def removeItemsFromTree(self, dictItemList, treeWidget, controlList): if catChild.text(0) in catList: for j in range(catChild.childCount())[::-1]: nodeChild = catChild.child(j) - nodeChildDict = self.getItemList(nodeChild, returnAsDict = True) + nodeChildDict = self.getItemList(nodeChild, returnAsDict=True) nodeChildDict[self.headerList[0]] = catChild.text(0) if nodeChildDict in dictItemList: catChild.takeChild(j) diff --git a/DsgTools/gui/CustomWidgets/SelectionWidgets/customTableWidget.py b/DsgTools/gui/CustomWidgets/SelectionWidgets/customTableWidget.py index 38493c601..ae0b4ef0c 100644 --- a/DsgTools/gui/CustomWidgets/SelectionWidgets/customTableWidget.py +++ b/DsgTools/gui/CustomWidgets/SelectionWidgets/customTableWidget.py @@ -32,14 +32,16 @@ from qgis.PyQt.QtWidgets import QFileDialog -FORM_CLASS, _ = uic.loadUiType(os.path.join( - os.path.dirname(__file__), 'customTableWidget.ui')) +FORM_CLASS, _ = uic.loadUiType( + os.path.join(os.path.dirname(__file__), "customTableWidget.ui") +) + class ValidatedItemDelegate(QtWidgets.QStyledItemDelegate): - def defineValidatorList(self, validatorList, maskList = None): + def defineValidatorList(self, validatorList, maskList=None): self.validatorList = validatorList if not maskList: - self.maskList = [None]*len(self.validatorList) + self.maskList = [None] * len(self.validatorList) else: self.maskList = maskList @@ -54,40 +56,42 @@ def createEditor(self, widget, option, index): return editor return super(ValidatedItemDelegate, self).createEditor(widget, option, index) + class CustomTableWidget(QtWidgets.QWidget, FORM_CLASS): filesSelected = pyqtSignal() - def __init__(self, parent = None): + + def __init__(self, parent=None): """Constructor.""" super(self.__class__, self).__init__(parent) self.setupUi(self) - + def setHeaders(self, headerList): for header in headerList: currColumn = self.tableWidget.columnCount() self.tableWidget.insertColumn(currColumn) self.tableWidget.setHorizontalHeaderLabels(headerList) - + def setValidator(self, validatorList): itemDelegate = ValidatedItemDelegate() itemDelegate.defineValidatorList(validatorList) self.tableWidget.setItemDelegate(itemDelegate) - - @pyqtSlot(bool, name = 'on_addPushButton_clicked') - def addItems(self, itemList = []): + + @pyqtSlot(bool, name="on_addPushButton_clicked") + def addItems(self, itemList=[]): if isinstance(itemList, bool): - oneItemList = ['' for i in range(self.tableWidget.columnCount())] + oneItemList = ["" for i in range(self.tableWidget.columnCount())] self.addOneItem(oneItemList) else: for item in itemList: self.addOneItem(item) - + def addOneItem(self, oneItemList): rowCount = self.tableWidget.rowCount() self.tableWidget.insertRow(rowCount) for i in range(len(oneItemList)): newItem = QtGui.QTableWidgetItem(oneItemList[i]) self.tableWidget.setItem(rowCount, i, newItem) - + @pyqtSlot(bool) def on_removePushButton_clicked(self): selected = self.tableWidget.selectedIndexes() @@ -97,7 +101,7 @@ def on_removePushButton_clicked(self): self.tableWidget.removeRow(row) self.validatorList.pop(row) self.maskList.pop(row) - + def clearItems(self): rowList = list(range(self.tableWidget.rowCount())) rowList.sort(reverse=True) diff --git a/DsgTools/gui/CustomWidgets/SelectionWidgets/listSelector.py b/DsgTools/gui/CustomWidgets/SelectionWidgets/listSelector.py index cf4deb2c9..987e3e965 100644 --- a/DsgTools/gui/CustomWidgets/SelectionWidgets/listSelector.py +++ b/DsgTools/gui/CustomWidgets/SelectionWidgets/listSelector.py @@ -27,28 +27,37 @@ # Qt imports from qgis.PyQt import QtWidgets, uic from qgis.PyQt.QtCore import pyqtSlot, Qt -from qgis.PyQt.QtWidgets import QListWidgetItem, QMessageBox, QMenu, QApplication, QFileDialog +from qgis.PyQt.QtWidgets import ( + QListWidgetItem, + QMessageBox, + QMenu, + QApplication, + QFileDialog, +) from qgis.PyQt.QtGui import QCursor -FORM_CLASS, _ = uic.loadUiType(os.path.join( - os.path.dirname(__file__), 'listSelector.ui')) +FORM_CLASS, _ = uic.loadUiType( + os.path.join(os.path.dirname(__file__), "listSelector.ui") +) + class ListSelector(QtWidgets.QDialog, FORM_CLASS): - - def __init__(self, originList, destinationList, parent = None): + def __init__(self, originList, destinationList, parent=None): """Constructor.""" super(self.__class__, self).__init__(parent) self.setupUi(self) self.originList = originList self.destinationList = destinationList - self.listCustomSelector.setTitle(self.tr('Select')) - self.listCustomSelector.setFromList(list(originList), unique = True) #passes a copy using list() + self.listCustomSelector.setTitle(self.tr("Select")) + self.listCustomSelector.setFromList( + list(originList), unique=True + ) # passes a copy using list() self.listCustomSelector.setToList(list(destinationList)) - + def getSelected(self): return self.listCustomSelector.toLs - + def getInputAndOutputLists(self): return (self.listCustomSelector.fromLs, self.listCustomSelector.toLs) @@ -58,4 +67,4 @@ def on_buttonBox_accepted(self): @pyqtSlot() def on_buttonBox_rejected(self): - self.done(0) \ No newline at end of file + self.done(0) diff --git a/DsgTools/gui/CustomWidgets/SelectionWidgets/selectFileWidget.py b/DsgTools/gui/CustomWidgets/SelectionWidgets/selectFileWidget.py index 7e22e2041..84f1cec92 100644 --- a/DsgTools/gui/CustomWidgets/SelectionWidgets/selectFileWidget.py +++ b/DsgTools/gui/CustomWidgets/SelectionWidgets/selectFileWidget.py @@ -31,20 +31,23 @@ from qgis.PyQt.QtWidgets import QFileDialog -FORM_CLASS, _ = uic.loadUiType(os.path.join( - os.path.dirname(__file__), 'selectFileWidget.ui')) +FORM_CLASS, _ = uic.loadUiType( + os.path.join(os.path.dirname(__file__), "selectFileWidget.ui") +) + class SelectFileWidget(QtWidgets.QWidget, FORM_CLASS): filesSelected = pyqtSignal() - def __init__(self, parent = None): + + def __init__(self, parent=None): """Constructor.""" super(self.__class__, self).__init__(parent) self.setupUi(self) self.fileNameList = [] self.lineEdit.setReadOnly(True) - self.caption = '' - self.filter = '' - self.type = 'single' + self.caption = "" + self.filter = "" + self.type = "single" @pyqtSlot(bool) def on_selectFilePushButton_clicked(self): @@ -53,48 +56,56 @@ def on_selectFilePushButton_clicked(self): """ fd = QFileDialog() fd.setDirectory(QDir.homePath()) - if self.type == 'multi': - self.fileNameList = fd.getOpenFileNames(caption=self.caption, filter=self.filter) - selectedFiles = ', '.join(self.fileNameList[0]) - elif self.type == 'single': + if self.type == "multi": + self.fileNameList = fd.getOpenFileNames( + caption=self.caption, filter=self.filter + ) + selectedFiles = ", ".join(self.fileNameList[0]) + elif self.type == "single": selectedFiles = fd.getOpenFileName(caption=self.caption, filter=self.filter) if isinstance(selectedFiles, tuple): self.fileNameList = selectedFiles[0] - elif self.type == 'dir': - selectedFiles = fd.getExistingDirectory(directory=os.path.expanduser('~'), caption=self.caption, options=QFileDialog.ShowDirsOnly) - if selectedFiles != '': - self.fileNameList = [selectedFiles] - selectedFiles = selectedFiles[0] if isinstance(selectedFiles, tuple) else selectedFiles + elif self.type == "dir": + selectedFiles = fd.getExistingDirectory( + directory=os.path.expanduser("~"), + caption=self.caption, + options=QFileDialog.ShowDirsOnly, + ) + if selectedFiles != "": + self.fileNameList = [selectedFiles] + selectedFiles = ( + selectedFiles[0] if isinstance(selectedFiles, tuple) else selectedFiles + ) self.lineEdit.setText(selectedFiles) self.filesSelected.emit() - + def resetAll(self): """ Resets all """ self.lineEdit.clear() self.fileNameList = [] - + def setTitle(self, text): """ Sets the label title """ self.label.setText(text) - + def setCaption(self, caption): """ Sets the caption """ self.caption = caption - + def setFilter(self, filter): """ Sets the file filter """ self.filter = filter - + def setType(self, type): """ Sets selection type (e.g multi, single, dir) """ - self.type = type \ No newline at end of file + self.type = type diff --git a/DsgTools/gui/CustomWidgets/SelectionWidgets/selectTaskWizard.py b/DsgTools/gui/CustomWidgets/SelectionWidgets/selectTaskWizard.py index 468a34398..b5824e16d 100644 --- a/DsgTools/gui/CustomWidgets/SelectionWidgets/selectTaskWizard.py +++ b/DsgTools/gui/CustomWidgets/SelectionWidgets/selectTaskWizard.py @@ -7,7 +7,7 @@ git sha : $Format:%H$ copyright : (C) 2017 by Philipe Borba - Cartographic Engineer @ Brazilian Army email : borba.philipe@eb.mil.br - mod history : + mod history : ***************************************************************************/ /*************************************************************************** @@ -21,15 +21,17 @@ """ import os, json -#PyQt imports +# PyQt imports from qgis.PyQt import QtWidgets, QtCore, uic from qgis.PyQt.QtCore import pyqtSlot, Qt from qgis.PyQt.QtWidgets import QApplication, QMessageBox from qgis.PyQt.QtGui import QCursor -#DsgTools imports -FORM_CLASS, _ = uic.loadUiType(os.path.join( - os.path.dirname(__file__), 'selectTaskWizard.ui')) +# DsgTools imports +FORM_CLASS, _ = uic.loadUiType( + os.path.join(os.path.dirname(__file__), "selectTaskWizard.ui") +) + class SelectTaskWizard(QtWidgets.QDialog, FORM_CLASS): def __init__(self, iface, settingList, parent=None): @@ -40,20 +42,20 @@ def __init__(self, iface, settingList, parent=None): self.setupUi(self) self.hideSettings(True) self.settingList = settingList - + def hideSettings(self, hide): self.settingComboBox.hide(hide) self.label.hide(hide) - + def populateSettingCombo(self, settingList): self.settingComboBox.clear() - self.settingComboBox.addItem(self.tr('Select one setting')) + self.settingComboBox.addItem(self.tr("Select one setting")) for setting in settingList: self.settingComboBox.addItem(setting) - - @pyqtSlot(name='on_importRadioButton_toggled') - @pyqtSlot(name='on_createNewRadioButton_toggled') - @pyqtSlot(name='on_installRadioButton_toggled') + + @pyqtSlot(name="on_importRadioButton_toggled") + @pyqtSlot(name="on_createNewRadioButton_toggled") + @pyqtSlot(name="on_installRadioButton_toggled") def manageCombos(self): if self.installRadioButton.checkState() == Qt.Checked: self.hideSettings(False) @@ -64,17 +66,21 @@ def manageCombos(self): def validateCurrentPage(self): if self.currentId() == 0: - if self.importRadioButton.checkState() == Qt.Unchecked() and self.createNewRadioButton.checkState() == Qt.Unchecked() and self.installRadioButton.checkState() == Qt.Unchecked(): - errorMsg = self.tr('An option must be chosen!\n') - QMessageBox.warning(self, self.tr('Error!'), errorMsg) + if ( + self.importRadioButton.checkState() == Qt.Unchecked() + and self.createNewRadioButton.checkState() == Qt.Unchecked() + and self.installRadioButton.checkState() == Qt.Unchecked() + ): + errorMsg = self.tr("An option must be chosen!\n") + QMessageBox.warning(self, self.tr("Error!"), errorMsg) return False if self.installRadioButton.checkState() == Qt.Checked(): if self.settingComboBox.currentIndex() == 0: - errorMsg = self.tr('A setting must be chosen!\n') - QMessageBox.warning(self, self.tr('Error!'), errorMsg) + errorMsg = self.tr("A setting must be chosen!\n") + QMessageBox.warning(self, self.tr("Error!"), errorMsg) return False else: return True return True else: - return True \ No newline at end of file + return True diff --git a/DsgTools/gui/CustomWidgets/SelectionWidgets/tabDbSelectorWidget.py b/DsgTools/gui/CustomWidgets/SelectionWidgets/tabDbSelectorWidget.py index e5d0aac27..b1ca9de39 100644 --- a/DsgTools/gui/CustomWidgets/SelectionWidgets/tabDbSelectorWidget.py +++ b/DsgTools/gui/CustomWidgets/SelectionWidgets/tabDbSelectorWidget.py @@ -28,14 +28,15 @@ from qgis.PyQt.QtWidgets import QMessageBox +FORM_CLASS, _ = uic.loadUiType( + os.path.join(os.path.dirname(__file__), "tabDbSelectorWidget.ui") +) -FORM_CLASS, _ = uic.loadUiType(os.path.join( - os.path.dirname(__file__), 'tabDbSelectorWidget.ui')) class TabDbSelectorWidget(QtWidgets.QWidget, FORM_CLASS): - selectionChanged = pyqtSignal(list,str) + selectionChanged = pyqtSignal(list, str) - def __init__(self, parent = None): + def __init__(self, parent=None): """Constructor.""" super(self.__class__, self).__init__(parent) # Set up the user interface from Designer. @@ -50,16 +51,20 @@ def __init__(self, parent = None): def setSpatiaLitePage(self): """ - By default, select files comes "clean", this method adapts it for SpatiaLite databases. + By default, select files comes "clean", this method adapts it for SpatiaLite databases. """ - self.outputDirSelector.setCaption(self.tr("Select a path to save the SpatiaLite database")) + self.outputDirSelector.setCaption( + self.tr("Select a path to save the SpatiaLite database") + ) self.outputDirSelector.setType("dir") def setGeopackagePage(self): """ - By default, select files comes "clean", this method adapts it for Geopackage databases. + By default, select files comes "clean", this method adapts it for Geopackage databases. """ - self.outputDirSelectorGeopackage.setCaption(self.tr("Select a path to save the Geopackage database")) + self.outputDirSelectorGeopackage.setCaption( + self.tr("Select a path to save the Geopackage database") + ) self.outputDirSelectorGeopackage.setType("dir") @pyqtSlot(int) @@ -77,13 +82,17 @@ def validate(self): """ if self.tabWidget.currentIndex() == 0: if self.serverWidget.serversCombo.currentIndex() == 0: - QMessageBox.critical(self, self.tr('Critical!'), self.tr('Select a server!')) + QMessageBox.critical( + self, self.tr("Critical!"), self.tr("Select a server!") + ) return False else: return True elif self.tabWidget.currentIndex() == 1: if self.outputDirSelector.fileNameList == []: - QMessageBox.critical(self, self.tr('Critical!'), self.tr('Select a folder!')) + QMessageBox.critical( + self, self.tr("Critical!"), self.tr("Select a folder!") + ) return False else: return True @@ -93,27 +102,33 @@ def validate(self): # return False # else: # return True - + def getFactoryCreationParam(self): """ Adjusts the database selection according to the database type """ - if self.tabWidget.currentIndex() == 0 and self.serverWidget.serversCombo.currentIndex() > 0: - return self.serverWidget.abstractDb - elif self.tabWidget.currentIndex() == 1 and self.outputDirSelector.fileNameList != []: + if ( + self.tabWidget.currentIndex() == 0 + and self.serverWidget.serversCombo.currentIndex() > 0 + ): + return self.serverWidget.abstractDb + elif ( + self.tabWidget.currentIndex() == 1 + and self.outputDirSelector.fileNameList != [] + ): return self.outputDirSelector.fileNameList[0] # elif self.tabWidget.currentIndex() == 2 and self.outputDirSelectorGeopackage.fileNameList != []: # return self.outputDirSelectorGeopackage.fileNameList[0] else: return None - + def getType(self): """ gets database type (QPSQL, QSQLITE, GPKG) """ if self.tabWidget.currentIndex() == 0: - return 'QPSQL' + return "QPSQL" elif self.tabWidget.currentIndex() == 1: - return 'QSQLITE' + return "QSQLITE" # elif self.tabWidget.currentIndex() == 2: - # return 'GPKG' \ No newline at end of file + # return 'GPKG' diff --git a/DsgTools/gui/CustomWidgets/ValidationWidgets/validationProcessWidget.py b/DsgTools/gui/CustomWidgets/ValidationWidgets/validationProcessWidget.py index b2ffa41a8..2c992b9e1 100644 --- a/DsgTools/gui/CustomWidgets/ValidationWidgets/validationProcessWidget.py +++ b/DsgTools/gui/CustomWidgets/ValidationWidgets/validationProcessWidget.py @@ -28,39 +28,47 @@ # Qt imports from qgis.PyQt import QtWidgets, uic from qgis.PyQt.QtCore import pyqtSlot, Qt, QSettings -from qgis.PyQt.QtWidgets import QListWidgetItem, QMessageBox, QMenu, QApplication, QFileDialog +from qgis.PyQt.QtWidgets import ( + QListWidgetItem, + QMessageBox, + QMenu, + QApplication, + QFileDialog, +) from qgis.PyQt.QtGui import QCursor from qgis.PyQt.QtSql import QSqlDatabase, QSqlQuery -FORM_CLASS, _ = uic.loadUiType(os.path.join( - os.path.dirname(__file__), 'validationProcessWidget.ui')) +FORM_CLASS, _ = uic.loadUiType( + os.path.join(os.path.dirname(__file__), "validationProcessWidget.ui") +) + class ValidationProcessWidget(QtWidgets.QWidget, FORM_CLASS): - def __init__(self, parameterDict = {}, parent = None): + def __init__(self, parameterDict={}, parent=None): """Constructor.""" - super(ValidationProcessWidget, self).__init__(parent = parent) + super(ValidationProcessWidget, self).__init__(parent=parent) self.setupUi(self) self.parent = parent if self.parent: self.validationManager = parent.validationManager - self.validKeys = ['halt', 'validationProcess'] + self.validKeys = ["halt", "validationProcess"] self.parameters = None self.setInitialState() if parameterDict != {}: self.populateInterface(parameterDict) - + def setInitialState(self): self.validationProcessComboBox.clear() - self.validationProcessComboBox.addItem(self.tr('Select a model')) + self.validationProcessComboBox.addItem(self.tr("Select a model")) for model in self.validationManager.modelList: self.validationProcessComboBox.addItem(model.displayName()) - + def clearAll(self): """ Clears all widget information """ pass - + def getParameterDict(self): """ Components: @@ -70,7 +78,9 @@ def getParameterDict(self): if not self.validate(): raise Exception(self.invalidatedReason()) parameterDict = dict() - parameterDict['validationProcess'] = self.validationProcessComboBox.currentText() + parameterDict[ + "validationProcess" + ] = self.validationProcessComboBox.currentText() return parameterDict def populateInterface(self, parameterDict): @@ -79,10 +89,12 @@ def populateInterface(self, parameterDict): """ if parameterDict: if not self.validateJson(parameterDict): - raise Exception(self.tr('Invalid Validation Process Widget json config!')) - #set layer combo - self.validationProcessComboBox.setText(parameterDict['validationProcess']) - + raise Exception( + self.tr("Invalid Validation Process Widget json config!") + ) + # set layer combo + self.validationProcessComboBox.setText(parameterDict["validationProcess"]) + def validateJson(self, inputJson): """ Validates input json @@ -98,15 +110,15 @@ def validate(self): """ Validates fields. Returns True if all information are filled correctly. """ - if self.attributeRuleTypeLineEdit.text() == '': + if self.attributeRuleTypeLineEdit.text() == "": return False return True - + def invalidatedReason(self): """ Error reason """ - msg = '' - if self.attributeRuleTypeLineEdit.text() == '': - msg += self.tr('Invalid rule name!\n') - return msg \ No newline at end of file + msg = "" + if self.attributeRuleTypeLineEdit.text() == "": + msg += self.tr("Invalid rule name!\n") + return msg diff --git a/DsgTools/gui/CustomWidgets/ValidationWidgets/validationWorkflowItemWidget.py b/DsgTools/gui/CustomWidgets/ValidationWidgets/validationWorkflowItemWidget.py index 7739ff2b4..da4692c4e 100644 --- a/DsgTools/gui/CustomWidgets/ValidationWidgets/validationWorkflowItemWidget.py +++ b/DsgTools/gui/CustomWidgets/ValidationWidgets/validationWorkflowItemWidget.py @@ -30,31 +30,39 @@ # Qt imports from qgis.PyQt import QtWidgets, uic from qgis.PyQt.QtCore import pyqtSlot, Qt, QSettings -from qgis.PyQt.QtWidgets import QListWidgetItem, QMessageBox, QMenu, QApplication, QFileDialog +from qgis.PyQt.QtWidgets import ( + QListWidgetItem, + QMessageBox, + QMenu, + QApplication, + QFileDialog, +) from qgis.PyQt.QtGui import QCursor from qgis.PyQt.QtSql import QSqlDatabase, QSqlQuery -FORM_CLASS, _ = uic.loadUiType(os.path.join( - os.path.dirname(__file__), 'validationWorkflowItemWidget.ui')) +FORM_CLASS, _ = uic.loadUiType( + os.path.join(os.path.dirname(__file__), "validationWorkflowItemWidget.ui") +) + class ValidationWorkflowItemWidget(QtWidgets.QWidget, FORM_CLASS): - def __init__(self, parameterDict = {}, parent = None): + def __init__(self, parameterDict={}, parent=None): """Constructor.""" - super(ValidationWorkflowItemWidget, self).__init__(parent = parent) + super(ValidationWorkflowItemWidget, self).__init__(parent=parent) self.setupUi(self) - self.validKeys = ['name', 'validationProcessList'] + self.validKeys = ["name", "validationProcessList"] self.parent = parent if self.parent: self.validationManager = parent.validationManager if parameterDict != {}: self.populateInterface(parameterDict) - + def clearAll(self): """ Clears all widget information """ pass - + def getParameterDict(self): """ Components: @@ -66,8 +74,10 @@ def getParameterDict(self): if not self.validate(): raise Exception(self.invalidatedReason()) parameterDict = dict() - parameterDict['attributeRuleType'] = self.attributeRuleTypeLineEdit.text() - parameterDict['ruleColor'] = ','.join(map(str,self.mColorButton.color().getRgb())) + parameterDict["attributeRuleType"] = self.attributeRuleTypeLineEdit.text() + parameterDict["ruleColor"] = ",".join( + map(str, self.mColorButton.color().getRgb()) + ) return parameterDict def populateInterface(self, parameterDict): @@ -76,12 +86,16 @@ def populateInterface(self, parameterDict): """ if parameterDict: if not self.validateJson(parameterDict): - raise Exception(self.tr('Invalid Attribute Rule Type Widget json config!')) - #set layer combo - self.attributeRuleTypeLineEdit.setText(parameterDict['attributeRuleType']) - R,G,B,A = list(map(int,parameterDict['ruleColor'].split(','))) #QColor only accepts int values - self.mColorButton.setColor(QColor(R,G,B,A)) - + raise Exception( + self.tr("Invalid Attribute Rule Type Widget json config!") + ) + # set layer combo + self.attributeRuleTypeLineEdit.setText(parameterDict["attributeRuleType"]) + R, G, B, A = list( + map(int, parameterDict["ruleColor"].split(",")) + ) # QColor only accepts int values + self.mColorButton.setColor(QColor(R, G, B, A)) + def validateJson(self, inputJson): """ Validates input json @@ -97,24 +111,24 @@ def validate(self): """ Validates fields. Returns True if all information are filled correctly. """ - if self.attributeRuleTypeLineEdit.text() == '': + if self.attributeRuleTypeLineEdit.text() == "": return False return True - + def invalidatedReason(self): """ Error reason """ - msg = '' - if self.attributeRuleTypeLineEdit.text() == '': - msg += self.tr('Invalid rule name!\n') + msg = "" + if self.attributeRuleTypeLineEdit.text() == "": + msg += self.tr("Invalid rule name!\n") return msg - + @pyqtSlot(bool) def on_mGroupBox_collapsedStateChanged(self): for i in range(self.parent.tableWidget.rowCount()): self.parent.tableWidget.resizeRowToContents(i) - + @pyqtSlot(str) def on_workspaceItemLineEdit_textEdited(self, text): - self.mGroupBox.setTitle(text) \ No newline at end of file + self.mGroupBox.setTitle(text) diff --git a/DsgTools/gui/CustomWidgets/customRasterToolTip.py b/DsgTools/gui/CustomWidgets/customRasterToolTip.py index d930ca57e..63fb8a778 100644 --- a/DsgTools/gui/CustomWidgets/customRasterToolTip.py +++ b/DsgTools/gui/CustomWidgets/customRasterToolTip.py @@ -25,8 +25,10 @@ from qgis.PyQt import QtWidgets, uic -FORM_CLASS, _ = uic.loadUiType(os.path.join( - os.path.dirname(__file__), 'createDatabaseCustomization.ui')) +FORM_CLASS, _ = uic.loadUiType( + os.path.join(os.path.dirname(__file__), "createDatabaseCustomization.ui") +) + class CreateDatabaseCustomization(QtWidgets.QDialog, FORM_CLASS): def __init__(self, iface): @@ -35,4 +37,4 @@ def __init__(self, iface): self.setupUi(self) def setToolUse(self, enabled): - self.toolCheckBox.setEnabled(enabled) \ No newline at end of file + self.toolCheckBox.setEnabled(enabled) diff --git a/DsgTools/gui/DatabaseTools/ConversionTools/datasourceConversion.py b/DsgTools/gui/DatabaseTools/ConversionTools/datasourceConversion.py index b4cfe0a61..b06d84784 100644 --- a/DsgTools/gui/DatabaseTools/ConversionTools/datasourceConversion.py +++ b/DsgTools/gui/DatabaseTools/ConversionTools/datasourceConversion.py @@ -31,18 +31,26 @@ from qgis.core import Qgis, QgsApplication, QgsMessageLog, Qgis from qgis.gui import QgsCollapsibleGroupBox, QgsMessageBar -from DsgTools.gui.CustomWidgets.BasicInterfaceWidgets.genericDialogLayout import GenericDialogLayout -from DsgTools.gui.CustomWidgets.BasicInterfaceWidgets.textBrowserDialog import TextBrowserDialog +from DsgTools.gui.CustomWidgets.BasicInterfaceWidgets.genericDialogLayout import ( + GenericDialogLayout, +) +from DsgTools.gui.CustomWidgets.BasicInterfaceWidgets.textBrowserDialog import ( + TextBrowserDialog, +) from DsgTools.core.DbTools.dbConverter import DbConverter -FORM_CLASS, _ = uic.loadUiType(os.path.join( - os.path.dirname(__file__), 'datasourceConversion.ui')) +FORM_CLASS, _ = uic.loadUiType( + os.path.join(os.path.dirname(__file__), "datasourceConversion.ui") +) + class DatasourceConversion(QtWidgets.QWizard, FORM_CLASS): # enum for column ordering COLUMN_COUNT = 7 # InDs, Filter, SpatialFilterFanOut, InEdgv, OutDs, OutEdgv, outCrs, ConversionMode = list(range(COLUMN_COUNT)) - InDs, Filter, InEdgv, OutDs, OutEdgv, outCrs, ConversionMode = list(range(COLUMN_COUNT)) + InDs, Filter, InEdgv, OutDs, OutEdgv, outCrs, ConversionMode = list( + range(COLUMN_COUNT) + ) def __init__(self, manager, parentMenu, parentButton, parent=None): """ @@ -61,48 +69,82 @@ def __init__(self, manager, parentMenu, parentButton, parent=None): self.datasourceManagementWidgetOut.fillSupportedDatasources(inputPage=False) self.connectToolSignals() # initiate widget dicts - self.outDs = self.getWidgetNameDict(self.datasourceManagementWidgetOut.activeDrivers) - self.inDs = self.getWidgetNameDict(self.datasourceManagementWidgetIn.activeDrivers) + self.outDs = self.getWidgetNameDict( + self.datasourceManagementWidgetOut.activeDrivers + ) + self.inDs = self.getWidgetNameDict( + self.datasourceManagementWidgetIn.activeDrivers + ) # set table to its initial state self.resetTable(enabled=True) # set pages titles - self.page(0).setTitle(self.tr('Input Datasources')) - self.page(1).setTitle(self.tr('Output Datasources')) - self.page(2).setTitle(self.tr('Conversion Map and Summary')) + self.page(0).setTitle(self.tr("Input Datasources")) + self.page(1).setTitle(self.tr("Output Datasources")) + self.page(2).setTitle(self.tr("Conversion Map and Summary")) # set policy to make cell size adjust to content - self.tableWidget.setSizeAdjustPolicy(QtWidgets.QAbstractScrollArea.AdjustToContents) - + self.tableWidget.setSizeAdjustPolicy( + QtWidgets.QAbstractScrollArea.AdjustToContents + ) + def connectToolSignals(self): """ Connects all tool generic signals. """ # if any widget was turned active/inactive - self.datasourceManagementWidgetIn.activeWidgetAdded.connect(self.addInputDatasource) - self.datasourceManagementWidgetOut.activeWidgetAdded.connect(self.addOutputDatasource) - self.datasourceManagementWidgetIn.activeWidgetRemoved.connect(self.removeInputDatasource) - self.datasourceManagementWidgetOut.activeWidgetRemoved.connect(self.removeOutputDatasource) + self.datasourceManagementWidgetIn.activeWidgetAdded.connect( + self.addInputDatasource + ) + self.datasourceManagementWidgetOut.activeWidgetAdded.connect( + self.addOutputDatasource + ) + self.datasourceManagementWidgetIn.activeWidgetRemoved.connect( + self.removeInputDatasource + ) + self.datasourceManagementWidgetOut.activeWidgetRemoved.connect( + self.removeOutputDatasource + ) # if datasource is changed (e.g. user changed his postgis database selection, for instance) - self.datasourceManagementWidgetIn.widgetUpdated.connect(self.updateInputInformation) - self.datasourceManagementWidgetOut.widgetUpdated.connect(self.updateOutputInformation) + self.datasourceManagementWidgetIn.widgetUpdated.connect( + self.updateInputInformation + ) + self.datasourceManagementWidgetOut.widgetUpdated.connect( + self.updateOutputInformation + ) # erase all options settled self.refreshPushButton.clicked.connect(self.setTableInitialState) # conversion mapping start - self.button(QtWidgets.QWizard.FinishButton).clicked.connect(self.startConversion) + self.button(QtWidgets.QWizard.FinishButton).clicked.connect( + self.startConversion + ) def disconnectToolSignals(self): """ Connects all tool generic signals. """ # if any widget was turned active/inactive - self.datasourceManagementWidgetIn.activeWidgetAdded.disconnect(self.addInputDatasource) - self.datasourceManagementWidgetOut.activeWidgetAdded.disconnect(self.addOutputDatasource) - self.datasourceManagementWidgetIn.activeWidgetRemoved.disconnect(self.removeInputDatasource) - self.datasourceManagementWidgetOut.activeWidgetRemoved.disconnect(self.removeOutputDatasource) + self.datasourceManagementWidgetIn.activeWidgetAdded.disconnect( + self.addInputDatasource + ) + self.datasourceManagementWidgetOut.activeWidgetAdded.disconnect( + self.addOutputDatasource + ) + self.datasourceManagementWidgetIn.activeWidgetRemoved.disconnect( + self.removeInputDatasource + ) + self.datasourceManagementWidgetOut.activeWidgetRemoved.disconnect( + self.removeOutputDatasource + ) # if datasource is changed (e.g. user changed his postgis database selection, for instance) - self.datasourceManagementWidgetIn.widgetUpdated.disconnect(self.updateInputInformation) - self.datasourceManagementWidgetOut.widgetUpdated.disconnect(self.updateOutputInformation) + self.datasourceManagementWidgetIn.widgetUpdated.disconnect( + self.updateInputInformation + ) + self.datasourceManagementWidgetOut.widgetUpdated.disconnect( + self.updateOutputInformation + ) self.refreshPushButton.clicked.disconnect(self.setTableInitialState) - self.button(QtWidgets.QWizard.FinishButton).clicked.disconnect(self.startConversion) + self.button(QtWidgets.QWizard.FinishButton).clicked.disconnect( + self.startConversion + ) def getWidgetNameDict(self, d): """ @@ -121,7 +163,10 @@ def replicateFirstRowContent(self, col): Replicates first row value to all the other rows from a selected column. :param col: (int) column to have its first row replicated. """ - if col in [DatasourceConversion.OutDs, DatasourceConversion.ConversionMode]: #, DatasourceConversion.SpatialFilterFanOut]: + if col in [ + DatasourceConversion.OutDs, + DatasourceConversion.ConversionMode, + ]: # , DatasourceConversion.SpatialFilterFanOut]: value = None for row in range(self.tableWidget.rowCount()): widget = self.getRowContents(row=row)[col] @@ -155,19 +200,23 @@ def resetTable(self, enabled=False): self.tableWidget.setRowCount(0) # map header to its enum headerDict = { - DatasourceConversion.InDs : self.tr("Input"), - DatasourceConversion.Filter : self.tr("Filters"), + DatasourceConversion.InDs: self.tr("Input"), + DatasourceConversion.Filter: self.tr("Filters"), # DatasourceConversion.SpatialFilterFanOut : self.tr("Spatial Fan-out"), - DatasourceConversion.InEdgv : self.tr("In: EDGV Version"), - DatasourceConversion.OutDs : self.tr("Output"), - DatasourceConversion.outCrs : self.tr("Out: CRS"), - DatasourceConversion.OutEdgv : self.tr("Out: EDGV Version"), - DatasourceConversion.ConversionMode : self.tr("Conversion Mode") + DatasourceConversion.InEdgv: self.tr("In: EDGV Version"), + DatasourceConversion.OutDs: self.tr("Output"), + DatasourceConversion.outCrs: self.tr("Out: CRS"), + DatasourceConversion.OutEdgv: self.tr("Out: EDGV Version"), + DatasourceConversion.ConversionMode: self.tr("Conversion Mode"), } # make the order always follow as presented at enum - self.tableWidget.setHorizontalHeaderLabels(list([headerDict[i] for i in range(DatasourceConversion.COLUMN_COUNT)])) + self.tableWidget.setHorizontalHeaderLabels( + list([headerDict[i] for i in range(DatasourceConversion.COLUMN_COUNT)]) + ) # connect header double click signal to first row contents replicate to the other rows - self.tableWidget.horizontalHeader().sectionDoubleClicked.connect(self.replicateFirstRowContent) + self.tableWidget.horizontalHeader().sectionDoubleClicked.connect( + self.replicateFirstRowContent + ) def addInputDatasource(self, containerWidget, resizeColumns=True): """ @@ -175,26 +224,43 @@ def addInputDatasource(self, containerWidget, resizeColumns=True): :param containerWidget: :param resizeColumns: (bool) """ - self.inDs = self.getWidgetNameDict(self.datasourceManagementWidgetIn.activeDrivers) + self.inDs = self.getWidgetNameDict( + self.datasourceManagementWidgetIn.activeDrivers + ) # create a 'function' to get datasource exposing name and create the output list - getNameAlias = lambda widget : '{0}: {1}'.format(widget.groupBox.title(), widget.getDatasourceConnectionName()) + getNameAlias = lambda widget: "{0}: {1}".format( + widget.groupBox.title(), widget.getDatasourceConnectionName() + ) # use it in a map loop to get output list - outDsList = [self.tr('Select a datasource')] + sorted(list(map(getNameAlias, self.outDs.values()))) + outDsList = [self.tr("Select a datasource")] + sorted( + list(map(getNameAlias, self.outDs.values())) + ) # update table rows # lastRow = self.tableWidget.rowCount() self.tableWidget.insertRow(lastRow) # crsIcon = QIcon(os.path.join(os.path.dirname(__file__), '..', '..', '..', 'icons', 'CRS_qgis.svg')) # create the item containing current loop's input ds - t = '{0}: {1}'.format(containerWidget.groupBox.title(), containerWidget.getDatasourceConnectionName()) - self.addItemToTable(col=DatasourceConversion.InDs, row=lastRow, text=t, isEditable=False) + t = "{0}: {1}".format( + containerWidget.groupBox.title(), + containerWidget.getDatasourceConnectionName(), + ) + self.addItemToTable( + col=DatasourceConversion.InDs, row=lastRow, text=t, isEditable=False + ) # populate edgv versions column # input is always text t = containerWidget.connectionWidget.getDatasourceEdgvVersion() - self.addItemToTable(col=DatasourceConversion.InEdgv, row=lastRow, text=t, isEditable=False) + self.addItemToTable( + col=DatasourceConversion.InEdgv, row=lastRow, text=t, isEditable=False + ) # create filter push button filterPushButton = QtWidgets.QPushButton() filterPushButton.setIcon( - QIcon(os.path.join(os.path.dirname(__file__), '..', '..', '..', 'icons', 'filter.png')) + QIcon( + os.path.join( + os.path.dirname(__file__), "..", "..", "..", "icons", "filter.png" + ) + ) ) # # create push button # fanOutCheckBox = QtWidgets.QCheckBox() @@ -207,18 +273,32 @@ def addInputDatasource(self, containerWidget, resizeColumns=True): outDsComboBox.addItems(outDsList) # create combobox containing conversion mode options convModeComboBox = QtWidgets.QComboBox() - convModeComboBox.addItems([ - self.tr('Choose Conversion Mode'), self.tr('Flexible Conversion'), self.tr('Strict Conversion') - ]) + convModeComboBox.addItems( + [ + self.tr("Choose Conversion Mode"), + self.tr("Flexible Conversion"), + self.tr("Strict Conversion"), + ] + ) # set each widget to their column - self.tableWidget.setCellWidget(lastRow, DatasourceConversion.OutDs, outDsComboBox) - self.tableWidget.setCellWidget(lastRow, DatasourceConversion.Filter, filterPushButton) + self.tableWidget.setCellWidget( + lastRow, DatasourceConversion.OutDs, outDsComboBox + ) + self.tableWidget.setCellWidget( + lastRow, DatasourceConversion.Filter, filterPushButton + ) # self.tableWidget.setCellWidget(lastRow, DatasourceConversion.SpatialFilterFanOut, fanOutCheckBox) - self.tableWidget.setCellWidget(lastRow, DatasourceConversion.ConversionMode, convModeComboBox) + self.tableWidget.setCellWidget( + lastRow, DatasourceConversion.ConversionMode, convModeComboBox + ) # start filter widget - filterPushButton.clicked.connect(partial(self.prepareRowFilterDialog, container=containerWidget)) + filterPushButton.clicked.connect( + partial(self.prepareRowFilterDialog, container=containerWidget) + ) # set table output information population to its widget - outDsComboBox.currentIndexChanged.connect(partial(self.fillOutDsInfoRow, row=lastRow)) + outDsComboBox.currentIndexChanged.connect( + partial(self.fillOutDsInfoRow, row=lastRow) + ) if resizeColumns: # resize to contents self.tableWidget.resizeColumnsToContents() @@ -226,42 +306,59 @@ def addInputDatasource(self, containerWidget, resizeColumns=True): def removeInputDatasource(self, containerWidget): """ Removes the map table row containing a given input information. - :param containerWidget: (DatasourceContainerWidget) input container widget. + :param containerWidget: (DatasourceContainerWidget) input container widget. """ row, _ = self.getInputDatasourceRow(inputDatasourceWidget=containerWidget) self.tableWidget.removeRow(row) # after the row is removed, it is also necessary to update datasources names, given that group boxes were renamed for row in range(self.tableWidget.rowCount()): inDs = self.getRowContents(row=row)[DatasourceConversion.InDs] - widget = self.inDs[inDs.split(':')[0]] - t = '{0}: {1}'.format(widget.groupBox.title(), widget.getDatasourceConnectionName()) - self.addItemToTable(col=DatasourceConversion.InDs, row=row, text=t, isEditable=False) + widget = self.inDs[inDs.split(":")[0]] + t = "{0}: {1}".format( + widget.groupBox.title(), widget.getDatasourceConnectionName() + ) + self.addItemToTable( + col=DatasourceConversion.InDs, row=row, text=t, isEditable=False + ) # update input map - if map was updated before it would not be possible to retrieve widget (name changed) - self.inDs = self.getWidgetNameDict(self.datasourceManagementWidgetIn.activeDrivers) + self.inDs = self.getWidgetNameDict( + self.datasourceManagementWidgetIn.activeDrivers + ) def addOutputDatasource(self, containerWidget): """ Updates datasource options for every row in table widget. - :param containerWidget: (DatasourceContainerWidget) output container widget. + :param containerWidget: (DatasourceContainerWidget) output container widget. """ # update output map - self.outDs = self.getWidgetNameDict(self.datasourceManagementWidgetOut.activeDrivers) + self.outDs = self.getWidgetNameDict( + self.datasourceManagementWidgetOut.activeDrivers + ) # get new datasource info - dsName = '{0}: {1}'.format(containerWidget.groupBox.title(), containerWidget.getDatasourceConnectionName()) + dsName = "{0}: {1}".format( + containerWidget.groupBox.title(), + containerWidget.getDatasourceConnectionName(), + ) for row in range(self.tableWidget.rowCount()): outCombobox = self.getRowContents(row=row)[DatasourceConversion.OutDs] outCombobox.addItem(dsName) def removeOutputDatasource(self, containerWidget): """ - Removes output option from evey row in table widget. - :param containerWidget: (DatasourceContainerWidget) output container widget. + Removes output option from evey row in table widget. + :param containerWidget: (DatasourceContainerWidget) output container widget. """ # update output map - self.outDs = self.getWidgetNameDict(self.datasourceManagementWidgetOut.activeDrivers) + self.outDs = self.getWidgetNameDict( + self.datasourceManagementWidgetOut.activeDrivers + ) # get new datasource info - getNewDsNames = lambda widget : '{0}: {1}'.format(widget.groupBox.title(), widget.getDatasourceConnectionName()) - newDsNames = [self.tr('Select a datasource')] + sorted(list(map(getNewDsNames, self.outDs.values()))) + getNewDsNames = lambda widget: "{0}: {1}".format( + widget.groupBox.title(), widget.getDatasourceConnectionName() + ) + newDsNames = [self.tr("Select a datasource")] + sorted( + list(map(getNewDsNames, self.outDs.values())) + ) groupTitle = containerWidget.groupBox.title() # initiate its index dsIdx = None @@ -271,7 +368,7 @@ def removeOutputDatasource(self, containerWidget): # retrieve replaced datasource old index if dsIdx is None: # retrive old name - oldName = '' + oldName = "" for i in range(outDsCombobox.count()): if groupTitle in outDsCombobox.itemText(i): oldName = outDsCombobox.itemText(i) @@ -299,29 +396,42 @@ def removeOutputDatasource(self, containerWidget): def updateInputInformation(self, containerWidget): """ Updates input information. - :param containerWidget: (DatasourceContainerWidget) input container widget. + :param containerWidget: (DatasourceContainerWidget) input container widget. """ # update input map - self.inDs = self.getWidgetNameDict(self.datasourceManagementWidgetIn.activeDrivers) + self.inDs = self.getWidgetNameDict( + self.datasourceManagementWidgetIn.activeDrivers + ) # get input row row, _ = self.getInputDatasourceRow(inputDatasourceWidget=containerWidget) # get new datasource info - dsName = '{0}: {1}'.format(containerWidget.groupBox.title(), containerWidget.getDatasourceConnectionName()) + dsName = "{0}: {1}".format( + containerWidget.groupBox.title(), + containerWidget.getDatasourceConnectionName(), + ) inEdgv = containerWidget.connectionWidget.getDatasourceEdgvVersion() # update edgv and input name - self.addItemToTable(col=DatasourceConversion.InDs, row=row, text=dsName, isEditable=False) - self.addItemToTable(col=DatasourceConversion.InEdgv, row=row, text=inEdgv, isEditable=False) + self.addItemToTable( + col=DatasourceConversion.InDs, row=row, text=dsName, isEditable=False + ) + self.addItemToTable( + col=DatasourceConversion.InEdgv, row=row, text=inEdgv, isEditable=False + ) def updateOutputInformation(self, containerWidget): """ Updates input information. - :param containerWidget: (DatasourceContainerWidget) output container widget. + :param containerWidget: (DatasourceContainerWidget) output container widget. """ # update output map - self.outDs = self.getWidgetNameDict(self.datasourceManagementWidgetOut.activeDrivers) + self.outDs = self.getWidgetNameDict( + self.datasourceManagementWidgetOut.activeDrivers + ) # get new datasource info groupTitle = containerWidget.groupBox.title() - dsName = '{0}: {1}'.format(groupTitle, containerWidget.getDatasourceConnectionName()) + dsName = "{0}: {1}".format( + groupTitle, containerWidget.getDatasourceConnectionName() + ) outEdgv = containerWidget.connectionWidget.getDatasourceEdgvVersion() # initiate its index dsIdx = None @@ -331,7 +441,7 @@ def updateOutputInformation(self, containerWidget): # retrieve replaced datasource old index if dsIdx is None: # retrive old name - oldName = '' + oldName = "" for i in range(outDsCombobox.count()): if groupTitle in outDsCombobox.itemText(i): oldName = outDsCombobox.itemText(i) @@ -356,8 +466,10 @@ def getRowContents(self, row): inDs = self.tableWidget.item(row, DatasourceConversion.InDs).text() inEdgv = self.tableWidget.item(row, DatasourceConversion.InEdgv).text() outEdgvItem = self.tableWidget.item(row, DatasourceConversion.OutEdgv) - outEdgv = outEdgvItem.text() if outEdgvItem else '' - conversionMode = self.tableWidget.cellWidget(row, DatasourceConversion.ConversionMode) + outEdgv = outEdgvItem.text() if outEdgvItem else "" + conversionMode = self.tableWidget.cellWidget( + row, DatasourceConversion.ConversionMode + ) # output datasource, input and output SRC and filter status are always a QWidget outDs = self.tableWidget.cellWidget(row, DatasourceConversion.OutDs) # however, output info might not yet have been filled @@ -386,13 +498,28 @@ def getInputDatasourceRow(self, inputDatasourceWidget): inputText = inputDatasourceWidget.groupBox.title() for row in range(self.tableWidget.rowCount()): # inDs, _filter, spatialFanOut, inEdgv, outDs, outEdgv, outCrs, conversionMode = self.getRowContents(row=row) - inDs, _filter, inEdgv, outDs, outEdgv, outCrs, conversionMode = self.getRowContents(row=row) + ( + inDs, + _filter, + inEdgv, + outDs, + outEdgv, + outCrs, + conversionMode, + ) = self.getRowContents(row=row) if inputText in inDs: # return row, [inDs, _filter, spatialFanOut, inEdgv, outDs, outEdgv, outCrs, conversionMode] - return row, [inDs, _filter, inEdgv, outDs, outEdgv, outCrs, conversionMode] + return row, [ + inDs, + _filter, + inEdgv, + outDs, + outEdgv, + outCrs, + conversionMode, + ] return -1, [] - def clearOutDsInforRow(self, row): """ Clears output information for a given row. @@ -406,7 +533,7 @@ def clearOutDsInforRow(self, row): def fillOutDsInfoRow(self, row): """ - Fills out row with output info for each output column. In here, ouput SRC and EDGV are filled. + Fills out row with output info for each output column. In here, ouput SRC and EDGV are filled. :param row: (int) row index to have its output columns populated. :return: (list-of-object) return a list containing (str) output EDGV version and (QPushButton) output SRC. """ @@ -419,8 +546,12 @@ def fillOutDsInfoRow(self, row): outDs = self.getRowContents(row=row)[DatasourceConversion.OutDs] # widget dict keys are defined as group title, which is part of outDs current text if outDs: - groupTitle = outDs.currentText().split(':')[0] - crsIcon = QIcon(os.path.join(os.path.dirname(__file__), '..', '..', '..', 'icons', 'CRS_qgis.svg')) + groupTitle = outDs.currentText().split(":")[0] + crsIcon = QIcon( + os.path.join( + os.path.dirname(__file__), "..", "..", "..", "icons", "CRS_qgis.svg" + ) + ) else: return [] if groupTitle in self.outDs: @@ -431,10 +562,10 @@ def fillOutDsInfoRow(self, row): outCrs.setIcon(crsIcon) # get new text item to add output datasource edgvOut = containerWidget.connectionWidget.getDatasourceEdgvVersion() - edgvOut = edgvOut[5:] if 'EDGV' in edgvOut else edgvOut + edgvOut = edgvOut[5:] if "EDGV" in edgvOut else edgvOut itemEdgvOut = QtWidgets.QTableWidgetItem() itemEdgvOut.setText(edgvOut) - itemEdgvOut.setFlags(Qt.ItemIsEditable) # not editable + itemEdgvOut.setFlags(Qt.ItemIsEditable) # not editable # add both to table self.tableWidget.setCellWidget(row, DatasourceConversion.outCrs, outCrs) self.tableWidget.setItem(row, DatasourceConversion.OutEdgv, itemEdgvOut) @@ -443,7 +574,7 @@ def fillOutDsInfoRow(self, row): # if is not controlled, clear line return [] - def getNewTableItem(self, text='', isEditable=True): + def getNewTableItem(self, text="", isEditable=True): """ Gets an item to be added to the table that may be set to not be editable. :param text: (str) name to be exposed on table cell. @@ -453,10 +584,10 @@ def getNewTableItem(self, text='', isEditable=True): item = QtWidgets.QTableWidgetItem() item.setText(text) if not isEditable: - item.setFlags(Qt.ItemIsEditable) # not editable + item.setFlags(Qt.ItemIsEditable) # not editable return item - def addItemToTable(self, col, row, text='', isEditable=True): + def addItemToTable(self, col, row, text="", isEditable=True): """ Adds an item to the mapping table into a given column and row. :param col: (int) column containing new item. @@ -491,14 +622,24 @@ def setTableInitialState(self): """ self.resetTable(enabled=True) # output ds dict/list - self.outDs = self.getWidgetNameDict(self.datasourceManagementWidgetOut.activeDrivers) + self.outDs = self.getWidgetNameDict( + self.datasourceManagementWidgetOut.activeDrivers + ) # create a 'function' to get datasource exposing name and create the output list - getNameAlias = lambda widget : '{0}: {1}'.format(widget.groupBox.title(), widget.getDatasourceConnectionName()) - outDsList = [self.tr('Select a datasource')] + sorted(list(map(getNameAlias, self.outDs.values()))) + getNameAlias = lambda widget: "{0}: {1}".format( + widget.groupBox.title(), widget.getDatasourceConnectionName() + ) + outDsList = [self.tr("Select a datasource")] + sorted( + list(map(getNameAlias, self.outDs.values())) + ) # input ds dict/list - self.inDs = self.getWidgetNameDict(self.datasourceManagementWidgetIn.activeDrivers) + self.inDs = self.getWidgetNameDict( + self.datasourceManagementWidgetIn.activeDrivers + ) for groupTitle in sorted(self.inDs.keys()): - self.addInputDatasource(containerWidget=self.inDs[groupTitle], resizeColumns=False) + self.addInputDatasource( + containerWidget=self.inDs[groupTitle], resizeColumns=False + ) self.tableWidget.resizeColumnsToContents() def getConversionMap(self): @@ -516,23 +657,35 @@ def getConversionMap(self): # initiate this row's mapping dict and fill it rowMapping = dict() # get input information to be mapped - input datasource identification and filtering options - containerWidget = self.inDs[inDs.split(':')[0]] # input group box title (widget's dict key) - inputDatasourceId = containerWidget.connectionWidget.getDatasourcePath() + containerWidget = self.inDs[ + inDs.split(":")[0] + ] # input group box title (widget's dict key) + inputDatasourceId = containerWidget.connectionWidget.getDatasourcePath() inputFilteredLayers = containerWidget.filters() # get output information to be mapped - output datasource identification and if it's - containerWidget = self.outDs[outDs.currentText().split(':')[0]] # output group box title (widget's dict key) + containerWidget = self.outDs[ + outDs.currentText().split(":")[0] + ] # output group box title (widget's dict key) # populate row's conversion map - rowMapping['outDs'] = containerWidget.connectionWidget.getDatasourcePath(), # still to decide what to fill up in here - rowMapping['outDs'] = rowMapping['outDs'][-1] # I DON'T KNOW WHY, BUT THAT'S THE ONLY WAY THIS COMES OUT AS A TUPLE. - rowMapping['filter'] = inputFilteredLayers + rowMapping["outDs"] = ( + containerWidget.connectionWidget.getDatasourcePath(), + ) # still to decide what to fill up in here + rowMapping["outDs"] = rowMapping["outDs"][ + -1 + ] # I DON'T KNOW WHY, BUT THAT'S THE ONLY WAY THIS COMES OUT AS A TUPLE. + rowMapping["filter"] = inputFilteredLayers # rowMapping['spatialFanOut'] = spatialFanOut.isChecked() # parameter indicating whether it is a new datasource - rowMapping['createDs'] = self.tr('new') in outDs.currentText().split(':')[0] - if self.tr('new') in outDs.currentText().split(':')[0]: + rowMapping["createDs"] = self.tr("new") in outDs.currentText().split(":")[0] + if self.tr("new") in outDs.currentText().split(":")[0]: # if a new datasource will be created, EDGV version and CRS will be needed - rowMapping['edgv'] = containerWidget.connectionWidget.selectionWidget.edgvVersion() - rowMapping['crs'] = containerWidget.connectionWidget.selectionWidget.authId() - rowMapping['conversionMode'] = conversionMode.currentIndex() + rowMapping[ + "edgv" + ] = containerWidget.connectionWidget.selectionWidget.edgvVersion() + rowMapping[ + "crs" + ] = containerWidget.connectionWidget.selectionWidget.authId() + rowMapping["conversionMode"] = conversionMode.currentIndex() # it is possible for the same dataset to be chosen for different outputs, in order to prevent instantiating it # more than once, map it all to the same dict entry and control layer/feature flux through filter entry if inputDatasourceId not in conversionMap: @@ -557,8 +710,8 @@ def exportConversionJson(self, filepath=None): """ conversionMap = self.getConversionMap() if not filepath: - filepath = os.path.join(os.path.dirname(__file__), 'conversion_map.json') - with open(filepath, 'w') as fp: + filepath = os.path.join(os.path.dirname(__file__), "conversion_map.json") + with open(filepath, "w") as fp: json.dump(conversionMap, fp, indent=4, sort_keys=True) def validateJson(self, inputJson): @@ -579,7 +732,7 @@ def checkEdgvConversion(edgvIn, edgvOut): :param edgvOut: (str) output EDGV version. """ # TO DO - return edgvIn == edgvOut and edgvOut != '' + return edgvIn == edgvOut and edgvOut != "" def validate(self): """ @@ -594,10 +747,12 @@ def validate(self): msgBar = QgsMessageBar(self) # if window is resized, msgBar stays, not ideal, but works for now # maybe we should connect to some parent resizing signal or something... - msgBar.resize(QSize(self.geometry().size().width(), msgBar.geometry().height())) - msgBar.pushMessage(self.tr('Warning!'), msg, level=Qgis.Warning, duration=5) - QgsMessageLog.logMessage(msg, 'DSGTools Plugin', Qgis.Critical) - return msg == '' + msgBar.resize( + QSize(self.geometry().size().width(), msgBar.geometry().height()) + ) + msgBar.pushMessage(self.tr("Warning!"), msg, level=Qgis.Warning, duration=5) + QgsMessageLog.logMessage(msg, "DSGTools Plugin", Qgis.Critical) + return msg == "" def validateCurrentPage(self): """ @@ -616,7 +771,10 @@ def invalidatedReason(self): """ if self.tableWidget.rowCount() == 0: return self.tr("No datasets were selected (input or output)") - for obj in [self.datasourceManagementWidgetIn, self.datasourceManagementWidgetOut]: + for obj in [ + self.datasourceManagementWidgetIn, + self.datasourceManagementWidgetOut, + ]: # validate in/ouput msg = obj.validate() if msg: @@ -627,31 +785,54 @@ def invalidatedReason(self): for row in range(self.tableWidget.rowCount()): # get row contents # inDsName, _, _, inEdgv, outDs, _, outEdgv, conversionMode = self.getRowContents(row=row) - inDsName, _, inEdgv, outDs, outEdgv, _, conversionMode = self.getRowContents(row=row) + ( + inDsName, + _, + inEdgv, + outDs, + outEdgv, + _, + conversionMode, + ) = self.getRowContents(row=row) outDsName = outDs.currentText() # FTer was discontinued. conv should not allow dataset creation for this EDGV version - if outEdgv == 'EDGV 2.1.3 F Ter' and self.tr('new') in outDsName.split(' #')[0]: - return self.tr('EDGV 2.1.3 F Ter model was terminated. DSGTools no longer support its creation (row {1})').format(inDsName, row + 1) + if ( + outEdgv == "EDGV 2.1.3 F Ter" + and self.tr("new") in outDsName.split(" #")[0] + ): + return self.tr( + "EDGV 2.1.3 F Ter model was terminated. DSGTools no longer support its creation (row {1})" + ).format(inDsName, row + 1) # check if a conversion mode was selected - if conversionMode.currentText() == self.tr('Choose Conversion Mode'): - return self.tr('Conversion mode not selected for input {0} (row {1})').format(inDsName, row + 1) + if conversionMode.currentText() == self.tr("Choose Conversion Mode"): + return self.tr( + "Conversion mode not selected for input {0} (row {1})" + ).format(inDsName, row + 1) # check if EDGV versions are compatible if not self.checkEdgvConversion(edgvIn=inEdgv, edgvOut=outEdgv): - return self.tr('Conversion map unavailable for {0} to {1} (row {2})').format(inEdgv, outEdgv, row + 1) + return self.tr( + "Conversion map unavailable for {0} to {1} (row {2})" + ).format(inEdgv, outEdgv, row + 1) # # add input to the checked ones list # inChecked.append(inDsName) # add output to checked ones list, if it's not 'select a datasource' - if outDsName == self.tr('Select a datasource'): - return self.tr('Output datasource not selected for {0} (row {1})').format(inDsName, row + 1) + if outDsName == self.tr("Select a datasource"): + return self.tr( + "Output datasource not selected for {0} (row {1})" + ).format(inDsName, row + 1) outChecked.add(outDsName) # last check: if all chosen outputs are listed - splitAlias = lambda x : x.split(':')[0] + splitAlias = lambda x: x.split(":")[0] if len(outChecked) != len(self.outDs): # if not all outputs were used, user should remove it (or may have wrongfully chosen a different dataset) notUsed = set(self.outDs.keys()) - set(map(splitAlias, outChecked)) - msg = self.tr('Output datasource {0} was not used.') if len(notUsed) == 1 else self.tr('Output datasources {0} were not used.') + msg = ( + self.tr("Output datasource {0} was not used.") + if len(notUsed) == 1 + else self.tr("Output datasources {0} were not used.") + ) return msg.format(", ".join(notUsed)) - return '' + return "" def cancelConversion(self, conversionTask, summaryDlg): """ @@ -664,7 +845,11 @@ def cancelConversion(self, conversionTask, summaryDlg): summaryDlg.cancelPushButton.setEnabled(False) conversionTask.blockSignals(True) summaryDlg.progressBar.setValue(0) - summaryDlg.addToHtml(self.tr('

CONVERSION TASK WAS CANCELLED.

')) + summaryDlg.addToHtml( + self.tr( + '

CONVERSION TASK WAS CANCELLED.

' + ) + ) summaryDlg.savePushButton.setEnabled(True) def run(self, conversionMap): @@ -686,7 +871,9 @@ def run(self, conversionMap): # QgsApplication.taskManager().addTask(task) # summaryDlg.show() # conversion off the thread - conv = DbConverter(iface, conversionMap, description=self.tr('DSGTools Dataset Conversion')) + conv = DbConverter( + iface, conversionMap, description=self.tr("DSGTools Dataset Conversion") + ) summaryDlg = TextBrowserDialog(parent=iface.mainWindow()) summaryDlg.cancelPushButton.hide() summaryDlg.progressBar.hide() @@ -694,17 +881,25 @@ def run(self, conversionMap): QtWidgets.QApplication.setOverrideCursor(QCursor(Qt.WaitCursor)) if not conv.run(): # advise conversion has failed - msg = self.tr("Dataset conversion has finished with some errors. Check conversion log for details.") - iface.messageBar().pushMessage(self.tr('Warning!'), msg, level=Qgis.Warning, duration=5) + msg = self.tr( + "Dataset conversion has finished with some errors. Check conversion log for details." + ) + iface.messageBar().pushMessage( + self.tr("Warning!"), msg, level=Qgis.Warning, duration=5 + ) else: self.resetInterface() QtWidgets.QApplication.restoreOverrideCursor() - summaryDlg.setHtml(conv.output['log']) + summaryDlg.setHtml(conv.output["log"]) except Exception as e: QtWidgets.QApplication.restoreOverrideCursor() - msg = self.tr("Dataset conversion has failed: '{0}'").format(', '.join(map(str, e.args))) - iface.messageBar().pushMessage(self.tr('Warning!'), msg, level=Qgis.Warning, duration=5) - QgsMessageLog.logMessage(':'.join(e.args), "DSGTools Plugin", Qgis.Critical) + msg = self.tr("Dataset conversion has failed: '{0}'").format( + ", ".join(map(str, e.args)) + ) + iface.messageBar().pushMessage( + self.tr("Warning!"), msg, level=Qgis.Warning, duration=5 + ) + QgsMessageLog.logMessage(":".join(e.args), "DSGTools Plugin", Qgis.Critical) summaryDlg.exec_() def startConversion(self, exportMap=False): @@ -734,15 +929,15 @@ def execute(self): def initGui(self): """ - Instantiate GUI for user, including button shortcut (if necessary) and tool insertion on DSGTools tab on QGIS. + Instantiate GUI for user, including button shortcut (if necessary) and tool insertion on DSGTools tab on QGIS. """ self.manager.addTool( - text=self.tr('Convert Databases'), + text=self.tr("Convert Databases"), callback=self.execute, parentMenu=self.parentMenu, - icon='install.png', + icon="install.png", parentButton=self.parentButton, - defaultButton=False + defaultButton=False, ) def resetInterface(self): @@ -767,7 +962,10 @@ def unload(self): except: pass # remove every widget added to interface (in and output) and, consequently, disconnect all signals - for obj in [self.datasourceManagementWidgetIn, self.datasourceManagementWidgetOut]: + for obj in [ + self.datasourceManagementWidgetIn, + self.datasourceManagementWidgetOut, + ]: for driverName, wList in obj.activeDrivers.items(): for w in wList: # removeWidget method disconnects all widget signals diff --git a/DsgTools/gui/DatabaseTools/DbTools/BatchDbCreator/batchDbCreator.py b/DsgTools/gui/DatabaseTools/DbTools/BatchDbCreator/batchDbCreator.py index 7e05d2792..a3a3e15f9 100644 --- a/DsgTools/gui/DatabaseTools/DbTools/BatchDbCreator/batchDbCreator.py +++ b/DsgTools/gui/DatabaseTools/DbTools/BatchDbCreator/batchDbCreator.py @@ -28,14 +28,21 @@ from qgis.PyQt.QtWidgets import QMessageBox, QFileDialog, QWizard from fileinput import filename from DsgTools.core.Utils.utils import Utils -from DsgTools.gui.DatabaseTools.DbTools.BatchDbCreator.createBatchFromCsv import CreateBatchFromCsv -from DsgTools.gui.DatabaseTools.DbTools.BatchDbCreator.createBatchIncrementing import CreateBatchIncrementing +from DsgTools.gui.DatabaseTools.DbTools.BatchDbCreator.createBatchFromCsv import ( + CreateBatchFromCsv, +) +from DsgTools.gui.DatabaseTools.DbTools.BatchDbCreator.createBatchIncrementing import ( + CreateBatchIncrementing, +) + +FORM_CLASS, _ = uic.loadUiType( + os.path.join(os.path.dirname(__file__), "batchDbCreator.ui") +) -FORM_CLASS, _ = uic.loadUiType(os.path.join( - os.path.dirname(__file__), 'batchDbCreator.ui')) class BatchDbCreator(QtWidgets.QWizard, FORM_CLASS): coverageChanged = pyqtSignal() + def __init__(self, manager, parentButton, parentMenu, parent=None): """Constructor.""" super(self.__class__, self).__init__() @@ -49,39 +56,47 @@ def __init__(self, manager, parentButton, parentMenu, parent=None): self.parentMenu = parentMenu self.parent = parent self.setupUi(self) - self.sequenceDict = {'CreateBatchFromCsv':1, 'CreateBatchIncrementing':2, 'CreateBatchBasedOnList':3} - - self.setPage(self.sequenceDict['CreateBatchFromCsv'],CreateBatchFromCsv()) - self.setPage(self.sequenceDict['CreateBatchIncrementing'],CreateBatchIncrementing()) - + self.sequenceDict = { + "CreateBatchFromCsv": 1, + "CreateBatchIncrementing": 2, + "CreateBatchBasedOnList": 3, + } + + self.setPage(self.sequenceDict["CreateBatchFromCsv"], CreateBatchFromCsv()) + self.setPage( + self.sequenceDict["CreateBatchIncrementing"], CreateBatchIncrementing() + ) + def nextId(self): if self.currentId() == 0: if self.csvRadioButton.isChecked(): - return self.sequenceDict['CreateBatchFromCsv'] + return self.sequenceDict["CreateBatchFromCsv"] elif self.patternRadioButton.isChecked(): - return self.sequenceDict['CreateBatchIncrementing'] + return self.sequenceDict["CreateBatchIncrementing"] else: return self.currentId() - elif self.currentId() == self.sequenceDict['CreateBatchFromCsv']: + elif self.currentId() == self.sequenceDict["CreateBatchFromCsv"]: return -1 - elif self.currentId() == self.sequenceDict['CreateBatchIncrementing']: + elif self.currentId() == self.sequenceDict["CreateBatchIncrementing"]: return -1 else: return -1 def initGui(self): """ - Instantiates user interface and prepare it to be called whenever tool button is activated. + Instantiates user interface and prepare it to be called whenever tool button is activated. """ - callback = lambda : self.manager.createDatabase(isBatchCreation=True) + callback = lambda: self.manager.createDatabase(isBatchCreation=True) self.manager.addTool( - text=self.tr('Create batches of PostGIS, SpatiaLite or Geopackage Databases'), + text=self.tr( + "Create batches of PostGIS, SpatiaLite or Geopackage Databases" + ), callback=callback, parentMenu=self.parentMenu, - icon='batchDatabase.png', + icon="batchDatabase.png", parentButton=self.parentButton, - defaultButton=False + defaultButton=False, ) def unload(self): - pass \ No newline at end of file + pass diff --git a/DsgTools/gui/DatabaseTools/DbTools/BatchDbCreator/createBatchFromCsv.py b/DsgTools/gui/DatabaseTools/DbTools/BatchDbCreator/createBatchFromCsv.py index bb1504673..c5c43c516 100644 --- a/DsgTools/gui/DatabaseTools/DbTools/BatchDbCreator/createBatchFromCsv.py +++ b/DsgTools/gui/DatabaseTools/DbTools/BatchDbCreator/createBatchFromCsv.py @@ -33,42 +33,63 @@ from DsgTools.core.Utils.utils import Utils from DsgTools.core.Factories.DbCreatorFactory.dbCreatorFactory import DbCreatorFactory -FORM_CLASS, _ = uic.loadUiType(os.path.join( - os.path.dirname(__file__), 'createBatchFromCsv.ui')) +FORM_CLASS, _ = uic.loadUiType( + os.path.join(os.path.dirname(__file__), "createBatchFromCsv.ui") +) + class CreateBatchFromCsv(QtWidgets.QWizardPage, FORM_CLASS): coverageChanged = pyqtSignal() + def __init__(self, parent=None): """Constructor.""" super(self.__class__, self).__init__() self.setupUi(self) self.databaseParameterWidget.setDbNameVisible(False) - self.customFileSelector.setCaption(self.tr('Select a Comma Separated Values File')) - self.customFileSelector.setFilter(self.tr('Comma Separated Values File (*.csv)')) - self.customFileSelector.setType('single') - self.customFileSelector.setTitle(self.tr('CSV File')) - self.tabDbSelectorWidget.tabWidget.currentChanged.connect(self.changeTemplateInterface) - self.tabDbSelectorWidget.serverWidget.serverAbstractDbLoaded.connect(self.databaseParameterWidget.setServerDb) + self.customFileSelector.setCaption( + self.tr("Select a Comma Separated Values File") + ) + self.customFileSelector.setFilter( + self.tr("Comma Separated Values File (*.csv)") + ) + self.customFileSelector.setType("single") + self.customFileSelector.setTitle(self.tr("CSV File")) + self.tabDbSelectorWidget.tabWidget.currentChanged.connect( + self.changeTemplateInterface + ) + self.tabDbSelectorWidget.serverWidget.serverAbstractDbLoaded.connect( + self.databaseParameterWidget.setServerDb + ) self.databaseParameterWidget.comboBoxPostgis.parent = self - + def getParameters(self): - #Get outputDir, outputList, refSys + # Get outputDir, outputList, refSys parameterDict = dict() - parameterDict['prefix'] = None - parameterDict['sufix'] = None - parameterDict['srid'] = self.databaseParameterWidget.mQgsProjectionSelectionWidget.crs().authid().split(':')[-1] - parameterDict['version'] = self.databaseParameterWidget.getVersion() - parameterDict['nonDefaultTemplate'] = self.databaseParameterWidget.getTemplateName() - if self.databaseParameterWidget.prefixLineEdit.text() != '': - parameterDict['prefix'] = self.databaseParameterWidget.prefixLineEdit.text() - if self.databaseParameterWidget.sufixLineEdit.text() != '': - parameterDict['sufix'] = self.databaseParameterWidget.sufixLineEdit.text() - parameterDict['miList'] = self.getMiListFromCSV() - parameterDict['driverName'] = self.tabDbSelectorWidget.getType() - parameterDict['factoryParam'] = self.tabDbSelectorWidget.getFactoryCreationParam() - parameterDict['templateInfo'] = self.databaseParameterWidget.getTemplateParameters() + parameterDict["prefix"] = None + parameterDict["sufix"] = None + parameterDict["srid"] = ( + self.databaseParameterWidget.mQgsProjectionSelectionWidget.crs() + .authid() + .split(":")[-1] + ) + parameterDict["version"] = self.databaseParameterWidget.getVersion() + parameterDict[ + "nonDefaultTemplate" + ] = self.databaseParameterWidget.getTemplateName() + if self.databaseParameterWidget.prefixLineEdit.text() != "": + parameterDict["prefix"] = self.databaseParameterWidget.prefixLineEdit.text() + if self.databaseParameterWidget.sufixLineEdit.text() != "": + parameterDict["sufix"] = self.databaseParameterWidget.sufixLineEdit.text() + parameterDict["miList"] = self.getMiListFromCSV() + parameterDict["driverName"] = self.tabDbSelectorWidget.getType() + parameterDict[ + "factoryParam" + ] = self.tabDbSelectorWidget.getFactoryCreationParam() + parameterDict[ + "templateInfo" + ] = self.databaseParameterWidget.getTemplateParameters() return parameterDict - + def getMiListFromCSV(self): """ Old method for CSV reading. It identifies the databases names from the @@ -83,7 +104,7 @@ def getMiListFromCSV(self): return miList def validatePage(self): - #insert validation messages + # insert validation messages validatedDbParams = self.databaseParameterWidget.validate() if not validatedDbParams: return False @@ -92,50 +113,66 @@ def validatePage(self): return False parameterDict = self.getParameters() dbDict, errorDict = self.createDatabases(parameterDict) - creationMsg = '' + creationMsg = "" if len(list(dbDict.keys())) > 0: - creationMsg += self.tr('Database(s) {0} created successfully.').format(', '.join(list(dbDict.keys()))) - errorFrameMsg = '' - errorMsg = '' + creationMsg += self.tr("Database(s) {0} created successfully.").format( + ", ".join(list(dbDict.keys())) + ) + errorFrameMsg = "" + errorMsg = "" if len(list(errorDict.keys())) > 0: frameList = [] errorList = [] for key in list(errorDict.keys()): - if self.tr('Invalid inomen parameter!') in errorDict[key]: + if self.tr("Invalid inomen parameter!") in errorDict[key]: frameList.append(key) else: errorList.append(key) - QgsMessageLog.logMessage(self.tr('Error on {0}: ').format(key)+errorDict[key], "DSGTools Plugin", Qgis.Critical) + QgsMessageLog.logMessage( + self.tr("Error on {0}: ").format(key) + errorDict[key], + "DSGTools Plugin", + Qgis.Critical, + ) if len(frameList) > 0: - errorFrameMsg += self.tr('Frame was not created on the following databases: {0}').format(', '.join(frameList)) + errorFrameMsg += self.tr( + "Frame was not created on the following databases: {0}" + ).format(", ".join(frameList)) if len(errorList) > 0: - errorMsg += self.tr('Some errors occurred while trying to create database(s) {0}').format(', '.join(errorList)) - logMsg = '' - if errorFrameMsg != '' or errorMsg != '': - logMsg += self.tr('Check log for more details.') - msg = [i for i in (creationMsg, errorFrameMsg, errorMsg, logMsg) if i != ''] - QMessageBox.warning(self, self.tr('Info!'), self.tr('Process finished.')+'\n'+'\n'.join(msg)) + errorMsg += self.tr( + "Some errors occurred while trying to create database(s) {0}" + ).format(", ".join(errorList)) + logMsg = "" + if errorFrameMsg != "" or errorMsg != "": + logMsg += self.tr("Check log for more details.") + msg = [i for i in (creationMsg, errorFrameMsg, errorMsg, logMsg) if i != ""] + QMessageBox.warning( + self, self.tr("Info!"), self.tr("Process finished.") + "\n" + "\n".join(msg) + ) return True - + def createDatabases(self, parameterDict): - dbCreator = DbCreatorFactory().createDbCreatorFactory(parameterDict['driverName'], parameterDict['factoryParam'], parentWidget = self) + dbCreator = DbCreatorFactory().createDbCreatorFactory( + parameterDict["driverName"], + parameterDict["factoryParam"], + parentWidget=self, + ) QApplication.setOverrideCursor(QCursor(Qt.WaitCursor)) dbDict, errorDict = dbCreator.createDbFromMIList( - parameterDict['miList'], - parameterDict['srid'], - prefix=parameterDict['prefix'], - sufix=parameterDict['sufix'], + parameterDict["miList"], + parameterDict["srid"], + prefix=parameterDict["prefix"], + sufix=parameterDict["sufix"], # DEEPER FIX SUGGESTION: validate whether name matches INOM or MI - # formatting and, if it does, set this to True + # formatting and, if it does, set this to True # createFrame=True, # i don't know why this is ALWAYS true createFrame=False, - paramDict=parameterDict['templateInfo'] + paramDict=parameterDict["templateInfo"], ) QApplication.restoreOverrideCursor() return dbDict, errorDict - + def changeTemplateInterface(self): if self.tabDbSelectorWidget.tabWidget.currentIndex() == 1: - self.databaseParameterWidget.changeInterfaceState(True, hideInterface = True) + self.databaseParameterWidget.changeInterfaceState(True, hideInterface=True) else: - self.databaseParameterWidget.changeInterfaceState(True, hideInterface = False) + self.databaseParameterWidget.changeInterfaceState(True, hideInterface=False) diff --git a/DsgTools/gui/DatabaseTools/DbTools/BatchDbCreator/createBatchIncrementing.py b/DsgTools/gui/DatabaseTools/DbTools/BatchDbCreator/createBatchIncrementing.py index 2e60ab853..cd0c9e7aa 100644 --- a/DsgTools/gui/DatabaseTools/DbTools/BatchDbCreator/createBatchIncrementing.py +++ b/DsgTools/gui/DatabaseTools/DbTools/BatchDbCreator/createBatchIncrementing.py @@ -29,46 +29,65 @@ from qgis.PyQt.QtWidgets import QMessageBox, QFileDialog, QApplication from qgis.PyQt.QtGui import QCursor from DsgTools.core.Utils.utils import Utils -from DsgTools.gui.CustomWidgets.BasicInterfaceWidgets.progressWidget import ProgressWidget -from DsgTools.gui.CustomWidgets.SelectionWidgets.tabDbSelectorWidget import TabDbSelectorWidget +from DsgTools.gui.CustomWidgets.BasicInterfaceWidgets.progressWidget import ( + ProgressWidget, +) +from DsgTools.gui.CustomWidgets.SelectionWidgets.tabDbSelectorWidget import ( + TabDbSelectorWidget, +) from DsgTools.core.Factories.DbCreatorFactory.dbCreatorFactory import DbCreatorFactory -FORM_CLASS, _ = uic.loadUiType(os.path.join( - os.path.dirname(__file__), 'createBatchIncrementing.ui')) +FORM_CLASS, _ = uic.loadUiType( + os.path.join(os.path.dirname(__file__), "createBatchIncrementing.ui") +) + class CreateBatchIncrementing(QtWidgets.QWizardPage, FORM_CLASS): parametersSet = pyqtSignal(dict) + def __init__(self, parent=None): """Constructor.""" super(self.__class__, self).__init__() self.setupUi(self) self.databaseParameterWidget.setDbNameVisible(False) - self.tabDbSelectorWidget.serverWidget.serverAbstractDbLoaded.connect(self.databaseParameterWidget.setServerDb) + self.tabDbSelectorWidget.serverWidget.serverAbstractDbLoaded.connect( + self.databaseParameterWidget.setServerDb + ) self.databaseParameterWidget.comboBoxPostgis.parent = self self.databaseParameterWidget.useFrame = False self.databaseParameterWidget.setDbNameVisible(True) - + def getParameters(self): - #Get outputDir, outputList, refSys + # Get outputDir, outputList, refSys parameterDict = dict() - parameterDict['prefix'] = None - parameterDict['sufix'] = None - parameterDict['srid'] = self.databaseParameterWidget.mQgsProjectionSelectionWidget.crs().authid().split(':')[-1] - parameterDict['version'] = self.databaseParameterWidget.getVersion() - parameterDict['nonDefaultTemplate'] = self.databaseParameterWidget.getTemplateName() - if self.databaseParameterWidget.prefixLineEdit.text() != '': - parameterDict['prefix'] = self.databaseParameterWidget.prefixLineEdit.text() - if self.databaseParameterWidget.sufixLineEdit.text() != '': - parameterDict['sufix'] = self.databaseParameterWidget.sufixLineEdit.text() - parameterDict['dbBaseName'] = self.databaseParameterWidget.dbNameLineEdit.text() - parameterDict['driverName'] = self.tabDbSelectorWidget.getType() - parameterDict['factoryParam'] = self.tabDbSelectorWidget.getFactoryCreationParam() - parameterDict['numberOfDatabases'] = self.spinBox.value() - parameterDict['templateInfo'] = self.databaseParameterWidget.getTemplateParameters() + parameterDict["prefix"] = None + parameterDict["sufix"] = None + parameterDict["srid"] = ( + self.databaseParameterWidget.mQgsProjectionSelectionWidget.crs() + .authid() + .split(":")[-1] + ) + parameterDict["version"] = self.databaseParameterWidget.getVersion() + parameterDict[ + "nonDefaultTemplate" + ] = self.databaseParameterWidget.getTemplateName() + if self.databaseParameterWidget.prefixLineEdit.text() != "": + parameterDict["prefix"] = self.databaseParameterWidget.prefixLineEdit.text() + if self.databaseParameterWidget.sufixLineEdit.text() != "": + parameterDict["sufix"] = self.databaseParameterWidget.sufixLineEdit.text() + parameterDict["dbBaseName"] = self.databaseParameterWidget.dbNameLineEdit.text() + parameterDict["driverName"] = self.tabDbSelectorWidget.getType() + parameterDict[ + "factoryParam" + ] = self.tabDbSelectorWidget.getFactoryCreationParam() + parameterDict["numberOfDatabases"] = self.spinBox.value() + parameterDict[ + "templateInfo" + ] = self.databaseParameterWidget.getTemplateParameters() return parameterDict def validatePage(self): - #insert validation messages + # insert validation messages validatedDbParams = self.databaseParameterWidget.validate() if not validatedDbParams: return False @@ -77,28 +96,49 @@ def validatePage(self): return False parameterDict = self.getParameters() dbDict, errorDict = self.createDatabases(parameterDict) - creationMsg = '' + creationMsg = "" if len(list(dbDict.keys())) > 0: - creationMsg += self.tr('Database(s) {0} created successfully.').format(', '.join(list(dbDict.keys()))) - errorMsg = '' + creationMsg += self.tr("Database(s) {0} created successfully.").format( + ", ".join(list(dbDict.keys())) + ) + errorMsg = "" if len(list(errorDict.keys())) > 0: frameList = [] errorList = [] for key in list(errorDict.keys()): errorList.append(key) - QgsMessageLog.logMessage(self.tr('Error on {0}: ').format(key)+errorDict[key], "DSGTools Plugin", Qgis.Critical) + QgsMessageLog.logMessage( + self.tr("Error on {0}: ").format(key) + errorDict[key], + "DSGTools Plugin", + Qgis.Critical, + ) if len(errorList) > 0: - errorMsg += self.tr('Some errors occurred while trying to create database(s) {0}').format(', '.join(errorList)) - logMsg = '' - if errorMsg != '': - logMsg += self.tr('Check log for more details.') - msg = [i for i in (creationMsg, errorMsg, logMsg) if i != ''] - QMessageBox.warning(self, self.tr('Info!'), self.tr('Process finished.')+'\n'+'\n'.join(msg)) + errorMsg += self.tr( + "Some errors occurred while trying to create database(s) {0}" + ).format(", ".join(errorList)) + logMsg = "" + if errorMsg != "": + logMsg += self.tr("Check log for more details.") + msg = [i for i in (creationMsg, errorMsg, logMsg) if i != ""] + QMessageBox.warning( + self, self.tr("Info!"), self.tr("Process finished.") + "\n" + "\n".join(msg) + ) return True - + def createDatabases(self, parameterDict): - dbCreator = DbCreatorFactory().createDbCreatorFactory(parameterDict['driverName'], parameterDict['factoryParam'], parentWidget = self) + dbCreator = DbCreatorFactory().createDbCreatorFactory( + parameterDict["driverName"], + parameterDict["factoryParam"], + parentWidget=self, + ) QApplication.setOverrideCursor(QCursor(Qt.WaitCursor)) - dbDict, errorDict = dbCreator.createDbWithAutoIncrementingName(parameterDict['dbBaseName'], parameterDict['srid'], parameterDict['numberOfDatabases'], prefix = parameterDict['prefix'], sufix = parameterDict['sufix'], paramDict = parameterDict['templateInfo']) + dbDict, errorDict = dbCreator.createDbWithAutoIncrementingName( + parameterDict["dbBaseName"], + parameterDict["srid"], + parameterDict["numberOfDatabases"], + prefix=parameterDict["prefix"], + sufix=parameterDict["sufix"], + paramDict=parameterDict["templateInfo"], + ) QApplication.restoreOverrideCursor() return dbDict, errorDict diff --git a/DsgTools/gui/DatabaseTools/DbTools/SingleDbCreator/singleDbCreator.py b/DsgTools/gui/DatabaseTools/DbTools/SingleDbCreator/singleDbCreator.py index 882da6eaa..636750c6f 100644 --- a/DsgTools/gui/DatabaseTools/DbTools/SingleDbCreator/singleDbCreator.py +++ b/DsgTools/gui/DatabaseTools/DbTools/SingleDbCreator/singleDbCreator.py @@ -31,15 +31,22 @@ from qgis.PyQt.QtWidgets import QMessageBox, QFileDialog, QApplication from qgis.PyQt.QtGui import QCursor from DsgTools.core.Utils.utils import Utils -from DsgTools.gui.CustomWidgets.BasicInterfaceWidgets.progressWidget import ProgressWidget -from DsgTools.gui.CustomWidgets.SelectionWidgets.tabDbSelectorWidget import TabDbSelectorWidget +from DsgTools.gui.CustomWidgets.BasicInterfaceWidgets.progressWidget import ( + ProgressWidget, +) +from DsgTools.gui.CustomWidgets.SelectionWidgets.tabDbSelectorWidget import ( + TabDbSelectorWidget, +) from DsgTools.core.Factories.DbCreatorFactory.dbCreatorFactory import DbCreatorFactory -FORM_CLASS, _ = uic.loadUiType(os.path.join( - os.path.dirname(__file__), 'singleDbCreator.ui')) +FORM_CLASS, _ = uic.loadUiType( + os.path.join(os.path.dirname(__file__), "singleDbCreator.ui") +) + class CreateSingleDatabase(QtWidgets.QDialog, FORM_CLASS): parametersSet = pyqtSignal(dict) + def __init__(self, manager, parentButton, parentMenu, parent=None): """Constructor.""" super(CreateSingleDatabase, self).__init__() @@ -53,13 +60,17 @@ def __init__(self, manager, parentButton, parentMenu, parent=None): self.databaseParameterWidget.sufixLineEdit.hide() self.databaseParameterWidget.prefixLabel.hide() self.databaseParameterWidget.sufixLabel.hide() - self.databaseParameterWidget.groupBox.setTitle('') + self.databaseParameterWidget.groupBox.setTitle("") self.databaseParameterWidget.setDbNameVisible(False) - self.tabDbSelectorWidget.serverWidget.serverAbstractDbLoaded.connect(self.databaseParameterWidget.setServerDb) + self.tabDbSelectorWidget.serverWidget.serverAbstractDbLoaded.connect( + self.databaseParameterWidget.setServerDb + ) self.databaseParameterWidget.comboBoxPostgis.parent = self self.databaseParameterWidget.useFrame = False self.databaseParameterWidget.setDbNameVisible(True) - self.tabDbSelectorWidget.outputDirSelector.label.setText(self.tr('Select Database Path')) + self.tabDbSelectorWidget.outputDirSelector.label.setText( + self.tr("Select Database Path") + ) self.okPushButton.clicked.connect(self.validateParameters) self.cancelPushButton.clicked.connect(self.close_) @@ -85,19 +96,29 @@ def getParameters(self): } } """ - #Get outputDir, outputList, refSys + # Get outputDir, outputList, refSys parameterDict = dict() - parameterDict['srid'] = self.databaseParameterWidget.mQgsProjectionSelectionWidget.crs().authid().split(':')[-1] - parameterDict['version'] = self.databaseParameterWidget.getVersion() - parameterDict['nonDefaultTemplate'] = self.databaseParameterWidget.getTemplateName() - parameterDict['dbBaseName'] = self.databaseParameterWidget.dbNameLineEdit.text() - parameterDict['driverName'] = self.tabDbSelectorWidget.getType() - parameterDict['factoryParam'] = self.tabDbSelectorWidget.getFactoryCreationParam() - parameterDict['templateInfo'] = self.databaseParameterWidget.getTemplateParameters() + parameterDict["srid"] = ( + self.databaseParameterWidget.mQgsProjectionSelectionWidget.crs() + .authid() + .split(":")[-1] + ) + parameterDict["version"] = self.databaseParameterWidget.getVersion() + parameterDict[ + "nonDefaultTemplate" + ] = self.databaseParameterWidget.getTemplateName() + parameterDict["dbBaseName"] = self.databaseParameterWidget.dbNameLineEdit.text() + parameterDict["driverName"] = self.tabDbSelectorWidget.getType() + parameterDict[ + "factoryParam" + ] = self.tabDbSelectorWidget.getFactoryCreationParam() + parameterDict[ + "templateInfo" + ] = self.databaseParameterWidget.getTemplateParameters() return parameterDict def validateParameters(self): - #insert validation messages + # insert validation messages validatedDbParams = self.databaseParameterWidget.validate() if not validatedDbParams: return False @@ -106,51 +127,69 @@ def validateParameters(self): return False parameterDict = self.getParameters() dbDict, errorDict = self.createDatabases(parameterDict) - creationMsg = '' + creationMsg = "" if len(dbDict): - creationMsg = self.tr('Database {0} successfully created.').format(', '.join(list(dbDict.keys()))) - errorMsg = '' + creationMsg = self.tr("Database {0} successfully created.").format( + ", ".join(list(dbDict.keys())) + ) + errorMsg = "" if len(errorDict): frameList = [] errorList = [] for key in list(errorDict.keys()): errorList.append(key) - QgsMessageLog.logMessage(self.tr('Error on {0}: ').format(key)+errorDict[key], "DSGTools Plugin", Qgis.Critical) + QgsMessageLog.logMessage( + self.tr("Error on {0}: ").format(key) + errorDict[key], + "DSGTools Plugin", + Qgis.Critical, + ) if len(errorList) > 0: - errorMsg += self.tr('Some errors occurred while trying to create database(s) {0}').format(', '.join(errorList)) - logMsg = '' - if errorMsg != '': - logMsg += self.tr('Check log for more details.') - msg = [i for i in (creationMsg, errorMsg, logMsg) if i != ''] - QMessageBox.warning(self, self.tr('Info!'), self.tr('Process finished.')+'\n'+'\n'.join(msg)) + errorMsg += self.tr( + "Some errors occurred while trying to create database(s) {0}" + ).format(", ".join(errorList)) + logMsg = "" + if errorMsg != "": + logMsg += self.tr("Check log for more details.") + msg = [i for i in (creationMsg, errorMsg, logMsg) if i != ""] + QMessageBox.warning( + self, self.tr("Info!"), self.tr("Process finished.") + "\n" + "\n".join(msg) + ) self.close() return True - + def createDatabases(self, parameterDict): - dbCreator = DbCreatorFactory().createDbCreatorFactory(parameterDict['driverName'], parameterDict['factoryParam'], parentWidget=self) + dbCreator = DbCreatorFactory().createDbCreatorFactory( + parameterDict["driverName"], + parameterDict["factoryParam"], + parentWidget=self, + ) QApplication.setOverrideCursor(QCursor(Qt.WaitCursor)) dbDict, errorDict = dict(), dict() try: - newDb = dbCreator.createDb(dbName=parameterDict['dbBaseName'], srid=parameterDict['srid'],\ - paramDict=parameterDict['templateInfo'], parentWidget=self) - dbDict[parameterDict['dbBaseName']] = newDb + newDb = dbCreator.createDb( + dbName=parameterDict["dbBaseName"], + srid=parameterDict["srid"], + paramDict=parameterDict["templateInfo"], + parentWidget=self, + ) + dbDict[parameterDict["dbBaseName"]] = newDb except Exception as e: - errorDict[parameterDict['dbBaseName']] = ':'.join(map(str, e.args)) - QApplication.restoreOverrideCursor() + errorDict[parameterDict["dbBaseName"]] = ":".join(map(str, e.args)) + QApplication.restoreOverrideCursor() return dbDict, errorDict def initGui(self): """ - Instantiates user interface and prepare it to be called whenever tool button is activated. + Instantiates user interface and prepare it to be called whenever tool button is activated. """ - callback = lambda : self.manager.createDatabase(isBatchCreation=False) + callback = lambda: self.manager.createDatabase(isBatchCreation=False) self.manager.addTool( - text=self.tr('Create a PostGIS, SpatiaLite or Geopackage Database'), + text=self.tr("Create a PostGIS, SpatiaLite or Geopackage Database"), callback=callback, parentMenu=self.parentMenu, - icon='database.png', + icon="database.png", parentButton=self.parentButton, - defaultButton=True + defaultButton=True, ) def close_(self): @@ -160,4 +199,4 @@ def close_(self): self.close() def unload(self): - pass \ No newline at end of file + pass diff --git a/DsgTools/gui/DatabaseTools/UserTools/PermissionManagerWizard/permissionWizard.py b/DsgTools/gui/DatabaseTools/UserTools/PermissionManagerWizard/permissionWizard.py index c682ee124..1a8756b89 100644 --- a/DsgTools/gui/DatabaseTools/UserTools/PermissionManagerWizard/permissionWizard.py +++ b/DsgTools/gui/DatabaseTools/UserTools/PermissionManagerWizard/permissionWizard.py @@ -28,14 +28,18 @@ from fileinput import filename from DsgTools.core.Utils.utils import Utils -from DsgTools.gui.DatabaseTools.UserTools.PermissionManagerWizard.permissionWizardProfile import PermissionWizardProfile +from DsgTools.gui.DatabaseTools.UserTools.PermissionManagerWizard.permissionWizardProfile import ( + PermissionWizardProfile, +) + +FORM_CLASS, _ = uic.loadUiType( + os.path.join(os.path.dirname(__file__), "permissionWizard.ui") +) -FORM_CLASS, _ = uic.loadUiType(os.path.join( - os.path.dirname(__file__), 'permissionWizard.ui')) class PermissionWizard(QtWidgets.QWizard, FORM_CLASS): def __init__(self, serverAbstractDb, dbsDict, parent=None): - '''Constructor.''' + """Constructor.""" super(self.__class__, self).__init__() # Set up the user interface from Designer. # After setupUI you can access any designer object by doing @@ -45,21 +49,21 @@ def __init__(self, serverAbstractDb, dbsDict, parent=None): self.parent = parent self.setupUi(self) self.serverAbstractDb = serverAbstractDb - self.userCustomSelector.setTitle(self.tr('Select users to be managed')) + self.userCustomSelector.setTitle(self.tr("Select users to be managed")) userList = [i[0] for i in self.serverAbstractDb.getUsersFromServer()] self.userCustomSelector.setInitialState(userList) - self.sequenceDict = {'PermissionWizardProfile':1} - - self.setPage(self.sequenceDict['PermissionWizardProfile'],PermissionWizardProfile()) - #self.setPage(self.sequenceDict['CreateBatchIncrementing'],CreateBatchIncrementing()) + self.sequenceDict = {"PermissionWizardProfile": 1} + + self.setPage( + self.sequenceDict["PermissionWizardProfile"], PermissionWizardProfile() + ) + # self.setPage(self.sequenceDict['CreateBatchIncrementing'],CreateBatchIncrementing()) def nextId(self): if self.currentId() == 0: if len(self.userCustomSelector.toLs) != 0: - return self.sequenceDict['PermissionWizardProfile'] + return self.sequenceDict["PermissionWizardProfile"] else: return -1 else: return self.currentId() - - \ No newline at end of file diff --git a/DsgTools/gui/DatabaseTools/UserTools/PermissionManagerWizard/permissionWizardProfile.py b/DsgTools/gui/DatabaseTools/UserTools/PermissionManagerWizard/permissionWizardProfile.py index 8cbc46c9c..f2149bc6a 100644 --- a/DsgTools/gui/DatabaseTools/UserTools/PermissionManagerWizard/permissionWizardProfile.py +++ b/DsgTools/gui/DatabaseTools/UserTools/PermissionManagerWizard/permissionWizardProfile.py @@ -30,12 +30,14 @@ from DsgTools.core.Utils.utils import Utils from DsgTools.core.Factories.DbCreatorFactory.dbCreatorFactory import DbCreatorFactory -FORM_CLASS, _ = uic.loadUiType(os.path.join( - os.path.dirname(__file__), 'permissionWizardProfile.ui')) +FORM_CLASS, _ = uic.loadUiType( + os.path.join(os.path.dirname(__file__), "permissionWizardProfile.ui") +) + class PermissionWizardProfile(QtWidgets.QWizardPage, FORM_CLASS): def __init__(self, parent=None): - '''Constructor.''' + """Constructor.""" super(self.__class__, self).__init__() # Set up the user interface from Designer. # After setupUI you can access any designer object by doing @@ -43,18 +45,18 @@ def __init__(self, parent=None): # http://qt-project.org/doc/qt-4.8/designer-using-a-ui-file.html # #widgets-and-dialogs-with-auto-connect self.setupUi(self) - self.profileCustomSelector.setTitle(self.tr('Select profiles to be installed')) + self.profileCustomSelector.setTitle(self.tr("Select profiles to be installed")) profiles = self.getModelProfiles() self.profileCustomSelector.setInitialState(profiles) - + def getModelProfiles(self): ret = [] - folder = os.path.join(os.path.dirname(__file__),'..', 'profiles') + folder = os.path.join(os.path.dirname(__file__), "..", "profiles") for root, dirs, files in os.walk(folder): for file in files: - ext = file.split('.')[-1] - if ext == 'json': - ret.append(file.split('.')[0]) + ext = file.split(".")[-1] + if ext == "json": + ret.append(file.split(".")[0]) ret.sort() return ret diff --git a/DsgTools/gui/DatabaseTools/UserTools/alter_user_password.py b/DsgTools/gui/DatabaseTools/UserTools/alter_user_password.py index db6e386f2..770e9642a 100644 --- a/DsgTools/gui/DatabaseTools/UserTools/alter_user_password.py +++ b/DsgTools/gui/DatabaseTools/UserTools/alter_user_password.py @@ -29,11 +29,13 @@ from qgis.core import Qgis, QgsMessageLog -FORM_CLASS, _ = uic.loadUiType(os.path.join( - os.path.dirname(__file__), 'alter_user_password.ui')) +FORM_CLASS, _ = uic.loadUiType( + os.path.join(os.path.dirname(__file__), "alter_user_password.ui") +) + class AlterUserPassword(QtWidgets.QDialog, FORM_CLASS): - def __init__(self, user = None, abstractDb = None, userList = None, parent = None): + def __init__(self, user=None, abstractDb=None, userList=None, parent=None): """ Constructor """ @@ -48,7 +50,7 @@ def __init__(self, user = None, abstractDb = None, userList = None, parent = Non self.user = user self.newPasswordLineEdit.setFocus() self.userList = userList - + @pyqtSlot(bool) def on_alterPasswordButton_clicked(self): """ @@ -57,14 +59,18 @@ def on_alterPasswordButton_clicked(self): newpassword = self.newPasswordLineEdit.text() newpassword_2 = self.newPasswordLineEdit_2.text() if newpassword != newpassword_2: - QMessageBox.critical(self, self.tr('Critical!'), self.tr('Password mismatch! Password not altered!')) + QMessageBox.critical( + self, + self.tr("Critical!"), + self.tr("Password mismatch! Password not altered!"), + ) return if self.user: self.alterDatabasePassword(self.user, newpassword) if self.userList: self.alterServerPassword(self.userList, newpassword) self.close() - + def alterDatabasePassword(self, user, newpassword): """ Alters the password of a specific user @@ -72,10 +78,18 @@ def alterDatabasePassword(self, user, newpassword): try: self.abstractDb.alterUserPass(self.user, newpassword) except Exception as e: - QMessageBox.critical(self, self.tr('Critical!'), e.args[0]) + QMessageBox.critical(self, self.tr("Critical!"), e.args[0]) return - QMessageBox.warning(self, self.tr('Success!'), self.tr('User ') +self.user+self.tr(' password successfully updated on database ')+self.abstractDb.getDatabaseName()+'!') - + QMessageBox.warning( + self, + self.tr("Success!"), + self.tr("User ") + + self.user + + self.tr(" password successfully updated on database ") + + self.abstractDb.getDatabaseName() + + "!", + ) + def alterServerPassword(self, userList, newpassword): """ Alters the password of a list of database users @@ -87,38 +101,49 @@ def alterServerPassword(self, userList, newpassword): self.abstractDb.alterUserPass(user, newpassword) successList.append(user) except Exception as e: - exceptionDict[user] = ':'.join(e.args) - header = self.tr('Alter operation on server ')+self.abstractDb.getHostName()+self.tr(' complete!\n') + exceptionDict[user] = ":".join(e.args) + header = ( + self.tr("Alter operation on server ") + + self.abstractDb.getHostName() + + self.tr(" complete!\n") + ) self.outputMessage(header, successList, exceptionDict) - + def outputMessage(self, header, successList, exceptionDict): """ Makes the output message """ msg = header if len(successList) > 0: - msg += self.tr('\nSuccessful users: ') - msg +=', '.join(successList) + msg += self.tr("\nSuccessful users: ") + msg += ", ".join(successList) msg += self.logInternalError(exceptionDict) - QMessageBox.warning(self, self.tr('Operation Complete!'), msg) + QMessageBox.warning(self, self.tr("Operation Complete!"), msg) def logInternalError(self, exceptionDict): """ Logs all internal errors into QGIS' log """ - msg = '' + msg = "" errorDbList = list(exceptionDict.keys()) - if len(errorDbList)> 0: - msg += self.tr('\nUsers with error:') - msg+= ', '.join(errorDbList) - msg+= self.tr('\nError messages for each user were output in qgis log.') + if len(errorDbList) > 0: + msg += self.tr("\nUsers with error:") + msg += ", ".join(errorDbList) + msg += self.tr("\nError messages for each user were output in qgis log.") for errorDb in errorDbList: - QgsMessageLog.logMessage(self.tr('Error for user ')+ errorDb + ': ' +exceptionDict[errorDb], "DSGTools Plugin", Qgis.Critical) - return msg + QgsMessageLog.logMessage( + self.tr("Error for user ") + + errorDb + + ": " + + exceptionDict[errorDb], + "DSGTools Plugin", + Qgis.Critical, + ) + return msg @pyqtSlot(bool) def on_cancelButton_clicked(self): """ Cancels everything """ - self.close() \ No newline at end of file + self.close() diff --git a/DsgTools/gui/DatabaseTools/UserTools/assign_profiles.py b/DsgTools/gui/DatabaseTools/UserTools/assign_profiles.py index 2c7049722..165362882 100644 --- a/DsgTools/gui/DatabaseTools/UserTools/assign_profiles.py +++ b/DsgTools/gui/DatabaseTools/UserTools/assign_profiles.py @@ -22,7 +22,7 @@ """ import os -#PyQt imports +# PyQt imports from qgis.PyQt.QtWidgets import QApplication from qgis.PyQt.QtGui import QCursor @@ -35,11 +35,13 @@ import json -FORM_CLASS, _ = uic.loadUiType(os.path.join( - os.path.dirname(__file__), 'assign_profiles.ui')) +FORM_CLASS, _ = uic.loadUiType( + os.path.join(os.path.dirname(__file__), "assign_profiles.ui") +) + class AssignProfiles(QtWidgets.QDialog, FORM_CLASS): - def __init__(self, serverIndex = None, index = None, parent = None): + def __init__(self, serverIndex=None, index=None, parent=None): """ Constructor """ @@ -55,56 +57,60 @@ def __init__(self, serverIndex = None, index = None, parent = None): self.widget.serverWidget.serversCombo.setCurrentIndex(serverIndex) self.widget.comboBoxPostgis.setCurrentIndex(index) self.widget.serverWidget.superNeeded = True - self.folder = os.path.join(os.path.dirname(__file__), 'profiles') + self.folder = os.path.join(os.path.dirname(__file__), "profiles") self.getModelProfiles() self.getInstalledProfiles() - - #Objects Connections - QtCore.QObject.connect(self.widget, QtCore.SIGNAL(("connectionChanged()")), self.getInstalledProfiles) + + # Objects Connections + QtCore.QObject.connect( + self.widget, + QtCore.SIGNAL(("connectionChanged()")), + self.getInstalledProfiles, + ) def parseJson(self, filename): """ Parses the profile file and creates a dictionary """ try: - file = open(filename, 'r') + file = open(filename, "r") data = file.read() profileDict = json.loads(data) file.close() return profileDict except: return None - + def getModelProfiles(self): """ Scans the profile folder for files and make a list with them """ self.possibleProfiles.clear() - + ret = [] for root, dirs, files in os.walk(self.folder): for file in files: - ext = file.split('.')[-1] - if ext == 'json': - ret.append(file.split('.')[0]) + ext = file.split(".")[-1] + if ext == "json": + ret.append(file.split(".")[0]) ret.sort() self.possibleProfiles.addItems(ret) - + def getInstalledProfiles(self): """ Gets the installed profiles from a database """ self.assignedProfiles.clear() - + if not self.widget.abstractDb: return - + ret = [] try: ret = self.widget.abstractDb.getRoles() except Exception as e: - QMessageBox.critical(self, self.tr('Critical!'), ':'.join(e.args)) + QMessageBox.critical(self, self.tr("Critical!"), ":".join(e.args)) self.assignedProfiles.addItems(ret) @@ -114,35 +120,41 @@ def on_installButton_clicked(self): Installs the selected profiles into the database selected """ if len(self.possibleProfiles.selectedItems()) == 0: - QMessageBox.warning(self, self.tr('Warning!'), self.tr('Select at least one profile and try again!')) - return - + QMessageBox.warning( + self, + self.tr("Warning!"), + self.tr("Select at least one profile and try again!"), + ) + return + QApplication.setOverrideCursor(QCursor(Qt.WaitCursor)) for item in self.possibleProfiles.selectedItems(): role = item.text() - profile = os.path.join(self.folder, role +'.json') + profile = os.path.join(self.folder, role + ".json") dict = self.parseJson(profile) - + try: self.widget.abstractDb.createRole(role, dict) except Exception as e: QApplication.restoreOverrideCursor() - QMessageBox.critical(self, self.tr('Critical!'), ':'.join(e.args)) + QMessageBox.critical(self, self.tr("Critical!"), ":".join(e.args)) return - + QApplication.restoreOverrideCursor() - QMessageBox.warning(self, self.tr('Warning!'), self.tr('Profiles assigned successfully!')) - + QMessageBox.warning( + self, self.tr("Warning!"), self.tr("Profiles assigned successfully!") + ) + self.getInstalledProfiles() - + @pyqtSlot(bool) def on_closeButton_clicked(self): """ Closes the dialog """ self.close() - + @pyqtSlot(bool) def on_openProfileEditor_clicked(self): """ @@ -151,16 +163,20 @@ def on_openProfileEditor_clicked(self): dlg = ProfileEditor() dlg.exec_() self.getModelProfiles() - + @pyqtSlot(bool) def on_removeButton_clicked(self): """ Removes a installed profile from the database (i.e we execute a drop role sql query) """ if len(self.assignedProfiles.selectedItems()) == 0: - QMessageBox.warning(self, self.tr('Warning!'), self.tr('Select at least one profile and try again!')) - return - + QMessageBox.warning( + self, + self.tr("Warning!"), + self.tr("Select at least one profile and try again!"), + ) + return + QApplication.setOverrideCursor(QCursor(Qt.WaitCursor)) problem = False @@ -172,12 +188,14 @@ def on_removeButton_clicked(self): except Exception as e: problem = True QApplication.restoreOverrideCursor() - QMessageBox.critical(self, self.tr('Critical!'), ':'.join(e.args)) + QMessageBox.critical(self, self.tr("Critical!"), ":".join(e.args)) if not problem: QApplication.restoreOverrideCursor() - QMessageBox.warning(self, self.tr('Warning!'), self.tr('Profiles removed successfully!')) - + QMessageBox.warning( + self, self.tr("Warning!"), self.tr("Profiles removed successfully!") + ) + self.getInstalledProfiles() @pyqtSlot(bool) @@ -186,19 +204,38 @@ def on_removeJson_clicked(self): Deletes a profile file """ if len(self.possibleProfiles.selectedItems()) == 0: - QMessageBox.warning(self, self.tr('Warning!'), self.tr('Select at least one profile and try again!')) - return - - if QMessageBox.question(self, self.tr('Question'), self.tr('Do you really want to remove selected profile models?'), QMessageBox.Ok|QMessageBox.Cancel) == QMessageBox.Cancel: + QMessageBox.warning( + self, + self.tr("Warning!"), + self.tr("Select at least one profile and try again!"), + ) + return + + if ( + QMessageBox.question( + self, + self.tr("Question"), + self.tr("Do you really want to remove selected profile models?"), + QMessageBox.Ok | QMessageBox.Cancel, + ) + == QMessageBox.Cancel + ): return - + for item in self.possibleProfiles.selectedItems(): json = item.text() - file = json+'.json' + file = json + ".json" path = os.path.join(self.folder, file) try: os.remove(path) except OSError as e: - QMessageBox.critical(self, self.tr('Critical!'), self.tr('Problem removing profile model: ')+json+'\n'+e.strerror) - + QMessageBox.critical( + self, + self.tr("Critical!"), + self.tr("Problem removing profile model: ") + + json + + "\n" + + e.strerror, + ) + self.getModelProfiles() diff --git a/DsgTools/gui/DatabaseTools/UserTools/createProfileWithProfileManager.py b/DsgTools/gui/DatabaseTools/UserTools/createProfileWithProfileManager.py index 51b571b23..cfcb967b8 100644 --- a/DsgTools/gui/DatabaseTools/UserTools/createProfileWithProfileManager.py +++ b/DsgTools/gui/DatabaseTools/UserTools/createProfileWithProfileManager.py @@ -33,13 +33,15 @@ import json -FORM_CLASS, _ = uic.loadUiType(os.path.join( - os.path.dirname(__file__), 'createProfileWithProfileManager.ui')) +FORM_CLASS, _ = uic.loadUiType( + os.path.join(os.path.dirname(__file__), "createProfileWithProfileManager.ui") +) + class CreateProfileWithProfileManager(QtWidgets.QDialog, FORM_CLASS): profileCreated = pyqtSignal(str, str) - - def __init__(self, permissionManager, abstractDb, parent = None): + + def __init__(self, permissionManager, abstractDb, parent=None): """ Constructor """ @@ -55,7 +57,7 @@ def __init__(self, permissionManager, abstractDb, parent = None): self.abstractDbFactory = DbFactory() self.populateTreeDict() - + def __del__(self): """ Destructor @@ -70,26 +72,30 @@ def populateTreeDict(self): """ try: geomTypeDict = self.abstractDb.getGeomTypeDict() - geomDict = self.abstractDb.getGeomDict(geomTypeDict, insertCategory = True) + geomDict = self.abstractDb.getGeomDict(geomTypeDict, insertCategory=True) except Exception as e: - QMessageBox.critical(self, self.tr('Critical!'), self.tr('A problem occurred! Check log for details.')) - QgsMessageLog.logMessage(':'.join(e.args), 'DSGTools Plugin', Qgis.Critical) + QMessageBox.critical( + self, + self.tr("Critical!"), + self.tr("A problem occurred! Check log for details."), + ) + QgsMessageLog.logMessage(":".join(e.args), "DSGTools Plugin", Qgis.Critical) return version = self.abstractDb.getDatabaseVersion() self.profile = dict() categories = dict() for layerName in list(geomDict.keys()): - schema = geomDict[layerName]['schema'] - category = geomDict[layerName]['category'] + schema = geomDict[layerName]["schema"] + category = geomDict[layerName]["category"] if schema not in list(categories.keys()): categories[schema] = dict() if category not in list(categories[schema].keys()): categories[schema][category] = dict() if layerName not in categories[schema][category]: categories[schema][category][layerName] = dict() - categories[schema][category][layerName]['read'] = '0' - categories[schema][category][layerName]['write'] = '0' - self.profile['database'+'_'+version] = categories + categories[schema][category][layerName]["read"] = "0" + categories[schema][category][layerName]["write"] = "0" + self.profile["database" + "_" + version] = categories @pyqtSlot() def on_buttonBox_accepted(self): @@ -97,7 +103,9 @@ def on_buttonBox_accepted(self): Creates the profile file """ if not self.lineEdit.text(): - QMessageBox.warning(self, self.tr('Warning!'), self.tr('Fill the profile name!')) + QMessageBox.warning( + self, self.tr("Warning!"), self.tr("Fill the profile name!") + ) return else: profileName = self.lineEdit.text() @@ -105,7 +113,15 @@ def on_buttonBox_accepted(self): edgvVersion = self.versionCombo.currentText() if edgvVersion in list(permissionDict.keys()): if profileName in permissionDict[edgvVersion]: - QMessageBox.warning(self, self.tr('Warning!'), self.tr('Profile ') + profileName + self.tr(' for EDGV ') + edgvVersion + self.tr(' already exists!')) + QMessageBox.warning( + self, + self.tr("Warning!"), + self.tr("Profile ") + + profileName + + self.tr(" for EDGV ") + + edgvVersion + + self.tr(" already exists!"), + ) return jsonDict = json.dumps(self.profile, sort_keys=True, indent=4) self.permissionManager.createSetting(profileName, edgvVersion, jsonDict) diff --git a/DsgTools/gui/DatabaseTools/UserTools/create_profile.py b/DsgTools/gui/DatabaseTools/UserTools/create_profile.py index ce4303906..fe5b75df2 100644 --- a/DsgTools/gui/DatabaseTools/UserTools/create_profile.py +++ b/DsgTools/gui/DatabaseTools/UserTools/create_profile.py @@ -34,13 +34,15 @@ import json -FORM_CLASS, _ = uic.loadUiType(os.path.join( - os.path.dirname(__file__), 'create_profile.ui')) +FORM_CLASS, _ = uic.loadUiType( + os.path.join(os.path.dirname(__file__), "create_profile.ui") +) + class CreateProfile(QtWidgets.QDialog, FORM_CLASS): profileCreated = pyqtSignal(str) - - def __init__(self, parent = None): + + def __init__(self, parent=None): """ Constructor """ @@ -51,13 +53,13 @@ def __init__(self, parent = None): # http://qt-project.org/doc/qt-4.8/designer-using-a-ui-file.html # #widgets-and-dialogs-with-auto-connect self.setupUi(self) - self.folder = os.path.join(os.path.dirname(__file__), 'profiles') + self.folder = os.path.join(os.path.dirname(__file__), "profiles") self.abstractDb = None self.abstractDbFactory = DbFactory() self.populateTreeDict() - + def __del__(self): """ Destructor @@ -65,28 +67,54 @@ def __del__(self): if self.abstractDb: del self.abstractDb self.abstractDb = None - + def getDbInfo(self): """ Gets database info. This info is used to create a profile model that will be adjusted by the user """ currentPath = os.path.dirname(__file__) - if self.versionCombo.currentText() == '2.1.3': - edgvPath = os.path.join(currentPath, '..', 'DbTools', 'SpatialiteTool', 'template', '213', 'seed_edgv213.sqlite') - elif self.versionCombo.currentText() == 'FTer_2a_Ed': - edgvPath = os.path.join(currentPath, '..', 'DbTools', 'SpatialiteTool', 'template', 'FTer_2a_Ed', 'seed_edgvfter_2a_ed.sqlite') - - self.abstractDb = self.abstractDbFactory.createDbFactory(DsgEnums.DriverSpatiaLite) + if self.versionCombo.currentText() == "2.1.3": + edgvPath = os.path.join( + currentPath, + "..", + "DbTools", + "SpatialiteTool", + "template", + "213", + "seed_edgv213.sqlite", + ) + elif self.versionCombo.currentText() == "FTer_2a_Ed": + edgvPath = os.path.join( + currentPath, + "..", + "DbTools", + "SpatialiteTool", + "template", + "FTer_2a_Ed", + "seed_edgvfter_2a_ed.sqlite", + ) + + self.abstractDb = self.abstractDbFactory.createDbFactory( + DsgEnums.DriverSpatiaLite + ) if not self.abstractDb: - QtWidgets.QMessageBox.warning(self, self.tr('Warning!'), self.tr('A problem occurred! Check log for details.')) + QtWidgets.QMessageBox.warning( + self, + self.tr("Warning!"), + self.tr("A problem occurred! Check log for details."), + ) return self.abstractDb.connectDatabase(edgvPath) try: self.abstractDb.checkAndOpenDb() except Exception as e: - QtWidgets.QMessageBox.critical(self, self.tr('Critical!'), self.tr('A problem occurred! Check log for details.')) - QgsMessageLog.logMessage(':'.join(e.args), 'DSGTools Plugin', Qgis.Critical) + QtWidgets.QMessageBox.critical( + self, + self.tr("Critical!"), + self.tr("A problem occurred! Check log for details."), + ) + QgsMessageLog.logMessage(":".join(e.args), "DSGTools Plugin", Qgis.Critical) def populateTreeDict(self): """ @@ -98,34 +126,46 @@ def populateTreeDict(self): try: tables = self.abstractDb.getTablesFromDatabase() except Exception as e: - QtWidgets.QMessageBox.critical(self, self.tr('Critical!'), self.tr('A problem occurred! Check log for details.')) - QgsMessageLog.logMessage(':'.join(e.args), 'DSGTools Plugin', Qgis.Critical) - + QtWidgets.QMessageBox.critical( + self, + self.tr("Critical!"), + self.tr("A problem occurred! Check log for details."), + ) + QgsMessageLog.logMessage(":".join(e.args), "DSGTools Plugin", Qgis.Critical) + self.profile = dict() categories = dict() for tableName in tables: - #proceed only for edgv tables - if tableName.split("_")[-1] == "p" or tableName.split("_")[-1] == "l" or tableName.split("_")[-1] == "a" or tableName.split("_")[0] == 'complexos' or tableName.split("_")[0] == 'dominios': - layerName = tableName.split('_')[0]+'.'+'_'.join(tableName.split('_')[1::]) - split = tableName.split('_') - + # proceed only for edgv tables + if ( + tableName.split("_")[-1] == "p" + or tableName.split("_")[-1] == "l" + or tableName.split("_")[-1] == "a" + or tableName.split("_")[0] == "complexos" + or tableName.split("_")[0] == "dominios" + ): + layerName = ( + tableName.split("_")[0] + "." + "_".join(tableName.split("_")[1::]) + ) + split = tableName.split("_") + if len(split) < 2: continue - + schema = split[0] category = split[1] if schema not in list(categories.keys()): categories[schema] = dict() - + if category not in list(categories[schema].keys()): categories[schema][category] = dict() if layerName not in categories[schema][category]: categories[schema][category][layerName] = dict() - categories[schema][category][layerName]['read'] = '0' - categories[schema][category][layerName]['write'] = '0' - - self.profile['database'+'_'+self.versionCombo.currentText()] = categories + categories[schema][category][layerName]["read"] = "0" + categories[schema][category][layerName]["write"] = "0" + + self.profile["database" + "_" + self.versionCombo.currentText()] = categories @pyqtSlot() def on_buttonBox_accepted(self): @@ -133,14 +173,16 @@ def on_buttonBox_accepted(self): Creates the profile file """ if not self.lineEdit.text(): - QtWidgets.QMessageBox.warning(self, self.tr('Warning!'), self.tr('Fill the profile name!')) + QtWidgets.QMessageBox.warning( + self, self.tr("Warning!"), self.tr("Fill the profile name!") + ) return else: profileName = self.lineEdit.text() - - path = os.path.join(self.folder, profileName+'.json') - - with open(path, 'w') as outfile: + + path = os.path.join(self.folder, profileName + ".json") + + with open(path, "w") as outfile: json.dump(self.profile, outfile, sort_keys=True, indent=4) self.profileCreated.emit(profileName) diff --git a/DsgTools/gui/DatabaseTools/UserTools/create_user.py b/DsgTools/gui/DatabaseTools/UserTools/create_user.py index be5374f69..5bd542071 100644 --- a/DsgTools/gui/DatabaseTools/UserTools/create_user.py +++ b/DsgTools/gui/DatabaseTools/UserTools/create_user.py @@ -27,11 +27,13 @@ from qgis.PyQt.QtCore import pyqtSlot from qgis.PyQt.QtSql import QSqlQuery -FORM_CLASS, _ = uic.loadUiType(os.path.join( - os.path.dirname(__file__), 'create_user.ui')) +FORM_CLASS, _ = uic.loadUiType( + os.path.join(os.path.dirname(__file__), "create_user.ui") +) + class CreateUser(QtWidgets.QDialog, FORM_CLASS): - def __init__(self, user = None, abstractDb = None, parent = None): + def __init__(self, user=None, abstractDb=None, parent=None): """ Constructor """ @@ -44,16 +46,16 @@ def __init__(self, user = None, abstractDb = None, parent = None): self.setupUi(self) self.abstractDb = abstractDb self.refreshScreen() - + def refreshScreen(self): """ Restores the initial state """ - self.userLineEdit.setText('') - self.passwordLineEdit.setText('') - self.passwordLineEdit_2.setText('') + self.userLineEdit.setText("") + self.passwordLineEdit.setText("") + self.passwordLineEdit_2.setText("") self.superUserCheckBox.setCheckState(0) - + @pyqtSlot(bool) def on_createUserButton_clicked(self): """ @@ -63,11 +65,14 @@ def on_createUserButton_clicked(self): password = self.passwordLineEdit.text() password_2 = self.passwordLineEdit_2.text() if password != password_2: - QtWidgets.QMessageBox.critical(self, self.tr('Critical!'), self.tr('Password mismatch! User not created!')) + QtWidgets.QMessageBox.critical( + self, + self.tr("Critical!"), + self.tr("Password mismatch! User not created!"), + ) self.refreshScreen() return - - + if self.superUserCheckBox.checkState() == 2: isSuperUser = True else: @@ -76,11 +81,19 @@ def on_createUserButton_clicked(self): try: self.abstractDb.createUser(user, password, isSuperUser) except Exception as e: - QtWidgets.QMessageBox.critical(self, self.tr('Critical!'), ':'.join(e.args)) + QtWidgets.QMessageBox.critical(self, self.tr("Critical!"), ":".join(e.args)) self.refreshScreen() return - QtWidgets.QMessageBox.warning(self, self.tr('Success!'), self.tr('User ') +user+self.tr(' created successfully on server ')+self.abstractDb.getHostName()+'!') + QtWidgets.QMessageBox.warning( + self, + self.tr("Success!"), + self.tr("User ") + + user + + self.tr(" created successfully on server ") + + self.abstractDb.getHostName() + + "!", + ) self.refreshScreen() return diff --git a/DsgTools/gui/DatabaseTools/UserTools/dbProfileManager.py b/DsgTools/gui/DatabaseTools/UserTools/dbProfileManager.py index ac3594d94..d4367592d 100644 --- a/DsgTools/gui/DatabaseTools/UserTools/dbProfileManager.py +++ b/DsgTools/gui/DatabaseTools/UserTools/dbProfileManager.py @@ -28,16 +28,32 @@ # Qt imports from qgis.PyQt import QtWidgets, uic from qgis.PyQt.QtCore import pyqtSlot, Qt -from qgis.PyQt.QtWidgets import QListWidgetItem, QMessageBox, QMenu, QApplication, QFileDialog +from qgis.PyQt.QtWidgets import ( + QListWidgetItem, + QMessageBox, + QMenu, + QApplication, + QFileDialog, +) from qgis.PyQt.QtGui import QCursor -FORM_CLASS, _ = uic.loadUiType(os.path.join( - os.path.dirname(__file__), 'dbProfileManager.ui')) +FORM_CLASS, _ = uic.loadUiType( + os.path.join(os.path.dirname(__file__), "dbProfileManager.ui") +) + class DbProfileManager(QtWidgets.QDialog, FORM_CLASS): - - def __init__(self, grantedProfileList, notGrantedProfileList, permissionManager, userName, dbName, edgvVersion, parent = None): + def __init__( + self, + grantedProfileList, + notGrantedProfileList, + permissionManager, + userName, + dbName, + edgvVersion, + parent=None, + ): """Constructor.""" super(self.__class__, self).__init__(parent) self.setupUi(self) @@ -47,54 +63,80 @@ def __init__(self, grantedProfileList, notGrantedProfileList, permissionManager, self.userName = userName self.dbName = dbName self.edgvVersion = edgvVersion - self.profileCustomSelector.setTitle(self.tr('Manage permissions to user ') + userName + self.tr(' on database ') + dbName) - self.profileCustomSelector.setFromList(list(notGrantedProfileList), unique = True) #passes a copy using list() + self.profileCustomSelector.setTitle( + self.tr("Manage permissions to user ") + + userName + + self.tr(" on database ") + + dbName + ) + self.profileCustomSelector.setFromList( + list(notGrantedProfileList), unique=True + ) # passes a copy using list() self.profileCustomSelector.setToList(list(grantedProfileList)) - + @pyqtSlot(bool) def on_applyPushButton_clicked(self): - permissionsToGrant = [i for i in self.profileCustomSelector.toLs if i not in self.grantedProfileList] - profilesToRevoke = [i for i in self.profileCustomSelector.fromLs if i not in self.notGrantedProfileList] - #grant operation - header = self.tr('Grant / Revoke operation complete: ') + permissionsToGrant = [ + i + for i in self.profileCustomSelector.toLs + if i not in self.grantedProfileList + ] + profilesToRevoke = [ + i + for i in self.profileCustomSelector.fromLs + if i not in self.notGrantedProfileList + ] + # grant operation + header = self.tr("Grant / Revoke operation complete: ") successList = [] errorDict = dict() QApplication.setOverrideCursor(QCursor(Qt.WaitCursor)) for profileName in permissionsToGrant: try: - self.permissionManager.grantPermission(self.dbName, profileName, self.edgvVersion, self.userName) #TODO: add error treatment + self.permissionManager.grantPermission( + self.dbName, profileName, self.edgvVersion, self.userName + ) # TODO: add error treatment successList.append(profileName) except Exception as e: errorDict[profileName] = str(e.args[0]) for profileName in profilesToRevoke: try: - self.permissionManager.revokePermission(self.dbName, profileName, self.userName) #TODO: add error treatment + self.permissionManager.revokePermission( + self.dbName, profileName, self.userName + ) # TODO: add error treatment successList.append(profileName) except Exception as e: - errorDict[profileName] = ':'.join(e.args) + errorDict[profileName] = ":".join(e.args) QApplication.restoreOverrideCursor() self.outputMessage(header, successList, errorDict) self.close() - + @pyqtSlot(bool) def on_cancelPushButton_clicked(self): - self.close() - + self.close() + def outputMessage(self, header, successList, exceptionDict): msg = header if len(successList) > 0: - msg += self.tr('\nSuccessful profiles: ') - msg +=', '.join(successList) + msg += self.tr("\nSuccessful profiles: ") + msg += ", ".join(successList) msg += self.logInternalError(exceptionDict) - QMessageBox.warning(self, self.tr('Operation Complete!'), msg) - + QMessageBox.warning(self, self.tr("Operation Complete!"), msg) + def logInternalError(self, exceptionDict): - msg = '' + msg = "" errorDbList = list(exceptionDict.keys()) - if len(errorDbList)> 0: - msg += self.tr('\Profiles with error:') - msg+= ', '.join(errorDbList) - msg+= self.tr('\nError messages for each profile were output in qgis log.') + if len(errorDbList) > 0: + msg += self.tr("\Profiles with error:") + msg += ", ".join(errorDbList) + msg += self.tr("\nError messages for each profile were output in qgis log.") for errorDb in errorDbList: - QgsMessageLog.logMessage(self.tr('Error for profile ')+ errorDb + ': ' +exceptionDict[errorDb], "DSGTools Plugin", Qgis.Critical) - return msg \ No newline at end of file + QgsMessageLog.logMessage( + self.tr("Error for profile ") + + errorDb + + ": " + + exceptionDict[errorDb], + "DSGTools Plugin", + Qgis.Critical, + ) + return msg diff --git a/DsgTools/gui/DatabaseTools/UserTools/manageServerUsers.py b/DsgTools/gui/DatabaseTools/UserTools/manageServerUsers.py index 5bffb7a2c..16d165751 100644 --- a/DsgTools/gui/DatabaseTools/UserTools/manageServerUsers.py +++ b/DsgTools/gui/DatabaseTools/UserTools/manageServerUsers.py @@ -28,29 +28,38 @@ # Qt imports from qgis.PyQt import QtWidgets, uic from qgis.PyQt.QtCore import pyqtSlot, Qt, QSettings -from qgis.PyQt.QtWidgets import QListWidgetItem, QMessageBox, QMenu, QApplication, QFileDialog +from qgis.PyQt.QtWidgets import ( + QListWidgetItem, + QMessageBox, + QMenu, + QApplication, + QFileDialog, +) from qgis.PyQt.QtGui import QCursor from qgis.PyQt.QtSql import QSqlDatabase, QSqlQuery # DSGTools imports from DsgTools.gui.DatabaseTools.UserTools.create_user import CreateUser from DsgTools.gui.DatabaseTools.UserTools.alter_user_password import AlterUserPassword -from DsgTools.gui.DatabaseTools.UserTools.permission_properties import PermissionProperties +from DsgTools.gui.DatabaseTools.UserTools.permission_properties import ( + PermissionProperties, +) -FORM_CLASS, _ = uic.loadUiType(os.path.join( - os.path.dirname(__file__), 'manageServerUsers.ui')) +FORM_CLASS, _ = uic.loadUiType( + os.path.join(os.path.dirname(__file__), "manageServerUsers.ui") +) + class ManageServerUsers(QtWidgets.QDialog, FORM_CLASS): - - def __init__(self, abstractDb, parent = None): + def __init__(self, abstractDb, parent=None): """Constructor.""" super(self.__class__, self).__init__(parent) self.setupUi(self) self.abstractDb = abstractDb - self.userTypeDict = {True:self.tr('Super User'), False:self.tr('User')} + self.userTypeDict = {True: self.tr("Super User"), False: self.tr("User")} self.populateUsers() - + def populateUsers(self): self.serverUserTable.clear() rootNode = self.serverUserTable.invisibleRootItem() @@ -60,36 +69,51 @@ def populateUsers(self): try: ret = self.abstractDb.getUsersFromServer() except Exception as e: - QMessageBox.critical(self, self.tr('Critical!'), ':'.join(e.args)) + QMessageBox.critical(self, self.tr("Critical!"), ":".join(e.args)) for user, type in ret: userNameItem = self.createItem(rootNode, user, 0) - userNameItem.setText(1,self.userTypeDict[type]) - + userNameItem.setText(1, self.userTypeDict[type]) + def createItem(self, parent, text, column): item = QtWidgets.QTreeWidgetItem(parent) item.setText(column, text) return item - + @pyqtSlot(bool) def on_createUserButton_clicked(self): if not self.abstractDb: - QMessageBox.critical(self, self.tr('Critical!'), self.tr('First select a database!')) + QMessageBox.critical( + self, self.tr("Critical!"), self.tr("First select a database!") + ) return dlg = CreateUser(abstractDb=self.abstractDb) dlg.exec_() self.populateUsers() - - @pyqtSlot(bool) + + @pyqtSlot(bool) def on_removeUserButton_clicked(self): selectedUsers = self.serverUserTable.selectedItems() if not self.abstractDb: - QMessageBox.critical(self, self.tr('Critical!'), self.tr('First select a database!')) + QMessageBox.critical( + self, self.tr("Critical!"), self.tr("First select a database!") + ) return if len(selectedUsers) == 0: - QMessageBox.critical(self, self.tr('Critical!'), self.tr('First select a user to remove!')) + QMessageBox.critical( + self, self.tr("Critical!"), self.tr("First select a user to remove!") + ) return selectedUserNames = [i.text(0) for i in selectedUsers] - if QMessageBox.question(self, self.tr('Question'), self.tr('Do you really want to remove users: ')+', '.join(selectedUserNames), QMessageBox.Ok|QMessageBox.Cancel) == QMessageBox.Cancel: + if ( + QMessageBox.question( + self, + self.tr("Question"), + self.tr("Do you really want to remove users: ") + + ", ".join(selectedUserNames), + QMessageBox.Ok | QMessageBox.Cancel, + ) + == QMessageBox.Cancel + ): return exceptionDict = dict() successList = [] @@ -98,44 +122,53 @@ def on_removeUserButton_clicked(self): self.abstractDb.reassignAndDropUser(user) successList.append(user) except Exception as e: - exceptionDict[user] = ':'.join(e.args) - header = self.tr('Drop user(s) operation complete!\n') + exceptionDict[user] = ":".join(e.args) + header = self.tr("Drop user(s) operation complete!\n") self.outputMessage(header, successList, exceptionDict) - self.populateUsers() + self.populateUsers() @pyqtSlot(bool) def on_alterPasswordButton_clicked(self): selectedUsers = self.serverUserTable.selectedItems() selectedUserNames = [i.text(0) for i in selectedUsers] if not self.abstractDb: - QMessageBox.critical(self, self.tr('Critical!'), self.tr('First select a database!')) + QMessageBox.critical( + self, self.tr("Critical!"), self.tr("First select a database!") + ) return if len(selectedUsers) == 0: - QMessageBox.critical(self, self.tr('Critical!'), self.tr('First select a user to remove!')) + QMessageBox.critical( + self, self.tr("Critical!"), self.tr("First select a user to remove!") + ) return - dlg = AlterUserPassword(userList = selectedUserNames, abstractDb = self.abstractDb) + dlg = AlterUserPassword(userList=selectedUserNames, abstractDb=self.abstractDb) dlg.exec_() - + @pyqtSlot(bool) def on_closeButton_clicked(self): self.done(0) - + def outputMessage(self, header, successList, exceptionDict): msg = header if len(successList) > 0: - msg += self.tr('\nSuccessful users: ') - msg +=', '.join(successList) + msg += self.tr("\nSuccessful users: ") + msg += ", ".join(successList) msg += self.logInternalError(exceptionDict) - QMessageBox.warning(self, self.tr('Operation Complete!'), msg) + QMessageBox.warning(self, self.tr("Operation Complete!"), msg) def logInternalError(self, exceptionDict): - msg = '' + msg = "" errorDbList = list(exceptionDict.keys()) - if len(errorDbList)> 0: - msg += self.tr('\nUsers with error:') - msg+= ', '.join(errorDbList) - msg+= self.tr('\nError messages for each user were output in qgis log.') + if len(errorDbList) > 0: + msg += self.tr("\nUsers with error:") + msg += ", ".join(errorDbList) + msg += self.tr("\nError messages for each user were output in qgis log.") for errorDb in errorDbList: - QgsMessageLog.logMessage(self.tr('Error for user {user}: {exception}').format(user=errorDb, exception=exceptionDict[errorDb]), "DSGTools Plugin", Qgis.Critical) - return msg - \ No newline at end of file + QgsMessageLog.logMessage( + self.tr("Error for user {user}: {exception}").format( + user=errorDb, exception=exceptionDict[errorDb] + ), + "DSGTools Plugin", + Qgis.Critical, + ) + return msg diff --git a/DsgTools/gui/DatabaseTools/UserTools/permission_properties.py b/DsgTools/gui/DatabaseTools/UserTools/permission_properties.py index 1872345b1..29a2c48a7 100644 --- a/DsgTools/gui/DatabaseTools/UserTools/permission_properties.py +++ b/DsgTools/gui/DatabaseTools/UserTools/permission_properties.py @@ -29,11 +29,13 @@ # DSGTools imports -FORM_CLASS, _ = uic.loadUiType(os.path.join( - os.path.dirname(__file__), 'permission_properties.ui')) +FORM_CLASS, _ = uic.loadUiType( + os.path.join(os.path.dirname(__file__), "permission_properties.ui") +) + class PermissionProperties(QtWidgets.QDialog, FORM_CLASS): - def __init__(self, permissionsDict, parent = None): + def __init__(self, permissionsDict, parent=None): """ Constructor """ @@ -45,17 +47,17 @@ def __init__(self, permissionsDict, parent = None): # #widgets-and-dialogs-with-auto-connect self.setupUi(self) self.treeWidget.setColumnWidth(0, 400) - - #invisible root item + + # invisible root item rootItem = self.treeWidget.invisibleRootItem() - #database item - dbItem = self.createItem(rootItem, 'database') + # database item + dbItem = self.createItem(rootItem, "database") self.createChildrenItems(dbItem, permissionsDict) - + self.treeWidget.sortByColumn(0, QtCore.Qt.AscendingOrder) self.treeWidget.setEditTriggers(QAbstractItemView.NoEditTriggers) - + def createItem(self, parent, text): """ Creates a tree widget item @@ -68,15 +70,15 @@ def createItem(self, parent, text): item.setCheckState(2, QtCore.Qt.Unchecked) item.setText(0, text) return item - + def createChildrenItems(self, parent, mydict): """ Creates children items parent: parent item mydict: data dictionary used to populate tree items """ - #permissions - lista = ['read', 'write'] + # permissions + lista = ["read", "write"] for key in list(mydict.keys()): if key in lista: self.setItemCheckState(parent, mydict, key) @@ -84,13 +86,12 @@ def createChildrenItems(self, parent, mydict): itemText = key item = self.createItem(parent, itemText) self.createChildrenItems(item, mydict[key]) - + def setItemCheckState(self, item, mydict, key): """ Sets item check state """ - if key == 'read': + if key == "read": item.setCheckState(1, int(mydict[key])) - elif key == 'write': + elif key == "write": item.setCheckState(2, int(mydict[key])) - \ No newline at end of file diff --git a/DsgTools/gui/DatabaseTools/UserTools/profileUserManager.py b/DsgTools/gui/DatabaseTools/UserTools/profileUserManager.py index 425211b51..e1cdee9ed 100644 --- a/DsgTools/gui/DatabaseTools/UserTools/profileUserManager.py +++ b/DsgTools/gui/DatabaseTools/UserTools/profileUserManager.py @@ -27,16 +27,32 @@ # Qt imports from qgis.PyQt import QtWidgets, uic from qgis.PyQt.QtCore import pyqtSlot, Qt -from qgis.PyQt.QtWidgets import QListWidgetItem, QMessageBox, QMenu, QApplication, QFileDialog +from qgis.PyQt.QtWidgets import ( + QListWidgetItem, + QMessageBox, + QMenu, + QApplication, + QFileDialog, +) from qgis.PyQt.QtGui import QCursor -FORM_CLASS, _ = uic.loadUiType(os.path.join( - os.path.dirname(__file__), 'profileUserManager.ui')) +FORM_CLASS, _ = uic.loadUiType( + os.path.join(os.path.dirname(__file__), "profileUserManager.ui") +) + class ProfileUserManager(QtWidgets.QDialog, FORM_CLASS): - - def __init__(self, grantedUserList, notGrantedUserList, permissionManager, profileName, dbName, edgvVersion, parent = None): + def __init__( + self, + grantedUserList, + notGrantedUserList, + permissionManager, + profileName, + dbName, + edgvVersion, + parent=None, + ): """Constructor.""" super(self.__class__, self).__init__(parent) self.setupUi(self) @@ -46,54 +62,78 @@ def __init__(self, grantedUserList, notGrantedUserList, permissionManager, profi self.profileName = profileName self.dbName = dbName self.edgvVersion = edgvVersion - self.userCustomSelector.setTitle(self.tr('Manage user permissions to profile ') + profileName + self.tr(' on database ') + dbName) - self.userCustomSelector.setFromList(list(notGrantedUserList), unique = True) #passes a copy using list() + self.userCustomSelector.setTitle( + self.tr("Manage user permissions to profile ") + + profileName + + self.tr(" on database ") + + dbName + ) + self.userCustomSelector.setFromList( + list(notGrantedUserList), unique=True + ) # passes a copy using list() self.userCustomSelector.setToList(list(grantedUserList)) - + @pyqtSlot(bool) def on_applyPushButton_clicked(self): - usersToGrant = [i for i in self.userCustomSelector.toLs if i not in self.grantedUserList] - usersToRevoke = [i for i in self.userCustomSelector.fromLs if i not in self.notGrantedUserList] - #grant operation - header = self.tr('Grant / Revoke operation complete: ') + usersToGrant = [ + i for i in self.userCustomSelector.toLs if i not in self.grantedUserList + ] + usersToRevoke = [ + i + for i in self.userCustomSelector.fromLs + if i not in self.notGrantedUserList + ] + # grant operation + header = self.tr("Grant / Revoke operation complete: ") successList = [] errorDict = dict() QApplication.setOverrideCursor(QCursor(Qt.WaitCursor)) for userName in usersToGrant: try: - self.permissionManager.grantPermission(self.dbName, self.profileName, self.edgvVersion, userName) + self.permissionManager.grantPermission( + self.dbName, self.profileName, self.edgvVersion, userName + ) successList.append(userName) except Exception as e: - errorDict[userName] = ':'.join(e.args) + errorDict[userName] = ":".join(e.args) for userName in usersToRevoke: try: - self.permissionManager.revokePermission(self.dbName, self.profileName, userName) + self.permissionManager.revokePermission( + self.dbName, self.profileName, userName + ) successList.append(userName) except Exception as e: - errorDict[userName] = ':'.join(e.args) + errorDict[userName] = ":".join(e.args) QApplication.restoreOverrideCursor() self.outputMessage(header, successList, errorDict) self.close() - + @pyqtSlot(bool) def on_cancelPushButton_clicked(self): - self.close() - + self.close() + def outputMessage(self, header, successList, exceptionDict): msg = header if len(successList) > 0: - msg += self.tr('\nSuccessful users: ') - msg +=', '.join(successList) + msg += self.tr("\nSuccessful users: ") + msg += ", ".join(successList) msg += self.logInternalError(exceptionDict) - QMessageBox.warning(self, self.tr('Operation Complete!'), msg) - + QMessageBox.warning(self, self.tr("Operation Complete!"), msg) + def logInternalError(self, exceptionDict): - msg = '' + msg = "" errorDbList = list(exceptionDict.keys()) - if len(errorDbList)> 0: - msg += self.tr('\nUsers with error:') - msg+= ', '.join(errorDbList) - msg+= self.tr('\nError messages for each user were output in qgis log.') + if len(errorDbList) > 0: + msg += self.tr("\nUsers with error:") + msg += ", ".join(errorDbList) + msg += self.tr("\nError messages for each user were output in qgis log.") for errorDb in errorDbList: - QgsMessageLog.logMessage(self.tr('Error for user ')+ errorDb + ': ' +exceptionDict[errorDb], "DSGTools Plugin", Qgis.Critical) - return msg \ No newline at end of file + QgsMessageLog.logMessage( + self.tr("Error for user ") + + errorDb + + ": " + + exceptionDict[errorDb], + "DSGTools Plugin", + Qgis.Critical, + ) + return msg diff --git a/DsgTools/gui/DatabaseTools/UserTools/profile_editor.py b/DsgTools/gui/DatabaseTools/UserTools/profile_editor.py index 389e7b9e6..c6c1996a1 100644 --- a/DsgTools/gui/DatabaseTools/UserTools/profile_editor.py +++ b/DsgTools/gui/DatabaseTools/UserTools/profile_editor.py @@ -33,11 +33,13 @@ import json -FORM_CLASS, _ = uic.loadUiType(os.path.join( - os.path.dirname(__file__), 'profile_editor.ui')) +FORM_CLASS, _ = uic.loadUiType( + os.path.join(os.path.dirname(__file__), "profile_editor.ui") +) + class ProfileEditor(QtWidgets.QDialog, FORM_CLASS): - def __init__(self, parent = None): + def __init__(self, parent=None): """ Constructor """ @@ -49,27 +51,27 @@ def __init__(self, parent = None): # #widgets-and-dialogs-with-auto-connect self.setupUi(self) self.treeWidget.setColumnWidth(0, 400) - - self.folder = os.path.join(os.path.dirname(__file__), 'profiles') + + self.folder = os.path.join(os.path.dirname(__file__), "profiles") self.getProfiles() self.setInitialState() - - def getProfiles(self, profileName = None): + + def getProfiles(self, profileName=None): """ Get profile files and insert them in the combo box """ ret = [] for root, dirs, files in os.walk(self.folder): for file in files: - ext = file.split('.')[-1] - if ext == 'json': - ret.append(file.split('.')[0]) + ext = file.split(".")[-1] + if ext == "json": + ret.append(file.split(".")[0]) ret.sort() self.jsonCombo.clear() - self.jsonCombo.addItem(self.tr('Select a profile')) + self.jsonCombo.addItem(self.tr("Select a profile")) self.jsonCombo.addItems(ret) - + index = self.jsonCombo.findText(profileName) if index != -1: self.jsonCombo.setCurrentIndex(index) @@ -85,33 +87,37 @@ def setInitialState(self): self.treeWidget.clear() return else: - profile = os.path.join(self.folder, self.jsonCombo.currentText()+'.json') + profile = os.path.join(self.folder, self.jsonCombo.currentText() + ".json") self.readJsonFile(profile) self.treeWidget.sortByColumn(0, QtCore.Qt.AscendingOrder) - + def createItem(self, parent, text): """ Creates tree widget items """ item = QtWidgets.QTreeWidgetItem(parent) - item.setFlags(QtCore.Qt.ItemIsEnabled | QtCore.Qt.ItemIsTristate | QtCore.Qt.ItemIsUserCheckable) + item.setFlags( + QtCore.Qt.ItemIsEnabled + | QtCore.Qt.ItemIsTristate + | QtCore.Qt.ItemIsUserCheckable + ) item.setCheckState(1, QtCore.Qt.Unchecked) item.setCheckState(2, QtCore.Qt.Unchecked) item.setText(0, text) return item - + def makeProfileDict(self): """ Makes a dictionary out of the tree widget items """ profileDict = dict() - - #invisible root item + + # invisible root item rootItem = self.treeWidget.invisibleRootItem() - #database item + # database item dbItem = rootItem.child(0) permissions = dict() - + schema_count = dbItem.childCount() for i in range(schema_count): schemaItem = dbItem.child(i) @@ -123,38 +129,40 @@ def makeProfileDict(self): layer_count = categoryItem.childCount() for k in range(layer_count): layerItem = categoryItem.child(k) - permissions[schemaItem.text(0)][categoryItem.text(0)][layerItem.text(0)] = self.getItemCheckState(layerItem) - - profileDict[self.parent] = permissions + permissions[schemaItem.text(0)][categoryItem.text(0)][ + layerItem.text(0) + ] = self.getItemCheckState(layerItem) + + profileDict[self.parent] = permissions return profileDict - + def readJsonFile(self, filename): """ Reads the profile file, gets a dictionary of it and builds the tree widget """ try: - file = open(filename, 'r') + file = open(filename, "r") data = file.read() profileDict = json.loads(data) self.parent = list(profileDict.keys())[0] file.close() except: return - - #invisible root item + + # invisible root item rootItem = self.treeWidget.invisibleRootItem() - #database item + # database item dbItem = self.createItem(rootItem, self.parent) permissions = profileDict[self.parent] self.createChildrenItems(dbItem, permissions) - + def createChildrenItems(self, parent, mydict): """ Creates children item in the tree widget """ - #permissions - lista = ['read', 'write'] + # permissions + lista = ["read", "write"] for key in list(mydict.keys()): if key in lista: self.setItemCheckState(parent, mydict, key) @@ -162,32 +170,32 @@ def createChildrenItems(self, parent, mydict): itemText = key item = self.createItem(parent, itemText) self.createChildrenItems(item, mydict[key]) - + def setItemCheckState(self, item, mydict, key): """ Sets the item check state """ - if key == 'read': + if key == "read": item.setCheckState(1, int(mydict[key])) - elif key == 'write': + elif key == "write": item.setCheckState(2, int(mydict[key])) - + def getItemCheckState(self, item): """ Gets the item check state for READ and WRITE columns """ ret = dict() - ret['read'] = str(item.checkState(1)) - ret['write'] = str(item.checkState(2)) + ret["read"] = str(item.checkState(1)) + ret["write"] = str(item.checkState(2)) return ret - + @pyqtSlot(int) def on_jsonCombo_currentIndexChanged(self): """ Slot to update the initial state """ self.setInitialState() - + @pyqtSlot(bool) def on_createButton_clicked(self): """ @@ -196,49 +204,57 @@ def on_createButton_clicked(self): dlg = CreateProfile() dlg.profileCreated.connect(self.getProfiles) dlg.exec_() - + @pyqtSlot(bool) def on_clearButton_clicked(self): """ Clears the tree widget """ - #invisible root item + # invisible root item rootItem = self.treeWidget.invisibleRootItem() - #database item + # database item dbItem = rootItem.child(0) if dbItem: dbItem.setCheckState(1, 0) dbItem.setCheckState(2, 0) - + @pyqtSlot(bool) def on_saveButton_clicked(self): """ Saves the profile file """ if self.jsonCombo.currentIndex() == 0: - QMessageBox.warning(self, self.tr('Warning!'), self.tr('Select a profile model!')) + QMessageBox.warning( + self, self.tr("Warning!"), self.tr("Select a profile model!") + ) return else: profile = self.jsonCombo.currentText() - - path = os.path.join(self.folder, profile+'.json') - + + path = os.path.join(self.folder, profile + ".json") + try: - with open(path, 'w') as outfile: + with open(path, "w") as outfile: json.dump(self.makeProfileDict(), outfile, sort_keys=True, indent=4) except Exception as e: - QMessageBox.warning(self, self.tr('Warning!'), self.tr('Problem saving file! \n')+':'.join(e.args)) + QMessageBox.warning( + self, + self.tr("Warning!"), + self.tr("Problem saving file! \n") + ":".join(e.args), + ) return - - QMessageBox.warning(self, self.tr('Warning!'), self.tr('Profile saved successfully!')) - + + QMessageBox.warning( + self, self.tr("Warning!"), self.tr("Profile saved successfully!") + ) + @pyqtSlot(bool) def on_closeButton_clicked(self): """ Closes the dialog """ self.close() - + @pyqtSlot(bool) def on_deletePushButton_clicked(self): """ @@ -247,12 +263,26 @@ def on_deletePushButton_clicked(self): """ if self.jsonCombo.currentIndex() != 0: profileName = self.jsonCombo.currentText() - if QMessageBox.question(self, self.tr('Question'), self.tr('Do you really want to remove profile ')+profileName+'?', QMessageBox.Ok|QMessageBox.Cancel) == QMessageBox.Cancel: + if ( + QMessageBox.question( + self, + self.tr("Question"), + self.tr("Do you really want to remove profile ") + + profileName + + "?", + QMessageBox.Ok | QMessageBox.Cancel, + ) + == QMessageBox.Cancel + ): return try: - os.remove(os.path.join(self.folder,profileName+'.json')) + os.remove(os.path.join(self.folder, profileName + ".json")) except Exception as e: - QMessageBox.warning(self, self.tr('Warning!'), self.tr('Problem deleting profile! \n')+':'.join(e.args)) + QMessageBox.warning( + self, + self.tr("Warning!"), + self.tr("Problem deleting profile! \n") + ":".join(e.args), + ) return self.getProfiles() - self.setInitialState() \ No newline at end of file + self.setInitialState() diff --git a/DsgTools/gui/DatabaseTools/UserTools/serverProfilesManager.py b/DsgTools/gui/DatabaseTools/UserTools/serverProfilesManager.py index ebb832d22..e3b80a749 100644 --- a/DsgTools/gui/DatabaseTools/UserTools/serverProfilesManager.py +++ b/DsgTools/gui/DatabaseTools/UserTools/serverProfilesManager.py @@ -33,17 +33,24 @@ from qgis.core import QgsMessageLog # DSGTools imports -from DsgTools.gui.DatabaseTools.UserTools.createProfileWithProfileManager import CreateProfileWithProfileManager -from DsgTools.gui.CustomWidgets.DatabasePropertiesWidgets.BasicPropertyWidgets.genericParameterSetter import GenericParameterSetter +from DsgTools.gui.DatabaseTools.UserTools.createProfileWithProfileManager import ( + CreateProfileWithProfileManager, +) +from DsgTools.gui.CustomWidgets.DatabasePropertiesWidgets.BasicPropertyWidgets.genericParameterSetter import ( + GenericParameterSetter, +) import json -FORM_CLASS, _ = uic.loadUiType(os.path.join( - os.path.dirname(__file__), 'serverProfilesManager.ui')) +FORM_CLASS, _ = uic.loadUiType( + os.path.join(os.path.dirname(__file__), "serverProfilesManager.ui") +) + class ServerProfilesManager(QtWidgets.QDialog, FORM_CLASS): profilesChanged = pyqtSignal() - def __init__(self, permissionManager, parent = None): + + def __init__(self, permissionManager, parent=None): """ Constructor """ @@ -56,30 +63,34 @@ def __init__(self, permissionManager, parent = None): self.setupUi(self) self.permissionManager = permissionManager self.refreshProfileList() - + def createItem(self, parent, text): """ Creates tree widget items """ item = QtWidgets.QTreeWidgetItem(parent) - item.setFlags(QtCore.Qt.ItemIsEnabled | QtCore.Qt.ItemIsTristate | QtCore.Qt.ItemIsUserCheckable) + item.setFlags( + QtCore.Qt.ItemIsEnabled + | QtCore.Qt.ItemIsTristate + | QtCore.Qt.ItemIsUserCheckable + ) item.setCheckState(1, QtCore.Qt.Unchecked) item.setCheckState(2, QtCore.Qt.Unchecked) item.setText(0, text) return item - + def makeProfileDict(self): """ Makes a dictionary out of the tree widget items """ profileDict = dict() - - #invisible root item + + # invisible root item rootItem = self.treeWidget.invisibleRootItem() - #database item + # database item dbItem = rootItem.child(0) permissions = dict() - + schema_count = dbItem.childCount() for i in range(schema_count): schemaItem = dbItem.child(i) @@ -91,11 +102,13 @@ def makeProfileDict(self): layer_count = categoryItem.childCount() for k in range(layer_count): layerItem = categoryItem.child(k) - permissions[schemaItem.text(0)][categoryItem.text(0)][layerItem.text(0)] = self.getItemCheckState(layerItem) - - profileDict[self.parent] = permissions + permissions[schemaItem.text(0)][categoryItem.text(0)][ + layerItem.text(0) + ] = self.getItemCheckState(layerItem) + + profileDict[self.parent] = permissions return profileDict - + def readJsonFromDatabase(self, profileName, edgvVersion): """ Reads the profile file, gets a dictionary of it and builds the tree widget @@ -103,21 +116,21 @@ def readJsonFromDatabase(self, profileName, edgvVersion): profileDict = self.permissionManager.getSetting(profileName, edgvVersion) self.parent = list(profileDict.keys())[0] - #invisible root item + # invisible root item rootItem = self.treeWidget.invisibleRootItem() - #database item + # database item dbItem = self.createItem(rootItem, self.parent) permissions = profileDict[self.parent] self.createChildrenItems(dbItem, permissions) self.treeWidget.sortItems(0, Qt.AscendingOrder) - + def createChildrenItems(self, parent, mydict): """ Creates children item in the tree widget """ - #permissions - lista = ['read', 'write'] + # permissions + lista = ["read", "write"] for key in list(mydict.keys()): if key in lista: self.setItemCheckState(parent, mydict, key) @@ -125,145 +138,203 @@ def createChildrenItems(self, parent, mydict): itemText = key item = self.createItem(parent, itemText) self.createChildrenItems(item, mydict[key]) - + def setItemCheckState(self, item, mydict, key): """ Sets the item check state """ - if key == 'read': + if key == "read": item.setCheckState(1, int(mydict[key])) - elif key == 'write': + elif key == "write": item.setCheckState(2, int(mydict[key])) - + def getItemCheckState(self, item): """ Gets the item check state for READ and WRITE columns """ ret = dict() - ret['read'] = str(item.checkState(1)) - ret['write'] = str(item.checkState(2)) + ret["read"] = str(item.checkState(1)) + ret["write"] = str(item.checkState(2)) return ret - + @pyqtSlot(bool) def on_clearButton_clicked(self): """ Clears the tree widget """ - #invisible root item + # invisible root item rootItem = self.treeWidget.invisibleRootItem() - #database item + # database item dbItem = rootItem.child(0) if dbItem: dbItem.setCheckState(1, 0) dbItem.setCheckState(2, 0) - + @pyqtSlot(bool) def on_closeButton_clicked(self): """ Closes the dialog """ self.close() - + def refreshProfileList(self): self.profilesListWidget.clear() self.treeWidget.clear() self.setEnabled(False) profilesDict = self.permissionManager.getSettings() for edgvVersion in list(profilesDict.keys()): - self.profilesListWidget.addItems([i + ' ({0})'.format(edgvVersion) for i in profilesDict[edgvVersion]] ) - self.profilesListWidget.sortItems(order = Qt.AscendingOrder) - + self.profilesListWidget.addItems( + [i + " ({0})".format(edgvVersion) for i in profilesDict[edgvVersion]] + ) + self.profilesListWidget.sortItems(order=Qt.AscendingOrder) + @pyqtSlot(bool) def on_createPermissionPushButton_clicked(self): """ Slot that opens the create profile dialog """ - #use selector + # use selector permissionDict = self.permissionManager.getSettings() - parameterDlg = GenericParameterSetter(nameList = list(permissionDict.keys())) + parameterDlg = GenericParameterSetter(nameList=list(permissionDict.keys())) if not parameterDlg.exec_(): return templateDb, profileName, edgvVersion = parameterDlg.getParameters() if edgvVersion in list(permissionDict.keys()): if profileName in permissionDict[edgvVersion]: - QMessageBox.warning(self, self.tr('Warning!'), self.tr('Profile ') + profileName + self.tr(' for EDGV ') + edgvVersion + self.tr(' already exists!')) + QMessageBox.warning( + self, + self.tr("Warning!"), + self.tr("Profile ") + + profileName + + self.tr(" for EDGV ") + + edgvVersion + + self.tr(" already exists!"), + ) return newItem = self.populateTreeDict(templateDb, edgvVersion) jsonDict = json.dumps(newItem, sort_keys=True, indent=4) self.permissionManager.createSetting(profileName, edgvVersion, jsonDict) self.updateInterface(profileName, edgvVersion) - QMessageBox.warning(self, self.tr('Success!'), self.tr('Profile ') + profileName + self.tr(' created successfully!')) - + QMessageBox.warning( + self, + self.tr("Success!"), + self.tr("Profile ") + profileName + self.tr(" created successfully!"), + ) + def setEnabled(self, enabled): self.treeWidget.setEnabled(enabled) self.saveButton.setEnabled(enabled) self.clearButton.setEnabled(enabled) - + @pyqtSlot() def on_profilesListWidget_itemSelectionChanged(self): - profileName, edgvVersion = self.profilesListWidget.currentItem().text().split(' (') - edgvVersion = edgvVersion.replace(')','') + profileName, edgvVersion = ( + self.profilesListWidget.currentItem().text().split(" (") + ) + edgvVersion = edgvVersion.replace(")", "") try: self.setEnabled(True) self.treeWidget.clear() self.readJsonFromDatabase(profileName, edgvVersion) except: pass - + def updateInterface(self, profileName, edgvVersion): self.refreshProfileList() - profileItem = self.profilesListWidget.findItems(profileName + ' ({0})'.format(edgvVersion), Qt.MatchExactly)[0] + profileItem = self.profilesListWidget.findItems( + profileName + " ({0})".format(edgvVersion), Qt.MatchExactly + )[0] self.profilesListWidget.setCurrentItem(profileItem) - + @pyqtSlot(bool) def on_deletePermissionPushButton_clicked(self): if self.profilesListWidget.currentItem() is not None: - profileName, edgvVersion = self.profilesListWidget.currentItem().text().split(' (') - edgvVersion = edgvVersion.replace(')','') - if QMessageBox.question(self, self.tr('Question'), self.tr('Do you really want to delete profile ')+profileName+'?', QMessageBox.Ok|QMessageBox.Cancel) == QMessageBox.Cancel: + profileName, edgvVersion = ( + self.profilesListWidget.currentItem().text().split(" (") + ) + edgvVersion = edgvVersion.replace(")", "") + if ( + QMessageBox.question( + self, + self.tr("Question"), + self.tr("Do you really want to delete profile ") + + profileName + + "?", + QMessageBox.Ok | QMessageBox.Cancel, + ) + == QMessageBox.Cancel + ): return try: QApplication.setOverrideCursor(QCursor(Qt.WaitCursor)) self.permissionManager.deleteSetting(profileName, edgvVersion) QApplication.restoreOverrideCursor() - QMessageBox.warning(self, self.tr('Success!'), self.tr('Permission ') + profileName + self.tr(' successfully deleted.')) + QMessageBox.warning( + self, + self.tr("Success!"), + self.tr("Permission ") + + profileName + + self.tr(" successfully deleted."), + ) self.refreshProfileList() except Exception as e: QApplication.restoreOverrideCursor() - QMessageBox.warning(self, self.tr('Warning!'), self.tr('Error! Problem deleting permission: ') + ':'.join(e.args)) - + QMessageBox.warning( + self, + self.tr("Warning!"), + self.tr("Error! Problem deleting permission: ") + ":".join(e.args), + ) + @pyqtSlot(bool) def on_saveButton_clicked(self): - profileName, edgvVersion = self.profilesListWidget.currentItem().text().split(' (') - edgvVersion = edgvVersion.replace(')','') + profileName, edgvVersion = ( + self.profilesListWidget.currentItem().text().split(" (") + ) + edgvVersion = edgvVersion.replace(")", "") newProfileDict = self.makeProfileDict() try: QApplication.setOverrideCursor(QCursor(Qt.WaitCursor)) - self.permissionManager.updateSetting(profileName, edgvVersion, newProfileDict) + self.permissionManager.updateSetting( + profileName, edgvVersion, newProfileDict + ) QApplication.restoreOverrideCursor() - QMessageBox.warning(self, self.tr('Success!'), self.tr('Permission ') + profileName + self.tr(' successfully updated.')) + QMessageBox.warning( + self, + self.tr("Success!"), + self.tr("Permission ") + + profileName + + self.tr(" successfully updated."), + ) except Exception as e: QApplication.restoreOverrideCursor() - QMessageBox.warning(self, self.tr('Warning!'), self.tr('Error! Problem updating permission: ') + ':'.join(e.args)) + QMessageBox.warning( + self, + self.tr("Warning!"), + self.tr("Error! Problem updating permission: ") + ":".join(e.args), + ) def populateTreeDict(self, abstractDb, version): """ Makes a tree widget were the user can define profile properties """ try: - #get a dict with all tables from database + # get a dict with all tables from database geomList = abstractDb.getTablesJsonList() except Exception as e: - QMessageBox.critical(self, self.tr('Critical!'), self.tr('A problem occurred! Check log for details.')) - QgsMessageLog.logMessage(':'.join(e.args), 'DSGTools Plugin', Qgis.Critical) + QMessageBox.critical( + self, + self.tr("Critical!"), + self.tr("A problem occurred! Check log for details."), + ) + QgsMessageLog.logMessage(":".join(e.args), "DSGTools Plugin", Qgis.Critical) return profile = dict() categories = dict() for jsonItem in geomList: - layerName = jsonItem['table_name'] - schema = jsonItem['table_schema'] - if version != 'Non_EDGV': - category = layerName.split('_')[0] + layerName = jsonItem["table_name"] + schema = jsonItem["table_schema"] + if version != "Non_EDGV": + category = layerName.split("_")[0] else: category = schema if schema not in list(categories.keys()): @@ -272,7 +343,7 @@ def populateTreeDict(self, abstractDb, version): categories[schema][category] = dict() if layerName not in categories[schema][category]: categories[schema][category][layerName] = dict() - categories[schema][category][layerName]['read'] = '0' - categories[schema][category][layerName]['write'] = '0' - profile['database'+'_'+version] = categories - return profile \ No newline at end of file + categories[schema][category][layerName]["read"] = "0" + categories[schema][category][layerName]["write"] = "0" + profile["database" + "_" + version] = categories + return profile diff --git a/DsgTools/gui/DatabaseTools/UserTools/user_profiles.py b/DsgTools/gui/DatabaseTools/UserTools/user_profiles.py index a23bbe33e..f4004ca68 100644 --- a/DsgTools/gui/DatabaseTools/UserTools/user_profiles.py +++ b/DsgTools/gui/DatabaseTools/UserTools/user_profiles.py @@ -36,13 +36,17 @@ from DsgTools.gui.DatabaseTools.UserTools.assign_profiles import AssignProfiles from DsgTools.gui.DatabaseTools.UserTools.create_user import CreateUser from DsgTools.gui.DatabaseTools.UserTools.alter_user_password import AlterUserPassword -from DsgTools.gui.DatabaseTools.UserTools.permission_properties import PermissionProperties +from DsgTools.gui.DatabaseTools.UserTools.permission_properties import ( + PermissionProperties, +) + +FORM_CLASS, _ = uic.loadUiType( + os.path.join(os.path.dirname(__file__), "user_profiles.ui") +) -FORM_CLASS, _ = uic.loadUiType(os.path.join( - os.path.dirname(__file__), 'user_profiles.ui')) class ManageUserProfiles(QtWidgets.QDialog, FORM_CLASS): - def __init__(self, parent = None): + def __init__(self, parent=None): """ Constructor """ @@ -55,27 +59,33 @@ def __init__(self, parent = None): self.setupUi(self) self.widget.tabWidget.setTabEnabled(1, False) self.widget.serverWidget.superNeeded = True - #Objects Connections - QtCore.QObject.connect(self.widget, QtCore.SIGNAL(("connectionChanged()")), self.populateUsers) - + # Objects Connections + QtCore.QObject.connect( + self.widget, QtCore.SIGNAL(("connectionChanged()")), self.populateUsers + ) + self.installedProfiles.setContextMenuPolicy(Qt.CustomContextMenu) - self.installedProfiles.customContextMenuRequested.connect(self.createMenuInstalled) + self.installedProfiles.customContextMenuRequested.connect( + self.createMenuInstalled + ) self.assignedProfiles.setContextMenuPolicy(Qt.CustomContextMenu) - self.assignedProfiles.customContextMenuRequested.connect(self.createMenuAssigned) + self.assignedProfiles.customContextMenuRequested.connect( + self.createMenuAssigned + ) def createMenuInstalled(self, position): """ Creates a pop up menu to show permission properties """ menu = QMenu() - + item = self.installedProfiles.itemAt(position) - if item: - menu.addAction(self.tr('Show properties'), self.showInstalledProperties) - + if item: + menu.addAction(self.tr("Show properties"), self.showInstalledProperties) + menu.exec_(self.installedProfiles.viewport().mapToGlobal(position)) - + def showInstalledProperties(self): """ Shows the installed permission's properties dialog @@ -86,13 +96,15 @@ def showInstalledProperties(self): permissionsDict = dict() try: - permissionsDict = self.widget.abstractDb.getRolePrivileges(permission, dbname) + permissionsDict = self.widget.abstractDb.getRolePrivileges( + permission, dbname + ) except Exception as e: - QMessageBox.critical(self, self.tr('Critical!'), ':'.join(e.args)) - + QMessageBox.critical(self, self.tr("Critical!"), ":".join(e.args)) + dlg = PermissionProperties(permissionsDict) dlg.exec_() - + def createMenuAssigned(self, position): """ Creates a pop up menu to show properties of a permission assigned to a user @@ -102,7 +114,7 @@ def createMenuAssigned(self, position): item = self.assignedProfiles.itemAt(position) if item: - menu.addAction(self.tr('Show properties'), self.showAssignedProperties) + menu.addAction(self.tr("Show properties"), self.showAssignedProperties) menu.exec_(self.assignedProfiles.viewport().mapToGlobal(position)) @@ -116,9 +128,11 @@ def showAssignedProperties(self): permissionsDict = dict() try: - permissionsDict = self.widget.abstractDb.getRolePrivileges(permission, dbname) + permissionsDict = self.widget.abstractDb.getRolePrivileges( + permission, dbname + ) except Exception as e: - QMessageBox.critical(self, self.tr('Critical!'), ':'.join(e.args)) + QMessageBox.critical(self, self.tr("Critical!"), ":".join(e.args)) dlg = PermissionProperties(permissionsDict) dlg.exec_() @@ -128,19 +142,19 @@ def populateUsers(self): Populates postgresql users list """ self.comboBox.clear() - + if not self.widget.abstractDb: return - + ret = [] try: ret = self.widget.abstractDb.getUsers() except Exception as e: - QMessageBox.critical(self, self.tr('Critical!'), ':'.join(e.args)) - - self.comboBox.addItem(self.tr('Select a User')) + QMessageBox.critical(self, self.tr("Critical!"), ":".join(e.args)) + + self.comboBox.addItem(self.tr("Select a User")) self.comboBox.addItems(ret) - + def getProfiles(self, username): """ Gets the installed and assigned profiles related to a user @@ -151,27 +165,32 @@ def getProfiles(self, username): if self.comboBox.currentIndex() == 0: return - + if not self.widget.abstractDb: return - + self.installed, self.assigned = [], [] try: - self.installed, self.assigned = self.widget.abstractDb.getUserRelatedRoles(username) + self.installed, self.assigned = self.widget.abstractDb.getUserRelatedRoles( + username + ) except Exception as e: - QMessageBox.critical(self, self.tr('Critical!'), ':'.join(e.args)) + QMessageBox.critical(self, self.tr("Critical!"), ":".join(e.args)) self.installedProfiles.addItems(self.installed) self.assignedProfiles.addItems(self.assigned) - + @pyqtSlot(bool) def on_installProfile_clicked(self): """ Slot to install profile """ - dlg = AssignProfiles(self.widget.serverWidget.serversCombo.currentIndex(),self.widget.comboBoxPostgis.currentIndex()) + dlg = AssignProfiles( + self.widget.serverWidget.serversCombo.currentIndex(), + self.widget.comboBoxPostgis.currentIndex(), + ) dlg.exec_() - self.getProfiles(self.comboBox.currentText()) + self.getProfiles(self.comboBox.currentText()) @pyqtSlot(bool) def on_createUserButton_clicked(self): @@ -179,35 +198,43 @@ def on_createUserButton_clicked(self): Slot to open create user dialog """ if not self.widget.abstractDb: - QMessageBox.critical(self, self.tr('Critical!'), self.tr('First select a database!')) + QMessageBox.critical( + self, self.tr("Critical!"), self.tr("First select a database!") + ) return - dlg = CreateUser(self.comboBox.currentText(),self.widget.abstractDb) + dlg = CreateUser(self.comboBox.currentText(), self.widget.abstractDb) dlg.exec_() self.populateUsers() - - @pyqtSlot(bool) + + @pyqtSlot(bool) def on_removeUserButton_clicked(self): """ Slot to remove user """ user = self.comboBox.currentText() if not self.widget.abstractDb: - QMessageBox.critical(self, self.tr('Critical!'), self.tr('First select a database!')) + QMessageBox.critical( + self, self.tr("Critical!"), self.tr("First select a database!") + ) return if self.comboBox.currentIndex() == 0: - QMessageBox.critical(self, self.tr('Critical!'), self.tr('First select a user to remove!')) + QMessageBox.critical( + self, self.tr("Critical!"), self.tr("First select a user to remove!") + ) return try: self.widget.abstractDb.removeUser(user) except Exception as e: - QMessageBox.critical(self, self.tr('Critical!'), ':'.join(e.args)) + QMessageBox.critical(self, self.tr("Critical!"), ":".join(e.args)) self.getProfiles(user) return self.getProfiles(user) - QMessageBox.warning(self, self.tr('Warning!'), self.tr('User removed successfully!')) - self.populateUsers() + QMessageBox.warning( + self, self.tr("Warning!"), self.tr("User removed successfully!") + ) + self.populateUsers() @pyqtSlot(bool) def on_alterPasswordButton_clicked(self): @@ -216,10 +243,14 @@ def on_alterPasswordButton_clicked(self): """ user = self.comboBox.currentText() if not self.widget.abstractDb: - QMessageBox.critical(self, self.tr('Critical!'), self.tr('First select a database!')) + QMessageBox.critical( + self, self.tr("Critical!"), self.tr("First select a database!") + ) return if self.comboBox.currentIndex() == 0: - QMessageBox.critical(self, self.tr('Critical!'), self.tr('First select a user!')) + QMessageBox.critical( + self, self.tr("Critical!"), self.tr("First select a user!") + ) return dlg = AlterUserPassword(user, self.widget.abstractDb) dlg.exec_() @@ -230,7 +261,7 @@ def on_comboBox_currentIndexChanged(self): Slot to update assigned and installed profiles """ self.getProfiles(self.comboBox.currentText()) - + def saveUserState(self): """ Saves the user state. @@ -246,7 +277,7 @@ def saveUserState(self): for i in range(self.assignedProfiles.__len__()): role = self.assignedProfiles.item(i).text() profiles1.append(role) - + for role in profiles1: if role not in self.assigned: grant.append(role) @@ -255,16 +286,16 @@ def saveUserState(self): for i in range(self.installedProfiles.__len__()): role = self.installedProfiles.item(i).text() profiles2.append(role) - + for role in profiles2: if role not in self.installed: revoke.append(role) - + for role in grant: try: self.widget.abstractDb.grantRole(user, role) except Exception as e: - QMessageBox.critical(self, self.tr('Critical!'), e.args[0]) + QMessageBox.critical(self, self.tr("Critical!"), e.args[0]) self.getProfiles(user) return @@ -272,20 +303,22 @@ def saveUserState(self): try: self.widget.abstractDb.revokeRole(user, role) except Exception as e: - QMessageBox.critical(self, self.tr('Critical!'), ':'.join(e.args)) + QMessageBox.critical(self, self.tr("Critical!"), ":".join(e.args)) self.getProfiles(user) return self.getProfiles(user) - QMessageBox.warning(self, self.tr('Warning!'), self.tr('User updated successfully!')) - + QMessageBox.warning( + self, self.tr("Warning!"), self.tr("User updated successfully!") + ) + @pyqtSlot(bool) def on_closeButton_clicked(self): """ Closes the dialog """ self.close() - + @pyqtSlot(bool) def on_insertAllButton_clicked(self): """ @@ -293,14 +326,18 @@ def on_insertAllButton_clicked(self): """ tam = self.installedProfiles.__len__() if tam == 0: - QMessageBox.warning(self, self.tr('Warning!'), self.tr('No profiles installed! Install at least one and try again.')) + QMessageBox.warning( + self, + self.tr("Warning!"), + self.tr("No profiles installed! Install at least one and try again."), + ) return - - for i in range(tam+1,1,-1): - item = self.installedProfiles.takeItem(i-2) + + for i in range(tam + 1, 1, -1): + item = self.installedProfiles.takeItem(i - 2) self.assignedProfiles.addItem(item) self.assignedProfiles.sortItems() - + self.saveUserState() @pyqtSlot(bool) @@ -310,11 +347,15 @@ def on_removeAllButton_clicked(self): """ tam = self.assignedProfiles.__len__() if tam == 0: - QMessageBox.warning(self, self.tr('Warning!'), self.tr('No profiles assigned! Assign at least one and try again.')) + QMessageBox.warning( + self, + self.tr("Warning!"), + self.tr("No profiles assigned! Assign at least one and try again."), + ) return - - for i in range(tam+1,1,-1): - item = self.assignedProfiles.takeItem(i-2) + + for i in range(tam + 1, 1, -1): + item = self.assignedProfiles.takeItem(i - 2) self.installedProfiles.addItem(item) self.installedProfiles.sortItems() @@ -327,9 +368,11 @@ def on_insertButton_clicked(self): """ listedItems = self.installedProfiles.selectedItems() if len(listedItems) == 0: - QMessageBox.warning(self, self.tr('Warning!'), self.tr('Select a profile first!')) + QMessageBox.warning( + self, self.tr("Warning!"), self.tr("Select a profile first!") + ) return - + for i in listedItems: item = self.installedProfiles.takeItem(self.installedProfiles.row(i)) self.assignedProfiles.addItem(item) @@ -344,12 +387,14 @@ def on_removeButton_clicked(self): """ listedItems = self.assignedProfiles.selectedItems() if len(listedItems) == 0: - QMessageBox.warning(self, self.tr('Warning!'), self.tr('Select a profile first!')) + QMessageBox.warning( + self, self.tr("Warning!"), self.tr("Select a profile first!") + ) return - + for i in listedItems: item = self.assignedProfiles.takeItem(self.assignedProfiles.row(i)) self.installedProfiles.addItem(item) self.installedProfiles.sortItems() - self.saveUserState() \ No newline at end of file + self.saveUserState() diff --git a/DsgTools/gui/DatabaseTools/databaseManager.py b/DsgTools/gui/DatabaseTools/databaseManager.py index 5a76e501e..34b5c50df 100644 --- a/DsgTools/gui/DatabaseTools/databaseManager.py +++ b/DsgTools/gui/DatabaseTools/databaseManager.py @@ -24,12 +24,18 @@ from qgis.PyQt.QtCore import QObject -from DsgTools.gui.DatabaseTools.DbTools.SingleDbCreator.singleDbCreator import CreateSingleDatabase -from DsgTools.gui.DatabaseTools.DbTools.BatchDbCreator.batchDbCreator import BatchDbCreator -from DsgTools.gui.DatabaseTools.ConversionTools.datasourceConversion import DatasourceConversion +from DsgTools.gui.DatabaseTools.DbTools.SingleDbCreator.singleDbCreator import ( + CreateSingleDatabase, +) +from DsgTools.gui.DatabaseTools.DbTools.BatchDbCreator.batchDbCreator import ( + BatchDbCreator, +) +from DsgTools.gui.DatabaseTools.ConversionTools.datasourceConversion import ( + DatasourceConversion, +) -class DatabaseGuiManager(QObject): +class DatabaseGuiManager(QObject): def __init__(self, manager, iface, parentMenu=None, toolbar=None): """Constructor. :param iface: An interface instance that will be passed to this class @@ -44,13 +50,17 @@ def __init__(self, manager, iface, parentMenu=None, toolbar=None): self.parentMenu = parentMenu # self.dbAbstract = dbAbstract self.toolbar = toolbar - self.menu = self.manager.addMenu(u'databasetools', self.tr('Database Tools'),'database.png') - self.stackButton = self.manager.createToolButton(self.toolbar, u'DatabaseTools') - self.iconBasePath = ':/plugins/DsgTools/icons/' + self.menu = self.manager.addMenu( + "databasetools", self.tr("Database Tools"), "database.png" + ) + self.stackButton = self.manager.createToolButton(self.toolbar, "DatabaseTools") + self.iconBasePath = ":/plugins/DsgTools/icons/" self.singleDbCreator = None self.batchCreator = None - - def addTool(self, text, callback, parentMenu, icon, parentButton=None, defaultButton=False): + + def addTool( + self, text, callback, parentMenu, icon, parentButton=None, defaultButton=False + ): """ Prepares the funcionalities to be added to both the DSGTools menu and it's shortcut button into QGIS main interface. :param text: (str) text to be shown when the action is hovered over. @@ -58,7 +68,7 @@ def addTool(self, text, callback, parentMenu, icon, parentButton=None, defaultBu :param parentMenu: (QMenu) menu to which action will be added. :param parentButton: (QButton) button to which action will be associated. :param defaultButton: (bool) considering it is a stack button (button overloaded with >1 actions associated), it indicates - whether the included action will be the default one (e.g. if it will the action representative and + whether the included action will be the default one (e.g. if it will the action representative and 1st to be displayed). """ icon_path = self.iconBasePath + icon @@ -71,34 +81,36 @@ def addTool(self, text, callback, parentMenu, icon, parentButton=None, defaultBu withShortcut=False, parentToolbar=parentMenu, isCheckable=False, - parentButton=self.stackButton + parentButton=self.stackButton, ) if defaultButton: self.stackButton.setDefaultAction(action) def initGui(self): """ - Instantiates all available database creation GUI. + Instantiates all available database creation GUI. """ - callback = lambda : self.createDatabase(isBatchCreation=False) + callback = lambda: self.createDatabase(isBatchCreation=False) self.addTool( - text=self.tr('Create a PostGIS or SpatiaLite Database'), + text=self.tr("Create a PostGIS or SpatiaLite Database"), callback=callback, parentMenu=self.menu, - icon='database.png', + icon="database.png", parentButton=self.stackButton, - defaultButton=True + defaultButton=True, ) - callback = lambda : self.createDatabase(isBatchCreation=True) + callback = lambda: self.createDatabase(isBatchCreation=True) self.addTool( - text=self.tr('Create batches of PostGIS or SpatiaLite Databases'), + text=self.tr("Create batches of PostGIS or SpatiaLite Databases"), callback=callback, parentMenu=self.menu, - icon='batchDatabase.png', + icon="batchDatabase.png", parentButton=self.stackButton, - defaultButton=False + defaultButton=False, + ) + self.datasourceConversion = DatasourceConversion( + manager=self, parentMenu=self.menu, parentButton=self.stackButton ) - self.datasourceConversion = DatasourceConversion(manager=self, parentMenu=self.menu, parentButton=self.stackButton) self.datasourceConversion.initGui() def unload(self): @@ -122,11 +134,15 @@ def createDatabase(self, isBatchCreation): pass if not isBatchCreation: if self.singleDbCreator is None: - self.singleDbCreator = CreateSingleDatabase(manager=self, parentButton=self.stackButton, parentMenu=self.menu) + self.singleDbCreator = CreateSingleDatabase( + manager=self, parentButton=self.stackButton, parentMenu=self.menu + ) dlg = self.singleDbCreator else: if self.batchCreator is None: - self.batchCreator = BatchDbCreator(manager=self, parentButton=self.stackButton, parentMenu=self.menu) + self.batchCreator = BatchDbCreator( + manager=self, parentButton=self.stackButton, parentMenu=self.menu + ) dlg = self.batchCreator if dlg: result = dlg.exec_() diff --git a/DsgTools/gui/LayerTools/CreateFrameTool/ui_create_inom_dialog.py b/DsgTools/gui/LayerTools/CreateFrameTool/ui_create_inom_dialog.py index bc08b9246..7086b06df 100644 --- a/DsgTools/gui/LayerTools/CreateFrameTool/ui_create_inom_dialog.py +++ b/DsgTools/gui/LayerTools/CreateFrameTool/ui_create_inom_dialog.py @@ -24,25 +24,34 @@ from __future__ import print_function from builtins import str from builtins import range -from qgis.core import QgsCoordinateReferenceSystem, QgsCoordinateTransform, \ - QgsProcessingContext, QgsFeature +from qgis.core import ( + QgsCoordinateReferenceSystem, + QgsCoordinateTransform, + QgsProcessingContext, + QgsFeature, +) from qgis.PyQt import QtWidgets, QtCore, uic, QtGui from qgis.PyQt.QtWidgets import QMessageBox from qgis.PyQt.QtCore import pyqtSlot, Qt from qgis.PyQt.QtGui import QCursor import os -FORM_CLASS, _ = uic.loadUiType(os.path.join( - os.path.dirname(__file__), 'ui_create_inom_dialog_base.ui')) -#DsgTools imports +FORM_CLASS, _ = uic.loadUiType( + os.path.join(os.path.dirname(__file__), "ui_create_inom_dialog_base.ui") +) + +# DsgTools imports from DsgTools.core.Utils.FrameTools.map_index import UtmGrid -from DsgTools.core.Factories.LayerLoaderFactory.layerLoaderFactory import LayerLoaderFactory +from DsgTools.core.Factories.LayerLoaderFactory.layerLoaderFactory import ( + LayerLoaderFactory, +) -#qgis imports +# qgis imports import qgis as qgis import processing + class CreateInomDialog(QtWidgets.QDialog, FORM_CLASS): def __init__(self, iface, parent=None): """Constructor.""" @@ -65,11 +74,15 @@ def on_okButton_clicked(self): Creates the actual frame. """ if not self.widget.dbLoaded: - QMessageBox.warning(self, self.tr("Warning!"), self.tr('Please, select a database first.')) + QMessageBox.warning( + self, self.tr("Warning!"), self.tr("Please, select a database first.") + ) return if not self.validateMI(): - QMessageBox.warning(self, self.tr("Warning!"), self.tr('Map name index not valid!')) + QMessageBox.warning( + self, self.tr("Warning!"), self.tr("Map name index not valid!") + ) return try: QtWidgets.QApplication.setOverrideCursor(QCursor(Qt.WaitCursor)) @@ -80,29 +93,30 @@ def on_okButton_clicked(self): QtWidgets.QApplication.restoreOverrideCursor() raise e self.done(1) - + def runCreateFrameAndAddFeaturesToFrame(self, layer): crs = self.widget.crs.authid() inom = self.inomLineEdit.text() scaleIdx = self.scaleCombo.currentIndex() context = QgsProcessingContext() processingOutput = processing.run( - 'dsgtools:gridzonegenerator', + "dsgtools:gridzonegenerator", { - 'START_SCALE' : scaleIdx, - 'STOP_SCALE' : scaleIdx, - 'INDEX_TYPE' : 1, - 'INDEX' : inom, - 'CRS' : crs, - 'OUTPUT' : 'memory:' + "START_SCALE": scaleIdx, + "STOP_SCALE": scaleIdx, + "INDEX_TYPE": 1, + "INDEX": inom, + "CRS": crs, + "OUTPUT": "memory:", }, - context = context) + context=context, + ) featList = [] - for feat in processingOutput['OUTPUT'].getFeatures(): + for feat in processingOutput["OUTPUT"].getFeatures(): newFeat = QgsFeature(layer.fields()) - newFeat['mi'] = feat['mi'] - newFeat['inom'] = feat['inom'] - newFeat['escala'] = self.scaleCombo.currentText() + newFeat["mi"] = feat["mi"] + newFeat["inom"] = feat["inom"] + newFeat["escala"] = self.scaleCombo.currentText() newFeat.setGeometry(feat.geometry()) newFeat.geometry().convertToMultiType() featList.append(newFeat) @@ -110,7 +124,7 @@ def runCreateFrameAndAddFeaturesToFrame(self, layer): layer.addFeatures(featList) layer.commitChanges() self.zoomToLayer(layer, featList[0].geometry()) - + def zoomToLayer(self, layer, frame): """ Zooms in to the updated frame layer. @@ -122,47 +136,63 @@ def zoomToLayer(self, layer, frame): bbox = self.iface.mapCanvas().mapSettings().layerToMapCoordinates(layer, bbox) self.iface.mapCanvas().setExtent(bbox) self.iface.mapCanvas().refresh() - + def loadFrameLayer(self): """ Loads the frame layer case it is not loaded yet. """ - loader = LayerLoaderFactory().makeLoader(self.iface,self.widget.abstractDb) - if loader.provider == 'postgres': - layerMeta = {'cat': 'aux', 'geom': 'geom', 'geomType':'MULTIPOLYGON', 'lyrName': 'moldura_a', 'tableName':'aux_moldura_a', 'tableSchema':'public', 'tableType': 'BASE TABLE'} - elif loader.provider == 'spatialite': - layerMeta = {'cat': 'aux', 'geom': 'GEOMETRY', 'geomType':'MULTIPOLYGON', 'lyrName': 'moldura_a', 'tableName':'aux_moldura_a', 'tableSchema':'public', 'tableType': 'BASE TABLE'} + loader = LayerLoaderFactory().makeLoader(self.iface, self.widget.abstractDb) + if loader.provider == "postgres": + layerMeta = { + "cat": "aux", + "geom": "geom", + "geomType": "MULTIPOLYGON", + "lyrName": "moldura_a", + "tableName": "aux_moldura_a", + "tableSchema": "public", + "tableType": "BASE TABLE", + } + elif loader.provider == "spatialite": + layerMeta = { + "cat": "aux", + "geom": "GEOMETRY", + "geomType": "MULTIPOLYGON", + "lyrName": "moldura_a", + "tableName": "aux_moldura_a", + "tableSchema": "public", + "tableType": "BASE TABLE", + } else: layerMeta = None - layerDict = loader.load([layerMeta], uniqueLoad = True) - if layerMeta['lyrName'] in list(layerDict.keys()): - layer = layerDict[layerMeta['lyrName']] + layerDict = loader.load([layerMeta], uniqueLoad=True) + if layerMeta["lyrName"] in list(layerDict.keys()): + layer = layerDict[layerMeta["lyrName"]] else: layer = None return layer - def getFrameLayer(self,ifaceLayers): + def getFrameLayer(self, ifaceLayers): """ Gets the frame layer according to the database. """ for lyr in ifaceLayers: - if 'moldura_a' in lyr.name(): + if "moldura_a" in lyr.name(): dbname = self.getDBNameFromLayer(lyr) if dbname == self.widget.abstractDb.getDatabaseName(): return lyr return None - + def getDBNameFromLayer(self, lyr): """ Gets the database name according to the database. """ dbname = None - splitUri = lyr.dataProvider().dataSourceUri().split(' ') + splitUri = lyr.dataProvider().dataSourceUri().split(" ") if len(splitUri) > 0: - dbsplit = splitUri[0].split('=') - if len(dbsplit) > 1 and dbsplit[0] == 'dbname': + dbsplit = splitUri[0].split("=") + if len(dbsplit) > 1 and dbsplit[0] == "dbname": dbnameInString = dbsplit[1] - dbnameSplit = dbnameInString.split('\'') + dbnameSplit = dbnameInString.split("'") if len(dbnameSplit) > 1: dbname = dbnameSplit[1] return dbname @@ -173,41 +203,41 @@ def on_cancelButton_clicked(self): Closes the dialog returning 0. """ self.done(0) - + @pyqtSlot(str) - def on_inomLineEdit_textEdited(self,s): + def on_inomLineEdit_textEdited(self, s): """ Method to automatically update MI based on the INOM. It also changes all characters to upper case """ - if (s!=''): + if s != "": s = s.upper() self.inomLineEdit.setText(s) mi = self.map_index.getMIfromInom(str(s)) self.miLineEdit.setText(mi) @pyqtSlot(str) - def on_miLineEdit_textEdited(self,s): + def on_miLineEdit_textEdited(self, s): """ Method to automatically update INOM based on the MI. It also changes all characters to upper case """ - if (s!=''): + if s != "": s = s.upper() self.miLineEdit.setText(s) - self.inomen=self.map_index.getINomenFromMI(str(s)) + self.inomen = self.map_index.getINomenFromMI(str(s)) self.inomLineEdit.setText(self.inomen) @pyqtSlot(str) - def on_mirLineEdit_textEdited(self,s): + def on_mirLineEdit_textEdited(self, s): """ Method to automatically update INOM based on the MIR. It also changes all characters to upper case """ - if (s!=''): + if s != "": s = s.upper() self.mirLineEdit.setText(s) - self.inomen=self.map_index.getINomenFromMIR(str(s)) + self.inomen = self.map_index.getINomenFromMIR(str(s)) self.inomLineEdit.setText(self.inomen) def reprojectFrame(self, poly): @@ -229,79 +259,151 @@ def setValidCharacters(self): """ self.chars = [] - chars = 'NS' + chars = "NS" self.chars.append(chars) - chars = 'ABCDEFGHIJKLMNOPQRSTUVZ' + chars = "ABCDEFGHIJKLMNOPQRSTUVZ" self.chars.append(chars) - chars = ['01','02','03','04','05','06','07','08','09','10', - '11','12','13','14','15','16','17','18','19','20', - '21','22','23','24','25','26','27','28','29','30', - '31','32','33','34','35','36','37','38','39','40', - '41','42','43','44','45','46','47','48','49','50', - '51','52','53','54','55','56','57','58','59','60'] + chars = [ + "01", + "02", + "03", + "04", + "05", + "06", + "07", + "08", + "09", + "10", + "11", + "12", + "13", + "14", + "15", + "16", + "17", + "18", + "19", + "20", + "21", + "22", + "23", + "24", + "25", + "26", + "27", + "28", + "29", + "30", + "31", + "32", + "33", + "34", + "35", + "36", + "37", + "38", + "39", + "40", + "41", + "42", + "43", + "44", + "45", + "46", + "47", + "48", + "49", + "50", + "51", + "52", + "53", + "54", + "55", + "56", + "57", + "58", + "59", + "60", + ] self.chars.append(chars) - chars = 'VXYZ' + chars = "VXYZ" self.chars.append(chars) - chars = 'ABCD' + chars = "ABCD" self.chars.append(chars) - chars = ['I','II','III','IV','V','VI'] + chars = ["I", "II", "III", "IV", "V", "VI"] self.chars.append(chars) - chars = '1234' + chars = "1234" self.chars.append(chars) - chars = ['NO','NE','SO','SE'] + chars = ["NO", "NE", "SO", "SE"] self.chars.append(chars) - chars = 'ABCDEF' + chars = "ABCDEF" self.chars.append(chars) - chars = ['I','II','III','IV'] + chars = ["I", "II", "III", "IV"] self.chars.append(chars) - chars = '123456' + chars = "123456" self.chars.append(chars) - chars = 'ABCD' + chars = "ABCD" self.chars.append(chars) def setMask(self): """ REGEx closely related to the valid chars method 'setValidCharacters' """ - if self.scaleCombo.currentText() == '1000k': - regex = QtCore.QRegExp('[NSns]{1}[A-Za-z]{1}\-[0-9]{1,2}') + if self.scaleCombo.currentText() == "1000k": + regex = QtCore.QRegExp("[NSns]{1}[A-Za-z]{1}\-[0-9]{1,2}") validator = QtGui.QRegExpValidator(regex, self.inomLineEdit) self.inomLineEdit.setValidator(validator) - elif self.scaleCombo.currentText() == '500k': - regex = QtCore.QRegExp('[NSns]{1}[A-Za-z]{1}\-[0-9]{1,2}\-[V-Zv-z]{1}') + elif self.scaleCombo.currentText() == "500k": + regex = QtCore.QRegExp("[NSns]{1}[A-Za-z]{1}\-[0-9]{1,2}\-[V-Zv-z]{1}") validator = QtGui.QRegExpValidator(regex, self.inomLineEdit) self.inomLineEdit.setValidator(validator) - elif self.scaleCombo.currentText() == '250k': - regex = QtCore.QRegExp('[NSns]{1}[A-Za-z]{1}\-[0-9]{1,2}\-[V-Zv-z]{1}\-[A-Da-d]{1}') + elif self.scaleCombo.currentText() == "250k": + regex = QtCore.QRegExp( + "[NSns]{1}[A-Za-z]{1}\-[0-9]{1,2}\-[V-Zv-z]{1}\-[A-Da-d]{1}" + ) validator = QtGui.QRegExpValidator(regex, self.inomLineEdit) self.inomLineEdit.setValidator(validator) - elif self.scaleCombo.currentText() == '100k': - regex = QtCore.QRegExp('[NSns]{1}[A-Za-z]{1}\-[0-9]{1,2}\-[V-Zv-z]{1}\-[A-Da-d]{1}\-[IViv]{1,3}') + elif self.scaleCombo.currentText() == "100k": + regex = QtCore.QRegExp( + "[NSns]{1}[A-Za-z]{1}\-[0-9]{1,2}\-[V-Zv-z]{1}\-[A-Da-d]{1}\-[IViv]{1,3}" + ) validator = QtGui.QRegExpValidator(regex, self.inomLineEdit) self.inomLineEdit.setValidator(validator) - elif self.scaleCombo.currentText() == '50k': - self.inomLineEdit.setInputMask('NN-NN-N-N-Nnn-0') - regex = QtCore.QRegExp('[NSns]{1}[A-Za-z]{1}\-[0-9]{1,2}\-[V-Zv-z]{1}\-[A-Da-d]{1}\-[IViv]{1,3}\-[1-4]{1}') + elif self.scaleCombo.currentText() == "50k": + self.inomLineEdit.setInputMask("NN-NN-N-N-Nnn-0") + regex = QtCore.QRegExp( + "[NSns]{1}[A-Za-z]{1}\-[0-9]{1,2}\-[V-Zv-z]{1}\-[A-Da-d]{1}\-[IViv]{1,3}\-[1-4]{1}" + ) validator = QtGui.QRegExpValidator(regex, self.inomLineEdit) self.inomLineEdit.setValidator(validator) - elif self.scaleCombo.currentText() == '25k': - regex = QtCore.QRegExp('[NSns]{1}[A-Za-z]{1}\-[0-9]{1,2}\-[V-Zv-z]{1}\-[A-Da-d]{1}\-[IViv]{1,3}\-[1-4]{1}\-[NSns]{1}[OEoe]{1}') + elif self.scaleCombo.currentText() == "25k": + regex = QtCore.QRegExp( + "[NSns]{1}[A-Za-z]{1}\-[0-9]{1,2}\-[V-Zv-z]{1}\-[A-Da-d]{1}\-[IViv]{1,3}\-[1-4]{1}\-[NSns]{1}[OEoe]{1}" + ) validator = QtGui.QRegExpValidator(regex, self.inomLineEdit) self.inomLineEdit.setValidator(validator) - elif self.scaleCombo.currentText() == '10k': - regex = QtCore.QRegExp('[NSns]{1}[A-Za-z]{1}\-[0-9]{1,2}\-[V-Zv-z]{1}\-[A-Da-d]{1}\-[IViv]{1,3}\-[1-4]{1}\-[NSns]{1}[OEoe]{1}\-[A-Fa-f]{1}') + elif self.scaleCombo.currentText() == "10k": + regex = QtCore.QRegExp( + "[NSns]{1}[A-Za-z]{1}\-[0-9]{1,2}\-[V-Zv-z]{1}\-[A-Da-d]{1}\-[IViv]{1,3}\-[1-4]{1}\-[NSns]{1}[OEoe]{1}\-[A-Fa-f]{1}" + ) validator = QtGui.QRegExpValidator(regex, self.inomLineEdit) self.inomLineEdit.setValidator(validator) - elif self.scaleCombo.currentText() == '5k': - regex = QtCore.QRegExp('[NSns]{1}[A-Za-z]{1}\-[0-9]{1,2}\-[V-Zv-z]{1}\-[A-Da-d]{1}\-[IViv]{1,3}\-[1-4]{1}\-[NSns]{1}[OEoe]{1}\-[A-Fa-f]{1}\-[IViv]{1,3}') + elif self.scaleCombo.currentText() == "5k": + regex = QtCore.QRegExp( + "[NSns]{1}[A-Za-z]{1}\-[0-9]{1,2}\-[V-Zv-z]{1}\-[A-Da-d]{1}\-[IViv]{1,3}\-[1-4]{1}\-[NSns]{1}[OEoe]{1}\-[A-Fa-f]{1}\-[IViv]{1,3}" + ) validator = QtGui.QRegExpValidator(regex, self.inomLineEdit) self.inomLineEdit.setValidator(validator) - elif self.scaleCombo.currentText() == '2k': - regex = QtCore.QRegExp('[NSns]{1}[A-Za-z]{1}\-[0-9]{1,2}\-[V-Zv-z]{1}\-[A-Da-d]{1}\-[IViv]{1,3}\-[1-4]{1}\-[NSns]{1}[OEoe]{1}\-[A-Fa-f]{1}\-[IViv]{1,3}\-[1-6]{1}') + elif self.scaleCombo.currentText() == "2k": + regex = QtCore.QRegExp( + "[NSns]{1}[A-Za-z]{1}\-[0-9]{1,2}\-[V-Zv-z]{1}\-[A-Da-d]{1}\-[IViv]{1,3}\-[1-4]{1}\-[NSns]{1}[OEoe]{1}\-[A-Fa-f]{1}\-[IViv]{1,3}\-[1-6]{1}" + ) validator = QtGui.QRegExpValidator(regex, self.inomLineEdit) self.inomLineEdit.setValidator(validator) - elif self.scaleCombo.currentText() == '1k': - regex = QtCore.QRegExp('[NSns]{1}[A-Za-z]{1}\-[0-9]{1,2}\-[V-Zv-z]{1}\-[A-Da-d]{1}\-[IViv]{1,3}\-[1-4]{1}\-[NSns]{1}[OEoe]{1}\-[A-Fa-f]{1}\-[IViv]{1,3}\-[1-6]{1}\-[A-Da-d]{1}') + elif self.scaleCombo.currentText() == "1k": + regex = QtCore.QRegExp( + "[NSns]{1}[A-Za-z]{1}\-[0-9]{1,2}\-[V-Zv-z]{1}\-[A-Da-d]{1}\-[IViv]{1,3}\-[1-4]{1}\-[NSns]{1}[OEoe]{1}\-[A-Fa-f]{1}\-[IViv]{1,3}\-[1-6]{1}\-[A-Da-d]{1}" + ) validator = QtGui.QRegExpValidator(regex, self.inomLineEdit) self.inomLineEdit.setValidator(validator) @@ -310,7 +412,7 @@ def validateMI(self): Method to validate INOM based on the valid characters. """ mi = self.inomLineEdit.text() - split = mi.split('-') + split = mi.split("-") for i in range(len(split)): word = str(split[i]) if len(word) == 0: @@ -390,7 +492,7 @@ def on_scaleCombo_currentIndexChanged(self): Adjusts the mask according to the scale. """ self.setMask() - if self.scaleCombo.currentText() == '1000k': + if self.scaleCombo.currentText() == "1000k": self.miRadioButton.setEnabled(False) self.miLineEdit.setEnabled(False) self.mirRadioButton.setEnabled(True) @@ -429,4 +531,4 @@ def on_inomRadioButton_toggled(self, toggled): if toggled: self.inomLineEdit.setEnabled(True) else: - self.inomLineEdit.setEnabled(False) \ No newline at end of file + self.inomLineEdit.setEnabled(False) diff --git a/DsgTools/gui/LayerTools/LoadLayersFromServer/loadLayersFromServer.py b/DsgTools/gui/LayerTools/LoadLayersFromServer/loadLayersFromServer.py index 565c6a64a..71ec63d49 100644 --- a/DsgTools/gui/LayerTools/LoadLayersFromServer/loadLayersFromServer.py +++ b/DsgTools/gui/LayerTools/LoadLayersFromServer/loadLayersFromServer.py @@ -239,6 +239,7 @@ def on_buttonBox_accepted(self): QApplication.restoreOverrideCursor() self.logInternalError(exceptionDict) self.close() + def logInternalError(self, exceptionDict): """ Logs internal errors during the load process in QGIS' log diff --git a/DsgTools/gui/LayerTools/layerToolsGuiManager.py b/DsgTools/gui/LayerTools/layerToolsGuiManager.py index f311a8ac0..10d1412a8 100644 --- a/DsgTools/gui/LayerTools/layerToolsGuiManager.py +++ b/DsgTools/gui/LayerTools/layerToolsGuiManager.py @@ -29,44 +29,55 @@ from .LoadLayersFromServer.loadLayersFromServer import LoadLayersFromServer from .CreateFrameTool.ui_create_inom_dialog import CreateInomDialog -class LayerToolsGuiManager(QObject): - def __init__(self, manager, iface, parentMenu = None, toolbar = None): - """Constructor. - """ +class LayerToolsGuiManager(QObject): + def __init__(self, manager, iface, parentMenu=None, toolbar=None): + """Constructor.""" super(LayerToolsGuiManager, self).__init__() self.manager = manager self.iface = iface self.parentMenu = parentMenu self.toolbar = toolbar - self.menu = self.manager.addMenu(u'layers', self.tr('Layer Tools'),'layers.png') - self.stackButton = self.manager.createToolButton(self.toolbar, u'LayerTools') - self.iconBasePath = ':/plugins/DsgTools/icons/' - - def addTool(self, text, callback, parentMenu, icon, defaultButton = False): + self.menu = self.manager.addMenu("layers", self.tr("Layer Tools"), "layers.png") + self.stackButton = self.manager.createToolButton(self.toolbar, "LayerTools") + self.iconBasePath = ":/plugins/DsgTools/icons/" + + def addTool(self, text, callback, parentMenu, icon, defaultButton=False): icon_path = self.iconBasePath + icon action = self.manager.add_action( icon_path, text=text, callback=callback, - add_to_menu = False, - add_to_toolbar = False, - withShortcut = False, - parentToolbar = parentMenu, - isCheckable = False + add_to_menu=False, + add_to_toolbar=False, + withShortcut=False, + parentToolbar=parentMenu, + isCheckable=False, ) self.stackButton.addAction(action) if defaultButton: self.stackButton.setDefaultAction(action) - + def initGui(self): - #adding minimum area tool - self.addTool(self.tr('Load Layers'), self.loadLayersFromServer, self.menu, 'category.png', defaultButton=True) - self.addTool(self.tr('Create Frame'), self.createFrame, self.menu, 'frame.png', defaultButton=False) - + # adding minimum area tool + self.addTool( + self.tr("Load Layers"), + self.loadLayersFromServer, + self.menu, + "category.png", + defaultButton=True, + ) + self.addTool( + self.tr("Create Frame"), + self.createFrame, + self.menu, + "frame.png", + defaultButton=False, + ) + def unload(self): pass - + def loadLayersFromServer(self): """ Shows the dialog that loads layers from server @@ -86,4 +97,4 @@ def createFrame(self): dlg.show() result = dlg.exec_() if result: - pass \ No newline at end of file + pass diff --git a/DsgTools/gui/LayerTools/loadAuxStruct.py b/DsgTools/gui/LayerTools/loadAuxStruct.py index 44b21ca0a..9c6ba93a0 100644 --- a/DsgTools/gui/LayerTools/loadAuxStruct.py +++ b/DsgTools/gui/LayerTools/loadAuxStruct.py @@ -9,7 +9,7 @@ git sha : $Format:%H$ copyright : (C) 2014 by Philipe Borba - Cartographic Engineer @ Brazilian Army email : borba.philipe@eb.mil.br - mod history : + mod history : ***************************************************************************/ /*************************************************************************** @@ -23,22 +23,26 @@ """ import os, json -#Qgis imports +# Qgis imports from qgis.gui import QgsMessageBar from qgis.core import QgsMessageLog -#PyQt imports +# PyQt imports from qgis.PyQt import QtWidgets, QtCore, uic from qgis.PyQt.QtCore import pyqtSlot, Qt from qgis.PyQt.QtWidgets import QApplication from qgis.PyQt.QtGui import QCursor import qgis as qgis -#DsgTools imports -from DsgTools.core.Factories.LayerLoaderFactory.layerLoaderFactory import LayerLoaderFactory +# DsgTools imports +from DsgTools.core.Factories.LayerLoaderFactory.layerLoaderFactory import ( + LayerLoaderFactory, +) + +FORM_CLASS, _ = uic.loadUiType( + os.path.join(os.path.dirname(__file__), "loadAuxStruct.ui") +) -FORM_CLASS, _ = uic.loadUiType(os.path.join( - os.path.dirname(__file__), 'loadAuxStruct.ui')) class LoadAuxStruct(QtWidgets.QDialog, FORM_CLASS): def __init__(self, iface, parent=None): @@ -50,18 +54,22 @@ def __init__(self, iface, parent=None): self.iface = iface self.layerFactory = LayerLoaderFactory() self.selectedClasses = [] - self.widget.tabWidget.setTabEnabled(0,True) - self.widget.tabWidget.setTabEnabled(1,False) + self.widget.tabWidget.setTabEnabled(0, True) + self.widget.tabWidget.setTabEnabled(1, False) self.widget.tabWidget.setCurrentIndex(0) self.bar = QgsMessageBar() self.setLayout(QtGui.QGridLayout(self)) - self.layout().setContentsMargins(0,0,0,0) + self.layout().setContentsMargins(0, 0, 0, 0) self.layout().setAlignment(QtCore.Qt.AlignTop) - sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Fixed) + sizePolicy = QtGui.QSizePolicy( + QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Fixed + ) self.bar.setSizePolicy(sizePolicy) - self.layout().addWidget(self.bar, 0,0,1,1) + self.layout().addWidget(self.bar, 0, 0, 1, 1) - QtCore.QObject.connect(self.widget, QtCore.SIGNAL(("problemOccurred()")), self.pushMessage) + QtCore.QObject.connect( + self.widget, QtCore.SIGNAL(("problemOccurred()")), self.pushMessage + ) self.widget.dbChanged.connect(self.widgetConv.setDatabase) @pyqtSlot(bool) @@ -70,7 +78,7 @@ def on_pushButtonCancel_clicked(self): Closes the dialog """ self.close() - + def pushMessage(self, msg): """ Pushes a message into message bar @@ -80,12 +88,16 @@ def pushMessage(self, msg): @pyqtSlot(bool) def on_pushButtonOk_clicked(self): """ - Checks the linee-centroid structure and loads the correspondent layers + Checks the linee-centroid structure and loads the correspondent layers """ QApplication.setOverrideCursor(QCursor(Qt.WaitCursor)) if self.widgetConv.settingDict == dict(): QApplication.restoreOverrideCursor() - self.bar.pushMessage(self.tr("Error!"), self.tr("Could not load auxiliary classes! Check log for details!"), level=QgsMessageBar.CRITICAL) + self.bar.pushMessage( + self.tr("Error!"), + self.tr("Could not load auxiliary classes! Check log for details!"), + level=QgsMessageBar.CRITICAL, + ) else: self.loadLayers() QApplication.restoreOverrideCursor() @@ -96,27 +108,34 @@ def loadLayers(self): Loads the layers defined in the line-centroid structure """ try: - if self.widget.abstractDb.getDatabaseVersion() == 'Non_EDGV': + if self.widget.abstractDb.getDatabaseVersion() == "Non_EDGV": isEdgv = False else: isEdgv = True - auxClassesDict = self.widgetConv.settingDict['earthCoverageDict'] + auxClassesDict = self.widgetConv.settingDict["earthCoverageDict"] auxClasses = [] for key in list(auxClassesDict.keys()): for cl in auxClassesDict[key]: if cl not in auxClasses: - if '.' in cl: - classToLoad = cl.split('.')[-1] + if "." in cl: + classToLoad = cl.split(".")[-1] else: classToLoad = cl auxClasses.append(classToLoad) auxCentroids = self.widgetConv.abstractDb.getEarthCoverageCentroids() auxClasses = auxClasses + auxCentroids auxClasses.sort(reverse=True) - auxClasses = [self.widgetConv.settingDict['frameLayer'].split('.')[-1]]+auxClasses - factory = self.layerFactory.makeLoader(self.iface, self.widget.abstractDb, loadCentroids=True) - factory.load(auxClasses, uniqueLoad = True, isEdgv = isEdgv) + auxClasses = [ + self.widgetConv.settingDict["frameLayer"].split(".")[-1] + ] + auxClasses + factory = self.layerFactory.makeLoader( + self.iface, self.widget.abstractDb, loadCentroids=True + ) + factory.load(auxClasses, uniqueLoad=True, isEdgv=isEdgv) except Exception as e: - QgsMessageLog.logMessage(':'.join(e.args), "DSGTools Plugin", Qgis.Critical) - self.bar.pushMessage(self.tr("Error!"), self.tr("Could not load auxiliary classes! Check log for details!"), level=QgsMessageBar.CRITICAL) - \ No newline at end of file + QgsMessageLog.logMessage(":".join(e.args), "DSGTools Plugin", Qgis.Critical) + self.bar.pushMessage( + self.tr("Error!"), + self.tr("Could not load auxiliary classes! Check log for details!"), + level=QgsMessageBar.CRITICAL, + ) diff --git a/DsgTools/gui/LayerTools/load_by_class.py b/DsgTools/gui/LayerTools/load_by_class.py index 3ad6dea92..e1baf78e4 100644 --- a/DsgTools/gui/LayerTools/load_by_class.py +++ b/DsgTools/gui/LayerTools/load_by_class.py @@ -24,22 +24,24 @@ from builtins import range import os -#Qgis imports +# Qgis imports from qgis.gui import QgsMessageBar from qgis.core import QgsMessageLog -#PyQt imports +# PyQt imports from qgis.PyQt import QtWidgets, QtCore, uic from qgis.PyQt.QtCore import Qt, pyqtSlot from qgis.PyQt.QtWidgets import QApplication from qgis.PyQt.QtGui import QCursor import qgis as qgis -#DsgTools imports +# DsgTools imports from DsgTools.core.Factories.LayerFactory.layerFactory import LayerFactory -FORM_CLASS, _ = uic.loadUiType(os.path.join( - os.path.dirname(__file__), 'load_by_class_base.ui')) +FORM_CLASS, _ = uic.loadUiType( + os.path.join(os.path.dirname(__file__), "load_by_class_base.ui") +) + class LoadByClass(QtWidgets.QDialog, FORM_CLASS): def __init__(self, codeList, parent=None): @@ -58,53 +60,73 @@ def __init__(self, codeList, parent=None): self.bar = QgsMessageBar() self.setLayout(QtGui.QGridLayout(self)) - self.layout().setContentsMargins(0,0,0,0) + self.layout().setContentsMargins(0, 0, 0, 0) self.layout().setAlignment(QtCore.Qt.AlignTop) - sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Fixed) + sizePolicy = QtGui.QSizePolicy( + QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Fixed + ) self.bar.setSizePolicy(sizePolicy) - self.layout().addWidget(self.bar, 0,0,1,1) - - #Objects Connections - QtCore.QObject.connect(self.widget, QtCore.SIGNAL(("connectionChanged()")), self.listClassesFromDatabase) - QtCore.QObject.connect(self.widget, QtCore.SIGNAL(("problemOccurred()")), self.pushMessage) - - QtCore.QObject.connect(self.pushButtonCancel, QtCore.SIGNAL(("clicked()")), self.cancel) - QtCore.QObject.connect(self.selectAllCheck, QtCore.SIGNAL(("stateChanged(int)")), self.selectAll) - QtCore.QObject.connect(self.pushButtonOk, QtCore.SIGNAL(("clicked()")), self.okSelected) - + self.layout().addWidget(self.bar, 0, 0, 1, 1) + + # Objects Connections + QtCore.QObject.connect( + self.widget, + QtCore.SIGNAL(("connectionChanged()")), + self.listClassesFromDatabase, + ) + QtCore.QObject.connect( + self.widget, QtCore.SIGNAL(("problemOccurred()")), self.pushMessage + ) + + QtCore.QObject.connect( + self.pushButtonCancel, QtCore.SIGNAL(("clicked()")), self.cancel + ) + QtCore.QObject.connect( + self.selectAllCheck, QtCore.SIGNAL(("stateChanged(int)")), self.selectAll + ) + QtCore.QObject.connect( + self.pushButtonOk, QtCore.SIGNAL(("clicked()")), self.okSelected + ) + self.widget.tabWidget.currentChanged.connect(self.restoreInitialState) self.widget.styleChanged.connect(self.populateStyleCombo) self.codeList = codeList self.layerFactory = LayerFactory() def restoreInitialState(self): - ''' + """ Restores the dialog initial state - ''' + """ self.selectedClasses = [] tam = self.classesListWidget.__len__() - for i in range(tam+1,1,-1): - item = self.classesListWidget.takeItem(i-2) + for i in range(tam + 1, 1, -1): + item = self.classesListWidget.takeItem(i - 2) self.selectAllCheck.setCheckState(0) def listClassesFromDatabase(self): - ''' + """ List all classes from database - ''' + """ self.classes = [] self.classesListWidget.clear() self.dbVersion = self.widget.getDBVersion() self.qmlPath = self.widget.getQmlPath() - self.parentClassList = self.widget.abstractDb.getOrphanGeomTablesWithElements(loading = True) + self.parentClassList = self.widget.abstractDb.getOrphanGeomTablesWithElements( + loading=True + ) self.classes = [] try: self.classes = self.widget.abstractDb.listGeomClassesFromDatabase() except Exception as e: - self.bar.pushMessage(self.tr("CRITICAL!"), self.tr('A problem occurred! Check log for details.'), level=QgsMessageBar.CRITICAL) - QgsMessageLog.logMessage(':'.join(e.args), 'DSGTools Plugin', Qgis.Critical) + self.bar.pushMessage( + self.tr("CRITICAL!"), + self.tr("A problem occurred! Check log for details."), + level=QgsMessageBar.CRITICAL, + ) + QgsMessageLog.logMessage(":".join(e.args), "DSGTools Plugin", Qgis.Critical) if self.onlyParentsCheckBox.isChecked() and not self.widget.isSpatialite: self.classesListWidget.addItems(self.parentClassList) @@ -113,48 +135,48 @@ def listClassesFromDatabase(self): self.classesListWidget.sortItems() def on_filterEdit_textChanged(self, text): - ''' + """ Filters shown classes text: text used to filter classes - ''' + """ classes = [edgvClass for edgvClass in self.classes if text in edgvClass] self.classesListWidget.clear() self.classesListWidget.addItems(classes) self.classesListWidget.sortItems() def cancel(self): - ''' + """ Cancels the process - ''' + """ self.restoreInitialState() self.close() - + def pushMessage(self, msg): - ''' + """ Pushes a message into message bar - ''' + """ self.bar.pushMessage("", msg, level=QgsMessageBar.CRITICAL) def selectAll(self): - ''' + """ Select all classes to be loaded - ''' + """ if self.selectAllCheck.isChecked(): tam = self.classesListWidget.__len__() - for i in range(tam+1): - item = self.classesListWidget.item(i-1) - self.classesListWidget.setItemSelected(item,2) + for i in range(tam + 1): + item = self.classesListWidget.item(i - 1) + self.classesListWidget.setItemSelected(item, 2) else: tam = self.classesListWidget.__len__() - for i in range(tam+1): - item = self.classesListWidget.item(i-1) - self.classesListWidget.setItemSelected(item,0) + for i in range(tam + 1): + item = self.classesListWidget.item(i - 1) + self.classesListWidget.setItemSelected(item, 0) def getSelectedItems(self): - ''' + """ Gets the selected classes - ''' + """ lista = self.classesListWidget.selectedItems() self.selectedClasses = [] tam = len(lista) @@ -163,39 +185,61 @@ def getSelectedItems(self): self.selectedClasses.sort() def okSelected(self): - ''' + """ Loads the selected layers - ''' + """ QApplication.setOverrideCursor(QCursor(Qt.WaitCursor)) self.loadLayers() QApplication.restoreOverrideCursor() def loadLayers(self): - ''' + """ Actual method that load layers - ''' + """ self.getSelectedItems() - if len(self.selectedClasses)>0: + if len(self.selectedClasses) > 0: try: selectedStyle = None if self.styleDict: if self.styleComboBox.currentText() in list(self.styleDict.keys()): - selectedStyle = self.styleDict[self.styleComboBox.currentText()] + selectedStyle = self.styleDict[self.styleComboBox.currentText()] for layer in self.selectedClasses: dbName = self.widget.abstractDb.getDatabaseName() - groupList = qgis.utils.iface.legendInterface().groups() - edgvLayer = self.layerFactory.makeLayer(self.widget.abstractDb, self.codeList, layer) + groupList = qgis.utils.iface.legendInterface().groups() + edgvLayer = self.layerFactory.makeLayer( + self.widget.abstractDb, self.codeList, layer + ) if dbName in groupList: - edgvLayer.load(self.widget.crs, groupList.index(dbName), stylePath = selectedStyle) + edgvLayer.load( + self.widget.crs, + groupList.index(dbName), + stylePath=selectedStyle, + ) else: - self.parentTreeNode = qgis.utils.iface.legendInterface().addGroup(self.widget.abstractDb.getDatabaseName(), -1) - edgvLayer.load(self.widget.crs, self.parentTreeNode, stylePath = selectedStyle) + self.parentTreeNode = ( + qgis.utils.iface.legendInterface().addGroup( + self.widget.abstractDb.getDatabaseName(), -1 + ) + ) + edgvLayer.load( + self.widget.crs, + self.parentTreeNode, + stylePath=selectedStyle, + ) self.restoreInitialState() self.close() except: - self.bar.pushMessage(self.tr("Error!"), self.tr("Could not load the selected classes!"), level=QgsMessageBar.CRITICAL) + self.bar.pushMessage( + self.tr("Error!"), + self.tr("Could not load the selected classes!"), + level=QgsMessageBar.CRITICAL, + ) else: - self.bar.pushMessage(self.tr("Warning!"), self.tr("Please, select at least one class!"), level=QgsMessageBar.WARNING) + self.bar.pushMessage( + self.tr("Warning!"), + self.tr("Please, select at least one class!"), + level=QgsMessageBar.WARNING, + ) def populateStyleCombo(self, styleDict): self.styleComboBox.clear() @@ -203,12 +247,12 @@ def populateStyleCombo(self, styleDict): styleList = list(styleDict.keys()) numberOfStyles = len(styleList) if numberOfStyles > 0: - self.styleComboBox.addItem(self.tr('Select Style')) + self.styleComboBox.addItem(self.tr("Select Style")) for i in range(numberOfStyles): self.styleComboBox.addItem(styleList[i]) else: - self.syleComboBox.addItem(self.tr('No available styles')) - + self.syleComboBox.addItem(self.tr("No available styles")) + @pyqtSlot(int) def on_onlyParentsCheckBox_stateChanged(self): - self.listClassesFromDatabase() \ No newline at end of file + self.listClassesFromDatabase() diff --git a/DsgTools/gui/Misc/ImageTools/processingTools.py b/DsgTools/gui/Misc/ImageTools/processingTools.py index 53649c256..d029725d8 100644 --- a/DsgTools/gui/Misc/ImageTools/processingTools.py +++ b/DsgTools/gui/Misc/ImageTools/processingTools.py @@ -36,8 +36,10 @@ from qgis.core import QgsCoordinateReferenceSystem, QgsMessageLog from qgis.gui import QgsProjectionSelectionTreeWidget -FORM_CLASS, _ = uic.loadUiType(os.path.join( - os.path.dirname(__file__), 'ui_processingTools.ui')) +FORM_CLASS, _ = uic.loadUiType( + os.path.join(os.path.dirname(__file__), "ui_processingTools.ui") +) + class ProcessingTools(QtWidgets.QDialog, FORM_CLASS): def __init__(self, iface): @@ -54,65 +56,93 @@ def __init__(self, iface): self.tabWidget.removeTab(1) self.epsg = 4326 - srs = QgsCoordinateReferenceSystem(self.epsg, QgsCoordinateReferenceSystem.EpsgCrsId) + srs = QgsCoordinateReferenceSystem( + self.epsg, QgsCoordinateReferenceSystem.EpsgCrsId + ) self.srLineEdit.setText(srs.description()) @pyqtSlot() def on_buttonBox_accepted(self): - ''' + """ Starts to process the selected images - ''' + """ if self.fileListWidget.count() == 0: - QMessageBox.warning(self.iface.mainWindow(), self.tr("Warning!"), self.tr("Please select at least one image.")) + QMessageBox.warning( + self.iface.mainWindow(), + self.tr("Warning!"), + self.tr("Please select at least one image."), + ) return - if self.outputFolderEdit.text() == '': - QMessageBox.warning(self.iface.mainWindow(), self.tr("Warning!"), self.tr("Please select at the output folder.")) + if self.outputFolderEdit.text() == "": + QMessageBox.warning( + self.iface.mainWindow(), + self.tr("Warning!"), + self.tr("Please select at the output folder."), + ) return - QMessageBox.information(self.iface.mainWindow(), self.tr("Information!"), self.tr("The processing may take several minutes. Please wait the final message.")) + QMessageBox.information( + self.iface.mainWindow(), + self.tr("Information!"), + self.tr( + "The processing may take several minutes. Please wait the final message." + ), + ) self.filesList = [] - for itemNumber in range(0,self.fileListWidget.count()): + for itemNumber in range(0, self.fileListWidget.count()): inFile = self.fileListWidget.item(itemNumber).text() self.filesList.append(str(inFile)) def getParameters(self): - ''' + """ Gets the process parameters - ''' + """ (rasterType, minOutValue, maxOutValue) = self.getGDALRasterType() - return (self.filesList, rasterType, minOutValue, maxOutValue, str(self.outputFolderEdit.text()), self.getStretchingPercentage(), self.epsg) + return ( + self.filesList, + rasterType, + minOutValue, + maxOutValue, + str(self.outputFolderEdit.text()), + self.getStretchingPercentage(), + self.epsg, + ) @pyqtSlot(bool) def on_srsButton_clicked(self): - ''' + """ Opens the dialog to select CRS - ''' + """ projSelector = QgsProjectionSelectionTreeWidget() - message = self.tr('Select the Spatial Reference System!') + message = self.tr("Select the Spatial Reference System!") projSelector.setMessage(theMessage=message) if not projSelector.exec_(): QMessageBox.warning(self, self.tr("Warning!"), message) return else: - self.epsg = int(projSelector.selectedAuthId().split(':')[-1]) - srs = QgsCoordinateReferenceSystem(self.epsg, QgsCoordinateReferenceSystem.EpsgCrsId) + self.epsg = int(projSelector.selectedAuthId().split(":")[-1]) + srs = QgsCoordinateReferenceSystem( + self.epsg, QgsCoordinateReferenceSystem.EpsgCrsId + ) self.srLineEdit.setText(srs.description()) @pyqtSlot(bool) def on_addButton_clicked(self): - ''' + """ Adds image files to be processed - ''' - fileNames, __ = QFileDialog.getOpenFileNames(self, self.tr("Select Images"), "", self.tr("Image files (*.tif)")) + """ + fileNames, __ = QFileDialog.getOpenFileNames( + self, self.tr("Select Images"), "", self.tr("Image files (*.tif)") + ) self.fileListWidget.addItems(fileNames) @pyqtSlot(bool) def on_removeButton_clicked(self): - ''' + """ Remove files from processing list - ''' + """ selectedItems = self.fileListWidget.selectedItems() for item in selectedItems: row = self.fileListWidget.row(item) @@ -120,27 +150,27 @@ def on_removeButton_clicked(self): @pyqtSlot(bool) def on_addFolderButton_clicked(self): - ''' + """ Adds a folder to be processed - ''' + """ folder = QFileDialog.getExistingDirectory(self, self.tr("Select Directory")) for dirName, subdirList, fileList in os.walk(folder): for fileName in fileList: - if fileName.split(".")[-1] == 'tif': - self.fileListWidget.addItem(os.path.join(dirName,fileName)) + if fileName.split(".")[-1] == "tif": + self.fileListWidget.addItem(os.path.join(dirName, fileName)) @pyqtSlot(bool) def on_outputFolderButton_clicked(self): - ''' + """ Defines the output folder - ''' + """ folder = QFileDialog.getExistingDirectory(self, self.tr("Select Directory")) self.outputFolderEdit.setText(folder) def getStretchingPercentage(self): - ''' + """ Gets the histogram stretching percentage - ''' + """ index = self.stretchComboBox.currentIndex() if index == 0: return 0 @@ -148,9 +178,9 @@ def getStretchingPercentage(self): return 2 def getGDALRasterType(self): - ''' + """ Gets the output raster type - ''' + """ index = self.numberComboBox.currentIndex() if index == 0: min = numpy.iinfo(numpy.uint8).min @@ -180,4 +210,3 @@ def getGDALRasterType(self): min = numpy.finfo(numpy.float64).min max = numpy.finfo(numpy.float64).max return (osgeo.gdal.GDT_Float64, min, max) - diff --git a/DsgTools/gui/Misc/ImageTools/raster_processing.py b/DsgTools/gui/Misc/ImageTools/raster_processing.py index 2a626f8bb..f09944c12 100644 --- a/DsgTools/gui/Misc/ImageTools/raster_processing.py +++ b/DsgTools/gui/Misc/ImageTools/raster_processing.py @@ -42,14 +42,14 @@ def __init__(self): gdal.UseExceptions() def openRaster(self, file): - ''' + """ Opens a gdal raster file - ''' + """ try: raster = gdal.Open(file) except RuntimeError as e: # fix_print_with_import - print('Unable to open image') + print("Unable to open image") # fix_print_with_import print(e) @@ -58,17 +58,17 @@ def openRaster(self, file): return raster def getBandAsArray(self, raster, bandnumber): - ''' + """ Gets a raster band as array raster: gdal raster file bandnumber: band number - ''' + """ try: band = raster.GetRasterBand(bandnumber) except RuntimeError as e: # for example, try GetRasterBand(10) # fix_print_with_import - print('Band ( %i ) not found' % bandnumber) + print("Band ( %i ) not found" % bandnumber) # fix_print_with_import print(e) sys.exit(1) @@ -76,10 +76,10 @@ def getBandAsArray(self, raster, bandnumber): return band.ReadAsArray() def getGeoreferenceInfo(self, raster): - ''' + """ Gets georeference information - raster: raster file - ''' + raster: raster file + """ # Get raster georeference info transform = raster.GetGeoTransform() xOrigin = transform[0] @@ -90,58 +90,60 @@ def getGeoreferenceInfo(self, raster): return (xOrigin, yOrigin, pixelWidth, pixelHeight) def getCRS(self, raster): - ''' + """ Gets raster file CRS - ''' + """ targetSR = osr.SpatialReference() targetSR.ImportFromWkt(raster.GetProjectionRef()) return targetSR def createRasterFromRGBbands(self, srcraster, red, green, blue, destfile): - ''' + """ Creates a raster file from RGB bands srcraster: source raster file red: red band green: green band blue: blue band destfile: destination file - ''' + """ outRaster = self.createRaster(srcraster, destfile) - + outRaster.GetRasterBand(1).WriteArray(red) outRaster.GetRasterBand(2).WriteArray(green) outRaster.GetRasterBand(3).WriteArray(blue) def createRaster(self, srcraster, destfile, pixelType): - ''' + """ Creates a raster file srcraster: source raster destfile: destination file pixelType: raster pixel type (e.g byte) - ''' + """ cols = srcraster.RasterXSize rows = srcraster.RasterYSize - (xOrigin, yOrigin, pixelWidth, pixelHeight) = self.getGeoreferenceInfo(srcraster) + (xOrigin, yOrigin, pixelWidth, pixelHeight) = self.getGeoreferenceInfo( + srcraster + ) targetSR = self.getCRS(srcraster) - driver = gdal.GetDriverByName('GTiff') + driver = gdal.GetDriverByName("GTiff") outRaster = driver.Create(destfile, cols, rows, 3, pixelType) outRaster.SetGeoTransform((xOrigin, pixelWidth, 0, yOrigin, 0, pixelHeight)) outRaster.SetProjection(targetSR.ExportToWkt()) - + return outRaster def pansharpenImage(self, rgbfile, panfile, destfile): - ''' + """ Performs a HSV fusion rgbfile: original RGB raster file panfile: original PAN raster file destfile: destination file - ''' + """ rgb = self.openRaster(rgbfile) red = rgb.GetRasterBand(1) green = rgb.GetRasterBand(2) @@ -149,10 +151,10 @@ def pansharpenImage(self, rgbfile, panfile, destfile): panraster = self.openRaster(panfile) pan = panraster.GetRasterBand(1) - + rgb_to_hsv = numpy.vectorize(colorsys.rgb_to_hsv) hsv_to_rgb = numpy.vectorize(colorsys.hsv_to_rgb) - + if red.DataType > pan.DataType: pixelType = red.DataType else: @@ -164,17 +166,17 @@ def pansharpenImage(self, rgbfile, panfile, destfile): outB = outRaster.GetRasterBand(3) sizeX = pan.XSize - sizeY = pan.YSize + sizeY = pan.YSize for row in range(sizeY): redblock = self.readBlock(red, sizeX, 1, row, red.DataType) greenblock = self.readBlock(green, sizeX, 1, row, green.DataType) blueblock = self.readBlock(blue, sizeX, 1, row, blue.DataType) - + panblock = self.readBlock(pan, sizeX, 1, row, pan.DataType) - + h, s, v = rgb_to_hsv(redblock, greenblock, blueblock) r, g, b = hsv_to_rgb(h, s, panblock) - + self.writeBlock(outR, r, sizeX, 1, row, pixelType) self.writeBlock(outG, g, sizeX, 1, row, pixelType) self.writeBlock(outB, b, sizeX, 1, row, pixelType) @@ -182,36 +184,38 @@ def pansharpenImage(self, rgbfile, panfile, destfile): rgb = None panraster = None outRaster = None - + def normalize(self, arr): - ''' + """ Function to normalize an input array to 0-1 - ''' + """ arr_min = arr.min() arr_max = arr.max() - return [(arr - arr_min) / (arr_max - arr_min)]*255 - - def readBlock(self, band, sizeX, sizeY = 1, offsetY = 0, pixelType = gdal.GDT_Byte): - ''' + return [(arr - arr_min) / (arr_max - arr_min)] * 255 + + def readBlock(self, band, sizeX, sizeY=1, offsetY=0, pixelType=gdal.GDT_Byte): + """ Reads image block band: band used sizeX: x block size sizeY: y block size offsetY: Y offset pixelType: pixel type - ''' + """ numpytype = self.getNumpyType(pixelType) - bandscanline =band.ReadRaster( 0, offsetY, sizeX, sizeY, sizeX, sizeY, pixelType ) - pixelArray=numpy.fromstring(bandscanline, dtype=numpytype) - + bandscanline = band.ReadRaster( + 0, offsetY, sizeX, sizeY, sizeX, sizeY, pixelType + ) + pixelArray = numpy.fromstring(bandscanline, dtype=numpytype) + return pixelArray - - def getNumpyType(self, pixelType = gdal.GDT_Byte): - ''' + + def getNumpyType(self, pixelType=gdal.GDT_Byte): + """ Translates the gdal raster type to numpy type pixelType: gdal raster type - ''' + """ if pixelType == gdal.GDT_Byte: return numpy.uint8 elif pixelType == gdal.GDT_UInt16: @@ -226,21 +230,26 @@ def getNumpyType(self, pixelType = gdal.GDT_Byte): return numpy.float32 elif pixelType == gdal.GDT_Float64: return numpy.float64 - - def writeBlock(self, band, block, sizeX, sizeY = 1, offsetY = 0, pixelType = gdal.GDT_Byte): - ''' + + def writeBlock( + self, band, block, sizeX, sizeY=1, offsetY=0, pixelType=gdal.GDT_Byte + ): + """ Writes image block band: band used sizeX: x block size sizeY: y block size offsetY: Y offset pixelType: pixel type - ''' + """ numpytype = self.getNumpyType(pixelType) band.WriteRaster(0, offsetY, sizeX, sizeY, block.astype(numpytype).tostring()) + obj = RasterProcess() -obj.pansharpenImage('/home/lclaudio/Documents/classificacao_rgb.tif', - '/home/lclaudio/Documents/corte_amp.tif', - '/home/lclaudio/Documents/teste.tif') +obj.pansharpenImage( + "/home/lclaudio/Documents/classificacao_rgb.tif", + "/home/lclaudio/Documents/corte_amp.tif", + "/home/lclaudio/Documents/teste.tif", +) diff --git a/DsgTools/gui/Misc/InventoryTools/inventoryTools.py b/DsgTools/gui/Misc/InventoryTools/inventoryTools.py index e66fed8f3..b855b045a 100644 --- a/DsgTools/gui/Misc/InventoryTools/inventoryTools.py +++ b/DsgTools/gui/Misc/InventoryTools/inventoryTools.py @@ -30,13 +30,23 @@ from qgis.PyQt import uic from qgis.PyQt.Qt import QObject from qgis.PyQt.QtCore import Qt, pyqtSlot -from qgis.PyQt.QtWidgets import QMenu, QApplication, QFileDialog, QMessageBox, QTreeWidgetItem, QInputDialog, QDialog +from qgis.PyQt.QtWidgets import ( + QMenu, + QApplication, + QFileDialog, + QMessageBox, + QTreeWidgetItem, + QInputDialog, + QDialog, +) from qgis.PyQt.QtGui import QCursor from _csv import writer from qgis._core import QgsAction -FORM_CLASS, _ = uic.loadUiType(os.path.join( - os.path.dirname(__file__), 'ui_inventoryTools.ui')) +FORM_CLASS, _ = uic.loadUiType( + os.path.join(os.path.dirname(__file__), "ui_inventoryTools.ui") +) + class InventoryTools(QDialog, FORM_CLASS): def __init__(self, iface): @@ -51,147 +61,175 @@ def __init__(self, iface): # #widgets-and-dialogs-with-auto-connect self.setupUi(self) self.iface = iface - + self.files = list() - + self.treeWidget.setContextMenuPolicy(Qt.CustomContextMenu) self.treeWidget.customContextMenuRequested.connect(self.createMenu) - + self.whitelistRadio.setChecked(True) - # set most used file extensions + # set most used file extensions item = QTreeWidgetItem(self.treeWidget.invisibleRootItem()) - item.setText(0,'shp') + item.setText(0, "shp") item = QTreeWidgetItem(self.treeWidget.invisibleRootItem()) - item.setText(0,'tif') - + item.setText(0, "tif") + def depth(self, item): - ''' + """ Calculates the depth of the item - ''' + """ depth = 0 while item is not None: item = item.parent() depth += 1 return depth - + def createMenu(self, position): - ''' + """ Creates the popup menu that allows extension insertion and removal position: mouse click position - ''' + """ menu = QMenu() - + item = self.treeWidget.itemAt(position) if not item: - menu.addAction(self.tr('Insert Extension'), self.insertExtension) - else: + menu.addAction(self.tr("Insert Extension"), self.insertExtension) + else: if self.depth(item) == 1: - menu.addAction(self.tr('Remove Extension'), self.removeExtension) - + menu.addAction(self.tr("Remove Extension"), self.removeExtension) + menu.exec_(self.treeWidget.viewport().mapToGlobal(position)) - + def insertExtension(self): - ''' + """ Inserts a new extension to be analyzed - ''' - text = QInputDialog.getText(self, self.tr('Type the extension'), self.tr('File extension'), mode=QLineEdit.Normal) + """ + text = QInputDialog.getText( + self, + self.tr("Type the extension"), + self.tr("File extension"), + mode=QLineEdit.Normal, + ) item = QTreeWidgetItem(self.treeWidget.invisibleRootItem()) - item.setText(0,text[0]) - + item.setText(0, text[0]) + def removeExtension(self): - ''' + """ Removes a extension from the list - ''' + """ item = self.treeWidget.selectedItems()[0] index = self.treeWidget.indexOfTopLevelItem(item) self.treeWidget.takeTopLevelItem(index) def getParameters(self): - ''' + """ Gets process parameters - ''' + """ formatsList = [] root = self.treeWidget.invisibleRootItem() for i in range(root.childCount()): item = root.child(i) extension = item.text(0) formatsList.append(extension) - - return (self.parentFolderEdit.text(), self.outputFileEdit.text(), self.copyFilesCheckBox.isChecked(), \ - self.destinationFolderEdit.text(), formatsList, self.whitelistRadio.isChecked(), self.onlyGeoCheckBox.isChecked()) - + + return ( + self.parentFolderEdit.text(), + self.outputFileEdit.text(), + self.copyFilesCheckBox.isChecked(), + self.destinationFolderEdit.text(), + formatsList, + self.whitelistRadio.isChecked(), + self.onlyGeoCheckBox.isChecked(), + ) + @pyqtSlot(bool) def on_parentFolderButton_clicked(self): - ''' + """ Opens the dialog to select the folder - ''' - folder = QFileDialog.getExistingDirectory(self, self.tr('Select Directory')) + """ + folder = QFileDialog.getExistingDirectory(self, self.tr("Select Directory")) self.parentFolderEdit.setText(folder) @pyqtSlot(bool) def on_copyFilesButton_clicked(self): - ''' + """ Opens the dialog to define the copy destination folder - ''' - folder = QFileDialog.getExistingDirectory(self, self.tr('Select Directory')) + """ + folder = QFileDialog.getExistingDirectory(self, self.tr("Select Directory")) self.destinationFolderEdit.setText(folder) @pyqtSlot(bool) def on_outputFileButton_clicked(self): - ''' + """ Inventory output file selection - ''' + """ if self.onlyGeoCheckBox.isChecked(): - fileName, __ = QFileDialog.getSaveFileName(parent=self, caption=self.tr('Save Output File'), filter='Shapefile (*.shp)') + fileName, __ = QFileDialog.getSaveFileName( + parent=self, + caption=self.tr("Save Output File"), + filter="Shapefile (*.shp)", + ) else: - fileName, __ = QFileDialog.getSaveFileName(parent=self, caption=self.tr('Save Output File'), filter='CSV (*.csv)') + fileName, __ = QFileDialog.getSaveFileName( + parent=self, caption=self.tr("Save Output File"), filter="CSV (*.csv)" + ) self.outputFileEdit.setText(fileName) - + @pyqtSlot(int) def on_copyFilesCheckBox_stateChanged(self, state): - ''' + """ Slot to update the dialog when copy files definition changes - ''' + """ if self.copyFilesCheckBox.isChecked(): self.frame_3.setEnabled(True) else: self.frame_3.setEnabled(False) - + @pyqtSlot(bool) def on_cancelButton_clicked(self): - ''' + """ Closes the dialog - ''' + """ self.done(0) @pyqtSlot(bool) def on_okButton_clicked(self): - ''' + """ Runs the process - ''' + """ parentFolder = self.parentFolderEdit.text() outputFile = self.outputFileEdit.text() if not parentFolder or not outputFile: QApplication.restoreOverrideCursor() - QMessageBox.information(self, self.tr('Information!'), self.tr('Please, fill all fields.')) + QMessageBox.information( + self, self.tr("Information!"), self.tr("Please, fill all fields.") + ) return if self.whitelistRadio.isChecked(): root = self.treeWidget.invisibleRootItem() if root.childCount() == 0: QApplication.restoreOverrideCursor() - QMessageBox.information(self, self.tr('Information!'), self.tr('Please, insert file extensions to be considered.')) + QMessageBox.information( + self, + self.tr("Information!"), + self.tr("Please, insert file extensions to be considered."), + ) return - + if self.copyFilesCheckBox.isChecked(): destinationFolder = self.destinationFolderEdit.text() - + if not destinationFolder: QApplication.restoreOverrideCursor() - QMessageBox.information(self, self.tr('Information!'), self.tr('Please, choose a location to save the files.')) + QMessageBox.information( + self, + self.tr("Information!"), + self.tr("Please, choose a location to save the files."), + ) return self.done(1) diff --git a/DsgTools/gui/Misc/PostgisCustomization/CustomJSONTools/customJSONBuilder.py b/DsgTools/gui/Misc/PostgisCustomization/CustomJSONTools/customJSONBuilder.py index 9f86df769..1c3426555 100644 --- a/DsgTools/gui/Misc/PostgisCustomization/CustomJSONTools/customJSONBuilder.py +++ b/DsgTools/gui/Misc/PostgisCustomization/CustomJSONTools/customJSONBuilder.py @@ -21,41 +21,101 @@ ***************************************************************************/ """ import json -#Qt Imports + +# Qt Imports from qgis.PyQt.Qt import QObject -#DsgTools Imports + +# DsgTools Imports + class CustomJSONBuilder(QObject): def __init__(self): - super(CustomJSONBuilder,self).__init__() + super(CustomJSONBuilder, self).__init__() def buildClassElement(self, schema, name, attrList): - return {'schema':schema, 'name':name, 'attrs':attrList} + return {"schema": schema, "name": name, "attrs": attrList} def buildNewAttributeElement(self, schema, name, attrList, childrenToAlter=[]): - return {'schema':schema, 'name':name, 'attrs':attrList, 'childrenToAlter':childrenToAlter} + return { + "schema": schema, + "name": name, + "attrs": attrList, + "childrenToAlter": childrenToAlter, + } - def buildAttributeElement(self, attrName, attrType, isPk, isNullable, defaultValue = None, references = None, filter=[]): - return {'attrName':attrName, 'attrType':attrType, 'isPk':isPk, 'isNullable':isNullable, 'defaultValue':defaultValue, 'references':references, 'filter':filter} + def buildAttributeElement( + self, + attrName, + attrType, + isPk, + isNullable, + defaultValue=None, + references=None, + filter=[], + ): + return { + "attrName": attrName, + "attrType": attrType, + "isPk": isPk, + "isNullable": isNullable, + "defaultValue": defaultValue, + "references": references, + "filter": filter, + } def addDomainTableElement(self, domainName, valueDict): - return {'domainName':domainName, 'valueDict': valueDict} + return {"domainName": domainName, "valueDict": valueDict} def addValueToValueDict(self, valueDict, code, codeName): if code not in list(valueDict.keys()): valueDict[code] = codeName - def buildCodeNameToChangeElement(self, domainTable, codeValue, oldCodeName, newCodeName): - return {'domainTable':domainTable, 'codeValue':codeValue, 'oldCodeName':oldCodeName, 'newCodeName':newCodeName} + def buildCodeNameToChangeElement( + self, domainTable, codeValue, oldCodeName, newCodeName + ): + return { + "domainTable": domainTable, + "codeValue": codeValue, + "oldCodeName": oldCodeName, + "newCodeName": newCodeName, + } def buildChangeDefaultElement(self, schema, table, attrName, oldValue, newValue): - return {'schema': schema, 'table': table, 'attrName':attrName, 'oldValue':oldValue, 'newValue':newValue} + return { + "schema": schema, + "table": table, + "attrName": attrName, + "oldValue": oldValue, + "newValue": newValue, + } def buildChangeNullityElement(self, schema, table, attrName, notNull): - return {'schema':schema, 'table':table, 'attrName':attrName, 'notNull':notNull} + return { + "schema": schema, + "table": table, + "attrName": attrName, + "notNull": notNull, + } def addDomainValueElement(self, domainName, code, codeName): - return {'domainName':domainName, 'code':code, 'codeName':codeName} + return {"domainName": domainName, "code": code, "codeName": codeName} - def alterFilterElement(self, schema, tableName, attrName, filterName, originalFilterList, valueList, isMulti = False): - return {'schema':schema, 'tableName':tableName, 'attrName':attrName, 'filterName':filterName,'originalFilterList':originalFilterList, 'valueList':valueList, 'isMulti':isMulti} \ No newline at end of file + def alterFilterElement( + self, + schema, + tableName, + attrName, + filterName, + originalFilterList, + valueList, + isMulti=False, + ): + return { + "schema": schema, + "tableName": tableName, + "attrName": attrName, + "filterName": filterName, + "originalFilterList": originalFilterList, + "valueList": valueList, + "isMulti": isMulti, + } diff --git a/DsgTools/gui/Misc/PostgisCustomization/CustomJSONTools/customJSONValidator.py b/DsgTools/gui/Misc/PostgisCustomization/CustomJSONTools/customJSONValidator.py index 2f76dfab3..355ba5219 100644 --- a/DsgTools/gui/Misc/PostgisCustomization/CustomJSONTools/customJSONValidator.py +++ b/DsgTools/gui/Misc/PostgisCustomization/CustomJSONTools/customJSONValidator.py @@ -21,26 +21,29 @@ ***************************************************************************/ """ import json -#Qt Imports + +# Qt Imports from qgis.PyQt.Qt import QObject -#DsgTools Imports + +# DsgTools Imports + class CustomJSONValidator(QObject): def __init__(self, jsonFile): - super(CustomJSONValidator,self).__init__() + super(CustomJSONValidator, self).__init__() self.jsonFile = jsonFile - + def parseJson(self): pass - + def validateTags(self): pass - + def validateDsgToolsClassNames(self): pass - + def validateGeometricPrimitives(self): pass - + def validate(self): - pass \ No newline at end of file + pass diff --git a/DsgTools/gui/Misc/PostgisCustomization/CustomJSONValidator/customJSONValidator.py b/DsgTools/gui/Misc/PostgisCustomization/CustomJSONValidator/customJSONValidator.py index 2f76dfab3..355ba5219 100644 --- a/DsgTools/gui/Misc/PostgisCustomization/CustomJSONValidator/customJSONValidator.py +++ b/DsgTools/gui/Misc/PostgisCustomization/CustomJSONValidator/customJSONValidator.py @@ -21,26 +21,29 @@ ***************************************************************************/ """ import json -#Qt Imports + +# Qt Imports from qgis.PyQt.Qt import QObject -#DsgTools Imports + +# DsgTools Imports + class CustomJSONValidator(QObject): def __init__(self, jsonFile): - super(CustomJSONValidator,self).__init__() + super(CustomJSONValidator, self).__init__() self.jsonFile = jsonFile - + def parseJson(self): pass - + def validateTags(self): pass - + def validateDsgToolsClassNames(self): pass - + def validateGeometricPrimitives(self): pass - + def validate(self): - pass \ No newline at end of file + pass diff --git a/DsgTools/gui/Misc/PostgisCustomization/createDatabaseCustomization.py b/DsgTools/gui/Misc/PostgisCustomization/createDatabaseCustomization.py index e0be406ca..7e861eaee 100644 --- a/DsgTools/gui/Misc/PostgisCustomization/createDatabaseCustomization.py +++ b/DsgTools/gui/Misc/PostgisCustomization/createDatabaseCustomization.py @@ -34,25 +34,55 @@ from qgis.PyQt.QtGui import QCursor # DSGTools imports -from DsgTools.gui.CustomWidgets.CustomDbManagementWidgets.newClassWidget import NewClassWidget -from DsgTools.gui.CustomWidgets.CustomDbManagementWidgets.newAttributeWidget import NewAttributeWidget -from DsgTools.gui.CustomWidgets.CustomDbManagementWidgets.newDomainWidget import NewDomainWidget -from DsgTools.gui.CustomWidgets.CustomDbManagementWidgets.newDomainValueWidget import NewDomainValueWidget -from DsgTools.gui.CustomWidgets.CustomDbManagementWidgets.codeNameCustomizationWidget import CodeNameCustomizationWidget -from DsgTools.gui.CustomWidgets.CustomDbManagementWidgets.changeNullityWidget import ChangeNullityWidget -from DsgTools.gui.CustomWidgets.CustomDbManagementWidgets.changeFilterWidget import ChangeFilterWidget -from DsgTools.gui.CustomWidgets.CustomDbManagementWidgets.alterDefaultWidget import AlterDefaultWidget -from DsgTools.gui.CustomWidgets.SelectionWidgets.selectFileWidget import SelectFileWidget +from DsgTools.gui.CustomWidgets.CustomDbManagementWidgets.newClassWidget import ( + NewClassWidget, +) +from DsgTools.gui.CustomWidgets.CustomDbManagementWidgets.newAttributeWidget import ( + NewAttributeWidget, +) +from DsgTools.gui.CustomWidgets.CustomDbManagementWidgets.newDomainWidget import ( + NewDomainWidget, +) +from DsgTools.gui.CustomWidgets.CustomDbManagementWidgets.newDomainValueWidget import ( + NewDomainValueWidget, +) +from DsgTools.gui.CustomWidgets.CustomDbManagementWidgets.codeNameCustomizationWidget import ( + CodeNameCustomizationWidget, +) +from DsgTools.gui.CustomWidgets.CustomDbManagementWidgets.changeNullityWidget import ( + ChangeNullityWidget, +) +from DsgTools.gui.CustomWidgets.CustomDbManagementWidgets.changeFilterWidget import ( + ChangeFilterWidget, +) +from DsgTools.gui.CustomWidgets.CustomDbManagementWidgets.alterDefaultWidget import ( + AlterDefaultWidget, +) +from DsgTools.gui.CustomWidgets.SelectionWidgets.selectFileWidget import ( + SelectFileWidget, +) from DsgTools.gui.Misc.PostgisCustomization.dbCustomizer import DbCustomizer -from DsgTools.gui.CustomWidgets.BasicInterfaceWidgets.progressWidget import ProgressWidget +from DsgTools.gui.CustomWidgets.BasicInterfaceWidgets.progressWidget import ( + ProgressWidget, +) from DsgTools.core.Factories.DbFactory.dbFactory import DbFactory from DsgTools.core.Utils.utils import Utils -FORM_CLASS, _ = uic.loadUiType(os.path.join( - os.path.dirname(__file__), 'createDatabaseCustomization.ui')) +FORM_CLASS, _ = uic.loadUiType( + os.path.join(os.path.dirname(__file__), "createDatabaseCustomization.ui") +) + class CreateDatabaseCustomization(QtWidgets.QDialog, FORM_CLASS): - def __init__(self, customizationName, abstractDb, edgvVersion, customizationManager, customJsonDict = None, parent = None): + def __init__( + self, + customizationName, + abstractDb, + edgvVersion, + customizationManager, + customJsonDict=None, + parent=None, + ): """Constructor.""" super(self.__class__, self).__init__(parent) self.setupUi(self) @@ -70,7 +100,7 @@ def __init__(self, customizationName, abstractDb, edgvVersion, customizationMana def clearWidgets(self): rootItem = self.customizationTreeWidget.invisibleRootItem() childNodeCount = rootItem.childCount() - #remove widgets + # remove widgets for i in range(childNodeCount): typeChild = rootItem.child(i) childCount = typeChild.childCount() @@ -78,100 +108,160 @@ def clearWidgets(self): for j in range(childCount): childTextList.append(typeChild.child(i).text(0)) for childText in childTextList: - self.removeWidget(widgetText = childText) - + self.removeWidget(widgetText=childText) + def setWidgetsEnabled(self, enabled): self.customizationSelectionComboBox.setEnabled(enabled) self.addAttributePushButton.setEnabled(enabled) self.customizationTreeWidget.setEnabled(enabled) self.removeSelectedPushButton.setEnabled(enabled) - + def populateCustomizationCombo(self): - ''' + """ Populates the customization combo and also defines customDict. - ''' + """ self.customDict = dict() - self.customDict['attribute'] = self.tr('Attribute Customization') - self.customDict['class'] = self.tr('Class Customization') - self.customDict['codeName'] = self.tr('Code Name Customization') - self.customDict['default'] = self.tr('Default Customization') - self.customDict['domain'] = self.tr('Domain Customization') - self.customDict['domainValue'] = self.tr('Domain Value Customization') - self.customDict['nullity'] = self.tr('Attribute Nullity Customization') - self.customDict['filter'] = self.tr('Attribute Filter Customization') + self.customDict["attribute"] = self.tr("Attribute Customization") + self.customDict["class"] = self.tr("Class Customization") + self.customDict["codeName"] = self.tr("Code Name Customization") + self.customDict["default"] = self.tr("Default Customization") + self.customDict["domain"] = self.tr("Domain Customization") + self.customDict["domainValue"] = self.tr("Domain Value Customization") + self.customDict["nullity"] = self.tr("Attribute Nullity Customization") + self.customDict["filter"] = self.tr("Attribute Filter Customization") rootNode = self.customizationTreeWidget.invisibleRootItem() for type in list(self.customDict.keys()): if self.customDict[type] not in list(self.contentsDict.keys()): self.contentsDict[self.customDict[type]] = dict() self.customizationSelectionComboBox.addItem(self.customDict[type]) - self.contentsDict[self.customDict[type]]['widgetList'] = [] - self.contentsDict[self.customDict[type]]['treeItem'] = self.createItem(rootNode, self.customDict[type], 0) + self.contentsDict[self.customDict[type]]["widgetList"] = [] + self.contentsDict[self.customDict[type]]["treeItem"] = self.createItem( + rootNode, self.customDict[type], 0 + ) self.customizationTreeWidget.expandAll() - + @pyqtSlot(bool) def on_addAttributePushButton_clicked(self): - if self.customizationSelectionComboBox.currentText() == self.tr('Attribute Customization'): + if self.customizationSelectionComboBox.currentText() == self.tr( + "Attribute Customization" + ): self.addAttributeWidget() - elif self.customizationSelectionComboBox.currentText() == self.tr('Class Customization'): + elif self.customizationSelectionComboBox.currentText() == self.tr( + "Class Customization" + ): self.addClassWidget() - elif self.customizationSelectionComboBox.currentText() == self.tr('Code Name Customization'): + elif self.customizationSelectionComboBox.currentText() == self.tr( + "Code Name Customization" + ): self.addCodeNameWidget() - elif self.customizationSelectionComboBox.currentText() == self.tr('Default Customization'): + elif self.customizationSelectionComboBox.currentText() == self.tr( + "Default Customization" + ): self.addDefaultWidget() - elif self.customizationSelectionComboBox.currentText() == self.tr('Domain Customization'): + elif self.customizationSelectionComboBox.currentText() == self.tr( + "Domain Customization" + ): self.addDomainWidget() - elif self.customizationSelectionComboBox.currentText() == self.tr('Domain Value Customization'): + elif self.customizationSelectionComboBox.currentText() == self.tr( + "Domain Value Customization" + ): self.addDomainValueWidget() - elif self.customizationSelectionComboBox.currentText() == self.tr('Attribute Nullity Customization'): + elif self.customizationSelectionComboBox.currentText() == self.tr( + "Attribute Nullity Customization" + ): self.addNullityWidget() - elif self.customizationSelectionComboBox.currentText() == self.tr('Attribute Filter Customization'): + elif self.customizationSelectionComboBox.currentText() == self.tr( + "Attribute Filter Customization" + ): self.addFilterWidget() else: - QMessageBox.warning(self, self.tr('Warning'), self.tr('Select a custom operation!')) - + QMessageBox.warning( + self, self.tr("Warning"), self.tr("Select a custom operation!") + ) + def addWidgetItem(self, contentsKey, widgetTitle, widget): - widgetList = self.contentsDict[contentsKey]['widgetList'] + widgetList = self.contentsDict[contentsKey]["widgetList"] if len(widgetList) > 0: - i = int(widgetList[-1].layout().itemAt(0).widget().getTitle().split('#')[-1]) + i = int( + widgetList[-1].layout().itemAt(0).widget().getTitle().split("#")[-1] + ) else: i = 0 - title = widgetTitle+' #{0}'.format(i+1) #add number + title = widgetTitle + " #{0}".format(i + 1) # add number widget.setTitle(title) - self.contentsDict[contentsKey]['widgetList'].append(self.addWidget(widget, title)) - self.createItem(self.contentsDict[contentsKey]['treeItem'], title, 0) - - def addAttributeWidget(self,uiParameterJsonDict=None): - widget = NewAttributeWidget(self.abstractDb,uiParameterJsonDict = uiParameterJsonDict) - self.addWidgetItem(self.tr('Attribute Customization'), self.tr('New Custom Attribute'), widget) - - def addClassWidget(self,uiParameterJsonDict=None): - widget = NewClassWidget(self.abstractDb,uiParameterJsonDict = uiParameterJsonDict) - self.addWidgetItem(self.tr('Class Customization'), self.tr('New Custom Class'), widget) - - def addCodeNameWidget(self,uiParameterJsonDict=None): - widget = CodeNameCustomizationWidget(self.abstractDb,uiParameterJsonDict = uiParameterJsonDict) - self.addWidgetItem(self.tr('Code Name Customization'), self.tr('New Custom Code Name'), widget) + self.contentsDict[contentsKey]["widgetList"].append( + self.addWidget(widget, title) + ) + self.createItem(self.contentsDict[contentsKey]["treeItem"], title, 0) + + def addAttributeWidget(self, uiParameterJsonDict=None): + widget = NewAttributeWidget( + self.abstractDb, uiParameterJsonDict=uiParameterJsonDict + ) + self.addWidgetItem( + self.tr("Attribute Customization"), self.tr("New Custom Attribute"), widget + ) + + def addClassWidget(self, uiParameterJsonDict=None): + widget = NewClassWidget( + self.abstractDb, uiParameterJsonDict=uiParameterJsonDict + ) + self.addWidgetItem( + self.tr("Class Customization"), self.tr("New Custom Class"), widget + ) - def addDefaultWidget(self,uiParameterJsonDict=None): - widget = AlterDefaultWidget(self.abstractDb,uiParameterJsonDict = uiParameterJsonDict) - self.addWidgetItem(self.tr('Default Customization'), self.tr('New Custom Default'), widget) + def addCodeNameWidget(self, uiParameterJsonDict=None): + widget = CodeNameCustomizationWidget( + self.abstractDb, uiParameterJsonDict=uiParameterJsonDict + ) + self.addWidgetItem( + self.tr("Code Name Customization"), self.tr("New Custom Code Name"), widget + ) - def addDomainWidget(self,uiParameterJsonDict=None): - widget = NewDomainWidget(self.abstractDb,uiParameterJsonDict = uiParameterJsonDict) - self.addWidgetItem(self.tr('Domain Customization'), self.tr('New Custom Domain'), widget) + def addDefaultWidget(self, uiParameterJsonDict=None): + widget = AlterDefaultWidget( + self.abstractDb, uiParameterJsonDict=uiParameterJsonDict + ) + self.addWidgetItem( + self.tr("Default Customization"), self.tr("New Custom Default"), widget + ) - def addDomainValueWidget(self,uiParameterJsonDict=None): - widget = NewDomainValueWidget(self.abstractDb,uiParameterJsonDict = uiParameterJsonDict) - self.addWidgetItem(self.tr('Domain Value Customization'), self.tr('New Domain Value'), widget) + def addDomainWidget(self, uiParameterJsonDict=None): + widget = NewDomainWidget( + self.abstractDb, uiParameterJsonDict=uiParameterJsonDict + ) + self.addWidgetItem( + self.tr("Domain Customization"), self.tr("New Custom Domain"), widget + ) - def addNullityWidget(self,uiParameterJsonDict=None): - widget = ChangeNullityWidget(self.abstractDb,uiParameterJsonDict = uiParameterJsonDict) - self.addWidgetItem(self.tr('Attribute Nullity Customization'), self.tr('New Custom Attribute Nullity'), widget) + def addDomainValueWidget(self, uiParameterJsonDict=None): + widget = NewDomainValueWidget( + self.abstractDb, uiParameterJsonDict=uiParameterJsonDict + ) + self.addWidgetItem( + self.tr("Domain Value Customization"), self.tr("New Domain Value"), widget + ) + + def addNullityWidget(self, uiParameterJsonDict=None): + widget = ChangeNullityWidget( + self.abstractDb, uiParameterJsonDict=uiParameterJsonDict + ) + self.addWidgetItem( + self.tr("Attribute Nullity Customization"), + self.tr("New Custom Attribute Nullity"), + widget, + ) + + def addFilterWidget(self, uiParameterJsonDict=None): + widget = ChangeFilterWidget( + self.abstractDb, uiParameterJsonDict=uiParameterJsonDict + ) + self.addWidgetItem( + self.tr("Attribute Filter Customization"), + self.tr("New Custom Attribute Filter"), + widget, + ) - def addFilterWidget(self,uiParameterJsonDict=None): - widget = ChangeFilterWidget(self.abstractDb,uiParameterJsonDict = uiParameterJsonDict) - self.addWidgetItem(self.tr('Attribute Filter Customization'), self.tr('New Custom Attribute Filter'), widget) - def addWidget(self, widget, title): layout = QtGui.QFormLayout() layout.addRow(widget) @@ -181,15 +271,15 @@ def addWidget(self, widget, title): groupBox.setLayout(layout) self.scrollAreaLayout.addWidget(groupBox) return groupBox - + def createItem(self, parent, text, column): item = QtWidgets.QTreeWidgetItem(parent) item.setText(column, text) return item - + def getWidgetIndexFromTreeItem(self, treeItem): parent = treeItem.parent() - widgetName = treeItem.text(0) + widgetName = treeItem.text(0) if not parent: return if parent == self.customizationTreeWidget.invisibleRootItem(): @@ -199,23 +289,25 @@ def getWidgetIndexFromTreeItem(self, treeItem): child = parent.child(i) if child.text(0) == widgetName: return i - - @pyqtSlot(bool, name='on_removeSelectedPushButton_clicked') - def removeWidget(self, widgetText = None): + + @pyqtSlot(bool, name="on_removeSelectedPushButton_clicked") + def removeWidget(self, widgetText=None): if not widgetText: treeItemList = [self.customizationTreeWidget.currentItem()] else: - treeItemList = self.customizationTreeWidget.findItems(widgetText, flags = Qt.MatchExactly) - if len(treeItemList)>0: + treeItemList = self.customizationTreeWidget.findItems( + widgetText, flags=Qt.MatchExactly + ) + if len(treeItemList) > 0: for treeItem in treeItemList: parent = treeItem.parent() if parent == self.customizationTreeWidget.invisibleRootItem(): return idx = self.getWidgetIndexFromTreeItem(treeItem) - itemToRemove = self.contentsDict[parent.text(0)]['widgetList'].pop(idx) + itemToRemove = self.contentsDict[parent.text(0)]["widgetList"].pop(idx) itemToRemove.setParent(None) - self.contentsDict[parent.text(0)]['treeItem'].removeChild(treeItem) - + self.contentsDict[parent.text(0)]["treeItem"].removeChild(treeItem) + @pyqtSlot() def on_buttonBox_accepted(self): QApplication.setOverrideCursor(QCursor(Qt.WaitCursor)) @@ -223,80 +315,98 @@ def on_buttonBox_accepted(self): customJsonDict = dict() for i in list(self.customDict.keys()): customJsonDict[i] = [] - correspondenceDict = {self.customDict[i]:i for i in list(self.customDict.keys())} + correspondenceDict = { + self.customDict[i]: i for i in list(self.customDict.keys()) + } nCustom = 0 for key in list(self.contentsDict.keys()): - for widgetItem in self.contentsDict[key]['widgetList']: + for widgetItem in self.contentsDict[key]["widgetList"]: nCustom += 1 - progress = ProgressWidget(1,nCustom,self.tr('Preparing to export customizations... '), parent = self) + progress = ProgressWidget( + 1, nCustom, self.tr("Preparing to export customizations... "), parent=self + ) progress.initBar() for key in list(self.contentsDict.keys()): jsonTagList = [] - for widget in self.contentsDict[key]['widgetList']: - currJsonItem = {'jsonUi':None, 'dbJsonTagList':[]} + for widget in self.contentsDict[key]["widgetList"]: + currJsonItem = {"jsonUi": None, "dbJsonTagList": []} currentWidget = widget.layout().itemAt(0).widget() try: jsonTagList = currentWidget.getJSONTag() jsonUi = currentWidget.getUiParameterJsonDict() except Exception as e: - exceptionList.append(':'.join(e.args)) + exceptionList.append(":".join(e.args)) if len(exceptionList) == 0: - currJsonItem['jsonUi'] = jsonUi + currJsonItem["jsonUi"] = jsonUi for jsonItem in jsonTagList: - if jsonItem not in currJsonItem['dbJsonTagList']: - currJsonItem['dbJsonTagList'].append(jsonItem) + if jsonItem not in currJsonItem["dbJsonTagList"]: + currJsonItem["dbJsonTagList"].append(jsonItem) if currJsonItem not in customJsonDict[correspondenceDict[key]]: customJsonDict[correspondenceDict[key]].append(currJsonItem) progress.step() QApplication.restoreOverrideCursor() if self.validateJsonDict(customJsonDict) and len(exceptionList) == 0: - versionText = 'database_'+self.edgvVersion - finalJsonDict = {versionText:customJsonDict} - self.customizationManager.createSetting(self.customizationName, self.edgvVersion, finalJsonDict) - QMessageBox.information(self, self.tr('Success!'), self.tr('Database Customization ') + self.customizationName + self.tr(' created successfuly!')) - #EMIT to reload? + versionText = "database_" + self.edgvVersion + finalJsonDict = {versionText: customJsonDict} + self.customizationManager.createSetting( + self.customizationName, self.edgvVersion, finalJsonDict + ) + QMessageBox.information( + self, + self.tr("Success!"), + self.tr("Database Customization ") + + self.customizationName + + self.tr(" created successfuly!"), + ) + # EMIT to reload? self.close() else: - msg = '' - if len(exceptionList)> 0: - msg += self.tr('\Errors occured while trying to export customs built. Check qgis log for further details.') + msg = "" + if len(exceptionList) > 0: + msg += self.tr( + "\Errors occured while trying to export customs built. Check qgis log for further details." + ) for error in exceptionList: - QgsMessageLog.logMessage(self.tr('Customization error: ') + error, "DSGTools Plugin", Qgis.Critical) - QMessageBox.warning(self, self.tr('Error!'), msg) - + QgsMessageLog.logMessage( + self.tr("Customization error: ") + error, + "DSGTools Plugin", + Qgis.Critical, + ) + QMessageBox.warning(self, self.tr("Error!"), msg) + def validateJsonDict(self, customJsonDict): """ Method to apply validation to customJsonDict """ - #TODO + # TODO return True def populateWidgetsFromSelectedFile(self): jsonFileName = self.selectFileWidget.fileNameList customJsonDict = self.utils.readJsonFile(jsonFileName) self.createWidgetsFromCustomJsonDict(customJsonDict) - + def createWidgetsFromCustomJsonDict(self, customJsonDict): for key in list(customJsonDict.keys()): for jsonTag in customJsonDict[key]: - self.createWidgetFromKey(key, jsonTag['jsonUi']) - + self.createWidgetFromKey(key, jsonTag["jsonUi"]) + def createWidgetFromKey(self, key, uiParameterJsonDict): - if key == 'attribute': + if key == "attribute": self.addAttributeWidget(uiParameterJsonDict=uiParameterJsonDict) - elif key == 'class': + elif key == "class": self.addClassWidget(uiParameterJsonDict=uiParameterJsonDict) - elif key == 'codeName': + elif key == "codeName": self.addCodeNameWidget(uiParameterJsonDict=uiParameterJsonDict) - elif key == 'default': + elif key == "default": self.addDefaultWidget(uiParameterJsonDict=uiParameterJsonDict) - elif key == 'domain': + elif key == "domain": self.addDomainWidget(uiParameterJsonDict=uiParameterJsonDict) - elif key == 'domainValue': + elif key == "domainValue": self.addDomainValueWidget(uiParameterJsonDict=uiParameterJsonDict) - elif key == 'nullity': + elif key == "nullity": self.addNullityWidget(uiParameterJsonDict=uiParameterJsonDict) - elif key == 'filter': + elif key == "filter": self.addFilterWidget(uiParameterJsonDict=uiParameterJsonDict) else: pass diff --git a/DsgTools/gui/Misc/PostgisCustomization/dbCustomizer.py b/DsgTools/gui/Misc/PostgisCustomization/dbCustomizer.py index 2e5d95e93..77465d78e 100644 --- a/DsgTools/gui/Misc/PostgisCustomization/dbCustomizer.py +++ b/DsgTools/gui/Misc/PostgisCustomization/dbCustomizer.py @@ -20,30 +20,40 @@ * * ***************************************************************************/ """ -#Qt Imports +# Qt Imports from qgis.PyQt.Qt import QObject -#DsgTools Imports -from DsgTools.core.Utils.utils import Utils + +# DsgTools Imports +from DsgTools.core.Utils.utils import Utils from DsgTools.core.Factories.DbFactory.postgisDb import PostgisDb -from DsgTools.gui.Misc.PostgisCustomization.CustomJSONTools.customJSONValidator import CustomJSONValidator -from DsgTools.core.Factories.DbCustomizationFactory.dbCustomizationFactory import DbCustomizationFactory +from DsgTools.gui.Misc.PostgisCustomization.CustomJSONTools.customJSONValidator import ( + CustomJSONValidator, +) +from DsgTools.core.Factories.DbCustomizationFactory.dbCustomizationFactory import ( + DbCustomizationFactory, +) + class DbCustomizer(QObject): def __init__(self): super(DbCustomizer, self).__init__() self.customJSONValidator = None self.dbCustomizationFactory = DbCustomizationFactory() - + def buildCustomizationSQL(self, customJSON): - sql = '' + sql = "" for customizationTag in list(customJSON.keys()): - customCreator = self.dbCustomizationFactory.createCustomization(customizationTag, customJSON[customizationTag]) + customCreator = self.dbCustomizationFactory.createCustomization( + customizationTag, customJSON[customizationTag] + ) sql += customCreator.buildSql() return sql - + def buildUndoCustomizationSQL(self, customJSON): - sql = '' + sql = "" for customizationTag in list(customJSON.keys()): - customCreator = self.dbCustomizationFactory.createCustomization(customizationTag, customJSON[customizationTag]) + customCreator = self.dbCustomizationFactory.createCustomization( + customizationTag, customJSON[customizationTag] + ) sql += customCreator.buildUndoSql() - return sql \ No newline at end of file + return sql diff --git a/DsgTools/gui/Misc/ProcessingTools/processManager.py b/DsgTools/gui/Misc/ProcessingTools/processManager.py index 9238cf85a..1d10e264d 100644 --- a/DsgTools/gui/Misc/ProcessingTools/processManager.py +++ b/DsgTools/gui/Misc/ProcessingTools/processManager.py @@ -30,6 +30,7 @@ from DsgTools.core.Factories.ThreadFactory.threadFactory import ThreadFactory + class ProcessManager(QObject): def __init__(self, iface): """ @@ -83,8 +84,8 @@ def stepProcessed(self, uuid): if not sip.isdeleted(progressBar): progressBar.setValue(progressBar.value() + 1) - @pyqtSlot(int,str,str) - def processFinished( self, feedback, message, uuid): + @pyqtSlot(int, str, str) + def processFinished(self, feedback, message, uuid): """ Finalizes the process feedback: feedback code @@ -101,7 +102,7 @@ def processFinished( self, feedback, message, uuid): if feedback == 1: progressBar.setValue(progressBar.maximum()) - QMessageBox.information(self.iface.mainWindow(), 'DSG Tools', message) + QMessageBox.information(self.iface.mainWindow(), "DSG Tools", message) def prepareProcess(self, process, message): """ @@ -112,67 +113,98 @@ def prepareProcess(self, process, message): # Setting the progress bar progressMessageBar = self.iface.messageBar().createMessage(message) progressBar = QProgressBar() - progressBar.setAlignment(Qt.AlignLeft|Qt.AlignVCenter) + progressBar.setAlignment(Qt.AlignLeft | Qt.AlignVCenter) progressMessageBar.layout().addWidget(progressBar) - self.iface.messageBar().pushWidget(progressMessageBar, self.iface.messageBar().INFO) + self.iface.messageBar().pushWidget( + progressMessageBar, self.iface.messageBar().INFO + ) - #connecting the destroyed signal + # connecting the destroyed signal progressMessageBar.destroyed.connect(process.messenger.progressCanceled) - #storing the process and its related progressBar + # storing the process and its related progressBar self.processDict[process] = progressBar - #initiating processing + # initiating processing QThreadPool.globalInstance().start(process) def createPostgisDatabaseProcess(self, dbName, abstractDb, version, epsg): """ Create the postgis databsae process """ - #creating process - process = self.threadFactory.makeProcess('pgdb') + # creating process + process = self.threadFactory.makeProcess("pgdb") stopped = [False] - process.setParameters(abstractDb,dbName,version,epsg,stopped) - #connecting signal/slots + process.setParameters(abstractDb, dbName, version, epsg, stopped) + # connecting signal/slots process.signals.rangeCalculated.connect(self.setProgressRange) process.signals.stepProcessed.connect(self.stepProcessed) process.signals.processingFinished.connect(self.processFinished) - #preparing the progressBar that will be created + # preparing the progressBar that will be created self.prepareProcess(process, self.tr("Creating database structure...")) - def createDpiProcess(self, filesList, rasterType, minOutValue, maxOutValue, outDir, percent, epsg): + def createDpiProcess( + self, filesList, rasterType, minOutValue, maxOutValue, outDir, percent, epsg + ): """ Creates the digital image process """ - #creating process - process = self.threadFactory.makeProcess('dpi') + # creating process + process = self.threadFactory.makeProcess("dpi") stopped = [False] - process.setParameters(filesList, rasterType, minOutValue, maxOutValue, outDir, percent, epsg, stopped) - - #connecting signal/slots + process.setParameters( + filesList, + rasterType, + minOutValue, + maxOutValue, + outDir, + percent, + epsg, + stopped, + ) + + # connecting signal/slots process.signals.rangeCalculated.connect(self.setProgressRange) process.signals.stepProcessed.connect(self.stepProcessed) process.signals.processingFinished.connect(self.processFinished) - #preparing the progressBar that will be created + # preparing the progressBar that will be created self.prepareProcess(process, self.tr("Processing images...")) - def createInventoryProcess(self, parentFolder, outputFile, makeCopy, destinationFolder, formatsList, isWhitelist, isOnlyGeo): + def createInventoryProcess( + self, + parentFolder, + outputFile, + makeCopy, + destinationFolder, + formatsList, + isWhitelist, + isOnlyGeo, + ): """ Creates the inventory process """ - #creating process - process = self.threadFactory.makeProcess('inventory') + # creating process + process = self.threadFactory.makeProcess("inventory") stopped = [False] - process.setParameters(parentFolder, outputFile, makeCopy, destinationFolder, formatsList, isWhitelist, isOnlyGeo, stopped) - - #connecting signal/slots + process.setParameters( + parentFolder, + outputFile, + makeCopy, + destinationFolder, + formatsList, + isWhitelist, + isOnlyGeo, + stopped, + ) + + # connecting signal/slots process.signals.rangeCalculated.connect(self.setProgressRange) process.signals.stepProcessed.connect(self.stepProcessed) process.signals.processingFinished.connect(self.processFinished) process.signals.loadFile.connect(self.loadInventoryFile) - #preparing the progressBar that will be created + # preparing the progressBar that will be created self.prepareProcess(process, self.tr("Making inventory, please wait...")) @pyqtSlot(str, bool) @@ -183,16 +215,24 @@ def loadInventoryFile(self, outputFile, isOnlyGeo): if not isOnlyGeo: # Adding the layer and making it active url = QUrl.fromLocalFile(outputFile) - url.addQueryItem('delimiter', ',') + url.addQueryItem("delimiter", ",") layer_uri = str(url.toEncoded()) - layer = self.iface.addVectorLayer(layer_uri, 'Inventory', 'delimitedtext') + layer = self.iface.addVectorLayer(layer_uri, "Inventory", "delimitedtext") else: - layer = self.iface.addVectorLayer(outputFile, 'Inventory', 'ogr') + layer = self.iface.addVectorLayer(outputFile, "Inventory", "ogr") if layer: - self.iface.setActiveLayer(layer) + self.iface.setActiveLayer(layer) # Creating and Attribute Action to load the inventoried file actions = layer.actions() field = '[% "fileName" %]' - actions.addAction(QgsAction.GenericPython, 'Load Vector Layer', 'qgis.utils.iface.addVectorLayer(r\'%s\', \'File\', \'ogr\')' % field) - actions.addAction(QgsAction.GenericPython, 'Load Raster Layer', 'qgis.utils.iface.addRasterLayer(r\'%s\', \'File\')' % field) + actions.addAction( + QgsAction.GenericPython, + "Load Vector Layer", + "qgis.utils.iface.addVectorLayer(r'%s', 'File', 'ogr')" % field, + ) + actions.addAction( + QgsAction.GenericPython, + "Load Raster Layer", + "qgis.utils.iface.addRasterLayer(r'%s', 'File')" % field, + ) diff --git a/DsgTools/gui/Misc/ToolboxTools/models_and_scripts_installer.py b/DsgTools/gui/Misc/ToolboxTools/models_and_scripts_installer.py index c357111d3..24ffab2aa 100644 --- a/DsgTools/gui/Misc/ToolboxTools/models_and_scripts_installer.py +++ b/DsgTools/gui/Misc/ToolboxTools/models_and_scripts_installer.py @@ -31,11 +31,13 @@ from processing.core.Processing import Processing from qgis.core import QgsMessageLog -FORM_CLASS, _ = uic.loadUiType(os.path.join( - os.path.dirname(__file__), 'models_and_scripts_installer.ui')) +FORM_CLASS, _ = uic.loadUiType( + os.path.join(os.path.dirname(__file__), "models_and_scripts_installer.ui") +) currentPath = os.path.dirname(__file__) + class ModelsAndScriptsInstaller(QDialog, FORM_CLASS): def __init__(self): """ @@ -60,7 +62,7 @@ def __del__(self): def createItems(self, widget, names): """ - Create items + Create items """ for name in names: item = QListWidgetItem(widget) @@ -74,9 +76,9 @@ def scanFolder(self, folder, extension): ret = [] for root, dirs, files in os.walk(folder): for file in files: - ext = file.split('.')[-1] + ext = file.split(".")[-1] if ext == extension: - path = os.path.join(root, file.decode(encoding='UTF-8')) + path = os.path.join(root, file.decode(encoding="UTF-8")) ret.append(path) return ret @@ -85,16 +87,16 @@ def getModels(self): """ Get models in the folder """ - modelspath = os.path.join(currentPath, '..', 'QGIS_Models') - extension = 'model' + modelspath = os.path.join(currentPath, "..", "QGIS_Models") + extension = "model" return self.scanFolder(modelspath, extension) def getScripts(self): """ Get scripts in the folder """ - scriptspath = os.path.join(currentPath, '..', 'QGIS_Scripts') - extension = 'py' + scriptspath = os.path.join(currentPath, "..", "QGIS_Scripts") + extension = "py" return self.scanFolder(scriptspath, extension) def copyFiles(self, widget, files, folder): @@ -109,7 +111,11 @@ def copyFiles(self, widget, files, folder): try: shutil.copy2(file, destination) except IOError as e: - QgsMessageLog.logMessage(self.tr('Error copying file: ')+text+'\n'+e.strerror, "DSGTools Plugin", QgsMessageLog.INFO) + QgsMessageLog.logMessage( + self.tr("Error copying file: ") + text + "\n" + e.strerror, + "DSGTools Plugin", + QgsMessageLog.INFO, + ) continue @pyqtSlot(QAbstractButton) @@ -126,7 +132,15 @@ def on_buttonBox_accepted(self): """ Copy the files to the correct location """ - self.copyFiles(self.scriptsList, self.scripts, os.path.join(currentPath, '..', '..', '..', '..', 'processing', 'scripts')) + self.copyFiles( + self.scriptsList, + self.scripts, + os.path.join(currentPath, "..", "..", "..", "..", "processing", "scripts"), + ) Processing.initialize() - self.copyFiles(self.modelsList, self.models, os.path.join(currentPath, '..', '..', '..', '..', 'processing', 'models')) + self.copyFiles( + self.modelsList, + self.models, + os.path.join(currentPath, "..", "..", "..", "..", "processing", "models"), + ) Processing.initialize() diff --git a/DsgTools/gui/ProcessingUI/attributeRulesWrapper.py b/DsgTools/gui/ProcessingUI/attributeRulesWrapper.py index d90a40b35..36c6e1b4a 100644 --- a/DsgTools/gui/ProcessingUI/attributeRulesWrapper.py +++ b/DsgTools/gui/ProcessingUI/attributeRulesWrapper.py @@ -20,34 +20,36 @@ * * ***************************************************************************/ """ -from DsgTools.gui.CustomWidgets.OrderedPropertyWidgets.orderedAttributeRulesWidget import \ - OrderedAttributeRulesWidget +from DsgTools.gui.CustomWidgets.OrderedPropertyWidgets.orderedAttributeRulesWidget import ( + OrderedAttributeRulesWidget, +) from processing.gui.wrappers import WidgetWrapper + class AttributeRulesWrapper(WidgetWrapper): def __init__(self, *args, **kwargs): super(AttributeRulesWrapper, self).__init__(*args, **kwargs) - + def createPanel(self): return OrderedAttributeRulesWidget() - + def createWidget(self): self.panel = self.createPanel() self.panel.dialogType = self.dialogType return self.panel - + def parentLayerChanged(self, layer=None): pass - + def setLayer(self, layer): pass - + def setValue(self, value): pass - + def value(self): return self.panel.getHierarchicalSnapDict() - + def postInitialize(self, wrappers): pass # for wrapper in wrappers: diff --git a/DsgTools/gui/ProcessingUI/colorWidgetWrapper.py b/DsgTools/gui/ProcessingUI/colorWidgetWrapper.py index ffab7781a..5513f0137 100644 --- a/DsgTools/gui/ProcessingUI/colorWidgetWrapper.py +++ b/DsgTools/gui/ProcessingUI/colorWidgetWrapper.py @@ -24,29 +24,30 @@ from qgis.PyQt.QtGui import QColor from processing.gui.wrappers import WidgetWrapper + class ColorWidgetWrapper(WidgetWrapper): def __init__(self, *args, **kwargs): super(ColorWidgetWrapper, self).__init__(*args, **kwargs) - + def createPanel(self): return QgsColorButton() - + def createWidget(self): self.panel = self.createPanel() self.panel.dialogType = self.dialogType return self.panel - + def parentLayerChanged(self, layer=None): pass - + def setLayer(self, layer): pass - + def setValue(self, value): self.panel.setColor(value) - + def value(self): return self.panel.color() - + def postInitialize(self, wrappers): pass diff --git a/DsgTools/gui/ProcessingUI/enforceAttributeRulesWrapper.py b/DsgTools/gui/ProcessingUI/enforceAttributeRulesWrapper.py index 6e4a4dd19..e2868055d 100644 --- a/DsgTools/gui/ProcessingUI/enforceAttributeRulesWrapper.py +++ b/DsgTools/gui/ProcessingUI/enforceAttributeRulesWrapper.py @@ -23,21 +23,26 @@ import json from functools import partial -from qgis.core import (QgsProject, QgsVectorLayer) +from qgis.core import QgsProject, QgsVectorLayer from qgis.gui import QgsFieldExpressionWidget from qgis.PyQt.QtCore import Qt -from qgis.PyQt.QtWidgets import (QMessageBox, - QHeaderView, - QComboBox, - QLineEdit) -from processing.gui.wrappers import (WidgetWrapper, - DIALOG_STANDARD, - DIALOG_MODELER, - DIALOG_BATCH) - -from DsgTools.gui.CustomWidgets.OrderedPropertyWidgets.orderedTableWidget import OrderedTableWidget -from DsgTools.gui.CustomWidgets.BasicInterfaceWidgets.colorSelectorWidget import ColorSelectorWidget -from DsgTools.gui.CustomWidgets.BasicInterfaceWidgets.layerAndFieldSelectorWidget import LayerAndFieldSelectorWidget +from qgis.PyQt.QtWidgets import QMessageBox, QHeaderView, QComboBox, QLineEdit +from processing.gui.wrappers import ( + WidgetWrapper, + DIALOG_STANDARD, + DIALOG_MODELER, + DIALOG_BATCH, +) + +from DsgTools.gui.CustomWidgets.OrderedPropertyWidgets.orderedTableWidget import ( + OrderedTableWidget, +) +from DsgTools.gui.CustomWidgets.BasicInterfaceWidgets.colorSelectorWidget import ( + ColorSelectorWidget, +) +from DsgTools.gui.CustomWidgets.BasicInterfaceWidgets.layerAndFieldSelectorWidget import ( + LayerAndFieldSelectorWidget, +) from ...core.Utils.utils import ValidateImportedDataMethods @@ -47,13 +52,13 @@ class EnforceAttributeRulesWrapper(WidgetWrapper): been customized, for a specific type of parameter used in QGIS processing algorithms. """ + __ATTRIBUTE_MAP_VERSION = 0.1 # enum for column ordering STD_COLUMN_COUNT = 5 MODELER_COLUMN_COUNT = 6 descStd, lyrStd, expStd, errStd, colorStd = list(range(STD_COLUMN_COUNT)) - descMd, lyrMd, fldMd, expMd, errMd, colorMd = list( - range(MODELER_COLUMN_COUNT)) + descMd, lyrMd, fldMd, expMd, errMd, colorMd = list(range(MODELER_COLUMN_COUNT)) def __init__(self, *args, **kwargs): """ @@ -95,10 +100,11 @@ def errorTypeComboBox(self): Retrieves the configured error type selection combo box. :return: (QComboBox) configured error selection widget. """ - errorTypeList = ["Atributo de valor incomum", - "Atributo com valor incorreto", - "Preencher atributo", - ] + errorTypeList = [ + "Atributo de valor incomum", + "Atributo com valor incorreto", + "Preencher atributo", + ] cb = QComboBox() cb.addItem(self.tr("Select an error type")) @@ -135,8 +141,7 @@ def getLoadedLayers(self): layers = QgsProject.instance().mapLayers().values() for layer in layers: if layer.type() == 0: - loaded[layer.name()] = [field.name() - for field in layer.fields()] + loaded[layer.name()] = [field.name() for field in layer.fields()] else: pass return loaded @@ -153,8 +158,9 @@ def getUnloadedLayers(self, attrRulesMap): for k, v in attrRulesMap.items(): if k == "metadata": continue - if self.validateMethods.validatePythonTypes(v["1"], "list") and \ - self.validateMethods.validateLengthOfDataTypes(v["1"], 2): + if self.validateMethods.validatePythonTypes( + v["1"], "list" + ) and self.validateMethods.validateLengthOfDataTypes(v["1"], 2): if v["1"][0] not in loadedLyr: unsortedNotLoadedLyr.append(v["1"][0]) @@ -175,12 +181,12 @@ def modifyImportedAttributeRulesMap(self, attrRulesMap): notLoadedLyrWarning = self.showLoadingMsg(notLoadedLyr, "warning") if notLoadedLyrWarning == QMessageBox.Ignore: invalidRulesWarning = self.validateMethods.showLoadingMsg( - invalidRules, "invalid") + invalidRules, "invalid" + ) if invalidRulesWarning == QMessageBox.Ignore: - self.modifyAttributeRulesMap(invalidRulesWarning, - attrRulesMap, - newDict, - notLoadedLyr) + self.modifyAttributeRulesMap( + invalidRulesWarning, attrRulesMap, newDict, notLoadedLyr + ) else: attrRulesMap.clear() else: @@ -188,18 +194,23 @@ def modifyImportedAttributeRulesMap(self, attrRulesMap): elif not notLoadedLyr and invalidRules: invalidRulesWarning = self.validateMethods.showLoadingMsg( - invalidRules, "invalid") + invalidRules, "invalid" + ) self.modifyAttributeRulesMap( - invalidRulesWarning, attrRulesMap, newDict, notLoadedLyr) + invalidRulesWarning, attrRulesMap, newDict, notLoadedLyr + ) elif notLoadedLyr and not invalidRules: notLoadedLyrWarning = self.showLoadingMsg(notLoadedLyr, "warning") self.modifyAttributeRulesMap( - notLoadedLyrWarning, attrRulesMap, newDict, notLoadedLyr) + notLoadedLyrWarning, attrRulesMap, newDict, notLoadedLyr + ) else: self.showLoadingMsg() - def modifyAttributeRulesMap(self, clickedAction, attrRulesMap, newDict, notLoadedLyr): + def modifyAttributeRulesMap( + self, clickedAction, attrRulesMap, newDict, notLoadedLyr + ): """ Modifies the attrRulesMap dict with newDict data. :param clickedAction: (QtAction) clicked button signal. @@ -229,33 +240,64 @@ def mapAttributeRulesToNewDict(self, attrRulesMap): for attrRulesMapKey, attrRulesMapValue in attrRulesMap.items(): if attrRulesMapKey == "metadata": continue - if self.validateMethods.validatePythonTypes(attrRulesMapValue["0"], "string"): - if self.validateMethods.validatePythonTypes(attrRulesMapValue["1"], "list") \ - and self.validateMethods.validateLengthOfDataTypes(attrRulesMapValue["1"], 2): - if self.validateMethods.validateQgsExpressions(attrRulesMapValue["2"]): - if self.validateMethods.validatePythonTypes(attrRulesMapValue["3"], "string"): - if self.validateMethods.validateQColor(attrRulesMapValue["4"]): + if self.validateMethods.validatePythonTypes( + attrRulesMapValue["0"], "string" + ): + if self.validateMethods.validatePythonTypes( + attrRulesMapValue["1"], "list" + ) and self.validateMethods.validateLengthOfDataTypes( + attrRulesMapValue["1"], 2 + ): + if self.validateMethods.validateQgsExpressions( + attrRulesMapValue["2"] + ): + if self.validateMethods.validatePythonTypes( + attrRulesMapValue["3"], "string" + ): + if self.validateMethods.validateQColor( + attrRulesMapValue["4"] + ): newDict[attrRulesMapKey] = attrRulesMapValue else: - invalidRules.append(self.tr( - "Rule number {} : {} - is not a valid color.".format( - attrRulesMapKey, attrRulesMapValue["4"]))) + invalidRules.append( + self.tr( + "Rule number {} : {} - is not a valid color.".format( + attrRulesMapKey, attrRulesMapValue["4"] + ) + ) + ) else: - invalidRules.append(self.tr( - "Rule number {} : {} - is not a valid string.".format( - attrRulesMapKey, attrRulesMapValue["3"]))) + invalidRules.append( + self.tr( + "Rule number {} : {} - is not a valid string.".format( + attrRulesMapKey, attrRulesMapValue["3"] + ) + ) + ) else: - invalidRules.append(self.tr( - "Rule number {} : {} - is not a valid expression.".format( - attrRulesMapKey, attrRulesMapValue["2"]))) + invalidRules.append( + self.tr( + "Rule number {} : {} - is not a valid expression.".format( + attrRulesMapKey, attrRulesMapValue["2"] + ) + ) + ) else: - invalidRules.append(self.tr( - "Rule number {} : {} - is not a valid length = 2 list.".format( - attrRulesMapKey, attrRulesMapValue["1"]))) + invalidRules.append( + self.tr( + "Rule number {} : {} - is not a valid length = 2 list.".format( + attrRulesMapKey, attrRulesMapValue["1"] + ) + ) + ) else: - invalidRules.append(self.tr( - "Rule number {} : {} - is not a valid string description.".format( - attrRulesMapKey, attrRulesMapValue["0"]))) + invalidRules.append( + self.tr( + "Rule number {} : {} - is not a valid string description.".format( + attrRulesMapKey, attrRulesMapValue["0"] + ) + ) + ) return newDict, invalidRules @@ -273,8 +315,7 @@ def modifyImportedAttributeRulesMapToModeler(self, attrRulesMap): for k, v in attrRulesMap.items(): if k == "metadata": continue - if v["1"][0] not in loadedLyr or \ - v["1"][1] not in loadedLyr[v["1"][0]]: + if v["1"][0] not in loadedLyr or v["1"][1] not in loadedLyr[v["1"][0]]: notLoadedLyr.append(v["1"][0]) else: if isinstance(v["1"], (list, tuple)): @@ -313,14 +354,15 @@ def showLoadingMsg(self, lyrList=None, msgType=None): msg.setIcon(QMessageBox.Warning) msg.setText(self.tr("Some rules have not been loaded")) msg.setInformativeText( - self.tr("Do you want to ignore and continue or cancel?")) + self.tr("Do you want to ignore and continue or cancel?") + ) textLyrList = sorted(set(lyrList)) formatedLyrList = ["{}" for item in textLyrList] msgString = ",".join(formatedLyrList).replace(",", "\n") formatedMsgString = self.tr( - "The following layers have not been loaded:\n") + \ - msgString.format(*textLyrList) + "The following layers have not been loaded:\n" + ) + msgString.format(*textLyrList) msg.setDetailedText(formatedMsgString) msg.setStandardButtons(QMessageBox.Ignore | QMessageBox.Cancel) @@ -380,48 +422,51 @@ def standardPanel(self): Returns the table prepared for the standard Processing GUI. :return: (OrderedTableWidget) DSGTools customized table widget. """ - otw = OrderedTableWidget(headerMap={ - 0: { - "header": self.tr("Description"), - "type": "widget", - "widget": lambda: self.stringDataWidget(self.tr( - "Set a name for this attribute rule...")), - "setter": "setText", - "getter": "text" - }, - 1: { - "header": self.tr("Layer and field"), - "type": "widget", - "widget": self.mapLyrAndFieldComboBox, - "setter": "setCurrentInfo", - "getter": "getCurrentInfo" - }, - 2: { - "header": self.tr("Expression"), - "type": "widget", - "widget": self.filterExpressionWidget, - "setter": "setExpression", - "getter": "currentText" - }, - 3: { - "header": self.tr("Error type"), - "type": "widget", - "widget": self.errorTypeComboBox, - "setter": "setCurrentText", - "getter": "currentText" - }, - 4: { - "header": self.tr("Color"), - "type": "widget", - "widget": self.colorSelectionWidget, - "setter": "setCurrentColor", - "getter": "getCurrentColor" - }, - - }) + otw = OrderedTableWidget( + headerMap={ + 0: { + "header": self.tr("Description"), + "type": "widget", + "widget": lambda: self.stringDataWidget( + self.tr("Set a name for this attribute rule...") + ), + "setter": "setText", + "getter": "text", + }, + 1: { + "header": self.tr("Layer and field"), + "type": "widget", + "widget": self.mapLyrAndFieldComboBox, + "setter": "setCurrentInfo", + "getter": "getCurrentInfo", + }, + 2: { + "header": self.tr("Expression"), + "type": "widget", + "widget": self.filterExpressionWidget, + "setter": "setExpression", + "getter": "currentText", + }, + 3: { + "header": self.tr("Error type"), + "type": "widget", + "widget": self.errorTypeComboBox, + "setter": "setCurrentText", + "getter": "currentText", + }, + 4: { + "header": self.tr("Color"), + "type": "widget", + "widget": self.colorSelectionWidget, + "setter": "setCurrentColor", + "getter": "getCurrentColor", + }, + } + ) for row in [1, 3, 4]: otw.horizontalHeader().setSectionResizeMode( - row, QHeaderView.ResizeToContents) + row, QHeaderView.ResizeToContents + ) otw.setHeaderDoubleClickBehaviour("order") otw.dataLoaded.connect(self.modifyImportedAttributeRulesMap) otw.rowAdded.connect(self.postAddRowStandard) @@ -439,85 +484,89 @@ def modelerPanel(self): Returns the table prepared for the modeler Processing GUI. :return: (OrderedTableWidget) DSGTools customized table widget. """ - otw = OrderedTableWidget(headerMap={ - 0: { - "header": self.tr("Rule description"), - "type": "widget", - "widget": lambda: self.stringDataWidget(self.tr( - "Set a name for this attribute rule...")), - "setter": "setText", - "getter": "text" - }, - 1: { - "header": self.tr("Layer"), - "type": "widget", - "widget": lambda: self.stringDataWidget(self.tr( - "Type a vector layer name...")), - "setter": "setText", - "getter": "text" - }, - 2: { - "header": self.tr("Field"), - "type": "widget", - "widget": lambda: self.stringDataWidget(self.tr( - "Type a field layer name...")), - "setter": "setText", - "getter": "text" - }, - 3: { - "header": self.tr("Expression"), - "type": "widget", - "widget": self.filterExpressionWidget, - "setter": "setExpression", - "getter": "currentText" - }, - 4: { - "header": self.tr("Error type"), - "type": "widget", - "widget": lambda: self.stringDataWidget(self.tr( - "Type an error type...")), - "setter": "setText", - "getter": "text" - }, - 5: { - "header": self.tr("Color"), - "type": "widget", - "widget": self.colorSelectionWidget, - "setter": "setCurrentColor", - "getter": "getCurrentColor" + otw = OrderedTableWidget( + headerMap={ + 0: { + "header": self.tr("Rule description"), + "type": "widget", + "widget": lambda: self.stringDataWidget( + self.tr("Set a name for this attribute rule...") + ), + "setter": "setText", + "getter": "text", + }, + 1: { + "header": self.tr("Layer"), + "type": "widget", + "widget": lambda: self.stringDataWidget( + self.tr("Type a vector layer name...") + ), + "setter": "setText", + "getter": "text", + }, + 2: { + "header": self.tr("Field"), + "type": "widget", + "widget": lambda: self.stringDataWidget( + self.tr("Type a field layer name...") + ), + "setter": "setText", + "getter": "text", + }, + 3: { + "header": self.tr("Expression"), + "type": "widget", + "widget": self.filterExpressionWidget, + "setter": "setExpression", + "getter": "currentText", + }, + 4: { + "header": self.tr("Error type"), + "type": "widget", + "widget": lambda: self.stringDataWidget( + self.tr("Type an error type...") + ), + "setter": "setText", + "getter": "text", + }, + 5: { + "header": self.tr("Color"), + "type": "widget", + "widget": self.colorSelectionWidget, + "setter": "setCurrentColor", + "getter": "getCurrentColor", + }, } - }) + ) otw.setHeaderDoubleClickBehaviour("order") - otw.dataLoaded.connect(self. modifyImportedAttributeRulesMapToModeler) + otw.dataLoaded.connect(self.modifyImportedAttributeRulesMapToModeler) otw.rowAdded.connect(self.postAddRowModeler) return otw def createPanel(self): - """ Docstring """ + """Docstring""" return { DIALOG_MODELER: self.modelerPanel, # DIALOG_MODELER: self.standardPanel, DIALOG_STANDARD: self.standardPanel, - DIALOG_BATCH: self.batchPanel + DIALOG_BATCH: self.batchPanel, }[self.dialogType]() def createWidget(self): - """ Docstring """ + """Docstring""" self.panel = self.createPanel() self.panel.showSaveLoadButtons(True) self.panel.extension = ".json" self.panel.fileType = self.tr("Set of DSGTools Attribute Rules") - self.panel.setMetadata({ - "version": self.__ATTRIBUTE_MAP_VERSION - }) + self.panel.setMetadata({"version": self.__ATTRIBUTE_MAP_VERSION}) return self.panel def parentLayerChanged(self, layer=None): - """ Docstring """ + """Docstring""" pass def setLayer(self, layer): - """ Docstring """ + """Docstring""" pass def setValue(self, value): @@ -528,13 +577,15 @@ def setValue(self, value): if value is None: return for valueMap in value: - self.panel.addRow({ - 0: valueMap["description"], - 1: valueMap["layerField"], - 2: valueMap["expression"], - 3: valueMap["errorType"], - 4: valueMap["color"], - }) + self.panel.addRow( + { + 0: valueMap["description"], + 1: valueMap["layerField"], + 2: valueMap["expression"], + 3: valueMap["errorType"], + 4: valueMap["color"], + } + ) def readStandardPanel(self): """ @@ -564,8 +615,10 @@ def readModelerPanel(self): for row in range(self.panel.rowCount()): values = dict() values["description"] = self.panel.getValue(row, 0).strip() - values["layerField"] = [self.panel.getValue(row, 1), - self.panel.getValue(row, 2)] + values["layerField"] = [ + self.panel.getValue(row, 1), + self.panel.getValue(row, 2), + ] values["expression"] = self.panel.getValue(row, 3) values["errorType"] = self.panel.getValue(row, 4) values["color"] = self.panel.getValue(row, 5) @@ -588,9 +641,9 @@ def value(self): return { DIALOG_STANDARD: self.readStandardPanel, DIALOG_MODELER: self.readModelerPanel, - DIALOG_BATCH: self.readBatchPanel + DIALOG_BATCH: self.readBatchPanel, }[self.dialogType]() def postInitialize(self, wrappers): - """ Docstring """ + """Docstring""" pass diff --git a/DsgTools/gui/ProcessingUI/enforceSpatialRuleWrapper.py b/DsgTools/gui/ProcessingUI/enforceSpatialRuleWrapper.py index 580c2d399..f20c269e1 100644 --- a/DsgTools/gui/ProcessingUI/enforceSpatialRuleWrapper.py +++ b/DsgTools/gui/ProcessingUI/enforceSpatialRuleWrapper.py @@ -27,25 +27,32 @@ from qgis.gui import QgsMessageBar, QgsMapLayerComboBox, QgsFieldExpressionWidget from qgis.PyQt.QtCore import QSize, QRegExp from qgis.PyQt.QtGui import QRegExpValidator -from qgis.PyQt.QtWidgets import (QWidget, - QCheckBox, - QComboBox, - QLineEdit, - QVBoxLayout, - QMessageBox) -from processing.gui.wrappers import (WidgetWrapper, - DIALOG_STANDARD, - DIALOG_MODELER, - DIALOG_BATCH) - -from DsgTools.core.GeometricTools\ - .spatialRelationsHandler import (SpatialRule, - SpatialRelationsHandler) -from DsgTools.gui.CustomWidgets.OrderedPropertyWidgets\ - .orderedTableWidget import OrderedTableWidget +from qgis.PyQt.QtWidgets import ( + QWidget, + QComboBox, + QLineEdit, + QVBoxLayout, + QMessageBox, +) +from processing.gui.wrappers import ( + WidgetWrapper, + DIALOG_STANDARD, + DIALOG_MODELER, + DIALOG_BATCH, +) + +from DsgTools.core.GeometricTools.spatialRelationsHandler import ( + SpatialRule, + SpatialRelationsHandler, +) +from DsgTools.gui.CustomWidgets.OrderedPropertyWidgets.orderedTableWidget import ( + OrderedTableWidget, +) + class EnforceSpatialRuleWrapper(WidgetWrapper): __ATTRIBUTE_MAP_VERSION = 0.2 + def __init__(self, *args, **kwargs): super(EnforceSpatialRuleWrapper, self).__init__(*args, **kwargs) self.messageBar = QgsMessageBar(self.panel) @@ -56,12 +63,7 @@ def resizeEvent(self, e): """ Resize QgsMessageBar to widget's width """ - self.messageBar.resize( - QSize( - self.panel.parent().geometry().size().width(), - 30 - ) - ) + self.messageBar.resize(QSize(self.panel.parent().geometry().size().width(), 30)) def ruleNameWidget(self): """ @@ -75,7 +77,7 @@ def ruleNameWidget(self): def mapLayerComboBox(self): """ Retrieves the configured map layer selection combo box. - :return: (QgsMapLayerComboBox) configured layer selection widget. + :return: (QgsMapLayerComboBox) configured layer selection widget. """ cb = QgsMapLayerComboBox() cb.setFilters(QgsMapLayerProxyModel.VectorLayer) @@ -97,6 +99,7 @@ def filterExpressionWidget(self): :return: (QgsFieldExpressionWidget) snap mode selection widget. """ fe = QgsFieldExpressionWidget() + def setValueProxy(exp): layer = fe.layer() if layer and exp.strip() in layer.fields().names(): @@ -105,12 +108,14 @@ def setValueProxy(exp): # crash when running the algorithm. this seems to solve it. exp = "" fe.setExpression(exp) + def getValueProxy(): layer = fe.layer() exp = fe.currentText() if layer and exp.strip() in layer.fields().names(): exp = "" return exp + fe.setExpression_ = setValueProxy fe.currentText_ = getValueProxy return fe @@ -121,9 +126,7 @@ def predicateComboBox(self): :return: (QComboBox) a combo box with all available predicates. """ cb = QComboBox() - cb.addItems( - list(SpatialRelationsHandler().availablePredicates().values()) - ) + cb.addItems(list(SpatialRelationsHandler().availablePredicates().values())) return cb def de9imWidget(self): @@ -149,13 +152,15 @@ def cardinalityWidget(self): le.setPlaceholderText("1..*") return le - def useDE9IM(self): - """ - Identifies whether user chose to input predicate as a DE-9IM mask. - :return: (bool) whether GUI should handle the DE-9IM mask widget over - the combo box selection. - """ - return self.panel.cb.isChecked() + def _check_de9im_is_available(self, row): + otw = self.panel.otw + predicate = otw.getValue(row, 3) + handler = SpatialRelationsHandler() + enableDE9IM = predicate == handler.DE9IM + otw.itemAt(row, 4).setEnabled(enableDE9IM) + if not enableDE9IM: + otw.setValue(row, 4, "") + return enableDE9IM def _checkCardinalityAvailability(self, row): """ @@ -166,19 +171,19 @@ def _checkCardinalityAvailability(self, row): :return: (bool) whether cardinality is available """ otw = self.panel.otw - if self.useDE9IM(): - # if user is using the DE-9IM input, cardinality won't be - # managed - otw.itemAt(row, 7).setEnabled(True) - return True predicate = otw.getValue(row, 3) handler = SpatialRelationsHandler() noCardinality = predicate in ( - handler.DISJOINT, handler.NOTEQUALS, handler.NOTINTERSECTS, - handler.NOTTOUCHES, handler.NOTCROSSES, handler.NOTWITHIN, - handler.NOTOVERLAPS, handler.NOTCONTAINS + handler.DISJOINT, + handler.NOTEQUALS, + handler.NOTINTERSECTS, + handler.NOTTOUCHES, + handler.NOTCROSSES, + handler.NOTWITHIN, + handler.NOTOVERLAPS, + handler.NOTCONTAINS, ) - otw.itemAt(row, 7).setEnabled(not noCardinality) + otw.itemAt(row, 7).setEnabled(noCardinality) if noCardinality: otw.setValue(row, 7, "") return not noCardinality @@ -209,6 +214,10 @@ def postAddRowStandard(self, row): ) # also triggers the action for the first time it is open self._checkCardinalityAvailability(row) + predicateWidget.currentIndexChanged.connect( + partial(self._check_de9im_is_available, row) + ) + self._check_de9im_is_available(row) def postAddRowModeler(self, row): """ @@ -216,6 +225,7 @@ def postAddRowModeler(self, row): :param row: (int) row to have its widgets setup. """ otw = self.panel.otw + def checkLayerBeforeConnect(le, filterExp): lName = le.text().strip() for layer in QgsProject.instance().mapLayersByName(lName): @@ -223,6 +233,7 @@ def checkLayerBeforeConnect(le, filterExp): filterExp.setLayer(layer) return filterExp.setLayer(None) + for col in [1, 5]: le = otw.itemAt(row, col) filterWidget = otw.itemAt(row, col + 1) @@ -234,6 +245,10 @@ def checkLayerBeforeConnect(le, filterExp): partial(self._checkCardinalityAvailability, row) ) self._checkCardinalityAvailability(row) + predicateWidget.currentIndexChanged.connect( + partial(self._check_de9im_is_available, row) + ) + self._check_de9im_is_available(row) def standardPanel(self): """ @@ -243,78 +258,67 @@ def standardPanel(self): widget = QWidget() layout = QVBoxLayout() # added as an attribute in order to make it easier to be read - widget.cb = QCheckBox() - widget.cb.setText(self.tr("Use DE-9IM inputs")) - layout.addWidget(widget.cb) - widget.otw = OrderedTableWidget(headerMap={ - 0 : { - "header" : self.tr("Rule name"), - "type" : "widget", - "widget" : self.ruleNameWidget, - "setter" : "setText", - "getter" : "text" - }, - 1 : { - "header" : self.tr("Layer A"), - "type" : "widget", - "widget" : self.mapLayerComboBox, - "setter" : "setCurrentText", - "getter" : "currentText" - }, - 2 : { - "header" : self.tr("Filter A"), - "type" : "widget", - "widget" : self.filterExpressionWidget, - "setter" : "setExpression_", - "getter" : "currentText_" - }, - 3 : { - "header" : self.tr("Predicate"), - "type" : "widget", - "widget" : self.predicateComboBox, - "setter" : "setCurrentIndex", - "getter" : "currentIndex" - }, - 4 : { - "header" : self.tr("DE-9IM mask predicate"), - "type" : "widget", - "widget" : self.de9imWidget, - "setter" : "setText", - "getter" : "text" - }, - 5 : { - "header" : self.tr("Layer B"), - "type" : "widget", - "widget" : self.mapLayerComboBox, - "setter" : "setCurrentText", - "getter" : "currentText" - }, - 6 : { - "header" : self.tr("Filter B"), - "type" : "widget", - "widget" : self.filterExpressionWidget, - "setter" : "setExpression_", - "getter" : "currentText_" - }, - 7 : { - "header" : self.tr("Cardinality"), - "type" : "widget", - "widget" : self.cardinalityWidget, - "setter" : "setText", - "getter" : "text" + widget.otw = OrderedTableWidget( + headerMap={ + 0: { + "header": self.tr("Rule name"), + "type": "widget", + "widget": self.ruleNameWidget, + "setter": "setText", + "getter": "text", + }, + 1: { + "header": self.tr("Layer A"), + "type": "widget", + "widget": self.mapLayerComboBox, + "setter": "setCurrentText", + "getter": "currentText", + }, + 2: { + "header": self.tr("Filter A"), + "type": "widget", + "widget": self.filterExpressionWidget, + "setter": "setExpression_", + "getter": "currentText_", + }, + 3: { + "header": self.tr("Predicate"), + "type": "widget", + "widget": self.predicateComboBox, + "setter": "setCurrentIndex", + "getter": "currentIndex", + }, + 4: { + "header": self.tr("DE-9IM mask predicate"), + "type": "widget", + "widget": self.de9imWidget, + "setter": "setText", + "getter": "text", + }, + 5: { + "header": self.tr("Layer B"), + "type": "widget", + "widget": self.mapLayerComboBox, + "setter": "setCurrentText", + "getter": "currentText", + }, + 6: { + "header": self.tr("Filter B"), + "type": "widget", + "widget": self.filterExpressionWidget, + "setter": "setExpression_", + "getter": "currentText_", + }, + 7: { + "header": self.tr("Cardinality"), + "type": "widget", + "widget": self.cardinalityWidget, + "setter": "setText", + "getter": "text", + }, } - }) - def handlePredicateColumns(checked): - """ - Predicate input widgets are mutually exclusively: the user may only - input data through either of them. This method manages hiding and - showing correct columns in accord to the user selection. - :param checked: (bool) whether the DE-9IM usage checkbox is ticked. - """ - widget.otw.tableWidget.hideColumn(3 if checked else 4) - widget.otw.tableWidget.showColumn(4 if checked else 3) - widget.cb.toggled.connect(handlePredicateColumns) - widget.cb.toggled.emit(widget.cb.isChecked()) + ) + widget.otw.setHeaderDoubleClickBehaviour("replicate") widget.otw.rowAdded.connect(self.postAddRowStandard) layout.addWidget(widget.otw) @@ -336,78 +340,67 @@ def modelerPanel(self): widget = QWidget() layout = QVBoxLayout() # added as an attribute in order to make it easier to be read - widget.cb = QCheckBox() - widget.cb.setText(self.tr("Use DE-9IM inputs")) - layout.addWidget(widget.cb) - widget.otw = OrderedTableWidget(headerMap={ - 0 : { - "header" : self.tr("Rule name"), - "type" : "widget", - "widget" : self.ruleNameWidget, - "setter" : "setText", - "getter" : "text" - }, - 1 : { - "header" : self.tr("Layer A"), - "type" : "widget", - "widget" : self.mapLayerModelDialog, - "setter" : "setText", - "getter" : "text" - }, - 2 : { - "header" : self.tr("Filter A"), - "type" : "widget", - "widget" : self.filterExpressionWidget, - "setter" : "setExpression_", - "getter" : "currentText_" - }, - 3 : { - "header" : self.tr("Predicate"), - "type" : "widget", - "widget" : self.predicateComboBox, - "setter" : "setCurrentIndex", - "getter" : "currentIndex" - }, - 4 : { - "header" : self.tr("DE-9IM mask predicate"), - "type" : "widget", - "widget" : self.de9imWidget, - "setter" : "setText", - "getter" : "text" - }, - 5 : { - "header" : self.tr("Layer B"), - "type" : "widget", - "widget" : self.mapLayerModelDialog, - "setter" : "setText", - "getter" : "text" - }, - 6 : { - "header" : self.tr("Filter B"), - "type" : "widget", - "widget" : self.filterExpressionWidget, - "setter" : "setExpression_", - "getter" : "currentText_" - }, - 7 : { - "header" : self.tr("Cardinality"), - "type" : "widget", - "widget" : self.cardinalityWidget, - "setter" : "setText", - "getter" : "text" + widget.otw = OrderedTableWidget( + headerMap={ + 0: { + "header": self.tr("Rule name"), + "type": "widget", + "widget": self.ruleNameWidget, + "setter": "setText", + "getter": "text", + }, + 1: { + "header": self.tr("Layer A"), + "type": "widget", + "widget": self.mapLayerModelDialog, + "setter": "setText", + "getter": "text", + }, + 2: { + "header": self.tr("Filter A"), + "type": "widget", + "widget": self.filterExpressionWidget, + "setter": "setExpression_", + "getter": "currentText_", + }, + 3: { + "header": self.tr("Predicate"), + "type": "widget", + "widget": self.predicateComboBox, + "setter": "setCurrentIndex", + "getter": "currentIndex", + }, + 4: { + "header": self.tr("DE-9IM mask predicate"), + "type": "widget", + "widget": self.de9imWidget, + "setter": "setText", + "getter": "text", + }, + 5: { + "header": self.tr("Layer B"), + "type": "widget", + "widget": self.mapLayerModelDialog, + "setter": "setText", + "getter": "text", + }, + 6: { + "header": self.tr("Filter B"), + "type": "widget", + "widget": self.filterExpressionWidget, + "setter": "setExpression_", + "getter": "currentText_", + }, + 7: { + "header": self.tr("Cardinality"), + "type": "widget", + "widget": self.cardinalityWidget, + "setter": "setText", + "getter": "text", + }, } - }) - def handlePredicateColumns(checked): - """ - Predicate input widgets are mutually exclusively: the user may only - input data through either of them. This method manages hiding and - showing correct columns in accord to the user selection. - :param checked: (bool) whether the DE-9IM usage checkbox is ticked. - """ - widget.otw.tableWidget.hideColumn(3 if checked else 4) - widget.otw.tableWidget.showColumn(4 if checked else 3) - widget.cb.toggled.connect(handlePredicateColumns) - widget.cb.toggled.emit(widget.cb.isChecked()) + ) + widget.otw.setHeaderDoubleClickBehaviour("replicate") widget.otw.rowAdded.connect(self.postAddRowModeler) layout.addWidget(widget.otw) @@ -416,24 +409,22 @@ def handlePredicateColumns(checked): def createPanel(self): return { - DIALOG_MODELER : self.modelerPanel, - DIALOG_STANDARD : self.standardPanel, - DIALOG_BATCH : self.batchPanel + DIALOG_MODELER: self.modelerPanel, + DIALOG_STANDARD: self.standardPanel, + DIALOG_BATCH: self.batchPanel, }[self.dialogType]() - + def createWidget(self): self.panel = self.createPanel() self.panel.otw.showSaveLoadButtons(True) self.panel.otw.extension = ".rules" self.panel.otw.fileType = self.tr("Set of DSGTools Spatial Rules") - self.panel.otw.setMetadata({ - "version": self.__ATTRIBUTE_MAP_VERSION - }) + self.panel.otw.setMetadata({"version": self.__ATTRIBUTE_MAP_VERSION}) return self.panel - + def parentLayerChanged(self, layer=None): pass - + def setLayer(self, layer): pass @@ -452,7 +443,8 @@ def showLoadingMsg(self, invalidRules=None, msgType=None): msg.setIcon(QMessageBox.Warning) msg.setText(self.tr("Some rules have not been loaded")) msg.setInformativeText( - self.tr("Do you want to ignore and continue or cancel?")) + self.tr("Do you want to ignore and continue or cancel?") + ) msgString = "\n".join((r.ruleName() for r in invalidRules)) formatedMsgString = self.tr( "The following layers have not been loaded:\n{0}" @@ -474,10 +466,6 @@ def setValue(self, value): if not value: return otw = self.panel.otw - useDE9IM = value[0].get("useDE9IM", False) - self.panel.cb.setChecked(useDE9IM) - # signal must be triggered to adjust the correct column display - self.panel.cb.toggled.emit(useDE9IM) isNotModeler = self.dialogType != DIALOG_MODELER invalids = list() for rule in value: @@ -489,33 +477,36 @@ def setValue(self, value): if not rule.isValid(checkLoaded=isNotModeler): invalids.append(rule) continue - otw.addRow({ - 0: rule.ruleName(), - 1: rule.layerA(), - 2: rule.filterA(), - 3: rule.predicateEnum(), - 4: rule.predicateDE9IM(), - 5: rule.layerB(), - 6: rule.filterB(), - 7: rule.cardinality() - }) + otw.addRow( + { + 0: rule.ruleName(), + 1: rule.layerA(), + 2: rule.filterA(), + 3: rule.predicateEnum(), + 4: rule.predicateDE9IM(), + 5: rule.layerB(), + 6: rule.filterB(), + 7: rule.cardinality(), + } + ) choice = self.showLoadingMsg(invalids, "warning" if invalids else "") if choice == QMessageBox.Cancel: otw.clear() def readStandardPanel(self): """ - Reads widget's contents when process' parameters are set from an + Reads widget's contents when process' parameters are set from an algorithm call (e.g. Processing toolbox). """ ruleList = list() otw = self.panel.otw - useDe9im = self.useDE9IM() + handler = SpatialRelationsHandler() for row in range(otw.rowCount()): + useDE9IM = otw.getValue(row, 3) == handler.DE9IM ruleList.append( SpatialRule( - name=otw.getValue(row, 0).strip(), # or \ - # self.tr("Spatial Rule #{n}".format(n=row + 1)), + name=otw.getValue(row, 0).strip(), # or \ + # self.tr("Spatial Rule #{n}".format(n=row + 1)), layer_a=otw.getValue(row, 1), filter_a=otw.getValue(row, 2), predicate=otw.getValue(row, 3), @@ -523,8 +514,8 @@ def readStandardPanel(self): layer_b=otw.getValue(row, 5), filter_b=otw.getValue(row, 6), cardinality=otw.getValue(row, 7) or "1..*", - useDE9IM=useDe9im, - checkLoadedLayer=False + useDE9IM=useDE9IM, + checkLoadedLayer=False, ).asDict() ) return ruleList @@ -551,16 +542,16 @@ def validate(self, pushAlert=False): :return: (bool) whether set of filled parameters if valid. """ inputMap = { - DIALOG_STANDARD : self.readStandardPanel, - DIALOG_MODELER : self.readModelerPanel, - DIALOG_BATCH : self.readBatchPanel + DIALOG_STANDARD: self.readStandardPanel, + DIALOG_MODELER: self.readModelerPanel, + DIALOG_BATCH: self.readBatchPanel, }[self.dialogType]() if len(inputMap) == 0: if pushAlert: self.messageBar.pushMessage( self.tr("Please provide at least 1 spatial rule."), level=Qgis.Warning, - duration=5 + duration=5, ) return False for row, rule in enumerate(inputMap): @@ -569,10 +560,9 @@ def validate(self, pushAlert=False): if not rule.isValid(): if pushAlert: self.messageBar.pushMessage( - self.tr("{0} (row {1}).")\ - .format(rule.validate(), row + 1), + self.tr("{0} (row {1}).").format(rule.validate(), row + 1), level=Qgis.Warning, - duration=5 + duration=5, ) return False return True @@ -584,10 +574,10 @@ def value(self): """ if self.validate(pushAlert=True): return { - DIALOG_STANDARD : self.readStandardPanel, - DIALOG_MODELER : self.readModelerPanel, - DIALOG_BATCH : self.readBatchPanel + DIALOG_STANDARD: self.readStandardPanel, + DIALOG_MODELER: self.readModelerPanel, + DIALOG_BATCH: self.readBatchPanel, }[self.dialogType]() - + def postInitialize(self, wrappers): pass diff --git a/DsgTools/gui/ProcessingUI/fmeManagerWrapper.py b/DsgTools/gui/ProcessingUI/fmeManagerWrapper.py index 721aa943c..080acff47 100644 --- a/DsgTools/gui/ProcessingUI/fmeManagerWrapper.py +++ b/DsgTools/gui/ProcessingUI/fmeManagerWrapper.py @@ -20,34 +20,36 @@ * * ***************************************************************************/ """ -from DsgTools.gui.CustomWidgets.ProcessingParameterWidgets.fmeManagerWidget import \ - FMEManagerWidget +from DsgTools.gui.CustomWidgets.ProcessingParameterWidgets.fmeManagerWidget import ( + FMEManagerWidget, +) from processing.gui.wrappers import WidgetWrapper + class FMEManagerWrapper(WidgetWrapper): def __init__(self, *args, **kwargs): super(FMEManagerWrapper, self).__init__(*args, **kwargs) - + def createPanel(self): return FMEManagerWidget() - + def createWidget(self): self.panel = self.createPanel() self.panel.dialogType = self.dialogType return self.panel - + def parentLayerChanged(self, layer=None): pass - + def setLayer(self, layer): pass - + def setValue(self, value): pass - + def value(self): return self.panel.getParameters() - + def postInitialize(self, wrappers): pass # for wrapper in wrappers: diff --git a/DsgTools/gui/ProcessingUI/fontWidgetWrapper.py b/DsgTools/gui/ProcessingUI/fontWidgetWrapper.py index 3b001bc52..4434900f7 100644 --- a/DsgTools/gui/ProcessingUI/fontWidgetWrapper.py +++ b/DsgTools/gui/ProcessingUI/fontWidgetWrapper.py @@ -24,29 +24,30 @@ from processing.gui.wrappers import WidgetWrapper from qgis.PyQt.QtGui import QFont + class FontWidgetWrapper(WidgetWrapper): def __init__(self, *args, **kwargs): super(FontWidgetWrapper, self).__init__(*args, **kwargs) - + def createPanel(self): return QFontComboBox() - + def createWidget(self): self.panel = self.createPanel() self.panel.dialogType = self.dialogType return self.panel - + def parentLayerChanged(self, layer=None): pass - + def setLayer(self, layer): pass - + def setValue(self, value): self.panel.setCurrentFont(value) - + def value(self): return self.panel.currentFont() - + def postInitialize(self, wrappers): pass diff --git a/DsgTools/gui/ProcessingUI/snapHierarchyWrapper.py b/DsgTools/gui/ProcessingUI/snapHierarchyWrapper.py index 2b8e64eb5..bb8cb83b1 100644 --- a/DsgTools/gui/ProcessingUI/snapHierarchyWrapper.py +++ b/DsgTools/gui/ProcessingUI/snapHierarchyWrapper.py @@ -22,15 +22,18 @@ """ from qgis.gui import QgsMapLayerComboBox -from qgis.PyQt.QtWidgets import (QComboBox, - QLineEdit, - QDoubleSpinBox) -from processing.gui.wrappers import (WidgetWrapper, - DIALOG_STANDARD, - DIALOG_MODELER, - DIALOG_BATCH) +from qgis.PyQt.QtWidgets import QComboBox, QLineEdit, QDoubleSpinBox +from processing.gui.wrappers import ( + WidgetWrapper, + DIALOG_STANDARD, + DIALOG_MODELER, + DIALOG_BATCH, +) + +from DsgTools.gui.CustomWidgets.OrderedPropertyWidgets.orderedTableWidget import ( + OrderedTableWidget, +) -from DsgTools.gui.CustomWidgets.OrderedPropertyWidgets.orderedTableWidget import OrderedTableWidget class SnapHierarchyWrapper(WidgetWrapper): def __init__(self, *args, **kwargs): @@ -39,15 +42,15 @@ def __init__(self, *args, **kwargs): def mapLayerComboBox(self): """ Retrieves the configured map layer selection combo box. - :return: (QgsMapLayerComboBox) configured layer selection widget. + :return: (QgsMapLayerComboBox) configured layer selection widget. """ cb = QgsMapLayerComboBox() return cb - + def doubleSpinBox(self): """ Retrieves the configured map layer selection combo box. - :return: (QgsMapLayerComboBox) configured layer selection widget. + :return: (QgsMapLayerComboBox) configured layer selection widget. """ sb = QDoubleSpinBox() sb.setDecimals(10) @@ -69,15 +72,17 @@ def modeComboBox(self): :return: (QComboBox) snap mode selection widget. """ cb = QComboBox() - cb.addItems([ - self.tr("Prefer aligning nodes, insert extra vertices where required"), - self.tr("Prefer closest point, insert extra vertices where required"), - self.tr("Prefer aligning nodes, don't insert new vertices"), - self.tr("Prefer closest point, don't insert new vertices"), - self.tr("Move end points only, prefer aligning nodes"), - self.tr("Move end points only, prefer closest point"), - self.tr("Snap end points to end points only") - ]) + cb.addItems( + [ + self.tr("Prefer aligning nodes, insert extra vertices where required"), + self.tr("Prefer closest point, insert extra vertices where required"), + self.tr("Prefer aligning nodes, don't insert new vertices"), + self.tr("Prefer closest point, don't insert new vertices"), + self.tr("Move end points only, prefer aligning nodes"), + self.tr("Move end points only, prefer closest point"), + self.tr("Snap end points to end points only"), + ] + ) return cb def standardPanel(self): @@ -85,29 +90,31 @@ def standardPanel(self): Returns the table prepared for the standard Processing GUI. :return: (OrderedTableWidget) DSGTools customized table widget. """ - otw = OrderedTableWidget(headerMap={ - 0 : { - "header" : self.tr("Layer"), - "type" : "widget", - "widget" : self.mapLayerComboBox, - "setter" : "setCurrentText", - "getter" : "currentText" - }, - 1 : { - "header" : self.tr("Snap"), - "type" : "widget", - "widget" : self.doubleSpinBox, - "setter" : "setValue", - "getter" : "value" - }, - 2 : { - "header" : self.tr("Snap mode"), - "type" : "widget", - "widget" : self.modeComboBox, - "setter" : "setCurrentIndex", - "getter" : "currentIndex" + otw = OrderedTableWidget( + headerMap={ + 0: { + "header": self.tr("Layer"), + "type": "widget", + "widget": self.mapLayerComboBox, + "setter": "setCurrentText", + "getter": "currentText", + }, + 1: { + "header": self.tr("Snap"), + "type": "widget", + "widget": self.doubleSpinBox, + "setter": "setValue", + "getter": "value", + }, + 2: { + "header": self.tr("Snap mode"), + "type": "widget", + "widget": self.modeComboBox, + "setter": "setCurrentIndex", + "getter": "currentIndex", + }, } - }) + ) otw.setHeaderDoubleClickBehaviour("replicate") return otw @@ -123,50 +130,52 @@ def modelerPanel(self): Returns the table prepared for the modeler Processing GUI. :return: (OrderedTableWidget) DSGTools customized table widget. """ - otw = OrderedTableWidget(headerMap={ - 0 : { - "header" : self.tr("Layer"), - "type" : "widget", - "widget" : self.mapLayerModelDialog, - "setter" : "setText", - "getter" : "text" - }, - 1 : { - "header" : self.tr("Snap"), - "type" : "widget", - "widget" : self.doubleSpinBox, - "setter" : "setValue", - "getter" : "value" - }, - 2 : { - "header" : self.tr("Snap mode"), - "type" : "widget", - "widget" : self.modeComboBox, - "setter" : "setCurrentIndex", - "getter" : "currentIndex" + otw = OrderedTableWidget( + headerMap={ + 0: { + "header": self.tr("Layer"), + "type": "widget", + "widget": self.mapLayerModelDialog, + "setter": "setText", + "getter": "text", + }, + 1: { + "header": self.tr("Snap"), + "type": "widget", + "widget": self.doubleSpinBox, + "setter": "setValue", + "getter": "value", + }, + 2: { + "header": self.tr("Snap mode"), + "type": "widget", + "widget": self.modeComboBox, + "setter": "setCurrentIndex", + "getter": "currentIndex", + }, } - }) + ) otw.setHeaderDoubleClickBehaviour("replicate") return otw def createPanel(self): return { - DIALOG_MODELER : self.modelerPanel, - DIALOG_STANDARD : self.standardPanel, - DIALOG_BATCH : self.batchPanel + DIALOG_MODELER: self.modelerPanel, + DIALOG_STANDARD: self.standardPanel, + DIALOG_BATCH: self.batchPanel, }[self.dialogType]() - + def createWidget(self): self.panel = self.createPanel() # self.panel.dialogType = self.dialogType return self.panel - + def parentLayerChanged(self, layer=None): pass - + def setLayer(self, layer): pass - + def setValue(self, value): """ Sets back parameters to the GUI. Method reimplementation. @@ -175,27 +184,27 @@ def setValue(self, value): if value is None: return for valueMap in value: - self.panel.addRow({ - 0 : valueMap["referenceLayer"], - 1 : valueMap["snap"], - 2 : valueMap["mode"] - }) + self.panel.addRow( + { + 0: valueMap["referenceLayer"], + 1: valueMap["snap"], + 2: valueMap["mode"], + } + ) def readStandardPanel(self): """ - Reads widget's contents when process' parameters are set from an + Reads widget's contents when process' parameters are set from an algorithm call (e.g. Processing toolbox). """ valueMaplist = list() - layers = [ - self.panel.getValue(r, 0) for r in range(self.panel.rowCount()) - ] + layers = [self.panel.getValue(r, 0) for r in range(self.panel.rowCount())] for row in range(self.panel.rowCount()): values = dict() values["referenceLayer"] = self.panel.getValue(row, 0) values["snap"] = self.panel.getValue(row, 1) values["mode"] = self.panel.getValue(row, 2) - values["snapLayerList"] = [l for l in layers[(row + 1)::]] + values["snapLayerList"] = [l for l in layers[(row + 1) : :]] valueMaplist.append(values) return valueMaplist @@ -219,11 +228,11 @@ def value(self): :return: (dict) value currently set to the GUI. """ return { - DIALOG_STANDARD : self.readStandardPanel, - DIALOG_MODELER : self.readModelerPanel, - DIALOG_BATCH : self.readBatchPanel + DIALOG_STANDARD: self.readStandardPanel, + DIALOG_MODELER: self.readModelerPanel, + DIALOG_BATCH: self.readBatchPanel, }[self.dialogType]() - + def postInitialize(self, wrappers): pass # for wrapper in wrappers: diff --git a/DsgTools/gui/ProductionTools/MapTools/Acquisition/acquisition.py b/DsgTools/gui/ProductionTools/MapTools/Acquisition/acquisition.py index 365a7d1cd..0560fd834 100755 --- a/DsgTools/gui/ProductionTools/MapTools/Acquisition/acquisition.py +++ b/DsgTools/gui/ProductionTools/MapTools/Acquisition/acquisition.py @@ -8,6 +8,7 @@ from .circle import Circle from .polygon import Polygon + class Acquisition(QObject): def __init__(self, iface): super(Acquisition, self).__init__() @@ -17,26 +18,28 @@ def __init__(self, iface): self.polygonAction = None self.circleAction = None self.toolAction = None - + def addTool(self, manager, callback, parentMenu, iconBasePath): - icon_path = iconBasePath + 'home.png' - toolTip = self.tr("DSGTools: Right Degree Angle Digitizing\nControl modifier: disables tool while control is pressed.") + icon_path = iconBasePath + "home.png" + toolTip = self.tr( + "DSGTools: Right Degree Angle Digitizing\nControl modifier: disables tool while control is pressed." + ) action = manager.add_action( icon_path, - text=self.tr('DSGTools: Right Degree Angle Digitizing'), + text=self.tr("DSGTools: Right Degree Angle Digitizing"), callback=self.acquisitionNinetyDegrees, add_to_menu=False, add_to_toolbar=True, - withShortcut = True, - tooltip = toolTip, - parentToolbar =parentMenu - ) + withShortcut=True, + tooltip=toolTip, + parentToolbar=parentMenu, + ) self.setPolygonAction(action) self.toolAction = action def setPolygonAction(self, action): self.polygonAction = action - + def setCircleAction(self, action): self.circleAction = action @@ -45,10 +48,14 @@ def acquisitionNinetyDegrees(self): def acquisitionCircle(self): self.run(Circle, self.circleAction) - + def setToolEnabled(self): - layer = self.iface.activeLayer() - if not isinstance(layer, QgsVectorLayer) or layer.geometryType() == QgsWkbTypes.PointGeometry or not layer.isEditable(): + layer = self.iface.activeLayer() + if ( + not isinstance(layer, QgsVectorLayer) + or layer.geometryType() == QgsWkbTypes.PointGeometry + or not layer.isEditable() + ): enabled = False else: enabled = True @@ -59,22 +66,34 @@ def setToolEnabled(self): if self.circleAction: self.circleAction.setEnabled(enabled) return enabled - + def run(self, func, action): layer = self.canvas.currentLayer() if layer in self.iface.editableLayers(): - if layer.geometryType() in [QgsWkbTypes.LineGeometry , QgsWkbTypes.PolygonGeometry]: + if layer.geometryType() in [ + QgsWkbTypes.LineGeometry, + QgsWkbTypes.PolygonGeometry, + ]: if self.tool: self.tool.deactivate() self.tool = func(self.canvas, self.iface, action) self.tool.setAction(action) self.canvas.setMapTool(self.tool) else: - self.iface.messageBar().pushMessage(self.tr('Warning'), self.tr('Tool not defined for points'), - level=Qgis.Info, duration=3) + self.iface.messageBar().pushMessage( + self.tr("Warning"), + self.tr("Tool not defined for points"), + level=Qgis.Info, + duration=3, + ) self.tool.deactivate() if self.tool else "" else: - self.iface.messageBar().pushMessage(self.tr('Warning'), self.tr('Start editing in current layer!'), level=Qgis.Info, duration=3) + self.iface.messageBar().pushMessage( + self.tr("Warning"), + self.tr("Start editing in current layer!"), + level=Qgis.Info, + duration=3, + ) self.tool.deactivate() if self.tool else "" def unload(self): diff --git a/DsgTools/gui/ProductionTools/MapTools/Acquisition/circle.py b/DsgTools/gui/ProductionTools/MapTools/Acquisition/circle.py index 0b8fb9ee9..06ab05b5a 100755 --- a/DsgTools/gui/ProductionTools/MapTools/Acquisition/circle.py +++ b/DsgTools/gui/ProductionTools/MapTools/Acquisition/circle.py @@ -15,6 +15,7 @@ from qgis.core import QgsPointXY, Qgis, QgsWkbTypes from qgis.gui import QgsMapMouseEvent, QgsMapTool + class Circle(GeometricaAcquisition): def __init__(self, canvas, iface, action): super(Circle, self).__init__(canvas, iface, action) @@ -22,7 +23,7 @@ def __init__(self, canvas, iface, action): self.iface = iface self.rubberBand = None self.initVariable() - + def initVariable(self): if self.rubberBand: self.rubberBand.reset(True) @@ -31,23 +32,27 @@ def initVariable(self): self.endPoint = None self.qntPoint = 0 self.geometry = [] - + def showCircle(self, startPoint, endPoint): nPoints = 50 x = startPoint.x() y = startPoint.y() - r = math.sqrt((endPoint.x() - startPoint.x())**2 + (endPoint.y() - startPoint.y())**2) + r = math.sqrt( + (endPoint.x() - startPoint.x()) ** 2 + (endPoint.y() - startPoint.y()) ** 2 + ) self.rubberBand.reset(self.iface.activeLayer().geometryType()) - for itheta in range(nPoints+1): - theta = itheta*(2.0*math.pi/nPoints) - self.rubberBand.addPoint(QgsPointXY(x+r*math.cos(theta), y+r*math.sin(theta))) + for itheta in range(nPoints + 1): + theta = itheta * (2.0 * math.pi / nPoints) + self.rubberBand.addPoint( + QgsPointXY(x + r * math.cos(theta), y + r * math.sin(theta)) + ) self.rubberBand.closePoints() def endGeometry(self): self.geometry = self.rubberBand.asGeometry() self.createGeometry(self.geometry) - + def canvasReleaseEvent(self, event): if event.button() == Qt.LeftButton: if not self.startPoint: @@ -55,7 +60,7 @@ def canvasReleaseEvent(self, event): self.rubberBand = self.getRubberBand() if event.button() == Qt.RightButton: self.endGeometry() - + def canvasMoveEvent(self, event): if self.snapCursorRubberBand: self.snapCursorRubberBand.hide() diff --git a/DsgTools/gui/ProductionTools/MapTools/Acquisition/distanceToolTip.py b/DsgTools/gui/ProductionTools/MapTools/Acquisition/distanceToolTip.py index 49fa3e1d5..850108dbf 100644 --- a/DsgTools/gui/ProductionTools/MapTools/Acquisition/distanceToolTip.py +++ b/DsgTools/gui/ProductionTools/MapTools/Acquisition/distanceToolTip.py @@ -22,58 +22,61 @@ """ from qgis.core import ( - QgsDistanceArea, - QgsCoordinateTransformContext, - QgsCoordinateReferenceSystem, - QgsCoordinateTransform, - QgsProject, - QgsGeometry - ) + QgsDistanceArea, + QgsCoordinateTransformContext, + QgsCoordinateReferenceSystem, + QgsCoordinateTransform, + QgsProject, + QgsGeometry, +) from DsgTools.gui.ProductionTools.MapTools.Acquisition.toolTip import ToolTip + class DistanceToolTip(ToolTip): - def __init__(self, iface, minSegmentDistance, decimals): - super(DistanceToolTip, self).__init__(iface) - self.iface = iface - self.canvas = iface.mapCanvas() - self.last_distance = 0 - self.showing = False - self.minSegmentDistance = minSegmentDistance - self.decimals = decimals + def __init__(self, iface, minSegmentDistance, decimals): + super(DistanceToolTip, self).__init__(iface) + self.iface = iface + self.canvas = iface.mapCanvas() + self.last_distance = 0 + self.showing = False + self.minSegmentDistance = minSegmentDistance + self.decimals = decimals - def calculateDistance(self, p1, p2): - source_crs = self.iface.mapCanvas().mapSettings().destinationCrs() - dest_crs = QgsCoordinateReferenceSystem(3857) - tr = QgsCoordinateTransform(source_crs, dest_crs, QgsCoordinateTransformContext()) - p1t = QgsGeometry().fromPointXY(p1) - p1t.transform(tr) - p2t = QgsGeometry().fromPointXY(p2) - p2t.transform(tr) - distance = QgsDistanceArea() - m = distance.measureLine(p1t.asPoint(), p2t.asPoint()) - return m + def calculateDistance(self, p1, p2): + source_crs = self.iface.mapCanvas().mapSettings().destinationCrs() + dest_crs = QgsCoordinateReferenceSystem(3857) + tr = QgsCoordinateTransform( + source_crs, dest_crs, QgsCoordinateTransformContext() + ) + p1t = QgsGeometry().fromPointXY(p1) + p1t.transform(tr) + p2t = QgsGeometry().fromPointXY(p2) + p2t.transform(tr) + distance = QgsDistanceArea() + m = distance.measureLine(p1t.asPoint(), p2t.asPoint()) + return m - def canvasMoveEvent(self, last_p, current_p): - m = float(self.calculateDistance(last_p, current_p)) - if self.showing: - if m != self.last_distance: - color = 'red' - if m >= self.minSegmentDistance: - color = 'green' - txt = f"

{m:.{self.decimals}f}

" - self.show(txt, current_p) - self.last_distance = m - else: - if m > 1: - color = 'red' - if m >= self.minSegmentDistance: - color = 'green' - txt = f"

{m:.{self.decimals}f}

" - super(DistanceToolTip, self).show(txt, current_p) - self.last_distance = m - self.showing = True + def canvasMoveEvent(self, last_p, current_p): + m = float(self.calculateDistance(last_p, current_p)) + if self.showing: + if m != self.last_distance: + color = "red" + if m >= self.minSegmentDistance: + color = "green" + txt = f"

{m:.{self.decimals}f}

" + self.show(txt, current_p) + self.last_distance = m + else: + if m > 1: + color = "red" + if m >= self.minSegmentDistance: + color = "green" + txt = f"

{m:.{self.decimals}f}

" + super(DistanceToolTip, self).show(txt, current_p) + self.last_distance = m + self.showing = True - def deactivate(self): - self.deactivate() - self.showing = False + def deactivate(self): + self.deactivate() + self.showing = False diff --git a/DsgTools/gui/ProductionTools/MapTools/Acquisition/geometricaAquisition.py b/DsgTools/gui/ProductionTools/MapTools/Acquisition/geometricaAquisition.py index 97023c886..232e48257 100755 --- a/DsgTools/gui/ProductionTools/MapTools/Acquisition/geometricaAquisition.py +++ b/DsgTools/gui/ProductionTools/MapTools/Acquisition/geometricaAquisition.py @@ -23,20 +23,37 @@ from qgis import core, gui from qgis.PyQt.QtCore import Qt, QSettings from qgis.PyQt.QtGui import QCursor, QPixmap, QColor -from qgis.gui import QgsMapTool, QgsRubberBand, QgsAttributeDialog, \ - QgsAttributeForm, QgsSnapIndicator +from qgis.gui import ( + QgsMapTool, + QgsRubberBand, + QgsAttributeDialog, + QgsAttributeForm, + QgsSnapIndicator, +) from qgis.utils import iface -from qgis.core import QgsPointXY, QgsFeature, QgsGeometry, Qgis, QgsCoordinateReferenceSystem,\ - QgsCoordinateTransform, QgsEditFormConfig, QgsWkbTypes, QgsProject, \ - QgsPointLocator +from qgis.core import ( + QgsPointXY, + QgsFeature, + QgsGeometry, + Qgis, + QgsCoordinateReferenceSystem, + QgsCoordinateTransform, + QgsEditFormConfig, + QgsWkbTypes, + QgsProject, + QgsPointLocator, +) + +from DsgTools.gui.ProductionTools.MapTools.Acquisition.distanceToolTip import ( + DistanceToolTip, +) -from DsgTools.gui.ProductionTools.MapTools.Acquisition.distanceToolTip import DistanceToolTip class GeometricaAcquisition(QgsMapTool): def __init__(self, canvas, iface, action): super(GeometricaAcquisition, self).__init__(canvas) super(GeometricaAcquisition, self).__init__(canvas) - self.iface=iface + self.iface = iface self.canvas = canvas self.rubberBand = None self.snapCursorRubberBand = None @@ -44,44 +61,52 @@ def __init__(self, canvas, iface, action): self.setAction(action) self.minSegmentDistance = self.getMinSegmentDistance() self.decimals = self.getDecimals() - self.distanceToolTip = DistanceToolTip(self.iface, self.minSegmentDistance, self.decimals) + self.distanceToolTip = DistanceToolTip( + self.iface, self.minSegmentDistance, self.decimals + ) def getSuppressOption(self): qgisSettigns = QSettings() - qgisSettigns.beginGroup('qgis/digitizing') - setting = qgisSettigns.value('disable_enter_attribute_values_dialog') + qgisSettigns.beginGroup("qgis/digitizing") + setting = qgisSettigns.value("disable_enter_attribute_values_dialog") qgisSettigns.endGroup() - return setting == 'true' + return setting == "true" def setAction(self, action): self.toolAction = action self.toolAction.setCheckable(True) - + def canvasPressEvent(self, e): pass - + def activate(self): if self.toolAction: self.toolAction.setChecked(True) self.free = False - self.cur = QCursor(QPixmap(["18 13 4 1", - " c None", - "# c #FF0000", - ". c #FF0000", - "+ c #1210f3", - " ", - " +++++++++++ ", - " + # + ", - " + # + ", - "+ # +", - "+ # +", - "++#############++", - "+ # +", - "+ # +", - " + # +", - " + # + ", - " +++++++++++ ", - " ",])) + self.cur = QCursor( + QPixmap( + [ + "18 13 4 1", + " c None", + "# c #FF0000", + ". c #FF0000", + "+ c #1210f3", + " ", + " +++++++++++ ", + " + # + ", + " + # + ", + "+ # +", + "+ # +", + "++#############++", + "+ # +", + "+ # +", + " + # +", + " + # + ", + " +++++++++++ ", + " ", + ] + ) + ) self.canvas.setCursor(self.cur) def deactivate(self): @@ -96,7 +121,7 @@ def keyReleaseEvent(self, event): self.initVariable() if event.key() == Qt.Key_Control: self.free = False - + def keyPressEvent(self, event): if event.key() == Qt.Key_Control: self.free = True @@ -107,20 +132,20 @@ def keyPressEvent(self, event): self.rubberBand.setToGeometry(geom, self.iface.activeLayer()) def getParametersFromConfig(self): - #Método para obter as configurações da tool do QSettings - #Parâmetro de retorno: parameters (Todas os parâmetros do QSettings usado na ferramenta) + # Método para obter as configurações da tool do QSettings + # Parâmetro de retorno: parameters (Todas os parâmetros do QSettings usado na ferramenta) settings = QSettings() - settings.beginGroup('PythonPlugins/DsgTools/Options') + settings.beginGroup("PythonPlugins/DsgTools/Options") parameters = { - u'minSegmentDistance' : settings.value('minSegmentDistance'), - u'rightAngleDecimals': settings.value('rightAngleDecimals'), + "minSegmentDistance": settings.value("minSegmentDistance"), + "rightAngleDecimals": settings.value("rightAngleDecimals"), } settings.endGroup() return parameters def initVariable(self): if self.rubberBand: - self.rubberBand.reset(geometryType = self.iface.activeLayer().geometryType()) + self.rubberBand.reset(geometryType=self.iface.activeLayer().geometryType()) self.rubberBand = None self.qntPoint = 0 self.geometry = [] @@ -131,32 +156,41 @@ def initVariable(self): def getMinSegmentDistance(self): parameters = self.getParametersFromConfig() - return float(parameters[u'minSegmentDistance']) - + return float(parameters["minSegmentDistance"]) + def getDecimals(self): parameters = self.getParametersFromConfig() - return int(parameters[u'rightAngleDecimals']) if parameters[u'rightAngleDecimals'] is not None else 2 + return ( + int(parameters["rightAngleDecimals"]) + if parameters["rightAngleDecimals"] is not None + else 2 + ) - def completePolygon(self,geom, p4): - if (len(geom)>=2) and (len(geom) % 2 == 0): - p1 = geom[1] - p2 = geom[0] - p3 = geom[-1] + def completePolygon(self, geom, p4): + if (len(geom) >= 2) and (len(geom) % 2 == 0): + p1 = geom[1] + p2 = geom[0] + p3 = geom[-1] pf = self.lineIntersection(p1, p2, p3, p4) - new_geom = QgsGeometry.fromPolygonXY([self.geometry+[p4, pf]]) + new_geom = QgsGeometry.fromPolygonXY([self.geometry + [p4, pf]]) else: - new_geom = QgsGeometry.fromPolygonXY([self.geometry+[QgsPointXY(p4.x(), p4.y())]]) - pf = p4 + new_geom = QgsGeometry.fromPolygonXY( + [self.geometry + [QgsPointXY(p4.x(), p4.y())]] + ) + pf = p4 return new_geom, pf def bufferDistanceTest(self, geom, penult, last): def isWithinLimits(pnt): """checks whether point is distant enough from proposed geom's ending points (penult and last)""" - return self.distanceToolTip.calculateDistance( - last, pnt) >= self.minSegmentDistance and \ - self.distanceToolTip.calculateDistance( - penult, pnt) >= self.minSegmentDistance + return ( + self.distanceToolTip.calculateDistance(last, pnt) + >= self.minSegmentDistance + and self.distanceToolTip.calculateDistance(penult, pnt) + >= self.minSegmentDistance + ) + for i in range(len(geom)): if not isWithinLimits(geom[i]): return False @@ -164,11 +198,11 @@ def isWithinLimits(pnt): def distanceBetweenLinesTest(self, geom, p): teste_answer = True - for i in range(len(geom)-1): + for i in range(len(geom) - 1): p1 = geom[i] p2 = geom[i + 1] - projected_point = self.projectPoint(p1,p2,p) - distance = self.distanceToolTip.calculateDistance(projected_point,p2) + projected_point = self.projectPoint(p1, p2, p) + distance = self.distanceToolTip.calculateDistance(projected_point, p2) if distance > self.minSegmentDistance: continue else: @@ -176,54 +210,54 @@ def distanceBetweenLinesTest(self, geom, p): break return teste_answer - def lineIntersection(self, p1, p2, p3, p4): + def lineIntersection(self, p1, p2, p3, p4): p3Projected = p4 - if((p1.y() == p2.y()) or (p3.x()==p4.x())): + if (p1.y() == p2.y()) or (p3.x() == p4.x()): y = p3Projected.y() x = p2.x() - return QgsPointXY(x,y) - if((p1.x() == p2.x()) or (p3.y() == p4.y())): + return QgsPointXY(x, y) + if (p1.x() == p2.x()) or (p3.y() == p4.y()): y = p2.y() - x = p3Projected.x() - return QgsPointXY(x,y) - else: - m1 = (p1.y() - p2.y())/(p1.x() - p2.x()) - a1 = p2.y() + p2.x()/m1 - m2 = (p3.y() - p4.y())/(p3.x() - p4.x()) - #Reta perpendicular P3 P4 que passa por P4 - a2 = p4.y() + p4.x()/m2 + x = p3Projected.x() + return QgsPointXY(x, y) + else: + m1 = (p1.y() - p2.y()) / (p1.x() - p2.x()) + a1 = p2.y() + p2.x() / m1 + m2 = (p3.y() - p4.y()) / (p3.x() - p4.x()) + # Reta perpendicular P3 P4 que passa por P4 + a2 = p4.y() + p4.x() / m2 if abs(m1 - m2) > 0.01: - #intersecao - x = (a2 - a1)/(1/m2 - 1/m1) - y = -x/m1 + a1 - return QgsPointXY(x,y) + # intersecao + x = (a2 - a1) / (1 / m2 - 1 / m1) + y = -x / m1 + a1 + return QgsPointXY(x, y) return False - + def projectPoint(self, p1, p2, p3): - #reta P1 P2 + # reta P1 P2 try: # p1 e p2 na vertical - if (p1.x() == p2.x()): + if p1.x() == p2.x(): x = p3.x() y = p2.y() # p1 e p2 na horizontal - elif (p1.y()== p2.y()): + elif p1.y() == p2.y(): x = p2.x() y = p3.y() else: - a = (p2.y()-p1.y())/(p2.x()-p1.x()) - #reta perpendicular a P1P2 que passa por P2 - a2 = -1/a - b2 = p2.y() - a2*p2.x() - #reta paralela a P1P2 que passa por P3 - b3 = p3.y() - a*p3.x() - #intersecao entre retas - x = (b3 - b2)/(a2 - a) - y = a*x + b3 + a = (p2.y() - p1.y()) / (p2.x() - p1.x()) + # reta perpendicular a P1P2 que passa por P2 + a2 = -1 / a + b2 = p2.y() - a2 * p2.x() + # reta paralela a P1P2 que passa por P3 + b3 = p3.y() - a * p3.x() + # intersecao entre retas + x = (b3 - b2) / (a2 - a) + y = a * x + b3 return QgsPointXY(x, y) except: return None - + def getRubberBand(self): geomType = self.iface.activeLayer().geometryType() if geomType == QgsWkbTypes.PolygonGeometry: @@ -234,9 +268,9 @@ def getRubberBand(self): rubberBand.setSecondaryStrokeColor(QColor(255, 0, 0, 200)) rubberBand.setWidth(2) return rubberBand - + def getSnapRubberBand(self): - rubberBand = QgsRubberBand(self.canvas, geometryType = QgsWkbTypes.PointGeometry) + rubberBand = QgsRubberBand(self.canvas, geometryType=QgsWkbTypes.PointGeometry) rubberBand.setFillColor(QColor(255, 0, 0, 40)) rubberBand.setSecondaryStrokeColor(QColor(255, 0, 0, 200)) rubberBand.setWidth(2) @@ -257,47 +291,53 @@ def loadDefaultFields(self, layer, feature): attributesValues = {} primaryKeyIndexes = layer.dataProvider().pkAttributeIndexes() for fieldIndex in layer.attributeList(): - fieldName = layer.fields().field( fieldIndex ).name() + fieldName = layer.fields().field(fieldIndex).name() if fieldIndex in primaryKeyIndexes: continue - attributeExpression = layer.defaultValueDefinition( fieldIndex ).expression() - if attributeExpression == '': + attributeExpression = layer.defaultValueDefinition(fieldIndex).expression() + if attributeExpression == "": continue - evaluatedExpression = self.evaluateExpression(layer, layer.defaultValueDefinition( fieldIndex ).expression() ) + evaluatedExpression = self.evaluateExpression( + layer, layer.defaultValueDefinition(fieldIndex).expression() + ) if evaluatedExpression is None: - feature[ fieldName ] = attributeExpression + feature[fieldName] = attributeExpression continue - feature[ fieldName ] = evaluatedExpression + feature[fieldName] = evaluatedExpression def evaluateExpression(self, layer, expression): context = core.QgsExpressionContext() - context.appendScopes( core.QgsExpressionContextUtils.globalProjectLayerScopes(layer) ) - return core.QgsExpression( expression ).evaluate( context ) + context.appendScopes( + core.QgsExpressionContextUtils.globalProjectLayerScopes(layer) + ) + return core.QgsExpression(expression).evaluate(context) def createGeometry(self, geom): geom = self.reprojectRubberBand(geom) - if geom : + if geom: layer = self.canvas.currentLayer() fields = layer.fields() feature = core.QgsFeature() feature.setFields(fields) feature.setGeometry(geom) - - feature.initAttributes(fields.count()) - provider = layer.dataProvider() + + feature.initAttributes(fields.count()) + provider = layer.dataProvider() for i in range(fields.count()): defaultClauseCandidate = provider.defaultValueClause(i) if defaultClauseCandidate: - feature.setAttribute(i, defaultClauseCandidate) + feature.setAttribute(i, defaultClauseCandidate) + + self.loadDefaultFields(layer, feature) - self.loadDefaultFields( layer, feature ) - form = QgsAttributeDialog(layer, feature, False) - form.setAttribute( QtCore.Qt.WA_DeleteOnClose ) + form.setAttribute(QtCore.Qt.WA_DeleteOnClose) form.setMode(int(QgsAttributeForm.AddFeatureMode)) formSuppress = layer.editFormConfig().suppress() if formSuppress == QgsEditFormConfig.SuppressDefault: - if self.getSuppressOption(): #this is calculated every time because user can switch options while using tool + if ( + self.getSuppressOption() + ): # this is calculated every time because user can switch options while using tool layer.addFeature(feature) else: form.exec_() @@ -307,12 +347,12 @@ def createGeometry(self, geom): layer.addFeature(feature) layer.endEditCommand() self.canvas.refresh() - self.initVariable() + self.initVariable() def createSnapCursor(self, point): self.snapCursorRubberBand = self.getSnapRubberBand() - self.snapCursorRubberBand.addPoint(point) - + self.snapCursorRubberBand.addPoint(point) + def reprojectRubberBand(self, geom): """ Reprojects the geometry @@ -321,12 +361,16 @@ def reprojectRubberBand(self, geom): # Defining the crs from src and destiny epsg = self.canvas.mapSettings().destinationCrs().authid() crsSrc = QgsCoordinateReferenceSystem(epsg) - #getting srid from something like 'EPSG:31983' + # getting srid from something like 'EPSG:31983' layer = self.canvas.currentLayer() srid = layer.crs().authid() - crsDest = QgsCoordinateReferenceSystem(srid) #here we have to put authid, not srid + crsDest = QgsCoordinateReferenceSystem( + srid + ) # here we have to put authid, not srid # Creating a transformer - coordinateTransformer = QgsCoordinateTransform(crsSrc, crsDest, QgsProject.instance()) + coordinateTransformer = QgsCoordinateTransform( + crsSrc, crsDest, QgsProject.instance() + ) lyrType = self.iface.activeLayer().geometryType() # Transforming the points if lyrType == QgsWkbTypes.LineGeometry: diff --git a/DsgTools/gui/ProductionTools/MapTools/Acquisition/metadata.txt b/DsgTools/gui/ProductionTools/MapTools/Acquisition/metadata.txt index f8385d904..6fe41f2e0 100755 --- a/DsgTools/gui/ProductionTools/MapTools/Acquisition/metadata.txt +++ b/DsgTools/gui/ProductionTools/MapTools/Acquisition/metadata.txt @@ -5,7 +5,7 @@ name=Ferramenta de Aquisição personalizada qgisMinimumVersion=2.0 description=Ferramenta para auxiliar na aquisição de contornos version=version Version 0.1 -author=Jossan +author=Jossan email=me@hotmail.com ; end of mandatory metadata @@ -25,4 +25,3 @@ tags=digitizing ; in a future version of the web application it will ; be probably possible to create a project on redmine ; if they are not filled - diff --git a/DsgTools/gui/ProductionTools/MapTools/Acquisition/polygon.py b/DsgTools/gui/ProductionTools/MapTools/Acquisition/polygon.py index edc851b21..4119ccad4 100755 --- a/DsgTools/gui/ProductionTools/MapTools/Acquisition/polygon.py +++ b/DsgTools/gui/ProductionTools/MapTools/Acquisition/polygon.py @@ -25,6 +25,7 @@ from .geometricaAquisition import GeometricaAcquisition + class Polygon(GeometricaAcquisition): def __init__(self, canvas, iface, action): super(Polygon, self).__init__(canvas, iface, action) @@ -53,10 +54,14 @@ def distance_acceptable(self, p1, p_n, p_n_1, p_n_2): d_n = self.distanceToolTip.calculateDistance(p_n, p1) d_n_1 = self.distanceToolTip.calculateDistance(p_n, p_n_1) d_n_2 = self.distanceToolTip.calculateDistance(p_n_1, p_n_2) - return (d_n > self.minSegmentDistance) and (d_n_1 > self.minSegmentDistance) and (d_n_2 > self.minSegmentDistance) + return ( + (d_n > self.minSegmentDistance) + and (d_n_1 > self.minSegmentDistance) + and (d_n_2 > self.minSegmentDistance) + ) def canvasReleaseEvent(self, event): - event.snapPoint() #snap!!! + event.snapPoint() # snap!!! if self.snapCursorRubberBand: self.snapCursorRubberBand.reset(geometryType=QgsWkbTypes.PointGeometry) self.snapCursorRubberBand.hide() @@ -72,28 +77,42 @@ def canvasReleaseEvent(self, event): self.endGeometryFree() self.qntPoint = 0 else: - if (self.qntPoint >=2): - if (self.qntPoint % 2 == 0): + if self.qntPoint >= 2: + if self.qntPoint % 2 == 0: point = QgsPointXY(pointMap) - projectedMousePoint = self.projectPoint(self.geometry[-2], self.geometry[-1], point) - if projectedMousePoint: - new_geom, last_point = self.completePolygon(self.geometry, projectedMousePoint) - if self.bufferDistanceTest(self.geometry, projectedMousePoint, last_point): - self.geometry.append(QgsPointXY(projectedMousePoint.x(), projectedMousePoint.y())) - self.geometry.append(last_point) - self.endGeometry() + projectedMousePoint = self.projectPoint( + self.geometry[-2], self.geometry[-1], point + ) + if projectedMousePoint: + new_geom, last_point = self.completePolygon( + self.geometry, projectedMousePoint + ) + if self.bufferDistanceTest( + self.geometry, projectedMousePoint, last_point + ): + self.geometry.append( + QgsPointXY( + projectedMousePoint.x(), projectedMousePoint.y() + ) + ) + self.geometry.append(last_point) + self.endGeometry() else: self.iface.messageBar().pushMessage( - self.tr("Info:"), - self.tr("Not possible to digitize, segment smaller than minimun distance."), - level=Qgis.Info - ) + self.tr("Info:"), + self.tr( + "Not possible to digitize, segment smaller than minimun distance." + ), + level=Qgis.Info, + ) else: self.iface.messageBar().pushMessage( - self.tr("Info:"), - self.tr("The right angle tool should be used only for rectangular shapes."), - level=Qgis.Info - ) + self.tr("Info:"), + self.tr( + "The right angle tool should be used only for rectangular shapes." + ), + level=Qgis.Info, + ) elif self.free: self.geometry.append(pointMap) self.qntPoint += 1 @@ -106,29 +125,46 @@ def canvasReleaseEvent(self, event): self.qntPoint += 1 elif self.qntPoint == 1: point = QgsPointXY(pointMap) - if self.distanceToolTip.calculateDistance(self.geometry[-1], point) > self.minSegmentDistance: + if ( + self.distanceToolTip.calculateDistance(self.geometry[-1], point) + > self.minSegmentDistance + ): self.geometry.append(point) self.qntPoint += 1 else: self.iface.messageBar().pushMessage( - self.tr("Info:"), - self.tr("Not possible to digitise, segment smaller than minimun distance."), - level=Qgis.Info - ) + self.tr("Info:"), + self.tr( + "Not possible to digitise, segment smaller than minimun distance." + ), + level=Qgis.Info, + ) else: point = QgsPointXY(pointMap) - projectedMousePoint = self.projectPoint(self.geometry[-2], self.geometry[-1], point) + projectedMousePoint = self.projectPoint( + self.geometry[-2], self.geometry[-1], point + ) if projectedMousePoint: - new_geom, last_point = self.completePolygon(self.geometry, projectedMousePoint) - if self.bufferDistanceTest(self.geometry, projectedMousePoint, last_point): - self.geometry.append(QgsPointXY(projectedMousePoint.x(), projectedMousePoint.y())) + new_geom, last_point = self.completePolygon( + self.geometry, projectedMousePoint + ) + if self.bufferDistanceTest( + self.geometry, projectedMousePoint, last_point + ): + self.geometry.append( + QgsPointXY( + projectedMousePoint.x(), projectedMousePoint.y() + ) + ) self.qntPoint += 1 else: self.iface.messageBar().pushMessage( - self.tr("Info:"), - self.tr("Not possible to digitise, segment smaller than minimun distance."), - level=Qgis.Info - ) + self.tr("Info:"), + self.tr( + "Not possible to digitise, segment smaller than minimun distance." + ), + level=Qgis.Info, + ) def canvasMoveEvent(self, event): if self.snapCursorRubberBand: @@ -145,20 +181,28 @@ def canvasMoveEvent(self, event): self.distanceToolTip.canvasMoveEvent(self.geometry[0], point) geom = QgsGeometry.fromPolylineXY([self.geometry[0], point]) self.rubberBand.setToGeometry(geom, None) - elif self.qntPoint >= 2: + elif self.qntPoint >= 2: if self.free: self.distanceToolTip.canvasMoveEvent(self.geometry[-1], point) - geom = QgsGeometry.fromPolygonXY([self.geometry+[QgsPointXY(point.x(), point.y())]]) + geom = QgsGeometry.fromPolygonXY( + [self.geometry + [QgsPointXY(point.x(), point.y())]] + ) self.rubberBand.setToGeometry(geom, None) - else: - if (self.qntPoint % 2 == 1): + else: + if self.qntPoint % 2 == 1: self.setAvoidStyleSnapRubberBand() else: - self.setAllowedStyleSnapRubberBand() - projectedMousePoint = self.projectPoint(self.geometry[-2], self.geometry[-1], point) - self.distanceToolTip.canvasMoveEvent(self.geometry[-1], projectedMousePoint) + self.setAllowedStyleSnapRubberBand() + projectedMousePoint = self.projectPoint( + self.geometry[-2], self.geometry[-1], point + ) + self.distanceToolTip.canvasMoveEvent( + self.geometry[-1], projectedMousePoint + ) if projectedMousePoint: - geom, pf = self.completePolygon(self.geometry, projectedMousePoint) + geom, pf = self.completePolygon( + self.geometry, projectedMousePoint + ) self.rubberBand.setToGeometry(geom, None) else: self.initVariable() diff --git a/DsgTools/gui/ProductionTools/MapTools/Acquisition/toolTip.py b/DsgTools/gui/ProductionTools/MapTools/Acquisition/toolTip.py index ce0c5b3c6..7801a1245 100644 --- a/DsgTools/gui/ProductionTools/MapTools/Acquisition/toolTip.py +++ b/DsgTools/gui/ProductionTools/MapTools/Acquisition/toolTip.py @@ -23,14 +23,16 @@ from PyQt5.QtWidgets import QToolTip + class ToolTip(object): - def __init__(self, iface): - self.iface = iface - self.canvas = iface.mapCanvas() - - def show(self, text, toolTipPoint): - QToolTip.showText(self.canvas.mapToGlobal(self.canvas.mouseLastXY()),str(text), self.canvas) - - def deactivate(self): - QToolTip.hideText() + def __init__(self, iface): + self.iface = iface + self.canvas = iface.mapCanvas() + + def show(self, text, toolTipPoint): + QToolTip.showText( + self.canvas.mapToGlobal(self.canvas.mouseLastXY()), str(text), self.canvas + ) + def deactivate(self): + QToolTip.hideText() diff --git a/DsgTools/gui/ProductionTools/MapTools/AuxTools/copiarwkt.py b/DsgTools/gui/ProductionTools/MapTools/AuxTools/copiarwkt.py index 33115754c..2dd81a04a 100644 --- a/DsgTools/gui/ProductionTools/MapTools/AuxTools/copiarwkt.py +++ b/DsgTools/gui/ProductionTools/MapTools/AuxTools/copiarwkt.py @@ -21,7 +21,12 @@ ***************************************************************************/ """ -from qgis.core import Qgis, QgsCoordinateReferenceSystem, QgsCoordinateTransform, QgsCoordinateTransformContext +from qgis.core import ( + Qgis, + QgsCoordinateReferenceSystem, + QgsCoordinateTransform, + QgsCoordinateTransformContext, +) from PyQt5.QtWidgets import * from PyQt5.QtGui import * from PyQt5.QtCore import * @@ -30,23 +35,19 @@ from qgis.utils import iface import os -class GetCrsDialog(QDialog): +class GetCrsDialog(QDialog): def __init__(self): super(GetCrsDialog, self).__init__() uic.loadUi(self.getUiPath(), self) self.buttonBox.addButton("Sim", QDialogButtonBox.AcceptRole) self.buttonBox.addButton("Não mudar", QDialogButtonBox.RejectRole) - def setCrsValue(self, value): - self.selectCRS.setCrs( value) + self.selectCRS.setCrs(value) def getUiPath(self): - return os.path.join( - os.path.abspath(os.path.dirname(__file__)), - 'changeCRS.ui' - ) + return os.path.join(os.path.abspath(os.path.dirname(__file__)), "changeCRS.ui") def getCrs(self): return self.selectCRS.crs() @@ -54,7 +55,14 @@ def getCrs(self): def copywkt(): layer = iface.activeLayer() - + if layer is None: + iface.messageBar().pushMessage( + "Warning", + "Selecione uma camada antes de rodar o processo", + level=Qgis.Warning, + duration=5 + ) + result, destCrs = callDialog(layer.crs()) wktcoord = [] for feature in layer.getSelectedFeatures(): @@ -63,11 +71,16 @@ def copywkt(): transformcrs = getGeometryTransforms(layer.crs(), destCrs) geom.transform(transformcrs) wktcoord.append(geom.asWkt()) - QApplication.clipboard().setText( - '\n'.join(wktcoord) + QApplication.clipboard().setText("\n".join(wktcoord)) + iface.messageBar().pushMessage( + "Executado", + " As coordenadas das feições selecionadas foram copiadas em WKT para o sistema {}".format( + destCrs.authid() + ), + level=Qgis.Success, + duration=5, ) - iface.messageBar().pushMessage("Executado", - u" As coordenadas das feições selecionadas foram copiadas em WKT para o sistema {}".format(destCrs.authid()), level=Qgis.Success, duration=5) + def callDialog(crsvalue): getCrsDialog = GetCrsDialog() @@ -78,11 +91,20 @@ def callDialog(crsvalue): errorAction() return callDialog() return result, crs + + def errorAction(): - reply = QMessageBox.question(iface.mainWindow(), 'CRS Invalido', - 'Se deseja mudar o CRS, selecione um CRS valido', QMessageBox.Ok) + reply = QMessageBox.question( + iface.mainWindow(), + "CRS Invalido", + "Se deseja mudar o CRS, selecione um CRS valido", + QMessageBox.Ok, + ) return False + def getGeometryTransforms(sourceCrs, destCrs): - destTransform = QgsCoordinateTransform(sourceCrs, destCrs, QgsCoordinateTransformContext()) + destTransform = QgsCoordinateTransform( + sourceCrs, destCrs, QgsCoordinateTransformContext() + ) return destTransform diff --git a/DsgTools/gui/ProductionTools/MapTools/AuxTools/filterTools.py b/DsgTools/gui/ProductionTools/MapTools/AuxTools/filterTools.py index 617669425..de311b28a 100644 --- a/DsgTools/gui/ProductionTools/MapTools/AuxTools/filterTools.py +++ b/DsgTools/gui/ProductionTools/MapTools/AuxTools/filterTools.py @@ -22,29 +22,38 @@ ***************************************************************************/ """ from qgis import core +from qgis.gui import QgsMapTool from qgis.utils import iface from qgis.PyQt.QtCore import QObject -class FilterTools(QObject): +class FilterTools(QgsMapTool): + + def __init__(self, iface): + """ + Hides or show active layers labels. + """ + self.iface = iface + self.canvas = self.iface.mapCanvas() + super(FilterTools, self).__init__(self.canvas) def addTool(self, manager, callback, parentToolbar, stackButton, iconBasePath): self.stackButton = stackButton - icon_path = iconBasePath + '/filter.svg' + icon_path = iconBasePath + "/filter.svg" toolTip = self.tr("DSGTools: Filter Selected") action = manager.add_action( icon_path, - text=self.tr('DSGTools: Filter Selected'), + text=self.tr("DSGTools: Filter Selected"), callback=self.filterSelections, add_to_menu=False, add_to_toolbar=False, withShortcut=True, tooltip=toolTip, parentButton=stackButton, - isCheckable=False + isCheckable=False, ) - icon_path = iconBasePath + '/filterByGeomtries.png' + icon_path = iconBasePath + "/filterByGeomtries.png" toolTip = self.tr("DSGTools: Filter All Using the Selected Feature's Geometry") action = manager.add_action( icon_path, @@ -55,10 +64,10 @@ def addTool(self, manager, callback, parentToolbar, stackButton, iconBasePath): withShortcut=True, tooltip=toolTip, parentButton=stackButton, - isCheckable=False + isCheckable=False, ) - icon_path = iconBasePath + '/removeSpatialFilter.png' + icon_path = iconBasePath + "/removeSpatialFilter.png" toolTip = self.tr("DSGTools: Remove Filters") action = manager.add_action( icon_path, @@ -69,52 +78,67 @@ def addTool(self, manager, callback, parentToolbar, stackButton, iconBasePath): withShortcut=True, tooltip=toolTip, parentButton=stackButton, - isCheckable=False + isCheckable=False, ) - + def unload(self): pass + + def setCurrentActionOnStackButton(self): + try: + self.stackButton.setDefaultAction(self.sender()) + except: + pass def cleanAllFilters(self): - loadedLayers = core.QgsProject.instance().mapLayers().values() + self.setCurrentActionOnStackButton() + loadedLayers = core.QgsProject.instance().mapLayers().values() showMessage = False for layer in loadedLayers: if layer.isEditable(): showMessage = True - layer.setSubsetString('') + layer.setSubsetString("") iface.mapCanvas().refresh() if showMessage: - iface.messageBar().pushMessage("Attention", "Enabled layers for edition have not been unfiltered.", level=core.Qgis.Info, duration=3) + iface.messageBar().pushMessage( + "Attention", + "Enabled layers for edition have not been unfiltered.", + level=core.Qgis.Info, + duration=3, + ) def filterBySelectedGeometries(self): + self.setCurrentActionOnStackButton() layer = iface.activeLayer() if not layer: return selectedFeatures = layer.selectedFeatures() if not selectedFeatures: return - if not( layer.geometryType() == core.QgsWkbTypes.PolygonGeometry ): + if not (layer.geometryType() == core.QgsWkbTypes.PolygonGeometry): return multiPolygon = core.QgsMultiPolygon() for feature in selectedFeatures: for geometry in feature.geometry().asGeometryCollection(): - multiPolygon.addGeometry( geometry.constGet().clone() ) + multiPolygon.addGeometry(geometry.constGet().clone()) multiPolygon = core.QgsGeometry(multiPolygon).makeValid() - textFilter = "(geom && st_geomfromewkt('SRID={0};{1}') ) AND st_relate(geom, st_geomfromewkt('SRID={0};{1}'), 'T********')".format( - layer.crs().authid().split(':')[-1], - multiPolygon.asWkt() + textFilter = "(geom && st_geomfromewkt('SRID={0};{1}') ) AND st_relate(geom, st_geomfromewkt('SRID={0};{1}'), 'T********')".format( + layer.crs().authid().split(":")[-1], multiPolygon.asWkt() ) - layersBacklist = [ 'aux_moldura_a' ] - loadedLayers = core.QgsProject.instance().mapLayers().values() + layersBacklist = ["aux_moldura_a"] + loadedLayers = core.QgsProject.instance().mapLayers().values() for loadedLayer in loadedLayers: - if not isinstance(loadedLayer, core.QgsVectorLayer) or \ - loadedLayer.dataProvider().name() != 'postgres' or \ - loadedLayer.dataProvider().uri().table() in layersBacklist: + if ( + not isinstance(loadedLayer, core.QgsVectorLayer) + or loadedLayer.dataProvider().name() != "postgres" + or loadedLayer.dataProvider().uri().table() in layersBacklist + ): continue - loadedLayer.setSubsetString( textFilter ) + loadedLayer.setSubsetString(textFilter) iface.mapCanvas().refresh() def filterSelections(self): + self.setCurrentActionOnStackButton() layer = iface.activeLayer() if not layer: return @@ -122,13 +146,17 @@ def filterSelections(self): if not selectedFeatures: return primaryKeyIndex = layer.primaryKeyAttributes()[0] - primaryKeyName = layer.fields().names()[ primaryKeyIndex ] - layer.setSubsetString( - '"{0}" in ({1})'.format( - primaryKeyName, - ','.join([ - "'{}'".format(str(i[primaryKeyName])) if not isinstance(i[primaryKeyName], int) else str(i[primaryKeyName]) - for i in selectedFeatures - ]) - ) + primaryKeyName = layer.fields().names()[primaryKeyIndex] + layer.setSubsetString( + '"{0}" in ({1})'.format( + primaryKeyName, + ",".join( + [ + "'{}'".format(str(i[primaryKeyName])) + if not isinstance(i[primaryKeyName], int) + else str(i[primaryKeyName]) + for i in selectedFeatures + ] + ), + ) ) diff --git a/DsgTools/gui/ProductionTools/MapTools/AuxTools/otherTools.py b/DsgTools/gui/ProductionTools/MapTools/AuxTools/otherTools.py index cbbc64dc9..f1ca63d92 100644 --- a/DsgTools/gui/ProductionTools/MapTools/AuxTools/otherTools.py +++ b/DsgTools/gui/ProductionTools/MapTools/AuxTools/otherTools.py @@ -21,62 +21,80 @@ * * ***************************************************************************/ """ -from qgis.core import (QgsProject, - Qgis, - QgsVectorLayer - ) +from qgis.core import QgsProject, Qgis, QgsVectorLayer +from qgis.gui import QgsMapTool from qgis.utils import iface from qgis.PyQt.QtCore import QObject from qgis.PyQt.QtWidgets import QMessageBox from .copiarwkt import copywkt -class OtherTools(QObject): + +class OtherTools(QgsMapTool): + def __init__(self, iface): + self.iface = iface + self.canvas = self.iface.mapCanvas() + super(OtherTools, self).__init__(self.canvas) def addTool(self, manager, callback, parentToolbar, stackButton, iconBasePath): self.stackButton = stackButton - icon_path = iconBasePath + '/tempLayer.png' + icon_path = iconBasePath + "/tempLayer.png" toolTip = self.tr("DSGTools: Copy Features to Temporary Layer") action = manager.add_action( icon_path, - text=self.tr('DSGTools: Copy Features to Temporary Layer'), + text=self.tr("DSGTools: Copy Features to Temporary Layer"), callback=self.copyToTempLayer, add_to_menu=False, add_to_toolbar=False, withShortcut=True, tooltip=toolTip, parentButton=stackButton, - isCheckable=False + isCheckable=False, ) self.stackButton.setDefaultAction(action) - icon_path = iconBasePath + '/copywkt.png' + icon_path = iconBasePath + "/copywkt.png" toolTip = self.tr("DSGTools: Copy Feature's Coordinates as WKT") action = manager.add_action( icon_path, text=self.tr("DSGTools: Copy Feature's Coordinates as WKT"), - callback=copywkt, + callback=self.runCopyWkt, add_to_menu=False, add_to_toolbar=False, withShortcut=True, tooltip=toolTip, parentButton=stackButton, - isCheckable=False + isCheckable=False, ) - + def setCurrentActionOnStackButton(self): + try: + self.stackButton.setDefaultAction(self.sender()) + except: + pass + def unload(self): pass + + def runCopyWkt(self): + self.setCurrentActionOnStackButton() + copywkt() def copyToTempLayer(self): + self.setCurrentActionOnStackButton() confirmation = self.confirmAction() if not confirmation: - iface.messageBar().pushMessage("Cancelado", u"ação cancelada pelo usuário", - level=Qgis.Warning, duration=5) + iface.messageBar().pushMessage( + "Cancelado", + "ação cancelada pelo usuário", + level=Qgis.Warning, + duration=5, + ) return layer = iface.activeLayer() if not layer: - iface.messageBar().pushMessage("Erro", u"Selecione uma camada válida", - level=Qgis.Critical, duration=5) + iface.messageBar().pushMessage( + "Erro", "Selecione uma camada válida", level=Qgis.Critical, duration=5 + ) return features = layer.selectedFeatures() newFields = layer.fields() @@ -84,9 +102,9 @@ def copyToTempLayer(self): geomtype = layer.geometryType() print(geomtype) print(type(geomtype)) - newName = name + '_temp' - geomdict = {0:'multipoint', 1:'multilinestring', 2:'multipolygon'} - selection = QgsVectorLayer(geomdict[int(geomtype)], newName , 'memory') + newName = name + "_temp" + geomdict = {0: "multipoint", 1: "multilinestring", 2: "multipolygon"} + selection = QgsVectorLayer(geomdict[int(geomtype)], newName, "memory") selection.startEditing() selection.setCrs(layer.crs()) dp = selection.dataProvider() @@ -95,11 +113,19 @@ def copyToTempLayer(self): selection.commitChanges() selection.updateExtents() QgsProject.instance().addMapLayer(selection) - iface.messageBar().pushMessage("Executado", "Camada temporária criada: "+newName, - level=Qgis.Success, duration=5) + iface.messageBar().pushMessage( + "Executado", + "Camada temporária criada: " + newName, + level=Qgis.Success, + duration=5, + ) def confirmAction(self): - reply = QMessageBox.question(iface.mainWindow(), 'Continuar?', - 'Será criado uma nova camada com as feições selecionadas. Deseja continuar?', QMessageBox.Yes, QMessageBox.No) + reply = QMessageBox.question( + iface.mainWindow(), + "Continuar?", + "Será criado uma nova camada com as feições selecionadas. Deseja continuar?", + QMessageBox.Yes, + QMessageBox.No, + ) return reply == QMessageBox.Yes - diff --git a/DsgTools/gui/ProductionTools/MapTools/AuxTools/spatialFilter.py b/DsgTools/gui/ProductionTools/MapTools/AuxTools/spatialFilter.py index aca7e8e18..6ec344819 100644 --- a/DsgTools/gui/ProductionTools/MapTools/AuxTools/spatialFilter.py +++ b/DsgTools/gui/ProductionTools/MapTools/AuxTools/spatialFilter.py @@ -22,32 +22,50 @@ """ from qgis import gui, core +from qgis.gui import QgsMapTool from qgis.utils import iface from PyQt5 import QtGui, QtCore -class SpatialFilter: - def __init__(self): +class SpatialFilter(QgsMapTool): + def __init__(self, stackButton): + self.stackButton = stackButton self.previousMapTool = iface.mapCanvas().mapTool() - self.myMapTool = gui.QgsMapToolEmitPoint( iface.mapCanvas() ) + self.myMapTool = gui.QgsMapToolEmitPoint(iface.mapCanvas()) self.coordinates = [] self.isEditing = 0 self.isActive = False - self.myMapTool.canvasClicked.connect( self.mouseClick ) - self.myMapTool.keyReleaseEvent = lambda event: self.disconnect() if event.key() == QtCore.Qt.Key_Escape else '' + self.myMapTool.canvasClicked.connect(self.mouseClick) + self.myMapTool.keyReleaseEvent = ( + lambda event: self.disconnect() + if event.key() == QtCore.Qt.Key_Escape + else "" + ) + self.iface = iface + self.canvas = self.iface.mapCanvas() + super(SpatialFilter, self).__init__(self.canvas) + + def setCurrentActionOnStackButton(self): + try: + self.stackButton.setDefaultAction(self.sender()) + except: + pass def start(self): + self.setCurrentActionOnStackButton() self.isActive = not self.isActive if self.isActive: - self.myRubberBand = gui.QgsRubberBand( iface.mapCanvas(), core.QgsWkbTypes.PolygonGeometry ) + self.myRubberBand = gui.QgsRubberBand( + iface.mapCanvas(), core.QgsWkbTypes.PolygonGeometry + ) color = QtGui.QColor(78, 97, 114) color.setAlpha(190) self.myRubberBand.setColor(color) self.myRubberBand.setFillColor(QtGui.QColor(255, 0, 0, 40)) - + # Set MapTool - iface.mapCanvas().setMapTool( self.myMapTool ) - iface.mapCanvas().xyCoordinates.connect( self.mouseMove ) + iface.mapCanvas().setMapTool(self.myMapTool) + iface.mapCanvas().xyCoordinates.connect(self.mouseMove) else: self.disconnect() @@ -56,7 +74,7 @@ def disconnect(self): self.coordinates = [] iface.mapCanvas().unsetMapTool(self.myMapTool) try: - iface.mapCanvas().xyCoordinates.disconnect (self.mouseMove) + iface.mapCanvas().xyCoordinates.disconnect(self.mouseMove) except: pass @@ -65,54 +83,64 @@ def disconnect(self): except: pass - def mouseClick( self, currentPos, clickedButton ): - if clickedButton == QtCore.Qt.LeftButton:# and myRubberBand.numberOfVertices() == 0: - self.myRubberBand.addPoint( core.QgsPointXY(currentPos)) - self.coordinates.append( core.QgsPointXY(currentPos)) + def mouseClick(self, currentPos, clickedButton): + if ( + clickedButton == QtCore.Qt.LeftButton + ): # and myRubberBand.numberOfVertices() == 0: + self.myRubberBand.addPoint(core.QgsPointXY(currentPos)) + self.coordinates.append(core.QgsPointXY(currentPos)) self.isEditing = 1 - - elif clickedButton == QtCore.Qt.RightButton and self.myRubberBand.numberOfVertices() > 2: + + elif ( + clickedButton == QtCore.Qt.RightButton + and self.myRubberBand.numberOfVertices() > 2 + ): self.isEditing = 0 # create feature and set geometry. - - poly = core.QgsFeature() + + poly = core.QgsFeature() geomP = self.myRubberBand.asGeometry() poly.setGeometry(geomP) - g = geomP.asWkt() # Get WKT coordenates. + g = geomP.asWkt() # Get WKT coordenates. - canvas=iface.mapCanvas() + canvas = iface.mapCanvas() + + c = canvas.mapSettings().destinationCrs().authid() # Get EPSG. + rep = c.replace("EPSG:", "") + + vlyr = core.QgsVectorLayer( + "?query=SELECT geom_from_wkt('%s') as geometry&geometry=geometry:3:%s" + % (g, rep), + "Polygon_Reference", + "virtual", + ) - c = canvas.mapSettings().destinationCrs().authid() # Get EPSG. - rep = c.replace("EPSG:","") - - vlyr = core.QgsVectorLayer("?query=SELECT geom_from_wkt('%s') as geometry&geometry=geometry:3:%s"%(g,rep), "Polygon_Reference", "virtual") - core.QgsProject.instance().addMapLayer(vlyr) self.myRubberBand.reset(core.QgsWkbTypes.PolygonGeometry) string = f"(geom && ST_GEOMFROMEWKT('SRID={rep};{g}')) AND ST_INTERSECTS(geom, ST_GEOMFROMEWKT('SRID={rep};{g}'))" layers = core.QgsProject.instance().mapLayers().values() - + layersBacklist = self.getLayersBacklist() - + for layer in layers: - if not isinstance(layer, core.QgsVectorLayer) or \ - layer.dataProvider().name() != 'postgres' or \ - layer.dataProvider().uri().table() in layersBacklist: + if ( + not isinstance(layer, core.QgsVectorLayer) + or layer.dataProvider().name() != "postgres" + or layer.dataProvider().uri().table() in layersBacklist + ): continue try: layer.setSubsetString(string) except Exception: pass - + self.myRubberBand.reset(core.QgsWkbTypes.PolygonGeometry) self.disconnect() def getLayersBacklist(self): - return [ - 'aux_moldura_a' - ] + return ["aux_moldura_a"] - def mouseMove( self, currentPos ): + def mouseMove(self, currentPos): if self.isEditing == 1: - self.myRubberBand.movePoint(core.QgsPointXY(currentPos)) \ No newline at end of file + self.myRubberBand.movePoint(core.QgsPointXY(currentPos)) diff --git a/DsgTools/gui/ProductionTools/MapTools/FlipLineTool/flipLineTool.py b/DsgTools/gui/ProductionTools/MapTools/FlipLineTool/flipLineTool.py index 06a7cd2ed..f24b62065 100644 --- a/DsgTools/gui/ProductionTools/MapTools/FlipLineTool/flipLineTool.py +++ b/DsgTools/gui/ProductionTools/MapTools/FlipLineTool/flipLineTool.py @@ -22,36 +22,47 @@ """ from __future__ import absolute_import from qgis.gui import QgsMapTool, QgsMessageBar -from qgis.core import QgsMapLayer, QgsVectorLayer, QgsMessageLog, QgsFeatureRequest, QgsWkbTypes, Qgis +from qgis.core import ( + QgsMapLayer, + QgsVectorLayer, + QgsMessageLog, + QgsFeatureRequest, + QgsWkbTypes, + Qgis, +) from qgis.PyQt import QtCore, QtGui from .....core.GeometricTools.geometryHandler import GeometryHandler + class FlipLine(QgsMapTool): """ Tool expected behaviour: When (valid) line features are selected, it flips them upon tool activation. """ + def __init__(self, iface): - self.iface = iface + self.iface = iface self.canvas = self.iface.mapCanvas() self.toolAction = None QgsMapTool.__init__(self, self.canvas) self.DsgGeometryHandler = GeometryHandler(iface) self.currentLayer = None - + def addTool(self, manager, callback, parentMenu, iconBasePath): - icon_path = iconBasePath + '/flipLineTool.png' - toolTip = self.tr("DSGTools: Flip Line Tool\nInsert tool tip for Flip Line Tool.") + icon_path = iconBasePath + "/flipLineTool.png" + toolTip = self.tr( + "DSGTools: Flip Line Tool\nInsert tool tip for Flip Line Tool." + ) action = manager.add_action( icon_path, - text=self.tr('DSGTools: Flip Line Tool'), + text=self.tr("DSGTools: Flip Line Tool"), callback=callback, add_to_menu=False, add_to_toolbar=True, - withShortcut = True, - tooltip = toolTip, - parentToolbar =parentMenu + withShortcut=True, + tooltip=toolTip, + parentToolbar=parentMenu, ) self.setAction(action) @@ -63,7 +74,12 @@ def setToolEnabled(self, layer=None): """ if not isinstance(layer, QgsVectorLayer): layer = self.iface.mapCanvas().currentLayer() - if not layer or not isinstance(layer, QgsVectorLayer) or layer.geometryType() != QgsWkbTypes.LineGeometry or not layer.isEditable(): + if ( + not layer + or not isinstance(layer, QgsVectorLayer) + or layer.geometryType() != QgsWkbTypes.LineGeometry + or not layer.isEditable() + ): enabled = False else: enabled = True @@ -76,7 +92,7 @@ def activate(self): """ if self.toolAction: self.toolAction.setChecked(False) - + def setAction(self, action): """ Defines an action for tool. @@ -101,37 +117,43 @@ def getAllSelectedLines(self): def flipSelectedLines(self): """ Method for flipping all selected lines. Used for button callback. - """ + """ # get all selected features and remove all features that are not lines selectedFeatures = self.getAllSelectedLines() pop = 0 for idx, item in enumerate(selectedFeatures): if item[2] != 1: - selectedFeatures.pop(idx-pop) + selectedFeatures.pop(idx - pop) pop += 1 if not selectedFeatures: logMsg = self.getLogMessage(None, None) - self.iface.messageBar().pushMessage(self.tr('Error'), logMsg, level=Qgis.Critical, duration=3) + self.iface.messageBar().pushMessage( + self.tr("Error"), logMsg, level=Qgis.Critical, duration=3 + ) # QMessageBox.critical(self, self.tr('Critical!'), logMsg) QgsMessageLog.logMessage(logMsg, "DSGTools Plugin", Qgis.Critical) return # call the method for flipping features from geometry module - flippedLines, failedLines = self.DsgGeometryHandler.flipFeatureList(featureList=selectedFeatures, debugging=True) + flippedLines, failedLines = self.DsgGeometryHandler.flipFeatureList( + featureList=selectedFeatures, debugging=True + ) logMsg = self.getLogMessage(flippedLines, failedLines) - self.iface.messageBar().pushMessage(self.tr('Success'), logMsg, level=Qgis.Info, duration=3) + self.iface.messageBar().pushMessage( + self.tr("Success"), logMsg, level=Qgis.Info, duration=3 + ) QgsMessageLog.logMessage(logMsg, "DSGTools Plugin", Qgis.Info) - + def getLogMessage(self, flippedLines, failedLines): """ Method for mounting log message to be exposed to user. :param flippedLines: list of lines that were selected and were successfully flipped. :param failedLines: list of lines that were selected and failed to be flipped. - :param success: indicates whether the log is for a failed execution or + :param success: indicates whether the log is for a failed execution or """ - nrFlipped = nrFailed = 0 - logMsg = '' + nrFlipped = nrFailed = 0 + logMsg = "" if not flippedLines and not failedLines: - return self.tr('There are no (valid) lines selected!') + return self.tr("There are no (valid) lines selected!") if flippedLines: nrFlipped = len(flippedLines) logMsg = self.tr("Feature(s) flipped: ") @@ -144,14 +166,21 @@ def getLogMessage(self, flippedLines, failedLines): for item in failedLines: logMsg += "{} (id={}), ".format(item[0].name(), item[1].id()) logMsg = (logMsg + ")").replace(", )", ".") - return logMsg + self.tr("\n{} lines flipped. {} failed to be flipped.").format(nrFlipped, nrFailed) + return logMsg + self.tr("\n{} lines flipped. {} failed to be flipped.").format( + nrFlipped, nrFailed + ) def startFlipLineTool(self): if self.canvas.currentLayer() in self.iface.editableLayers(): self.flipSelectedLines() else: - self.iface.messageBar().pushMessage(self.tr('Warning'), self.tr('Start editing in current layer!'), level=Qgis.Info, duration=3) + self.iface.messageBar().pushMessage( + self.tr("Warning"), + self.tr("Start editing in current layer!"), + level=Qgis.Info, + duration=3, + ) def deactivate(self): QgsMapTool.deactivate(self) - self.canvas.unsetMapTool(self) \ No newline at end of file + self.canvas.unsetMapTool(self) diff --git a/DsgTools/gui/ProductionTools/MapTools/FreeHandTool/controllers/acquisitionFreeController.py b/DsgTools/gui/ProductionTools/MapTools/FreeHandTool/controllers/acquisitionFreeController.py index 611885d07..ccd1cc64a 100644 --- a/DsgTools/gui/ProductionTools/MapTools/FreeHandTool/controllers/acquisitionFreeController.py +++ b/DsgTools/gui/ProductionTools/MapTools/FreeHandTool/controllers/acquisitionFreeController.py @@ -25,13 +25,22 @@ from qgis.PyQt.QtWidgets import QMessageBox from qgis import core, gui from qgis.utils import iface -from qgis.core import QgsPoint, QgsLineString, QgsVectorLayer, QgsWkbTypes, \ - QgsProject, QgsMessageLog, Qgis +from qgis.core import ( + QgsPoint, + QgsLineString, + QgsVectorLayer, + QgsWkbTypes, + QgsProject, + QgsMessageLog, + Qgis, +) -from DsgTools.gui.ProductionTools.MapTools.FreeHandTool.models.acquisitionFree import AcquisitionFree +from DsgTools.gui.ProductionTools.MapTools.FreeHandTool.models.acquisitionFree import ( + AcquisitionFree, +) -class AcquisitionFreeController(object): +class AcquisitionFreeController(object): def __init__(self, acquisitionFree, iface): """ Class constructor. @@ -42,7 +51,7 @@ def __init__(self, acquisitionFree, iface): self.acquisitionFree = acquisitionFree self.iface = iface self.active = False - + def setIface(self, iface): """ Sets a QGIS interface object to iface attribute from AcquisitionFreeController object. @@ -57,43 +66,52 @@ def getIface(self): return self.iface def setActionAcquisitionFree(self, actionAcquisitionFree): - #Método para definir a classe ActionAcquisitionFree - #Parâmetro de entrada: actionAcquisitionFree (classe ActionAcquisitionFree) + # Método para definir a classe ActionAcquisitionFree + # Parâmetro de entrada: actionAcquisitionFree (classe ActionAcquisitionFree) self.actionAcquisitionFree = actionAcquisitionFree - + def getActionAcquisitionFree(self): - #Método para obter a classe ActionAcquisitionFree - #Parâmetro de retorno: self.actionAcquisitionFree (classe ActionAcquisitionFree) - return self.actionAcquisitionFree + # Método para obter a classe ActionAcquisitionFree + # Parâmetro de retorno: self.actionAcquisitionFree (classe ActionAcquisitionFree) + return self.actionAcquisitionFree @property def toolAction(self): return self.actionAcquisitionFree def setAcquisitionFree(self, acquisitionFree): - #Método para definir a classe AcquisitionFree - #Parâmetro de entrada: acquisitionFree (classe AcquisitionFree) + # Método para definir a classe AcquisitionFree + # Parâmetro de entrada: acquisitionFree (classe AcquisitionFree) self.acquisitionFree = acquisitionFree def getAcquisitionFree(self): - #Método para obter a classe AcquisitionFree - #Parâmetro de retorno: self.acquisitionFree (classe AcquisitionFree) + # Método para obter a classe AcquisitionFree + # Parâmetro de retorno: self.acquisitionFree (classe AcquisitionFree) return self.acquisitionFree def setActiveState(self, state): - #Método para definir estado da ferramento (ativada ou desativada) - #Parâmetro de entrada: state (boleano) + # Método para definir estado da ferramento (ativada ou desativada) + # Parâmetro de entrada: state (boleano) self.active = state - + def getActiveState(self): - #Método para obter estado da tool (ativada ou desativada) - #Parâmetro de retorno: state (boleano) + # Método para obter estado da tool (ativada ou desativada) + # Parâmetro de retorno: state (boleano) return self.active def checkToActiveAction(self): - #Método para testar se a camada ativa é valida para ativar a ferramenta - layer = self.getIface().activeLayer() - if core is not None and layer and layer.isEditable() and (layer.type() == core.QgsMapLayer.VectorLayer) and (layer.geometryType() in [core.QgsWkbTypes.LineGeometry, core.QgsWkbTypes.PolygonGeometry]): + # Método para testar se a camada ativa é valida para ativar a ferramenta + layer = self.getIface().activeLayer() + if ( + core is not None + and layer + and layer.isEditable() + and (layer.type() == core.QgsMapLayer.VectorLayer) + and ( + layer.geometryType() + in [core.QgsWkbTypes.LineGeometry, core.QgsWkbTypes.PolygonGeometry] + ) + ): if not self.actionAcquisitionFree.isEnabled(): self.actionAcquisitionFree.setEnabled(True) return True @@ -103,8 +121,12 @@ def checkToActiveAction(self): return False def setToolEnabled(self): - layer = self.iface.activeLayer() - if not isinstance(layer, QgsVectorLayer) or layer.geometryType() == QgsWkbTypes.PointGeometry or not layer.isEditable(): + layer = self.iface.activeLayer() + if ( + not isinstance(layer, QgsVectorLayer) + or layer.geometryType() == QgsWkbTypes.PointGeometry + or not layer.isEditable() + ): enabled = False else: enabled = True @@ -115,68 +137,76 @@ def setToolEnabled(self): return enabled def getParametersFromConfig(self): - #Método para obter as configurações da tool do QSettings - #Parâmetro de retorno: parameters (Todas os parâmetros do QSettings usado na ferramenta) + # Método para obter as configurações da tool do QSettings + # Parâmetro de retorno: parameters (Todas os parâmetros do QSettings usado na ferramenta) settings = QtCore.QSettings() - settings.beginGroup('PythonPlugins/DsgTools/Options') + settings.beginGroup("PythonPlugins/DsgTools/Options") parameters = { - u'freeHandTolerance' : settings.value('freeHandTolerance'), - u'freeHandFinalSimplifyTolerance' : settings.value('freeHandFinalSimplifyTolerance'), - u'freeHandSmoothIterations' : settings.value('freeHandSmoothIterations'), - u'freeHandSmoothOffset' : settings.value('freeHandSmoothOffset'), - u'algIterations' : settings.value('algIterations'), - u'undoPoints' : settings.value('undoPoints') + "freeHandTolerance": settings.value("freeHandTolerance"), + "freeHandFinalSimplifyTolerance": settings.value( + "freeHandFinalSimplifyTolerance" + ), + "freeHandSmoothIterations": settings.value("freeHandSmoothIterations"), + "freeHandSmoothOffset": settings.value("freeHandSmoothOffset"), + "algIterations": settings.value("algIterations"), + "undoPoints": settings.value("undoPoints"), } settings.endGroup() return parameters def getTolerance(self, layer): - #Método para obter tolerância para simplificação de geometria - #Parâmetro de entrada: layer (camada em uso) - #Parâmetro de retorno: sGeom (Geometria simplificada) + # Método para obter tolerância para simplificação de geometria + # Parâmetro de entrada: layer (camada em uso) + # Parâmetro de retorno: sGeom (Geometria simplificada) parameters = self.getParametersFromConfig() - return parameters[u'freeHandTolerance'] - + return parameters["freeHandTolerance"] + def getFinalTolerance(self): parameters = self.getParametersFromConfig() - finalTolerance = parameters[u'freeHandFinalSimplifyTolerance'] + finalTolerance = parameters["freeHandFinalSimplifyTolerance"] return 0 if finalTolerance is None else float(finalTolerance) def simplifyGeometry(self, geom, tolerance): - #Método para simplificar geometria - #Parâmetro de entrada: geom (Geometria adquirida), tolerance (Tolerância para simplificação) - #Parâmetro de retorno: sGeom (Geometria simplificada) + # Método para simplificar geometria + # Parâmetro de entrada: geom (Geometria adquirida), tolerance (Tolerância para simplificação) + # Parâmetro de retorno: sGeom (Geometria simplificada) parameters = self.getParametersFromConfig() - firstVertex = geom.vertexAt(0) - lastVertex = geom.vertexAt(geom.constGet().nCoordinates() - 1 ) + firstVertex = geom.vertexAt(0) + lastVertex = geom.vertexAt(geom.constGet().nCoordinates() - 1) sGeom = geom source_crs = self.iface.activeLayer().crs() dest_crs = core.QgsCoordinateReferenceSystem(3857) - tr = core.QgsCoordinateTransform(source_crs, dest_crs, core.QgsCoordinateTransformContext()) + tr = core.QgsCoordinateTransform( + source_crs, dest_crs, core.QgsCoordinateTransformContext() + ) sGeom.transform(tr) - for x in range(int(parameters[u'algIterations'])): + for x in range(int(parameters["algIterations"])): sGeom = sGeom.simplify(float(tolerance)) try: sGeom = sGeom.smooth( - int(parameters[u'freeHandSmoothIterations']), - float(parameters[u'freeHandSmoothOffset']) + int(parameters["freeHandSmoothIterations"]), + float(parameters["freeHandSmoothOffset"]), ) except: - msg = QMessageBox().tr('Probably too many smoothing iteration, try reducing it (3 usually is enough). Geometry was not smoothened.') + msg = QMessageBox().tr( + "Probably too many smoothing iteration, try reducing it (3 usually is enough). Geometry was not smoothened." + ) QMessageBox.warning( - self.iface.mainWindow(), - QMessageBox().tr('Error!'), - msg + self.iface.mainWindow(), QMessageBox().tr("Error!"), msg ) - QgsMessageLog.logMessage(msg, 'DSGTools Plugin', Qgis.Critical) + QgsMessageLog.logMessage(msg, "DSGTools Plugin", Qgis.Critical) return geom finalGeom = sGeom.simplify(self.getFinalTolerance()) - tr = core.QgsCoordinateTransform(dest_crs, source_crs, core.QgsCoordinateTransformContext()) + tr = core.QgsCoordinateTransform( + dest_crs, source_crs, core.QgsCoordinateTransformContext() + ) finalGeom.transform(tr) if self.iface.activeLayer().geometryType() == core.QgsWkbTypes.PolygonGeometry: return finalGeom finalGeom.moveVertex(firstVertex.x(), firstVertex.y(), 0) - finalGeom.moveVertex(lastVertex.x(), lastVertex.y(), finalGeom.constGet().nCoordinates() - 1) + finalGeom.moveVertex( + lastVertex.x(), lastVertex.y(), finalGeom.constGet().nCoordinates() - 1 + ) return finalGeom def reprojectGeometry(self, geom): @@ -186,18 +216,18 @@ def reprojectGeometry(self, geom): epsgSrc = canvas.mapSettings().destinationCrs().authid() epsgDest = layer.crs().authid() if epsgSrc != epsgDest: - ct = canvas.mapSettings().layerTransform( layer ) + ct = canvas.mapSettings().layerTransform(layer) geom.transform(ct, core.QgsCoordinateTransform.ReverseTransform) - return geom + return geom def createFeature(self, geom): - #Método para criar feição - #Parâmetro de entrada: geom (geometria adquirida) - if not geom : + # Método para criar feição + # Parâmetro de entrada: geom (geometria adquirida) + if not geom: return settings = QtCore.QSettings() canvas = self.getIface().mapCanvas() - layer = canvas.currentLayer() + layer = canvas.currentLayer() tolerance = self.getTolerance(layer) geom = self.reprojectGeometry(geom) simplifyGeometry = self.simplifyGeometry(geom, tolerance) @@ -205,7 +235,7 @@ def createFeature(self, geom): feature = core.QgsFeature() feature.setFields(fields) feature.setGeometry(simplifyGeometry) - provider = layer.dataProvider() + provider = layer.dataProvider() for i in range(fields.count()): defaultClauseCandidate = provider.defaultValueClause(i) if defaultClauseCandidate: @@ -213,13 +243,10 @@ def createFeature(self, geom): formSuppressOnLayer = layer.editFormConfig().suppress() formSuppressOnSettings = self.getFormSuppressStateSettings() featureAdded = True - if ( - formSuppressOnLayer == core.QgsEditFormConfig.SuppressOn - or ( - formSuppressOnLayer == core.QgsEditFormConfig.SuppressDefault - and formSuppressOnSettings == 'true' - ) - ): + if formSuppressOnLayer == core.QgsEditFormConfig.SuppressOn or ( + formSuppressOnLayer == core.QgsEditFormConfig.SuppressDefault + and formSuppressOnSettings == "true" + ): self.addFeatureWithoutForm(layer, feature) else: featureAdded = self.addFeatureWithForm(layer, feature) @@ -227,15 +254,14 @@ def createFeature(self, geom): self.createTopology(feature) def createTopology(self, feature): - currentLayer = iface.activeLayer() - otherLayers = [ - layer for layer in iface.mapCanvas().layers() + currentLayer = iface.activeLayer() + otherLayers = [ + layer + for layer in iface.mapCanvas().layers() if ( layer.id() != currentLayer.id() - and - layer.isEditable() - and - layer.type() == core.QgsMapLayer.VectorLayer + and layer.isEditable() + and layer.type() == core.QgsMapLayer.VectorLayer ) ] createdGeometry = feature.geometry() @@ -244,57 +270,69 @@ def createTopology(self, feature): currentLayer.addTopologicalPoints(createdGeometry) iface.mapCanvas().refresh() - def reshapeSimplify(self, reshapeLine): + def reshapeSimplify(self, reshapeLine): canvas = self.getIface().mapCanvas() layer = canvas.currentLayer() tolerance = self.getTolerance(layer) reshapeLine_ = self.reprojectGeometry(reshapeLine) rsLine = self.simplifyGeometry(reshapeLine_, tolerance) request = core.QgsFeatureRequest().setFilterRect(rsLine.boundingBox()) - for feat in layer.getSelectedFeatures(request) if layer.selectedFeatureCount() > 0 else layer.getFeatures(request): - geom = feat.geometry() # geometria que receberá o reshape. - if geom.intersects(rsLine): # Se intersecta e transforma frompolyline em geometria. - geom.reshapeGeometry(QgsLineString([QgsPoint(p) for p in rsLine.asPolyline()])) # realiza o reshape entre a linha e a geometria. + for feat in ( + layer.getSelectedFeatures(request) + if layer.selectedFeatureCount() > 0 + else layer.getFeatures(request) + ): + geom = feat.geometry() # geometria que receberá o reshape. + if geom.intersects( + rsLine + ): # Se intersecta e transforma frompolyline em geometria. + geom.reshapeGeometry( + QgsLineString([QgsPoint(p) for p in rsLine.asPolyline()]) + ) # realiza o reshape entre a linha e a geometria. layer.changeGeometry(feat.id(), geom) - - canvas.refresh() # Refresh para atualizar, mas não salvar as alterações. + + canvas.refresh() # Refresh para atualizar, mas não salvar as alterações. def getFormSuppressStateSettings(self): - #Método para verificar se o formulário de aquisição está suprimido nas configurações do projeto - #Parâmetro de retorno: suppressForm ( boleano ) + # Método para verificar se o formulário de aquisição está suprimido nas configurações do projeto + # Parâmetro de retorno: suppressForm ( boleano ) s = QtCore.QSettings() - suppressForm = s.value(u"qgis/digitizing/disable_enter_attribute_values_dialog") + suppressForm = s.value("qgis/digitizing/disable_enter_attribute_values_dialog") return suppressForm == "true" def loadDefaultFields(self, layer, feature): attributesValues = {} primaryKeyIndexes = layer.dataProvider().pkAttributeIndexes() for fieldIndex in layer.attributeList(): - fieldName = layer.fields().field( fieldIndex ).name() + fieldName = layer.fields().field(fieldIndex).name() if fieldIndex in primaryKeyIndexes: continue - attributeExpression = layer.defaultValueDefinition( fieldIndex ).expression() - if attributeExpression == '': + attributeExpression = layer.defaultValueDefinition(fieldIndex).expression() + if attributeExpression == "": continue - evaluatedExpression = self.evaluateExpression(layer, layer.defaultValueDefinition( fieldIndex ).expression() ) + evaluatedExpression = self.evaluateExpression( + layer, layer.defaultValueDefinition(fieldIndex).expression() + ) if evaluatedExpression is None: - feature[ fieldName ] = attributeExpression + feature[fieldName] = attributeExpression continue - feature[ fieldName ] = evaluatedExpression + feature[fieldName] = evaluatedExpression def evaluateExpression(self, layer, expression): context = core.QgsExpressionContext() - context.appendScopes( core.QgsExpressionContextUtils.globalProjectLayerScopes(layer) ) - return core.QgsExpression( expression ).evaluate( context ) + context.appendScopes( + core.QgsExpressionContextUtils.globalProjectLayerScopes(layer) + ) + return core.QgsExpression(expression).evaluate(context) def addFeatureWithForm(self, layer, feature): - #Método para adicionar a feição com formulário - #Parâmetro de entrada: layer (Camada ativa), feature (Feição adquirida) + # Método para adicionar a feição com formulário + # Parâmetro de entrada: layer (Camada ativa), feature (Feição adquirida) layer.beginEditCommand("dsgtools freehand feature added") - self.loadDefaultFields( layer, feature ) + self.loadDefaultFields(layer, feature) attrDialog = gui.QgsAttributeDialog(layer, feature, False) - attrDialog.setAttribute( QtCore.Qt.WA_DeleteOnClose ) - attrDialog.setMode( int( gui.QgsAttributeForm.AddFeatureMode ) ) + attrDialog.setAttribute(QtCore.Qt.WA_DeleteOnClose) + attrDialog.setMode(int(gui.QgsAttributeForm.AddFeatureMode)) res = attrDialog.exec_() if res == 0: layer.destroyEditCommand() @@ -303,15 +341,15 @@ def addFeatureWithForm(self, layer, feature): return res def addFeatureWithoutForm(self, layer, feature): - #Método para adicionar a feição sem formulário - #Parâmetro de entrada: layer (Camada ativa), feature (Feição adquirida) + # Método para adicionar a feição sem formulário + # Parâmetro de entrada: layer (Camada ativa), feature (Feição adquirida) layer.beginEditCommand("dsgtools freehand feature added") layer.addFeatures([feature]) layer.removeSelection() layer.endEditCommand() def activateTool(self): - #Método para iniciar a ferramenta + # Método para iniciar a ferramenta state = self.actionAcquisitionFree.isChecked() self.actionAcquisitionFree.setChecked(not state) self.setActiveState(state) diff --git a/DsgTools/gui/ProductionTools/MapTools/FreeHandTool/freeHandMain.py b/DsgTools/gui/ProductionTools/MapTools/FreeHandTool/freeHandMain.py index 156bbe831..797760506 100644 --- a/DsgTools/gui/ProductionTools/MapTools/FreeHandTool/freeHandMain.py +++ b/DsgTools/gui/ProductionTools/MapTools/FreeHandTool/freeHandMain.py @@ -24,31 +24,40 @@ from .models.acquisitionFree import AcquisitionFree from .controllers.acquisitionFreeController import AcquisitionFreeController -class FreeHandMain(QObject): +class FreeHandMain(QObject): def __init__(self, iface): - #construtor + # construtor super(FreeHandMain, self).__init__() self.iface = iface self.acquisitionFree = AcquisitionFree(iface) self.acquisitionFreeController = AcquisitionFreeController( - self.acquisitionFree, - iface + self.acquisitionFree, iface ) - def addTool(self, manager, callback, parentMenu, iconBasePath, parentButton=None, defaultButton=False): + def addTool( + self, + manager, + callback, + parentMenu, + iconBasePath, + parentButton=None, + defaultButton=False, + ): self.parentButton = parentButton - icon_path = iconBasePath + 'free_hand.png' + icon_path = iconBasePath + "free_hand.png" action = manager.add_action( icon_path, - text=self.tr('DSGTools: Free Hand Acquisition'), + text=self.tr("DSGTools: Free Hand Acquisition"), callback=self.run, add_to_menu=False, add_to_toolbar=False, withShortcut=True, - tooltip = self.tr('DSGTools: Free Hand Acquisition\nAcquires polygon or line features from mouse movement.'), + tooltip=self.tr( + "DSGTools: Free Hand Acquisition\nAcquires polygon or line features from mouse movement." + ), parentToolbar=parentMenu, - parentButton=parentButton + parentButton=parentButton, ) self.setAction(action) if defaultButton: @@ -56,7 +65,7 @@ def addTool(self, manager, callback, parentMenu, iconBasePath, parentButton=None def setAcquisitionFreeController(self, acquisitionFreeController): self.acquisitionFreeController = acquisitionFreeController - + def getAcquisitionFreeController(self): return self.acquisitionFreeController @@ -65,7 +74,7 @@ def toolAction(self): return self.getAction() def setIface(self, iface): - self.iface = iface + self.iface = iface def getIface(self): return self.iface @@ -85,4 +94,4 @@ def run(self): try: self.parentButton.setDefaultAction(self.action) except: - pass \ No newline at end of file + pass diff --git a/DsgTools/gui/ProductionTools/MapTools/FreeHandTool/freeHandReshape.py b/DsgTools/gui/ProductionTools/MapTools/FreeHandTool/freeHandReshape.py index 5d1664cd4..4a888b1d8 100644 --- a/DsgTools/gui/ProductionTools/MapTools/FreeHandTool/freeHandReshape.py +++ b/DsgTools/gui/ProductionTools/MapTools/FreeHandTool/freeHandReshape.py @@ -20,27 +20,37 @@ from .freeHandMain import FreeHandMain -class FreeHandReshape(FreeHandMain): +class FreeHandReshape(FreeHandMain): def __init__(self, iface): - #construtor + # construtor super(FreeHandReshape, self).__init__(iface) self.acquisitionFree.controlPressed = True - def addTool(self, manager, callback, parentMenu, iconBasePath, parentButton=None, defaultButton=False): + def addTool( + self, + manager, + callback, + parentMenu, + iconBasePath, + parentButton=None, + defaultButton=False, + ): self.parentButton = parentButton - icon_path = iconBasePath + 'free_hand_reshape.png' + icon_path = iconBasePath + "free_hand_reshape.png" action = manager.add_action( icon_path, - text=self.tr('DSGTools: Free Hand Reshape'), + text=self.tr("DSGTools: Free Hand Reshape"), callback=self.run, add_to_menu=False, add_to_toolbar=False, withShortcut=True, - tooltip = self.tr('DSGTools: Free Hand Reshape\nReshapes polygon or line features from mouse movement.'), + tooltip=self.tr( + "DSGTools: Free Hand Reshape\nReshapes polygon or line features from mouse movement." + ), parentToolbar=parentMenu, - parentButton=parentButton + parentButton=parentButton, ) self.setAction(action) if defaultButton: - self.parentButton.setDefaultAction(action) \ No newline at end of file + self.parentButton.setDefaultAction(action) diff --git a/DsgTools/gui/ProductionTools/MapTools/FreeHandTool/metadata.txt b/DsgTools/gui/ProductionTools/MapTools/FreeHandTool/metadata.txt index 09c61bd5e..718f16091 100644 --- a/DsgTools/gui/ProductionTools/MapTools/FreeHandTool/metadata.txt +++ b/DsgTools/gui/ProductionTools/MapTools/FreeHandTool/metadata.txt @@ -25,5 +25,3 @@ tags=digitizing ; in a future version of the web application it will ; be probably possible to create a project on redmine ; if they are not filled - - diff --git a/DsgTools/gui/ProductionTools/MapTools/FreeHandTool/models/acquisitionFree.py b/DsgTools/gui/ProductionTools/MapTools/FreeHandTool/models/acquisitionFree.py index 1b7e0aef0..3dcd0d705 100644 --- a/DsgTools/gui/ProductionTools/MapTools/FreeHandTool/models/acquisitionFree.py +++ b/DsgTools/gui/ProductionTools/MapTools/FreeHandTool/models/acquisitionFree.py @@ -23,14 +23,15 @@ from qgis.utils import iface from qgis.core import QgsGeometry + class AcquisitionFree(gui.QgsMapTool): - - #Sinal usado para enviar a geometria adquirida ao finalizar aquisição + + # Sinal usado para enviar a geometria adquirida ao finalizar aquisição acquisitionFinished = QtCore.pyqtSignal(QgsGeometry) reshapeLineCreated = QtCore.pyqtSignal(QgsGeometry) def __init__(self, iface): - #construtor + # construtor self.iface = iface self.canvas = iface.mapCanvas() super(AcquisitionFree, self).__init__(self.canvas) @@ -41,125 +42,131 @@ def __init__(self, iface): self.active = False self.contadorVert = 0 self.stopState = False - self.cur = QtGui.QCursor(QtGui.QPixmap(["18 13 4 1", - " c None", - "# c #FF0000", - ". c #FF0000", - "+ c #1210f3", - " ", - " +++++++++++ ", - " + # + ", - " + # + ", - "+ # +", - "+ # +", - "++#############++", - "+ # +", - "+ # +", - " + # +", - " + # + ", - " +++++++++++ ", - " ",])) + self.cur = QtGui.QCursor( + QtGui.QPixmap( + [ + "18 13 4 1", + " c None", + "# c #FF0000", + ". c #FF0000", + "+ c #1210f3", + " ", + " +++++++++++ ", + " + # + ", + " + # + ", + "+ # +", + "+ # +", + "++#############++", + "+ # +", + "+ # +", + " + # +", + " + # + ", + " +++++++++++ ", + " ", + ] + ) + ) self.controlPressed = False def setCursor(self, cursor): - #Método para definir cursor da ferramenta - #Parâmetro de entrada: cursor (cursor usado na ferramenta) - self.cur = cursor + # Método para definir cursor da ferramenta + # Parâmetro de entrada: cursor (cursor usado na ferramenta) + self.cur = cursor def getCursor(self): - #Método para obter cursor da ferramenta - #Parâmetro de retorno: cursor (cursor usado na ferramenta) + # Método para obter cursor da ferramenta + # Parâmetro de retorno: cursor (cursor usado na ferramenta) return self.cur def setCanvas(self, canvas): - #Método para definir o canvas do Qgis - #Parâmetro de entrada: canvas (Canvas do Qgis) + # Método para definir o canvas do Qgis + # Parâmetro de entrada: canvas (Canvas do Qgis) self.canvas = canvas def getCanvas(self): - #Método para obter o canvas do Qgis - #Parâmetro de retorno: canvas (Canvas do Qgis) + # Método para obter o canvas do Qgis + # Parâmetro de retorno: canvas (Canvas do Qgis) return self.canvas def setActiveState(self, state): - #Método para definir se a ferramenta está ativa ou não - #Parâmetro de entrada: state (Boleano) - self.active = state - + # Método para definir se a ferramenta está ativa ou não + # Parâmetro de entrada: state (Boleano) + self.active = state + def getActiveState(self): - #Método para obter se a ferramenta está ativa ou não - #Parâmetro de retorno: state (Boleano) + # Método para obter se a ferramenta está ativa ou não + # Parâmetro de retorno: state (Boleano) return self.active - + def setStopedState(self, state): - #Método para definir se a ferramenta está pausada - #Parâmetro de entrada: state (Boleano) + # Método para definir se a ferramenta está pausada + # Parâmetro de entrada: state (Boleano) self.stopState = state - + def getStopedState(self): - #Método para obter se a ferramenta está pausada - #Parâmetro de retorno: state (Boleano) + # Método para obter se a ferramenta está pausada + # Parâmetro de retorno: state (Boleano) return self.stopState def setDrawingState(self, state): - #Método para definir se a ferramenta está desenhando - #Parâmetro de entrada: state (Boleano) + # Método para definir se a ferramenta está desenhando + # Parâmetro de entrada: state (Boleano) self.drawing = state def getDrawingState(self): - #Método para obter se a ferramenta está desenhando - #Parâmetro de retorno: state (Boleano) + # Método para obter se a ferramenta está desenhando + # Parâmetro de retorno: state (Boleano) return self.drawing def setRubberBand(self, rb): - #Método para definir o rubberBand de aquisição - #Parâmetro de entrada: rb (rubberBand) + # Método para definir o rubberBand de aquisição + # Parâmetro de entrada: rb (rubberBand) self.rubberBand = rb def getRubberBand(self): - #Método para obter o rubberBand de aquisição - #Parâmetro de retorno: rb (rubberBand) + # Método para obter o rubberBand de aquisição + # Parâmetro de retorno: rb (rubberBand) return self.rubberBand def setRubberBandToStopState(self, rb): - #Método para definir o rubberBand de pausa da ferramenta - #Parâmetro de entrada: rb (rubberBand) + # Método para definir o rubberBand de pausa da ferramenta + # Parâmetro de entrada: rb (rubberBand) self.rubberBandToStopState = rb def getRubberBandToStopState(self): - #Método para obter o rubberBand de pausa da ferramenta - #Parâmetro de retorno: rb (rubberBand) + # Método para obter o rubberBand de pausa da ferramenta + # Parâmetro de retorno: rb (rubberBand) return self.rubberBandToStopState def setGeometryType(self, geomType): - #Método para definir o tipo da geometria - #Parâmetro de entrada: geomType (Tipo da geometria) + # Método para definir o tipo da geometria + # Parâmetro de entrada: geomType (Tipo da geometria) self.geometryType = geomType def getGeometryType(self): - #Método para obter o tipo da geometria - #Parâmetro de retorno: geomType (Tipo da geometria) + # Método para obter o tipo da geometria + # Parâmetro de retorno: geomType (Tipo da geometria) return self.geometryType def setSnapRubberBand(self, snapRb): - #Método para definir o rubberBand do snap - #Parâmetro de entrada: rb (rubberBand) - self.snapCursorRubberBand = snapRb + # Método para definir o rubberBand do snap + # Parâmetro de entrada: rb (rubberBand) + self.snapCursorRubberBand = snapRb def getSnapRubberBand(self): - #Método para obter o rubberBand do snap - #Parâmetro de entrada: rb (rubberBand) + # Método para obter o rubberBand do snap + # Parâmetro de entrada: rb (rubberBand) return self.snapCursorRubberBand def isPolygon(self): - #Método para testar se a camada atual é polígono - #Parâmetro de retorno: isPolygon (Boleano) - isPolygon = (self.getGeometryType() != core.QgsWkbTypes.LineGeometry) + # Método para testar se a camada atual é polígono + # Parâmetro de retorno: isPolygon (Boleano) + isPolygon = self.getGeometryType() != core.QgsWkbTypes.LineGeometry return isPolygon - + def keyPressEvent(self, event): - #Método para receber os eventos do teclado - #Parâmetro de entrada: event (Evento que chamou o método) + # Método para receber os eventos do teclado + # Parâmetro de entrada: event (Evento que chamou o método) if event.key() in [QtCore.Qt.Key_Delete, QtCore.Qt.Key_Backspace]: self.setStopedState(True) self.removeVertice() @@ -168,8 +175,8 @@ def keyPressEvent(self, event): self.cancelEdition() event.ignore() - def cancelEdition(self): - #Método para cancelar aquisição + def cancelEdition(self): + # Método para cancelar aquisição self.getRubberBand().reset() if self.getRubberBand() else None self.getRubberBandToStopState().reset() if self.getRubberBandToStopState() else None self.setRubberBand(None) @@ -177,18 +184,18 @@ def cancelEdition(self): self.setActiveState(False) self.contadorVert = 0 self.getCanvas().refresh() - + def getParametersFromConfig(self): - #Método para obter as configurações da tool do QSettings - #Parâmetro de retorno: parameters (Todas os parâmetros do QSettings usado na ferramenta) + # Método para obter as configurações da tool do QSettings + # Parâmetro de retorno: parameters (Todas os parâmetros do QSettings usado na ferramenta) settings = QtCore.QSettings() - settings.beginGroup('PythonPlugins/DsgTools/Options') - undoPoints = settings.value('undoPoints') + settings.beginGroup("PythonPlugins/DsgTools/Options") + undoPoints = settings.value("undoPoints") settings.endGroup() return int(undoPoints) - + def removeVertice(self): - #Método para remover vertices + # Método para remover vertices firstPoint = None lastPoint = None rubberBand = self.getRubberBand() @@ -198,13 +205,17 @@ def removeVertice(self): rubberBand.removeLastPoint() if not self.isPolygon(): lastPoint = rubberBand.asGeometry().asPolyline()[-1] - new_rubberBand = gui.QgsRubberBand(self.getCanvas(), core.QgsWkbTypes.LineGeometry) + new_rubberBand = gui.QgsRubberBand( + self.getCanvas(), core.QgsWkbTypes.LineGeometry + ) new_rubberBand.setColor(QtGui.QColor(255, 0, 0, 150)) - else: + else: if len(rubberBand.asGeometry().asPolygon()[0]) > 1: firstPoint = rubberBand.asGeometry().asPolygon()[0][0] lastPoint = rubberBand.asGeometry().asPolygon()[0][-2] - new_rubberBand = gui.QgsRubberBand(self.getCanvas(), core.QgsWkbTypes.PolygonGeometry) + new_rubberBand = gui.QgsRubberBand( + self.getCanvas(), core.QgsWkbTypes.PolygonGeometry + ) new_rubberBand.setColor(QtGui.QColor(255, 0, 0, 63)) new_rubberBand.setWidth(1) rubberBandToStopState = self.getRubberBandToStopState() @@ -217,30 +228,29 @@ def removeVertice(self): self.setRubberBandToStopState(new_rubberBand) elif rubberBand: self.setStopedState(False) - self.getRubberBandToStopState().reset() if self.getRubberBandToStopState() else '' + self.getRubberBandToStopState().reset() if self.getRubberBandToStopState() else "" self.cancelEdition() def createSnapCursor(self, point): - #Método para criar rubberBand do snap + # Método para criar rubberBand do snap rubberBand = self.getSnapRubberBand() if rubberBand: rubberBand.reset() else: rubberBand = gui.QgsRubberBand( - self.getCanvas(), - geometryType = core.QgsWkbTypes.PointGeometry + self.getCanvas(), geometryType=core.QgsWkbTypes.PointGeometry ) rubberBand.setColor(QtGui.QColor(255, 0, 0, 200)) rubberBand.setFillColor(QtGui.QColor(255, 0, 0, 40)) rubberBand.setWidth(5) rubberBand.setIcon(gui.QgsRubberBand.ICON_X) rubberBand.addPoint(point) - self.setSnapRubberBand(rubberBand) - + self.setSnapRubberBand(rubberBand) + def canvasReleaseEvent(self, event): - #Método para receber os eventos release do canvas do Qgis - #Parâmetro de entrada: event (Evento que chamou o método) - self.getRubberBandToStopState().reset() if self.getRubberBandToStopState() else '' + # Método para receber os eventos release do canvas do Qgis + # Parâmetro de entrada: event (Evento que chamou o método) + self.getRubberBandToStopState().reset() if self.getRubberBandToStopState() else "" if self.getStopedState(): self.setStopedState(False) elif self.getActiveState(): @@ -251,8 +261,8 @@ def canvasReleaseEvent(self, event): self.startEdition(event) def startEdition(self, event): - #Método para iniciar a aquisição - #Parâmetro de entrada: event (Evento) + # Método para iniciar a aquisição + # Parâmetro de entrada: event (Evento) snapRubberBand = self.getSnapRubberBand() if snapRubberBand: snapRubberBand.reset(geometryType=core.QgsWkbTypes.PointGeometry) @@ -260,29 +270,33 @@ def startEdition(self, event): self.setSnapRubberBand(None) layer = self.getCanvas().currentLayer() if layer: - mapPoint = event.snapPoint() + mapPoint = event.snapPoint() self.startRubberBand(mapPoint, layer) def startRubberBand(self, pointMap, layer): - #Método para iniciar o rubberBand da aquisição - #Parâmetro de entrada: pointMap (Primeiro ponto da feição em aquisição), layer (Camada ativa) + # Método para iniciar o rubberBand da aquisição + # Parâmetro de entrada: pointMap (Primeiro ponto da feição em aquisição), layer (Camada ativa) self.setDrawingState(True) self.setGeometryType(layer.geometryType()) if self.isPolygon(): - rubberBand = gui.QgsRubberBand(self.getCanvas(), core.QgsWkbTypes.PolygonGeometry) + rubberBand = gui.QgsRubberBand( + self.getCanvas(), core.QgsWkbTypes.PolygonGeometry + ) rubberBand.setColor(QtGui.QColor(255, 0, 0, 63)) rubberBand.setWidth(2) else: - rubberBand = gui.QgsRubberBand(self.getCanvas(), core.QgsWkbTypes.LineGeometry) + rubberBand = gui.QgsRubberBand( + self.getCanvas(), core.QgsWkbTypes.LineGeometry + ) rubberBand.setColor(QtGui.QColor(255, 0, 0, 150)) rubberBand.setWidth(1) rubberBand.addPoint(pointMap) self.setRubberBand(rubberBand) - + def canvasMoveEvent(self, event): - #Método para receber os eventos canvas move do Qgis - #Parâmetro de entrada: event (Evento que chamou o método) - if not(self.getStopedState()): + # Método para receber os eventos canvas move do Qgis + # Parâmetro de entrada: event (Evento que chamou o método) + if not (self.getStopedState()): snapRubberBand = self.getSnapRubberBand() if snapRubberBand: snapRubberBand.hide() @@ -291,21 +305,23 @@ def canvasMoveEvent(self, event): oldPoint = event.mapPoint() event.snapPoint() point = event.mapPoint() - self.createSnapCursor(point) if oldPoint != point else '' + self.createSnapCursor(point) if oldPoint != point else "" if self.getRubberBand() and self.getRubberBand().numberOfVertices() == 0: self.getRubberBand().addPoint(point) elif self.getRubberBand(): self.getRubberBand().addPoint(oldPoint) if self.getRubberBandToStopState(): - self.updateRubberBandToStopState( - self.toMapCoordinates( event.pos() ) - ) + self.updateRubberBandToStopState(self.toMapCoordinates(event.pos())) def updateRubberBandToStopState(self, point): - #Método para atualizar o rubberband do pause da ferramenta + # Método para atualizar o rubberband do pause da ferramenta rubberBand = self.getRubberBandToStopState() if rubberBand.asGeometry(): - listPoints = rubberBand.asGeometry().asPolygon() if self.isPolygon() else rubberBand.asGeometry().asPolyline() + listPoints = ( + rubberBand.asGeometry().asPolygon() + if self.isPolygon() + else rubberBand.asGeometry().asPolyline() + ) if self.isPolygon() and self.getRubberBand(): rubberBand.reset(geometryType=core.QgsWkbTypes.PolygonGeometry) firstPoint = self.getRubberBand().asGeometry().asPolygon()[0][0] @@ -313,12 +329,12 @@ def updateRubberBandToStopState(self, point): rubberBand.addPoint(secondPoint) rubberBand.addPoint(point) rubberBand.addPoint(firstPoint) - elif not(self.isPolygon()) and len(listPoints) >= 1: + elif not (self.isPolygon()) and len(listPoints) >= 1: rubberBand.removeLastPoint() rubberBand.addPoint(point) def finishEdition(self, event): - #Método para finalizar a aquisição + # Método para finalizar a aquisição if self.getRubberBand(): event.snapPoint() self.getRubberBand().addPoint(event.mapPoint()) @@ -333,7 +349,7 @@ def finishEdition(self, event): self.cancelEdition() def doReshape(self, geom): - line = '' + line = "" if geom.type() == core.QgsWkbTypes.LineGeometry: line = geom.asPolyline() elif geom.type() == core.QgsWkbTypes.PolygonGeometry: @@ -342,11 +358,11 @@ def doReshape(self, geom): else: line = geom.asPolygon()[0] del line[-1] - + self.reshapeLineCreated.emit(QgsGeometry.fromPolylineXY(line)) def activate(self): - #Método chamado ao ativar a ferramenta + # Método chamado ao ativar a ferramenta mapCanvas = self.getCanvas() mapCanvas.setCursor(self.getCursor()) diff --git a/DsgTools/gui/ProductionTools/MapTools/GenericSelectionTool/genericSelectionTool.py b/DsgTools/gui/ProductionTools/MapTools/GenericSelectionTool/genericSelectionTool.py index cffdfacb4..92ba5132d 100644 --- a/DsgTools/gui/ProductionTools/MapTools/GenericSelectionTool/genericSelectionTool.py +++ b/DsgTools/gui/ProductionTools/MapTools/GenericSelectionTool/genericSelectionTool.py @@ -27,20 +27,28 @@ from functools import partial from qgis.gui import QgsMapTool, QgsRubberBand -from qgis.core import QgsPointXY, QgsRectangle, QgsFeatureRequest, QgsVectorLayer, \ - QgsProject, QgsWkbTypes, QgsRasterLayer +from qgis.core import ( + QgsPointXY, + QgsRectangle, + QgsFeatureRequest, + QgsVectorLayer, + QgsProject, + QgsWkbTypes, + QgsRasterLayer, +) from qgis.PyQt.QtCore import Qt, QSettings from qgis.PyQt.QtGui import QColor, QCursor from qgis.PyQt.QtWidgets import QMenu, QApplication from DsgTools.core.GeometricTools.geometryHandler import GeometryHandler + class GenericSelectionTool(QgsMapTool): def __init__(self, iface): """ Tool Behaviours: (all behaviours start edition, except for rectangle one) - 1- Left Click: Clears previous selection, selects feature, sets feature layer as active layer. - The selection is done with the following priority: Point, Line then Polygon. + 1- Left Click: Clears previous selection, selects feature, sets feature layer as active layer. + The selection is done with the following priority: Point, Line then Polygon. Selection is only done in visible layer. 2- Control + Left Click: Adds to selection selected feature. This selection follows the priority in item 1. 3- Right Click: Opens feature form @@ -48,60 +56,50 @@ def __init__(self, iface): follows priority of item 1; 5- Shift + drag and drop: draws a rectangle, then features that intersect this rectangl'e are added to selection """ - self.iface = iface + self.iface = iface self.canvas = self.iface.mapCanvas() self.toolAction = None QgsMapTool.__init__(self, self.canvas) self.rubberBand = QgsRubberBand(self.canvas, QgsWkbTypes.PolygonGeometry) self.hoverRubberBand = QgsRubberBand(self.canvas, QgsWkbTypes.PolygonGeometry) - mFillColor = QColor( 254, 178, 76, 63 ) + mFillColor = QColor(254, 178, 76, 63) self.rubberBand.setColor(mFillColor) - self.hoverRubberBand.setColor(QColor( 255, 0, 0, 90 )) + self.hoverRubberBand.setColor(QColor(255, 0, 0, 90)) self.rubberBand.setWidth(1) self.reset() self.blackList = self.getBlackList() self.cursorChanged = False - self.cursorChangingHotkey = Qt.Key_Alt - self.menuHovered = False # indicates hovering actions over context menu + self.menuHovered = False # indicates hovering actions over context menu self.geometryHandler = GeometryHandler(iface=self.iface) - + def addTool(self, manager, callback, parentMenu, iconBasePath): - icon_path = iconBasePath + '/genericSelect.png' - toolTip = self.tr("DSGTools: Generic Selector\nLeft Click: select feature's layer and put it on edit mode\nRight Click: Open feature's form\nControl+Left Click: add/remove feature from selection\nShift+Left Click+drag and drop: select all features that intersects rubberband.") + icon_path = iconBasePath + "/genericSelect.png" + toolTip = self.tr( + "DSGTools: Generic Selector\nLeft Click: select feature's layer and put it on edit mode\nRight Click: Open feature's form\nControl+Left Click: add/remove feature from selection\nShift+Left Click+drag and drop: select all features that intersects rubberband." + ) action = manager.add_action( icon_path, - text=self.tr('DSGTools: Generic Selector'), + text=self.tr("DSGTools: Generic Selector"), callback=callback, add_to_menu=False, add_to_toolbar=True, - withShortcut = True, - tooltip = toolTip, - parentToolbar =parentMenu, - isCheckable = True + withShortcut=True, + tooltip=toolTip, + parentToolbar=parentMenu, + isCheckable=True, ) self.setAction(action) - - def keyPressEvent(self, e): - """ - Reimplemetation of keyPressEvent() in order to handle cursor changing hotkey (Alt). - """ - if e.key() == self.cursorChangingHotkey and not self.cursorChanged: - self.cursorChanged = True - QApplication.setOverrideCursor(QCursor(Qt.PointingHandCursor)) - else: - self.cursorChanged = False - QApplication.restoreOverrideCursor() - + def getBlackList(self): settings = QSettings() - settings.beginGroup('PythonPlugins/DsgTools/Options') - valueList = settings.value('valueList') + settings.beginGroup("PythonPlugins/DsgTools/Options") + valueList = settings.value("valueList") if valueList: - valueList = valueList.split(';') + valueList = valueList.split(";") return valueList else: - return ['moldura'] - + return ["moldura"] + def reset(self): """ Resets rubber band. @@ -109,29 +107,18 @@ def reset(self): self.startPoint = self.endPoint = None self.isEmittingPoint = False self.rubberBand.reset(QgsWkbTypes.PolygonGeometry) - - def keyPressEvent(self, e): - """ - Reimplemetation of keyPressEvent() in order to handle cursor changing hotkey (F2). - """ - if e.key() == self.cursorChangingHotkey and not self.cursorChanged: - self.cursorChanged = True - QApplication.setOverrideCursor(QCursor(Qt.PointingHandCursor)) - else: - self.cursorChanged = False - QApplication.restoreOverrideCursor() def canvasMoveEvent(self, e): """ Used only on rectangle select. """ if self.menuHovered: - # deactivates rubberband when the context menu is "destroyed" + # deactivates rubberband when the context menu is "destroyed" self.hoverRubberBand.reset(QgsWkbTypes.PolygonGeometry) if not self.isEmittingPoint: return - self.endPoint = self.toMapCoordinates( e.pos() ) - self.showRect(self.startPoint, self.endPoint) + self.endPoint = self.toMapCoordinates(e.pos()) + self.showRect(self.startPoint, self.endPoint) def showRect(self, startPoint, endPoint): """ @@ -144,11 +131,11 @@ def showRect(self, startPoint, endPoint): point2 = QgsPointXY(startPoint.x(), endPoint.y()) point3 = QgsPointXY(endPoint.x(), endPoint.y()) point4 = QgsPointXY(endPoint.x(), startPoint.y()) - + self.rubberBand.addPoint(point1, False) self.rubberBand.addPoint(point2, False) self.rubberBand.addPoint(point3, False) - self.rubberBand.addPoint(point4, True) # true to update canvas + self.rubberBand.addPoint(point4, True) # true to update canvas self.rubberBand.show() def rectangle(self): @@ -157,14 +144,17 @@ def rectangle(self): """ if self.startPoint is None or self.endPoint is None: return None - elif self.startPoint.x() == self.endPoint.x() or self.startPoint.y() == self.endPoint.y(): + elif ( + self.startPoint.x() == self.endPoint.x() + or self.startPoint.y() == self.endPoint.y() + ): return None return QgsRectangle(self.startPoint, self.endPoint) def setAction(self, action): self.toolAction = action self.toolAction.setCheckable(True) - + def canvasReleaseEvent(self, e): """ After the rectangle is built, here features are selected. @@ -177,16 +167,18 @@ def canvasReleaseEvent(self, e): return layers = self.canvas.layers() for layer in layers: - #ignore layers on black list and features that are not vector layers - if not isinstance(layer, QgsVectorLayer) or (self.layerHasPartInBlackList(layer.name())): + # ignore layers on black list and features that are not vector layers + if not isinstance(layer, QgsVectorLayer) or ( + self.layerHasPartInBlackList(layer.name()) + ): continue if firstGeom is not None and layer.geometryType() != firstGeom: # if there are features already selected, shift will only get the same type geometry # if more than one ty of geometry is present, only the strongest will be selected continue - #builds bbRect and select from layer, adding selection + # builds bbRect and select from layer, adding selection bbRect = self.canvas.mapSettings().mapToLayerCoordinates(layer, r) - layer.selectByRect(bbRect, behavior = QgsVectorLayer.AddToSelection) + layer.selectByRect(bbRect, behavior=QgsVectorLayer.AddToSelection) self.rubberBand.hide() def canvasPressEvent(self, e): @@ -202,15 +194,15 @@ def canvasPressEvent(self, e): else: self.isEmittingPoint = False self.createContextMenu(e) - + def getCursorRect(self, e): """ Calculates small cursor rectangle around mouse position. Used to facilitate operations """ p = self.toMapCoordinates(e.pos()) w = self.canvas.mapUnitsPerPixel() * 10 - return QgsRectangle(p.x()-w, p.y()-w, p.x()+w, p.y()+w) - + return QgsRectangle(p.x() - w, p.y() - w, p.x() + w, p.y() + w) + def layerHasPartInBlackList(self, lyrName): """ Verifies if terms in black list appear on lyrName @@ -219,35 +211,50 @@ def layerHasPartInBlackList(self, lyrName): if item.lower() in lyrName.lower(): return True return False - - def getPrimitiveDict(self, e, hasControlModifier=False): + + def getPrimitiveDict(self, e, hasControlModifier=False, hasAltModifier=False): """ Builds a dict with keys as geometryTypes of layer, which are Qgis.Point (value 0), Qgis.Line (value 1) or Qgis.Polygon (value 2), and values as layers from self.iface.mapCanvas().layers(). When self.iface.mapCanvas().layers() is called, a list of layers ordered according to lyr order in TOC is returned. """ - #these layers are ordered by view order + # these layers are ordered by view order primitiveDict = dict() firstGeom = self.checkSelectedLayers() visibleLayers = QgsProject.instance().layerTreeRoot().checkedLayers() - for lyr in self.iface.mapCanvas().layers(): #ordered layers - #layer types other than VectorLayer are ignored, as well as layers in black list and layers that are not visible - if not isinstance(lyr, QgsVectorLayer) or (self.layerHasPartInBlackList(lyr.name())) or lyr not in visibleLayers: + iterator = ( + self.iface.mapCanvas().layers() + if not hasAltModifier + else [self.iface.activeLayer()] + ) + for lyr in iterator: # ordered layers + # layer types other than VectorLayer are ignored, as well as layers in black list and layers that are not visible + if ( + not isinstance(lyr, QgsVectorLayer) + or (self.layerHasPartInBlackList(lyr.name())) + or lyr not in visibleLayers + ): continue - if hasControlModifier and (not firstGeom) and (not primitiveDict or lyr.geometryType() < firstGeom): + if ( + hasControlModifier + and (not firstGeom) + and (not primitiveDict or lyr.geometryType() < firstGeom) + ): firstGeom = lyr.geometryType() geomType = lyr.geometryType() if geomType not in primitiveDict: primitiveDict[geomType] = [] - #removes selection - if (not hasControlModifier and e.button() == Qt.LeftButton) or (hasControlModifier and e.button() == Qt.RightButton): + # removes selection + if (not hasControlModifier and e.button() == Qt.LeftButton) or ( + hasControlModifier and e.button() == Qt.RightButton + ): lyr.removeSelection() primitiveDict[geomType].append(lyr) if hasControlModifier and firstGeom in [0, 1, 2]: - return { firstGeom : primitiveDict[firstGeom] } + return {firstGeom: primitiveDict[firstGeom]} else: return primitiveDict - + def deactivate(self): """ Deactivate tool. @@ -271,15 +278,17 @@ def activate(self): self.toolAction.setChecked(True) QgsMapTool.activate(self) - def setSelectionFeature(self, layer, feature, selectAll=False, setActiveLayer=False): + def setSelectionFeature( + self, layer, feature, selectAll=False, setActiveLayer=False + ): """ - Selects a given feature on canvas. + Selects a given feature on canvas. :param layer: (QgsVectorLayer) layer containing the target feature. :param feature: (QgsFeature) taget feature to be selected. :param selectAll: (bool) indicates whether or not this fuction was called from a select all command. so it doesn't remove selection from those that are selected already from the list. :param setActiveLayer: (bool) indicates whether method should set layer as active. - """ + """ idList = layer.selectedFeatureIds() self.iface.setActiveLayer(layer) layer.startEditing() @@ -296,7 +305,7 @@ def setSelectionFeature(self, layer, feature, selectAll=False, setActiveLayer=Fa def setSelectionListFeature(self, dictLayerFeature, selectAll=True): """ - Selects all features on canvas of a given dict. + Selects all features on canvas of a given dict. :param dictLayerFeature: (dict) dict of layers/features to be selected. :param selectAll: (bool) indicates if "All"-command comes from a "Select All". In that case, selected features won't be deselected. @@ -315,7 +324,7 @@ def setSelectionListFeature(self, dictLayerFeature, selectAll=True): idList.pop(idList.index(featId)) layer.selectByIds(idList) layer.startEditing() - # last layer is set active and + # last layer is set active and self.iface.setActiveLayer(layer) def openMultipleFeatureForm(self, dictLayerFeature): @@ -346,11 +355,11 @@ def filterStrongestGeometry(self, dictLayerFeature): if lyr.geometryType() == strongest_geometry: outDict[lyr] = dictLayerFeature[lyr] return outDict - + def createRubberBand(self, feature, layer, geom): """ Creates a rubber band around from a given a standard feature string. - :param feature: taget feature to be highlighted + :param feature: taget feature to be highlighted :param layer: layer containing the target feature :param geom: int indicating geometry type of target feature """ @@ -423,20 +432,32 @@ def getCallback(self, e, layer, feature, geomType=None, selectAll=True): """ if not geomType: geomType = layer.geometryType() - if e.button() == Qt.LeftButton: + if e.button() == Qt.LeftButton: # line added to make sure the action is associated with current loop value, # lambda function is used with standard parameter set to current loops value. # triggeredAction = lambda t=[layer, feature] : self.setSelectionFeature(t[0], feature=t[1], selectAll=selectAll, setActiveLayer=True) - triggeredAction = partial(self.setSelectionFeature, layer=layer, feature=feature, selectAll=selectAll, setActiveLayer=True) - hoveredAction = partial(self.createRubberBand, feature=feature, layer=layer, geom=geomType) + triggeredAction = partial( + self.setSelectionFeature, + layer=layer, + feature=feature, + selectAll=selectAll, + setActiveLayer=True, + ) + hoveredAction = partial( + self.createRubberBand, feature=feature, layer=layer, geom=geomType + ) elif e.button() == Qt.RightButton: - selected = (QApplication.keyboardModifiers() == Qt.ControlModifier) + selected = QApplication.keyboardModifiers() == Qt.ControlModifier if selected: triggeredAction = partial(self.iface.setActiveLayer, layer) hoveredAction = None else: - triggeredAction = partial(self.iface.openFeatureForm, layer, feature, showModal=False) - hoveredAction = partial(self.createRubberBand, feature=feature, layer=layer, geom=geomType) + triggeredAction = partial( + self.iface.openFeatureForm, layer, feature, showModal=False + ) + hoveredAction = partial( + self.createRubberBand, feature=feature, layer=layer, geom=geomType + ) return triggeredAction, hoveredAction def getCallbackMultipleFeatures(self, e, dictLayerFeature, selectAll=True): @@ -448,16 +469,24 @@ def getCallbackMultipleFeatures(self, e, dictLayerFeature, selectAll=True): """ # setting the action for the "All" options if e.button() == Qt.LeftButton: - triggeredAction = partial(self.setSelectionListFeature, dictLayerFeature=dictLayerFeature, selectAll=selectAll) + triggeredAction = partial( + self.setSelectionListFeature, + dictLayerFeature=dictLayerFeature, + selectAll=selectAll, + ) else: - triggeredAction = partial(self.openMultipleFeatureForm, dictLayerFeature=dictLayerFeature) + triggeredAction = partial( + self.openMultipleFeatureForm, dictLayerFeature=dictLayerFeature + ) # to trigger "Hover" signal on QMenu for the multiple options - hoveredAction = partial(self.createMultipleRubberBand, dictLayerFeature=dictLayerFeature) + hoveredAction = partial( + self.createMultipleRubberBand, dictLayerFeature=dictLayerFeature + ) return triggeredAction, hoveredAction def createSubmenu(self, e, parentMenu, menuDict, genericAction, selectAll): """ - Creates a submenu in a given parent context menu and populates it, with classes/feature sublevels from the menuDict. + Creates a submenu in a given parent context menu and populates it, with classes/feature sublevels from the menuDict. :param e: (QMouseEvent) mouse event on canvas. If menuDict has only 1 class in it, method will populate parent QMenu. :param parentMenu: (QMenu) menu containing the populated submenu :param menuDict: (dict) dictionary containing all classes and their features to be filled into submenu. @@ -467,7 +496,7 @@ def createSubmenu(self, e, parentMenu, menuDict, genericAction, selectAll): # creating a dict to handle all "menu" for each class submenuDict = dict() # sort the layers from diciotnary - classNameDict = { cl.name() : cl for cl in menuDict } + classNameDict = {cl.name(): cl for cl in menuDict} layers = sorted(list(classNameDict.keys())) for className in layers: # menu for features of each class @@ -476,54 +505,92 @@ def createSubmenu(self, e, parentMenu, menuDict, genericAction, selectAll): # get layer database name dsUri = cl.dataProvider().dataSourceUri() temp = [] - if '/' in dsUri or '\\' in dsUri: + if "/" in dsUri or "\\" in dsUri: db_name = dsUri.split("|")[0] if "|" in dsUri else dsUri - db_name = os.path.basename(db_name.split("'")[1] if "'" in db_name else db_name) - elif 'memory' in dsUri: - db_name = self.tr('{0} (Memory Layer)').format(className) + db_name = os.path.basename( + db_name.split("'")[1] if "'" in db_name else db_name + ) + elif "memory" in dsUri: + db_name = self.tr("{0} (Memory Layer)").format(className) else: db_name = dsUri.split("'")[1] if len(menuDict) == 1: # if dictionaty has only 1 class, no need for an extra QMenu - features will be enlisted directly # order features by ID to be displayer ordered - featDict = { feat.id() : feat for feat in menuDict[cl] } + featDict = {feat.id(): feat for feat in menuDict[cl]} orderedFeatIdList = sorted(list(featDict.keys())) for featId in orderedFeatIdList: feat = featDict[featId] - s = "{db_name} | {className} (feat_id = {featId})".format(db_name=db_name, className=className, featId=featId) + s = "{db_name} | {className} (feat_id = {featId})".format( + db_name=db_name, className=className, featId=featId + ) # inserting action for each feature action = parentMenu.addAction(s) - triggeredAction, hoveredAction = self.getCallback(e=e, layer=cl, feature=feat, geomType=geomType, selectAll=selectAll) - self.addCallBackToAction(action=action, onTriggeredAction=triggeredAction, onHoveredAction=hoveredAction) + triggeredAction, hoveredAction = self.getCallback( + e=e, + layer=cl, + feature=feat, + geomType=geomType, + selectAll=selectAll, + ) + self.addCallBackToAction( + action=action, + onTriggeredAction=triggeredAction, + onHoveredAction=hoveredAction, + ) # inserting generic action, if necessary if len(menuDict[cl]) > 1: # if there are more than 1 feature to be filled, "All"-command should be added - action = parentMenu.addAction(self.tr("{0} From Class {1}").format(genericAction, className)) - triggeredAction, hoveredAction = self.getCallbackMultipleFeatures(e=e, dictLayerFeature=menuDict, selectAll=selectAll) - self.addCallBackToAction(action=action, onTriggeredAction=triggeredAction, onHoveredAction=hoveredAction) + action = parentMenu.addAction( + self.tr("{0} From Class {1}").format(genericAction, className) + ) + triggeredAction, hoveredAction = self.getCallbackMultipleFeatures( + e=e, dictLayerFeature=menuDict, selectAll=selectAll + ) + self.addCallBackToAction( + action=action, + onTriggeredAction=triggeredAction, + onHoveredAction=hoveredAction, + ) # there is no mapping of class to be exposed, only information added to parent QMenu itself return dict() - title = "{db_name} | {className}".format(db_name=db_name, className=className) + title = "{db_name} | {className}".format( + db_name=db_name, className=className + ) submenuDict[cl] = QMenu(title=title, parent=parentMenu) parentMenu.addMenu(submenuDict[cl]) # inserting an entry for every feature of each class in its own context menu # order features by ID to be displayer ordered - featDict = { feat.id() : feat for feat in menuDict[cl] } + featDict = {feat.id(): feat for feat in menuDict[cl]} orderedFeatIdList = sorted(list(featDict.keys())) for featId in orderedFeatIdList: feat = featDict[featId] - s = 'feat_id = {0}'.format(featId) + s = "feat_id = {0}".format(featId) action = submenuDict[cl].addAction(s) - triggeredAction, hoveredAction = self.getCallback(e=e, layer=cl, feature=feat, geomType=geomType, selectAll=selectAll) - self.addCallBackToAction(action=action, onTriggeredAction=triggeredAction, onHoveredAction=hoveredAction) + triggeredAction, hoveredAction = self.getCallback( + e=e, layer=cl, feature=feat, geomType=geomType, selectAll=selectAll + ) + self.addCallBackToAction( + action=action, + onTriggeredAction=triggeredAction, + onHoveredAction=hoveredAction, + ) # set up list for the "All"-commands temp.append([cl, feat, geomType]) # adding generic action for each class if len(menuDict[cl]) > 1: # if there are more than 1 feature to be filled, "All"-command should be added - action = submenuDict[cl].addAction(self.tr("{0} From Class {1}").format(genericAction, className)) - triggeredAction, hoveredAction = self.getCallbackMultipleFeatures(e=e, dictLayerFeature={ cl : menuDict[cl] }, selectAll=selectAll) - self.addCallBackToAction(action=action, onTriggeredAction=triggeredAction, onHoveredAction=hoveredAction) + action = submenuDict[cl].addAction( + self.tr("{0} From Class {1}").format(genericAction, className) + ) + triggeredAction, hoveredAction = self.getCallbackMultipleFeatures( + e=e, dictLayerFeature={cl: menuDict[cl]}, selectAll=selectAll + ) + self.addCallBackToAction( + action=action, + onTriggeredAction=triggeredAction, + onHoveredAction=hoveredAction, + ) return submenuDict def setContextMenuStyle(self, e, dictMenuSelected, dictMenuNotSelected): @@ -538,54 +605,97 @@ def setContextMenuStyle(self, e, dictMenuSelected, dictMenuNotSelected): selectedDict = bool(dictMenuSelected) notSelectedDict = bool(dictMenuNotSelected) # finding out if one of either dictionaty are filled ("Exclusive or") - selectedXORnotSelected = (selectedDict != notSelectedDict) + selectedXORnotSelected = selectedDict != notSelectedDict # setting "All"-command name if e.button() == Qt.RightButton: - genericAction = self.tr('Open All Feature Forms') + genericAction = self.tr("Open All Feature Forms") else: - genericAction = self.tr('Select All Features') + genericAction = self.tr("Select All Features") # in case one of given dict is empty if selectedXORnotSelected: if selectedDict: - menuDict, menu = dictMenuSelected, QMenu(title=self.tr('Selected Features')) - genericAction = self.tr('Deselect All Features') + menuDict, menu = dictMenuSelected, QMenu( + title=self.tr("Selected Features") + ) + genericAction = self.tr("Deselect All Features") # if the dictionary is from selected features, we want commands to be able to deselect them selectAll = False else: - menuDict, menu = dictMenuNotSelected, QMenu(title=self.tr('Not Selected Features')) - genericAction = self.tr('Select All Features') + menuDict, menu = dictMenuNotSelected, QMenu( + title=self.tr("Not Selected Features") + ) + genericAction = self.tr("Select All Features") # if the dictionary is from non-selected features, we want commands to be able to select them selectAll = True if e.button() == Qt.RightButton: - genericAction = self.tr('Open All Feature Forms') - self.createSubmenu(e=e, parentMenu=menu, menuDict=menuDict, genericAction=genericAction, selectAll=selectAll) + genericAction = self.tr("Open All Feature Forms") + self.createSubmenu( + e=e, + parentMenu=menu, + menuDict=menuDict, + genericAction=genericAction, + selectAll=selectAll, + ) if len(menuDict) != 1 and len(list(menuDict.values())) > 1: # if there's only one class, "All"-command is given by createSubmenu method action = menu.addAction(genericAction) - triggeredAction, hoveredAction = self.getCallbackMultipleFeatures(e=e, dictLayerFeature=menuDict, selectAll=selectAll) - self.addCallBackToAction(action=action, onTriggeredAction=triggeredAction, onHoveredAction=hoveredAction) + triggeredAction, hoveredAction = self.getCallbackMultipleFeatures( + e=e, dictLayerFeature=menuDict, selectAll=selectAll + ) + self.addCallBackToAction( + action=action, + onTriggeredAction=triggeredAction, + onHoveredAction=hoveredAction, + ) elif selectedDict: # if both of them is empty one more QMenu level is added menu = QMenu() - selectedMenu = QMenu(title=self.tr('Selected Features')) - notSelectedMenu = QMenu(title=self.tr('Not Selected Features')) + selectedMenu = QMenu(title=self.tr("Selected Features")) + notSelectedMenu = QMenu(title=self.tr("Not Selected Features")) menu.addMenu(selectedMenu) menu.addMenu(notSelectedMenu) - selectedGenericAction = self.tr('Deselect All Features') - notSelectedGenericAction = self.tr('Select All Features') + selectedGenericAction = self.tr("Deselect All Features") + notSelectedGenericAction = self.tr("Select All Features") # selectAll is set to True as now we want command to Deselect Features in case they are selected - self.createSubmenu(e=e, parentMenu=selectedMenu, menuDict=dictMenuSelected, genericAction=selectedGenericAction, selectAll=False) + self.createSubmenu( + e=e, + parentMenu=selectedMenu, + menuDict=dictMenuSelected, + genericAction=selectedGenericAction, + selectAll=False, + ) if len(dictMenuSelected) != 1 and len(list(dictMenuSelected.values())) > 1: # if there's only one class, "All"-command is given by createSubmenu method action = selectedMenu.addAction(selectedGenericAction) - triggeredAction, hoveredAction = self.getCallbackMultipleFeatures(e=e, dictLayerFeature=dictMenuSelected, selectAll=False) - self.addCallBackToAction(action=action, onTriggeredAction=triggeredAction, onHoveredAction=hoveredAction) - self.createSubmenu(e=e, parentMenu=notSelectedMenu, menuDict=dictMenuNotSelected, genericAction=notSelectedGenericAction, selectAll=True) - if len(dictMenuNotSelected) != 1 and len(list(dictMenuNotSelected.values())) > 1: + triggeredAction, hoveredAction = self.getCallbackMultipleFeatures( + e=e, dictLayerFeature=dictMenuSelected, selectAll=False + ) + self.addCallBackToAction( + action=action, + onTriggeredAction=triggeredAction, + onHoveredAction=hoveredAction, + ) + self.createSubmenu( + e=e, + parentMenu=notSelectedMenu, + menuDict=dictMenuNotSelected, + genericAction=notSelectedGenericAction, + selectAll=True, + ) + if ( + len(dictMenuNotSelected) != 1 + and len(list(dictMenuNotSelected.values())) > 1 + ): # if there's only one class, "All"-command is given by createSubmenu method action = notSelectedMenu.addAction(notSelectedGenericAction) - triggeredAction, hoveredAction = self.getCallbackMultipleFeatures(e=e, dictLayerFeature=dictMenuNotSelected, selectAll=True) - self.addCallBackToAction(action=action, onTriggeredAction=triggeredAction, onHoveredAction=hoveredAction) + triggeredAction, hoveredAction = self.getCallbackMultipleFeatures( + e=e, dictLayerFeature=dictMenuNotSelected, selectAll=True + ) + self.addCallBackToAction( + action=action, + onTriggeredAction=triggeredAction, + onHoveredAction=hoveredAction, + ) menu.exec_(self.canvas.viewport().mapToGlobal(e.pos())) def checkSelectedFeaturesOnDict(self, menuDict): @@ -610,24 +720,11 @@ def checkSelectedFeaturesOnDict(self, menuDict): notSelectedFeaturesDict[cl].append(feat) return selectedFeaturesDict, notSelectedFeaturesDict - def getSelectedRasters(self, e): - rasters = [] - rect = self.getCursorRect(e) - layers = self.iface.mapCanvas().layers() - for layer in self.iface.mapCanvas().layers(): - if not isinstance(layer, QgsRasterLayer): - continue - bbRect = self.canvas.mapSettings().mapToLayerCoordinates(layer, rect) - if not layer.extent().intersects(bbRect): - continue - rasters.append(layer) - return rasters - def addRasterMenu(self, menu, rasters): rasterMenu = QMenu(title="Rasters", parent=menu) for raster in rasters: action = rasterMenu.addAction(raster.name()) - action.triggered.connect(lambda : self.iface.setActiveLayer(raster)) + action.triggered.connect(lambda: self.iface.setActiveLayer(raster)) menu.addMenu(rasterMenu) def createContextMenu(self, e): @@ -635,75 +732,86 @@ def createContextMenu(self, e): Creates the context menu for overlapping layers. :param e: mouse event caught from canvas. """ - selected = (QApplication.keyboardModifiers() == Qt.ControlModifier) + selected = QApplication.keyboardModifiers() == Qt.ControlModifier if selected: firstGeom = self.checkSelectedLayers() # setting a list of features to iterate over - layerList = self.getPrimitiveDict(e, hasControlModifier=selected) + layerList = self.getPrimitiveDict( + e, + hasControlModifier=selected, + hasAltModifier=QApplication.keyboardModifiers() == Qt.AltModifier, + ) layers = [] for key in layerList: layers += layerList[key] - if layers: - rect = self.getCursorRect(e) - lyrFeatDict = dict() - for layer in layers: - if not isinstance(layer, QgsVectorLayer): + if not layers: + return + rect = self.getCursorRect(e) + lyrFeatDict = dict() + for layer in layers: + if not isinstance(layer, QgsVectorLayer): + continue + geomType = layer.geometryType() + # iterate over features inside the mouse bounding box + bbRect = self.canvas.mapSettings().mapToLayerCoordinates(layer, rect) + for feature in layer.getFeatures(QgsFeatureRequest(bbRect)): + geom = feature.geometry() + if not geom: continue - geomType = layer.geometryType() - # iterate over features inside the mouse bounding box - bbRect = self.canvas.mapSettings().mapToLayerCoordinates(layer, rect) - for feature in layer.getFeatures(QgsFeatureRequest(bbRect)): - geom = feature.geometry() - if geom: - searchRect = self.geometryHandler.reprojectSearchArea(layer, rect) - if selected: - # if Control was held, appending behaviour is different - if not firstGeom: - firstGeom = geomType - elif firstGeom > geomType: - firstGeom = geomType - if geomType == firstGeom and geom.intersects(searchRect): - # only appends features if it has the same geometry as first selected feature - if layer in lyrFeatDict: - lyrFeatDict[layer].append(feature) - else: - lyrFeatDict[layer] = [feature] + searchRect = self.geometryHandler.reprojectSearchArea(layer, rect) + if selected: + # if Control was held, appending behaviour is different + if not firstGeom: + firstGeom = geomType + elif firstGeom > geomType: + firstGeom = geomType + if geomType == firstGeom and geom.intersects(searchRect): + # only appends features if it has the same geometry as first selected feature + if layer in lyrFeatDict: + lyrFeatDict[layer].append(feature) else: - if geom.intersects(searchRect): - if layer in lyrFeatDict: - lyrFeatDict[layer].append(feature) - else: - lyrFeatDict[layer] = [feature] - lyrFeatDict = self.filterStrongestGeometry(lyrFeatDict) - #rasters = self.getSelectedRasters(e) - if lyrFeatDict: - moreThanOneFeat = len(list(lyrFeatDict.values())) > 1 or len(list(lyrFeatDict.values())[0]) > 1 - if moreThanOneFeat: - # if there are overlapping features (valid candidates only) - selectedFeaturesDict, notSelectedFeaturesDict = self.checkSelectedFeaturesOnDict(menuDict=lyrFeatDict) - self.setContextMenuStyle( - e=e, - dictMenuSelected=selectedFeaturesDict, - dictMenuNotSelected=notSelectedFeaturesDict - ) + lyrFeatDict[layer] = [feature] else: - layer = list(lyrFeatDict.keys())[0] - feature = lyrFeatDict[layer][0] - selected = (QApplication.keyboardModifiers() == Qt.ControlModifier) - if e.button() == Qt.LeftButton: - # if feature is selected, we want it to be de-selected - self.setSelectionFeature(layer=layer, feature=feature, selectAll=False, setActiveLayer=True) - elif selected: - self.iface.setActiveLayer(layer) + if not geom.intersects(searchRect): + continue + if layer in lyrFeatDict: + lyrFeatDict[layer].append(feature) else: - self.iface.openFeatureForm(layer, feature, showModal=False) - #elif rasters and e.button() == Qt.LeftButton: - # self.openRastersMenu(e, rasters) - - def openRastersMenu(self, e, rasters): - menu = QMenu() - self.addRasterMenu(menu, rasters) - menu.exec_(self.canvas.viewport().mapToGlobal(e.pos())) + lyrFeatDict[layer] = [feature] + lyrFeatDict = self.filterStrongestGeometry(lyrFeatDict) + if not lyrFeatDict: + return + moreThanOneFeat = ( + len(list(lyrFeatDict.values())) > 1 + or len(list(lyrFeatDict.values())[0]) > 1 + ) + if moreThanOneFeat: + # if there are overlapping features (valid candidates only) + ( + selectedFeaturesDict, + notSelectedFeaturesDict, + ) = self.checkSelectedFeaturesOnDict(menuDict=lyrFeatDict) + self.setContextMenuStyle( + e=e, + dictMenuSelected=selectedFeaturesDict, + dictMenuNotSelected=notSelectedFeaturesDict, + ) + else: + layer = list(lyrFeatDict.keys())[0] + feature = lyrFeatDict[layer][0] + selected = QApplication.keyboardModifiers() == Qt.ControlModifier + if e.button() == Qt.LeftButton: + # if feature is selected, we want it to be de-selected + self.setSelectionFeature( + layer=layer, + feature=feature, + selectAll=False, + setActiveLayer=True, + ) + elif selected: + self.iface.setActiveLayer(layer) + else: + self.iface.openFeatureForm(layer, feature, showModal=False) def unload(self): self.deactivate() diff --git a/DsgTools/gui/ProductionTools/MapTools/LabelTogglingTool/labelTogglingTool.py b/DsgTools/gui/ProductionTools/MapTools/LabelTogglingTool/labelTogglingTool.py index 776492f8a..06927249d 100644 --- a/DsgTools/gui/ProductionTools/MapTools/LabelTogglingTool/labelTogglingTool.py +++ b/DsgTools/gui/ProductionTools/MapTools/LabelTogglingTool/labelTogglingTool.py @@ -26,68 +26,76 @@ from qgis.gui import QgsMapTool from qgis.core import QgsProject, QgsVectorLayer + class LabelTogglingTool(QgsMapTool): AllLayers, SelectedLayers, ActiveLayer = range(3) + def __init__(self, iface): """ Hides or show active layers labels. """ - self.iface = iface + self.iface = iface self.canvas = self.iface.mapCanvas() super(LabelTogglingTool, self).__init__(self.canvas) - + def addTool(self, manager, callback, parentToolbar, stackButton, iconBasePath): self.stackButton = stackButton - icon_path = iconBasePath + '/toggleAllLabels.png' + icon_path = iconBasePath + "/toggleAllLabels.png" toolTip = self.tr("DSGTools: Toggle all labels visibility") action = manager.add_action( icon_path, - text=self.tr('DSGTools: Toggle all labels visibility'), - callback=partial(self.run, mode=LabelTogglingTool.AllLayers, iface=self.iface), + text=self.tr("DSGTools: Toggle all labels visibility"), + callback=partial( + self.run, mode=LabelTogglingTool.AllLayers, iface=self.iface + ), add_to_menu=False, add_to_toolbar=False, withShortcut=True, tooltip=toolTip, parentButton=self.stackButton, - isCheckable=False + isCheckable=False, ) self.setAction(action) self.stackButton.setDefaultAction(action) - icon_path = iconBasePath + '/toggleSelectedLayersLabel.png' + icon_path = iconBasePath + "/toggleSelectedLayersLabel.png" toolTip = self.tr("DSGTools: Toggle selected layers' labels visibility") action = manager.add_action( icon_path, text=self.tr("DSGTools: Toggle selected layers' label visibility"), - callback=partial(self.run, mode=LabelTogglingTool.SelectedLayers, iface=self.iface), + callback=partial( + self.run, mode=LabelTogglingTool.SelectedLayers, iface=self.iface + ), add_to_menu=False, add_to_toolbar=False, withShortcut=True, tooltip=toolTip, parentButton=self.stackButton, - isCheckable=False + isCheckable=False, ) - self.setAction(action) + self.setAction(action) - icon_path = iconBasePath + '/toggleActiveLayerLabel.png' + icon_path = iconBasePath + "/toggleActiveLayerLabel.png" toolTip = self.tr("DSGTools: Toggle active layer' label visibility") action = manager.add_action( icon_path, text=self.tr("DSGTools: Toggle active layer' label visibility"), - callback=partial(self.run, mode=LabelTogglingTool.ActiveLayer, iface=self.iface), + callback=partial( + self.run, mode=LabelTogglingTool.ActiveLayer, iface=self.iface + ), add_to_menu=False, add_to_toolbar=False, withShortcut=True, tooltip=toolTip, parentButton=self.stackButton, - isCheckable=False + isCheckable=False, ) self.setAction(action) def setAction(self, action): self.toolAction = action - + def deactivate(self): """ Deactivate tool. @@ -107,7 +115,7 @@ def run(self, iface, mode=None): self.stackButton.setDefaultAction(self.sender()) except: pass - for lyr in self.getLayers(iface, mode): #ordered layers + for lyr in self.getLayers(iface, mode): # ordered layers if not isinstance(lyr, QgsVectorLayer): continue lyr.setLabelsEnabled(not lyr.labelsEnabled()) diff --git a/DsgTools/gui/ProductionTools/MapTools/SelectRasterTool/selectRaster.py b/DsgTools/gui/ProductionTools/MapTools/SelectRasterTool/selectRaster.py index 0cdadc00b..877773b33 100644 --- a/DsgTools/gui/ProductionTools/MapTools/SelectRasterTool/selectRaster.py +++ b/DsgTools/gui/ProductionTools/MapTools/SelectRasterTool/selectRaster.py @@ -29,50 +29,30 @@ class SelectRasterTool(QgsMapTool): def __init__(self, iface): self.rasters = [] - self.iface = iface + self.iface = iface self.canvas = self.iface.mapCanvas() super(SelectRasterTool, self).__init__(self.canvas) - + def addTool(self, manager, callback, parentToolbar, iconBasePath): - icon_path = iconBasePath + '/selectRaster.png' + icon_path = iconBasePath + "/selectRaster.png" toolTip = self.tr("DSGTools: Select Raster") action = manager.add_action( icon_path, - text=self.tr('DSGTools: Select Raster'), + text=self.tr("DSGTools: Select Raster"), callback=callback, add_to_menu=False, add_to_toolbar=False, - withShortcut = True, - tooltip = toolTip, + withShortcut=True, + tooltip=toolTip, parentToolbar=parentToolbar, - isCheckable = True + isCheckable=True, ) self.setAction(action) - + def setAction(self, action): self.toolAction = action self.toolAction.setCheckable(True) - - # def activate(self): - # """ - # Activate tool. - # """ - # if self.toolAction: - # self.toolAction.setChecked(True) - # QgsMapTool.activate(self) - - # def deactivate(self): - # """ - # Deactivate tool. - # """ - # try: - # if self.toolAction: - # self.toolAction.setChecked(False) - # if self is not None: - # QgsMapTool.deactivate(self) - # except: - # pass - + def canvasPressEvent(self, e): self.run() @@ -113,7 +93,10 @@ def addRasterMenu(self, menu, rasters): for raster in rasters: action = rasterMenu.addAction(raster.name()) action.triggered.connect(lambda b, raster=raster: self.selectOnly(raster)) - # menu.addMenu(rasterMenu) + dummyAction = rasterMenu.addAction("") + dummyAction.setSeparator(True) + action = rasterMenu.addAction(self.tr("Deselect all rasters")) + action.triggered.connect(lambda x: self.selectAll(visible=False)) def selectOnly(self, raster): for otherRaster in self.rasters: @@ -121,6 +104,13 @@ def selectOnly(self, raster): otherRaster, otherRaster.id() == raster.id() ) self.toolAction.setChecked(False) + + def selectAll(self, visible=True): + for otherRaster in self.rasters: + self.iface.layerTreeView().setLayerVisible( + otherRaster, visible + ) + self.toolAction.setChecked(False) def unload(self): self.deactivate() diff --git a/DsgTools/gui/ProductionTools/MapTools/ShortcutTool/shortcutTool.py b/DsgTools/gui/ProductionTools/MapTools/ShortcutTool/shortcutTool.py index d1a1c84f1..e747bf274 100644 --- a/DsgTools/gui/ProductionTools/MapTools/ShortcutTool/shortcutTool.py +++ b/DsgTools/gui/ProductionTools/MapTools/ShortcutTool/shortcutTool.py @@ -27,31 +27,32 @@ from qgis.core import QgsProject, QgsVectorLayer + class ShortcutTool(QObject): def __init__(self, iface): """ Hides or show active layers labels. """ - self.iface = iface + self.iface = iface super(ShortcutTool, self).__init__() - + def addTool(self, manager, callback, parentToolbar, stackButton, iconBasePath): self.stackButton = stackButton - icon_path = iconBasePath + '/on_off.png' + icon_path = iconBasePath + "/on_off.png" toolTip = self.tr("DSGTools: Active Layer visibility") action = manager.add_action( icon_path, - text=self.tr('DSGTools: Active Layer visibility'), + text=self.tr("DSGTools: Active Layer visibility"), callback=self.hideOrShowActiveLayer, add_to_menu=False, add_to_toolbar=False, withShortcut=True, tooltip=toolTip, parentButton=stackButton, - isCheckable=False + isCheckable=False, ) - icon_path = iconBasePath + '/vertex.png' + icon_path = iconBasePath + "/vertex.png" toolTip = self.tr("DSGTools: Toggle vertex's marker visibility") action = manager.add_action( icon_path, @@ -62,7 +63,7 @@ def addTool(self, manager, callback, parentToolbar, stackButton, iconBasePath): withShortcut=True, tooltip=toolTip, parentButton=stackButton, - isCheckable=False + isCheckable=False, ) def hideOrShowMarkers(self): @@ -71,8 +72,8 @@ def hideOrShowMarkers(self): except: pass qSettings = QSettings() - currentState = qSettings.value(u'qgis/digitizing/marker_only_for_selected') - qSettings.setValue(u'qgis/digitizing/marker_only_for_selected', not currentState) + currentState = qSettings.value("qgis/digitizing/marker_only_for_selected") + qSettings.setValue("qgis/digitizing/marker_only_for_selected", not currentState) self.iface.mapCanvas().refresh() def hideOrShowActiveLayer(self): @@ -83,8 +84,9 @@ def hideOrShowActiveLayer(self): activeLayer = self.iface.activeLayer() layerTreeRoot = QgsProject.instance().layerTreeRoot() layerVisibilityState = activeLayer in layerTreeRoot.checkedLayers() - layerTreeRoot.findLayer(activeLayer.id()).setItemVisibilityChecked(not layerVisibilityState) - + layerTreeRoot.findLayer(activeLayer.id()).setItemVisibilityChecked( + not layerVisibilityState + ) + def unload(self): pass - diff --git a/DsgTools/gui/ProductionTools/MapTools/mapToolsGuiManager.py b/DsgTools/gui/ProductionTools/MapTools/mapToolsGuiManager.py index dbed4d8a4..44d89a87d 100644 --- a/DsgTools/gui/ProductionTools/MapTools/mapToolsGuiManager.py +++ b/DsgTools/gui/ProductionTools/MapTools/mapToolsGuiManager.py @@ -25,7 +25,9 @@ import os.path import sys from DsgTools.gui.ProductionTools.MapTools.AuxTools.spatialFilter import SpatialFilter -from DsgTools.gui.ProductionTools.MapTools.SelectRasterTool.selectRaster import SelectRasterTool +from DsgTools.gui.ProductionTools.MapTools.SelectRasterTool.selectRaster import ( + SelectRasterTool, +) from qgis.PyQt.QtCore import pyqtSignal from qgis.core import QgsVectorLayer @@ -41,83 +43,140 @@ from .AuxTools.otherTools import OtherTools from qgis.PyQt.QtCore import QObject + class MapToolsGuiManager(QObject): # signals to replicate current layer's editing started/stopped signal editingStarted = pyqtSignal() editingStopped = pyqtSignal() - def __init__(self, manager, iface, parentMenu = None, toolbar = None): - """Constructor. - """ + def __init__(self, manager, iface, parentMenu=None, toolbar=None): + """Constructor.""" super(MapToolsGuiManager, self).__init__() self.manager = manager self.iface = iface self.parentMenu = parentMenu self.toolbar = toolbar - self.toolbar_extra = self.iface.addToolBar(u'DsgTools_ExtraTools') - self.toolbar_extra.setObjectName(u'DsgTools_ExtraTools') - self.iconBasePath = ':/plugins/DsgTools/icons/' + self.toolbar_extra = self.iface.addToolBar("DsgTools_ExtraTools") + self.toolbar_extra.setObjectName("DsgTools_ExtraTools") + self.iconBasePath = ":/plugins/DsgTools/icons/" # initiate current layer and make sure signals are connected self.currentLayer = None self.resetCurrentLayerSignals() self.iface.currentLayerChanged.connect(self.resetCurrentLayerSignals) def initGui(self): - #adding generic selection tool + # adding generic selection tool self.genericTool = GenericSelectionTool(self.iface) - self.genericTool.addTool(self.manager, self.activateGenericTool, self.parentMenu, self.iconBasePath) - #adding flip line tool + self.genericTool.addTool( + self.manager, self.activateGenericTool, self.parentMenu, self.iconBasePath + ) + # adding flip line tool self.flipLineTool = FlipLine(self.iface) - self.flipLineTool.addTool(self.manager, self.flipLineTool.startFlipLineTool, self.parentMenu, self.iconBasePath) + self.flipLineTool.addTool( + self.manager, + self.flipLineTool.startFlipLineTool, + self.parentMenu, + self.iconBasePath, + ) self.flipLineTool.setToolEnabled(self.iface.mapCanvas().currentLayer()) - #adding acquisition + # adding acquisition self.acquisition = Acquisition(self.iface) self.acquisition.addTool(self.manager, None, self.parentMenu, self.iconBasePath) self.acquisition.setToolEnabled() - #adding stack - self.freeHandStackButton = self.manager.createToolButton(self.toolbar, u'FreeHandTools') - #adding free hand tool (acquisition) + # adding stack + self.freeHandStackButton = self.manager.createToolButton( + self.toolbar, "FreeHandTools" + ) + # adding free hand tool (acquisition) self.freeHandAcquisiton = FreeHandMain(self.iface) - self.freeHandAcquisiton.addTool(self.manager, None, self.parentMenu, self.iconBasePath, parentButton=self.freeHandStackButton, defaultButton=True) + self.freeHandAcquisiton.addTool( + self.manager, + None, + self.parentMenu, + self.iconBasePath, + parentButton=self.freeHandStackButton, + defaultButton=True, + ) self.freeHandAcquisiton.acquisitionFreeController.setToolEnabled() - #adding free hand tool (acquisition) + # adding free hand tool (acquisition) self.freeHandReshape = FreeHandReshape(self.iface) - self.freeHandReshape.addTool(self.manager, None, self.parentMenu, self.iconBasePath, parentButton=self.freeHandStackButton) + self.freeHandReshape.addTool( + self.manager, + None, + self.parentMenu, + self.iconBasePath, + parentButton=self.freeHandStackButton, + ) self.freeHandReshape.acquisitionFreeController.setToolEnabled() - #adding select raster - self.labelStackButton = self.manager.createToolButton(self.toolbar_extra, u'LabelTools') + # adding select raster + self.labelStackButton = self.manager.createToolButton( + self.toolbar_extra, "LabelTools" + ) self.rasterSelectTool = SelectRasterTool(self.iface) - self.rasterSelectTool.addTool(self.manager, self.rasterSelectTool.run, self.labelStackButton, self.iconBasePath) - #adding label toggling tool + self.rasterSelectTool.addTool( + self.manager, + self.rasterSelectTool.run, + self.labelStackButton, + self.iconBasePath, + ) + # adding label toggling tool self.labelTool = LabelTogglingTool(self.iface) - self.labelTool.addTool(self.manager, None, self.toolbar_extra, self.labelStackButton, self.iconBasePath) - #adding shortcuts tools + self.labelTool.addTool( + self.manager, + None, + self.toolbar_extra, + self.labelStackButton, + self.iconBasePath, + ) + # adding shortcuts tools self.shortcutsTool = ShortcutTool(self.iface) - self.shortcutsTool.addTool(self.manager, None, self.toolbar_extra, self.labelStackButton, self.iconBasePath) + self.shortcutsTool.addTool( + self.manager, + None, + self.toolbar_extra, + self.labelStackButton, + self.iconBasePath, + ) - self.filterStackButton = self.manager.createToolButton(self.toolbar_extra, u'FilterTools') - self.spatialFilterTool = SpatialFilter() + self.filterStackButton = self.manager.createToolButton( + self.toolbar_extra, "FilterTools" + ) + self.spatialFilterTool = SpatialFilter( + stackButton=self.filterStackButton + ) action = self.manager.add_action( - icon_path=self.iconBasePath + 'spatialFilter.png', + icon_path=self.iconBasePath + "spatialFilter.png", text=self.tr("DSGTools: Spatial Filter"), callback=self.spatialFilterTool.start, add_to_toolbar=False, parentButton=self.filterStackButton, - withShortcut=True + withShortcut=True, ) self.filterStackButton.setDefaultAction(action) self.filterTool = FilterTools(self.iface) - self.filterTool.addTool(self.manager, None, self.toolbar_extra, self.filterStackButton, self.iconBasePath) + self.filterTool.addTool( + self.manager, + None, + self.toolbar_extra, + self.filterStackButton, + self.iconBasePath, + ) - self.otherToolsStackButton = self.manager.createToolButton(self.toolbar_extra, u'OtherTools') + self.otherToolsStackButton = self.manager.createToolButton( + self.toolbar_extra, "OtherTools" + ) self.otherTools = OtherTools(self.iface) - self.otherTools.addTool(self.manager, None, self.toolbar_extra, self.otherToolsStackButton, self.iconBasePath) - + self.otherTools.addTool( + self.manager, + None, + self.toolbar_extra, + self.otherToolsStackButton, + self.iconBasePath, + ) - #initiate tools signals + # initiate tools signals self.initiateToolsSignals() - def resetCurrentLayerSignals(self): """ @@ -140,8 +199,12 @@ def initiateToolsSignals(self): """ Connects all tools' signals. """ - for tool in [self.flipLineTool, self.acquisition, self.freeHandAcquisiton.acquisitionFreeController, \ - self.freeHandReshape.acquisitionFreeController]: + for tool in [ + self.flipLineTool, + self.acquisition, + self.freeHandAcquisiton.acquisitionFreeController, + self.freeHandReshape.acquisitionFreeController, + ]: # connect current layer changed signal to all tools that use it self.iface.currentLayerChanged.connect(tool.setToolEnabled) # connect editing started/stopped signals to all tools that use it @@ -151,16 +214,19 @@ def initiateToolsSignals(self): self.iface.actionToggleEditing().triggered.connect(tool.setToolEnabled) # free hand has its own signal connected when started for free_hand_tool in [self.freeHandAcquisiton, self.freeHandReshape]: - free_hand_tool.acquisitionFreeController.actionAcquisitionFree.triggered.connect(\ - free_hand_tool.acquisitionFreeController.activateTool) - free_hand_tool.acquisitionFreeController.acquisitionFree.acquisitionFinished.connect(\ - free_hand_tool.acquisitionFreeController.createFeature) - free_hand_tool.acquisitionFreeController.acquisitionFree.reshapeLineCreated.connect(\ - free_hand_tool.acquisitionFreeController.reshapeSimplify) + free_hand_tool.acquisitionFreeController.actionAcquisitionFree.triggered.connect( + free_hand_tool.acquisitionFreeController.activateTool + ) + free_hand_tool.acquisitionFreeController.acquisitionFree.acquisitionFinished.connect( + free_hand_tool.acquisitionFreeController.createFeature + ) + free_hand_tool.acquisitionFreeController.acquisitionFree.reshapeLineCreated.connect( + free_hand_tool.acquisitionFreeController.reshapeSimplify + ) def activateGenericTool(self): self.iface.mapCanvas().setMapTool(self.genericTool) - + def activateRasterSelectTool(self): self.iface.mapCanvas().setMapTool(self.rasterSelectTool) @@ -169,4 +235,3 @@ def unload(self): self.rasterSelectTool.unload() self.iface.mainWindow().removeToolBar(self.toolbar_extra) del self.toolbar_extra - diff --git a/DsgTools/gui/ProductionTools/Toolbars/DataValidationTool/dataValidationTool.py b/DsgTools/gui/ProductionTools/Toolbars/DataValidationTool/dataValidationTool.py index b318bd9f8..220ca3a63 100644 --- a/DsgTools/gui/ProductionTools/Toolbars/DataValidationTool/dataValidationTool.py +++ b/DsgTools/gui/ProductionTools/Toolbars/DataValidationTool/dataValidationTool.py @@ -22,19 +22,17 @@ import processing from processing.modeler.ModelerUtils import ModelerUtils -from qgis.core import (QgsProject, - QgsMapLayer, - QgsProcessingModelAlgorithm, - QgsProcessingContext, - QgsProcessingFeedback, - QgsLayerTreeLayer, - QgsMessageLog, - Qgis) -from qgis.PyQt.QtWidgets import (QApplication, - QWidget, - QMessageBox, - QFileDialog, - QAction) +from qgis.core import ( + QgsProject, + QgsMapLayer, + QgsProcessingModelAlgorithm, + QgsProcessingContext, + QgsProcessingFeedback, + QgsLayerTreeLayer, + QgsMessageLog, + Qgis, +) +from qgis.PyQt.QtWidgets import QApplication, QWidget, QMessageBox, QFileDialog, QAction from qgis.PyQt.QtGui import QCursor, QIcon from qgis.PyQt import uic from qgis.PyQt.QtCore import pyqtSlot, pyqtSignal, Qt @@ -42,16 +40,18 @@ from DsgTools.gui.AboutAndFurtherInfo.Options.options import Options FORM_CLASS, _ = uic.loadUiType( - os.path.join(os.path.dirname(__file__), 'dataValidationTool.ui') + os.path.join(os.path.dirname(__file__), "dataValidationTool.ui") ) + class DataValidationTool(QWidget, FORM_CLASS): """ Toolbar for fast usage of processing methods. It is assumed that the models - have all of its child algorithm's variable's well defined and the only - variables expected on input are the output layers, whenever needed and as - many as it may be. + have all of its child algorithm's variable's well defined and the only + variables expected on input are the output layers, whenever needed and as + many as it may be. """ + __dsgToolsModelPath__ = os.path.join( os.path.dirname(__file__), "..", "..", "..", "..", "core", "Misc", "QGIS_Models" ) @@ -89,7 +89,7 @@ def _widgets(self): self.addModelPushButton, self.removeModelPushButton, self.runModelPushButton, - self.splitter + self.splitter, ] def options(self): @@ -133,12 +133,12 @@ def resetModelList(self): self.modelComboBox.addItem(self.tr("Select a model...")) models = [] for file_ in os.listdir(self.defaultModelPath()): - if file_.endswith('.model') or file_.endswith('.model3'): + if file_.endswith(".model") or file_.endswith(".model3"): models.append(file_) if models: self.modelComboBox.addItems(models) - @pyqtSlot(bool, name='on_validationPushButton_toggled') + @pyqtSlot(bool, name="on_validationPushButton_toggled") def activateTool(self, toggled=None): """ Shows/hides the toolbar. @@ -159,15 +159,22 @@ def confirmAction(self, msg, showCancel=True): :return: (bool) whether action was confirmed. """ if showCancel: - return QMessageBox.question( - self, self.tr('Confirm Action'), msg, - QMessageBox.Ok|QMessageBox.Cancel - ) == QMessageBox.Ok + return ( + QMessageBox.question( + self, + self.tr("Confirm Action"), + msg, + QMessageBox.Ok | QMessageBox.Cancel, + ) + == QMessageBox.Ok + ) else: - return QMessageBox.question( - self, self.tr('Confirm Action'), msg, - QMessageBox.Ok - ) == QMessageBox.Ok + return ( + QMessageBox.question( + self, self.tr("Confirm Action"), msg, QMessageBox.Ok + ) + == QMessageBox.Ok + ) def modelExists(self, modelName): """ @@ -191,7 +198,7 @@ def setActiveModel(self, modelName): return True return False - @pyqtSlot(int, name='on_modelComboBox_currentIndexChanged') + @pyqtSlot(int, name="on_modelComboBox_currentIndexChanged") def modelIsValid(self, idx): """ Checks if a model is valid and sets GUI buttons enabled if so. @@ -226,7 +233,7 @@ def addLayerToGroup(self, layer, groupname, subgroupname=None): QgsProject.instance().addMapLayer(layer, False) subgroup.insertChildNode(1, QgsLayerTreeLayer(layer)) - @pyqtSlot(bool, name='on_updatePushButton_clicked') + @pyqtSlot(bool, name="on_updatePushButton_clicked") def updateModelList(self): """ Checks current default path for models and refreshes current displayed @@ -238,7 +245,7 @@ def updateModelList(self): self.setActiveModel(currentModel) QApplication.restoreOverrideCursor() - @pyqtSlot(bool, name='on_addModelPushButton_clicked') + @pyqtSlot(bool, name="on_addModelPushButton_clicked") def registerModel(self, modelPath=None): """ Registers a model to the model runner. This application register all @@ -248,23 +255,22 @@ def registerModel(self, modelPath=None): if modelPath is None or not isinstance(modelPath, str): fd = QFileDialog() modelPathList = fd.getOpenFileNames( - caption=self.tr('Select a QGIS processing model to be added'), - filter=self.tr('QGIS Processing Model (*.model *.model3)') + caption=self.tr("Select a QGIS processing model to be added"), + filter=self.tr("QGIS Processing Model (*.model *.model3)"), ) modelPathList = modelPathList[0] if modelPathList else modelPathList if modelPathList == []: return msg = self.tr( - "Model seems to be already registered, would you like to overwrite" - " it?" + "Model seems to be already registered, would you like to overwrite" " it?" ) for modelPath in modelPathList: modelName = os.path.basename(modelPath) if self.modelExists(modelName) and not self.confirmAction(msg): QgsMessageLog.logMessage( self.tr("Model {model} was not imported.").format(model=modelName), - 'DSGTools Plugin', - Qgis.Info + "DSGTools Plugin", + Qgis.Info, ) return dest = os.path.join(self.defaultModelPath(), modelName) @@ -275,16 +281,17 @@ def registerModel(self, modelPath=None): self.setActiveModel(modelName) self.modelAdded.emit(modelName) QgsMessageLog.logMessage( - self.tr("Model {model} imported to {dest}.").format(model=modelName, dest=dest), - 'DSGTools Plugin', - Qgis.Info + self.tr("Model {model} imported to {dest}.").format( + model=modelName, dest=dest + ), + "DSGTools Plugin", + Qgis.Info, ) - - @pyqtSlot(bool, name='on_removeModelPushButton_clicked') + @pyqtSlot(bool, name="on_removeModelPushButton_clicked") def unregisterModel(self, modelName=None): """ - Unregisters a model to the model runner. Removes the model from the + Unregisters a model to the model runner. Removes the model from the default directory. :param modelName: (str) basename for the model to be removed. """ @@ -300,7 +307,9 @@ def unregisterModel(self, modelName=None): try: os.remove(modelPath) if not os.path.exists(modelPath): - self.modelComboBox.removeItem(self.modelComboBox.findText(modelName)) + self.modelComboBox.removeItem( + self.modelComboBox.findText(modelName) + ) self.modelRemoved.emit(modelName) except Exception as e: msg = self.tr("Unable to remove '{model}':\n{error}.").format( @@ -308,7 +317,7 @@ def unregisterModel(self, modelName=None): ) self.confirmAction(msg, showCancel=False) - @pyqtSlot(bool, name='on_runModelPushButton_clicked') + @pyqtSlot(bool, name="on_runModelPushButton_clicked") def runModel(self, modelName=None): """ Executes chosen model, if possible. @@ -325,36 +334,38 @@ def runModel(self, modelName=None): if not self.modelExists(modelName): # if model was manually removed and combo box was not refreshed self.iface.messageBar().pushMessage( - self.tr('Failed'), - self.tr("model {model} seems to have been deleted.").format(model=modelName), + self.tr("Failed"), + self.tr("model {model} seems to have been deleted.").format( + model=modelName + ), level=Qgis.Critical, - duration=5 + duration=5, ) return alg.fromFile(modelPath) alg.initAlgorithm() # as this tool assumes that every parameter is pre-set, only output shall # be passed on - ALL outputs from this tool is set to memory layers. - param = {vl.name() : "memory:" for vl in alg.parameterDefinitions()} + param = {vl.name(): "memory:" for vl in alg.parameterDefinitions()} msg = self.tr("Would you like to run {model}").format(model=modelName) if self.options()["checkBeforeRunModel"] and not self.confirmAction(msg): return try: out = processing.run(alg, param) self.iface.messageBar().pushMessage( - self.tr('Sucess'), + self.tr("Sucess"), self.tr("model {model} finished.").format(model=modelName), level=Qgis.Info, - duration=5 + duration=5, ) QgsMessageLog.logMessage( - self.tr( - "Model {model} finished running with no errors. You may" - " check model output on Processing log tab." - ).format(model=modelName), - 'DSGTools Plugin', - Qgis.Info - ) + self.tr( + "Model {model} finished running with no errors. You may" + " check model output on Processing log tab." + ).format(model=modelName), + "DSGTools Plugin", + Qgis.Info, + ) if not self.options()["loadModelOutput"]: return for var, value in out.items(): @@ -371,12 +382,12 @@ def runModel(self, modelName=None): "execution log) {model}:\n{error}" ).format(model=modelName, error=str(e)) self.iface.messageBar().pushMessage( - self.tr("Model {model} failed").format(model=modelName), + self.tr("Model {model} failed").format(model=modelName), self.tr("check log for more information."), level=Qgis.Critical, - duration=5 + duration=5, ) - QgsMessageLog.logMessage(msg, 'DSGTools Plugin',Qgis.Info) + QgsMessageLog.logMessage(msg, "DSGTools Plugin", Qgis.Info) def unload(self): """ @@ -390,18 +401,18 @@ def unload(self): for w in self._widgets(): w.blockSignals(True) del w - self.iface.unregisterMainWindowAction(self.runAction) + self.iface.unregisterMainWindowAction(self.runAction) def addShortcut(self): """ Adds the action to main menu allowing QGIS to assign a shortcut for run. """ self.runAction = QAction( - QIcon(':/plugins/DsgTools/icons/runModel.png'), - self.tr('DSGTools: Validation Toolbar - Run Processing Model'), - self.parent + QIcon(":/plugins/DsgTools/icons/runModel.png"), + self.tr("DSGTools: Validation Toolbar - Run Processing Model"), + self.parent, ) self.runAction.triggered.connect(self.runModel) if self.parent: self.parent.addAction(self.runAction) - self.iface.registerMainWindowAction(self.runAction, '') + self.iface.registerMainWindowAction(self.runAction, "") diff --git a/DsgTools/gui/ProductionTools/Toolbars/DsgRasterInfoTool/assignBandValueTool.py b/DsgTools/gui/ProductionTools/Toolbars/DsgRasterInfoTool/assignBandValueTool.py index 13f60813d..5116bf031 100644 --- a/DsgTools/gui/ProductionTools/Toolbars/DsgRasterInfoTool/assignBandValueTool.py +++ b/DsgTools/gui/ProductionTools/Toolbars/DsgRasterInfoTool/assignBandValueTool.py @@ -23,12 +23,28 @@ from functools import partial -from qgis.gui import QgsMapTool, QgsRubberBand, QgsMapToolEmitPoint, \ - QgsAttributeDialog, QgsAttributeForm, QgsMessageBar +from qgis.gui import ( + QgsMapTool, + QgsRubberBand, + QgsMapToolEmitPoint, + QgsAttributeDialog, + QgsAttributeForm, + QgsMessageBar, +) from qgis import core -from qgis.core import QgsPointXY, QgsRectangle, QgsVectorLayer, QgsGeometry, \ - QgsEditFormConfig, QgsRaster, QgsFeature, QgsWkbTypes, \ - QgsProject, QgsVectorLayerUtils, Qgis +from qgis.core import ( + QgsPointXY, + QgsRectangle, + QgsVectorLayer, + QgsGeometry, + QgsEditFormConfig, + QgsRaster, + QgsFeature, + QgsWkbTypes, + QgsProject, + QgsVectorLayerUtils, + Qgis, +) from qgis.PyQt.QtCore import QSettings from qgis.PyQt import QtCore, QtGui from qgis.PyQt.QtGui import QColor, QCursor @@ -37,15 +53,16 @@ from qgis.PyQt.QtCore import Qt from DsgTools.core.GeometricTools.geometryHandler import GeometryHandler + class AssignBandValueTool(QgsMapTool): def __init__(self, iface, rasterLayer): """ Tool Behaviours: (all behaviours start edition, except for rectangle one) - 1- Left Click: Creates a new point feature with the value from raster, according to selected attribute. - 5- Shift + drag and drop: draws a rectangle, then features that intersect this rectangle are selected + 1- Left Click: Creates a new point feature with the value from raster, according to selected attribute. + 5- Shift + drag and drop: draws a rectangle, then features that intersect this rectangle are selected and their value is set according to raster value and selected attribute. """ - self.iface = iface + self.iface = iface self.canvas = self.iface.mapCanvas() QgsMapTool.__init__(self, self.canvas) self.toolAction = None @@ -59,28 +76,28 @@ def __init__(self, iface, rasterLayer): def getDecimals(self): settings = QSettings() - settings.beginGroup('PythonPlugins/DsgTools/Options') - decimals = settings.value('decimals') + settings.beginGroup("PythonPlugins/DsgTools/Options") + decimals = settings.value("decimals") if decimals: return int(decimals) else: return 0 - + def getSuppressOptions(self): qgisSettings = QSettings() - qgisSettings.beginGroup('qgis/digitizing') - setting = qgisSettings.value('disable_enter_attribute_values_dialog') + qgisSettings.beginGroup("qgis/digitizing") + setting = qgisSettings.value("disable_enter_attribute_values_dialog") qgisSettings.endGroup() return setting def setRubberbandParameters(self): self.rubberBand = QgsRubberBand(self.canvas, QgsWkbTypes.PolygonGeometry) self.hoverRubberBand = QgsRubberBand(self.canvas, QgsWkbTypes.PolygonGeometry) - mFillColor = QColor( 254, 178, 76, 63 ) + mFillColor = QColor(254, 178, 76, 63) self.rubberBand.setColor(mFillColor) - self.hoverRubberBand.setColor(QColor( 255, 0, 0, 90 )) + self.hoverRubberBand.setColor(QColor(255, 0, 0, 90)) self.rubberBand.setWidth(1) - + def reset(self): """ Resets rubber band. @@ -109,8 +126,8 @@ def canvasMoveEvent(self, e): """ if not self.isEmittingPoint: return - self.endPoint = self.toMapCoordinates( e.pos() ) - self.showRect(self.startPoint, self.endPoint) + self.endPoint = self.toMapCoordinates(e.pos()) + self.showRect(self.startPoint, self.endPoint) def showRect(self, startPoint, endPoint): """ @@ -123,11 +140,11 @@ def showRect(self, startPoint, endPoint): point2 = QgsPointXY(startPoint.x(), endPoint.y()) point3 = QgsPointXY(endPoint.x(), endPoint.y()) point4 = QgsPointXY(endPoint.x(), startPoint.y()) - + self.rubberBand.addPoint(point1, False) self.rubberBand.addPoint(point2, False) self.rubberBand.addPoint(point3, False) - self.rubberBand.addPoint(point4, True) # true to update canvas + self.rubberBand.addPoint(point4, True) # true to update canvas self.rubberBand.show() def rectangle(self): @@ -136,19 +153,22 @@ def rectangle(self): """ if self.startPoint is None or self.endPoint is None: return None - elif self.startPoint.x() == self.endPoint.x() or self.startPoint.y() == self.endPoint.y(): + elif ( + self.startPoint.x() == self.endPoint.x() + or self.startPoint.y() == self.endPoint.y() + ): return None return QgsRectangle(self.startPoint, self.endPoint) def setAction(self, action): self.toolAction = action self.toolAction.setCheckable(True) - + def canvasReleaseEvent(self, e): """ After the rectangle is built, here features are selected. """ - # tool was planned to work on left click + # tool was planned to work on left click if e.button() == QtCore.Qt.LeftButton: layer = self.iface.mapCanvas().currentLayer() if QApplication.keyboardModifiers() == QtCore.Qt.ShiftModifier: @@ -158,25 +178,29 @@ def canvasReleaseEvent(self, e): return bbRect = self.canvas.mapSettings().mapToLayerCoordinates(layer, r) self.rubberBand.hide() - #select all stuff - layer.selectByIds([]) #portar para o feature handler + # select all stuff + layer.selectByIds([]) # portar para o feature handler layer.selectByRect(bbRect) - #mudar depois para o dsgmothafucka + # mudar depois para o dsgmothafucka featDict = dict() pointDict = dict() for feat in layer.selectedFeatures(): featDict[feat.id()] = feat pointDict[feat.id()] = feat.geometry() - pixelValueDict = self.getPixelValueFromPointDict(pointDict, self.rasterLayer) + pixelValueDict = self.getPixelValueFromPointDict( + pointDict, self.rasterLayer + ) for idx in pointDict: value = pixelValueDict[idx] if value: - self.auxList.append({'featId':idx, 'feat':featDict[idx], 'value':value}) + self.auxList.append( + {"featId": idx, "feat": featDict[idx], "value": value} + ) else: value, pointGeom = self.getPixelValue(self.rasterLayer) if value: - self.auxList.append({'geom':pointGeom, 'value':value}) - #create context menu to select attribute + self.auxList.append({"geom": pointGeom, "value": value}) + # create context menu to select attribute if self.auxList: self.createContextMenuOnPosition(e, layer) self.iface.mapCanvas().currentLayer().triggerRepaint() @@ -190,34 +214,38 @@ def createContextMenuOnPosition(self, e, layer): callback = partial(self.handleFeatures, field, layer) action.triggered.connect(callback) menu.exec_(self.canvas.viewport().mapToGlobal(e.pos())) - + def handleFeatures(self, selectedField, layer): layer.startEditing() for item in self.auxList: - if 'featId' in item: - feat = item['feat'] + if "featId" in item: + feat = item["feat"] idx = feat.fieldNameIndex(selectedField) - feat.setAttribute(idx, item['value']) + feat.setAttribute(idx, item["value"]) layer.updateFeature(feat) else: - self.geometryHandler.reprojectFeature(item['geom'], layer.crs()) - feature = QgsVectorLayerUtils.createFeature(layer, item['geom']) - self.addFeature(feature, layer, selectedField, item['value']) + self.geometryHandler.reprojectFeature(item["geom"], layer.crs()) + feature = QgsVectorLayerUtils.createFeature(layer, item["geom"]) + self.addFeature(feature, layer, selectedField, item["value"]) self.auxList = [] self.canvas.refresh() - + def addFeature(self, feature, layer, field, pointValue): - fields = layer.fields() - provider = layer.dataProvider() + fields = layer.fields() + provider = layer.dataProvider() for i in range(fields.count()): - value = provider.defaultValue(i) if fields[i].name() != field else pointValue + value = ( + provider.defaultValue(i) if fields[i].name() != field else pointValue + ) if value is not None: - feature.setAttribute(i, value) + feature.setAttribute(i, value) form = QgsAttributeDialog(layer, feature, False) form.setMode(int(QgsAttributeForm.AddFeatureMode)) formSuppress = layer.editFormConfig().suppress() if formSuppress == QgsEditFormConfig.SuppressDefault: - if self.getSuppressOptions(): #this is calculated every time because user can switch options while using tool + if ( + self.getSuppressOptions() + ): # this is calculated every time because user can switch options while using tool layer.addFeature(feature) else: if not form.exec_(): @@ -234,8 +262,8 @@ def getCursorRect(self, e): """ p = self.toMapCoordinates(e.pos()) w = self.canvas.mapUnitsPerPixel() * 10 - return QgsRectangle(p.x()-w, p.y()-w, p.x()+w, p.y()+w) - + return QgsRectangle(p.x() - w, p.y() - w, p.x() + w, p.y() + w) + def deactivate(self): """ Deactivate tool. @@ -261,7 +289,12 @@ def activate(self): # self.iface.mapCanvas().setMapTool(self) layer = self.iface.mapCanvas().currentLayer() if not layer or not isinstance(layer, QgsVectorLayer): - self.iface.messageBar().pushMessage(self.tr("Warning"), self.tr("Select a point vector layer as the active layer"), level=Qgis.Warning, duration=5) + self.iface.messageBar().pushMessage( + self.tr("Warning"), + self.tr("Select a point vector layer as the active layer"), + level=Qgis.Warning, + duration=5, + ) self.deactivate() def getPixelValue(self, rasterLayer): @@ -270,30 +303,41 @@ def getPixelValue(self, rasterLayer): return self.getPixelValueFromPoint(mousePosGeom, rasterLayer), mousePosGeom def getPixelValueFromPoint(self, mousePosGeom, rasterLayer, fromCanvas=True): - """ - - """ + """ """ rasterCrs = rasterLayer.crs() # if fromCanvas: # self.geometryHandler.reprojectFeature(mousePosGeom, rasterCrs, QgsProject.instance().crs()) # else: mousePosGeom = QgsGeometry(mousePosGeom) - self.geometryHandler.reprojectFeature(mousePosGeom, rasterCrs, self.canvas.currentLayer().crs()) - mousePos = mousePosGeom.asMultiPoint()[0] if mousePosGeom.isMultipart() else mousePosGeom.asPoint() + self.geometryHandler.reprojectFeature( + geom=mousePosGeom, + destinationCrs=self.canvas.currentLayer().crs(), + referenceCrs=rasterCrs, + ) + mousePos = ( + mousePosGeom.asMultiPoint()[0] + if mousePosGeom.isMultipart() + else mousePosGeom.asPoint() + ) # identify pixel(s) information - i = rasterLayer.dataProvider().identify( mousePos, QgsRaster.IdentifyFormatValue ) + i = rasterLayer.dataProvider().identify(mousePos, QgsRaster.IdentifyFormatValue) if i.isValid(): value = list(i.results().values())[0] if value: - value = int(value) if self.decimals == 0 else round(value, self.decimals) + value = ( + int(value) if self.decimals == 0 else round(value, self.decimals) + ) return value else: return None - + def getPixelValueFromPointDict(self, pointDict, rasterLayer): """ pointDict = {'pointId':QgsGeometry} returns {'pointId': value} """ - return {key : self.getPixelValueFromPoint(value, rasterLayer, fromCanvas=False) for key, value in pointDict.items()} #no python3 eh items() + return { + key: self.getPixelValueFromPoint(value, rasterLayer, fromCanvas=False) + for key, value in pointDict.items() + } # no python3 eh items() diff --git a/DsgTools/gui/ProductionTools/Toolbars/DsgRasterInfoTool/bandValueTool.py b/DsgTools/gui/ProductionTools/Toolbars/DsgRasterInfoTool/bandValueTool.py index d483870a2..f3652c667 100644 --- a/DsgTools/gui/ProductionTools/Toolbars/DsgRasterInfoTool/bandValueTool.py +++ b/DsgTools/gui/ProductionTools/Toolbars/DsgRasterInfoTool/bandValueTool.py @@ -30,6 +30,7 @@ from .....core.GeometricTools.geometryHandler import GeometryHandler + class BandValueTool(QgsMapTool): """ This class is supposed to help revision operators. It shows, on mouse hovering @@ -39,6 +40,7 @@ class BandValueTool(QgsMapTool): 2- On mouse click: create a new instance of desired layer (filled on config). * behaviour 2 is an extrapolation of first conception """ + def __init__(self, iface, parent): """ Class constructor. @@ -51,15 +53,13 @@ def __init__(self, iface, parent): self.toolAction = None self.QgsMapToolEmitPoint = QgsMapToolEmitPoint(self.canvas) self.geometryHandler = GeometryHandler(iface) - self.timerMapTips = QTimer( self.canvas ) - self.timerMapTips.timeout.connect( self.showToolTip ) + self.timerMapTips = QTimer(self.canvas) + self.timerMapTips.timeout.connect(self.showToolTip) self.activated = False self.canvasCrs = self.canvas.mapRenderer().destinationCrs() - + def setAction(self, action): - """ - - """ + """ """ self.toolAction = action def activate(self): @@ -70,7 +70,7 @@ def activate(self): self.activated = True QgsMapTool.activate(self) self.canvas.setMapTool(self) - + def deactivate(self): """ Deactivates tool. @@ -83,38 +83,36 @@ def deactivate(self): if self is not None: QgsMapTool.deactivate(self) except: - pass + pass def canvasMoveEvent(self, e): QToolTip.hideText() - self.timerMapTips.start( 500 ) # time in milliseconds - self.showToolTip() - + self.timerMapTips.start(500) # time in milliseconds + self.showToolTip() + def getPixelValue(self, rasterLayer): - """ - - """ + """ """ rasterCrs = rasterLayer.crs() mousePos = self.QgsMapToolEmitPoint.toMapCoordinates(self.canvas.mouseLastXY()) mousePosGeom = QgsGeometry.fromPoint(mousePos) self.geometryHandler.reprojectFeature(mousePosGeom, rasterCrs, self.canvasCrs) mousePos = mousePosGeom.asPoint() # identify pixel(s) information - i = rasterLayer.dataProvider().identify( mousePos, QgsRaster.IdentifyFormatValue ) + i = rasterLayer.dataProvider().identify(mousePos, QgsRaster.IdentifyFormatValue) if i.isValid(): - text = ", ".join(['{0:g}'.format(r) for r in list(i.results().values()) if r is not None] ) + text = ", ".join( + ["{0:g}".format(r) for r in list(i.results().values()) if r is not None] + ) else: text = "" return text def showToolTip(self): - """ - - """ + """ """ self.timerMapTips.stop() if self.canvas.underMouse(): raster = self.parent.rasterComboBox.currentLayer() if raster: text = self.getPixelValue(raster) - p = self.canvas.mapToGlobal( self.canvas.mouseLastXY() ) - QToolTip.showText( p, text, self.canvas ) \ No newline at end of file + p = self.canvas.mapToGlobal(self.canvas.mouseLastXY()) + QToolTip.showText(p, text, self.canvas) diff --git a/DsgTools/gui/ProductionTools/Toolbars/DsgRasterInfoTool/dsgRasterInfoTool.py b/DsgTools/gui/ProductionTools/Toolbars/DsgRasterInfoTool/dsgRasterInfoTool.py index ccc9d4f81..e355e1349 100644 --- a/DsgTools/gui/ProductionTools/Toolbars/DsgRasterInfoTool/dsgRasterInfoTool.py +++ b/DsgTools/gui/ProductionTools/Toolbars/DsgRasterInfoTool/dsgRasterInfoTool.py @@ -30,7 +30,7 @@ QgsVectorLayer, QgsRasterLayer, QgsWkbTypes, - Qgis + Qgis, ) from qgis.PyQt import QtGui, uic @@ -49,6 +49,7 @@ # FORM_CLASS, _ = uic.loadUiType(os.path.join(os.path.dirname(__file__), 'dsgRasterInfoTool.ui')) from .dsgRasterInfoTool_ui import Ui_DsgRasterInfoTool + class DsgRasterInfoTool(QWidget, Ui_DsgRasterInfoTool): """ This class is supposed to help revision operators. It shows, on mouse hovering diff --git a/DsgTools/gui/ProductionTools/Toolbars/DsgRasterInfoTool/dsgRasterInfoTool_ui.py b/DsgTools/gui/ProductionTools/Toolbars/DsgRasterInfoTool/dsgRasterInfoTool_ui.py index a4b2b5aed..67af411dd 100644 --- a/DsgTools/gui/ProductionTools/Toolbars/DsgRasterInfoTool/dsgRasterInfoTool_ui.py +++ b/DsgTools/gui/ProductionTools/Toolbars/DsgRasterInfoTool/dsgRasterInfoTool_ui.py @@ -12,26 +12,35 @@ try: _fromUtf8 = QtCore.QString.fromUtf8 except AttributeError: + def _fromUtf8(s): return s + try: _encoding = QtWidgets.QApplication.UnicodeUTF8 + def _translate(context, text, disambig): return QtWidgets.QApplication.translate(context, text, disambig, _encoding) + except AttributeError: + def _translate(context, text, disambig): return QtWidgets.QApplication.translate(context, text, disambig) + from qgis.gui import QgsMapLayerComboBox from qgis.core import QgsMapLayerProxyModel import resources_rc + class Ui_DsgRasterInfoTool(object): def setupUi(self, DsgRasterInfoTool): DsgRasterInfoTool.setObjectName(_fromUtf8("DsgRasterInfoTool")) DsgRasterInfoTool.resize(309, 49) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.MinimumExpanding) + sizePolicy = QtWidgets.QSizePolicy( + QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.MinimumExpanding + ) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(DsgRasterInfoTool.sizePolicy().hasHeightForWidth()) @@ -42,16 +51,24 @@ def setupUi(self, DsgRasterInfoTool): self.gridLayout = QtWidgets.QGridLayout(DsgRasterInfoTool) self.gridLayout.setObjectName(_fromUtf8("gridLayout")) self.rasterInfoPushButton = QtWidgets.QPushButton(DsgRasterInfoTool) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed) + sizePolicy = QtWidgets.QSizePolicy( + QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed + ) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.rasterInfoPushButton.sizePolicy().hasHeightForWidth()) + sizePolicy.setHeightForWidth( + self.rasterInfoPushButton.sizePolicy().hasHeightForWidth() + ) self.rasterInfoPushButton.setSizePolicy(sizePolicy) self.rasterInfoPushButton.setMinimumSize(QtCore.QSize(16, 16)) self.rasterInfoPushButton.setMaximumSize(QtCore.QSize(24, 24)) self.rasterInfoPushButton.setText(_fromUtf8("")) icon = QtGui.QIcon() - icon.addPixmap(QtGui.QPixmap(_fromUtf8(":/plugins/DsgTools/icons/rasterToolTip.png")), QtGui.QIcon.Normal, QtGui.QIcon.Off) + icon.addPixmap( + QtGui.QPixmap(_fromUtf8(":/plugins/DsgTools/icons/rasterToolTip.png")), + QtGui.QIcon.Normal, + QtGui.QIcon.Off, + ) self.rasterInfoPushButton.setIcon(icon) self.rasterInfoPushButton.setIconSize(QtCore.QSize(16, 16)) self.rasterInfoPushButton.setCheckable(True) @@ -62,73 +79,111 @@ def setupUi(self, DsgRasterInfoTool): self.splitter.setObjectName(_fromUtf8("splitter")) self.rasterComboBox = QgsMapLayerComboBox(self.splitter) self.rasterComboBox.setFilters(QgsMapLayerProxyModel.RasterLayer) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.MinimumExpanding, QtWidgets.QSizePolicy.Fixed) + sizePolicy = QtWidgets.QSizePolicy( + QtWidgets.QSizePolicy.MinimumExpanding, QtWidgets.QSizePolicy.Fixed + ) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.rasterComboBox.sizePolicy().hasHeightForWidth()) + sizePolicy.setHeightForWidth( + self.rasterComboBox.sizePolicy().hasHeightForWidth() + ) self.rasterComboBox.setSizePolicy(sizePolicy) self.rasterComboBox.setMinimumSize(QtCore.QSize(0, 20)) self.rasterComboBox.setMaximumSize(QtCore.QSize(16777215, 24)) self.rasterComboBox.setObjectName(_fromUtf8("rasterComboBox")) self.refreshPushButton = QtWidgets.QPushButton(self.splitter) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed) + sizePolicy = QtWidgets.QSizePolicy( + QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed + ) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.refreshPushButton.sizePolicy().hasHeightForWidth()) + sizePolicy.setHeightForWidth( + self.refreshPushButton.sizePolicy().hasHeightForWidth() + ) self.refreshPushButton.setSizePolicy(sizePolicy) self.refreshPushButton.setMinimumSize(QtCore.QSize(24, 24)) self.refreshPushButton.setMaximumSize(QtCore.QSize(24, 24)) self.refreshPushButton.setText("") icon = QtGui.QIcon() - icon.addPixmap(QtGui.QPixmap(":/plugins/DsgTools/icons/reload.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off) + icon.addPixmap( + QtGui.QPixmap(":/plugins/DsgTools/icons/reload.png"), + QtGui.QIcon.Normal, + QtGui.QIcon.Off, + ) self.refreshPushButton.setIcon(icon) self.refreshPushButton.setIconSize(QtCore.QSize(16, 16)) self.refreshPushButton.setObjectName("refreshPushButton") self.bandTooltipButton = QtWidgets.QPushButton(self.splitter) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed) + sizePolicy = QtWidgets.QSizePolicy( + QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed + ) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.bandTooltipButton.sizePolicy().hasHeightForWidth()) + sizePolicy.setHeightForWidth( + self.bandTooltipButton.sizePolicy().hasHeightForWidth() + ) self.bandTooltipButton.setSizePolicy(sizePolicy) self.bandTooltipButton.setMinimumSize(QtCore.QSize(16, 16)) self.bandTooltipButton.setMaximumSize(QtCore.QSize(24, 24)) self.bandTooltipButton.setToolTip(_fromUtf8("Show raster tooltip")) self.bandTooltipButton.setText(_fromUtf8("")) icon1 = QtGui.QIcon() - icon1.addPixmap(QtGui.QPixmap(_fromUtf8(":/plugins/DsgTools/icons/band_tooltip.png")), QtGui.QIcon.Normal, QtGui.QIcon.Off) + icon1.addPixmap( + QtGui.QPixmap(_fromUtf8(":/plugins/DsgTools/icons/band_tooltip.png")), + QtGui.QIcon.Normal, + QtGui.QIcon.Off, + ) self.bandTooltipButton.setIcon(icon1) self.bandTooltipButton.setIconSize(QtCore.QSize(16, 16)) self.bandTooltipButton.setCheckable(True) self.bandTooltipButton.setObjectName(_fromUtf8("bandTooltipButton")) self.dynamicHistogramButton = QtWidgets.QPushButton(self.splitter) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed) + sizePolicy = QtWidgets.QSizePolicy( + QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed + ) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.dynamicHistogramButton.sizePolicy().hasHeightForWidth()) + sizePolicy.setHeightForWidth( + self.dynamicHistogramButton.sizePolicy().hasHeightForWidth() + ) self.dynamicHistogramButton.setSizePolicy(sizePolicy) self.dynamicHistogramButton.setMinimumSize(QtCore.QSize(16, 16)) self.dynamicHistogramButton.setMaximumSize(QtCore.QSize(24, 24)) self.dynamicHistogramButton.setToolTip(_fromUtf8("Dynamic histogram view")) self.dynamicHistogramButton.setText(_fromUtf8("")) icon2 = QtGui.QIcon() - icon2.addPixmap(QtGui.QPixmap(_fromUtf8(":/plugins/DsgTools/icons/dynamic_histogram_viewer.png")), QtGui.QIcon.Normal, QtGui.QIcon.Off) + icon2.addPixmap( + QtGui.QPixmap( + _fromUtf8(":/plugins/DsgTools/icons/dynamic_histogram_viewer.png") + ), + QtGui.QIcon.Normal, + QtGui.QIcon.Off, + ) self.dynamicHistogramButton.setIcon(icon2) - self.dynamicHistogramButton.setIconSize(QtCore.QSize(16,16)) + self.dynamicHistogramButton.setIconSize(QtCore.QSize(16, 16)) self.dynamicHistogramButton.setCheckable(True) self.dynamicHistogramButton.setObjectName(_fromUtf8("dynamicHistogramButton")) self.gridLayout.addWidget(self.splitter, 0, 1, 1, 1) self.valueSetterButton = QtWidgets.QPushButton(self.splitter) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed) + sizePolicy = QtWidgets.QSizePolicy( + QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed + ) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.valueSetterButton.sizePolicy().hasHeightForWidth()) + sizePolicy.setHeightForWidth( + self.valueSetterButton.sizePolicy().hasHeightForWidth() + ) self.valueSetterButton.setSizePolicy(sizePolicy) self.valueSetterButton.setMinimumSize(QtCore.QSize(16, 16)) self.valueSetterButton.setMaximumSize(QtCore.QSize(24, 24)) self.valueSetterButton.setToolTip(_fromUtf8("Set Value From Raster")) self.valueSetterButton.setText(_fromUtf8("")) icon2 = QtGui.QIcon() - icon2.addPixmap(QtGui.QPixmap(_fromUtf8(":/plugins/DsgTools/icons/valueSetter.png")), QtGui.QIcon.Normal, QtGui.QIcon.Off) + icon2.addPixmap( + QtGui.QPixmap(_fromUtf8(":/plugins/DsgTools/icons/valueSetter.png")), + QtGui.QIcon.Normal, + QtGui.QIcon.Off, + ) self.valueSetterButton.setIcon(icon2) self.valueSetterButton.setIconSize(QtCore.QSize(40, 40)) self.valueSetterButton.setCheckable(True) @@ -140,4 +195,6 @@ def setupUi(self, DsgRasterInfoTool): def retranslateUi(self, DsgRasterInfoTool): DsgRasterInfoTool.setWindowTitle(_translate("DsgRasterInfoTool", "Form", None)) - self.rasterInfoPushButton.setToolTip(_translate("DsgRasterInfoTool", "Raster Info Tool", None)) + self.rasterInfoPushButton.setToolTip( + _translate("DsgRasterInfoTool", "Raster Info Tool", None) + ) diff --git a/DsgTools/gui/ProductionTools/Toolbars/InspectFeatures/inspectFeatures.py b/DsgTools/gui/ProductionTools/Toolbars/InspectFeatures/inspectFeatures.py index 7056f594d..4f3021a03 100644 --- a/DsgTools/gui/ProductionTools/Toolbars/InspectFeatures/inspectFeatures.py +++ b/DsgTools/gui/ProductionTools/Toolbars/InspectFeatures/inspectFeatures.py @@ -27,16 +27,27 @@ from qgis.PyQt import QtGui, uic, QtCore from qgis.PyQt.Qt import QObject -from qgis.core import QgsMapLayer, Qgis, QgsVectorLayer, QgsCoordinateReferenceSystem, QgsCoordinateTransform, QgsFeatureRequest, QgsWkbTypes, QgsProject +from qgis.core import ( + QgsMapLayer, + Qgis, + QgsVectorLayer, + QgsCoordinateReferenceSystem, + QgsCoordinateTransform, + QgsFeatureRequest, + QgsWkbTypes, + QgsProject, +) from qgis.gui import QgsMessageBar from .inspectFeatures_ui import Ui_Form + # FORM_CLASS, _ = uic.loadUiType(os.path.join( # os.path.dirname(__file__), 'inspectFeatures.ui')) -class InspectFeatures(QWidget,Ui_Form): + +class InspectFeatures(QWidget, Ui_Form): # idxChanged = pyqtSignal(int) - def __init__(self, iface, parent = None): + def __init__(self, iface, parent=None): """ Constructor """ @@ -48,7 +59,9 @@ def __init__(self, iface, parent = None): self.iface = iface # self.iface.currentLayerChanged.connect(self.enableScale) self.mMapLayerComboBox.layerChanged.connect(self.enableScale) - self.mMapLayerComboBox.layerChanged.connect(self.mFieldExpressionWidget.setLayer) + self.mMapLayerComboBox.layerChanged.connect( + self.mFieldExpressionWidget.setLayer + ) self.mMapLayerComboBox.layerChanged.connect(self.mFieldComboBox.setLayer) if not self.iface.activeLayer(): self.enableTool(False) @@ -58,38 +71,48 @@ def __init__(self, iface, parent = None): self.zoomPercentageSpinBox.setMaximum(100) self.zoomPercentageSpinBox.setDecimals(3) self.zoomPercentageSpinBox.setSingleStep(1) - self.zoomPercentageSpinBox.setSuffix('%') + self.zoomPercentageSpinBox.setSuffix("%") self.zoomPercentageSpinBox.setValue(100) self.zoomPercentageSpinBox.setEnabled(False) self.zoomPercentageSpinBox.hide() - self.mScaleWidget.setScaleString('1:40000') + self.mScaleWidget.setScaleString("1:40000") self.mScaleWidget.setEnabled(False) self.mScaleWidget.hide() self.enableScale() self.canvas = self.iface.mapCanvas() - self.allLayers={} + self.allLayers = {} # self.idxChanged.connect(self.setNewId) - self.setToolTip('') - icon_path = ':/plugins/DsgTools/icons/inspectFeatures.png' - text = self.tr('DSGTools: Inspect Features') - self.activateToolAction = self.add_action(icon_path, text, self.inspectPushButton.toggle, parent = self.parent) - self.iface.registerMainWindowAction(self.activateToolAction, '') - icon_path = ':/plugins/DsgTools/icons/backInspect.png' - text = self.tr('DSGTools: Back Inspect') - self.backButtonAction = self.add_action(icon_path, text, self.backInspectButton.click, parent = self.parent) - self.iface.registerMainWindowAction(self.backButtonAction, '') - icon_path = ':/plugins/DsgTools/icons/nextInspect.png' - text = self.tr('DSGTools: Next Inspect') - self.nextButtonAction = self.add_action(icon_path, text, self.nextInspectButton.click, parent = self.parent) - self.iface.registerMainWindowAction(self.nextButtonAction, '') - icon_path = ':/plugins/DsgTools/icons/reload.png' - text = self.tr('DSGTools: Set Active Layer on Feature Inspector') - self.refreshPushButtonAction = self.add_action(icon_path, text, self.refreshPushButton.click, parent = self.parent) - self.iface.registerMainWindowAction(self.refreshPushButtonAction, '') - self.refreshPushButton.setToolTip(self.tr('Set current layer as selected layer on inspect tool')) - self.sortPushButton.setToolTip(self.tr('Sort by attribute')) + self.setToolTip("") + icon_path = ":/plugins/DsgTools/icons/inspectFeatures.png" + text = self.tr("DSGTools: Inspect Features") + self.activateToolAction = self.add_action( + icon_path, text, self.inspectPushButton.toggle, parent=self.parent + ) + self.iface.registerMainWindowAction(self.activateToolAction, "") + icon_path = ":/plugins/DsgTools/icons/backInspect.png" + text = self.tr("DSGTools: Back Inspect") + self.backButtonAction = self.add_action( + icon_path, text, self.backInspectButton.click, parent=self.parent + ) + self.iface.registerMainWindowAction(self.backButtonAction, "") + icon_path = ":/plugins/DsgTools/icons/nextInspect.png" + text = self.tr("DSGTools: Next Inspect") + self.nextButtonAction = self.add_action( + icon_path, text, self.nextInspectButton.click, parent=self.parent + ) + self.iface.registerMainWindowAction(self.nextButtonAction, "") + icon_path = ":/plugins/DsgTools/icons/reload.png" + text = self.tr("DSGTools: Set Active Layer on Feature Inspector") + self.refreshPushButtonAction = self.add_action( + icon_path, text, self.refreshPushButton.click, parent=self.parent + ) + self.iface.registerMainWindowAction(self.refreshPushButtonAction, "") + self.refreshPushButton.setToolTip( + self.tr("Set current layer as selected layer on inspect tool") + ) + self.sortPushButton.setToolTip(self.tr("Sort by attribute")) self.mFieldExpressionWidget.fieldChanged.connect(self.resetCurrentIndex) - + def add_action(self, icon_path, text, callback, parent=None): icon = QIcon(icon_path) action = QAction(icon, text, parent) @@ -97,19 +120,23 @@ def add_action(self, icon_path, text, callback, parent=None): if parent: parent.addAction(action) return action - + def getIterateLayer(self): - return self.mMapLayerComboBox.currentLayer() + return self.mMapLayerComboBox.currentLayer() - def enableTool(self, enabled = True): - allowed = False if enabled == None or not isinstance(enabled, QgsVectorLayer) else True + def enableTool(self, enabled=True): + allowed = ( + False + if enabled == None or not isinstance(enabled, QgsVectorLayer) + else True + ) toggled = self.inspectPushButton.isChecked() enabled = allowed and toggled self.backInspectButton.setEnabled(enabled) self.nextInspectButton.setEnabled(enabled) self.idSpinBox.setEnabled(enabled) self.sortPushButton.setEnabled(enabled) - + def enableScale(self): """ The scale combo should only be enabled for point layers @@ -129,16 +156,16 @@ def enableScale(self): self.mScaleWidget.hide() self.zoomPercentageSpinBox.setEnabled(True) self.zoomPercentageSpinBox.show() - + @pyqtSlot(bool) def on_nextInspectButton_clicked(self): """ Inspects the next feature """ if self.nextInspectButton.isEnabled(): - method = getattr(self, 'testIndexFoward') + method = getattr(self, "testIndexFoward") self.iterateFeature(method) - + def testIndexFoward(self, index, maxIndex, minIndex): """ Gets the next index @@ -147,7 +174,7 @@ def testIndexFoward(self, index, maxIndex, minIndex): if index > maxIndex: index = minIndex return index - + def testIndexBackwards(self, index, maxIndex, minIndex): """ gets the previous index @@ -156,17 +183,17 @@ def testIndexBackwards(self, index, maxIndex, minIndex): if index < minIndex: index = maxIndex return index - + @pyqtSlot(bool) def on_backInspectButton_clicked(self): """ Inspects the previous feature """ if self.backInspectButton.isEnabled(): - method = getattr(self, 'testIndexBackwards') + method = getattr(self, "testIndexBackwards") self.iterateFeature(method) - - @pyqtSlot(int, name = 'on_idSpinBox_valueChanged') + + @pyqtSlot(int, name="on_idSpinBox_valueChanged") def setNewId(self, newId): if not isinstance(self.sender(), QSpinBox): self.idSpinBox.setValue(newId) @@ -182,7 +209,11 @@ def setNewId(self, newId): featIdList = self.getFeatIdList(currentLayer) if oldIndex not in featIdList: oldIndex = 0 - zoom = self.mScaleWidget.scale() if currentLayer.geometryType() == QgsWkbTypes.PointGeometry else self.zoomPercentageSpinBox.value() + zoom = ( + self.mScaleWidget.scale() + if currentLayer.geometryType() == QgsWkbTypes.PointGeometry + else self.zoomPercentageSpinBox.value() + ) if oldIndex == newId: # self.iface.messageBar().pushMessage(self.tr('Warning!'), self.tr('Selected id does not exist in layer {0}. Returned to previous id.').format(lyrName), level=Qgis.Warning, duration=2) return @@ -190,24 +221,34 @@ def setNewId(self, newId): index = featIdList.index(newId) self.allLayers[lyrName] = index self.makeZoom(zoom, currentLayer, newId) - self.idSpinBox.setSuffix(' ({0}/{1})'.format(index+1,len(featIdList))) + self.idSpinBox.setSuffix( + " ({0}/{1})".format(index + 1, len(featIdList)) + ) except: # self.iface.messageBar().pushMessage(self.tr('Warning!'), self.tr('Selected id does not exist in layer {0}. Returned to previous id.').format(lyrName), level=Qgis.Warning, duration=2) self.idSpinBox.setValue(oldIndex) self.makeZoom(zoom, currentLayer, oldIndex) def getFeatIdList(self, currentLayer): - #getting all features ids - if self.mFieldExpressionWidget.currentText() != '' and not self.mFieldExpressionWidget.isValidExpression(): - self.iface.messageBar().pushMessage(self.tr('Warning!'), self.tr('Invalid attribute filter!'), level=Qgis.Warning, duration=2) + # getting all features ids + if ( + self.mFieldExpressionWidget.currentText() != "" + and not self.mFieldExpressionWidget.isValidExpression() + ): + self.iface.messageBar().pushMessage( + self.tr("Warning!"), + self.tr("Invalid attribute filter!"), + level=Qgis.Warning, + duration=2, + ) return [] request = QgsFeatureRequest() request.setFlags(QgsFeatureRequest.NoGeometry) - if self.mFieldExpressionWidget.currentText() != '': + if self.mFieldExpressionWidget.currentText() != "": request.setFilterExpression(self.mFieldExpressionWidget.asExpression()) clauseList = [] if self.sortPushButton.isChecked(): - #order by some attribute + # order by some attribute clause = QgsFeatureRequest.OrderByClause( self.mFieldComboBox.currentField(), self.ascRadioButton.isChecked(), @@ -221,9 +262,9 @@ def getFeatIdList(self, currentLayer): orderby = QgsFeatureRequest.OrderBy(clauseList) request.setOrderBy(orderby) featIdList = [i.id() for i in currentLayer.getFeatures(request)] - #sort is faster than sorted (but sort is just available for lists) + # sort is faster than sorted (but sort is just available for lists) return featIdList - + def iterateFeature(self, method): """ Iterates over the features selecting and zooming to the desired one @@ -231,52 +272,63 @@ def iterateFeature(self, method): """ currentLayer = self.getIterateLayer() lyrName = currentLayer.name() - - zoom = self.mScaleWidget.scale() if currentLayer.geometryType() == QgsWkbTypes.PointGeometry else self.zoomPercentageSpinBox.value() - + + zoom = ( + self.mScaleWidget.scale() + if currentLayer.geometryType() == QgsWkbTypes.PointGeometry + else self.zoomPercentageSpinBox.value() + ) + featIdList = self.getFeatIdList(currentLayer) if not currentLayer or len(featIdList) == 0: self.errorMessage() return - - #checking if this is the first time for this layer (currentLayer) + + # checking if this is the first time for this layer (currentLayer) first = False if lyrName not in list(self.allLayers.keys()): self.allLayers[lyrName] = 0 first = True - #getting the current index + # getting the current index index = self.allLayers[lyrName] - #getting max and min ids - #this was made because the list is already sorted, there's no need to calculate max and min + # getting max and min ids + # this was made because the list is already sorted, there's no need to calculate max and min maxIndex = len(featIdList) - 1 minIndex = 0 - + self.idSpinBox.setMaximum(maxIndex) self.idSpinBox.setMinimum(minIndex) - #getting the new index + # getting the new index if not first: index = method(index, maxIndex, minIndex) - self.idSpinBox.setSuffix(' ({0}/{1})'.format(index+1,len(featIdList))) + self.idSpinBox.setSuffix(" ({0}/{1})".format(index + 1, len(featIdList))) self.allLayers[lyrName] = index - #getting the new feature id + # getting the new feature id id = featIdList[index] - #adjustin the spin box value + # adjustin the spin box value # self.idxChanged.emit(id) self.makeZoom(zoom, currentLayer, id) self.selectLayer(id, currentLayer) - + def errorMessage(self): """ Shows am error message """ - QMessageBox.warning(self.iface.mainWindow(), self.tr(u"ERROR:"), self.tr(u"There are no features in the current layer:
Add features and try again!"), QMessageBox.Close) + QMessageBox.warning( + self.iface.mainWindow(), + self.tr("ERROR:"), + self.tr( + "There are no features in the current layer:
Add features and try again!" + ), + QMessageBox.Close, + ) def selectLayer(self, index, currentLayer): """ @@ -286,27 +338,31 @@ def selectLayer(self, index, currentLayer): if currentLayer: currentLayer.removeSelection() currentLayer.select(index) - - def zoomToLayer(self, layer, zoom = None): + + def zoomToLayer(self, layer, zoom=None): box = layer.boundingBoxOfSelected() if zoom is not None: - box.grow(min(box.width(),box.height())*(100-zoom)/100) + box.grow(min(box.width(), box.height()) * (100 - zoom) / 100) # Defining the crs from src and destiny epsg = self.iface.mapCanvas().mapSettings().destinationCrs().authid() crsDest = QgsCoordinateReferenceSystem(epsg) - #getting srid from something like 'EPSG:31983' + # getting srid from something like 'EPSG:31983' if not layer: layer = self.iface.mapCanvas().currentLayer() srid = layer.crs().authid() - crsSrc = QgsCoordinateReferenceSystem(srid) #here we have to put authid, not srid + crsSrc = QgsCoordinateReferenceSystem( + srid + ) # here we have to put authid, not srid # Creating a transformer - coordinateTransformer = QgsCoordinateTransform(crsSrc, crsDest, QgsProject.instance()) + coordinateTransformer = QgsCoordinateTransform( + crsSrc, crsDest, QgsProject.instance() + ) newBox = coordinateTransformer.transform(box) self.iface.mapCanvas().setExtent(newBox) self.iface.mapCanvas().refresh() - def zoomFeature(self, zoom, idDict = None): + def zoomFeature(self, zoom, idDict=None): """ Zooms to current layer selected features according to a specific zoom zoom: zoom to be applied @@ -316,18 +372,18 @@ def zoomFeature(self, zoom, idDict = None): if idDict == {}: self.zoomToLayer(currentLayer, zoom=float(zoom)) else: - id = idDict['id'] - lyr = idDict['lyr'] + id = idDict["id"] + lyr = idDict["lyr"] selectIdList = lyr.selectedFeatureIds() lyr.removeSelection() lyr.selectByIds([id]) - self.zoomToLayer(layer = lyr, zoom=float(zoom)) + self.zoomToLayer(layer=lyr, zoom=float(zoom)) lyr.selectByIds(selectIdList) if self.getIterateLayer().geometryType() == QgsWkbTypes.PointGeometry: self.iface.mapCanvas().zoomScale(float(zoom)) - - @pyqtSlot(bool, name = 'on_inspectPushButton_toggled') + + @pyqtSlot(bool, name="on_inspectPushButton_toggled") def toggleBar(self, toggled=None): """ Shows/Hides the tool bar @@ -337,13 +393,13 @@ def toggleBar(self, toggled=None): if toggled: self.splitter.show() self.enableTool(self.mMapLayerComboBox.currentLayer()) - self.setToolTip(self.tr('Select a vector layer to enable tool')) + self.setToolTip(self.tr("Select a vector layer to enable tool")) else: - self.splitter.hide() + self.splitter.hide() self.enableTool(False) - self.setToolTip('') - - @pyqtSlot(bool, name='on_sortPushButton_toggled') + self.setToolTip("") + + @pyqtSlot(bool, name="on_sortPushButton_toggled") def toggleSort(self, toggled=None): """ Shows/hides the sort options @@ -369,31 +425,31 @@ def setValues(self, featIdList, currentLayer): maxIndex = len(featIdList) - 1 minIndex = 0 - + self.idSpinBox.setMaximum(featIdList[maxIndex]) self.idSpinBox.setMinimum(featIdList[minIndex]) - #getting the new feature id + # getting the new feature id id = featIdList[0] - #adjustin the spin box value + # adjustin the spin box value # self.idxChanged.emit(id) - #self.idSpinBox.setValue(id) + # self.idSpinBox.setValue(id) zoom = self.mScaleWidget.scale() self.makeZoom(zoom, currentLayer, id) def makeZoom(self, zoom, currentLayer, id): - #selecting and zooming to the feature + # selecting and zooming to the feature # if not self.onlySelectedRadioButton.isChecked(): # self.selectLayer(id, currentLayer) # self.zoomFeature(zoom) # else: if self.usePanCkb.isChecked(): currentLayer.select(id) - self.iface.mapCanvas().panToFeatureIds( currentLayer, [id] ) + self.iface.mapCanvas().panToFeatureIds(currentLayer, [id]) return - self.zoomFeature(zoom, idDict = {'id':id, 'lyr':currentLayer}) + self.zoomFeature(zoom, idDict={"id": id, "lyr": currentLayer}) @pyqtSlot(bool) def on_onlySelectedRadioButton_toggled(self, toggled): @@ -406,18 +462,22 @@ def on_onlySelectedRadioButton_toggled(self, toggled): featIdList = currentLayer.allFeatureIds() self.setValues(featIdList, currentLayer) self.idSpinBox.setEnabled(True) - + @pyqtSlot(bool) def on_refreshPushButton_clicked(self): activeLayer = self.iface.activeLayer() if isinstance(activeLayer, QgsVectorLayer): self.mMapLayerComboBox.setLayer(activeLayer) else: - self.iface.messageBar().pushMessage(self.tr('Warning!'), self.tr('Active layer is not valid to be used in this tool.'), level=Qgis.Warning, duration=2) - self.mFieldExpressionWidget.setExpression('') - + self.iface.messageBar().pushMessage( + self.tr("Warning!"), + self.tr("Active layer is not valid to be used in this tool."), + level=Qgis.Warning, + duration=2, + ) + self.mFieldExpressionWidget.setExpression("") + def unload(self): self.iface.unregisterMainWindowAction(self.activateToolAction) self.iface.unregisterMainWindowAction(self.backButtonAction) self.iface.unregisterMainWindowAction(self.nextButtonAction) - diff --git a/DsgTools/gui/ProductionTools/Toolbars/InspectFeatures/inspectFeatures_ui.py b/DsgTools/gui/ProductionTools/Toolbars/InspectFeatures/inspectFeatures_ui.py index 06d8adc44..c51c70a71 100644 --- a/DsgTools/gui/ProductionTools/Toolbars/InspectFeatures/inspectFeatures_ui.py +++ b/DsgTools/gui/ProductionTools/Toolbars/InspectFeatures/inspectFeatures_ui.py @@ -8,11 +8,14 @@ from PyQt5 import QtCore, QtGui, QtWidgets + class Ui_Form(object): def setupUi(self, Form): Form.setObjectName("Form") Form.resize(858, 36) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.MinimumExpanding) + sizePolicy = QtWidgets.QSizePolicy( + QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.MinimumExpanding + ) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(Form.sizePolicy().hasHeightForWidth()) @@ -28,40 +31,66 @@ def setupUi(self, Form): self.splitter.setOrientation(QtCore.Qt.Horizontal) self.splitter.setObjectName("splitter") self.mMapLayerComboBox = QgsMapLayerComboBox(self.splitter) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.MinimumExpanding, QtWidgets.QSizePolicy.Fixed) + sizePolicy = QtWidgets.QSizePolicy( + QtWidgets.QSizePolicy.MinimumExpanding, QtWidgets.QSizePolicy.Fixed + ) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.mMapLayerComboBox.sizePolicy().hasHeightForWidth()) + sizePolicy.setHeightForWidth( + self.mMapLayerComboBox.sizePolicy().hasHeightForWidth() + ) self.mMapLayerComboBox.setSizePolicy(sizePolicy) self.mMapLayerComboBox.setMinimumSize(QtCore.QSize(0, 20)) self.mMapLayerComboBox.setMaximumSize(QtCore.QSize(16777215, 32)) - self.mMapLayerComboBox.setFilters(core.QgsMapLayerProxyModel.HasGeometry|core.QgsMapLayerProxyModel.LineLayer|core.QgsMapLayerProxyModel.NoGeometry|core.QgsMapLayerProxyModel.PluginLayer|core.QgsMapLayerProxyModel.PointLayer|core.QgsMapLayerProxyModel.PolygonLayer|core.QgsMapLayerProxyModel.VectorLayer) + self.mMapLayerComboBox.setFilters( + core.QgsMapLayerProxyModel.HasGeometry + | core.QgsMapLayerProxyModel.LineLayer + | core.QgsMapLayerProxyModel.NoGeometry + | core.QgsMapLayerProxyModel.PluginLayer + | core.QgsMapLayerProxyModel.PointLayer + | core.QgsMapLayerProxyModel.PolygonLayer + | core.QgsMapLayerProxyModel.VectorLayer + ) self.mMapLayerComboBox.setObjectName("mMapLayerComboBox") self.refreshPushButton = QtWidgets.QPushButton(self.splitter) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed) + sizePolicy = QtWidgets.QSizePolicy( + QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed + ) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.refreshPushButton.sizePolicy().hasHeightForWidth()) + sizePolicy.setHeightForWidth( + self.refreshPushButton.sizePolicy().hasHeightForWidth() + ) self.refreshPushButton.setSizePolicy(sizePolicy) self.refreshPushButton.setMinimumSize(QtCore.QSize(24, 24)) self.refreshPushButton.setMaximumSize(QtCore.QSize(24, 24)) self.refreshPushButton.setText("") icon = QtGui.QIcon() - icon.addPixmap(QtGui.QPixmap(":/plugins/DsgTools/icons/reload.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off) + icon.addPixmap( + QtGui.QPixmap(":/plugins/DsgTools/icons/reload.png"), + QtGui.QIcon.Normal, + QtGui.QIcon.Off, + ) self.refreshPushButton.setIcon(icon) self.refreshPushButton.setIconSize(QtCore.QSize(16, 16)) self.refreshPushButton.setObjectName("refreshPushButton") self.zoomPercentageSpinBox = QgsDoubleSpinBox(self.splitter) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed) + sizePolicy = QtWidgets.QSizePolicy( + QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed + ) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.zoomPercentageSpinBox.sizePolicy().hasHeightForWidth()) + sizePolicy.setHeightForWidth( + self.zoomPercentageSpinBox.sizePolicy().hasHeightForWidth() + ) self.zoomPercentageSpinBox.setSizePolicy(sizePolicy) self.zoomPercentageSpinBox.setMinimumSize(QtCore.QSize(0, 20)) self.zoomPercentageSpinBox.setMaximumSize(QtCore.QSize(16777215, 16777215)) self.zoomPercentageSpinBox.setObjectName("zoomPercentageSpinBox") self.mScaleWidget = QgsScaleWidget(self.splitter) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.MinimumExpanding, QtWidgets.QSizePolicy.Fixed) + sizePolicy = QtWidgets.QSizePolicy( + QtWidgets.QSizePolicy.MinimumExpanding, QtWidgets.QSizePolicy.Fixed + ) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(self.mScaleWidget.sizePolicy().hasHeightForWidth()) @@ -71,7 +100,9 @@ def setupUi(self, Form): self.mScaleWidget.setShowCurrentScaleButton(True) self.mScaleWidget.setObjectName("mScaleWidget") self.idSpinBox = QtWidgets.QSpinBox(self.splitter) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.MinimumExpanding, QtWidgets.QSizePolicy.Fixed) + sizePolicy = QtWidgets.QSizePolicy( + QtWidgets.QSizePolicy.MinimumExpanding, QtWidgets.QSizePolicy.Fixed + ) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(self.idSpinBox.sizePolicy().hasHeightForWidth()) @@ -81,8 +112,10 @@ def setupUi(self, Form): self.idSpinBox.setButtonSymbols(QtWidgets.QAbstractSpinBox.NoButtons) self.idSpinBox.setSuffix("") self.idSpinBox.setObjectName("idSpinBox") - self.usePanCkb = QtWidgets.QCheckBox(self.tr('Use pan'), self.splitter) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.MinimumExpanding, QtWidgets.QSizePolicy.Fixed) + self.usePanCkb = QtWidgets.QCheckBox(self.tr("Use pan"), self.splitter) + sizePolicy = QtWidgets.QSizePolicy( + QtWidgets.QSizePolicy.MinimumExpanding, QtWidgets.QSizePolicy.Fixed + ) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(self.usePanCkb.sizePolicy().hasHeightForWidth()) @@ -91,52 +124,80 @@ def setupUi(self, Form): self.usePanCkb.setMaximumSize(QtCore.QSize(70, 20)) self.usePanCkb.setObjectName("usePanCkb") self.backInspectButton = QtWidgets.QPushButton(self.splitter) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed) + sizePolicy = QtWidgets.QSizePolicy( + QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed + ) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.backInspectButton.sizePolicy().hasHeightForWidth()) + sizePolicy.setHeightForWidth( + self.backInspectButton.sizePolicy().hasHeightForWidth() + ) self.backInspectButton.setSizePolicy(sizePolicy) self.backInspectButton.setMinimumSize(QtCore.QSize(24, 24)) self.backInspectButton.setMaximumSize(QtCore.QSize(24, 24)) self.backInspectButton.setText("") icon = QtGui.QIcon() - icon.addPixmap(QtGui.QPixmap(":/plugins/DsgTools/icons/backInspect.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off) + icon.addPixmap( + QtGui.QPixmap(":/plugins/DsgTools/icons/backInspect.png"), + QtGui.QIcon.Normal, + QtGui.QIcon.Off, + ) self.backInspectButton.setIcon(icon) self.backInspectButton.setIconSize(QtCore.QSize(16, 16)) self.backInspectButton.setObjectName("backInspectButton") self.nextInspectButton = QtWidgets.QPushButton(self.splitter) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed) + sizePolicy = QtWidgets.QSizePolicy( + QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed + ) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.nextInspectButton.sizePolicy().hasHeightForWidth()) + sizePolicy.setHeightForWidth( + self.nextInspectButton.sizePolicy().hasHeightForWidth() + ) self.nextInspectButton.setSizePolicy(sizePolicy) self.nextInspectButton.setMinimumSize(QtCore.QSize(24, 24)) self.nextInspectButton.setMaximumSize(QtCore.QSize(24, 24)) self.nextInspectButton.setText("") icon1 = QtGui.QIcon() - icon1.addPixmap(QtGui.QPixmap(":/plugins/DsgTools/icons/nextInspect.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off) + icon1.addPixmap( + QtGui.QPixmap(":/plugins/DsgTools/icons/nextInspect.png"), + QtGui.QIcon.Normal, + QtGui.QIcon.Off, + ) self.nextInspectButton.setIcon(icon1) self.nextInspectButton.setIconSize(QtCore.QSize(16, 16)) self.nextInspectButton.setObjectName("nextInspectButton") self.mFieldExpressionWidget = QgsFieldExpressionWidget(self.splitter) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.MinimumExpanding, QtWidgets.QSizePolicy.Preferred) + sizePolicy = QtWidgets.QSizePolicy( + QtWidgets.QSizePolicy.MinimumExpanding, QtWidgets.QSizePolicy.Preferred + ) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.mFieldExpressionWidget.sizePolicy().hasHeightForWidth()) + sizePolicy.setHeightForWidth( + self.mFieldExpressionWidget.sizePolicy().hasHeightForWidth() + ) self.mFieldExpressionWidget.setSizePolicy(sizePolicy) self.mFieldExpressionWidget.setMinimumSize(QtCore.QSize(0, 20)) self.mFieldExpressionWidget.setObjectName("mFieldExpressionWidget") self.sortPushButton = QtWidgets.QPushButton(self.splitter) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed) + sizePolicy = QtWidgets.QSizePolicy( + QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed + ) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.sortPushButton.sizePolicy().hasHeightForWidth()) + sizePolicy.setHeightForWidth( + self.sortPushButton.sizePolicy().hasHeightForWidth() + ) self.sortPushButton.setSizePolicy(sizePolicy) self.sortPushButton.setMinimumSize(QtCore.QSize(24, 24)) self.sortPushButton.setMaximumSize(QtCore.QSize(24, 24)) self.sortPushButton.setText("") icon3 = QtGui.QIcon() - icon3.addPixmap(QtGui.QPixmap(":/plugins/DsgTools/icons/sort.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off) + icon3.addPixmap( + QtGui.QPixmap(":/plugins/DsgTools/icons/sort.png"), + QtGui.QIcon.Normal, + QtGui.QIcon.Off, + ) self.sortPushButton.setIcon(icon3) self.sortPushButton.setCheckable(True) self.sortPushButton.setObjectName("sortPushButton") @@ -144,10 +205,14 @@ def setupUi(self, Form): self.splitter2.setOrientation(QtCore.Qt.Horizontal) self.splitter2.setObjectName("splitter2") self.mFieldComboBox = QgsFieldComboBox(self.splitter2) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.MinimumExpanding, QtWidgets.QSizePolicy.Fixed) + sizePolicy = QtWidgets.QSizePolicy( + QtWidgets.QSizePolicy.MinimumExpanding, QtWidgets.QSizePolicy.Fixed + ) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.mFieldComboBox.sizePolicy().hasHeightForWidth()) + sizePolicy.setHeightForWidth( + self.mFieldComboBox.sizePolicy().hasHeightForWidth() + ) self.mFieldComboBox.setSizePolicy(sizePolicy) self.mFieldComboBox.setMinimumSize(QtCore.QSize(100, 0)) self.mFieldComboBox.setObjectName("mFieldComboBox") @@ -157,49 +222,75 @@ def setupUi(self, Form): self.horizontalLayout.setContentsMargins(0, 0, 0, 0) self.horizontalLayout.setObjectName("horizontalLayout") self.ascRadioButton = QtWidgets.QRadioButton(self.widget) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed) + sizePolicy = QtWidgets.QSizePolicy( + QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed + ) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.ascRadioButton.sizePolicy().hasHeightForWidth()) + sizePolicy.setHeightForWidth( + self.ascRadioButton.sizePolicy().hasHeightForWidth() + ) self.ascRadioButton.setSizePolicy(sizePolicy) self.ascRadioButton.setText("") icon4 = QtGui.QIcon() - icon4.addPixmap(QtGui.QPixmap(":/plugins/DsgTools/icons/up.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off) + icon4.addPixmap( + QtGui.QPixmap(":/plugins/DsgTools/icons/up.png"), + QtGui.QIcon.Normal, + QtGui.QIcon.Off, + ) self.ascRadioButton.setIcon(icon4) self.ascRadioButton.setChecked(True) self.ascRadioButton.setObjectName("ascRadioButton") self.horizontalLayout.addWidget(self.ascRadioButton) self.descRadioButton = QtWidgets.QRadioButton(self.widget) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed) + sizePolicy = QtWidgets.QSizePolicy( + QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed + ) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.descRadioButton.sizePolicy().hasHeightForWidth()) + sizePolicy.setHeightForWidth( + self.descRadioButton.sizePolicy().hasHeightForWidth() + ) self.descRadioButton.setSizePolicy(sizePolicy) self.descRadioButton.setText("") icon5 = QtGui.QIcon() - icon5.addPixmap(QtGui.QPixmap(":/plugins/DsgTools/icons/down.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off) + icon5.addPixmap( + QtGui.QPixmap(":/plugins/DsgTools/icons/down.png"), + QtGui.QIcon.Normal, + QtGui.QIcon.Off, + ) self.descRadioButton.setIcon(icon5) self.descRadioButton.setObjectName("descRadioButton") self.horizontalLayout.addWidget(self.descRadioButton) self.gridLayout.addWidget(self.splitter, 0, 2, 1, 1) self.inspectPushButton = QtWidgets.QPushButton(Form) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed) + sizePolicy = QtWidgets.QSizePolicy( + QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed + ) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.inspectPushButton.sizePolicy().hasHeightForWidth()) + sizePolicy.setHeightForWidth( + self.inspectPushButton.sizePolicy().hasHeightForWidth() + ) self.inspectPushButton.setSizePolicy(sizePolicy) self.inspectPushButton.setMinimumSize(QtCore.QSize(24, 24)) self.inspectPushButton.setMaximumSize(QtCore.QSize(24, 24)) self.inspectPushButton.setText("") icon2 = QtGui.QIcon() - icon2.addPixmap(QtGui.QPixmap(":/plugins/DsgTools/icons/inspectFeatures.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off) + icon2.addPixmap( + QtGui.QPixmap(":/plugins/DsgTools/icons/inspectFeatures.png"), + QtGui.QIcon.Normal, + QtGui.QIcon.Off, + ) self.inspectPushButton.setIcon(icon2) self.inspectPushButton.setIconSize(QtCore.QSize(16, 16)) self.inspectPushButton.setCheckable(True) self.inspectPushButton.setObjectName("inspectPushButton") self.gridLayout.addWidget(self.inspectPushButton, 0, 0, 1, 1) - spacerItem = QtWidgets.QSpacerItem(10, 20, QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Minimum) + spacerItem = QtWidgets.QSpacerItem( + 10, 20, QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Minimum + ) self.gridLayout.addItem(spacerItem, 0, 1, 1, 1) self.retranslateUi(Form) @@ -209,10 +300,24 @@ def retranslateUi(self, Form): _translate = QtCore.QCoreApplication.translate Form.setWindowTitle(_translate("Form", "Form")) # self.idSpinBox.setPrefix(_translate("Form", "ID: ")) - self.backInspectButton.setToolTip(_translate("Form", "

Back inspect


")) - self.nextInspectButton.setToolTip(_translate("Form", "

Next inspect

")) + self.backInspectButton.setToolTip( + _translate( + "Form", + "

Back inspect


", + ) + ) + self.nextInspectButton.setToolTip( + _translate("Form", "

Next inspect

") + ) self.inspectPushButton.setToolTip(_translate("Form", "Inspect Features Tool")) -from qgis.gui import QgsFieldExpressionWidget, QgsMapLayerComboBox, QgsScaleWidget, QgsDoubleSpinBox, QgsFieldComboBox + +from qgis.gui import ( + QgsFieldExpressionWidget, + QgsMapLayerComboBox, + QgsScaleWidget, + QgsDoubleSpinBox, + QgsFieldComboBox, +) from qgis import core import resources_rc diff --git a/DsgTools/gui/ProductionTools/Toolbars/MinimumAreaTool/customSizeSetter.py b/DsgTools/gui/ProductionTools/Toolbars/MinimumAreaTool/customSizeSetter.py index 40d6d9e71..e6db1e069 100644 --- a/DsgTools/gui/ProductionTools/Toolbars/MinimumAreaTool/customSizeSetter.py +++ b/DsgTools/gui/ProductionTools/Toolbars/MinimumAreaTool/customSizeSetter.py @@ -28,62 +28,65 @@ from qgis.PyQt.QtCore import pyqtSlot, pyqtSignal -FORM_CLASS, _ = uic.loadUiType(os.path.join( - os.path.dirname(__file__), 'customSizeSetter.ui')) +FORM_CLASS, _ = uic.loadUiType( + os.path.join(os.path.dirname(__file__), "customSizeSetter.ui") +) + class CustomSizeSetter(QtWidgets.QDialog, FORM_CLASS): sizeCreated = pyqtSignal(dict) - def __init__(self, customDict, parent = None): + + def __init__(self, customDict, parent=None): """Constructor.""" super(self.__class__, self).__init__(parent) self.customDict = customDict self.setupUi(self) - regex = QtCore.QRegExp('[0-9][0-9\.0-9]*') + regex = QtCore.QRegExp("[0-9][0-9\.0-9]*") validator = QtGui.QRegExpValidator(regex, self.measureLineEdit) self.measureLineEdit.setValidator(validator) - + def validateUi(self): - if self.comboTextLineEdit.text() == '': + if self.comboTextLineEdit.text() == "": return False - if self.measureLineEdit.text() == '': + if self.measureLineEdit.text() == "": return False return True - + def validateUiReason(self): - validateReason = '' - if self.comboTextLineEdit.text() == '': - validateReason += self.tr('Enter a combo box text!\n') - if self.measureLineEdit.text() == '': - validateReason += self.tr('Enter a measurement!\n') + validateReason = "" + if self.comboTextLineEdit.text() == "": + validateReason += self.tr("Enter a combo box text!\n") + if self.measureLineEdit.text() == "": + validateReason += self.tr("Enter a measurement!\n") return validateReason - + @pyqtSlot(bool) def on_okPushButton_clicked(self): if not self.validateUi(): reason = self.validateUiReason() - QtWidgets.QMessageBox.warning(self, self.tr('Warning!'), reason) + QtWidgets.QMessageBox.warning(self, self.tr("Warning!"), reason) else: self.done(1) newCustomDict = self.getCustomDictFromUi() self.sizeCreated.emit(newCustomDict) - + def getCustomDictFromUi(self): newValueDict = dict() if self.areaRadioButton.isChecked(): - newValueDict['shape'] = 'area' + newValueDict["shape"] = "area" else: - newValueDict['shape'] = 'distance' - newValueDict['comboText'] = self.comboTextLineEdit.text() - newValueDict['value'] = self.measureLineEdit.text() + newValueDict["shape"] = "distance" + newValueDict["comboText"] = self.comboTextLineEdit.text() + newValueDict["value"] = self.measureLineEdit.text() return newValueDict - - @pyqtSlot(bool, name = 'on_areaRadioButton_toggled') + + @pyqtSlot(bool, name="on_areaRadioButton_toggled") def turnButtonsOn(self, enabled): if enabled: - self.measureLabel.setText(self.tr(u'Area in mm²')) + self.measureLabel.setText(self.tr("Area in mm²")) else: - self.measureLabel.setText(self.tr('Distance in mm')) + self.measureLabel.setText(self.tr("Distance in mm")) @pyqtSlot(bool) - def on_cancelPushButton_clicked(self): + def on_cancelPushButton_clicked(self): self.done(0) diff --git a/DsgTools/gui/ProductionTools/Toolbars/MinimumAreaTool/minimumAreaTool.py b/DsgTools/gui/ProductionTools/Toolbars/MinimumAreaTool/minimumAreaTool.py index 4dfe01645..50cefcd1c 100644 --- a/DsgTools/gui/ProductionTools/Toolbars/MinimumAreaTool/minimumAreaTool.py +++ b/DsgTools/gui/ProductionTools/Toolbars/MinimumAreaTool/minimumAreaTool.py @@ -36,8 +36,10 @@ from .shapeTool import ShapeTool from .customSizeSetter import CustomSizeSetter -FORM_CLASS, _ = uic.loadUiType(os.path.join( - os.path.dirname(__file__), 'minimumAreaTool.ui')) +FORM_CLASS, _ = uic.loadUiType( + os.path.join(os.path.dirname(__file__), "minimumAreaTool.ui") +) + class MinimumAreaTool(QWidget, FORM_CLASS): def __init__(self, iface, parent=None): @@ -49,20 +51,24 @@ def __init__(self, iface, parent=None): self.parent = parent self.splitter.hide() self.iface = iface - self.mScaleWidget.setScaleString('1:100000') + self.mScaleWidget.setScaleString("1:100000") self.scale = None self.shape = None self.size = None self.populateSizesComboBox() - icon_path = ':/plugins/DsgTools/icons/minAreaTool.png' - text = self.tr('DSGTools: Minimum Area Tool') - self.showAction = self.add_action(icon_path, text, self.showPushButton.toggle, parent = self.parent) - self.iface.registerMainWindowAction(self.showAction, '') - icon_path = ':/plugins/DsgTools/icons/areaTool.png' - text = self.tr('DSGTools: Draw Shape') - self.shapeAction = self.add_action(icon_path, text, self.drawShape.click, parent = self.parent) - self.iface.registerMainWindowAction(self.shapeAction, '') - + icon_path = ":/plugins/DsgTools/icons/minAreaTool.png" + text = self.tr("DSGTools: Minimum Area Tool") + self.showAction = self.add_action( + icon_path, text, self.showPushButton.toggle, parent=self.parent + ) + self.iface.registerMainWindowAction(self.showAction, "") + icon_path = ":/plugins/DsgTools/icons/areaTool.png" + text = self.tr("DSGTools: Draw Shape") + self.shapeAction = self.add_action( + icon_path, text, self.drawShape.click, parent=self.parent + ) + self.iface.registerMainWindowAction(self.shapeAction, "") + def add_action(self, icon_path, text, callback, parent=None): icon = QIcon(icon_path) action = QAction(icon, text, parent) @@ -70,41 +76,41 @@ def add_action(self, icon_path, text, callback, parent=None): if parent: parent.addAction(action) return action - + def initGui(self): """ Adds the tool bar in QGIS """ self.iface.addToolBarWidget(self.splitter) - - def createDict(self, customDict = None): + + def createDict(self, customDict=None): """ Creates the dictionary used to create the geometry templates """ self.sizes = {} - self.sizes[u"25mm²"] = {'value': 25, 'shape': 'area'} - self.sizes[u"4mm²"] = {'value': 4, 'shape': 'area'} - self.sizes[u"1x1mm²"] = {'value': 1, 'shape': 'area'} - self.sizes[u"0.8x0.8mm²"] = {'value': 0.64, 'shape': 'area'} - self.sizes[u"0.8mm"] = {'value': 0.8,'shape': 'distance'} + self.sizes["25mm²"] = {"value": 25, "shape": "area"} + self.sizes["4mm²"] = {"value": 4, "shape": "area"} + self.sizes["1x1mm²"] = {"value": 1, "shape": "area"} + self.sizes["0.8x0.8mm²"] = {"value": 0.64, "shape": "area"} + self.sizes["0.8mm"] = {"value": 0.8, "shape": "distance"} if customDict: for key in customDict: self.sizes[key] = customDict[key] - + def shapeComboSetter(self): """ Sets the correct index for the shapes combo box according to the text select in the sizes combo box """ if self.sizesComboBox.currentText() in list(self.sizes.keys()): - if self.sizes[self.sizesComboBox.currentText()]['shape'] == 'distance': - #In this case we should force the use of circle, due to the measurement shape = distance and set the shape combo box enabled(False) + if self.sizes[self.sizesComboBox.currentText()]["shape"] == "distance": + # In this case we should force the use of circle, due to the measurement shape = distance and set the shape combo box enabled(False) self.shapesComboBox.setCurrentIndex(2) self.shapesComboBox.setEnabled(False) else: self.shapesComboBox.setEnabled(True) else: self.shapesComboBox.setEnabled(True) - + @pyqtSlot(int) def on_sizesComboBox_currentIndexChanged(self): """ @@ -113,7 +119,7 @@ def on_sizesComboBox_currentIndexChanged(self): """ if self.sizesComboBox.currentIndex() != 0: self.shapeComboSetter() - + @pyqtSlot(int) def on_shapesComboBox_currentIndexChanged(self): """ @@ -122,39 +128,53 @@ def on_shapesComboBox_currentIndexChanged(self): """ if self.shapesComboBox.currentIndex() != 0: self.shapeComboSetter() - + @pyqtSlot(bool) def on_drawShape_clicked(self): """ Draws the select template shape on the map canvas """ scaleText = self.mScaleWidget.scaleString() - scale = int(scaleText.split(':')[-1].replace('.','').replace(',',''))/1000 + scale = int(scaleText.split(":")[-1].replace(".", "").replace(",", "")) / 1000 size = self.sizesComboBox.currentText() shape = self.shapesComboBox.currentText() - validated = self.validateCombos(self.sizesComboBox.currentIndex(), self.shapesComboBox.currentIndex()) + validated = self.validateCombos( + self.sizesComboBox.currentIndex(), self.shapesComboBox.currentIndex() + ) if validated: self.run(scale, size, shape) else: - QMessageBox.warning(self.iface.mainWindow(), self.tr(u"Error!"), self.tr(u"Shape value not defined :
Define all values to activate tool!"), QMessageBox.Close) - + QMessageBox.warning( + self.iface.mainWindow(), + self.tr("Error!"), + self.tr( + "Shape value not defined :
Define all values to activate tool!" + ), + QMessageBox.Close, + ) + def run(self, scale, size, shape): """ Runs the ShapeTool and set it as the current map tool """ - #checking the selected type - if (self.sizes[size]['shape'] == 'area'): - param = (float(scale)**2)*float(self.sizes[size]['value']) + # checking the selected type + if self.sizes[size]["shape"] == "area": + param = (float(scale) ** 2) * float(self.sizes[size]["value"]) else: - param = float(scale)*float(self.sizes[size]['value']) + param = float(scale) * float(self.sizes[size]["value"]) color = self.mColorButton.color() color.setAlpha(63) - tool = ShapeTool(self.iface.mapCanvas(), shape, param, self.sizes[size]['shape'], color ) + tool = ShapeTool( + self.iface.mapCanvas(), shape, param, self.sizes[size]["shape"], color + ) tool.toolFinished.connect(self.refreshCombo) # draw the figure instantly, no need for move event at first me = QMouseEvent( - QEvent.MouseMove, iface.mapCanvas().mouseLastXY(), - Qt.NoButton, Qt.NoButton, Qt.NoModifier + QEvent.MouseMove, + iface.mapCanvas().mouseLastXY(), + Qt.NoButton, + Qt.NoButton, + Qt.NoModifier, ) # this maps the global positioning to canvas pos correctly and matches # the canvasMoveEvent slot/method signal. @@ -167,8 +187,8 @@ def refreshCombo(self): Re-enables the shapes combo """ self.shapesComboBox.setEnabled(True) - - def validateCombos(self,size,shape): + + def validateCombos(self, size, shape): """ Checks if all combos correctly selected """ @@ -177,7 +197,7 @@ def validateCombos(self,size,shape): else: return False - @pyqtSlot(bool, name = 'on_showPushButton_toggled') + @pyqtSlot(bool, name="on_showPushButton_toggled") def toggleBar(self, toggled=None): """ Slot to show/hide the tool bar @@ -188,61 +208,63 @@ def toggleBar(self, toggled=None): self.splitter.show() else: self.splitter.hide() - + def getCustomSizesDict(self): - #get custom sizes from qsettings + # get custom sizes from qsettings settings = QSettings() - settings.beginGroup('DSGTools/CustomSizes/') + settings.beginGroup("DSGTools/CustomSizes/") currentSettings = settings.childGroups() settings.endGroup() customSizesDict = dict() - #get each parameter + # get each parameter for settingName in currentSettings: customSizesDict[settingName] = dict() settings = QSettings() - settings.beginGroup('DSGTools/CustomSizes/'+settingName) - customSizesDict[settingName]['shape'] = settings.value('shape') - customSizesDict[settingName]['value'] = settings.value('value') + settings.beginGroup("DSGTools/CustomSizes/" + settingName) + customSizesDict[settingName]["shape"] = settings.value("shape") + customSizesDict[settingName]["value"] = settings.value("value") settings.endGroup() return customSizesDict - + def addValueToCustomSizesDict(self, newValueDict): settings = QSettings() - if not settings.contains('DSGTools/CustomSizes/'+newValueDict['comboText']+'/shape'): - settings.beginGroup('DSGTools/CustomSizes/'+newValueDict['comboText']) - settings.setValue('shape', newValueDict['shape']) - settings.setValue('value', newValueDict['value']) + if not settings.contains( + "DSGTools/CustomSizes/" + newValueDict["comboText"] + "/shape" + ): + settings.beginGroup("DSGTools/CustomSizes/" + newValueDict["comboText"]) + settings.setValue("shape", newValueDict["shape"]) + settings.setValue("value", newValueDict["value"]) settings.endGroup() self.populateSizesComboBox() - + def populateSizesComboBox(self): self.sizesComboBox.clear() - self.sizesComboBox.addItem(self.tr('SIZES')) - self.sizesComboBox.addItem(u'25mm²') - self.sizesComboBox.addItem(u'4mm²') - self.sizesComboBox.addItem(u'0.8x0.8mm²') - self.sizesComboBox.addItem(u'1x1mm²') - self.sizesComboBox.addItem(u'0.8mm') + self.sizesComboBox.addItem(self.tr("SIZES")) + self.sizesComboBox.addItem("25mm²") + self.sizesComboBox.addItem("4mm²") + self.sizesComboBox.addItem("0.8x0.8mm²") + self.sizesComboBox.addItem("1x1mm²") + self.sizesComboBox.addItem("0.8mm") customSizesDict = self.getCustomSizesDict() - self.createDict(customDict = customSizesDict) + self.createDict(customDict=customSizesDict) self.populateComboWithCustomSizes(customSizesDict) - + def updateAndPopulateSizes(self, sizeDict): self.size = sizeDict self.populateSizeComboBoxWithDict() - + def populateSizeComboBoxWithDict(self): self.sizesComboBox.clear() - self.sizesComboBox.addItem(self.tr('SIZES')) + self.sizesComboBox.addItem(self.tr("SIZES")) for key in self.sizes: self.sizesComboBox.addItem(key) - + def populateComboWithCustomSizes(self, customSizesDict): """ - Add to sizesComboBox values from customSizesDict and adds values to self.sizes + Add to sizesComboBox values from customSizesDict and adds values to self.sizes """ for size in list(customSizesDict.keys()): - #add item to comboBox + # add item to comboBox self.sizesComboBox.addItem(size) @pyqtSlot(bool) @@ -254,7 +276,7 @@ def on_createCustomSizesPushButton_clicked(self): dlg = CustomSizeSetter(customSizesDict) dlg.sizeCreated.connect(self.addValueToCustomSizesDict) dlg.exec_() - + def unload(self): try: self.iface.unregisterMainWindowAction(self.showAction) @@ -263,4 +285,4 @@ def unload(self): try: self.iface.unregisterMainWindowAction(self.shapeAction) except: - pass \ No newline at end of file + pass diff --git a/DsgTools/gui/ProductionTools/Toolbars/MinimumAreaTool/shapeTool.py b/DsgTools/gui/ProductionTools/Toolbars/MinimumAreaTool/shapeTool.py index bf10ef520..937fca146 100644 --- a/DsgTools/gui/ProductionTools/Toolbars/MinimumAreaTool/shapeTool.py +++ b/DsgTools/gui/ProductionTools/Toolbars/MinimumAreaTool/shapeTool.py @@ -26,31 +26,37 @@ from qgis.gui import QgsRubberBand, QgsMapTool from qgis.core import ( - QgsPointXY, - Qgis, - QgsWkbTypes, - QgsProject, - QgsDistanceArea, - QgsCoordinateTransformContext, - QgsCoordinateReferenceSystem + QgsPointXY, + Qgis, + QgsWkbTypes, + QgsProject, + QgsDistanceArea, + QgsCoordinateTransformContext, + QgsCoordinateReferenceSystem, ) from qgis.PyQt import QtGui, QtCore, QtWidgets -from qgis.core import (QgsPointXY, - QgsGeometry, - QgsWkbTypes, - QgsUnitTypes, - QgsDistanceArea, - QgsCoordinateTransform, - QgsCoordinateReferenceSystem, - QgsCoordinateTransformContext) +from qgis.core import ( + QgsPointXY, + QgsGeometry, + QgsWkbTypes, + QgsUnitTypes, + QgsDistanceArea, + QgsCoordinateTransform, + QgsCoordinateReferenceSystem, + QgsCoordinateTransformContext, +) from qgis.PyQt.QtCore import pyqtSignal, Qt as Qt2 from qgis.PyQt.QtGui import QColor, QCursor from qgis.PyQt.QtWidgets import QApplication + class ShapeTool(QgsMapTool): - #signal emitted when the mouse is clicked. This indicates that the tool finished its job + # signal emitted when the mouse is clicked. This indicates that the tool finished its job toolFinished = pyqtSignal() - def __init__(self, canvas, geometryType, param, type, color = QColor( 254, 178, 76, 63 )): + + def __init__( + self, canvas, geometryType, param, type, color=QColor(254, 178, 76, 63) + ): """ Constructor """ @@ -58,24 +64,24 @@ def __init__(self, canvas, geometryType, param, type, color = QColor( 254, 178, self.canvas = canvas self.active = False self.geometryType = self.tr(geometryType) - self.param=param - self.type=type - self.cursor=None - self.rubberBand = QgsRubberBand(self.canvas, QgsWkbTypes.PolygonGeometry) + self.param = param + self.type = type + self.cursor = None + self.rubberBand = QgsRubberBand(self.canvas, QgsWkbTypes.PolygonGeometry) self.setColor(color) self.reset() self.rotAngle = 0 self.currentCentroid = None self.rotate = False - + def setColor(self, mFillColor): """ Adjusting the color to create the rubber band """ - + self.rubberBand.setColor(mFillColor) self.rubberBand.setWidth(1) - + def reset(self): """ Resetting the rubber band @@ -94,15 +100,14 @@ def rotateRect(self, centroid, e): item_position = self.canvas.mapToGlobal(e.pos()) c = self.toCanvasCoordinates(centroid) c = self.canvas.mapToGlobal(c) - rotAngle = pi - atan2( - item_position.y() - c.y(), item_position.x() - c.x()) + rotAngle = pi - atan2(item_position.y() - c.y(), item_position.x() - c.x()) return rotAngle def canvasPressEvent(self, e): """ When the canvas is pressed the tool finishes its job """ - # enforce mouse restoring if clicked right after rotation + # enforce mouse restoring if clicked right after rotation QApplication.restoreOverrideCursor() self.canvas.unsetMapTool(self) self.toolFinished.emit() @@ -117,7 +122,8 @@ def _baseDistanceInMeters(self): source_crs = self.canvas.mapSettings().destinationCrs() dest_crs = QgsCoordinateReferenceSystem(3857) tr = QgsCoordinateTransform( - source_crs, dest_crs, QgsCoordinateTransformContext()) + source_crs, dest_crs, QgsCoordinateTransformContext() + ) p1t = QgsGeometry().fromPointXY(QgsPointXY(1, 0)) p1t.transform(tr) p2t = QgsGeometry().fromPointXY(QgsPointXY(0, 0)) @@ -130,7 +136,7 @@ def getAdjustedSize(self, size): size adjusted. This is necessary because input parameters are designed to be meters on tool's GUI. :param size: (float) tool's radius/length reference size in meters. - :return: (float) + :return: (float) """ source_crs = self.canvas.mapSettings().destinationCrs() if source_crs.mapUnits() != QgsUnitTypes.DistanceMeters: @@ -147,56 +153,61 @@ def canvasMoveEvent(self, e): # change rotate status self.rotate = False QApplication.restoreOverrideCursor() - self.endPoint = self.toMapCoordinates( e.pos() ) - elif e.button() != None and ctrlIsHeld \ - and self.geometryType == self.tr(u"Square"): + self.endPoint = self.toMapCoordinates(e.pos()) + elif ( + e.button() != None and ctrlIsHeld and self.geometryType == self.tr("Square") + ): # calculate angle between mouse and last rubberband centroid before holding control self.rotAngle = self.rotateRect(self.currentCentroid, e) if not self.rotate: # only override mouse if it is not overriden already QApplication.setOverrideCursor(QCursor(Qt2.BlankCursor)) self.rotate = True - if self.geometryType == self.tr(u"Circle"): - self.showCircle(self.endPoint, self.param) - elif self.geometryType == self.tr(u"Square"): + if self.geometryType == self.tr("Circle"): + self.showCircle(self.endPoint, self.param) + elif self.geometryType == self.tr("Square"): self.showRect(self.endPoint, self.param, self.rotAngle) - + def showCircle(self, startPoint, param): """ Draws a circle in the canvas """ - if not( self.type == self.tr('distance') ): - param = sqrt(param)/2 - #r = self.convertDistance( param ) + if not (self.type == self.tr("distance")): + param = sqrt(param) / 2 + # r = self.convertDistance( param ) nPoints = 50 x = startPoint.x() y = startPoint.y() - if self.type == self.tr('distance'): + if self.type == self.tr("distance"): r = self.getAdjustedSize(self.param) self.rubberBand.reset(QgsWkbTypes.PolygonGeometry) - for itheta in range(nPoints+1): - theta = itheta*(2.0*pi/nPoints) - self.rubberBand.addPoint(QgsPointXY(x+r*cos(theta), y+r*sin(theta))) + for itheta in range(nPoints + 1): + theta = itheta * (2.0 * pi / nPoints) + self.rubberBand.addPoint( + QgsPointXY(x + r * cos(theta), y + r * sin(theta)) + ) self.rubberBand.show() else: - r = self.getAdjustedSize(sqrt(self.param/pi)) + r = self.getAdjustedSize(sqrt(self.param / pi)) self.rubberBand.reset(QgsWkbTypes.PolygonGeometry) - for itheta in range(nPoints+1): - theta = itheta*(2.0*pi/nPoints) - self.rubberBand.addPoint(QgsPointXY(x+r*cos(theta), y+r*sin(theta))) + for itheta in range(nPoints + 1): + theta = itheta * (2.0 * pi / nPoints) + self.rubberBand.addPoint( + QgsPointXY(x + r * cos(theta), y + r * sin(theta)) + ) self.rubberBand.show() def showRect(self, startPoint, param, rotAngle=0): """ Draws a rectangle in the canvas - """ - if not( self.type == self.tr('distance') ): - param = sqrt(param)/2 - #param = self.convertDistance( param ) - + """ + if not (self.type == self.tr("distance")): + param = sqrt(param) / 2 + # param = self.convertDistance( param ) + self.rubberBand.reset(QgsWkbTypes.PolygonGeometry) - x = startPoint.x() # center point x - y = startPoint.y() # center point y + x = startPoint.x() # center point x + y = startPoint.y() # center point y # rotation angle is always applied in reference to center point # to avoid unnecessary calculations c = cos(rotAngle) @@ -216,12 +227,13 @@ def showRect(self, startPoint, param, rotAngle=0): def convertDistance(self, distance): distanceArea = QgsDistanceArea() - distanceArea.setSourceCrs( QgsCoordinateReferenceSystem(3857), QgsCoordinateTransformContext()) - return distanceArea.convertLengthMeasurement( - distance, - self.canvas.mapSettings().destinationCrs().mapUnits() + distanceArea.setSourceCrs( + QgsCoordinateReferenceSystem(3857), QgsCoordinateTransformContext() ) - + return distanceArea.convertLengthMeasurement( + distance, self.canvas.mapSettings().destinationCrs().mapUnits() + ) + def deactivate(self): """ Deactivates the tool and hides the rubber band @@ -230,7 +242,7 @@ def deactivate(self): QgsMapTool.deactivate(self) # restore mouse in case tool is disabled right after rotation QApplication.restoreOverrideCursor() - + def activate(self): """ Activates the tool diff --git a/DsgTools/gui/ProductionTools/Toolbars/ReviewTools/reviewToolbar.py b/DsgTools/gui/ProductionTools/Toolbars/ReviewTools/reviewToolbar.py index fd0332b14..c264c537c 100644 --- a/DsgTools/gui/ProductionTools/Toolbars/ReviewTools/reviewToolbar.py +++ b/DsgTools/gui/ProductionTools/Toolbars/ReviewTools/reviewToolbar.py @@ -23,9 +23,18 @@ import os from typing import List, Optional -from qgis.core import (Qgis, QgsCoordinateReferenceSystem, - QgsCoordinateTransform, QgsFeatureRequest, QgsMapLayer, - QgsProject, QgsRectangle, QgsVectorLayer, QgsWkbTypes, QgsFeature) +from qgis.core import ( + Qgis, + QgsCoordinateReferenceSystem, + QgsCoordinateTransform, + QgsFeatureRequest, + QgsMapLayer, + QgsProject, + QgsRectangle, + QgsVectorLayer, + QgsWkbTypes, + QgsFeature, +) from qgis.gui import QgsMapTool, QgsMessageBar, QgisInterface from qgis.PyQt import QtCore, QtGui, uic from qgis.PyQt.Qt import QObject, QVariant @@ -36,11 +45,14 @@ from qgis.core.additions.edit import edit from .review_ui import Ui_ReviewToolbar +from enum import Enum class ReviewToolbar(QWidget, Ui_ReviewToolbar): idxChanged = pyqtSignal(int) - def __init__(self, iface: QgisInterface, parent: Optional[QWidget] = None): + ZoomToNext, PanToNext, DoNothing = range(3) + + def __init__(self, iface: QgisInterface, parent: Optional[QWidget] = None): """ Constructor """ @@ -50,52 +62,60 @@ def __init__(self, iface: QgisInterface, parent: Optional[QWidget] = None): self.splitter.hide() self.iface = iface # self.iface.currentLayerChanged.connect(self.enableScale) - + self.canvas = self.iface.mapCanvas() self.mMapLayerComboBox.layerChanged.connect(self.visitedFieldComboBox.setLayer) self.mMapLayerComboBox.layerChanged.connect(self.rankFieldComboBox.setLayer) - self.setToolTip('') - self.visitedFieldComboBox.setToolTip(self.tr('Set visited field')) + self.setToolTip("") + self.visitedFieldComboBox.setToolTip(self.tr("Set visited field")) self.visitedFieldComboBox.setAllowEmptyFieldName(True) - self.rankFieldComboBox.setToolTip(self.tr('Set rank field')) + self.rankFieldComboBox.setToolTip(self.tr("Set rank field")) self.rankFieldComboBox.setAllowEmptyFieldName(True) - self.zoomToNextCheckBox.setChecked(True) - icon_path = ':/plugins/DsgTools/icons/attributeSelector.png' - text = self.tr('DSGTools: Mark tile as done') - self.applyPushButtonAction = self.add_action(icon_path, text, self.applyPushButton.click, parent = self.parent) - self.iface.registerMainWindowAction(self.applyPushButtonAction, '') - - text = self.tr('DSGTools: Mark tile as done') + self.zoomComboBox.setCurrentIndex(ReviewToolbar.ZoomToNext) + icon_path = ":/plugins/DsgTools/icons/attributeSelector.png" + text = self.tr("DSGTools: Mark tile as done") + self.applyPushButtonAction = self.add_action( + icon_path, text, self.applyPushButton.click, parent=self.parent + ) + self.iface.registerMainWindowAction(self.applyPushButtonAction, "") + + text = self.tr("DSGTools: Mark tile as done") self.previousTileAction = self.add_action( icon_path=":/plugins/DsgTools/icons/backInspect.png", - text=self.tr('DSGTools: Go to previous tile'), + text=self.tr("DSGTools: Go to previous tile"), callback=self.previousTileButton.click, - parent = self.parent + parent=self.parent, ) - self.iface.registerMainWindowAction(self.previousTileAction, '') + self.iface.registerMainWindowAction(self.previousTileAction, "") self.nextTileAction = self.add_action( icon_path=":/plugins/DsgTools/icons/nextInspect.png", - text=self.tr('DSGTools: Go to next tile'), + text=self.tr("DSGTools: Go to next tile"), callback=self.nextTileButton.click, - parent = self.parent + parent=self.parent, ) - self.iface.registerMainWindowAction(self.nextTileAction, '') - + self.iface.registerMainWindowAction(self.nextTileAction, "") + self.resetPushButtonAction = self.add_action( icon_path=":/plugins/DsgTools/icons/reset.png", - text=self.tr('DSGTools: Reset visited tiles on review toolbar'), + text=self.tr("DSGTools: Reset visited tiles on review toolbar"), callback=self.resetPushButton.click, - parent = self.parent + parent=self.parent, ) - self.iface.registerMainWindowAction(self.resetPushButtonAction, '') - + self.iface.registerMainWindowAction(self.resetPushButtonAction, "") + self.mMapLayerComboBox.setAllowEmptyLayer(True) self.mMapLayerComboBox.setCurrentIndex(0) self.currentTile = None self.originalValueList = self.getValueListFromQsettings() - - def add_action(self, icon_path: str, text: str, callback: QAction, parent: Optional[QWidget]=None) -> QAction: + + def add_action( + self, + icon_path: str, + text: str, + callback: QAction, + parent: Optional[QWidget] = None, + ) -> QAction: icon = QIcon(icon_path) action = QAction(icon, text, parent) action.triggered.connect(callback) @@ -104,74 +124,87 @@ def add_action(self, icon_path: str, text: str, callback: QAction, parent: Optio return action def enableTool(self, enabled: bool = True) -> None: - allowed = False if enabled == None or not isinstance(enabled, QgsVectorLayer) else True + allowed = ( + False + if enabled == None or not isinstance(enabled, QgsVectorLayer) + else True + ) toggled = self.reviewPushButton.isChecked() enabled = allowed and toggled self.applyPushButton.setEnabled(enabled) - - @pyqtSlot(int, name='on_rankFieldComboBox_currentIndexChanged') + + @pyqtSlot(int, name="on_rankFieldComboBox_currentIndexChanged") def validateRankField(self, idx: int) -> bool: if idx in (-1, 0): return False fieldName = self.rankFieldComboBox.itemText(idx) - fieldList = [field for field in self.rankFieldComboBox.fields() if field.name() == fieldName] + fieldList = [ + field + for field in self.rankFieldComboBox.fields() + if field.name() == fieldName + ] if len(fieldList) == 0 or fieldList[0].type() != QVariant.Int: self.iface.messageBar().pushMessage( - title=self.tr('Warning!'), - text=self.tr('Invalid rank field! Select an integer field with unique ordered items.'), + title=self.tr("Warning!"), + text=self.tr( + "Invalid rank field! Select an integer field with unique ordered items." + ), level=Qgis.Warning, - duration=2 + duration=2, ) self.rankFieldComboBox.setCurrentIndex(0) return False return True - - @pyqtSlot(int, name='on_visitedFieldComboBox_currentIndexChanged') + + @pyqtSlot(int, name="on_visitedFieldComboBox_currentIndexChanged") def validateVisitedField(self, idx: int) -> bool: if idx in (-1, 0): return False fieldName = self.visitedFieldComboBox.itemText(idx) fieldList = [ - field for field in self.visitedFieldComboBox.fields() \ - if field.name() == fieldName + field + for field in self.visitedFieldComboBox.fields() + if field.name() == fieldName ] if len(fieldList) == 0 or fieldList[0].type() != QVariant.Bool: self.iface.messageBar().pushMessage( - title=self.tr('Warning!'), - text=self.tr('Invalid attribute filter! Select a boolean field.'), + title=self.tr("Warning!"), + text=self.tr("Invalid attribute filter! Select a boolean field."), level=Qgis.Warning, - duration=2 + duration=2, ) self.visitedFieldComboBox.setCurrentIndex(0) return False return True - + def on_preparePushButton_clicked(self) -> None: currentLayer = self.mMapLayerComboBox.currentLayer() if currentLayer is None: self.iface.messageBar().pushMessage( - title=self.tr('Warning!'), - text=self.tr('Select a layer to prepare the environment!'), + title=self.tr("Warning!"), + text=self.tr("Select a layer to prepare the environment!"), level=Qgis.Warning, - duration=2 + duration=2, ) return if self.visitedFieldComboBox.currentIndex() == 0: self.iface.messageBar().pushMessage( - title=self.tr('Warning!'), - text=self.tr('Invalid attribute filter! Select a boolean field.'), + title=self.tr("Warning!"), + text=self.tr("Invalid attribute filter! Select a boolean field."), level=Qgis.Warning, - duration=2 + duration=2, ) return if not self.validateVisitedField(self.visitedFieldComboBox.currentIndex()): return if self.rankFieldComboBox.currentIndex() == 0: self.iface.messageBar().pushMessage( - title=self.tr('Warning!'), - text=self.tr('Invalid rank field! Select an integer field with unique ordered items.'), + title=self.tr("Warning!"), + text=self.tr( + "Invalid rank field! Select an integer field with unique ordered items." + ), level=Qgis.Warning, - duration=2 + duration=2, ) return if not self.validateRankField(self.rankFieldComboBox.currentIndex()): @@ -180,63 +213,62 @@ def on_preparePushButton_clicked(self) -> None: overviewWidget = self.getOverviewWidget() if overviewWidget is not None: overviewWidget.show() - currentLayerFromTreeRoot = QgsProject.instance().layerTreeRoot().findLayer( currentLayer.id() ) - currentLayerFromTreeRoot.setCustomProperty( "overview", 1 ) + currentLayerFromTreeRoot = ( + QgsProject.instance().layerTreeRoot().findLayer(currentLayer.id()) + ) + currentLayerFromTreeRoot.setCustomProperty("overview", 1) fieldList = [ - field for field in self.visitedFieldComboBox.fields() \ - if field.name() == self.visitedFieldComboBox.currentField() + field + for field in self.visitedFieldComboBox.fields() + if field.name() == self.visitedFieldComboBox.currentField() ] if len(fieldList) == 0 or fieldList[0].type() != QVariant.Bool: self.iface.messageBar().pushMessage( - title=self.tr('Warning!'), - text=self.tr('Invalid attribute filter!'), + title=self.tr("Warning!"), + text=self.tr("Invalid attribute filter!"), level=Qgis.Warning, - duration=2 + duration=2, ) return currentField = fieldList[0] self.applyStyle(currentLayer, currentField.name()) self.addCurrentLayerToGenericSelectionBlackList() currentLayer.setReadOnly(True) - - + def getOverviewWidget(self) -> None: itemList = [ - i for i in self.iface.mainWindow().children() \ - if i.objectName() == 'Overview' + i + for i in self.iface.mainWindow().children() + if i.objectName() == "Overview" ] - return None if len(itemList) == 0 \ - else itemList[0] - + return None if len(itemList) == 0 else itemList[0] + def applyStyle(self, lyr: QgsVectorLayer, fieldName: str) -> None: stylePath = self.createTempStyle(fieldName) lyr.loadNamedStyle(stylePath, True) lyr.triggerRepaint() self.deleteTempStyle(stylePath) - + def createTempStyle(self, fieldName: str) -> None: currentPath = os.path.dirname(os.path.abspath(__file__)) - templatePath = os.path.join(currentPath, 'grid_style.qml') - tempOutputPath = os.path.join(currentPath, 'grid_style_temp.qml') + templatePath = os.path.join(currentPath, "grid_style.qml") + tempOutputPath = os.path.join(currentPath, "grid_style_temp.qml") with open(templatePath) as f: templateFile = f.read() - templateFile = templateFile.replace( - 'attr="visited"', f'attr="{fieldName}"' - ) - with open(tempOutputPath, 'w') as f: + templateFile = templateFile.replace('attr="visited"', f'attr="{fieldName}"') + with open(tempOutputPath, "w") as f: f.write(templateFile) return tempOutputPath - + def deleteTempStyle(self, tempStylePath: str) -> None: os.remove(tempStylePath) - - @pyqtSlot(bool, name = 'on_reviewPushButton_toggled') + + @pyqtSlot(bool, name="on_reviewPushButton_toggled") def toggleBar(self, toggled: Optional[bool] = None) -> None: """ Shows/Hides the tool bar """ - toggled = self.reviewPushButton.isChecked() \ - if toggled is None else toggled + toggled = self.reviewPushButton.isChecked() if toggled is None else toggled if toggled: self.splitter.show() else: @@ -254,20 +286,29 @@ def on_previousTileButton_clicked(self) -> None: if visitedField is None: return request = self.getFeatureRequest( - rankField, - expression=f"{visitedField} = False", - ascending=True + rankField, expression=f"{visitedField} = False", ascending=True ) featDict = {feat.id(): feat for feat in layer.getFeatures(request)} featIdList = sorted(featDict.keys(), reverse=False) nFeats = len(featDict) if nFeats == 0: + self.iface.messageBar().pushMessage( + title=self.tr("Info!"), + text=self.tr("All tiles already visited!"), + level=Qgis.Info, + duration=2, + ) return - currentIdx = featIdList.index(self.currentTile) if self.currentTile in featIdList else 0 + currentIdx = ( + featIdList.index(self.currentTile) if self.currentTile in featIdList else 0 + ) nextFeature = featDict[featIdList[(currentIdx - 1)]] - self.zoomToFeature(nextFeature) + if self.zoomComboBox.currentIndex() == ReviewToolbar.ZoomToNext: + self.zoomToFeature(nextFeature) + else: + self.panToFeature(nextFeature) self.currentTile = nextFeature.id() - + @pyqtSlot(bool) def on_nextTileButton_clicked(self) -> None: layer = self.mMapLayerComboBox.currentLayer() @@ -280,20 +321,29 @@ def on_nextTileButton_clicked(self) -> None: if visitedField is None: return request = self.getFeatureRequest( - rankField, - expression=f"{visitedField} = False", - ascending=True + rankField, expression=f"{visitedField} = False", ascending=True ) featDict = {feat.id(): feat for feat in layer.getFeatures(request)} featIdList = sorted(featDict.keys(), reverse=False) nFeats = len(featDict) if nFeats == 0: + self.iface.messageBar().pushMessage( + title=self.tr("Info!"), + text=self.tr("All tiles already visited!"), + level=Qgis.Info, + duration=2, + ) return - currentIdx = featIdList.index(self.currentTile) if self.currentTile in featIdList else -1 + currentIdx = ( + featIdList.index(self.currentTile) if self.currentTile in featIdList else -1 + ) nextFeature = featDict[featIdList[(currentIdx + 1) % nFeats]] - self.zoomToFeature(nextFeature) + if self.zoomComboBox.currentIndex() == ReviewToolbar.ZoomToNext: + self.zoomToFeature(nextFeature) + else: + self.panToFeature(nextFeature) self.currentTile = nextFeature.id() - + @pyqtSlot(bool) def on_resetPushButton_clicked(self) -> None: layer = self.mMapLayerComboBox.currentLayer() @@ -302,14 +352,19 @@ def on_resetPushButton_clicked(self) -> None: visitedField = self.visitedFieldComboBox.currentField() if visitedField is None: return - if not QMessageBox.question( - self, self.tr('DSGTools Review Toolbar: Confirm action'), self.tr('Would you like to set all features from grid as unvisited?'), - QMessageBox.Ok|QMessageBox.Cancel - ) == QMessageBox.Ok: + if ( + not QMessageBox.question( + self, + self.tr("DSGTools Review Toolbar: Confirm action"), + self.tr("Would you like to set all features from grid as unvisited?"), + QMessageBox.Ok | QMessageBox.Cancel, + ) + == QMessageBox.Ok + ): return layer.setReadOnly(False) layer.startEditing() - layer.beginEditCommand('DSGTools review tool') + layer.beginEditCommand("DSGTools review tool") for feat in layer.getFeatures(): feat[visitedField] = False layer.updateFeature(feat) @@ -317,25 +372,37 @@ def on_resetPushButton_clicked(self) -> None: layer.commitChanges() layer.setReadOnly(True) - @pyqtSlot(bool) def on_applyPushButton_clicked(self) -> None: selectedFeatures = self.getSelectedFeatures() - featList = selectedFeatures if selectedFeatures != [] \ + featList = ( + selectedFeatures + if selectedFeatures != [] else self.getFeaturesFromCursorBoundingBox() + ) if featList == []: return self.setFeaturesAsVisited(featList) nextFeat = self.getNextFeature(featList[0]) if nextFeat is None: + self.iface.messageBar().pushMessage( + title=self.tr("Info!"), + text=self.tr("All tiles already visited!"), + level=Qgis.Info, + duration=2, + ) return - if self.zoomToNextCheckBox.isChecked(): + if self.zoomComboBox.currentIndex() == ReviewToolbar.ZoomToNext: self.zoomToFeature(nextFeat) + elif self.zoomComboBox.currentIndex() == ReviewToolbar.PanToNext: + self.panToFeature(nextFeat) + else: + self.iface.mapCanvas().refresh() currentField = self.rankFieldComboBox.currentField() if currentField is None: return self.currentTile = nextFeat.id() - + def getSelectedFeatures(self) -> List[QgsFeature]: layer = self.mMapLayerComboBox.currentLayer() if layer is None: @@ -351,9 +418,7 @@ def getFeaturesFromCursorBoundingBox(self) -> List[QgsFeature]: def getBoundingBoxFromCursor(self, layer: QgsVectorLayer) -> QgsRectangle: rect = self.getCursorRect() - bbRect = ( - self.iface.mapCanvas().mapSettings().mapToLayerCoordinates(layer, rect) - ) + bbRect = self.iface.mapCanvas().mapSettings().mapToLayerCoordinates(layer, rect) return bbRect def getCursorRect(self): @@ -362,7 +427,7 @@ def getCursorRect(self): ) w = self.iface.mapCanvas().mapUnitsPerPixel() * 10 return QgsRectangle(p.x() - w, p.y() - w, p.x() + w, p.y() + w) - + def setFeaturesAsVisited(self, featureList: List[QgsFeature]) -> None: layer = self.mMapLayerComboBox.currentLayer() if layer is None: @@ -370,15 +435,14 @@ def setFeaturesAsVisited(self, featureList: List[QgsFeature]) -> None: visitedField = self.visitedFieldComboBox.currentField() layer.setReadOnly(False) layer.startEditing() - layer.beginEditCommand('DSGTools review tool') + layer.beginEditCommand("DSGTools review tool") for feat in featureList: feat[visitedField] = not feat[visitedField] layer.updateFeature(feat) layer.endEditCommand() layer.commitChanges() layer.setReadOnly(True) - - + def getNextFeature(self, currentFeature, forward=True) -> QgsFeature: layer = self.mMapLayerComboBox.currentLayer() if layer is None: @@ -391,13 +455,12 @@ def getNextFeature(self, currentFeature, forward=True) -> QgsFeature: return # we first try to get the next local feature if currentFeature is not None: - expression = f"{visitedField} = False and {rankField} > {currentFeature[rankField]} " if forward \ + expression = ( + f"{visitedField} = False and {rankField} > {currentFeature[rankField]} " + if forward else f"{visitedField} = False and {rankField} < {currentFeature[rankField]} " - request = self.getFeatureRequest( - rankField, - expression=expression, - limit=1 ) + request = self.getFeatureRequest(rankField, expression=expression, limit=1) nextFeat = next(layer.getFeatures(request), None) if nextFeat is not None: return nextFeat @@ -406,19 +469,20 @@ def getNextFeature(self, currentFeature, forward=True) -> QgsFeature: rankField, expression=f"{visitedField} = False", ascending=True if forward else False, - limit=1 + limit=1, ) return next(layer.getFeatures(request), None) - def getFeatureRequest(self, rankField: str, expression: str, ascending: bool=True, limit: Optional[int]=None): + def getFeatureRequest( + self, + rankField: str, + expression: str, + ascending: bool = True, + limit: Optional[int] = None, + ): request = QgsFeatureRequest().setFilterExpression(expression) orderby = QgsFeatureRequest.OrderBy( - [ - QgsFeatureRequest.OrderByClause( - rankField, - ascending=ascending - ) - ] + [QgsFeatureRequest.OrderByClause(rankField, ascending=ascending)] ) request.setOrderBy(orderby) if limit is not None: @@ -430,24 +494,34 @@ def zoomToFeature(self, feat: QgsFeature) -> None: if layer is None: return bbox = feat.geometry().boundingBox() - bbox.grow(min(bbox.width(),bbox.height())*0.4) + bbox.grow(min(bbox.width(), bbox.height()) * 0.4) epsg = self.iface.mapCanvas().mapSettings().destinationCrs().authid() crsDest = QgsCoordinateReferenceSystem(epsg) srid = layer.crs().authid() - crsSrc = QgsCoordinateReferenceSystem(srid) #here we have to put authid, not srid + crsSrc = QgsCoordinateReferenceSystem( + srid + ) # here we have to put authid, not srid # Creating a transformer - coordinateTransformer = QgsCoordinateTransform(crsSrc, crsDest, QgsProject.instance()) + coordinateTransformer = QgsCoordinateTransform( + crsSrc, crsDest, QgsProject.instance() + ) newBox = coordinateTransformer.transform(bbox) self.iface.mapCanvas().setExtent(newBox) self.iface.mapCanvas().refresh() - + + def panToFeature(self, feat: QgsFeature) -> None: + layer = self.mMapLayerComboBox.currentLayer() + if layer is None: + return + self.iface.mapCanvas().panToFeatureIds(layer, [feat.id()]) + def addCurrentLayerToGenericSelectionBlackList(self, layer=None): layer = self.mMapLayerComboBox.currentLayer() if layer is None else layer if layer is None: return self.addLayerNameToGenericSelectionBlackList(layer.name()) - @pyqtSlot(QgsVectorLayer, name='on_mMapLayerComboBox_layerChanged') + @pyqtSlot(QgsVectorLayer, name="on_mMapLayerComboBox_layerChanged") def removeLayerFromGenericSelectionBlackList(self, layer=None): layer = self.mMapLayerComboBox.currentLayer() if layer is None else layer if layer is None: @@ -458,45 +532,53 @@ def removeLayerFromGenericSelectionBlackList(self, layer=None): def addLayerNameToGenericSelectionBlackList(self, layerName: str): settings = QSettings() - settings.beginGroup('PythonPlugins/DsgTools/Options') - valueList = [i for i in settings.value('valueList').split(';') if i != ''] + settings.beginGroup("PythonPlugins/DsgTools/Options") + valueList = [i for i in settings.value("valueList").split(";") if i != ""] if layerName in valueList: return valueList.append(layerName) - settings.setValue('valueList', ';'.join(valueList)) + settings.setValue("valueList", ";".join(valueList)) settings.endGroup() def removeLayerNameToGenericSelectionBlackList(self, layerName): settings = QSettings() - settings.beginGroup('PythonPlugins/DsgTools/Options') - valueList = [i for i in settings.value('valueList').split(';') if i != ''] - if valueList != [] and (layerName not in valueList or layerName in self.originalValueList): + settings.beginGroup("PythonPlugins/DsgTools/Options") + valueList = [i for i in settings.value("valueList").split(";") if i != ""] + if valueList != [] and ( + layerName not in valueList or layerName in self.originalValueList + ): return valueList.pop(layerName) - settings.setValue('valueList', ';'.join(valueList)) + settings.setValue("valueList", ";".join(valueList)) settings.endGroup() - + def getValueListFromQsettings(self): settings = QSettings() - settings.beginGroup('PythonPlugins/DsgTools/Options') - valueList = [i for i in settings.value('valueList').split(';') if i != ''] + settings.beginGroup("PythonPlugins/DsgTools/Options") + valueList = [i for i in settings.value("valueList").split(";") if i != ""] settings.endGroup() return valueList - + def restoreOriginalValueList(self): settings = QSettings() - settings.beginGroup('PythonPlugins/DsgTools/Options') + settings.beginGroup("PythonPlugins/DsgTools/Options") valueList = self.originalValueList - settings.setValue('valueList', ';'.join(valueList)) + settings.setValue("valueList", ";".join(valueList)) settings.endGroup() def unload(self) -> None: self.restoreOriginalValueList() - self.iface.unregisterMainWindowAction(self.applyPushButtonAction) - - def setState(self, layer: QgsVectorLayer, rankFieldName: str, visitedFieldName: str, zoomEnabled: bool = True): + self.iface.unregisterMainWindowAction(self.applyPushButtonAction) + + def setState( + self, + layer: QgsVectorLayer, + rankFieldName: str, + visitedFieldName: str, + zoomType: int = 0, + ): self.mMapLayerComboBox.setLayer(layer) self.rankFieldComboBox.setField(rankFieldName) self.visitedFieldComboBox.setField(visitedFieldName) - self.zoomToNextCheckBox.setChecked(zoomEnabled) + self.zoomComboBox.setCurrentIndex(int(zoomType)) self.preparePushButton.click() diff --git a/DsgTools/gui/ProductionTools/Toolbars/ReviewTools/review_ui.py b/DsgTools/gui/ProductionTools/Toolbars/ReviewTools/review_ui.py index f12a06f73..3cd0cb8d8 100644 --- a/DsgTools/gui/ProductionTools/Toolbars/ReviewTools/review_ui.py +++ b/DsgTools/gui/ProductionTools/Toolbars/ReviewTools/review_ui.py @@ -15,7 +15,9 @@ class Ui_ReviewToolbar(object): def setupUi(self, ReviewToolbar): ReviewToolbar.setObjectName("ReviewToolbar") ReviewToolbar.resize(335, 50) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.MinimumExpanding) + sizePolicy = QtWidgets.QSizePolicy( + QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.MinimumExpanding + ) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(ReviewToolbar.sizePolicy().hasHeightForWidth()) @@ -26,16 +28,24 @@ def setupUi(self, ReviewToolbar): self.gridLayout = QtWidgets.QGridLayout(ReviewToolbar) self.gridLayout.setObjectName("gridLayout") self.reviewPushButton = QtWidgets.QPushButton(ReviewToolbar) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed) + sizePolicy = QtWidgets.QSizePolicy( + QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed + ) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.reviewPushButton.sizePolicy().hasHeightForWidth()) + sizePolicy.setHeightForWidth( + self.reviewPushButton.sizePolicy().hasHeightForWidth() + ) self.reviewPushButton.setSizePolicy(sizePolicy) self.reviewPushButton.setMinimumSize(QtCore.QSize(24, 24)) self.reviewPushButton.setMaximumSize(QtCore.QSize(24, 24)) self.reviewPushButton.setText("") icon = QtGui.QIcon() - icon.addPixmap(QtGui.QPixmap(":/plugins/DsgTools/icons/review.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off) + icon.addPixmap( + QtGui.QPixmap(":/plugins/DsgTools/icons/review.png"), + QtGui.QIcon.Normal, + QtGui.QIcon.Off, + ) self.reviewPushButton.setIcon(icon) self.reviewPushButton.setIconSize(QtCore.QSize(16, 16)) self.reviewPushButton.setCheckable(True) @@ -46,112 +56,167 @@ def setupUi(self, ReviewToolbar): self.splitter.setOrientation(QtCore.Qt.Horizontal) self.splitter.setObjectName("splitter") self.mMapLayerComboBox = QgsMapLayerComboBox(self.splitter) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.MinimumExpanding, QtWidgets.QSizePolicy.Fixed) + sizePolicy = QtWidgets.QSizePolicy( + QtWidgets.QSizePolicy.MinimumExpanding, QtWidgets.QSizePolicy.Fixed + ) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.mMapLayerComboBox.sizePolicy().hasHeightForWidth()) + sizePolicy.setHeightForWidth( + self.mMapLayerComboBox.sizePolicy().hasHeightForWidth() + ) self.mMapLayerComboBox.setSizePolicy(sizePolicy) self.mMapLayerComboBox.setMinimumSize(QtCore.QSize(0, 24)) self.mMapLayerComboBox.setObjectName("mMapLayerComboBox") self.mMapLayerComboBox.setFilters(core.QgsMapLayerProxyModel.PolygonLayer) self.rankFieldComboBox = QgsFieldComboBox(self.splitter) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.MinimumExpanding, QtWidgets.QSizePolicy.Fixed) + sizePolicy = QtWidgets.QSizePolicy( + QtWidgets.QSizePolicy.MinimumExpanding, QtWidgets.QSizePolicy.Fixed + ) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.rankFieldComboBox.sizePolicy().hasHeightForWidth()) + sizePolicy.setHeightForWidth( + self.rankFieldComboBox.sizePolicy().hasHeightForWidth() + ) self.rankFieldComboBox.setSizePolicy(sizePolicy) self.rankFieldComboBox.setMinimumSize(QtCore.QSize(0, 24)) self.rankFieldComboBox.setObjectName("rankFieldComboBox") self.visitedFieldComboBox = QgsFieldComboBox(self.splitter) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.MinimumExpanding, QtWidgets.QSizePolicy.Fixed) + sizePolicy = QtWidgets.QSizePolicy( + QtWidgets.QSizePolicy.MinimumExpanding, QtWidgets.QSizePolicy.Fixed + ) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.visitedFieldComboBox.sizePolicy().hasHeightForWidth()) + sizePolicy.setHeightForWidth( + self.visitedFieldComboBox.sizePolicy().hasHeightForWidth() + ) self.visitedFieldComboBox.setSizePolicy(sizePolicy) self.visitedFieldComboBox.setMinimumSize(QtCore.QSize(0, 24)) self.visitedFieldComboBox.setObjectName("visitedFieldComboBox") - self.zoomToNextCheckBox = QtWidgets.QCheckBox(self.tr('Zoom to next'), self.splitter) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.MinimumExpanding, QtWidgets.QSizePolicy.Fixed) + self.zoomComboBox = QtWidgets.QComboBox(self.splitter) + sizePolicy = QtWidgets.QSizePolicy( + QtWidgets.QSizePolicy.MinimumExpanding, QtWidgets.QSizePolicy.Fixed + ) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.zoomToNextCheckBox.sizePolicy().hasHeightForWidth()) - self.zoomToNextCheckBox.setSizePolicy(sizePolicy) - self.zoomToNextCheckBox.setMinimumSize(QtCore.QSize(70, 20)) - self.zoomToNextCheckBox.setMaximumSize(QtCore.QSize(70, 20)) - self.zoomToNextCheckBox.setObjectName("zoomToNextCheckBox") + sizePolicy.setHeightForWidth(self.zoomComboBox.sizePolicy().hasHeightForWidth()) + self.zoomComboBox.setSizePolicy(sizePolicy) + self.zoomComboBox.setMinimumSize(QtCore.QSize(0, 24)) + self.zoomComboBox.setObjectName("zoomComboBox") + self.zoomComboBox.addItem(self.tr("Zoom to next")) + self.zoomComboBox.addItem(self.tr("Pan to next")) + self.zoomComboBox.addItem(self.tr("Do nothing")) self.preparePushButton = QtWidgets.QPushButton(self.splitter) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed) + sizePolicy = QtWidgets.QSizePolicy( + QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed + ) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.preparePushButton.sizePolicy().hasHeightForWidth()) + sizePolicy.setHeightForWidth( + self.preparePushButton.sizePolicy().hasHeightForWidth() + ) self.preparePushButton.setSizePolicy(sizePolicy) self.preparePushButton.setMinimumSize(QtCore.QSize(0, 24)) self.preparePushButton.setMaximumSize(QtCore.QSize(24, 24)) self.preparePushButton.setText("") icon1 = QtGui.QIcon() - icon1.addPixmap(QtGui.QPixmap(":/plugins/DsgTools/icons/config.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off) + icon1.addPixmap( + QtGui.QPixmap(":/plugins/DsgTools/icons/config.png"), + QtGui.QIcon.Normal, + QtGui.QIcon.Off, + ) self.preparePushButton.setIcon(icon1) self.preparePushButton.setIconSize(QtCore.QSize(16, 16)) self.preparePushButton.setObjectName("preparePushButton") self.previousTileButton = QtWidgets.QPushButton(self.splitter) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed) + sizePolicy = QtWidgets.QSizePolicy( + QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed + ) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.previousTileButton.sizePolicy().hasHeightForWidth()) + sizePolicy.setHeightForWidth( + self.previousTileButton.sizePolicy().hasHeightForWidth() + ) self.previousTileButton.setSizePolicy(sizePolicy) self.previousTileButton.setMinimumSize(QtCore.QSize(24, 24)) self.previousTileButton.setMaximumSize(QtCore.QSize(24, 24)) self.previousTileButton.setText("") icon = QtGui.QIcon() - icon.addPixmap(QtGui.QPixmap(":/plugins/DsgTools/icons/backInspect.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off) + icon.addPixmap( + QtGui.QPixmap(":/plugins/DsgTools/icons/backInspect.png"), + QtGui.QIcon.Normal, + QtGui.QIcon.Off, + ) self.previousTileButton.setIcon(icon) self.previousTileButton.setIconSize(QtCore.QSize(16, 16)) self.previousTileButton.setObjectName("previousTileButton") self.nextTileButton = QtWidgets.QPushButton(self.splitter) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed) + sizePolicy = QtWidgets.QSizePolicy( + QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed + ) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.nextTileButton.sizePolicy().hasHeightForWidth()) + sizePolicy.setHeightForWidth( + self.nextTileButton.sizePolicy().hasHeightForWidth() + ) self.nextTileButton.setSizePolicy(sizePolicy) self.nextTileButton.setMinimumSize(QtCore.QSize(24, 24)) self.nextTileButton.setMaximumSize(QtCore.QSize(24, 24)) self.nextTileButton.setText("") icon1 = QtGui.QIcon() - icon1.addPixmap(QtGui.QPixmap(":/plugins/DsgTools/icons/nextInspect.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off) + icon1.addPixmap( + QtGui.QPixmap(":/plugins/DsgTools/icons/nextInspect.png"), + QtGui.QIcon.Normal, + QtGui.QIcon.Off, + ) self.nextTileButton.setIcon(icon1) self.nextTileButton.setIconSize(QtCore.QSize(16, 16)) self.nextTileButton.setObjectName("nextTileButton") self.applyPushButton = QtWidgets.QPushButton(self.splitter) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed) + sizePolicy = QtWidgets.QSizePolicy( + QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed + ) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.applyPushButton.sizePolicy().hasHeightForWidth()) + sizePolicy.setHeightForWidth( + self.applyPushButton.sizePolicy().hasHeightForWidth() + ) self.applyPushButton.setSizePolicy(sizePolicy) self.applyPushButton.setMinimumSize(QtCore.QSize(0, 24)) self.applyPushButton.setMaximumSize(QtCore.QSize(24, 24)) self.applyPushButton.setText("") icon2 = QtGui.QIcon() - icon2.addPixmap(QtGui.QPixmap(":/plugins/DsgTools/icons/attributeSelector.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off) + icon2.addPixmap( + QtGui.QPixmap(":/plugins/DsgTools/icons/attributeSelector.png"), + QtGui.QIcon.Normal, + QtGui.QIcon.Off, + ) self.applyPushButton.setIcon(icon2) self.applyPushButton.setIconSize(QtCore.QSize(16, 16)) self.applyPushButton.setObjectName("applyPushButton") - + self.resetPushButton = QtWidgets.QPushButton(self.splitter) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed) + sizePolicy = QtWidgets.QSizePolicy( + QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed + ) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.resetPushButton.sizePolicy().hasHeightForWidth()) + sizePolicy.setHeightForWidth( + self.resetPushButton.sizePolicy().hasHeightForWidth() + ) self.resetPushButton.setSizePolicy(sizePolicy) self.resetPushButton.setMinimumSize(QtCore.QSize(0, 24)) self.resetPushButton.setMaximumSize(QtCore.QSize(24, 24)) self.resetPushButton.setText("") icon2 = QtGui.QIcon() - icon2.addPixmap(QtGui.QPixmap(":/plugins/DsgTools/icons/reset.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off) + icon2.addPixmap( + QtGui.QPixmap(":/plugins/DsgTools/icons/reset.png"), + QtGui.QIcon.Normal, + QtGui.QIcon.Off, + ) self.resetPushButton.setIcon(icon2) self.resetPushButton.setIconSize(QtCore.QSize(16, 16)) self.resetPushButton.setObjectName("resetPushButton") - - + self.gridLayout.addWidget(self.splitter, 0, 1, 1, 1) self.retranslateUi(ReviewToolbar) @@ -160,9 +225,12 @@ def setupUi(self, ReviewToolbar): def retranslateUi(self, ReviewToolbar): _translate = QtCore.QCoreApplication.translate ReviewToolbar.setWindowTitle(_translate("ReviewToolbar", "Form")) - self.reviewPushButton.setToolTip(_translate("ReviewToolbar", "Inspect Features Tool")) + self.reviewPushButton.setToolTip( + _translate("ReviewToolbar", "Inspect Features Tool") + ) + + from qgis import core from qgsfieldcombobox import QgsFieldComboBox from qgsmaplayercombobox import QgsMapLayerComboBox import resources_rc - diff --git a/DsgTools/gui/ProductionTools/Toolbars/StyleManagerTool/styleManagerTool.py b/DsgTools/gui/ProductionTools/Toolbars/StyleManagerTool/styleManagerTool.py index 455b69d76..faf8ea18e 100644 --- a/DsgTools/gui/ProductionTools/Toolbars/StyleManagerTool/styleManagerTool.py +++ b/DsgTools/gui/ProductionTools/Toolbars/StyleManagerTool/styleManagerTool.py @@ -28,7 +28,14 @@ from qgis.PyQt import QtGui, uic, QtCore from qgis.PyQt.Qt import QWidget, QObject -from qgis.core import QgsMapLayer, Qgis, QgsDataSourceUri, QgsMessageLog, QgsVectorLayer, QgsProcessingContext +from qgis.core import ( + QgsMapLayer, + Qgis, + QgsDataSourceUri, + QgsMessageLog, + QgsVectorLayer, + QgsProcessingContext, +) from .....core.Factories.DbFactory.dbFactory import DbFactory from .....core.Factories.LayerLoaderFactory.layerLoaderFactory import LayerLoaderFactory @@ -37,11 +44,13 @@ from DsgTools.core.dsgEnums import DsgEnums from DsgTools.core.DSGToolsProcessingAlgs.algRunner import AlgRunner -FORM_CLASS, _ = uic.loadUiType(os.path.join( - os.path.dirname(__file__), 'styleManagerTool.ui')) +FORM_CLASS, _ = uic.loadUiType( + os.path.join(os.path.dirname(__file__), "styleManagerTool.ui") +) -class StyleManagerTool(QWidget, FORM_CLASS): - def __init__(self, iface, parent = None): + +class StyleManagerTool(QWidget, FORM_CLASS): + def __init__(self, iface, parent=None): """ Constructor """ @@ -54,7 +63,7 @@ def __init__(self, iface, parent = None): # self.applyPushButton.setEnabled(False) self.utils = Utils() self.algRunner = AlgRunner() - + @pyqtSlot(bool) def on_layerPushButton_toggled(self, toggled): """ @@ -65,16 +74,16 @@ def on_layerPushButton_toggled(self, toggled): self.splitter.show() else: self.splitter.hide() - - @pyqtSlot(bool, name = 'on_refreshPushButton_clicked') + + @pyqtSlot(bool, name="on_refreshPushButton_clicked") def refreshDb(self): self.dbComboBox.clear() - self.dbComboBox.addItem(self.tr('Select Database')) - #populate database list + self.dbComboBox.addItem(self.tr("Select Database")) + # populate database list for dbName in self.getDatabaseList(): self.dbComboBox.addItem(dbName) - @pyqtSlot(int, name = 'on_styleComboBox_currentIndexChanged') + @pyqtSlot(int, name="on_styleComboBox_currentIndexChanged") def enableApply(self): dbIdx = self.dbComboBox.currentIndex() stylesIdx = self.styleComboBox.currentIndex() @@ -94,21 +103,20 @@ def on_applyPushButton_clicked(self): dbVersion = abstractDb.getDatabaseVersion() stylesDict = abstractDb.getStyleDict(dbVersion) selectedStyle = stylesDict[styleName] - if 'db:' in selectedStyle: + if "db:" in selectedStyle: self.algRunner.runApplStylesFromDatabaseToLayers( inputList=lyrList, context=QgsProcessingContext(), - styleName=selectedStyle.split(':')[-1] + styleName=selectedStyle.split(":")[-1], ) else: stylePath = os.path.join( - abstractDb.getStyleDirectory(dbVersion), - selectedStyle + abstractDb.getStyleDirectory(dbVersion), selectedStyle ) self.algRunner.runMatchAndApplyQmlStylesToLayer( inputList=lyrList, qmlFolder=stylePath, - context=QgsProcessingContext() + context=QgsProcessingContext(), ) # localProgress = ProgressWidget(1, len(lyrList) - 1, self.tr('Loading style {0}').format(styleName), parent=self.iface.mapCanvas()) # for lyr in lyrList: @@ -127,20 +135,31 @@ def on_applyPushButton_clicked(self): # self.iface.mapCanvas().refreshAllLayers() QApplication.restoreOverrideCursor() except Exception as e: - QgsMessageLog.logMessage(self.tr('Error setting style ') + styleName + ': ' +':'.join(e.args), "DSGTools Plugin", Qgis.Critical) + QgsMessageLog.logMessage( + self.tr("Error setting style ") + styleName + ": " + ":".join(e.args), + "DSGTools Plugin", + Qgis.Critical, + ) QApplication.restoreOverrideCursor() - def getLayers(self, dbName): lyrList = [] for lyr in self.iface.mapCanvas().layers(): if isinstance(lyr, QgsVectorLayer): candidateUri = QgsDataSourceUri(lyr.dataProvider().dataSourceUri()) - if (candidateUri.database() == dbName and lyr.providerType() in ['postgres', 'spatialite']) \ - or (os.path.splitext(os.path.basename(candidateUri.uri().split('|')[0]))[0] == dbName and lyr.providerType() == 'ogr'): + if ( + candidateUri.database() == dbName + and lyr.providerType() in ["postgres", "spatialite"] + ) or ( + os.path.splitext( + os.path.basename(candidateUri.uri().split("|")[0]) + )[0] + == dbName + and lyr.providerType() == "ogr" + ): lyrList.append(lyr) return lyrList - + def getDatabaseList(self): # dbList = list() dbSet = set() @@ -149,14 +168,18 @@ def getDatabaseList(self): candidateUri = QgsDataSourceUri(lyr.dataProvider().dataSourceUri()) dbName = candidateUri.database() # if dbName not in dbList and lyr.providerType() in ['postgres', 'spatialite']: - if lyr.providerType() in ['postgres', 'spatialite']: + if lyr.providerType() in ["postgres", "spatialite"]: dbSet.add(dbName) - elif lyr.providerType() == 'ogr': - dbName = os.path.splitext(os.path.basename(lyr.dataProvider().dataSourceUri().split('|')[0]))[0] + elif lyr.providerType() == "ogr": + dbName = os.path.splitext( + os.path.basename( + lyr.dataProvider().dataSourceUri().split("|")[0] + ) + )[0] # if db not in dbList: dbSet.add(dbName) return dbSet - + def loadStylesCombo(self, abstractDb): dbVersion = abstractDb.getDatabaseVersion() styleDict = abstractDb.getStyleDict(dbVersion) @@ -164,53 +187,66 @@ def loadStylesCombo(self, abstractDb): styleList = list(styleDict.keys()) numberOfStyles = len(styleList) if numberOfStyles > 0: - self.styleComboBox.addItem(self.tr('Select Style')) + self.styleComboBox.addItem(self.tr("Select Style")) for i in range(numberOfStyles): self.styleComboBox.addItem(styleList[i]) else: - self.styleComboBox.addItem(self.tr('No available styles')) - + self.styleComboBox.addItem(self.tr("No available styles")) + def getParametersFromLyr(self, dbName): for lyr in self.iface.mapCanvas().layers(): - if isinstance(lyr, QgsVectorLayer): - candidateUri = QgsDataSourceUri(lyr.dataProvider().dataSourceUri()) - if candidateUri.database() == dbName or \ - os.path.splitext(os.path.basename(candidateUri.uri().split('|')[0]))[0] == dbName: - currLyr = lyr - break + if isinstance(lyr, QgsVectorLayer): + candidateUri = QgsDataSourceUri(lyr.dataProvider().dataSourceUri()) + if ( + candidateUri.database() == dbName + or os.path.splitext( + os.path.basename(candidateUri.uri().split("|")[0]) + )[0] + == dbName + ): + currLyr = lyr + break dbParameters = dict() - if currLyr.providerType() == 'postgres': - dbParameters['host'] = candidateUri.host() - dbParameters['port'] = candidateUri.port() - dbParameters['user'] = candidateUri.username() - dbParameters['password'] = candidateUri.password() + if currLyr.providerType() == "postgres": + dbParameters["host"] = candidateUri.host() + dbParameters["port"] = candidateUri.port() + dbParameters["user"] = candidateUri.username() + dbParameters["password"] = candidateUri.password() return dbParameters, DsgEnums.DriverPostGIS - elif currLyr.providerType() == 'spatialite': - dbParameters['dbPath'] = candidateUri.database() + elif currLyr.providerType() == "spatialite": + dbParameters["dbPath"] = candidateUri.database() return dbParameters, DsgEnums.DriverSpatiaLite - elif currLyr.providerType() == 'ogr': + elif currLyr.providerType() == "ogr": # geopackage provider type is ogr - dbParameters['dbPath'] = candidateUri.database() + dbParameters["dbPath"] = candidateUri.database() return dbParameters, DsgEnums.DriverGeopackage else: - raise Exception(self.tr('Feature only implemented for PostGIS and Spatialite')) - + raise Exception( + self.tr("Feature only implemented for PostGIS and Spatialite") + ) + def getAbstractDb(self, dbName): dbParameters, driverName = self.getParametersFromLyr(dbName) abstractDb = self.dbFactory.createDbFactory(driverName) - if 'host' in list(dbParameters.keys()): - abstractDb.connectDatabaseWithParameters(dbParameters['host'], dbParameters['port'], dbName, dbParameters['user'], dbParameters['password']) + if "host" in list(dbParameters.keys()): + abstractDb.connectDatabaseWithParameters( + dbParameters["host"], + dbParameters["port"], + dbName, + dbParameters["user"], + dbParameters["password"], + ) else: - abstractDb.connectDatabase(dbParameters['dbPath']) + abstractDb.connectDatabase(dbParameters["dbPath"]) return abstractDb @pyqtSlot(int) def on_dbComboBox_currentIndexChanged(self, idx): self.enableApply() - if self.sender().objectName() == 'dbComboBox': + if self.sender().objectName() == "dbComboBox": if idx <= 0: self.styleComboBox.clear() - self.styleComboBox.addItem(self.tr('Select Style')) + self.styleComboBox.addItem(self.tr("Select Style")) self.styleComboBox.setEnabled(False) elif idx > 0: self.styleComboBox.setEnabled(True) diff --git a/DsgTools/gui/ProductionTools/Toolbars/toolBarsGuiManager.py b/DsgTools/gui/ProductionTools/Toolbars/toolBarsGuiManager.py index a4350d039..8baec283c 100644 --- a/DsgTools/gui/ProductionTools/Toolbars/toolBarsGuiManager.py +++ b/DsgTools/gui/ProductionTools/Toolbars/toolBarsGuiManager.py @@ -34,67 +34,60 @@ from .DataValidationTool.dataValidationTool import DataValidationTool from qgis.PyQt.QtCore import QObject -class ToolbarsGuiManager(QObject): - def __init__(self, manager, iface, parentMenu = None, toolbar = None): - """Constructor. - """ +class ToolbarsGuiManager(QObject): + def __init__(self, manager, iface, parentMenu=None, toolbar=None): + """Constructor.""" super(ToolbarsGuiManager, self).__init__() self.manager = manager self.iface = iface self.parentMenu = parentMenu self.toolbar = toolbar self.toolbarList = [] - self.iconBasePath = ':/plugins/DsgTools/icons/' - + self.iconBasePath = ":/plugins/DsgTools/icons/" + def initGui(self): - #adding minimum area tool - self.minimumAreaTool = MinimumAreaTool(self.iface, parent = self.parentMenu) + # adding minimum area tool + self.minimumAreaTool = MinimumAreaTool(self.iface, parent=self.parentMenu) self.createToolbarAndAddWidget( - name=u'DSGTools_Minimum_Area_Tool', - widget=self.minimumAreaTool + name="DSGTools_Minimum_Area_Tool", widget=self.minimumAreaTool ) - #adding inspect feature tool - self.inspectFeaturesTool = InspectFeatures(self.iface, parent = self.parentMenu) + # adding inspect feature tool + self.inspectFeaturesTool = InspectFeatures(self.iface, parent=self.parentMenu) self.createToolbarAndAddWidget( - name=u'DSGTools_Inspect_Features', - widget=self.inspectFeaturesTool + name="DSGTools_Inspect_Features", widget=self.inspectFeaturesTool ) - #adding review tool - self.reviewTool = ReviewToolbar(self.iface, parent = self.parentMenu) + # adding review tool + self.reviewTool = ReviewToolbar(self.iface, parent=self.parentMenu) self.createToolbarAndAddWidget( - name=u'DSGTools_Review_Toolbar', - widget=self.reviewTool + name="DSGTools_Review_Toolbar", widget=self.reviewTool ) - #adding style tools - self.styleManagerTool = StyleManagerTool(self.iface, parent = self.parentMenu) + # adding style tools + self.styleManagerTool = StyleManagerTool(self.iface, parent=self.parentMenu) self.createToolbarAndAddWidget( - name=u'DSGTools_Style_Manager', - widget=self.styleManagerTool + name="DSGTools_Style_Manager", widget=self.styleManagerTool ) - #adding raster info tool - self.rasterInfoTool = DsgRasterInfoTool(self.iface, parent = self.parentMenu) + # adding raster info tool + self.rasterInfoTool = DsgRasterInfoTool(self.iface, parent=self.parentMenu) self.createToolbarAndAddWidget( - name=u'DSGTools_Raster_Info', - widget=self.rasterInfoTool + name="DSGTools_Raster_Info", widget=self.rasterInfoTool ) - #adding raster info tool - self.dataValidationTool = DataValidationTool(self.iface, parent = self.parentMenu) + # adding raster info tool + self.dataValidationTool = DataValidationTool(self.iface, parent=self.parentMenu) self.createToolbarAndAddWidget( - name=u'DSGTools_Data_Validation', - widget=self.dataValidationTool + name="DSGTools_Data_Validation", widget=self.dataValidationTool ) - + def createToolbar(self, name): toolbar = self.iface.addToolBar(name) toolbar.setObjectName(name) self.toolbarList.append(toolbar) return toolbar - + def createToolbarAndAddWidget(self, name, widget): toolbar = self.createToolbar(name) toolbar.addWidget(widget) - + def unload(self): self.minimumAreaTool.unload() self.inspectFeaturesTool.unload() diff --git a/DsgTools/gui/ProductionTools/Toolboxes/AttributeTools/code_list.py b/DsgTools/gui/ProductionTools/Toolboxes/AttributeTools/code_list.py index fa6be3ca8..b50ef6330 100644 --- a/DsgTools/gui/ProductionTools/Toolboxes/AttributeTools/code_list.py +++ b/DsgTools/gui/ProductionTools/Toolboxes/AttributeTools/code_list.py @@ -29,8 +29,8 @@ from qgis.PyQt.QtSql import QSqlDatabase, QSqlQuery from qgis.core import QgsVectorLayer, QgsProject -FORM_CLASS, _ = uic.loadUiType(os.path.join( - os.path.dirname(__file__), 'code_list.ui')) +FORM_CLASS, _ = uic.loadUiType(os.path.join(os.path.dirname(__file__), "code_list.ui")) + class CodeList(QDockWidget, FORM_CLASS): def __init__(self, iface): @@ -53,7 +53,7 @@ def readClassFieldMap(self, preferEdgvMapping=True): """ Gets all layers with value maps. :param preferEdgvMapping: (bool) whether edgv mapping should be preferred, if exists. - :return: (dict) a map from layer to list of fields with a value map. + :return: (dict) a map from layer to list of fields with a value map. """ classFieldMap = defaultdict(dict) for layer in self.iface.mapCanvas().layers(): @@ -68,23 +68,26 @@ def readClassFieldMap(self, preferEdgvMapping=True): for field in layer.fields(): fieldName = field.name() fieldConfig = field.editorWidgetSetup().config() - if 'map' not in fieldConfig or fieldName in ('UseHtml', 'IsMultiline'): + if "map" not in fieldConfig or fieldName in ("UseHtml", "IsMultiline"): continue - if isinstance(fieldConfig['map'], list): - for map_ in fieldConfig['map']: + if isinstance(fieldConfig["map"], list): + for map_ in fieldConfig["map"]: if fieldName not in classFieldMap[layername]: classFieldMap[layername][fieldName] = map_ else: classFieldMap[layername][fieldName].update(map_) else: + def sortingMethod(item): try: return int(item[1]) except: return item[1] + classFieldMap[layername][fieldName] = { - k: v for k, v in sorted( - fieldConfig['map'].items(), key=sortingMethod + k: v + for k, v in sorted( + fieldConfig["map"].items(), key=sortingMethod ) } return classFieldMap @@ -118,16 +121,16 @@ def resetClasses(self): Sets current class-fields map data to combo boxes. """ self.classComboBox.clear() - self.classComboBox.addItem(self.tr('Select a layer...')) + self.classComboBox.addItem(self.tr("Select a layer...")) self.classComboBox.addItems(self.availableLayers()) - @pyqtSlot(int, name='on_classComboBox_currentIndexChanged') + @pyqtSlot(int, name="on_classComboBox_currentIndexChanged") def resetFields(self): """ Resets current available fields """ self.comboBox.clear() - self.comboBox.addItem(self.tr('Select a field...')) + self.comboBox.addItem(self.tr("Select a field...")) self.comboBox.addItems(self.availableFields()) def layerByName(self, layerName): @@ -144,20 +147,24 @@ def currentLayerName(self): Gets current selected layer name. :return: (str) current layer's name. """ - return self.classComboBox.currentText().split(': ')[-1] + return self.classComboBox.currentText().split(": ")[-1] def availableFieldsFromLayerName(self, layerName): """ Gets all available fields that have value maps. :param layerName: (str) layer to have its layers checked. - :return: (list-of-str) list of field names available. + :return: (list-of-str) list of field names available. """ - return [] if layerName not in self._classFieldMap else list(self._classFieldMap[layerName].keys()) + return ( + [] + if layerName not in self._classFieldMap + else list(self._classFieldMap[layerName].keys()) + ) def availableFields(self): """ Gets all available fields that have value maps from current layer selection. - :return: (list-of-str) list of field names available. + :return: (list-of-str) list of field names available. """ return self.availableFieldsFromLayerName(self.currentLayerName()) @@ -175,7 +182,10 @@ def fieldMapFromFieldName(self, fieldName, layerName): :param layerName: (str) field name to have its map retrieved. :return: (dict) field map. """ - if layerName in self._classFieldMap and fieldName in self._classFieldMap[layerName]: + if ( + layerName in self._classFieldMap + and fieldName in self._classFieldMap[layerName] + ): return self._classFieldMap[layerName][fieldName] return dict() @@ -185,7 +195,7 @@ def currentField(self): :return: (str) field name. """ ct = self.comboBox.currentText() - return '' if ct == self.tr('Select a field...') else ct + return "" if ct == self.tr("Select a field...") else ct def currentFieldMap(self): """ @@ -194,7 +204,7 @@ def currentFieldMap(self): """ return self.fieldMapFromFieldName(self.currentField(), self.currentLayerName()) - @pyqtSlot(bool, name='on_refreshButton_clicked') + @pyqtSlot(bool, name="on_refreshButton_clicked") def setInitialState(self): """ Sets interface components to its initial state. @@ -212,10 +222,10 @@ def edgvVersion(self, db): :return: (str) current EDGV version. """ # this method is not supposed to be here and must be crossed out on - # future database abstraction refactor. + # future database abstraction refactor. sql = { "QSQLITE": "SELECT edgvversion FROM public_db_metadata;", - "QPSQL": "SELECT edgvversion FROM public.db_metadata;" + "QPSQL": "SELECT edgvversion FROM public.db_metadata;", }.pop(db.driverName(), "") query = QSqlQuery(sql, db) return query.value(0) if query.next() else "" @@ -230,40 +240,47 @@ def getAllEdgvDomainsFromTableName(self, table): :return: (dict) value map for all attributes that have one. """ ret = defaultdict(dict) - currentLayer = table if isinstance(table, QgsVectorLayer) else self.layerByName(table) + currentLayer = ( + table if isinstance(table, QgsVectorLayer) else self.layerByName(table) + ) if currentLayer.isValid(): try: uri = currentLayer.dataProvider().uri() - if uri.host() == '': - db = QSqlDatabase('QSQLITE') + if uri.host() == "": + db = QSqlDatabase("QSQLITE") db.setDatabaseName( - uri.uri().split("|")[0].strip() if uri.uri().split("|")[0].strip().endswith(".gpkg") \ - else uri.database() + uri.uri().split("|")[0].strip() + if uri.uri().split("|")[0].strip().endswith(".gpkg") + else uri.database() ) - sql = 'select code, code_name from dominios_{field} order by code' + sql = "select code, code_name from dominios_{field} order by code" else: - db = QSqlDatabase('QPSQL') + db = QSqlDatabase("QPSQL") db.setHostName(uri.host()) db.setPort(int(uri.port())) db.setDatabaseName(uri.database()) db.setUserName(uri.username()) db.setPassword(uri.password()) - sql = 'select code, code_name from dominios.{field} order by code' + sql = "select code, code_name from dominios.{field} order by code" if not db.open(): db.close() return ret for field in currentLayer.fields(): fieldName = field.name() if fieldName in self.specialEdgvAttributes(): - # EDGV "special" attributes that are have different domains depending on + # EDGV "special" attributes that are have different domains depending on # which class it belongs to if self.edgvVersion(db) in ("2.1.3 Pro", "3.0 Pro"): cat = table if isinstance(table, str) else table.name() # Pro versions now follow the logic "{attribute}_{CLASS_NAME}" cat = cat.rsplit("_", 1)[0].split("_", 1)[-1] else: - cat = (table if isinstance(table, str) else table.name()).split("_")[0] - fieldN = "{attribute}_{cat}".format(attribute=fieldName, cat=cat) + cat = ( + table if isinstance(table, str) else table.name() + ).split("_")[0] + fieldN = "{attribute}_{cat}".format( + attribute=fieldName, cat=cat + ) query = QSqlQuery(sql.format(field=fieldN), db) else: query = QSqlQuery(sql.format(field=fieldName), db) @@ -272,7 +289,7 @@ def getAllEdgvDomainsFromTableName(self, table): while query.next(): code = str(query.value(0)) code_name = query.value(1) - ret[fieldName][code_name] = code + ret[fieldName][code_name] = code db.close() except: pass @@ -282,7 +299,7 @@ def specialEdgvAttributes(self): """ Gets the list of attributes shared by many EDGV classes and have a different domain depending on which category the EDGV class belongs to. - :return: (list-of-str) list of "special" EDGV classes. + :return: (list-of-str) list of "special" EDGV classes. """ return ["finalidade", "relacionado", "coincidecomdentrode", "tipo"] @@ -295,31 +312,38 @@ def getEdgvDomainsFromTableName(self, table, field=None): :return: (dict) value map. """ ret = dict() - currentLayer = table if isinstance(table, QgsVectorLayer) else self.layerByName(table) + currentLayer = ( + table if isinstance(table, QgsVectorLayer) else self.layerByName(table) + ) if currentLayer.isValid(): try: uri = currentLayer.dataProvider().uri() field = field or self.currentField() if field in self.specialEdgvAttributes(): - # EDGV "special" attributes that are have different domains depending on + # EDGV "special" attributes that are have different domains depending on # which class it belongs to category = self.currentLayerName().split("_")[0] field = "{attribute}_{cat}".format(attribute=field, cat=category) - if uri.host() == '': - db = QSqlDatabase('QSQLITE') + if uri.host() == "": + db = QSqlDatabase("QSQLITE") db.setDatabaseName( - uri.uri().split("|")[0].strip() if uri.uri().split("|")[0].strip().endswith(".gpkg") \ - else uri.database() + uri.uri().split("|")[0].strip() + if uri.uri().split("|")[0].strip().endswith(".gpkg") + else uri.database() + ) + sql = "select code, code_name from dominios_{field} order by code".format( + field=field ) - sql = 'select code, code_name from dominios_{field} order by code'.format(field=field) else: - db = QSqlDatabase('QPSQL') + db = QSqlDatabase("QPSQL") db.setHostName(uri.host()) db.setPort(int(uri.port())) db.setDatabaseName(uri.database()) db.setUserName(uri.username()) db.setPassword(uri.password()) - sql = 'select code, code_name from dominios.{field} order by code'.format(field=field) + sql = "select code, code_name from dominios.{field} order by code".format( + field=field + ) if not db.open(): db.close() return ret @@ -342,7 +366,7 @@ def getEdgvDomains(self): """ return self.getEdgvDomainsFromTableName(self.currentLayerName()) - @pyqtSlot(int, name='on_comboBox_currentIndexChanged') + @pyqtSlot(int, name="on_comboBox_currentIndexChanged") def populateFieldsTable(self): """ Populates field map to codelist table. diff --git a/DsgTools/gui/ProductionTools/Toolboxes/ComplexTools/complexWindow.py b/DsgTools/gui/ProductionTools/Toolboxes/ComplexTools/complexWindow.py index bebc14496..4888f11b4 100644 --- a/DsgTools/gui/ProductionTools/Toolboxes/ComplexTools/complexWindow.py +++ b/DsgTools/gui/ProductionTools/Toolboxes/ComplexTools/complexWindow.py @@ -24,23 +24,34 @@ from builtins import range import os -#PyQt5 imports +# PyQt5 imports from qgis.PyQt import QtWidgets, uic from qgis.PyQt.QtCore import pyqtSlot, QObject, Qt from qgis.PyQt.QtWidgets import QTreeWidgetItem, QMessageBox from qgis.PyQt.QtSql import QSqlDatabase, QSqlQuery -#QGIS imports -from qgis.core import QgsDataSourceUri, QgsCredentials, QgsMessageLog, QgsRectangle, QgsFeatureRequest, QgsMapLayer - -#DsgTools imports -from DsgTools.gui.ProductionTools.Toolboxes.ComplexTools.manageComplex import ManageComplexDialog +# QGIS imports +from qgis.core import ( + QgsDataSourceUri, + QgsCredentials, + QgsMessageLog, + QgsRectangle, + QgsFeatureRequest, + QgsMapLayer, +) + +# DsgTools imports +from DsgTools.gui.ProductionTools.Toolboxes.ComplexTools.manageComplex import ( + ManageComplexDialog, +) from DsgTools.core.Factories.DbFactory.abstractDb import AbstractDb from DsgTools.core.Factories.DbFactory.dbFactory import DbFactory from DsgTools.core.dsgEnums import DsgEnums -FORM_CLASS, _ = uic.loadUiType(os.path.join( - os.path.dirname(__file__), 'complexWindow_base.ui')) +FORM_CLASS, _ = uic.loadUiType( + os.path.join(os.path.dirname(__file__), "complexWindow_base.ui") +) + class ComplexWindow(QtWidgets.QDockWidget, FORM_CLASS): def __init__(self, iface, parent=None): @@ -53,7 +64,7 @@ def __init__(self, iface, parent=None): # #widgets-and-dialogs-with-auto-connect self.setupUi(self) self.iface = iface - + self.dbButton.clicked.connect(self.getDataSources) self.dbCombo.activated.connect(self.updateComplexClass) self.complexCombo.activated.connect(self.loadAssociatedFeatures) @@ -68,7 +79,7 @@ def __del__(self): Destructor """ self.renewDb - + def renewDb(self): """ Deletes the current abstractDb @@ -85,7 +96,7 @@ def clearDock(self): self.dbCombo.clear() self.complexCombo.clear() - #verificar se é necessario + # verificar se é necessario def isSpatialiteDatabase(self, dbName): """ Checks if the database in use is a spatialite database @@ -100,14 +111,16 @@ def getUserCredentials(self, lyr): Gets user credentials to acess the database """ dataSourceUri = QgsDataSourceUri(lyr.dataProvider().dataSourceUri()) - if dataSourceUri.host() == '': + if dataSourceUri.host() == "": return (None, None) - if dataSourceUri.password() != '': + if dataSourceUri.password() != "": return (dataSourceUri.username(), dataSourceUri.password()) connInfo = dataSourceUri.connectionInfo() - (success, user, passwd ) = QgsCredentials.instance().get(connInfo, dataSourceUri.username(), None) + (success, user, passwd) = QgsCredentials.instance().get( + connInfo, dataSourceUri.username(), None + ) # Put the credentials back (for yourself and the provider), as QGIS removes it when you "get" it if success: QgsCredentials.instance().put(connInfo, user, passwd) @@ -126,33 +139,41 @@ def updateComplexClass(self): return dbName = self.dbCombo.currentText() - + (dataSourceUri, credentials) = self.databases[dbName] - #verifying the connection type + # verifying the connection type if self.isSpatialiteDatabase(dbName): - self.abstractDb = self.abstractDbFactory.createDbFactory(DsgEnums.DriverSpatiaLite) + self.abstractDb = self.abstractDbFactory.createDbFactory( + DsgEnums.DriverSpatiaLite + ) self.abstractDb.connectDatabase(dataSourceUri.database()) else: - self.abstractDb = self.abstractDbFactory.createDbFactory(DsgEnums.DriverPostGIS) - + self.abstractDb = self.abstractDbFactory.createDbFactory( + DsgEnums.DriverPostGIS + ) + database = dbName host = dataSourceUri.host() port = int(dataSourceUri.port()) user = credentials[0] password = credentials[1] - - self.abstractDb.connectDatabaseWithParameters(host, port, database, user, password) + + self.abstractDb.connectDatabaseWithParameters( + host, port, database, user, password + ) try: self.abstractDb.checkAndOpenDb() self.populateComboBox() except Exception as e: - QMessageBox.critical(self.iface.mainWindow(), self.tr("Critical!"), ':'.join(e.args)) + QMessageBox.critical( + self.iface.mainWindow(), self.tr("Critical!"), ":".join(e.args) + ) def populateComboBox(self): """ Fills the complex combo box with complex classes """ - #getting all complex tables + # getting all complex tables self.complexCombo.clear() self.complexCombo.addItem(self.tr("select a complex class")) @@ -160,8 +181,10 @@ def populateComboBox(self): try: complexClasses = self.abstractDb.listComplexClassesFromDatabase() except Exception as e: - QMessageBox.critical(self.iface.mainWindow(), self.tr("Critical!"), ':'.join(e.args)) - QgsMessageLog.logMessage(e.args[0], 'DSGTools Plugin', Qgis.Critical) + QMessageBox.critical( + self.iface.mainWindow(), self.tr("Critical!"), ":".join(e.args) + ) + QgsMessageLog.logMessage(e.args[0], "DSGTools Plugin", Qgis.Critical) self.complexCombo.addItems(complexClasses) @@ -175,7 +198,7 @@ def getDataSources(self): if self.databases: self.databases.clear() - #dictionary of names and datasourceUri + # dictionary of names and datasourceUri self.databases = dict() self.layers = self.iface.mapCanvas().layers() for layer in self.layers: @@ -183,7 +206,7 @@ def getDataSources(self): dbName = dataSourceUri.database() if dbName not in list(self.databases.keys()): self.databases[dbName] = (dataSourceUri, self.getUserCredentials(layer)) - #populating the combo + # populating the combo self.dbCombo.addItem(dbName) @pyqtSlot(bool) @@ -191,14 +214,20 @@ def on_managePushButton_clicked(self): """ Opens the dialog to manage complex features """ - #opens a dialog to manage complexes + # opens a dialog to manage complexes if not self.abstractDb: - QMessageBox.critical(self.iface.mainWindow(), self.tr("Critical!"), self.tr('Select a database before managing a complex!')) + QMessageBox.critical( + self.iface.mainWindow(), + self.tr("Critical!"), + self.tr("Select a database before managing a complex!"), + ) return - dlg = ManageComplexDialog(self.iface, self.abstractDb, self.complexCombo.currentText()) - #connects a signal to update the tree widget when done + dlg = ManageComplexDialog( + self.iface, self.abstractDb, self.complexCombo.currentText() + ) + # connects a signal to update the tree widget when done dlg.tableUpdated.connect(self.loadAssociatedFeatures) - #connects a signal to disassociate features from complex before removal + # connects a signal to disassociate features from complex before removal dlg.markedToRemove.connect(self.disassociateFeatures) result = dlg.exec_() if result: @@ -216,19 +245,23 @@ def on_zoomButton_clicked(self): """ Slot used to zoom the mapcanvas to the features associated to a complex """ - #case no item is selected we should warn the user + # case no item is selected we should warn the user if len(self.treeWidget.selectedItems()) == 0: - QMessageBox.warning(self.iface.mainWindow(), self.tr("Warning!"), self.tr("Please, select an item to zoom.")) + QMessageBox.warning( + self.iface.mainWindow(), + self.tr("Warning!"), + self.tr("Please, select an item to zoom."), + ) return item = self.treeWidget.selectedItems()[0] - #checking if the item is a complex (it should have depth = 2) + # checking if the item is a complex (it should have depth = 2) if self.depth(item) == 2: bbox = QgsRectangle() for i in range(item.childCount()): aggregated_item = item.child(i) aggregated_class = aggregated_item.text(0) - #getting the layer the needs to be updated + # getting the layer the needs to be updated aggregated_layer = None layers = self.iface.mapCanvas().layers() for layer in layers: @@ -237,22 +270,32 @@ def on_zoomButton_clicked(self): break if not aggregated_layer: - QMessageBox.warning(self.iface.mainWindow(), self.tr("Warning!"), self.tr("The associated classes must be loaded in the table of contents.")) + QMessageBox.warning( + self.iface.mainWindow(), + self.tr("Warning!"), + self.tr( + "The associated classes must be loaded in the table of contents." + ), + ) return for j in range(aggregated_item.childCount()): id = aggregated_item.child(j).text(0) freq = QgsFeatureRequest() freq.setFilterFid(int(id)) - feature = next(layer.getFeatures( freq )) - if j==0 and i == 0: - bbox=feature.geometry().boundingBox() + feature = next(layer.getFeatures(freq)) + if j == 0 and i == 0: + bbox = feature.geometry().boundingBox() bbox.combineExtentWith(feature.geometry().boundingBox()) self.iface.mapCanvas().setExtent(bbox) self.iface.mapCanvas().refresh() else: - QMessageBox.warning(self.iface.mainWindow(), self.tr("Warning!"), self.tr("Select a complex.")) + QMessageBox.warning( + self.iface.mainWindow(), + self.tr("Warning!"), + self.tr("Select a complex."), + ) return def disassociateFeatures(self, toBeRemoved): @@ -278,28 +321,41 @@ def disassociateAggregatedClass(self, item): uuid = item.parent().text(1) complex = item.parent().parent().text(0) - link_column = '' + link_column = "" try: link_column = self.abstractDb.obtainLinkColumn(complex, aggregated_class) except Exception as e: - QMessageBox.critical(self.iface.mainWindow(), self.tr('Critical'), self.tr('A problem occurred! Check log for details.')) - QgsMessageLog.logMessage(':'.join(e.args), 'DSGTools Plugin', Qgis.Critical) - - #getting the layer the needs to be updated + QMessageBox.critical( + self.iface.mainWindow(), + self.tr("Critical"), + self.tr("A problem occurred! Check log for details."), + ) + QgsMessageLog.logMessage(":".join(e.args), "DSGTools Plugin", Qgis.Critical) + + # getting the layer the needs to be updated aggregated_layer = None layers = self.iface.mapCanvas().layers() for layer in layers: - #in case of spatialite databases when a complex class is added as a layer it's name has 'complexos_' - if layer.name() == aggregated_class or layer.name() == 'complexos_'+aggregated_class: + # in case of spatialite databases when a complex class is added as a layer it's name has 'complexos_' + if ( + layer.name() == aggregated_class + or layer.name() == "complexos_" + aggregated_class + ): aggregated_layer = layer break if not aggregated_layer: - QMessageBox.warning(self.iface.mainWindow(), self.tr("Warning!"), self.tr("The class you're trying to disassociate must loaded in the table of contents.")) + QMessageBox.warning( + self.iface.mainWindow(), + self.tr("Warning!"), + self.tr( + "The class you're trying to disassociate must loaded in the table of contents." + ), + ) return for i in range(item.childCount()): - #feature id that will be updated + # feature id that will be updated id = item.child(i).text(0) self.updateLayerOnDisassociate(layer, aggregated_class, link_column, id) @@ -307,32 +363,45 @@ def disassociateAggregatedId(self, item): """ Disassociates a particular feature from a complex item: aggregated feature to be disassociated - """ + """ aggregated_class = item.parent().text(0) uuid = item.parent().parent().text(1) complex = item.parent().parent().parent().text(0) - link_column = '' + link_column = "" try: link_column = self.abstractDb.obtainLinkColumn(complex, aggregated_class) except Exception as e: - QMessageBox.critical(self.iface.mainWindow(), self.tr('Critical'), self.tr('A problem occurred! Check log for details.')) - QgsMessageLog.logMessage(':'.join(e.args), 'DSGTools Plugin', Qgis.Critical) - - #getting the layer the needs to be updated + QMessageBox.critical( + self.iface.mainWindow(), + self.tr("Critical"), + self.tr("A problem occurred! Check log for details."), + ) + QgsMessageLog.logMessage(":".join(e.args), "DSGTools Plugin", Qgis.Critical) + + # getting the layer the needs to be updated aggregated_layer = None layers = self.iface.mapCanvas().layers() for layer in layers: - #in case of spatialite databases when a complex class is added as a layer it's name has 'complexos_' - if layer.name() == aggregated_class or layer.name() == 'complexos_'+aggregated_class: + # in case of spatialite databases when a complex class is added as a layer it's name has 'complexos_' + if ( + layer.name() == aggregated_class + or layer.name() == "complexos_" + aggregated_class + ): aggregated_layer = layer break if not aggregated_layer: - QMessageBox.warning(self.iface.mainWindow(), self.tr("Warning!"), self.tr("The class you're trying to disassociate must loaded in the table of contents.")) + QMessageBox.warning( + self.iface.mainWindow(), + self.tr("Warning!"), + self.tr( + "The class you're trying to disassociate must loaded in the table of contents." + ), + ) return - #feature id that will be updated + # feature id that will be updated id = item.text(0) self.updateLayerOnDisassociate(layer, aggregated_class, link_column, id) @@ -346,17 +415,25 @@ def updateLayerOnDisassociate(self, layer, aggregated_class, link_column, id): """ try: if self.abstractDb.isComplexClass(aggregated_class): - self.abstractDb.disassociateComplexFromComplex(aggregated_class, link_column, id) + self.abstractDb.disassociateComplexFromComplex( + aggregated_class, link_column, id + ) else: - #field index that will be set to NULL - fieldIndex = [i for i in range(len(layer.dataProvider().fields())) if layer.dataProvider().fields()[i].name() == link_column] - #attribute pair that will be changed - attrs = {fieldIndex[0]:None} - #actual update in the database - layer.dataProvider().changeAttributeValues({int(id):attrs}) + # field index that will be set to NULL + fieldIndex = [ + i + for i in range(len(layer.dataProvider().fields())) + if layer.dataProvider().fields()[i].name() == link_column + ] + # attribute pair that will be changed + attrs = {fieldIndex[0]: None} + # actual update in the database + layer.dataProvider().changeAttributeValues({int(id): attrs}) except Exception as e: - QMessageBox.critical(self.iface.mainWindow(), self.tr("Critical!"), e.args[0]) - QgsMessageLog.logMessage(':'.join(e.args), 'DSGTools Plugin', Qgis.Critical) + QMessageBox.critical( + self.iface.mainWindow(), self.tr("Critical!"), e.args[0] + ) + QgsMessageLog.logMessage(":".join(e.args), "DSGTools Plugin", Qgis.Critical) @pyqtSlot(bool) def on_disassociatePushButton_clicked(self): @@ -365,19 +442,27 @@ def on_disassociatePushButton_clicked(self): It will firts check the depth of the item that need to be disassociated and them call the correct method to to the job. It can be a particular class or a particular feature """ - #case no item is selected we should warn the user + # case no item is selected we should warn the user if len(self.treeWidget.selectedItems()) == 0: - QMessageBox.warning(self.iface.mainWindow(), self.tr("Warning!"), self.tr("Please, select an aggregated class or aggregated id.")) + QMessageBox.warning( + self.iface.mainWindow(), + self.tr("Warning!"), + self.tr("Please, select an aggregated class or aggregated id."), + ) return item = self.treeWidget.selectedItems()[0] - #checking if the item is a complex (it should have depth = 2) + # checking if the item is a complex (it should have depth = 2) if self.depth(item) == 3: self.disassociateAggregatedClass(item) elif self.depth(item) == 4: self.disassociateAggregatedId(item) else: - QMessageBox.warning(self.iface.mainWindow(), self.tr("Warning!"), self.tr("Please, select an aggregated class or aggregated id.")) + QMessageBox.warning( + self.iface.mainWindow(), + self.tr("Warning!"), + self.tr("Please, select an aggregated class or aggregated id."), + ) return self.loadAssociatedFeatures() @@ -397,21 +482,27 @@ def loadAssociatedFeatures(self): try: associatedDict = self.abstractDb.loadAssociatedFeatures(complex) except Exception as e: - QMessageBox.critical(self.iface.mainWindow(), self.tr('Critical'), self.tr('A problem occurred! Check log for details.')) - QgsMessageLog.logMessage(':'.join(e.args), 'DSGTools Plugin', Qgis.Critical) - + QMessageBox.critical( + self.iface.mainWindow(), + self.tr("Critical"), + self.tr("A problem occurred! Check log for details."), + ) + QgsMessageLog.logMessage(":".join(e.args), "DSGTools Plugin", Qgis.Critical) + for name in list(associatedDict.keys()): for complex_uuid in list(associatedDict[name].keys()): self.addAssociatedFeature(complex, name, complex_uuid, None, None) for aggregated_class in associatedDict[name][complex_uuid]: for ogc_fid in associatedDict[name][complex_uuid][aggregated_class]: - self.addAssociatedFeature(complex, name, complex_uuid, aggregated_class, ogc_fid) + self.addAssociatedFeature( + complex, name, complex_uuid, aggregated_class, ogc_fid + ) def depth(self, item): """ Calculates the item deth in the tree """ - #calculates the depth of the item + # calculates the depth of the item depth = 0 while item is not None: item = item.parent() @@ -422,67 +513,89 @@ def associateFeatures(self): """ Associates all features selected in the map canvas to a complex. """ - #case no item is selected we should warn the user + # case no item is selected we should warn the user if len(self.treeWidget.selectedItems()) == 0: - QMessageBox.warning(self.iface.mainWindow(), self.tr("Warning!"), self.tr("Please, select a complex.")) + QMessageBox.warning( + self.iface.mainWindow(), + self.tr("Warning!"), + self.tr("Please, select a complex."), + ) return item = self.treeWidget.selectedItems()[0] - #checking if the item is a complex (it should have depth = 2) + # checking if the item is a complex (it should have depth = 2) if self.depth(item) != 2: - QMessageBox.warning(self.iface.mainWindow(), self.tr("Warning!"), self.tr("Please, select a complex.")) + QMessageBox.warning( + self.iface.mainWindow(), + self.tr("Warning!"), + self.tr("Please, select a complex."), + ) return complex = self.complexCombo.currentText() - #uuid to be adjust on the selected features + # uuid to be adjust on the selected features uuid = item.text(1) - #getting the selected features + # getting the selected features forbiddenLayers = [] self.layers = self.iface.mapCanvas().layers() for layer in self.layers: if layer.type() != QgsMapLayer.VectorLayer: continue - #case no fetures selected we proceed to the next one + # case no fetures selected we proceed to the next one selectedFeatures = layer.selectedFeatures() if len(selectedFeatures) == 0: continue - #obtaining the link column - column_name = '' + # obtaining the link column + column_name = "" try: column_name = self.abstractDb.obtainLinkColumn(complex, layer.name()) except Exception as e: - QMessageBox.critical(self.iface.mainWindow(), self.tr('Critical'), self.tr('A problem occurred! Check log for details.')) - QgsMessageLog.logMessage(':'.join(e.args), 'DSGTools Plugin', Qgis.Critical) - - #storing the names of the incompatible layers - if column_name == '': + QMessageBox.critical( + self.iface.mainWindow(), + self.tr("Critical"), + self.tr("A problem occurred! Check log for details."), + ) + QgsMessageLog.logMessage( + ":".join(e.args), "DSGTools Plugin", Qgis.Critical + ) + + # storing the names of the incompatible layers + if column_name == "": forbiddenLayers.append(layer.name()) continue for feature in selectedFeatures: - fieldIndex = [i for i in range(len(layer.dataProvider().fields())) if layer.dataProvider().fields()[i].name() == column_name] - #feature id that will be updated + fieldIndex = [ + i + for i in range(len(layer.dataProvider().fields())) + if layer.dataProvider().fields()[i].name() == column_name + ] + # feature id that will be updated id = feature.id() - #attribute pair that will be changed - attrs = {fieldIndex[0]:uuid} - #actual update in the database - layer.dataProvider().changeAttributeValues({id:attrs}) + # attribute pair that will be changed + attrs = {fieldIndex[0]: uuid} + # actual update in the database + layer.dataProvider().changeAttributeValues({id: attrs}) - #show the message of incompatible classes to associate + # show the message of incompatible classes to associate if len(forbiddenLayers) > 0: message = "" - message += self.tr("The following layers cannot be associated to complexes from ")+self.complexCombo.currentText()+":\n" + message += ( + self.tr("The following layers cannot be associated to complexes from ") + + self.complexCombo.currentText() + + ":\n" + ) for text in forbiddenLayers: - message += text+"\n" + message += text + "\n" QMessageBox.warning(self.iface.mainWindow(), self.tr("Warning!"), message) - #updating the tree widget + # updating the tree widget self.loadAssociatedFeatures() - def createTreeItem(self, parent, text, uuid = ""): + def createTreeItem(self, parent, text, uuid=""): """ Creates tree items parent: parent item @@ -491,29 +604,31 @@ def createTreeItem(self, parent, text, uuid = ""): """ count = parent.childCount() children = [] - #making a list of item names + # making a list of item names for i in range(count): child = parent.child(i) children.append(child.text(0)) - #checking if the text is already in the tree widget + # checking if the text is already in the tree widget if text not in children: - #case not it should be created + # case not it should be created item = QTreeWidgetItem(parent) item.setExpanded(True) - item.setText(0,text) - #adding the complex uuid to the tree widget + item.setText(0, text) + # adding the complex uuid to the tree widget if uuid != "": item.setText(1, str(uuid)) else: - #case already exists the correspondind item should be returned + # case already exists the correspondind item should be returned for i in range(count): child = parent.child(i) if child.text(0) == text: item = child return item - def addAssociatedFeature(self, className, complexName, complexId, associatedClass, associatedId): + def addAssociatedFeature( + self, className, complexName, complexId, associatedClass, associatedId + ): """ Adds a feature to a complex className: class name @@ -522,18 +637,20 @@ def addAssociatedFeature(self, className, complexName, complexId, associatedClas associatedClass: associated class associatedId: associated id """ - #get the corresponding top level item - classNameItem = self.createTreeItem(self.treeWidget.invisibleRootItem(), className) - #get the corresponding complex item + # get the corresponding top level item + classNameItem = self.createTreeItem( + self.treeWidget.invisibleRootItem(), className + ) + # get the corresponding complex item complexNameItem = self.createTreeItem(classNameItem, complexName, complexId) if associatedClass and associatedId: - #get the corresponding class item + # get the corresponding class item associatedClassItem = self.createTreeItem(complexNameItem, associatedClass) - #creates the corresponding associated item + # creates the corresponding associated item self.createTreeItem(associatedClassItem, str(associatedId)) def __test(self, x): - if (x.parent() == None) : + if x.parent() == None: return True else: return False diff --git a/DsgTools/gui/ProductionTools/Toolboxes/ComplexTools/manageComplex.py b/DsgTools/gui/ProductionTools/Toolboxes/ComplexTools/manageComplex.py index ff6657572..8d2a1d0c8 100644 --- a/DsgTools/gui/ProductionTools/Toolboxes/ComplexTools/manageComplex.py +++ b/DsgTools/gui/ProductionTools/Toolboxes/ComplexTools/manageComplex.py @@ -31,15 +31,25 @@ # Import the PyQt and QGIS libraries from qgis.PyQt import uic, QtGui, QtCore from qgis.PyQt.QtCore import Qt, pyqtSignal -from qgis.PyQt.QtWidgets import QStyledItemDelegate, QComboBox, QItemDelegate, QDialog, QMessageBox, QListWidget, QListWidgetItem +from qgis.PyQt.QtWidgets import ( + QStyledItemDelegate, + QComboBox, + QItemDelegate, + QDialog, + QMessageBox, + QListWidget, + QListWidgetItem, +) from qgis.PyQt.QtSql import QSqlDatabase, QSqlQuery, QSqlTableModel -#DsgTools imports +# DsgTools imports from DsgTools.core.Misc.QmlTools.qmlParser import QmlParser from DsgTools.core.Factories.DbFactory.abstractDb import AbstractDb -FORM_CLASS, _ = uic.loadUiType(os.path.join( - os.path.dirname(__file__), 'ui_manageComplex.ui')) +FORM_CLASS, _ = uic.loadUiType( + os.path.join(os.path.dirname(__file__), "ui_manageComplex.ui") +) + class CustomTableModel(QSqlTableModel): def __init__(self, domainDict, parent=None, db=QSqlDatabase): @@ -56,11 +66,17 @@ def makeValueRelationDict(self, table, codes): """ ret = dict() - in_clause = '(%s)' % ",".join(map(str, codes)) - if self.db.driverName() == 'QPSQL': - sql = 'select code, code_name from dominios.%s where code in %s' % (table, in_clause) - elif self.db.driverName() == 'QSQLITE': - sql = 'select code, code_name from dominios_%s where code in %s' % (table, in_clause) + in_clause = "(%s)" % ",".join(map(str, codes)) + if self.db.driverName() == "QPSQL": + sql = "select code, code_name from dominios.%s where code in %s" % ( + table, + in_clause, + ) + elif self.db.driverName() == "QSQLITE": + sql = "select code, code_name from dominios_%s where code in %s" % ( + table, + in_clause, + ) query = QSqlQuery(sql, self.db) while next(query): @@ -96,7 +112,7 @@ def data(self, index, role): elif isinstance(self.dict[column], tuple): tupla = self.dict[column] valueMap = self.makeValueRelationDict(tupla[0], tupla[1]) - codes = str(dbdata)[1:-1].split(',') + codes = str(dbdata)[1:-1].split(",") code_names = list() for c in codes: if str(c) in list(valueMap.values()): @@ -104,7 +120,7 @@ def data(self, index, role): code_name = list(valueMap.keys())[id] code_names.append(code_name) if len(code_names) > 0: - return '{%s}' % ','.join(code_names) + return "{%s}" % ",".join(code_names) return dbdata def setData(self, index, value, role=Qt.EditRole): @@ -127,15 +143,16 @@ def setData(self, index, value, role=Qt.EditRole): elif isinstance(self.dict[column], tuple): tupla = self.dict[column] valueMap = self.makeValueRelationDict(tupla[0], tupla[1]) - code_names = value[1:-1].split(',') + code_names = value[1:-1].split(",") codes = [] for code_name in code_names: code = valueMap[code_name] codes.append(code) if len(codes) > 0: - newValue = '{%s}' % ','.join(map(str, codes)) + newValue = "{%s}" % ",".join(map(str, codes)) return QSqlTableModel.setData(self, index, newValue, role) + class ComboBoxDelegate(QStyledItemDelegate): def __init__(self, parent, itemsDict, column): """ @@ -182,6 +199,7 @@ def setModelData(self, editor, model, index): # use default QItemDelegate.setModelData(self, editor, model, index) + class ListWidgetDelegate(QStyledItemDelegate): def __init__(self, parent, itemsDict, column): """ @@ -213,10 +231,12 @@ def setEditorData(self, editor, index): try: if index.column() == self.column: txt = m.data(index, Qt.DisplayRole) - checkList = txt[1:-1].split(',') + checkList = txt[1:-1].split(",") for i in range(editor.count()): item = editor.item(i) - item.setCheckState(Qt.Checked if item.text() in checkList else Qt.Unchecked) + item.setCheckState( + Qt.Checked if item.text() in checkList else Qt.Unchecked + ) else: # use default QItemDelegate.setEditorData(self, editor, index) @@ -233,55 +253,65 @@ def setModelData(self, editor, model, index): item = editor.item(i) if item.checkState() == Qt.Checked: checkedItems.append(item.text()) - model.setData(index, '{%s}' % ','.join(checkedItems)) + model.setData(index, "{%s}" % ",".join(checkedItems)) else: # use default QItemDelegate.setModelData(self, editor, model, index) + class ManageComplexDialog(QDialog, FORM_CLASS): tableUpdated = pyqtSignal() markedToRemove = pyqtSignal(list) + def __init__(self, iface, abstractDb, table): """ Constructor. """ - QDialog.__init__( self ) - self.setupUi( self ) + QDialog.__init__(self) + self.setupUi(self) - #qgis interface + # qgis interface self.iface = iface - #database conenction + # database conenction if not abstractDb: - QMessageBox.critical(self.iface.mainWindow(), self.tr("Critical!"), self.tr('Select a database before managing a complex!')) + QMessageBox.critical( + self.iface.mainWindow(), + self.tr("Critical!"), + self.tr("Select a database before managing a complex!"), + ) return self.db = abstractDb.db - #table name + # table name self.table = table - #rows that are marked for removal + # rows that are marked for removal self.toBeRemoved = [] - #adjusting the table name to match the correspondent qml file - fileName = table.replace('complexos_', '') - fileName = fileName.split('.')[-1]+'.qml' + # adjusting the table name to match the correspondent qml file + fileName = table.replace("complexos_", "") + fileName = fileName.split(".")[-1] + ".qml" - #obtaining the qml file path - qmlDirPath = '' + # obtaining the qml file path + qmlDirPath = "" try: qmlDirPath = abstractDb.getQmlDir() except Exception as e: - QMessageBox.critical(self.iface.mainWindow(), self.tr("Critical!"), self.tr('A problem occurred! Check log for details.')) - QgsMessageLog.logMessage(':'.join(e.args), 'DSGTools Plugin', Qgis.Critical) + QMessageBox.critical( + self.iface.mainWindow(), + self.tr("Critical!"), + self.tr("A problem occurred! Check log for details."), + ) + QgsMessageLog.logMessage(":".join(e.args), "DSGTools Plugin", Qgis.Critical) qmlPath = os.path.join(qmlDirPath, fileName) - #getting the domain dictionary that will be used to generate the comboboxes + # getting the domain dictionary that will be used to generate the comboboxes try: parser = QmlParser(qmlPath) self.domainDict = parser.getDomainDict() except: self.domainDict = dict() pass - + self.addRow.clicked.connect(self.addComplex) self.removeRow.clicked.connect(self.removeComplex) self.updateButton.clicked.connect(self.updateTable) @@ -296,42 +326,56 @@ def generateDelegates(self): """ for key in self.domainDict: if isinstance(self.domainDict[key], dict): - #self.domainDict[key] in this case is a dict + # self.domainDict[key] in this case is a dict self.generateCombo(key, self.domainDict[key]) elif isinstance(self.domainDict[key], tuple): - #self.domainDict[key] in this case is a tuple where index 0 is the domain table and index 1 are the codes + # self.domainDict[key] in this case is a tuple where index 0 is the domain table and index 1 are the codes self.generateList(key, self.domainDict[key]) def generateCombo(self, column, domainValues): """ Generates a combo box delegate """ - #creating the delegate - combo = ComboBoxDelegate(self, domainValues, self.projectModel.fieldIndex(column)) - self.tableView.setItemDelegateForColumn(self.projectModel.fieldIndex(column), combo) + # creating the delegate + combo = ComboBoxDelegate( + self, domainValues, self.projectModel.fieldIndex(column) + ) + self.tableView.setItemDelegateForColumn( + self.projectModel.fieldIndex(column), combo + ) def generateList(self, column, tupla): """ Generates a lit widget delegate """ - #making a dict in the same way used for the Combobox delegate + # making a dict in the same way used for the Combobox delegate valueRelation = self.makeValueRelationDict(tupla[0], tupla[1]) - #creating the delagate - list = ListWidgetDelegate(self, valueRelation, self.projectModel.fieldIndex(column)) - self.tableView.setItemDelegateForColumn(self.projectModel.fieldIndex(column), list) + # creating the delagate + list = ListWidgetDelegate( + self, valueRelation, self.projectModel.fieldIndex(column) + ) + self.tableView.setItemDelegateForColumn( + self.projectModel.fieldIndex(column), list + ) def makeValueRelationDict(self, table, codes): """ Makes the value relation dictionary """ - #query to obtain the dict with code names and related codes + # query to obtain the dict with code names and related codes ret = dict() - in_clause = '(%s)' % ",".join(map(str, codes)) - if self.db.driverName() == 'QPSQL': - sql = 'select code, code_name from dominios.%s where code in %s' % (table, in_clause) - elif self.db.driverName() == 'QSQLITE': - sql = 'select code, code_name from dominios_%s where code in %s' % (table, in_clause) + in_clause = "(%s)" % ",".join(map(str, codes)) + if self.db.driverName() == "QPSQL": + sql = "select code, code_name from dominios.%s where code in %s" % ( + table, + in_clause, + ) + elif self.db.driverName() == "QSQLITE": + sql = "select code, code_name from dominios_%s where code in %s" % ( + table, + in_clause, + ) query = QSqlQuery(sql, self.db) while next(query): @@ -345,19 +389,19 @@ def updateTableView(self): """ Updates the table view """ - #setting the model in the view + # setting the model in the view self.projectModel = CustomTableModel(self.domainDict, None, self.db) - #adjusting the table + # adjusting the table self.projectModel.setTable(self.table) - #manual commit rule + # manual commit rule self.projectModel.setEditStrategy(QSqlTableModel.OnManualSubmit) - #selecting all item from the table + # selecting all item from the table self.projectModel.select() - #creating the comboboxes and listwidgets to map the domain values + # creating the comboboxes and listwidgets to map the domain values self.generateDelegates() - #case the first record is null we make some adjustments - #this is not supposed to happen + # case the first record is null we make some adjustments + # this is not supposed to happen record = self.projectModel.record(0) if not record.value("id"): adjustedRecord = self.adjustRecord(record) @@ -365,10 +409,10 @@ def updateTableView(self): self.tableView.setModel(self.projectModel) - #Hiding columns that point to other complexes so that the user can't change them + # Hiding columns that point to other complexes so that the user can't change them for i in range(self.projectModel.columnCount()): columnName = self.projectModel.headerData(i, Qt.Horizontal) - if 'id_' in columnName: + if "id_" in columnName: self.tableView.hideColumn(i) self.tableView.show() @@ -381,12 +425,12 @@ def addComplex(self): adjustedRecord = self.adjustRecord(record) self.projectModel.insertRecord(self.projectModel.rowCount(), adjustedRecord) - def adjustRecord(self,record): + def adjustRecord(self, record): """ Updates a existing record """ - #insert a new record with an already determined uuid value - record.setValue("id",str(uuid4())) + # insert a new record with an already determined uuid value + record.setValue("id", str(uuid4())) record.setValue("nome", self.tr("edit this field")) for i in range(self.projectModel.columnCount()): columnName = self.projectModel.headerData(i, Qt.Horizontal) @@ -398,11 +442,11 @@ def removeComplex(self): """ Removes a complex from the complex table """ - #getting the selected rows + # getting the selected rows selectionModel = self.tableView.selectionModel() selectedRows = selectionModel.selectedRows() for row in selectedRows: - #storing the complex to be removed + # storing the complex to be removed record = self.projectModel.record(row.row()) uuid = str(record.value("id")) if uuid not in self.toBeRemoved: @@ -422,8 +466,14 @@ def checkComplexNameField(self): count = self.projectModel.rowCount() for i in range(count): record = self.projectModel.record(i) - if record.isNull('nome'): - QMessageBox.warning(self.iface.mainWindow(), self.tr("Warning!"), self.tr('The field: \'nome\' must be filled in all rows. Please, check and try again.')) + if record.isNull("nome"): + QMessageBox.warning( + self.iface.mainWindow(), + self.tr("Warning!"), + self.tr( + "The field: 'nome' must be filled in all rows. Please, check and try again." + ), + ) return False return True @@ -431,15 +481,19 @@ def updateTable(self): """ Updates the complex table """ - #checking if the name field is filled - #Now the database checks the field "nome", therefore the method checkComplexNameField() is no longer needed + # checking if the name field is filled + # Now the database checks the field "nome", therefore the method checkComplexNameField() is no longer needed - #emit the signal to disassocite all features from the complexes marked for removal + # emit the signal to disassocite all features from the complexes marked for removal self.markedToRemove.emit(self.toBeRemoved) - #commmiting all pending changes + # commmiting all pending changes if not self.projectModel.submitAll(): - #In case something went wrong we show the message to the user - QMessageBox.warning(self.iface.mainWindow(), self.tr("Error!"), self.projectModel.lastError().text()) - - #Emit the signal to update the complex tree - self.tableUpdated.emit() \ No newline at end of file + # In case something went wrong we show the message to the user + QMessageBox.warning( + self.iface.mainWindow(), + self.tr("Error!"), + self.projectModel.lastError().text(), + ) + + # Emit the signal to update the complex tree + self.tableUpdated.emit() diff --git a/DsgTools/gui/ProductionTools/Toolboxes/ContourTool/calc_contour.py b/DsgTools/gui/ProductionTools/Toolboxes/ContourTool/calc_contour.py index d74328f71..befca0485 100644 --- a/DsgTools/gui/ProductionTools/Toolboxes/ContourTool/calc_contour.py +++ b/DsgTools/gui/ProductionTools/Toolboxes/ContourTool/calc_contour.py @@ -30,15 +30,17 @@ # QGIS imports from qgis.core import QgsVectorLayer, QgsGeometry, Qgis, QgsProject, QgsWkbTypes -#DSGTools imports +# DSGTools imports from DsgTools.gui.ProductionTools.Toolboxes.ContourTool.dsg_line_tool import DsgLineTool from DsgTools.gui.ProductionTools.Toolboxes.ContourTool.contour_tool import ContourTool -FORM_CLASS, _ = uic.loadUiType(os.path.join( - os.path.dirname(__file__), 'calc_contour.ui')) +FORM_CLASS, _ = uic.loadUiType( + os.path.join(os.path.dirname(__file__), "calc_contour.ui") +) + class CalcContour(QtWidgets.QDockWidget, FORM_CLASS): - def __init__(self, iface, parent = None): + def __init__(self, iface, parent=None): """ Constructor """ @@ -49,24 +51,24 @@ def __init__(self, iface, parent = None): # http://qt-project.org/doc/qt-4.8/designer-using-a-ui-file.html # #widgets-and-dialogs-with-auto-connect self.setupUi(self) - + self.iface = iface - #insert layers into the combobox + # insert layers into the combobox self.populateLayers() - #instance of the QgsMapTool derived class (line tool) + # instance of the QgsMapTool derived class (line tool) self.tool = DsgLineTool(self.iface.mapCanvas()) self.tool.lineCreated.connect(self.updateLayer) - #instance of the class responsible to update layer features + # instance of the class responsible to update layer features self.contourTool = ContourTool() - #Connecting slot to deal with adition/removal of layers + # Connecting slot to deal with adition/removal of layers QgsProject.instance().layersAdded.connect(self.addLayers) QgsProject.instance().layersRemoved.connect(self.populateLayers) - @pyqtSlot(bool, name = 'on_reactivatePushButton_clicked') + @pyqtSlot(bool, name="on_reactivatePushButton_clicked") def activateTool(self): """ Sets this tool as the current active qgis tool @@ -89,12 +91,15 @@ def populateLayers(self): Populates the layer combo box """ self.layerCombo.clear() - - self.layerCombo.addItem(self.tr('Select a Layer')) - + + self.layerCombo.addItem(self.tr("Select a Layer")) + layers = self.iface.mapCanvas().layers() for layer in layers: - if isinstance(layer, QgsVectorLayer) and layer.geometryType() == QgsWkbTypes.LineGeometry: + if ( + isinstance(layer, QgsVectorLayer) + and layer.geometryType() == QgsWkbTypes.LineGeometry + ): self.layerCombo.addItem(layer.name()) def getLayer(self): @@ -116,31 +121,75 @@ def updateLayer(self, geom): Updates the layer """ if self.layerCombo.currentIndex() == 0: - self.iface.messageBar().pushMessage(self.tr('Information'), self.tr('A layer must be selected!'), level=Qgis.Info, duration=3) + self.iface.messageBar().pushMessage( + self.tr("Information"), + self.tr("A layer must be selected!"), + level=Qgis.Info, + duration=3, + ) return if self.attributeCombo.currentIndex() == 0: - self.iface.messageBar().pushMessage(self.tr('Information'), self.tr('A field must be selected!'), level=Qgis.Info, duration=3) + self.iface.messageBar().pushMessage( + self.tr("Information"), + self.tr("A field must be selected!"), + level=Qgis.Info, + duration=3, + ) return - #canvas crs to be used in case a reprojection is needed + # canvas crs to be used in case a reprojection is needed canvasCrs = self.iface.mapCanvas().mapSettings().destinationCrs() if self.ascendingRadioButton.isChecked(): signal = 1 else: signal = -1 - ret = self.contourTool.assignValues(self.attributeCombo.currentText(), signal*self.spinBox.value(), geom, canvasCrs) + ret = self.contourTool.assignValues( + self.attributeCombo.currentText(), + signal * self.spinBox.value(), + geom, + canvasCrs, + ) self.iface.mapCanvas().refresh() if ret == 1: - self.iface.messageBar().pushMessage(self.tr('Information!'), self.tr('Layer successfully updated!'), level=Qgis.Info, duration=3) + self.iface.messageBar().pushMessage( + self.tr("Information!"), + self.tr("Layer successfully updated!"), + level=Qgis.Info, + duration=3, + ) elif ret == 0: - self.iface.messageBar().pushMessage(self.tr('Critical!'), self.tr('Could not update features!'), level=Qgis.Critical, duration=3) + self.iface.messageBar().pushMessage( + self.tr("Critical!"), + self.tr("Could not update features!"), + level=Qgis.Critical, + duration=3, + ) elif ret == -1: - self.iface.messageBar().pushMessage(self.tr('Critical!'), self.tr('Problem ordering the features!'), level=Qgis.Critical, duration=3) + self.iface.messageBar().pushMessage( + self.tr("Critical!"), + self.tr("Problem ordering the features!"), + level=Qgis.Critical, + duration=3, + ) elif ret == -2: - self.iface.messageBar().pushMessage(self.tr('Critical!'), self.tr('The line created does not cross any features in the selected layer!'), level=Qgis.Critical, duration=3) + self.iface.messageBar().pushMessage( + self.tr("Critical!"), + self.tr( + "The line created does not cross any features in the selected layer!" + ), + level=Qgis.Critical, + duration=3, + ) elif ret == -3: - self.iface.messageBar().pushMessage(self.tr('Critical!'), self.tr('Assign a value for the selected attribute of the first crossed feature!'), level=Qgis.Critical, duration=3) + self.iface.messageBar().pushMessage( + self.tr("Critical!"), + self.tr( + "Assign a value for the selected attribute of the first crossed feature!" + ), + level=Qgis.Critical, + duration=3, + ) @pyqtSlot(int) def on_layerCombo_currentIndexChanged(self): @@ -149,16 +198,16 @@ def on_layerCombo_currentIndexChanged(self): """ if self.layerCombo.currentIndex() == 0: return - + currentLayer = self.getLayer() if not currentLayer: return - #updating the reference layer + # updating the reference layer self.contourTool.updateReference(self.getLayer()) fields = currentLayer.fields() field_names = [field.name() for field in fields] self.attributeCombo.clear() - self.attributeCombo.addItem('Select a field') - self.attributeCombo.addItems(field_names) \ No newline at end of file + self.attributeCombo.addItem("Select a field") + self.attributeCombo.addItems(field_names) diff --git a/DsgTools/gui/ProductionTools/Toolboxes/ContourTool/contour_tool.py b/DsgTools/gui/ProductionTools/Toolboxes/ContourTool/contour_tool.py index 86f0e3165..d9553519a 100644 --- a/DsgTools/gui/ProductionTools/Toolboxes/ContourTool/contour_tool.py +++ b/DsgTools/gui/ProductionTools/Toolboxes/ContourTool/contour_tool.py @@ -23,13 +23,18 @@ from builtins import range from builtins import object -from qgis.core import (QgsProject, - QgsGeometry, - QgsWkbTypes, - QgsSpatialIndex, - QgsFeatureRequest, - QgsCoordinateTransform) -from DsgTools.gui.ProductionTools.Toolboxes.ContourTool.contour_value import ContourValue +from qgis.core import ( + QgsProject, + QgsGeometry, + QgsWkbTypes, + QgsSpatialIndex, + QgsFeatureRequest, + QgsCoordinateTransform, +) +from DsgTools.gui.ProductionTools.Toolboxes.ContourTool.contour_value import ( + ContourValue, +) + class ContourTool(object): def updateReference(self, referenceLayer): @@ -44,51 +49,53 @@ def populateIndex(self): """ Populates the spatial index """ - #spatial index + # spatial index self.index = QgsSpatialIndex() for feat in self.reference.getFeatures(): self.index.addFeature(feat) - + def getCandidates(self, bbox): """ Gets candidates using the spatial index to speedup the process """ - #features that might satisfy the query + # features that might satisfy the query ids = self.index.intersects(bbox) candidates = [] for id in ids: - candidates.append(next(self.reference.getFeatures(QgsFeatureRequest().setFilterFid(id)))) - return candidates - + candidates.append( + next(self.reference.getFeatures(QgsFeatureRequest().setFilterFid(id))) + ) + return candidates + def getFeatures(self, geom): """ Gets the features that intersect geom to be updated """ - #features that satisfy the query + # features that satisfy the query ret = [] - + rect = geom.boundingBox() candidates = self.getCandidates(rect) for candidate in candidates: featGeom = candidate.geometry() if featGeom.intersects(geom): ret.append(candidate) - + return ret - + def getKey(self, item): """ Gets the key """ return item[0] - + def sortFeatures(self, geom, features): """ Sorts features according to the distance """ - #sorting by distance + # sorting by distance distances = [] - + firstPoint = geom.asPolyline()[0] pointGeom = QgsGeometry.fromPointXY(firstPoint) @@ -97,9 +104,9 @@ def sortFeatures(self, geom, features): if intersection.type() == QgsWkbTypes.PointGeometry: distance = intersection.distance(pointGeom) distances.append((distance, intersected)) - + ordered = sorted(distances, key=self.getKey) - #returning a list of tuples (distance, feature) + # returning a list of tuples (distance, feature) return ordered def reproject(self, geom, canvasCrs): @@ -109,12 +116,10 @@ def reproject(self, geom, canvasCrs): destCrs = self.reference.crs() if canvasCrs.authid() != destCrs.authid(): coordinateTransformer = QgsCoordinateTransform( - canvasCrs, - destCrs, - QgsProject.instance() + canvasCrs, destCrs, QgsProject.instance() ) geom.transform(coordinateTransformer) - + def setFirstValue(self, value): self.first_value = value @@ -126,17 +131,17 @@ def assignValues(self, attribute, pace, geom, canvasCrs): features = self.getFeatures(geom) if len(features) == 0: return -2 - + ordered = self.sortFeatures(geom, features) if len(ordered) == 0: return -1 self.reference.startEditing() - #the first feature must have the initial value already assigned + # the first feature must have the initial value already assigned first_feature = ordered[0][1] - #getting the filed index that must be updated + # getting the filed index that must be updated fieldIndex = self.reference.fields().indexFromName(attribute) - #getting the initial value + # getting the initial value first_value = first_feature.attribute(attribute) if not first_value: first_value_dlg = ContourValue(self) @@ -144,20 +149,22 @@ def assignValues(self, attribute, pace, geom, canvasCrs): if self.first_value: id = first_feature.id() first_value = self.first_value - if not self.reference.changeAttributeValue(id, fieldIndex, self.first_value): + if not self.reference.changeAttributeValue( + id, fieldIndex, self.first_value + ): return 0 else: return -3 self.first_value = None for i in range(1, len(ordered)): - #value to be adjusted - value = first_value + pace*i - #feature that will be updated + # value to be adjusted + value = first_value + pace * i + # feature that will be updated feature = ordered[i][1] - #feature id that will be updated + # feature id that will be updated id = feature.id() - #actual update in the layer + # actual update in the layer if not self.reference.changeAttributeValue(id, fieldIndex, value): return 0 return 1 diff --git a/DsgTools/gui/ProductionTools/Toolboxes/ContourTool/contour_value.py b/DsgTools/gui/ProductionTools/Toolboxes/ContourTool/contour_value.py index 770e0ffbf..4829550e5 100644 --- a/DsgTools/gui/ProductionTools/Toolboxes/ContourTool/contour_value.py +++ b/DsgTools/gui/ProductionTools/Toolboxes/ContourTool/contour_value.py @@ -27,10 +27,12 @@ from qgis.PyQt.QtCore import pyqtSlot from qgis.PyQt.QtGui import QIntValidator -#DSGTools imports +# DSGTools imports + +FORM_CLASS, _ = uic.loadUiType( + os.path.join(os.path.dirname(__file__), "contour_value.ui") +) -FORM_CLASS, _ = uic.loadUiType(os.path.join( - os.path.dirname(__file__), 'contour_value.ui')) class ContourValue(QtWidgets.QDialog, FORM_CLASS): def __init__(self, contour_tool, parent=None): @@ -46,15 +48,15 @@ def __init__(self, contour_tool, parent=None): self.setupUi(self) self.value_line_edit.setValidator(QIntValidator(0, 1000000)) self.contour_tool = contour_tool - + @pyqtSlot(bool) def on_cancel_push_button_clicked(self): """ Closes the dialog """ self.done(0) - - @pyqtSlot() + + @pyqtSlot() def on_ok_push_button_clicked(self): """ Gets the first value entered by the user and return it @@ -62,4 +64,4 @@ def on_ok_push_button_clicked(self): """ value = self.value_line_edit.text() self.contour_tool.setFirstValue(int(value)) - self.done(1) \ No newline at end of file + self.done(1) diff --git a/DsgTools/gui/ProductionTools/Toolboxes/ContourTool/dsg_line_tool.py b/DsgTools/gui/ProductionTools/Toolboxes/ContourTool/dsg_line_tool.py index db8294465..9abe97f2f 100644 --- a/DsgTools/gui/ProductionTools/Toolboxes/ContourTool/dsg_line_tool.py +++ b/DsgTools/gui/ProductionTools/Toolboxes/ContourTool/dsg_line_tool.py @@ -26,6 +26,7 @@ from qgis.gui import QgsMapTool, QgsRubberBand from qgis.core import QgsGeometry, QgsWkbTypes + class DsgLineTool(QgsMapTool): lineCreated = pyqtSignal(QgsGeometry) @@ -35,7 +36,7 @@ def __init__(self, canvas): Constructor """ super(DsgLineTool, self).__init__(canvas) - + self.canvas = canvas self.rubberBand = None self.reset() @@ -46,7 +47,7 @@ def deactivate(self): """ self.canvas.scene().removeItem(self.rubberBand) super(DsgLineTool, self).deactivate() - + def defineRubberBand(self): """ Defines the rubber band style @@ -59,7 +60,7 @@ def defineRubberBand(self): self.rubberBand = QgsRubberBand(self.canvas) self.rubberBand.setColor(QColor(myRed, myGreen, myBlue, 100)) self.rubberBand.setWidth(3) - + def reset(self): """ Resets the tool @@ -80,7 +81,7 @@ def canvasPressEvent(self, e): self.reset() self.isEmittingPoint = True - + def canvasReleaseEvent(self, e): """ Reimplementation to add a vertex to the rubber band or to finish the rubber band according to the button used @@ -92,7 +93,7 @@ def canvasReleaseEvent(self, e): self.lineCreated.emit(geom) elif e.button() == Qt.LeftButton: self.isEmittingPoint = True - + self.rubberBand.addPoint(point, True) def canvasMoveEvent(self, e): @@ -101,10 +102,10 @@ def canvasMoveEvent(self, e): """ if not self.isEmittingPoint: return - + point = self.snapPoint(e.pos()) self.rubberBand.movePoint(point) - + def snapPoint(self, p): """ Reimplementation to make use of the snap @@ -113,4 +114,4 @@ def snapPoint(self, p): if m.isValid(): return m.point() else: - return self.canvas.getCoordinateTransform().toMapCoordinates(p) \ No newline at end of file + return self.canvas.getCoordinateTransform().toMapCoordinates(p) diff --git a/DsgTools/gui/ProductionTools/Toolboxes/QualityAssuranceToolBox/__init__.py b/DsgTools/gui/ProductionTools/Toolboxes/QualityAssuranceToolBox/__init__.py index 80823e1d6..bbe5134fa 100644 --- a/DsgTools/gui/ProductionTools/Toolboxes/QualityAssuranceToolBox/__init__.py +++ b/DsgTools/gui/ProductionTools/Toolboxes/QualityAssuranceToolBox/__init__.py @@ -32,4 +32,5 @@ def classFactory(iface): # pylint: disable=invalid-name """ # from .dsg_tools import DsgTools + return DsgTools(iface) diff --git a/DsgTools/gui/ProductionTools/Toolboxes/QualityAssuranceToolBox/qualityAssuranceDockWidget.py b/DsgTools/gui/ProductionTools/Toolboxes/QualityAssuranceToolBox/qualityAssuranceDockWidget.py index e7acb784c..ce82f8c82 100644 --- a/DsgTools/gui/ProductionTools/Toolboxes/QualityAssuranceToolBox/qualityAssuranceDockWidget.py +++ b/DsgTools/gui/ProductionTools/Toolboxes/QualityAssuranceToolBox/qualityAssuranceDockWidget.py @@ -27,34 +27,51 @@ from typing import Dict, List, OrderedDict from qgis.PyQt import uic -from qgis.core import (Qgis, - QgsProject, - QgsMessageLog, - QgsProcessingFeedback, - QgsExpressionContextUtils, - QgsVectorLayer) +from qgis.core import ( + Qgis, + QgsProject, + QgsMessageLog, + QgsProcessingFeedback, + QgsExpressionContextUtils, + QgsVectorLayer, +) from qgis.PyQt.QtGui import QBrush, QColor from qgis.PyQt.QtCore import Qt, pyqtSlot -from qgis.PyQt.QtWidgets import (QLineEdit, - QFileDialog, - QDockWidget, - QMessageBox, - QProgressBar, - QTableWidgetItem) +from qgis.PyQt.QtWidgets import ( + QLineEdit, + QFileDialog, + QDockWidget, + QMessageBox, + QProgressBar, + QTableWidgetItem, +) -from DsgTools.gui.ProductionTools.Toolboxes.QualityAssuranceToolBox\ - .workflowSetupDialog import WorkflowSetupDialog -from DsgTools.core.DSGToolsProcessingAlgs.Models.qualityAssuranceWorkflow\ - import QualityAssuranceWorkflow +from DsgTools.gui.ProductionTools.Toolboxes.QualityAssuranceToolBox.workflowSetupDialog import ( + WorkflowSetupDialog, +) +from DsgTools.core.DSGToolsProcessingAlgs.Models.qualityAssuranceWorkflow import ( + QualityAssuranceWorkflow, +) FORM_CLASS, _ = uic.loadUiType( - os.path.join(os.path.dirname(__file__), 'qualityAssuranceDockWidget.ui') + os.path.join(os.path.dirname(__file__), "qualityAssuranceDockWidget.ui") ) + class QualityAssuranceDockWidget(QDockWidget, FORM_CLASS): # current execution status - INITIAL, RUNNING, PAUSED, HALTED, CANCELED, FAILED, FINISHED, FINISHED_WITH_FLAGS, FINISHED_WITH_POSSIBLE_FALSE_POSITIVE_FLAGS = range(9) + ( + INITIAL, + RUNNING, + PAUSED, + HALTED, + CANCELED, + FAILED, + FINISHED, + FINISHED_WITH_FLAGS, + FINISHED_WITH_POSSIBLE_FALSE_POSITIVE_FLAGS, + ) = range(9) def __init__(self, iface, parent=None): """ @@ -72,45 +89,45 @@ def __init__(self, iface, parent=None): self._showButtons = True self.parent = parent self.statusMap = { - self.INITIAL : self.tr("Not yet run"), - self.RUNNING : self.tr("Running..."), - self.PAUSED : self.tr("On hold"), - self.HALTED : self.tr("Halted on flags"), - self.CANCELED : self.tr("Canceled"), - self.FAILED : self.tr("Failed"), - self.FINISHED : self.tr("Completed"), - self.FINISHED_WITH_FLAGS : self.tr("Completed (raised flags)") + self.INITIAL: self.tr("Not yet run"), + self.RUNNING: self.tr("Running..."), + self.PAUSED: self.tr("On hold"), + self.HALTED: self.tr("Halted on flags"), + self.CANCELED: self.tr("Canceled"), + self.FAILED: self.tr("Failed"), + self.FINISHED: self.tr("Completed"), + self.FINISHED_WITH_FLAGS: self.tr("Completed (raised flags)"), } self.colorForeground = { - self.INITIAL : (0, 0, 0), - self.RUNNING : (0, 0, 125), - self.PAUSED : (187, 201, 25), - self.HALTED : (187, 201, 25), - self.CANCELED : (200, 0, 0), - self.FAILED : (169, 18, 28), - self.FINISHED : (0, 125, 0), - self.FINISHED_WITH_FLAGS : (100, 150, 20), + self.INITIAL: (0, 0, 0), + self.RUNNING: (0, 0, 125), + self.PAUSED: (187, 201, 25), + self.HALTED: (187, 201, 25), + self.CANCELED: (200, 0, 0), + self.FAILED: (169, 18, 28), + self.FINISHED: (0, 125, 0), + self.FINISHED_WITH_FLAGS: (100, 150, 20), self.FINISHED_WITH_POSSIBLE_FALSE_POSITIVE_FLAGS: (0, 0, 0), } self.colorBackground = { - self.INITIAL : (255, 255, 255, 75), - self.RUNNING : (0, 0, 125, 90), - self.PAUSED : (187, 201, 25, 20), - self.HALTED : (200, 215, 40, 20), - self.CANCELED : (200, 0, 0, 85), - self.FAILED : (169, 18, 28, 85), - self.FINISHED : (0, 125, 0, 90), - self.FINISHED_WITH_FLAGS : (100, 150, 20, 45), + self.INITIAL: (255, 255, 255, 75), + self.RUNNING: (0, 0, 125, 90), + self.PAUSED: (187, 201, 25, 20), + self.HALTED: (200, 215, 40, 20), + self.CANCELED: (200, 0, 0, 85), + self.FAILED: (169, 18, 28, 85), + self.FINISHED: (0, 125, 0, 90), + self.FINISHED_WITH_FLAGS: (100, 150, 20, 45), self.FINISHED_WITH_POSSIBLE_FALSE_POSITIVE_FLAGS: (255, 230, 1), } - self.qgisStatusDict = { - self.RUNNING : Qgis.Info, - self.PAUSED : Qgis.Info, - self.HALTED : Qgis.Critical, - self.CANCELED : Qgis.Warning, - self.FAILED : Qgis.Critical, - self.FINISHED : Qgis.Info, - self.FINISHED_WITH_FLAGS : Qgis.Warning, + self.qgisStatusDict = { + self.RUNNING: Qgis.Info, + self.PAUSED: Qgis.Info, + self.HALTED: Qgis.Critical, + self.CANCELED: Qgis.Warning, + self.FAILED: Qgis.Critical, + self.FINISHED: Qgis.Info, + self.FINISHED_WITH_FLAGS: Qgis.Warning, self.FINISHED_WITH_POSSIBLE_FALSE_POSITIVE_FLAGS: Qgis.Warning, } self.workflowStatusDict = defaultdict(OrderedDict) @@ -134,10 +151,15 @@ def confirmAction(self, msg, showCancel=True): :param showCancel: (bool) whether Cancel button should be exposed. :return: (bool) whether action was confirmed. """ - return QMessageBox.question( - self, self.tr('DSGTools Q&A Tool Box: Confirm action'), msg, - QMessageBox.Ok|QMessageBox.Cancel if showCancel else QMessageBox.Ok - ) == QMessageBox.Ok + return ( + QMessageBox.question( + self, + self.tr("DSGTools Q&A Tool Box: Confirm action"), + msg, + QMessageBox.Ok | QMessageBox.Cancel if showCancel else QMessageBox.Ok, + ) + == QMessageBox.Ok + ) @pyqtSlot(bool, name="on_pausePushButton_clicked") def workflowOnHold(self): @@ -185,20 +207,23 @@ def prepareProgressBar(self): """ self.progressBar.setValue(0) if self._previousWorkflow is not None: - self._previousWorkflow.feedback.progressChanged.\ - disconnect(self.setProgress) + self._previousWorkflow.feedback.progressChanged.disconnect(self.setProgress) self._previousWorkflow = self.currentWorkflow() if self._previousWorkflow is not None: - self._previousWorkflow.feedback.progressChanged.\ - connect(self.setProgress) + self._previousWorkflow.feedback.progressChanged.connect(self.setProgress) def showEditionButton(self, show=False): """ Shows/hides buttons for workflow edition. :param show: (bool) visibility status. """ - for button in [self.addPushButton, self.editPushButton, - self.removePushButton, self.importPushButton, self.splitter]: + for button in [ + self.addPushButton, + self.editPushButton, + self.removePushButton, + self.importPushButton, + self.splitter, + ]: getattr(button, "show" if show else "hide")() self._showButtons = show @@ -238,9 +263,9 @@ def resetTable(self): """ self.clearTable() self.tableWidget.setColumnCount(3) - self.tableWidget.setHorizontalHeaderLabels([ - self.tr("Model name"), self.tr("Status"), self.tr("Progress") - ]) + self.tableWidget.setHorizontalHeaderLabels( + [self.tr("Model name"), self.tr("Status"), self.tr("Progress")] + ) self.resizeTable() def resetComboBox(self): @@ -257,13 +282,13 @@ def setWorkflowTooltip(self, idx, metadata): :param metadata: (dict) workflow's metadata. """ self.comboBox.setItemData( - idx, + idx, self.tr( "Workflow author: {author}\n" "Workflow version: {version}\n" "Last modification: {lastModified}" ).format(**metadata), - Qt.ToolTipRole + Qt.ToolTipRole, ) def setGuiState(self, isActive=False): @@ -306,9 +331,7 @@ def addWorkflow(self): else: self.comboBox.setCurrentIndex(idx) # what should we do? check version/last modified? replace model? - self.setWorkflowTooltip( - self.comboBox.currentIndex(), workflow.metadata() - ) + self.setWorkflowTooltip(self.comboBox.currentIndex(), workflow.metadata()) self.saveState() @pyqtSlot(bool, name="on_removePushButton_clicked") @@ -320,8 +343,9 @@ def removeWorkflow(self): if idx < 1: return # raise any confirmation question? - msg = self.tr("Are you sure you want to remove workflow {0}?")\ - .format(self.currentWorkflowName()) + msg = self.tr("Are you sure you want to remove workflow {0}?").format( + self.currentWorkflowName() + ) if not self.confirmAction(msg): return self.comboBox.removeItem(idx) @@ -342,8 +366,7 @@ def editCurrentWorkflow(self): dlg = WorkflowSetupDialog(self) dlg.show() temp = os.path.join( - os.path.dirname(__file__), - "temp_workflow_{0}.workflow".format(hash(time())) + os.path.dirname(__file__), "temp_workflow_{0}.workflow".format(hash(time())) ) with open(temp, "w+", encoding="utf-8") as f: json.dump(workflow.asDict(), f) @@ -362,13 +385,12 @@ def editCurrentWorkflow(self): " workflow. Nothing changed." ), Qgis.Warning, - duration=3 + duration=3, ) return if newName == previousName: self.setCurrentWorkflow() - msg = self.tr("{0} updated (make sure you exported it).")\ - .format(newName) + msg = self.tr("{0} updated (make sure you exported it).").format(newName) else: self.comboBox.setItemText(self.comboBox.currentIndex(), newName) self.workflows.pop(previousName, None) @@ -376,15 +398,10 @@ def editCurrentWorkflow(self): "{1} renamed to {0} and updated (make sure you exported it)." ).format(newName, previousName) self.workflows[newName] = newWorkflow - self.setWorkflowTooltip( - self.comboBox.currentIndex(), newWorkflow.metadata() - ) + self.setWorkflowTooltip(self.comboBox.currentIndex(), newWorkflow.metadata()) self.setCurrentWorkflow() self.iface.messageBar().pushMessage( - self.tr("DSGTools Q&A Tool Box"), - msg, - Qgis.Info, - duration=3 + self.tr("DSGTools Q&A Tool Box"), msg, Qgis.Info, duration=3 ) self.saveState() @@ -412,9 +429,14 @@ def setRowColor(self, row, backgroundColor, foregroundColor): :param backgroundColor: (tuple-of-int) tuple containing RGBA values. :param foregroundColor: (tuple-of-int) tuple containing RGB values. """ - styleSheet = "*{ background-color:rgba" + str(backgroundColor) + \ - "; color:rgb" + str(foregroundColor) + "; } " + \ - "QToolTip{ background-color:black; color:white; }" + styleSheet = ( + "*{ background-color:rgba" + + str(backgroundColor) + + "; color:rgb" + + str(foregroundColor) + + "; } " + + "QToolTip{ background-color:black; color:white; }" + ) self.tableWidget.cellWidget(row, 0).setStyleSheet(styleSheet) self.tableWidget.cellWidget(row, 1).setStyleSheet(styleSheet) @@ -423,7 +445,7 @@ def setModelStatus(self, row, code, modelName, raiseMessage=False): Sets model execution status to its cell. :param row: (int) model's row on GUI. :param code: (int) code to current status (check this class enumerator). - :param modelName: (str) para to notify user of status change. This + :param modelName: (str) para to notify user of status change. This should be passed only through dynamic changes in order to avoid polluting QGIS main window. """ @@ -431,23 +453,24 @@ def setModelStatus(self, row, code, modelName, raiseMessage=False): self.setRowStatus(row, code) self.tableWidget.cellWidget(row, 1).setText(status) if raiseMessage or code in [self.HALTED, self.FAILED, self.FINISHED_WITH_FLAGS]: - # advise user a model status has changed only if it came from a + # advise user a model status has changed only if it came from a # signal call self.iface.messageBar().pushMessage( self.tr("DSGTools Q&A Toolbox"), - self.tr("model {0} status changed to {1}.")\ - .format(modelName, status), + self.tr("model {0} status changed to {1}.").format(modelName, status), self.qgisStatusDict[code], - duration=3 + duration=3, ) if code != self.INITIAL: QgsMessageLog.logMessage( - self.tr("Model {0} status changed to {1}.")\ - .format(modelName, status), + self.tr("Model {0} status changed to {1}.").format(modelName, status), "DSGTools Plugin", - self.qgisStatusDict[code] + self.qgisStatusDict[code], ) - if modelName in self.workflowStatusDict[self.comboBox.currentText()] and code == self.workflowStatusDict[self.comboBox.currentText()][modelName]: + if ( + modelName in self.workflowStatusDict[self.comboBox.currentText()] + and code == self.workflowStatusDict[self.comboBox.currentText()][modelName] + ): return self.workflowStatusDict[self.comboBox.currentText()][modelName] = code @@ -486,8 +509,10 @@ def setWorkflow(self, workflow): return models = workflow.validModels() self.tableWidget.setRowCount(len(models)) + def progressInt(pb, x): pb.setValue(int(x)) + currentStatusDict = self.workflowStatusDict.get(workflow.name(), {}) for row, (modelName, model) in enumerate(models.items()): tooltip = self.tr( @@ -496,21 +521,27 @@ def progressInt(pb, x): "Last modification: {2}\n" "\n{3}" ).format( - model.author(), model.version(), - model.lastModified(), model.description() + model.author(), + model.version(), + model.lastModified(), + model.description(), ) nameWidget = self.customLineWidget(modelName, tooltip) self.tableWidget.setCellWidget(row, 0, nameWidget) statusWidget = self.customLineWidget("", tooltip) self.tableWidget.setCellWidget(row, 1, statusWidget) code = currentStatusDict.get(modelName, self.INITIAL) - self.setModelStatus( - row, - code, - modelName - ) + self.setModelStatus(row, code, modelName) pb = self.progressWidget( - value=100 if code in [self.FINISHED, self.FINISHED_WITH_FLAGS, self.FINISHED_WITH_POSSIBLE_FALSE_POSITIVE_FLAGS] else 0) + value=100 + if code + in [ + self.FINISHED, + self.FINISHED_WITH_FLAGS, + self.FINISHED_WITH_POSSIBLE_FALSE_POSITIVE_FLAGS, + ] + else 0 + ) self.tableWidget.setCellWidget(row, 2, pb) def preProcessing(self, firstModel=None): @@ -520,10 +551,8 @@ def preProcessing(self, firstModel=None): """ isAfter = False for row in range(self.tableWidget.rowCount()): - modelName = self.tableWidget.cellWidget(row, 0).text() - if firstModel is not None and \ - modelName != firstModel \ - and not isAfter: + modelName = self.tableWidget.cellWidget(row, 0).text() + if firstModel is not None and modelName != firstModel and not isAfter: continue isAfter = True self.setModelStatus(row, self.INITIAL, modelName) @@ -536,18 +565,21 @@ def saveState(self): """ # workflow objects cannot be serialized, so they must be passed as dict workflows = { - w.displayName(): w.asDict(withOutputDict=True) for w in self.workflows.values() + w.displayName(): w.asDict(withOutputDict=True) + for w in self.workflows.values() } QgsExpressionContextUtils.setProjectVariable( QgsProject.instance(), "dsgtools_qatoolbox_state", - json.dumps({ - "workflows" : workflows, - "current_workflow" : self.comboBox.currentIndex(), - "show_buttons" : self._showButtons, - "workflow_status_dict": self.workflowStatusDict, - }) + json.dumps( + { + "workflows": workflows, + "current_workflow": self.comboBox.currentIndex(), + "show_buttons": self._showButtons, + "workflow_status_dict": self.workflowStatusDict, + } + ), ) def loadState(self, state=None): @@ -558,10 +590,11 @@ def loadState(self, state=None): project. """ state = json.loads( - state or\ - QgsExpressionContextUtils.projectScope(QgsProject.instance())\ - .variable("dsgtools_qatoolbox_state") or\ - "{}" + state + or QgsExpressionContextUtils.projectScope(QgsProject.instance()).variable( + "dsgtools_qatoolbox_state" + ) + or "{}" ) workflows = state["workflows"] if "workflows" in state else {} workflow_status_dict = state.get("workflow_status_dict", {}) @@ -573,8 +606,7 @@ def loadState(self, state=None): self.workflowStatusDict[name] = OrderedDict( workflow_status_dict.get(name, {}) ) - currentIdx = state["current_workflow"] if "current_workflow" in state \ - else 0 + currentIdx = state["current_workflow"] if "current_workflow" in state else 0 self.comboBox.setCurrentIndex(currentIdx) showButtons = state["show_buttons"] if "show_buttons" in state else True self.showEditionButton(showButtons) @@ -605,7 +637,7 @@ def runWorkflow(self): self.tr("DSGTools Q&A Tool Box"), self.tr("please select a valid Workflow."), Qgis.Warning, - duration=3 + duration=3, ) return self.setGuiState(True) @@ -618,27 +650,27 @@ def refreshFeedback(): del workflow.feedback workflow.feedback = QgsProcessingFeedback() workflow.feedback.progressChanged.connect(self.setProgress) + def intWrapper(pb, v): pb.setValue(int(v)) + def statusChangedWrapper(row, model, status): """status: (QgsTask.Enum) status enum""" if row is None: for row in range(self.tableWidget.rowCount()): - if self.tableWidget.cellWidget(row, 0)\ - .text() == model.name(): + if self.tableWidget.cellWidget(row, 0).text() == model.name(): break code = { - model.Queued : self.INITIAL, - model.OnHold : self.PAUSED, - model.Running : self.RUNNING, - model.Complete : self.FINISHED, - model.Terminated : self.FAILED, - model.WarningFlags : self.FINISHED_WITH_FLAGS, - model.HaltedOnFlags : self.HALTED, - model.HaltedOnPossibleFalsePositiveFlags: self.FINISHED_WITH_POSSIBLE_FALSE_POSITIVE_FLAGS + model.Queued: self.INITIAL, + model.OnHold: self.PAUSED, + model.Running: self.RUNNING, + model.Complete: self.FINISHED, + model.Terminated: self.FAILED, + model.WarningFlags: self.FINISHED_WITH_FLAGS, + model.HaltedOnFlags: self.HALTED, + model.HaltedOnPossibleFalsePositiveFlags: self.FINISHED_WITH_POSSIBLE_FALSE_POSITIVE_FLAGS, }[status] - if status == model.Terminated and \ - model.output["finishStatus"] != "halt": + if status == model.Terminated and model.output["finishStatus"] != "halt": if self.__workflowCanceled: code = self.CANCELED # if workflow was canceled (through the cancel push button), @@ -647,6 +679,7 @@ def statusChangedWrapper(row, model, status): self.__workflowCanceled = False if code != self.INITIAL: self.setModelStatus(row, code, model.displayName(), raiseMessage=True) + def begin(model): for row in range(self.tableWidget.rowCount()): if self.tableWidget.cellWidget(row, 0).text() != model.name(): @@ -657,10 +690,9 @@ def begin(model): model.feedback.progressChanged.connect(self.__progressFunc) self.__statusFunc = partial(statusChangedWrapper, row, model) model.statusChanged.connect(self.__statusFunc) - self.setModelStatus( - row, self.RUNNING, model.displayName() - ) + self.setModelStatus(row, self.RUNNING, model.displayName()) return + def end(model): for row in range(self.tableWidget.rowCount()): if self.tableWidget.cellWidget(row, 0).text() != model.name(): @@ -668,11 +700,15 @@ def end(model): model.feedback.progressChanged.disconnect(self.__progressFunc) model.statusChanged.disconnect(self.__statusFunc) return + def stopOnFlags(model): refreshFeedback() isAfter = False for row in range(self.tableWidget.rowCount()): - if self.tableWidget.cellWidget(row, 0).text() != model.name() and not isAfter: + if ( + self.tableWidget.cellWidget(row, 0).text() != model.name() + and not isAfter + ): continue if isAfter: code = self.INITIAL @@ -682,20 +718,18 @@ def stopOnFlags(model): model.statusChanged.disconnect(self.__statusFunc) code = self.HALTED isAfter = True - self.setModelStatus( - row, code, model.displayName() - ) + self.setModelStatus(row, code, model.displayName()) postProcessing() + def warningFlags(model): for row in range(self.tableWidget.rowCount()): if self.tableWidget.cellWidget(row, 0).text() != model.name(): continue model.feedback.progressChanged.disconnect(self.__progressFunc) model.statusChanged.disconnect(self.__statusFunc) - self.setModelStatus( - row, self.FINISHED_WITH_FLAGS, model.displayName() - ) + self.setModelStatus(row, self.FINISHED_WITH_FLAGS, model.displayName()) return + def postProcessing(): """ When workflow finishes, its signals are kept connected and that @@ -722,8 +756,9 @@ def postProcessing(): self.tr("DSGTools Q&A Toolbox"), msg.format(workflow.displayName()), lvl, - duration=3 + duration=3, ) + workflow.modelStarted.connect(begin) workflow.modelFinished.connect(end) workflow.haltedOnFlags.connect(stopOnFlags) @@ -732,15 +767,13 @@ def postProcessing(): sender = self.sender() isFirstModel = sender is None or sender.objectName() == "runPushButton" self.preProcessing( - firstModel = None if isFirstModel else workflow.lastModelName() - ) - workflow.run( - firstModelName = None if isFirstModel else workflow.lastModelName() + firstModel=None if isFirstModel else workflow.lastModelName() ) + workflow.run(firstModelName=None if isFirstModel else workflow.lastModelName()) def prepareOutputTreeNodes(self, clearBeforeRunning=False): rootNode = QgsProject.instance().layerTreeRoot() - groupName = 'DSGTools_QA_Toolbox' + groupName = "DSGTools_QA_Toolbox" groupNode = rootNode.findGroup(groupName) groupNode = groupNode if groupNode else rootNode.addGroup(groupName) if clearBeforeRunning: @@ -750,7 +783,7 @@ def prepareOutputTreeNodes(self, clearBeforeRunning=False): lyr.rollBack() groupNode.removeAllChildren() return groupName - + def removeEmptyNodes(self): qaNode = self.prepareOutputTreeNodes() qaNode.removeChildrenGroupWithoutLayers() @@ -763,8 +796,8 @@ def importWorkflow(self): """ fd = QFileDialog() paths = fd.getOpenFileNames( - caption=self.tr('Select Workflow files'), - filter=self.tr('DSGTools Workflow (*.workflow *.json)') + caption=self.tr("Select Workflow files"), + filter=self.tr("DSGTools Workflow (*.workflow *.json)"), ) paths = paths[0] if isinstance(paths, tuple) else "" if not paths: @@ -777,10 +810,11 @@ def importWorkflow(self): except Exception as e: self.iface.messageBar().pushMessage( self.tr("DSGTools Q&A Tool Box"), - self.tr("workflow '{path}' was not imported: '{msg}'") - .format(path=wPath, msg=str(e)), + self.tr("workflow '{path}' was not imported: '{msg}'").format( + path=wPath, msg=str(e) + ), Qgis.Critical, - duration=3 + duration=3, ) continue self.addWorkflowItem(workflow) @@ -795,18 +829,15 @@ def addWorkflowItem(self, workflow: QualityAssuranceWorkflow): self.setCurrentWorkflow() else: self.comboBox.setCurrentIndex(idx) - # what should we do? check version/last modified? replace model? - self.setWorkflowTooltip( - self.comboBox.currentIndex(), workflow.metadata() - ) + # what should we do? check version/last modified? replace model? + self.setWorkflowTooltip(self.comboBox.currentIndex(), workflow.metadata()) self.saveState() QgsMessageLog.logMessage( - self.tr("Model {model} imported.")\ - .format(model=name), - "DSGTools Plugin", - Qgis.Info - ) - + self.tr("Model {model} imported.").format(model=name), + "DSGTools Plugin", + Qgis.Info, + ) + def importWorkflowFromJsonPayload(self, data: List[Dict]): for workflow_dict in data: try: @@ -814,10 +845,11 @@ def importWorkflowFromJsonPayload(self, data: List[Dict]): except Exception as e: self.iface.messageBar().pushMessage( self.tr("DSGTools Q&A Tool Box"), - self.tr("Error importing workflow. Error message: {msg}'") - .format(msg=str(e)), + self.tr("Error importing workflow. Error message: {msg}'").format( + msg=str(e) + ), Qgis.Critical, - duration=3 + duration=3, ) continue self.addWorkflowItem(workflow) @@ -831,23 +863,20 @@ def unload(self): self.iface.newProjectCreated.disconnect(self.loadState) self.iface.projectRead.disconnect(self.loadState) self.blockSignals(True) - + def workflowIsFinished(self, modelName=None) -> bool: """ - Returns True if all steps executed and finished or finished with + Returns True if all steps executed and finished or finished with possible false positive flags. """ - modelName = modelName if modelName is not None \ - else self.comboBox.currentText() + modelName = modelName if modelName is not None else self.comboBox.currentText() if modelName not in self.workflowStatusDict: return False return all( - value in ( - self.FINISHED, - self.FINISHED_WITH_POSSIBLE_FALSE_POSITIVE_FLAGS - ) for _, value in self.workflowStatusDict[modelName].items() + value in (self.FINISHED, self.FINISHED_WITH_POSSIBLE_FALSE_POSITIVE_FLAGS) + for _, value in self.workflowStatusDict[modelName].items() ) - + def allWorkflowsAreFinishedWithoutFlags(self) -> bool: for name in self.workflows.keys(): if name not in self.workflowStatusDict: diff --git a/DsgTools/gui/ProductionTools/Toolboxes/QualityAssuranceToolBox/workflowSetupDialog.py b/DsgTools/gui/ProductionTools/Toolboxes/QualityAssuranceToolBox/workflowSetupDialog.py index 1a74d5eb8..891d909e8 100644 --- a/DsgTools/gui/ProductionTools/Toolboxes/QualityAssuranceToolBox/workflowSetupDialog.py +++ b/DsgTools/gui/ProductionTools/Toolboxes/QualityAssuranceToolBox/workflowSetupDialog.py @@ -29,37 +29,52 @@ from qgis.core import Qgis from qgis.gui import QgsMessageBar from qgis.PyQt.QtCore import QSize, QCoreApplication, pyqtSlot -from qgis.PyQt.QtWidgets import (QDialog, - QComboBox, - QCheckBox, - QLineEdit, - QFileDialog, - QMessageBox, - QTableWidgetItem) +from qgis.PyQt.QtWidgets import ( + QDialog, + QComboBox, + QCheckBox, + QLineEdit, + QFileDialog, + QMessageBox, + QTableWidgetItem, +) from processing.modeler.ModelerUtils import ModelerUtils -from DsgTools.gui.CustomWidgets.SelectionWidgets.selectFileWidget import SelectFileWidget -from DsgTools.core.DSGToolsProcessingAlgs.Models.qualityAssuranceWorkflow import QualityAssuranceWorkflow -from DsgTools.core.DSGToolsProcessingAlgs.Models.dsgToolsProcessingModel import DsgToolsProcessingModel +from DsgTools.gui.CustomWidgets.SelectionWidgets.selectFileWidget import ( + SelectFileWidget, +) +from DsgTools.core.DSGToolsProcessingAlgs.Models.qualityAssuranceWorkflow import ( + QualityAssuranceWorkflow, +) +from DsgTools.core.DSGToolsProcessingAlgs.Models.dsgToolsProcessingModel import ( + DsgToolsProcessingModel, +) FORM_CLASS, _ = uic.loadUiType( - os.path.join(os.path.dirname(__file__), 'workflowSetupDialog.ui') + os.path.join(os.path.dirname(__file__), "workflowSetupDialog.ui") ) + class WorkflowSetupDialog(QDialog, FORM_CLASS): __qgisModelPath__ = ModelerUtils.modelsFolders()[0] ON_FLAGS_HALT, ON_FLAGS_WARN, ON_FLAGS_IGNORE = range(3) onFlagsDisplayNameMap = { - ON_FLAGS_HALT : QCoreApplication.translate('WorkflowSetupDialog', "Halt"), - ON_FLAGS_WARN : QCoreApplication.translate('WorkflowSetupDialog', "Warn"), - ON_FLAGS_IGNORE : QCoreApplication.translate('WorkflowSetupDialog', "Ignore") + ON_FLAGS_HALT: QCoreApplication.translate("WorkflowSetupDialog", "Halt"), + ON_FLAGS_WARN: QCoreApplication.translate("WorkflowSetupDialog", "Warn"), + ON_FLAGS_IGNORE: QCoreApplication.translate("WorkflowSetupDialog", "Ignore"), } onFlagsValueMap = { - ON_FLAGS_HALT : "halt", - ON_FLAGS_WARN : "warn", - ON_FLAGS_IGNORE : "ignore" + ON_FLAGS_HALT: "halt", + ON_FLAGS_WARN: "warn", + ON_FLAGS_IGNORE: "ignore", } - MODEL_NAME_HEADER, MODEL_SOURCE_HEADER, ON_FLAGS_HEADER, LOAD_OUT_HEADER, FLAG_KEYS_HEADER = range(5) + ( + MODEL_NAME_HEADER, + MODEL_SOURCE_HEADER, + ON_FLAGS_HEADER, + LOAD_OUT_HEADER, + FLAG_KEYS_HEADER, + ) = range(5) def __init__(self, parent=None): """ @@ -72,43 +87,45 @@ def __init__(self, parent=None): self.parent = parent self.setupUi(self) self.messageBar = QgsMessageBar(self) - self.orderedTableWidget.setHeaders({ - self.MODEL_NAME_HEADER : { - "header" : self.tr("Model name"), - "type" : "widget", - "widget" : self.modelNameWidget, - "setter" : "setText", - "getter" : "text" - }, - self.MODEL_SOURCE_HEADER : { - "header" : self.tr("Model source"), - "type" : "widget", - "widget" : self.modelWidget, - "setter" : "setText", - "getter" : "text" - }, - self.ON_FLAGS_HEADER : { - "header" : self.tr("On flags"), - "type" : "widget", - "widget" : self.onFlagsWidget, - "setter" : "setCurrentIndex", - "getter" : "currentIndex" - }, - self.LOAD_OUT_HEADER : { - "header" : self.tr("Load output"), - "type" : "widget", - "widget" : self.loadOutputWidget, - "setter" : "setChecked", - "getter" : "isChecked" - }, - self.FLAG_KEYS_HEADER: { - "header" : self.tr("Flag keys"), - "type" : "widget", - "widget" : self.loadFlagLayers, - "setter" : "setText", - "getter" : "text" - }, - }) + self.orderedTableWidget.setHeaders( + { + self.MODEL_NAME_HEADER: { + "header": self.tr("Model name"), + "type": "widget", + "widget": self.modelNameWidget, + "setter": "setText", + "getter": "text", + }, + self.MODEL_SOURCE_HEADER: { + "header": self.tr("Model source"), + "type": "widget", + "widget": self.modelWidget, + "setter": "setText", + "getter": "text", + }, + self.ON_FLAGS_HEADER: { + "header": self.tr("On flags"), + "type": "widget", + "widget": self.onFlagsWidget, + "setter": "setCurrentIndex", + "getter": "currentIndex", + }, + self.LOAD_OUT_HEADER: { + "header": self.tr("Load output"), + "type": "widget", + "widget": self.loadOutputWidget, + "setter": "setChecked", + "getter": "isChecked", + }, + self.FLAG_KEYS_HEADER: { + "header": self.tr("Flag keys"), + "type": "widget", + "widget": self.loadFlagLayers, + "setter": "setText", + "getter": "text", + }, + } + ) self.orderedTableWidget.setHeaderDoubleClickBehaviour("replicate") self.promptToAll = None @@ -116,13 +133,20 @@ def resizeTable(self): """ Adjusts table columns sizes. """ - dSize = self.orderedTableWidget.geometry().width() - \ - self.orderedTableWidget.horizontalHeader().geometry().width() + dSize = ( + self.orderedTableWidget.geometry().width() + - self.orderedTableWidget.horizontalHeader().geometry().width() + ) onFlagsColSize = self.orderedTableWidget.sectionSize(2) loadOutColSize = self.orderedTableWidget.sectionSize(3) flagsOutColSize = self.orderedTableWidget.sectionSize(4) - missingBarSize = self.geometry().size().width() - dSize\ - - onFlagsColSize - loadOutColSize - flagsOutColSize + missingBarSize = ( + self.geometry().size().width() + - dSize + - onFlagsColSize + - loadOutColSize + - flagsOutColSize + ) # the "-11" is empiric: it makes it fit header to table self.orderedTableWidget.tableWidget.horizontalHeader().resizeSection( 0, int(0.4 * missingBarSize) - 11 @@ -141,7 +165,7 @@ def resizeEvent(self, e): self.messageBar.resize( QSize( self.geometry().size().width(), - 40 # this felt nicer than the original height (30) + 40, # this felt nicer than the original height (30) ) ) self.resizeTable() @@ -153,28 +177,34 @@ def confirmAction(self, msg, showCancel=True, addPromptToAll=False): :param showCancel: (bool) whether Cancel button should be exposed. :return: (bool) whether action was confirmed. """ - if not addPromptToAll: #comportamento antigo + if not addPromptToAll: # comportamento antigo if showCancel: - return QMessageBox.question( - self, self.tr('Confirm Action'), msg, - QMessageBox.Ok|QMessageBox.Cancel - ) == QMessageBox.Ok + return ( + QMessageBox.question( + self, + self.tr("Confirm Action"), + msg, + QMessageBox.Ok | QMessageBox.Cancel, + ) + == QMessageBox.Ok + ) else: - return QMessageBox.question( - self, self.tr('Confirm Action'), msg, - QMessageBox.Ok - ) == QMessageBox.Ok + return ( + QMessageBox.question( + self, self.tr("Confirm Action"), msg, QMessageBox.Ok + ) + == QMessageBox.Ok + ) # prompt to all == true daqui para frente if self.promptToAll is not None: return self.promptToAll - # prompt to all == true daqui para frente e self.promptToAll is None + # prompt to all == true daqui para frente e self.promptToAll is None # (o usuario nao mandou algum sim ou nao para todos) buttonPromptList = QMessageBox.Ok | QMessageBox.YesAll | QMessageBox.NoAll if showCancel: buttonPromptList = buttonPromptList | QMessageBox.Cancel answer = QMessageBox.question( - self, self.tr('Confirm Action'), msg, - buttonPromptList + self, self.tr("Confirm Action"), msg, buttonPromptList ) if answer in [QMessageBox.YesAll, QMessageBox.NoAll]: self.promptToAll = answer == QMessageBox.YesAll @@ -220,9 +250,7 @@ def modelWidget(self, filepath=None): widget.lineEdit.setPlaceholderText(self.tr("Select a model...")) widget.lineEdit.setFrame(False) widget.setCaption(self.tr("Select a QGIS Processing model file")) - widget.setFilter( - self.tr("Select a QGIS Processing model (*.model *.model3)") - ) + widget.setFilter(self.tr("Select a QGIS Processing model (*.model *.model3)")) # defining setter and getter methods for composed widgets into OTW widget.setText = widget.lineEdit.setText widget.text = widget.lineEdit.text @@ -235,14 +263,16 @@ def onFlagsWidget(self, option=None): Gets a new instance for the widget that sets model's behaviour when flags are raised. :param option: (str) on flags raised behaviour (non translatable text). - :return: (QComboBox) model's behaviour selection widget. + :return: (QComboBox) model's behaviour selection widget. """ combo = QComboBox() - combo.addItems([ - self.onFlagsDisplayNameMap[self.ON_FLAGS_HALT], - self.onFlagsDisplayNameMap[self.ON_FLAGS_WARN], - self.onFlagsDisplayNameMap[self.ON_FLAGS_IGNORE] - ]) + combo.addItems( + [ + self.onFlagsDisplayNameMap[self.ON_FLAGS_HALT], + self.onFlagsDisplayNameMap[self.ON_FLAGS_WARN], + self.onFlagsDisplayNameMap[self.ON_FLAGS_IGNORE], + ] + ) if option is not None: optIdx = None for idx, txt in self.onFlagsValueMap.items(): @@ -275,7 +305,7 @@ def now(self): Gets time and date from the system. Format: "dd/mm/yyyy HH:MM:SS". :return: (str) current's date and time """ - paddle = lambda n : str(n) if n > 9 else "0{0}".format(n) + paddle = lambda n: str(n) if n > 9 else "0{0}".format(n) now = datetime.now() return "{day}/{month}/{year} {hour}:{minute}:{second}".format( year=now.year, @@ -283,7 +313,7 @@ def now(self): day=paddle(now.day), hour=paddle(now.hour), minute=paddle(now.minute), - second=paddle(now.second) + second=paddle(now.second), ) def workflowName(self): @@ -346,28 +376,28 @@ def readRow(self, row): onFlagsIdx = contents[self.ON_FLAGS_HEADER] name = contents[self.MODEL_NAME_HEADER].strip() loadOutput = contents[self.LOAD_OUT_HEADER] - flagLayerNames = contents[self.FLAG_KEYS_HEADER].strip().split(',') + flagLayerNames = contents[self.FLAG_KEYS_HEADER].strip().split(",") if not os.path.exists(filepath): xml = "" else: with open(filepath, "r", encoding="utf-8") as f: xml = f.read() return { - "displayName" : name, - "flags" : { - "onFlagsRaised" : self.onFlagsValueMap[onFlagsIdx], - "loadOutput" : loadOutput, + "displayName": name, + "flags": { + "onFlagsRaised": self.onFlagsValueMap[onFlagsIdx], + "loadOutput": loadOutput, "flagLayerNames": flagLayerNames, }, - "source" : { - "type" : "xml", - "data" : xml, + "source": { + "type": "xml", + "data": xml, + }, + "metadata": { + "originalName": os.path.relpath( + os.path.realpath(filepath), os.path.realpath(self.__qgisModelPath__) + ), }, - "metadata" : { - "originalName" : os.path.relpath( - os.path.realpath(filepath), - os.path.realpath(self.__qgisModelPath__)), - } } def setModelToRow(self, row, model): @@ -386,8 +416,11 @@ def setModelToRow(self, row, model): elif model.source() == "xml": xml = data meta = model.metadata() - originalName = model.originalName() if model.originalName() \ - else "temp_{0}.model3".format(hash(time())) + originalName = ( + model.originalName() + if model.originalName() + else "temp_{0}.model3".format(hash(time())) + ) else: return False path = os.path.join(self.__qgisModelPath__, originalName) @@ -399,18 +432,21 @@ def setModelToRow(self, row, model): if not os.path.exists(path): with open(path, "w") as f: f.write(xml) - self.orderedTableWidget.addRow(contents={ - self.MODEL_NAME_HEADER : model.displayName(), - self.MODEL_SOURCE_HEADER : path, - self.ON_FLAGS_HEADER : { - "halt" : self.ON_FLAGS_HALT, - "warn" : self.ON_FLAGS_WARN, - "ignore" : self.ON_FLAGS_IGNORE - - }[model.onFlagsRaised()], - self.LOAD_OUT_HEADER : model.loadOutput(), - self.FLAG_KEYS_HEADER: ",".join(map(lambda x: str(x).strip(), model.flagLayerNames())), - }) + self.orderedTableWidget.addRow( + contents={ + self.MODEL_NAME_HEADER: model.displayName(), + self.MODEL_SOURCE_HEADER: path, + self.ON_FLAGS_HEADER: { + "halt": self.ON_FLAGS_HALT, + "warn": self.ON_FLAGS_WARN, + "ignore": self.ON_FLAGS_IGNORE, + }[model.onFlagsRaised()], + self.LOAD_OUT_HEADER: model.loadOutput(), + self.FLAG_KEYS_HEADER: ",".join( + map(lambda x: str(x).strip(), model.flagLayerNames()) + ), + } + ) return True def validateRowContents(self, contents): @@ -455,13 +491,13 @@ def workflowParameterMap(self): Generates a Workflow map from input data. """ return { - "displayName" : self.workflowName(), - "models" : self.models(), - "metadata" : { - "author" : self.author(), - "version" : self.version(), - "lastModified" : self.now() - } + "displayName": self.workflowName(), + "models": self.models(), + "metadata": { + "author": self.author(), + "version": self.version(), + "lastModified": self.now(), + }, } def currentWorkflow(self): @@ -506,38 +542,44 @@ def export(self): msg = self.validate() if msg != "": self.messageBar.pushMessage( - self.tr('Invalid workflow'), msg, level=Qgis.Warning, duration=5 + self.tr("Invalid workflow"), msg, level=Qgis.Warning, duration=5 ) return False fd = QFileDialog() filename = fd.getSaveFileName( caption=self.tr("Export DSGTools Workflow"), - filter=self.tr("DSGTools Workflow (*.workflow)") + filter=self.tr("DSGTools Workflow (*.workflow)"), ) filename = filename[0] if isinstance(filename, tuple) else "" if filename == "": return False - filename = filename if filename.lower().endswith(".workflow") \ - else "{0}.workflow".format(filename) + filename = ( + filename + if filename.lower().endswith(".workflow") + else "{0}.workflow".format(filename) + ) try: self.exportWorkflow(filename) except Exception as e: self.messageBar.pushMessage( - self.tr('Invalid workflow'), + self.tr("Invalid workflow"), self.tr("Unable to export workflow to '{fp}' ({error}).").format( fp=filename, error=str(e) ), level=Qgis.Warning, - duration=5 + duration=5, ) return False result = os.path.exists(filename) - msg = (self.tr("Workflow exported to {fp}") if result else \ - self.tr("Unable to export workflow to '{fp}'")).format(fp=filename) + msg = ( + self.tr("Workflow exported to {fp}") + if result + else self.tr("Unable to export workflow to '{fp}'") + ).format(fp=filename) lvl = Qgis.Success if result else Qgis.Warning self.messageBar.pushMessage( - self.tr('Workflow exportation'), msg, level=lvl, duration=5 - ) + self.tr("Workflow exportation"), msg, level=lvl, duration=5 + ) return result def importWorkflow(self, filepath): @@ -563,8 +605,8 @@ def import_(self): """ fd = QFileDialog() filename = fd.getOpenFileName( - caption=self.tr('Select a Workflow file'), - filter=self.tr('DSGTools Workflow (*.workflow *.json)') + caption=self.tr("Select a Workflow file"), + filter=self.tr("DSGTools Workflow (*.workflow *.json)"), ) filename = filename[0] if isinstance(filename, tuple) else "" if not filename: @@ -573,21 +615,19 @@ def import_(self): self.importWorkflow(filename) except Exception as e: self.messageBar.pushMessage( - self.tr('Invalid workflow'), + self.tr("Invalid workflow"), self.tr("Unable to export workflow to '{fp}' ({error}).").format( fp=filename, error=str(e) ), level=Qgis.Critical, - duration=5 + duration=5, ) return False self.messageBar.pushMessage( - self.tr('Success'), - self.tr("Workflow '{fp}' imported!").format( - fp=filename - ), + self.tr("Success"), + self.tr("Workflow '{fp}' imported!").format(fp=filename), level=Qgis.Info, - duration=5 + duration=5, ) return True @@ -601,10 +641,10 @@ def ok(self): self.done(1) else: self.messageBar.pushMessage( - self.tr('Invalid workflow'), + self.tr("Invalid workflow"), self.validate(), level=Qgis.Warning, - duration=5 + duration=5, ) @pyqtSlot(bool, name="on_cancelPushButton_clicked") diff --git a/DsgTools/gui/ProductionTools/Toolboxes/toolBoxesGuiManager.py b/DsgTools/gui/ProductionTools/Toolboxes/toolBoxesGuiManager.py index 2159a9ef4..5ea471a53 100644 --- a/DsgTools/gui/ProductionTools/Toolboxes/toolBoxesGuiManager.py +++ b/DsgTools/gui/ProductionTools/Toolboxes/toolBoxesGuiManager.py @@ -28,59 +28,74 @@ from qgis.PyQt.QtCore import QObject, Qt from .AttributeTools.code_list import CodeList -from DsgTools.Modules.acquisitionMenu.controllers.acquisitionMenuCtrl import AcquisitionMenuCtrl +from DsgTools.Modules.acquisitionMenu.controllers.acquisitionMenuCtrl import ( + AcquisitionMenuCtrl, +) from .ContourTool.calc_contour import CalcContour from .ComplexTools.complexWindow import ComplexWindow -from .QualityAssuranceToolBox.qualityAssuranceDockWidget import QualityAssuranceDockWidget +from .QualityAssuranceToolBox.qualityAssuranceDockWidget import ( + QualityAssuranceDockWidget, +) -class ToolBoxesGuiManager(QObject): +class ToolBoxesGuiManager(QObject): def __init__( - self, - manager, - iface, - parentMenu = None, - toolbar = None, - stackButton = None, - acquisitionMenuCtrl = AcquisitionMenuCtrl() - ): - """Constructor. - """ + self, + manager, + iface, + parentMenu=None, + toolbar=None, + stackButton=None, + acquisitionMenuCtrl=AcquisitionMenuCtrl(), + ): + """Constructor.""" super(ToolBoxesGuiManager, self).__init__() self.manager = manager self.iface = iface self.parentMenu = parentMenu self.toolbar = toolbar self.stackButton = stackButton - self.iconBasePath = ':/plugins/DsgTools/icons/' + self.iconBasePath = ":/plugins/DsgTools/icons/" self.acquisitionMenuCtrl = acquisitionMenuCtrl - + def initGui(self): self.qaToolBox = None self.addTool( self.showQaToolBox, - 'validationtools.png', + "validationtools.png", self.tr("Geospatial Data Quality Assurance Tool"), parentButton=self.stackButton, - setDefaultAction=True + setDefaultAction=True, ) - + self.addTool( - self.acquisitionMenuCtrl.openMenuEditor, - 'customFeatureToolBox.png', - self.tr('Custom Feature Tool'), + self.acquisitionMenuCtrl.openMenuEditor, + "customFeatureToolBox.png", + self.tr("Custom Feature Tool"), parentButton=self.stackButton, ) - + self.calcContour = None - self.addTool(self.showCalcContourToolbox, 'calccontour.png', self.tr('Assign Contour Values')) + self.addTool( + self.showCalcContourToolbox, + "calccontour.png", + self.tr("Assign Contour Values"), + ) self.codeList = None - self.addTool(self.showCodeList, 'codelist.png', self.tr('View Code List Codes and Values')) + self.addTool( + self.showCodeList, + "codelist.png", + self.tr("View Code List Codes and Values"), + ) self.complexWindow = None - self.addTool(self.showComplexDock, 'complex.png', self.tr('Build Complex Structures')) + self.addTool( + self.showComplexDock, "complex.png", self.tr("Build Complex Structures") + ) - def addTool(self, callback, iconBaseName, text, setDefaultAction=False, parentButton=None): + def addTool( + self, callback, iconBaseName, text, setDefaultAction=False, parentButton=None + ): action = self.manager.add_action( os.path.join(self.iconBasePath, iconBaseName), text=text, @@ -88,7 +103,7 @@ def addTool(self, callback, iconBaseName, text, setDefaultAction=False, parentBu add_to_menu=False, add_to_toolbar=False, parentMenu=self.parentMenu, - parentButton=parentButton + parentButton=parentButton, ) if setDefaultAction: self.stackButton.setDefaultAction(action) @@ -115,9 +130,9 @@ def showCustomFeatureToolbox(self): self.iface.removeDockWidget(self.cfToolbox) else: self.cfToolbox = CustomFeatureTool() - self.iface.addDockWidget(Qt.RightDockWidgetArea, self.cfToolbox) """ + self.iface.addDockWidget(Qt.RightDockWidgetArea, self.cfToolbox) """ pass - + def refreshQaToolBoxObject(self): if self.qaToolBox is not None: self.iface.removeDockWidget(self.qaToolBox) @@ -144,7 +159,7 @@ def showCalcContourToolbox(self): else: self.calcContour = CalcContour(self.iface) self.iface.addDockWidget(Qt.BottomDockWidgetArea, self.calcContour) - + def showComplexDock(self): """ Shows the Manage Complex features Dock diff --git a/DsgTools/gui/ProductionTools/__init__.py b/DsgTools/gui/ProductionTools/__init__.py index 80823e1d6..bbe5134fa 100644 --- a/DsgTools/gui/ProductionTools/__init__.py +++ b/DsgTools/gui/ProductionTools/__init__.py @@ -32,4 +32,5 @@ def classFactory(iface): # pylint: disable=invalid-name """ # from .dsg_tools import DsgTools + return DsgTools(iface) diff --git a/DsgTools/gui/ProductionTools/productionToolsGuiManager.py b/DsgTools/gui/ProductionTools/productionToolsGuiManager.py index acb5391de..b7ce2d50c 100644 --- a/DsgTools/gui/ProductionTools/productionToolsGuiManager.py +++ b/DsgTools/gui/ProductionTools/productionToolsGuiManager.py @@ -22,14 +22,14 @@ from __future__ import absolute_import -from qgis.PyQt.QtCore import QObject +from qgis.PyQt.QtCore import QObject from .Toolboxes.toolBoxesGuiManager import ToolBoxesGuiManager from .MapTools.mapToolsGuiManager import MapToolsGuiManager from .Toolbars.toolBarsGuiManager import ToolbarsGuiManager -class ProductionToolsGuiManager(QObject): - def __init__(self, manager, iface, parentMenu = None, toolbar = None): +class ProductionToolsGuiManager(QObject): + def __init__(self, manager, iface, parentMenu=None, toolbar=None): """Constructor. :param iface: An interface instance that will be passed to this class which provides the hook by which you can manipulate the QGIS @@ -42,21 +42,31 @@ def __init__(self, manager, iface, parentMenu = None, toolbar = None): self.iface = iface self.parentMenu = parentMenu self.toolbar = toolbar - self.menu = self.manager.addMenu(u'productiontools', self.tr('Production Tools'),'productiontools.png') - self.stackButton = self.manager.createToolButton(self.toolbar, u'ProductionTools') - self.iconBasePath = ':/plugins/DsgTools/icons/' - + self.menu = self.manager.addMenu( + "productiontools", self.tr("Production Tools"), "productiontools.png" + ) + self.stackButton = self.manager.createToolButton( + self.toolbar, "ProductionTools" + ) + self.iconBasePath = ":/plugins/DsgTools/icons/" + def initGui(self): - self.toolBoxesGuiManager = ToolBoxesGuiManager(self.manager, self.iface, parentMenu=self.menu, stackButton=self.stackButton) + self.toolBoxesGuiManager = ToolBoxesGuiManager( + self.manager, self.iface, parentMenu=self.menu, stackButton=self.stackButton + ) self.toolBoxesGuiManager.initGui() self.menu.addSeparator() - self.mapToolsGuiManager = MapToolsGuiManager(self.manager, self.iface, parentMenu=self.menu, toolbar = self.toolbar) + self.mapToolsGuiManager = MapToolsGuiManager( + self.manager, self.iface, parentMenu=self.menu, toolbar=self.toolbar + ) self.mapToolsGuiManager.initGui() self.menu.addSeparator() - self.toolbarsGuiManager = ToolbarsGuiManager(self.manager, self.iface, parentMenu=self.menu, toolbar=self.toolbar) + self.toolbarsGuiManager = ToolbarsGuiManager( + self.manager, self.iface, parentMenu=self.menu, toolbar=self.toolbar + ) self.toolbarsGuiManager.initGui() - + def unload(self): self.toolBoxesGuiManager.unload() self.mapToolsGuiManager.unload() - self.toolbarsGuiManager.unload() \ No newline at end of file + self.toolbarsGuiManager.unload() diff --git a/DsgTools/gui/ServerTools/BatchDbManagerGui/batchDbManagerGui.py b/DsgTools/gui/ServerTools/BatchDbManagerGui/batchDbManagerGui.py index c9e817159..713c1a1c7 100644 --- a/DsgTools/gui/ServerTools/BatchDbManagerGui/batchDbManagerGui.py +++ b/DsgTools/gui/ServerTools/BatchDbManagerGui/batchDbManagerGui.py @@ -25,8 +25,8 @@ from DsgTools.gui.ServerTools.batchDbManager import BatchDbManager + class BatchDbManagerGui(QObject): - def __init__(self, manager, parentMenu): """ Class constructor. @@ -43,13 +43,13 @@ def initGui(self): """ Sets server tools to DSGTools/QGIS interface. """ - icon_path = ':/plugins/DsgTools/icons/server.png' + icon_path = ":/plugins/DsgTools/icons/server.png" action = self.manager.addTool( - text=self.tr('Manage Databases from Server'), + text=self.tr("Manage Databases from Server"), callback=self.openBatchDbManager, parentMenu=self.parentMenu, - icon='server.png' - ) + icon="server.png", + ) def openBatchDbManager(self): """ @@ -62,4 +62,4 @@ def unload(self): """ Removes GUI components. """ - pass \ No newline at end of file + pass diff --git a/DsgTools/gui/ServerTools/ViewServersGui/viewServersGui.py b/DsgTools/gui/ServerTools/ViewServersGui/viewServersGui.py index 70e92e342..51c8b9067 100644 --- a/DsgTools/gui/ServerTools/ViewServersGui/viewServersGui.py +++ b/DsgTools/gui/ServerTools/ViewServersGui/viewServersGui.py @@ -25,8 +25,8 @@ from DsgTools.gui.ServerTools.viewServers import ViewServers + class ViewServersGui(QObject): - def __init__(self, manager, parentMenu, iface=None, parent=None): """ Class constructor. @@ -44,13 +44,13 @@ def initGui(self): """ Sets server tools to DSGTools/QGIS interface. """ - icon_path = ':/plugins/DsgTools/icons/server.png' + icon_path = ":/plugins/DsgTools/icons/server.png" action = self.manager.addTool( - text=self.tr('Configure Servers'), + text=self.tr("Configure Servers"), callback=self.openViewServers, parentMenu=self.parentMenu, - icon='server.png' - ) + icon="server.png", + ) def openViewServers(self): """ @@ -63,4 +63,4 @@ def unload(self): """ Removes GUI components. """ - pass \ No newline at end of file + pass diff --git a/DsgTools/gui/ServerTools/batchDbManager.py b/DsgTools/gui/ServerTools/batchDbManager.py index f9cedf600..134277f11 100644 --- a/DsgTools/gui/ServerTools/batchDbManager.py +++ b/DsgTools/gui/ServerTools/batchDbManager.py @@ -30,7 +30,13 @@ # Qt imports from qgis.PyQt import QtWidgets, uic from qgis.PyQt.QtCore import pyqtSlot, Qt, QSettings, pyqtSignal -from qgis.PyQt.QtWidgets import QListWidgetItem, QMessageBox, QMenu, QApplication, QFileDialog +from qgis.PyQt.QtWidgets import ( + QListWidgetItem, + QMessageBox, + QMenu, + QApplication, + QFileDialog, +) from qgis.PyQt.QtGui import QCursor from qgis.PyQt.QtSql import QSqlDatabase, QSqlQuery @@ -46,43 +52,53 @@ from DsgTools.gui.ServerTools.selectStyles import SelectStyles from DsgTools.core.dsgEnums import DsgEnums -FORM_CLASS, _ = uic.loadUiType(os.path.join( - os.path.dirname(__file__), 'batchDbManager.ui')) +FORM_CLASS, _ = uic.loadUiType( + os.path.join(os.path.dirname(__file__), "batchDbManager.ui") +) + class BatchDbManager(QtWidgets.QDialog, FORM_CLASS): EDGV213, EDGV_FTer_2a_Ed, Non_EDGV = list(range(3)) - def __init__(self, parent = None): + + def __init__(self, parent=None): """Constructor.""" super(self.__class__, self).__init__(parent) self.setupUi(self) self.utils = Utils() self.dbFactory = DbFactory() self.factory = SqlGeneratorFactory() - self.showTabs(show = False) - #setting the sql generator + self.showTabs(show=False) + # setting the sql generator self.serverWidget.populateServersCombo() self.serverWidget.abstractDbLoaded.connect(self.checkSuperUser) self.serverWidget.abstractDbLoaded.connect(self.populateOtherInterfaces) - self.dbsCustomSelector.setTitle(self.tr('Server Databases')) + self.dbsCustomSelector.setTitle(self.tr("Server Databases")) self.dbsCustomSelector.selectionChanged.connect(self.showTabs) self.dbsCustomSelector.selectionChanged.connect(self.populateStylesInterface) self.dbsCustomSelector.selectionChanged.connect(self.populateOtherInterfaces) self.previousTab = 0 - self.dbDict = {'2.1.3':[], '2.1.3 Pro':[], 'FTer_2a_Ed':[],'Non_EDGV':[], '3.0':[], '3.0 Pro':[]} + self.dbDict = { + "2.1.3": [], + "2.1.3 Pro": [], + "FTer_2a_Ed": [], + "Non_EDGV": [], + "3.0": [], + "3.0 Pro": [], + } self.correspondenceDict = { - self.tr('Load Database Model EDGV Version 2.1.3'):'2.1.3', - self.tr('Load Database Model EDGV Version 2.1.3 Pro'):'2.1.3 Pro', - self.tr('Load Database Model EDGV Version 3.0'):'3.0', - self.tr('Load Database Model EDGV Version 3.0 Pro'):'3.0 Pro', - self.tr('Load Database Model EDGV Version FTer_2a_Ed'):'FTer_2a_Ed', - self.tr('Load Other Database Models'):'Non_EDGV' + self.tr("Load Database Model EDGV Version 2.1.3"): "2.1.3", + self.tr("Load Database Model EDGV Version 2.1.3 Pro"): "2.1.3 Pro", + self.tr("Load Database Model EDGV Version 3.0"): "3.0", + self.tr("Load Database Model EDGV Version 3.0 Pro"): "3.0 Pro", + self.tr("Load Database Model EDGV Version FTer_2a_Ed"): "FTer_2a_Ed", + self.tr("Load Other Database Models"): "Non_EDGV", } @pyqtSlot(bool) def on_closePushButton_clicked(self): self.done(0) - - def showTabs(self, show = True): + + def showTabs(self, show=True): if show: self.tabWidget.show() else: @@ -90,47 +106,77 @@ def showTabs(self, show = True): def populateListWithDatabasesFromServer(self): try: - dbList = self.serverWidget.abstractDb.getEDGVDbsFromServer(parentWidget = self) + dbList = self.serverWidget.abstractDb.getEDGVDbsFromServer( + parentWidget=self + ) except Exception as e: - QMessageBox.critical(self, self.tr('Critical!'), ':'.join(e.args)) + QMessageBox.critical(self, self.tr("Critical!"), ":".join(e.args)) dbList.sort() try: for (dbname, dbversion, impl_dummy) in dbList: - dbversion = dbversion.replace("EDGV ","") + dbversion = dbversion.replace("EDGV ", "") if dbversion not in list(self.dbDict.keys()): - dbversion = 'Non_EDGV' + dbversion = "Non_EDGV" if dbname not in self.dbDict[dbversion]: self.dbDict[dbversion].append(dbname) except Exception as e: - QMessageBox.critical(self, self.tr('Critical!'), str(dbList)) + QMessageBox.critical(self, self.tr("Critical!"), str(dbList)) def setDatabases(self): self.populateListWithDatabasesFromServer() - + @pyqtSlot(int) def on_edgvComboFilter_currentIndexChanged(self, idx): if idx != -1 and idx != 0: - self.dbsCustomSelector.setInitialState(self.dbDict[self.correspondenceDict[self.edgvComboFilter.currentText()]]) + self.dbsCustomSelector.setInitialState( + self.dbDict[self.correspondenceDict[self.edgvComboFilter.currentText()]] + ) def checkSuperUser(self): try: if self.serverWidget.abstractDb.checkSuperUser(): self.setDatabases() else: - QMessageBox.warning(self, self.tr('Info!'), self.tr('Connection refused. Connect with a super user to inspect server.')) + QMessageBox.warning( + self, + self.tr("Info!"), + self.tr( + "Connection refused. Connect with a super user to inspect server." + ), + ) except Exception as e: - QMessageBox.critical(self, self.tr('Critical!'), ':'.join(e.args)) + QMessageBox.critical(self, self.tr("Critical!"), ":".join(e.args)) def getSelectedDbList(self): return self.dbsCustomSelector.toLs - - def instantiateAbstractDbs(self, instantiateTemplates = False): + + def instantiateAbstractDbs(self, instantiateTemplates=False): dbsDict = dict() selectedDbNameList = self.getSelectedDbList() - selectedDbNameList = list(set(selectedDbNameList + ['template_edgv_213', 'template_edgv_fter_2a_ed', 'template_edgv_3', 'dsgtools_admindb'])) if instantiateTemplates else selectedDbNameList + selectedDbNameList = ( + list( + set( + selectedDbNameList + + [ + "template_edgv_213", + "template_edgv_fter_2a_ed", + "template_edgv_3", + "dsgtools_admindb", + ] + ) + ) + if instantiateTemplates + else selectedDbNameList + ) for dbName in selectedDbNameList: localDb = self.dbFactory.createDbFactory(DsgEnums.DriverPostGIS) - localDb.connectDatabaseWithParameters(self.serverWidget.abstractDb.db.hostName(), self.serverWidget.abstractDb.db.port(), dbName, self.serverWidget.abstractDb.db.userName(), self.serverWidget.abstractDb.db.password()) + localDb.connectDatabaseWithParameters( + self.serverWidget.abstractDb.db.hostName(), + self.serverWidget.abstractDb.db.port(), + dbName, + self.serverWidget.abstractDb.db.userName(), + self.serverWidget.abstractDb.db.password(), + ) dbsDict[dbName] = localDb return dbsDict @@ -140,44 +186,61 @@ def closeAbstractDbs(self, dbsDict): try: dbsDict[dbName].db.close() except Exception as e: - exceptionDict[dbName] = ':'.join(e.args) + exceptionDict[dbName] = ":".join(e.args) return exceptionDict def outputMessage(self, header, successList, exceptionDict): msg = header if len(successList) > 0: - msg += self.tr('\nSuccessful databases: ') - msg +=', '.join(successList) + msg += self.tr("\nSuccessful databases: ") + msg += ", ".join(successList) if exceptionDict != []: msg += self.logInternalError(exceptionDict) if successList != [] and exceptionDict != []: - QMessageBox.warning(self, self.tr('Operation Complete!'), msg) - + QMessageBox.warning(self, self.tr("Operation Complete!"), msg) + def logInternalError(self, exceptionDict): - msg = '' + msg = "" errorDbList = list(exceptionDict.keys()) - if len(errorDbList)> 0: - msg += self.tr('\nDatabases with error:') - msg+= ', '.join(errorDbList) - msg+= self.tr('\nError messages for each database were output in qgis log.') + if len(errorDbList) > 0: + msg += self.tr("\nDatabases with error:") + msg += ", ".join(errorDbList) + msg += self.tr( + "\nError messages for each database were output in qgis log." + ) for errorDb in errorDbList: - msg = self.tr("Error for database {0}: ").format(errorDb, exceptionDict[errorDb]) + msg = self.tr("Error for database {0}: ").format( + errorDb, exceptionDict[errorDb] + ) QgsMessageLog.logMessage(msg, "DSGTools Plugin", Qgis.Critical) - return msg + return msg @pyqtSlot(bool) def on_dropDatabasePushButton_clicked(self): selectedDbNameList = self.getSelectedDbList() if len(selectedDbNameList) == 0: - QMessageBox.warning(self, self.tr('Warning'), self.tr('Please select one or more databases to drop!')) + QMessageBox.warning( + self, + self.tr("Warning"), + self.tr("Please select one or more databases to drop!"), + ) return - if QMessageBox.question(self, self.tr('Question'), self.tr('Do you really want to drop databases: ')+', '.join(selectedDbNameList), QMessageBox.Ok|QMessageBox.Cancel) == QMessageBox.Cancel: + if ( + QMessageBox.question( + self, + self.tr("Question"), + self.tr("Do you really want to drop databases: ") + + ", ".join(selectedDbNameList), + QMessageBox.Ok | QMessageBox.Cancel, + ) + == QMessageBox.Cancel + ): return QApplication.setOverrideCursor(QCursor(Qt.WaitCursor)) successList, exceptionDict = self.batchDropDbs(selectedDbNameList) QApplication.restoreOverrideCursor() self.setDatabases() - header = self.tr('Drop operation complete. \n') + header = self.tr("Drop operation complete. \n") self.outputMessage(header, successList, exceptionDict) self.dbsCustomSelector.setInitialState(self.dbsCustomSelector.fromLs) @@ -188,28 +251,42 @@ def on_upgradePostgisPushButton_clicked(self): successList, exceptionDict = self.batchUpgradePostgis(selectedDbNameList) QApplication.restoreOverrideCursor() self.setDatabases() - header = self.tr('Upgrade Posgtis operation complete. \n') + header = self.tr("Upgrade Posgtis operation complete. \n") self.outputMessage(header, successList, exceptionDict) def batchUpgradePostgis(self, dbList): exceptionDict = dict() successList = [] - if QMessageBox.question(self, self.tr('Question'), self.tr('This operation will upgrade PostGIS version for templates databases as well as the selected databases. Would you like to continue?'), QMessageBox.Ok|QMessageBox.Cancel) == QMessageBox.Cancel: + if ( + QMessageBox.question( + self, + self.tr("Question"), + self.tr( + "This operation will upgrade PostGIS version for templates databases as well as the selected databases. Would you like to continue?" + ), + QMessageBox.Ok | QMessageBox.Cancel, + ) + == QMessageBox.Cancel + ): return successList, exceptionDict - dbsDict = self.instantiateAbstractDbs(instantiateTemplates = True) + dbsDict = self.instantiateAbstractDbs(instantiateTemplates=True) self.closeAbstractDbs(dbsDict) for dbName in dbsDict: try: if self.serverWidget.abstractDb.checkIfTemplate(dbName): - self.serverWidget.abstractDb.setDbAsTemplate(dbName = dbName, setTemplate = False) + self.serverWidget.abstractDb.setDbAsTemplate( + dbName=dbName, setTemplate=False + ) dbsDict[dbName].upgradePostgis() - self.serverWidget.abstractDb.setDbAsTemplate(dbName = dbName, setTemplate = True) + self.serverWidget.abstractDb.setDbAsTemplate( + dbName=dbName, setTemplate=True + ) successList.append(dbName) else: dbsDict[dbName].upgradePostgis() successList.append(dbName) except Exception as e: - exceptionDict[dbName] = ':'.join(e.args) + exceptionDict[dbName] = ":".join(e.args) return successList, exceptionDict def batchDropDbs(self, dbList): @@ -222,9 +299,9 @@ def batchDropDbs(self, dbList): self.serverWidget.abstractDb.dropDatabase(dbName) successList.append(dbName) except Exception as e: - exceptionDict[dbName] = ':'.join(e.args) + exceptionDict[dbName] = ":".join(e.args) return successList, exceptionDict - + @pyqtSlot(bool) def on_importStylesPushButton_clicked(self): dbsDict = self.instantiateAbstractDbs() @@ -237,11 +314,15 @@ def on_importStylesPushButton_clicked(self): if version not in versionList: versionList.append(version) except Exception as e: - exceptionDict[dbName] = ':'.join(e.args) - if len(list(exceptionDict.keys()))>0: + exceptionDict[dbName] = ":".join(e.args) + if len(list(exceptionDict.keys())) > 0: self.logInternalError(exceptionDict) if len(versionList) > 1: - QMessageBox.warning(self, self.tr('Warning'), self.tr('Multiple edgv versions are not allowed!')) + QMessageBox.warning( + self, + self.tr("Warning"), + self.tr("Multiple edgv versions are not allowed!"), + ) return styleDir = self.getStyleDir(versionList) styleList = self.getStyleList(styleDir) @@ -251,20 +332,21 @@ def on_importStylesPushButton_clicked(self): if len(selectedStyles) == 0: return QApplication.setOverrideCursor(QCursor(Qt.WaitCursor)) - successList, exceptionDict = self.batchImportStyles(dbsDict, styleDir, selectedStyles, versionList[0]) + successList, exceptionDict = self.batchImportStyles( + dbsDict, styleDir, selectedStyles, versionList[0] + ) QApplication.restoreOverrideCursor() - header = self.tr('Import operation complete. \n') + header = self.tr("Import operation complete. \n") self.outputMessage(header, successList, exceptionDict) self.populateStylesInterface() closeExceptionDict = self.closeAbstractDbs(dbsDict) - self.logInternalError(closeExceptionDict) - - + self.logInternalError(closeExceptionDict) + def getStyleList(self, styleDir): - #TODO: Reimplement + # TODO: Reimplement styleList = [] version = None - if os.path.basename(styleDir) in ['edgv_213','edgv_FTer_2a_Ed', 'edgv_3']: + if os.path.basename(styleDir) in ["edgv_213", "edgv_FTer_2a_Ed", "edgv_3"]: version = os.path.basename(styleDir) else: parentFolder = os.path.dirname(styleDir) @@ -276,11 +358,11 @@ def getStyleList(self, styleDir): for style in styles: if style == []: continue - styleList.append('/'.join([version,style])) + styleList.append("/".join([version, style])) if len(styleList) == 0: - styleList = [version+'/'+os.path.basename(styleDir)] + styleList = [version + "/" + os.path.basename(styleDir)] return styleList - + def batchImportStyles(self, dbsDict, styleDir, styleList, version): exceptionDict = dict() successList = [] @@ -293,36 +375,48 @@ def batchImportStyles(self, dbsDict, styleDir, styleList, version): errors = [] for arg in e.args: if isinstance(arg, str): - s = '{}'.format(arg.encode('utf-8')) + s = "{}".format(arg.encode("utf-8")) else: s = str(arg) errors.append(s) - exceptionDict[dbName] = ':'.join(errors) + exceptionDict[dbName] = ":".join(errors) return successList, exceptionDict - + def getStyleDir(self, versionList): - if versionList != [] and versionList[0] in self.serverWidget.abstractDb.versionFolderDict: - return os.path.join(os.path.dirname(__file__),'..', '..', 'core', 'Styles', self.serverWidget.abstractDb.versionFolderDict[versionList[0]]) + if ( + versionList != [] + and versionList[0] in self.serverWidget.abstractDb.versionFolderDict + ): + return os.path.join( + os.path.dirname(__file__), + "..", + "..", + "core", + "Styles", + self.serverWidget.abstractDb.versionFolderDict[versionList[0]], + ) elif versionList != []: - return os.path.join(os.path.dirname(__file__),'..', '..', 'core', 'Styles', "Non_EDGV") + return os.path.join( + os.path.dirname(__file__), "..", "..", "core", "Styles", "Non_EDGV" + ) return "" - - def getStylesFromDbs(self, perspective = 'style'): - ''' + + def getStylesFromDbs(self, perspective="style"): + """ Returns a dict of styles in a form acording to perspective: if perspective = 'style' : [styleName][dbName][tableName] = timestamp - if perspective = 'database' : [dbName][styleName][tableName] = timestamp - ''' + if perspective = 'database' : [dbName][styleName][tableName] = timestamp + """ dbsDict = self.instantiateAbstractDbs() allStylesDict = dict() exceptionDict = dict() for dbName in list(dbsDict.keys()): try: - newDict =dbsDict[dbName].getAllStylesDict(perspective) + newDict = dbsDict[dbName].getAllStylesDict(perspective) allStylesDict = self.utils.mergeDict(newDict, allStylesDict) except Exception as e: - exceptionDict[dbName] = ':'.join(e.args) - if len(list(exceptionDict.keys()))>0: + exceptionDict[dbName] = ":".join(e.args) + if len(list(exceptionDict.keys())) > 0: self.logInternalError(exceptionDict) return allStylesDict @@ -348,10 +442,12 @@ def populateStylesInterface(self): tableItem = self.createItem(dbItem, table, 2) timeStamp = allStylesDict[styleName][dbName][table].toString() timeList.append(timeStamp) - tableItem.setText(3,allStylesDict[styleName][dbName][table].toString()) + tableItem.setText( + 3, allStylesDict[styleName][dbName][table].toString() + ) parentTimeList.append(max(timeList)) - dbItem.setText(3,max(timeList)) - + dbItem.setText(3, max(timeList)) + @pyqtSlot(bool) def on_deleteStyles_clicked(self): dbsDict = self.instantiateAbstractDbs() @@ -361,16 +457,18 @@ def on_deleteStyles_clicked(self): execStatus = dlg.exec_() selectedStyles = dlg.selectedStyles if execStatus != 0 and selectedStyles != []: - selectedStyleDict = { k : styleDict[k] for k in selectedStyles } + selectedStyleDict = {k: styleDict[k] for k in selectedStyles} QApplication.setOverrideCursor(QCursor(Qt.WaitCursor)) - successList, exceptionDict = self.batchDeleteStyles(dbsDict, selectedStyleDict) + successList, exceptionDict = self.batchDeleteStyles( + dbsDict, selectedStyleDict + ) QApplication.restoreOverrideCursor() - header = self.tr('Delete operation complete. \n') + header = self.tr("Delete operation complete. \n") self.outputMessage(header, successList, exceptionDict) self.populateStylesInterface() closeExceptionDict = self.closeAbstractDbs(dbsDict) - self.logInternalError(closeExceptionDict) - + self.logInternalError(closeExceptionDict) + def batchDeleteStyles(self, dbsDict, styleDict): exceptionDict = dict() successList = [] @@ -380,28 +478,32 @@ def batchDeleteStyles(self, dbsDict, styleDict): dbsDict[dbName].deleteStyle(style) successList.append(dbName) except Exception as e: - exceptionDict[dbName] = ':'.join(e.args) + exceptionDict[dbName] = ":".join(e.args) return successList, exceptionDict - + def getSQLFile(self): fd = QFileDialog() - filename = fd.getOpenFileName(caption=self.tr('Select a SQL file'),filter=self.tr('sql file (*.sql)')) + filename = fd.getOpenFileName( + caption=self.tr("Select a SQL file"), filter=self.tr("sql file (*.sql)") + ) return filename - + @pyqtSlot(bool) def on_customizeFromSQLFilePushButton_clicked(self): dbsDict = self.instantiateAbstractDbs() sqlFilePath = self.getSQLFile() - if sqlFilePath == '': + if sqlFilePath == "": return QApplication.setOverrideCursor(QCursor(Qt.WaitCursor)) - successList, exceptionDict = self.batchCustomizeFromSQLFile(dbsDict, sqlFilePath) + successList, exceptionDict = self.batchCustomizeFromSQLFile( + dbsDict, sqlFilePath + ) QApplication.restoreOverrideCursor() - header = self.tr('Customize from SQL file operation complete. \n') + header = self.tr("Customize from SQL file operation complete. \n") self.outputMessage(header, successList, exceptionDict) closeExceptionDict = self.closeAbstractDbs(dbsDict) self.logInternalError(closeExceptionDict) - + def batchCustomizeFromSQLFile(self, dbsDict, sqlFilePath): exceptionDict = dict() successList = [] @@ -410,13 +512,17 @@ def batchCustomizeFromSQLFile(self, dbsDict, sqlFilePath): dbsDict[dbName].runSqlFromFile(sqlFilePath) successList.append(dbName) except Exception as e: - exceptionDict[dbName] = ':'.join(e.args) + exceptionDict[dbName] = ":".join(e.args) return successList, exceptionDict def populateOtherInterfaces(self): dbsDict = self.instantiateAbstractDbs() if self.edgvComboFilter.currentIndex() != 0: edgvVersion = self.correspondenceDict[self.edgvComboFilter.currentText()] - self.permissionWidget.setParameters(self.serverWidget.abstractDb, dbsDict, edgvVersion) + self.permissionWidget.setParameters( + self.serverWidget.abstractDb, dbsDict, edgvVersion + ) # self.customizationManagerWidget.setParameters(self.serverWidget.abstractDb, edgvVersion, dbsDict = dbsDict) - self.earthCoverageManagerWidget.setParameters(self.serverWidget.abstractDb, edgvVersion, dbsDict = dbsDict) + self.earthCoverageManagerWidget.setParameters( + self.serverWidget.abstractDb, edgvVersion, dbsDict=dbsDict + ) diff --git a/DsgTools/gui/ServerTools/createView.py b/DsgTools/gui/ServerTools/createView.py index f78ae55a2..8320a466e 100644 --- a/DsgTools/gui/ServerTools/createView.py +++ b/DsgTools/gui/ServerTools/createView.py @@ -27,13 +27,14 @@ from qgis.PyQt.QtCore import pyqtSlot, Qt from qgis.PyQt.QtWidgets import QAbstractItemView, QApplication, QMessageBox from qgis.PyQt.QtGui import QCursor + # DSGTools imports -FORM_CLASS, _ = uic.loadUiType(os.path.join( - os.path.dirname(__file__), 'createView.ui')) +FORM_CLASS, _ = uic.loadUiType(os.path.join(os.path.dirname(__file__), "createView.ui")) + class CreateView(QtWidgets.QDialog, FORM_CLASS): - def __init__(self, abstractDb, dbName, parent = None): + def __init__(self, abstractDb, dbName, parent=None): """ Constructor """ @@ -47,22 +48,26 @@ def __init__(self, abstractDb, dbName, parent = None): self.abstractDb = abstractDb self.dBLineEdit.setText(dbName) self.dBLineEdit.setReadOnly(True) - self.viewTypeDict = {0:'VIEW',1:'MATERIALIZED VIEW'} - self.inheritanceType = {0:'FROM ONLY',1:'FROM'} - + self.viewTypeDict = {0: "VIEW", 1: "MATERIALIZED VIEW"} + self.inheritanceType = {0: "FROM ONLY", 1: "FROM"} + @pyqtSlot() def on_buttonBox_accepted(self): - ''' + """ Creates view with resolved domain values - ''' + """ createViewClause = self.viewTypeDict[self.viewTypeComboBox.currentIndex()] fromClause = self.inheritanceType[self.inheritanceTypeComboBox.currentIndex()] try: QApplication.setOverrideCursor(QCursor(Qt.WaitCursor)) self.abstractDb.createResolvedDomainViews(createViewClause, fromClause) QApplication.restoreOverrideCursor() - QMessageBox.information(self, self.tr('Success!'), self.tr('Views created successfully on database ')+self.dBLineEdit.text()) + QMessageBox.information( + self, + self.tr("Success!"), + self.tr("Views created successfully on database ") + + self.dBLineEdit.text(), + ) except Exception as e: - QApplication.restoreOverrideCursor() - QMessageBox.critical(self, self.tr('Critical!'), ':'.join(e.args)) - \ No newline at end of file + QApplication.restoreOverrideCursor() + QMessageBox.critical(self, self.tr("Critical!"), ":".join(e.args)) diff --git a/DsgTools/gui/ServerTools/exploreDb.py b/DsgTools/gui/ServerTools/exploreDb.py index f81a8f23f..2f8049656 100644 --- a/DsgTools/gui/ServerTools/exploreDb.py +++ b/DsgTools/gui/ServerTools/exploreDb.py @@ -31,16 +31,18 @@ # DSGTools imports from DsgTools.core.Utils.utils import Utils from DsgTools.core.Factories.DbFactory.dbFactory import DbFactory -from DsgTools.gui.DatabaseTools.UserTools.permission_properties import PermissionProperties +from DsgTools.gui.DatabaseTools.UserTools.permission_properties import ( + PermissionProperties, +) from DsgTools.gui.ServerTools.createView import CreateView from DsgTools.gui.ServerTools.manageDBAuxiliarStructure import ManageDBAuxiliarStructure from DsgTools.core.dsgEnums import DsgEnums -FORM_CLASS, _ = uic.loadUiType(os.path.join( - os.path.dirname(__file__), 'exploreDb.ui')) +FORM_CLASS, _ = uic.loadUiType(os.path.join(os.path.dirname(__file__), "exploreDb.ui")) + class ExploreDb(QtWidgets.QDialog, FORM_CLASS): - def __init__(self, parent = None): + def __init__(self, parent=None): """ Constructor """ @@ -55,132 +57,155 @@ def __init__(self, parent = None): self.dbFactory = DbFactory() self.localDb = None self.serverWidget.populateServersCombo() - #signal connections + # signal connections self.serverWidget.abstractDbLoaded.connect(self.checkSuperUser) self.serverWidget.clearWidgets.connect(self.clearAll) self.treeWidget.setContextMenuPolicy(Qt.CustomContextMenu) self.treeWidget.customContextMenuRequested.connect(self.createMenuAssigned) - + def populateListWithDatabasesFromServer(self): - ''' + """ Populates databases list from server - ''' + """ dbList = [] try: dbList = self.serverWidget.abstractDb.getEDGVDbsFromServer() except Exception as e: - QMessageBox.critical(self, self.tr('Critical!'), ':'.join(e.args)) + QMessageBox.critical(self, self.tr("Critical!"), ":".join(e.args)) dbList.sort() for (dbname, dbversion) in dbList: item = QListWidgetItem(self.dbListWidget) - item.setText(dbname+' (EDGV v. '+dbversion+')') + item.setText(dbname + " (EDGV v. " + dbversion + ")") item.setData(Qt.UserRole, dbname) - + @pyqtSlot(bool) def on_closePushButton_clicked(self): - ''' + """ Closes the dialog - ''' + """ self.done(0) - + def renewDb(self): - ''' + """ Renews the database - ''' + """ if self.localDb: del self.localDb self.localDb = None - + def clearAll(self): - ''' + """ Clears the database list - ''' + """ self.dbListWidget.clear() self.treeWidget.clear() self.renewDb() - + def checkSuperUser(self): - ''' + """ Checks if the user is a super user - ''' + """ try: if self.serverWidget.abstractDb.checkSuperUser(): self.populateListWithDatabasesFromServer() else: - QMessageBox.warning(self, self.tr('Info!'), self.tr('Connection refused. Connect with a super user to inspect server.')) + QMessageBox.warning( + self, + self.tr("Info!"), + self.tr( + "Connection refused. Connect with a super user to inspect server." + ), + ) except Exception as e: - QMessageBox.critical(self, self.tr('Critical!'), ':'.join(e.args)) - + QMessageBox.critical(self, self.tr("Critical!"), ":".join(e.args)) + def createItem(self, parent, text, column): - ''' + """ Creates a tree widget item - ''' + """ item = QtWidgets.QTreeWidgetItem(parent) item.setFlags(QtCore.Qt.ItemIsEnabled) item.setText(column, text) return item - + @pyqtSlot(QListWidgetItem, QListWidgetItem) def on_dbListWidget_currentItemChanged(self, current, previous): - ''' + """ Updates the information related with the database (e.g. users and roles for instance) - ''' + """ self.treeWidget.clear() if not current: return self.localDb = self.dbFactory.createDbFactory(DsgEnums.DriverPostGIS) originalCon = self.serverWidget.abstractDb.makeOgrConn() - self.localDb.connectDatabaseWithParameters(self.serverWidget.abstractDb.db.hostName(), self.serverWidget.abstractDb.db.port(), current.text().split(' ')[0], self.serverWidget.abstractDb.db.userName(), self.serverWidget.abstractDb.db.password()) + self.localDb.connectDatabaseWithParameters( + self.serverWidget.abstractDb.db.hostName(), + self.serverWidget.abstractDb.db.port(), + current.text().split(" ")[0], + self.serverWidget.abstractDb.db.userName(), + self.serverWidget.abstractDb.db.password(), + ) candidateUserList = [] try: candidateUserList = self.localDb.getUsers() except Exception as e: - QMessageBox.critical(self, self.tr('Critical!'), ':'.join(e.args)) + QMessageBox.critical(self, self.tr("Critical!"), ":".join(e.args)) for candidate in candidateUserList: - installed,assigned = self.localDb.getUserRelatedRoles(candidate) - if len(assigned)>0: - userItem = self.createItem(self.treeWidget.invisibleRootItem(), candidate,0) + installed, assigned = self.localDb.getUserRelatedRoles(candidate) + if len(assigned) > 0: + userItem = self.createItem( + self.treeWidget.invisibleRootItem(), candidate, 0 + ) for perm in assigned: - self.createItem(userItem, perm,1) - + self.createItem(userItem, perm, 1) + def createMenuAssigned(self, position): - ''' + """ Creates a pop up menu - ''' + """ menu = QMenu() item = self.treeWidget.itemAt(position) if item: - menu.addAction(self.tr('Show properties'), self.showAssignedProperties) + menu.addAction(self.tr("Show properties"), self.showAssignedProperties) menu.exec_(self.treeWidget.viewport().mapToGlobal(position)) - + def showAssignedProperties(self): - ''' - Shows information about the selected permissions model - ''' + """ + Shows information about the selected permissions model + """ permission = self.treeWidget.currentItem().text(1) - dbname = self.dbListWidget.currentItem().text().split(' ')[0] + dbname = self.dbListWidget.currentItem().text().split(" ")[0] permissionsDict = dict() try: permissionsDict = self.localDb.getRolePrivileges(permission, dbname) except Exception as e: - QMessageBox.critical(self, self.tr('Critical!'), ':'.join(e.args)) + QMessageBox.critical(self, self.tr("Critical!"), ":".join(e.args)) dlg = PermissionProperties(permissionsDict) dlg.exec_() - + @pyqtSlot(bool) def on_dropDatabasePushButton_clicked(self): - ''' + """ Drops a database and updates QSettings - ''' + """ currentItem = self.dbListWidget.currentItem() if not currentItem: return - if QMessageBox.question(self, self.tr('Question'), self.tr('Do you really want to drop database: ')+currentItem.text().split(' ')[0], QMessageBox.Ok|QMessageBox.Cancel) == QMessageBox.Cancel: + if ( + QMessageBox.question( + self, + self.tr("Question"), + self.tr("Do you really want to drop database: ") + + currentItem.text().split(" ")[0], + QMessageBox.Ok | QMessageBox.Cancel, + ) + == QMessageBox.Cancel + ): return QApplication.setOverrideCursor(QCursor(Qt.WaitCursor)) localDbName = self.localDb.getDatabaseName() @@ -188,44 +213,54 @@ def on_dropDatabasePushButton_clicked(self): try: self.serverWidget.abstractDb.dropDatabase(localDbName) QApplication.restoreOverrideCursor() - QMessageBox.warning(self, self.tr('Success!'), self.tr('Database ')+localDbName+self.tr(' dropped successfully!')) + QMessageBox.warning( + self, + self.tr("Success!"), + self.tr("Database ") + localDbName + self.tr(" dropped successfully!"), + ) self.clearQSettings(localDbName) except Exception as e: - QApplication.restoreOverrideCursor() - QMessageBox.critical(self, self.tr('Critical!'), ':'.join(e.args)) + QApplication.restoreOverrideCursor() + QMessageBox.critical(self, self.tr("Critical!"), ":".join(e.args)) self.clearAll() self.populateListWithDatabasesFromServer() @pyqtSlot(bool) def on_createViewsPushButton_clicked(self): - ''' + """ Creates view button - ''' + """ if not self.localDb: - QMessageBox.critical(self, self.tr('Critical!'), self.tr('Select a database to create view')) + QMessageBox.critical( + self, self.tr("Critical!"), self.tr("Select a database to create view") + ) return - dlg = CreateView(self.localDb,self.dbListWidget.currentItem().text()) + dlg = CreateView(self.localDb, self.dbListWidget.currentItem().text()) dlg.exec_() pass - - def clearQSettings(self,database): - ''' + + def clearQSettings(self, database): + """ Clear the database from QSettings - ''' - name = self.serverWidget.serversCombo.currentText()+'_'+database + """ + name = self.serverWidget.serversCombo.currentText() + "_" + database settings = QSettings() - settings.beginGroup('PostgreSQL/connections/'+name) - settings.remove('') + settings.beginGroup("PostgreSQL/connections/" + name) + settings.remove("") settings.endGroup() - + @pyqtSlot(bool) def on_manageAuxStructPushButton_clicked(self): - ''' + """ Opens the dialog to manage database auxiliar structure - ''' + """ if not self.localDb: - QMessageBox.critical(self, self.tr('Critical!'), self.tr('Select a database to manage auxiliar structure')) + QMessageBox.critical( + self, + self.tr("Critical!"), + self.tr("Select a database to manage auxiliar structure"), + ) return dlg = ManageDBAuxiliarStructure(self.localDb) dlg.exec_() - pass + pass diff --git a/DsgTools/gui/ServerTools/manageDBAuxiliarStructure.py b/DsgTools/gui/ServerTools/manageDBAuxiliarStructure.py index 00238129a..a9a8d7a87 100644 --- a/DsgTools/gui/ServerTools/manageDBAuxiliarStructure.py +++ b/DsgTools/gui/ServerTools/manageDBAuxiliarStructure.py @@ -31,14 +31,18 @@ # DSGTools imports from DsgTools.core.Utils.utils import Utils from DsgTools.core.Factories.DbFactory.dbFactory import DbFactory -from DsgTools.gui.DatabaseTools.UserTools.permission_properties import PermissionProperties +from DsgTools.gui.DatabaseTools.UserTools.permission_properties import ( + PermissionProperties, +) from DsgTools.gui.ServerTools.createView import CreateView -FORM_CLASS, _ = uic.loadUiType(os.path.join( - os.path.dirname(__file__), 'manageDBAuxiliarStructure.ui')) +FORM_CLASS, _ = uic.loadUiType( + os.path.join(os.path.dirname(__file__), "manageDBAuxiliarStructure.ui") +) + class ManageDBAuxiliarStructure(QtWidgets.QDialog, FORM_CLASS): - def __init__(self, abstractDb, parent = None): + def __init__(self, abstractDb, parent=None): """Constructor.""" super(self.__class__, self).__init__(parent) # Set up the user interface from Designer. @@ -52,4 +56,3 @@ def __init__(self, abstractDb, parent = None): @pyqtSlot(bool) def on_closePushButton_clicked(self): self.done(0) - \ No newline at end of file diff --git a/DsgTools/gui/ServerTools/selectStyles.py b/DsgTools/gui/ServerTools/selectStyles.py index 5d5b22017..9a78df3f3 100644 --- a/DsgTools/gui/ServerTools/selectStyles.py +++ b/DsgTools/gui/ServerTools/selectStyles.py @@ -28,7 +28,13 @@ # Qt imports from qgis.PyQt import QtWidgets, uic from qgis.PyQt.QtCore import pyqtSlot, Qt, QSettings -from qgis.PyQt.QtWidgets import QListWidgetItem, QMessageBox, QMenu, QApplication, QFileDialog +from qgis.PyQt.QtWidgets import ( + QListWidgetItem, + QMessageBox, + QMenu, + QApplication, + QFileDialog, +) from qgis.PyQt.QtGui import QCursor from qgis.PyQt.QtSql import QSqlDatabase, QSqlQuery @@ -37,17 +43,20 @@ from DsgTools.core.Factories.SqlFactory.sqlGeneratorFactory import SqlGeneratorFactory from DsgTools.gui.ServerTools.viewServers import ViewServers from DsgTools.core.Factories.DbFactory.dbFactory import DbFactory -from DsgTools.gui.DatabaseTools.UserTools.permission_properties import PermissionProperties +from DsgTools.gui.DatabaseTools.UserTools.permission_properties import ( + PermissionProperties, +) from DsgTools.gui.ServerTools.createView import CreateView from DsgTools.gui.ServerTools.manageDBAuxiliarStructure import ManageDBAuxiliarStructure -FORM_CLASS, _ = uic.loadUiType(os.path.join( - os.path.dirname(__file__), 'selectStyles.ui')) +FORM_CLASS, _ = uic.loadUiType( + os.path.join(os.path.dirname(__file__), "selectStyles.ui") +) + class SelectStyles(QtWidgets.QDialog, FORM_CLASS): - - def __init__(self, styleList, parent = None): + def __init__(self, styleList, parent=None): """Constructor.""" super(self.__class__, self).__init__(parent) # Set up the user interface from Designer. @@ -57,11 +66,13 @@ def __init__(self, styleList, parent = None): # #widgets-and-dialogs-with-auto-connect self.setupUi(self) self.customSelector.setInitialState(styleList) - self.customSelector.setTitle(self.tr('Select Styles')) + self.customSelector.setTitle(self.tr("Select Styles")) self.selectedStyles = [] @pyqtSlot() def on_buttonBox_accepted(self): self.selectedStyles = self.customSelector.toLs if len(self.selectedStyles) == 0: - QMessageBox.warning(self, self.tr('Warning'), self.tr('Select at least one style!')) \ No newline at end of file + QMessageBox.warning( + self, self.tr("Warning"), self.tr("Select at least one style!") + ) diff --git a/DsgTools/gui/ServerTools/serverConfigurator.py b/DsgTools/gui/ServerTools/serverConfigurator.py index 648ddcf71..7ab07fd8e 100644 --- a/DsgTools/gui/ServerTools/serverConfigurator.py +++ b/DsgTools/gui/ServerTools/serverConfigurator.py @@ -25,8 +25,10 @@ from qgis.PyQt import uic import os -FORM_CLASS, _ = uic.loadUiType(os.path.join( - os.path.dirname(__file__), 'ui_serverConfigurator.ui')) +FORM_CLASS, _ = uic.loadUiType( + os.path.join(os.path.dirname(__file__), "ui_serverConfigurator.ui") +) + class ServerConfigurator(QDialog, FORM_CLASS): def __init__(self, iface): @@ -43,15 +45,15 @@ def __init__(self, iface): self.iface = iface self.isEdit = 0 - self.oldName='' + self.oldName = "" self.passwordEdit.setEchoMode(QLineEdit.Password) @pyqtSlot(bool) def on_saveButton_clicked(self): - ''' + """ Saves a new server - ''' + """ if self.checkFields(): name = self.servEdit.text() host = self.hostEdit.text() @@ -63,66 +65,82 @@ def on_saveButton_clicked(self): QMessageBox.warning(self, self.tr("Info!"), self.tr("Server stored.")) self.done(1) else: - QMessageBox.warning(self, self.tr("Warning!"), self.tr("Fill all parameters.")) + QMessageBox.warning( + self, self.tr("Warning!"), self.tr("Fill all parameters.") + ) @pyqtSlot(bool) def on_cancelButton_clicked(self): - ''' + """ Cancel everything - ''' + """ self.done(0) def checkFields(self): - ''' + """ Checks if the fields are filled - ''' - if self.hostEdit.text() == '' or self.portEdit.text() == '' or self.userEdit.text() == '': + """ + if ( + self.hostEdit.text() == "" + or self.portEdit.text() == "" + or self.userEdit.text() == "" + ): return False return True - def storeServerConfiguration(self, name, host, port, user, password, isDefault = False): - ''' + def storeServerConfiguration( + self, name, host, port, user, password, isDefault=False + ): + """ Stores server configuration in QSettings - ''' - if '_' in name: - QMessageBox.warning(self, self.tr("Warning!"), self.tr("Server name cannot contain the character \"_\".")) - self.servEdit.setStyleSheet('background-color: rgb(255, 150, 150)') + """ + if "_" in name: + QMessageBox.warning( + self, + self.tr("Warning!"), + self.tr('Server name cannot contain the character "_".'), + ) + self.servEdit.setStyleSheet("background-color: rgb(255, 150, 150)") return 0 - + settings = QSettings() if self.isEdit: - settings.beginGroup('PostgreSQL/servers/'+self.oldName) - settings.remove('') + settings.beginGroup("PostgreSQL/servers/" + self.oldName) + settings.remove("") settings.endGroup() else: - if settings.contains('PostgreSQL/servers/'+name+'/host'): - QMessageBox.warning(self, self.tr("Warning!"), self.tr("Already has a server with this name.")) - self.servEdit.setStyleSheet('background-color: rgb(255, 150, 150)') + if settings.contains("PostgreSQL/servers/" + name + "/host"): + QMessageBox.warning( + self, + self.tr("Warning!"), + self.tr("Already has a server with this name."), + ) + self.servEdit.setStyleSheet("background-color: rgb(255, 150, 150)") return 0 - settings.beginGroup('PostgreSQL/servers/'+name) - settings.setValue('host', host) - settings.setValue('port', port) - settings.setValue('username', user) - settings.setValue('password', password) + settings.beginGroup("PostgreSQL/servers/" + name) + settings.setValue("host", host) + settings.setValue("port", port) + settings.setValue("username", user) + settings.setValue("password", password) if isDefault: - settings.setValue('isDefault', True) + settings.setValue("isDefault", True) else: - settings.setValue('isDefault', False) + settings.setValue("isDefault", False) settings.endGroup() return 1 def setServerConfiguration(self, name): - ''' + """ Sets server confogiration by its name - ''' + """ self.isEdit = 1 - self.oldName=name + self.oldName = name settings = QSettings() - settings.beginGroup('PostgreSQL/servers/'+name) - host = settings.value('host') - port = settings.value('port') - user = settings.value('username') - password = settings.value('password') + settings.beginGroup("PostgreSQL/servers/" + name) + host = settings.value("host") + port = settings.value("port") + user = settings.value("username") + password = settings.value("password") settings.endGroup() self.servEdit.setText(name) diff --git a/DsgTools/gui/ServerTools/serverDBExplorer.py b/DsgTools/gui/ServerTools/serverDBExplorer.py index c528c2a9f..fa14a19e7 100644 --- a/DsgTools/gui/ServerTools/serverDBExplorer.py +++ b/DsgTools/gui/ServerTools/serverDBExplorer.py @@ -37,12 +37,13 @@ from DsgTools.gui.ServerTools.viewServers import ViewServers from DsgTools.core.dsgEnums import DsgEnums -FORM_CLASS, _ = uic.loadUiType(os.path.join( - os.path.dirname(__file__), 'ui_serverDBExplorer.ui')) +FORM_CLASS, _ = uic.loadUiType( + os.path.join(os.path.dirname(__file__), "ui_serverDBExplorer.ui") +) + class ServerDBExplorer(QtWidgets.QDialog, FORM_CLASS): - - def __init__(self, parent = None): + def __init__(self, parent=None): """Constructor.""" super(self.__class__, self).__init__(parent) # Set up the user interface from Designer. @@ -53,124 +54,130 @@ def __init__(self, parent = None): self.setupUi(self) self.utils = Utils() self.factory = SqlGeneratorFactory() - #setting the sql generator + # setting the sql generator self.gen = self.factory.createSqlGenerator(driver=DsgEnums.DriverPostGIS) self.serverWidget.populateServersCombo() - self.serverWidget.abstractDbLoaded.connect(self.populateListWithDatabasesFromServer) - + self.serverWidget.abstractDbLoaded.connect( + self.populateListWithDatabasesFromServer + ) + def storeConnection(self, server, database): - ''' + """ Stores database connection in the QSettings - ''' + """ (host, port, user, password) = self.getServerConfiguration(server) - connection = server+'_'+database + connection = server + "_" + database settings = QSettings() - if not settings.contains('PostgreSQL/connections/'+connection+'/database'): - settings.beginGroup('PostgreSQL/connections/'+connection) - settings.setValue('database', database) - settings.setValue('host', host) - settings.setValue('port', port) - settings.setValue('username', user) - settings.setValue('password', password) + if not settings.contains("PostgreSQL/connections/" + connection + "/database"): + settings.beginGroup("PostgreSQL/connections/" + connection) + settings.setValue("database", database) + settings.setValue("host", host) + settings.setValue("port", port) + settings.setValue("username", user) + settings.setValue("password", password) settings.endGroup() return True return False def getServerConfiguration(self, name): - ''' + """ Gets server configuration from QSetting by its name - ''' + """ settings = QSettings() - settings.beginGroup('PostgreSQL/servers/'+name) - host = settings.value('host') - port = settings.value('port') - user = settings.value('username') - password = settings.value('password') + settings.beginGroup("PostgreSQL/servers/" + name) + host = settings.value("host") + port = settings.value("port") + user = settings.value("username") + password = settings.value("password") settings.endGroup() return (host, port, user, password) def storeConnectionConfiguration(self, server, database): - ''' + """ Stores connection configuration in thw QSettings server: server name database: database name - ''' + """ name = self.connectionEdit.text() - + (host, port, user, password) = self.getServerConfiguration(server) settings = QSettings() - if not settings.contains('PostgreSQL/servers/'+name+'/host'): - settings.beginGroup('PostgreSQL/connections/'+name) - settings.setValue('database', database) - settings.setValue('host', host) - settings.setValue('port', port) - settings.setValue('username', user) - settings.setValue('password', password) + if not settings.contains("PostgreSQL/servers/" + name + "/host"): + settings.beginGroup("PostgreSQL/connections/" + name) + settings.setValue("database", database) + settings.setValue("host", host) + settings.setValue("port", port) + settings.setValue("username", user) + settings.setValue("password", password) settings.endGroup() - + def populateListWithDatabasesFromServer(self): - ''' + """ Populates databases from server - ''' + """ self.serverListWidget.clear() dbList = [] try: dbList = self.serverWidget.abstractDb.getEDGVDbsFromServer() except Exception as e: - QMessageBox.critical(self, self.tr('Critical!'), ':'.join(e.args)) + QMessageBox.critical(self, self.tr("Critical!"), ":".join(e.args)) dbList.sort() for (dbname, dbversion) in dbList: - item = QListWidgetItem(self.serverListWidget) - item.setText(dbname+' (EDGV v. '+dbversion+')') + item = QListWidgetItem(self.serverListWidget) + item.setText(dbname + " (EDGV v. " + dbversion + ")") item.setData(Qt.UserRole, dbname) - + @pyqtSlot(bool) def on_createConnectionPushButton_clicked(self): - ''' + """ Creates a connection with the selected databases - ''' + """ items = self.serverListWidget.selectedItems() existentConnections = [] newConnections = [] for item in items: dbname = item.data(Qt.UserRole) - ret = self.storeConnection(self.serverWidget.serversCombo.currentText(), dbname) + ret = self.storeConnection( + self.serverWidget.serversCombo.currentText(), dbname + ) if not ret: existentConnections.append(dbname) else: newConnections.append(dbname) - - msg = self.tr('Information:\n') + + msg = self.tr("Information:\n") if len(existentConnections) > 0: - msg += self.tr('The following databases connections already exist:\n') + msg += self.tr("The following databases connections already exist:\n") for conn in existentConnections: - msg += conn + ', ' + msg += conn + ", " if len(newConnections) > 0: - msg += self.tr('\nThe following databases connections were created successfully:\n') + msg += self.tr( + "\nThe following databases connections were created successfully:\n" + ) for conn in newConnections: - msg += conn+', ' + msg += conn + ", " QMessageBox.warning(self, self.tr("Warning!"), msg) - + @pyqtSlot(bool) def on_selectAllPushButton_clicked(self): - ''' + """ Select all databases on server to create connection - ''' + """ count = self.serverListWidget.count() for row in range(count): item = self.serverListWidget.item(row) - item.setSelected(True) + item.setSelected(True) @pyqtSlot(bool) def on_removeMissingPushButton_clicked(self): - ''' + """ Remove missing databases from QSetttings - ''' + """ servers = self.serverWidget.getServers() settings = QSettings() - settings.beginGroup('PostgreSQL/connections') + settings.beginGroup("PostgreSQL/connections") candidates = settings.childGroups() settings.endGroup() removedConn = [] @@ -178,26 +185,28 @@ def on_removeMissingPushButton_clicked(self): try: dbList = self.serverWidget.abstractDb.getDbsFromServer() except Exception as e: - QMessageBox.critical(self, self.tr('Critical!'), ':'.join(e.args)) + QMessageBox.critical(self, self.tr("Critical!"), ":".join(e.args)) for candidate in candidates: candidateSettings = QSettings() - candidateSettings.beginGroup('PostgreSQL/connections/'+candidate) - candidateDb = candidateSettings.value('database') + candidateSettings.beginGroup("PostgreSQL/connections/" + candidate) + candidateDb = candidateSettings.value("database") if candidateDb not in dbList: self.removeConnections(candidate, removedConn) - if len(removedConn)>0: - msg = self.tr('\nThe following databases connections were removed successfully:\n')+', '.join(removedConn) + if len(removedConn) > 0: + msg = self.tr( + "\nThe following databases connections were removed successfully:\n" + ) + ", ".join(removedConn) else: - msg = self.tr('No connections were removed.') + msg = self.tr("No connections were removed.") QMessageBox.warning(self, self.tr("Warning!"), msg) - - def removeConnections(self,candidate,removedConn): - ''' + + def removeConnections(self, candidate, removedConn): + """ Remove a specific connection from QSettings - ''' + """ candidateSettings = QSettings() - candidateSettings.beginGroup('PostgreSQL/connections/'+candidate) - candidateSettings.remove('') + candidateSettings.beginGroup("PostgreSQL/connections/" + candidate) + candidateSettings.remove("") removedConn.append(candidate) - candidateSettings.endGroup() \ No newline at end of file + candidateSettings.endGroup() diff --git a/DsgTools/gui/ServerTools/serverToolsGuiManager.py b/DsgTools/gui/ServerTools/serverToolsGuiManager.py index 42a6584b4..75711d450 100644 --- a/DsgTools/gui/ServerTools/serverToolsGuiManager.py +++ b/DsgTools/gui/ServerTools/serverToolsGuiManager.py @@ -24,10 +24,12 @@ from qgis.PyQt.QtCore import QObject from DsgTools.gui.ServerTools.ViewServersGui.viewServersGui import ViewServersGui -from DsgTools.gui.ServerTools.BatchDbManagerGui.batchDbManagerGui import BatchDbManagerGui +from DsgTools.gui.ServerTools.BatchDbManagerGui.batchDbManagerGui import ( + BatchDbManagerGui, +) -class ServerToolsGuiManager(QObject): +class ServerToolsGuiManager(QObject): def __init__(self, manager, iface, parentMenu=None, toolbar=None): """Constructor. :param iface: An interface instance that will be passed to this class @@ -42,9 +44,11 @@ def __init__(self, manager, iface, parentMenu=None, toolbar=None): self.parentMenu = parentMenu # self.dbAbstract = dbAbstract self.toolbar = toolbar - self.menu = self.manager.addMenu(u'server', self.tr('Servers Tools'),'server.png') - self.iconBasePath = ':/plugins/DsgTools/icons/' - + self.menu = self.manager.addMenu( + "server", self.tr("Servers Tools"), "server.png" + ) + self.iconBasePath = ":/plugins/DsgTools/icons/" + def addTool(self, text, callback, parentMenu, icon): """ Prepares the funcionalities to be added to both the DSGTools menu and it's shortcut button into QGIS main interface. @@ -62,12 +66,12 @@ def addTool(self, text, callback, parentMenu, icon): add_to_toolbar=False, withShortcut=False, parentToolbar=parentMenu, - isCheckable=False + isCheckable=False, ) def initGui(self): """ - Instantiates all available database creation GUI. + Instantiates all available database creation GUI. """ self.viewServersGui = ViewServersGui(manager=self, parentMenu=self.menu) self.viewServersGui.initGui() diff --git a/DsgTools/gui/ServerTools/viewServers.py b/DsgTools/gui/ServerTools/viewServers.py index a0cfe9f30..b4777487d 100644 --- a/DsgTools/gui/ServerTools/viewServers.py +++ b/DsgTools/gui/ServerTools/viewServers.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -''' +""" /*************************************************************************** DsgTools A QGIS plugin @@ -19,13 +19,19 @@ * (at your option) any later version. * * * ***************************************************************************/ -''' +""" from __future__ import absolute_import import os from qgis.PyQt import QtWidgets, uic from qgis.PyQt.QtCore import pyqtSlot, QSettings, pyqtSignal, Qt -from qgis.PyQt.QtWidgets import QHeaderView, QTableWidgetItem, QMessageBox, QApplication, QRadioButton +from qgis.PyQt.QtWidgets import ( + QHeaderView, + QTableWidgetItem, + QMessageBox, + QApplication, + QRadioButton, +) from qgis.PyQt.QtGui import QCursor from qgis.PyQt.QtSql import QSqlDatabase from .serverConfigurator import ServerConfigurator @@ -35,113 +41,129 @@ from ...core.Factories.DbFactory.dbFactory import DbFactory from DsgTools.core.dsgEnums import DsgEnums -FORM_CLASS, _ = uic.loadUiType(os.path.join( - os.path.dirname(__file__), 'ui_viewServers.ui')) +FORM_CLASS, _ = uic.loadUiType( + os.path.join(os.path.dirname(__file__), "ui_viewServers.ui") +) + class ViewServers(QtWidgets.QDialog, FORM_CLASS): defaultChanged = pyqtSignal() - def __init__(self, iface = None, parent=None): - '''Constructor.''' + + def __init__(self, iface=None, parent=None): + """Constructor.""" super(ViewServers, self).__init__(parent) self.setupUi(self) self.abstractDbFactory = DbFactory() self.initGui() connection, host, port, user, password = self.getDefaultConnectionParameters() - self.defaultConnectionDict = self.setDefaultConnectionParameters(connection, host, port, user, password) - + self.defaultConnectionDict = self.setDefaultConnectionParameters( + connection, host, port, user, password + ) + def initGui(self): - ''' + """ Initiates the dialog - ''' + """ header = self.tableWidget.horizontalHeader() header.setSectionResizeMode(QHeaderView.Stretch) self.populateTable() - + def populateTable(self): - ''' + """ Populates the servers table - ''' + """ currentConnections = self.getServers() self.tableWidget.setRowCount(len(currentConnections)) for i, connection in enumerate(currentConnections): self.tableWidget.setItem(i, 0, QTableWidgetItem(connection)) - (host, port, user, password, isDefault) = self.getServerConfiguration(connection) + (host, port, user, password, isDefault) = self.getServerConfiguration( + connection + ) self.tableWidget.setItem(i, 1, QTableWidgetItem(host)) self.tableWidget.setItem(i, 2, QTableWidgetItem(port)) self.tableWidget.setItem(i, 3, QTableWidgetItem(user)) if not password or len(password) == 0: - self.tableWidget.setItem(i, 4, QTableWidgetItem(self.tr('Not Saved'))) + self.tableWidget.setItem(i, 4, QTableWidgetItem(self.tr("Not Saved"))) else: - self.tableWidget.setItem(i, 4, QTableWidgetItem(self.tr('Saved'))) + self.tableWidget.setItem(i, 4, QTableWidgetItem(self.tr("Saved"))) radio = QRadioButton(self.tableWidget) radio.setAutoExclusive(True) if isDefault: radio.setChecked(True) self.tableWidget.setCellWidget(i, 5, radio) - + def setDefaultConnectionParameters(self, connection, host, port, user, password): defaultConnectionDict = dict() if host and port and user and password: - defaultConnectionDict['host'] = host - defaultConnectionDict['port'] = port - defaultConnectionDict['user'] = user - defaultConnectionDict['password'] = password + defaultConnectionDict["host"] = host + defaultConnectionDict["port"] = port + defaultConnectionDict["user"] = user + defaultConnectionDict["password"] = password # set all connection on QSettings to not default and this connetion to default settings = QSettings() - settings.beginGroup('PostgreSQL/servers') + settings.beginGroup("PostgreSQL/servers") connections = settings.childGroups() settings.endGroup() for conn in connections: - settings.beginGroup('PostgreSQL/servers/{0}'.format(conn)) - settings.setValue('isDefault', conn == connection) + settings.beginGroup("PostgreSQL/servers/{0}".format(conn)) + settings.setValue("isDefault", conn == connection) settings.endGroup() else: defaultConnectionDict = dict() return defaultConnectionDict - + def getDefaultConnectionParameters(self): currentConnections = self.getServers() for i, connection in enumerate(currentConnections): - (host, port, user, password, isDefault) = self.getServerConfiguration(connection) - if isDefault == True or isDefault == u'true': + (host, port, user, password, isDefault) = self.getServerConfiguration( + connection + ) + if isDefault == True or isDefault == "true": return (connection, host, port, user, password) return (None, None, None, None, None) - @pyqtSlot(bool) def on_closeButton_clicked(self): - ''' + """ Closes the dialog if default connection is set - ''' + """ currentConnections = self.getServers() self.tableWidget.setRowCount(len(currentConnections)) for i, connection in enumerate(currentConnections): if self.tableWidget.cellWidget(i, 5).isChecked(): - (host, port, user, password, isDefault) = self.getServerConfiguration(connection) + (host, port, user, password, isDefault) = self.getServerConfiguration( + connection + ) dlg = ServerConfigurator(self) dlg.setServerConfiguration(connection) - dlg.storeServerConfiguration(connection, host, port, user, password, isDefault = True) - self.defaultConnectionDict = self.setDefaultConnectionParameters(connection, host, port, user, password) + dlg.storeServerConfiguration( + connection, host, port, user, password, isDefault=True + ) + self.defaultConnectionDict = self.setDefaultConnectionParameters( + connection, host, port, user, password + ) self.defaultChanged.emit() self.done(0) return - QMessageBox.warning(self, self.tr('Info!'), self.tr('Set default connection before closing!')) - + QMessageBox.warning( + self, self.tr("Info!"), self.tr("Set default connection before closing!") + ) + @pyqtSlot(bool) def on_addButton_clicked(self): - ''' + """ Adds a new server - ''' + """ dlg = ServerConfigurator(self) result = dlg.exec_() if result: self.populateTable() - + @pyqtSlot(bool) def on_editButton_clicked(self): - ''' + """ Edits an existing server - ''' + """ selectedItem = self.returnSelectedName() if not selectedItem: return @@ -150,24 +172,24 @@ def on_editButton_clicked(self): result = dlg.exec_() if result: self.populateTable() - + @pyqtSlot(bool) def on_removeButton_clicked(self): - ''' + """ Removes an existing server - ''' + """ selectedItem = self.returnSelectedName() if not selectedItem: return self.removeServerConfiguration(selectedItem.text()) self.tableWidget.removeRow(selectedItem.row()) - QMessageBox.warning(self, self.tr('Info!'), self.tr('Server removed.')) - + QMessageBox.warning(self, self.tr("Info!"), self.tr("Server removed.")) + @pyqtSlot(bool) def on_testButton_clicked(self): - ''' + """ Tests server connection - ''' + """ selectedItem = self.returnSelectedName() if not selectedItem: return @@ -176,75 +198,95 @@ def on_testButton_clicked(self): QApplication.setOverrideCursor(QCursor(Qt.WaitCursor)) test = self.testServer(name) if test: - QMessageBox.warning(self, self.tr('Info!'), self.tr('Connection online.')) + QMessageBox.warning( + self, self.tr("Info!"), self.tr("Connection online.") + ) else: - QMessageBox.warning(self, self.tr('Info!'), self.tr('Connection was not successful. Check log for details.')) + QMessageBox.warning( + self, + self.tr("Info!"), + self.tr("Connection was not successful. Check log for details."), + ) QApplication.restoreOverrideCursor() except: QApplication.restoreOverrideCursor() - QMessageBox.warning(self, self.tr('Info!'), self.tr('Connection was not successful. Check log for details.')) - + QMessageBox.warning( + self, + self.tr("Info!"), + self.tr("Connection was not successful. Check log for details."), + ) + def getServers(self): - ''' + """ Gets all server from QSettings - ''' + """ settings = QSettings() - settings.beginGroup('PostgreSQL/servers') + settings.beginGroup("PostgreSQL/servers") currentConnections = settings.childGroups() settings.endGroup() return currentConnections - + def getServerConfiguration(self, name): - ''' + """ Gets server configuration - name: server name - ''' + name: server name + """ settings = QSettings() - settings.beginGroup('PostgreSQL/servers/'+name) - host = settings.value('host') - port = settings.value('port') - user = settings.value('username') - password = settings.value('password') - isDefault = settings.value('isDefault') + settings.beginGroup("PostgreSQL/servers/" + name) + host = settings.value("host") + port = settings.value("port") + user = settings.value("username") + password = settings.value("password") + isDefault = settings.value("isDefault") settings.endGroup() - + return (host, port, user, password, isDefault) - + def removeServerConfiguration(self, name): - ''' + """ Removes a server from QSettings - ''' + """ settings = QSettings() - settings.beginGroup('PostgreSQL/servers/'+name) - settings.remove('') + settings.beginGroup("PostgreSQL/servers/" + name) + settings.remove("") settings.endGroup() - + def testServer(self, name): - ''' + """ Tests if the server is online - ''' + """ abstractDb = self.abstractDbFactory.createDbFactory(DsgEnums.DriverPostGIS) if not abstractDb: - QMessageBox.critical(self, self.tr('Critical!'), self.tr('A problem occurred! Check log for details.')) + QMessageBox.critical( + self, + self.tr("Critical!"), + self.tr("A problem occurred! Check log for details."), + ) return False (host, port, user, password) = abstractDb.getServerConfiguration(name) - abstractDb.connectDatabaseWithParameters(host, port, 'postgres', user, password) + abstractDb.connectDatabaseWithParameters(host, port, "postgres", user, password) try: abstractDb.checkAndOpenDb() abstractDb.closeDatabase() return True except Exception as e: - QMessageBox.critical(self, self.tr('Critical!'), self.tr('A problem occurred! Check log for details.')) - QgsMessageLog.logMessage(':'.join(e.args), 'DSGTools Plugin', Qgis.Critical) + QMessageBox.critical( + self, + self.tr("Critical!"), + self.tr("A problem occurred! Check log for details."), + ) + QgsMessageLog.logMessage(":".join(e.args), "DSGTools Plugin", Qgis.Critical) abstractDb.closeDatabase() return False - + def returnSelectedName(self): - ''' - Gets the selected server name - ''' + """ + Gets the selected server name + """ if len(self.tableWidget.selectedItems()) == 0: - QMessageBox.warning(self, self.tr('Warning!'), self.tr('Select one server.')) + QMessageBox.warning( + self, self.tr("Warning!"), self.tr("Select one server.") + ) return return self.tableWidget.selectedItems()[0] @@ -255,11 +297,13 @@ def connectionParameters(self): """ return self.defaultConnectionDict + class ViewServersStatic(ViewServers): """ Class desgined to select servers' configs statically. Selections using this widget will not affect default behaviour. """ + def __init__(self, iface=None, parent=None): """ Class constructor. @@ -274,14 +318,16 @@ def renameColumnHeaders(self): """ Sets column headers to match the case of static server selection. """ - self.tableWidget.setHorizontalHeaderLabels([ - self.tr("Server Name"), - self.tr("Address"), - self.tr("Port"), - self.tr("User"), - self.tr("Password"), - self.tr("Selected") - ]) + self.tableWidget.setHorizontalHeaderLabels( + [ + self.tr("Server Name"), + self.tr("Address"), + self.tr("Port"), + self.tr("User"), + self.tr("Password"), + self.tr("Selected"), + ] + ) # header = self.tableWidget.horizontalHeader() # header.setSectionResizeMode(header.ResizeToContents) # header.setSectionResizeMode(header.Interactive) @@ -295,17 +341,21 @@ def populateTable(self): connParam = self.connectionParameters() for i, connection in enumerate(currentConnections): self.tableWidget.setItem(i, 0, QTableWidgetItem(connection)) - (host, port, user, password, isDefault) = self.getServerConfiguration(connection) + (host, port, user, password, isDefault) = self.getServerConfiguration( + connection + ) self.tableWidget.setItem(i, 1, QTableWidgetItem(host)) self.tableWidget.setItem(i, 2, QTableWidgetItem(port)) self.tableWidget.setItem(i, 3, QTableWidgetItem(user)) if not password or len(password) == 0: - self.tableWidget.setItem(i, 4, QTableWidgetItem(self.tr('Not Saved'))) + self.tableWidget.setItem(i, 4, QTableWidgetItem(self.tr("Not Saved"))) else: - self.tableWidget.setItem(i, 4, QTableWidgetItem(self.tr('Saved'))) + self.tableWidget.setItem(i, 4, QTableWidgetItem(self.tr("Saved"))) radio = QRadioButton(self.tableWidget) radio.setAutoExclusive(True) - if (not connParam and isDefault) or (connParam and connParam['connection'] == connection): + if (not connParam and isDefault) or ( + connParam and connParam["connection"] == connection + ): radio.setChecked(True) self.tableWidget.setCellWidget(i, 5, radio) @@ -318,16 +368,18 @@ def on_closeButton_clicked(self): if self.tableWidget.cellWidget(i, 5).isChecked(): host, port, user, password, _ = self.getServerConfiguration(connection) self._connParameters = { - 'connection' : self.tableWidget.item(i, 0).text(), - 'host' : self.tableWidget.item(i, 1).text(), - 'port' : self.tableWidget.item(i, 2).text(), - 'user' : self.tableWidget.item(i, 3).text(), - 'password' : password + "connection": self.tableWidget.item(i, 0).text(), + "host": self.tableWidget.item(i, 1).text(), + "port": self.tableWidget.item(i, 2).text(), + "user": self.tableWidget.item(i, 3).text(), + "password": password, } self.defaultChanged.emit() self.done(0) return - QMessageBox.warning(self, self.tr('Info!'), self.tr('Select a connection before closing!')) + QMessageBox.warning( + self, self.tr("Info!"), self.tr("Select a connection before closing!") + ) def connectionParameters(self): """ @@ -338,14 +390,16 @@ def connectionParameters(self): return self._connParameters connection, host, port, user, password = [None] * 5 for i, connection in enumerate(self.getServers()): - (host, port, user, password, isDefault) = self.getServerConfiguration(connection) - if isDefault == True or isDefault == u'true': + (host, port, user, password, isDefault) = self.getServerConfiguration( + connection + ) + if isDefault == True or isDefault == "true": return { - 'connection' : connection, - 'host' : host, - 'port' : port, - 'user' : user, - 'password' : password + "connection": connection, + "host": host, + "port": port, + "user": user, + "password": password, } return dict() @@ -358,11 +412,11 @@ def getDefaultConnectionParameters(self): connParam = self.connectionParameters() if connParam: return ( - connParam['connection'], - connParam['host'], - connParam['port'], - connParam['user'], - connParam['password'] + connParam["connection"], + connParam["host"], + connParam["port"], + connParam["user"], + connParam["password"], ) return (None, None, None, None, None) @@ -377,11 +431,11 @@ def setHost(self, hostname): if isDefault: host, port, user, password, _ = self.getServerConfiguration(connection) self._connParameters = { - 'connection' : self.tableWidget.item(i, 0).text(), - 'host' : self.tableWidget.item(i, 1).text(), - 'port' : self.tableWidget.item(i, 2).text(), - 'user' : self.tableWidget.item(i, 3).text(), - 'password' : password + "connection": self.tableWidget.item(i, 0).text(), + "host": self.tableWidget.item(i, 1).text(), + "port": self.tableWidget.item(i, 2).text(), + "user": self.tableWidget.item(i, 3).text(), + "password": password, } self.defaultChanged.emit() self.done(0) diff --git a/DsgTools/gui/__init__.py b/DsgTools/gui/__init__.py index 80823e1d6..bbe5134fa 100644 --- a/DsgTools/gui/__init__.py +++ b/DsgTools/gui/__init__.py @@ -32,4 +32,5 @@ def classFactory(iface): # pylint: disable=invalid-name """ # from .dsg_tools import DsgTools + return DsgTools(iface) diff --git a/DsgTools/gui/guiManager.py b/DsgTools/gui/guiManager.py index 35f351081..95402c7c6 100644 --- a/DsgTools/gui/guiManager.py +++ b/DsgTools/gui/guiManager.py @@ -34,11 +34,13 @@ from .ProductionTools.productionToolsGuiManager import ProductionToolsGuiManager from .DatabaseTools.databaseManager import DatabaseGuiManager from .ServerTools.serverToolsGuiManager import ServerToolsGuiManager -from .AboutAndFurtherInfo.aboutAndFurtherInfoGuiManager import AboutAndFurtherInfoGuiManager +from .AboutAndFurtherInfo.aboutAndFurtherInfoGuiManager import ( + AboutAndFurtherInfoGuiManager, +) -class GuiManager(QObject): - def __init__(self, iface, parentMenu = None, toolbar = None): +class GuiManager(QObject): + def __init__(self, iface, parentMenu=None, toolbar=None): """Constructor. :param iface: An interface instance that will be passed to this class which provides the hook by which you can manipulate the QGIS @@ -49,20 +51,20 @@ def __init__(self, iface, parentMenu = None, toolbar = None): super(GuiManager, self).__init__() self.iface = iface self.menu = parentMenu - self.iconBasePath = ':/plugins/DsgTools/icons/' + self.iconBasePath = ":/plugins/DsgTools/icons/" self.actions = [] self.managerList = [] self.menuList = [] self.toolbar = toolbar - def addMenu(self, name, title, icon_file, parentMenu = None): + def addMenu(self, name, title, icon_file, parentMenu=None): """ Adds a QMenu """ child = QMenu(self.menu) child.setObjectName(name) child.setTitle(self.tr(title)) - child.setIcon(QIcon(self.iconBasePath+icon_file)) + child.setIcon(QIcon(self.iconBasePath + icon_file)) if parentMenu: parentMenu.addMenu(child) else: @@ -81,7 +83,7 @@ def createToolButton(self, parent, text): parent.addWidget(button) self.actions.append(button) return button - + def add_action( self, icon_path, @@ -93,12 +95,13 @@ def add_action( status_tip=None, whats_this=None, parent=None, - parentMenu = None, + parentMenu=None, withShortcut=False, - tooltip = None, - parentToolbar = None, - parentButton = None, - isCheckable = False): + tooltip=None, + parentToolbar=None, + parentButton=None, + isCheckable=False, + ): """Add a toolbar icon to the InaSAFE toolbar. :param icon_path: Path to the icon for this action. Can be a resource path (e.g. ':/plugins/foo/bar.png') or a normal file system path. @@ -144,7 +147,7 @@ def add_action( if parentMenu: parentMenu.addAction(action) if withShortcut: - self.iface.registerMainWindowAction(action, '') + self.iface.registerMainWindowAction(action, "") if isCheckable: action.setCheckable(True) if tooltip: @@ -155,26 +158,38 @@ def add_action( parentButton.addAction(action) self.actions.append(action) return action - + def instantiateManagers(self): - self.serverToolsGuiManager = ServerToolsGuiManager(self, self.iface, parentMenu=self.menu, toolbar=self.toolbar) + self.serverToolsGuiManager = ServerToolsGuiManager( + self, self.iface, parentMenu=self.menu, toolbar=self.toolbar + ) self.managerList.append(self.serverToolsGuiManager) - self.databaseGuiManager = DatabaseGuiManager(self, self.iface, parentMenu=self.menu, toolbar=self.toolbar) + self.databaseGuiManager = DatabaseGuiManager( + self, self.iface, parentMenu=self.menu, toolbar=self.toolbar + ) self.managerList.append(self.databaseGuiManager) - self.layerToolsGuiManager = LayerToolsGuiManager(self, self.iface, parentMenu = self.menu, toolbar = self.toolbar) + self.layerToolsGuiManager = LayerToolsGuiManager( + self, self.iface, parentMenu=self.menu, toolbar=self.toolbar + ) self.managerList.append(self.layerToolsGuiManager) - self.productionToolsGuiManager = ProductionToolsGuiManager(self, self.iface, parentMenu = self.menu, toolbar = self.toolbar) + self.productionToolsGuiManager = ProductionToolsGuiManager( + self, self.iface, parentMenu=self.menu, toolbar=self.toolbar + ) self.managerList.append(self.productionToolsGuiManager) - self.bdgexGuiManager = BDGExGuiManager(self, self.iface, parentMenu = self.menu, toolbar = self.toolbar) + self.bdgexGuiManager = BDGExGuiManager( + self, self.iface, parentMenu=self.menu, toolbar=self.toolbar + ) self.managerList.append(self.bdgexGuiManager) - self.aboutAndFurtherGuiManager = AboutAndFurtherInfoGuiManager(self, self.iface, parentMenu = self.menu, toolbar = self.toolbar) + self.aboutAndFurtherGuiManager = AboutAndFurtherInfoGuiManager( + self, self.iface, parentMenu=self.menu, toolbar=self.toolbar + ) self.managerList.append(self.aboutAndFurtherGuiManager) - + def initGui(self): self.instantiateManagers() for manager in self.managerList: manager.initGui() - + def unload(self): for manager in self.managerList: manager.unload() @@ -182,4 +197,4 @@ def unload(self): try: self.iface.unregisterMainWindowAction(action) except: - pass \ No newline at end of file + pass diff --git a/DsgTools/i18n/DsgTools_pt.ts b/DsgTools/i18n/DsgTools_pt.ts index 08c5b81bb..5b6244ec4 100644 --- a/DsgTools/i18n/DsgTools_pt.ts +++ b/DsgTools/i18n/DsgTools_pt.ts @@ -1526,9 +1526,9 @@ Usuários com erro: - Invalid GetCapabilities response: + Invalid GetCapabilities response: {0} - Resposta do GetCapabilities Inválida: + Resposta do GetCapabilities Inválida: {0} @@ -1825,9 +1825,9 @@ Mensagens de erro para cada banco de dados foram registradas no log do QGIS. - Drop operation complete. + Drop operation complete. - Operação de deleção concluída. + Operação de deleção concluída. @@ -1837,16 +1837,16 @@ Mensagens de erro para cada banco de dados foram registradas no log do QGIS. - Import operation complete. + Import operation complete. - Operação de importação concluída. + Operação de importação concluída. - Delete operation complete. + Delete operation complete. - Operação de deleção completa. + Operação de deleção completa. @@ -1861,9 +1861,9 @@ Mensagens de erro para cada banco de dados foram registradas no log do QGIS. - Customize from SQL file operation complete. + Customize from SQL file operation complete. - Operação de cutomização a partir de arquivo SQL completa. + Operação de cutomização a partir de arquivo SQL completa. @@ -1918,9 +1918,9 @@ Mensagens de erro para cada banco de dados foram registradas no log do QGIS. - Upgrade Posgtis operation complete. + Upgrade Posgtis operation complete. - Operação de atualização do PostGIS completa. + Operação de atualização do PostGIS completa. @@ -2858,28 +2858,28 @@ Mensagens de erro para cada banco de dados foram registradas no log do QGIS. Layer Name - Nome da + Nome da camada Geometry Column - Coluna + Coluna geométrica Geometry Type - Tipo + Tipo geométrico Layer Type - Tipo da + Tipo da camada @@ -5404,11 +5404,11 @@ A conversão deve ser entre bancos de dados com a mesma versão! - Select Frame Layer (If this is + Select Frame Layer (If this is not checked and frame not selected, the frame will not be created - Selecionar camada de moldura -(se este item não estiver marcado e uma camada + Selecionar camada de moldura +(se este item não estiver marcado e uma camada para moldura não for selecionada, a moldura não será criada @@ -5751,7 +5751,7 @@ para moldura não for selecionada, a moldura não será criada Geometry Column - Coluna + Coluna geométrica @@ -6051,28 +6051,28 @@ Mensagens de erro para cada perfil foram geradas no log do QGIS. Layer Name - Nome da + Nome da Camada Geometry Column - Coluna + Coluna Geométrica Geometry Type - Tipo + Tipo Geométrico Layer Type - Tipo da + Tipo da Camada @@ -7142,21 +7142,21 @@ Dados nulos em campos não nulos serão modificados para -9999) Geometry Column - Coluna + Coluna geométrica Geometry Type - Tipo + Tipo geométrico Layer Type - Tipo da + Tipo da camada @@ -8113,9 +8113,9 @@ Ao segurar a tecla Control, a obrigatoriedade de ângulos retos é desligada enq - Update Earth Coverage configuration complete. + Update Earth Coverage configuration complete. - Atualização da configuração de cobertura terrestre completa. + Atualização da configuração de cobertura terrestre completa. @@ -8125,16 +8125,16 @@ Ao segurar a tecla Control, a obrigatoriedade de ângulos retos é desligada enq - Uninstall Earth Coverage configuration complete. + Uninstall Earth Coverage configuration complete. - Desinstalação configuração de cobertura terrestre completa. + Desinstalação configuração de cobertura terrestre completa. - Install Earth Coverage configuration complete. + Install Earth Coverage configuration complete. - Instalação de configuração de cobertura terrestre concluída. + Instalação de configuração de cobertura terrestre concluída. @@ -8144,9 +8144,9 @@ Ao segurar a tecla Control, a obrigatoriedade de ângulos retos é desligada enq - Delete Earth Coverage configuration complete. + Delete Earth Coverage configuration complete. - Remoção de configuração de cobertura terrestra completa. + Remoção de configuração de cobertura terrestra completa. @@ -9166,9 +9166,9 @@ Ao segurar a tecla Control, a obrigatoriedade de ângulos retos é desligada enq - Update Field Toolbox configuration complete. + Update Field Toolbox configuration complete. - Atualização da configuração da Ferramenta de Classificação completa. + Atualização da configuração da Ferramenta de Classificação completa. @@ -9178,16 +9178,16 @@ Ao segurar a tecla Control, a obrigatoriedade de ângulos retos é desligada enq - Uninstall Field Toolbox configuration complete. + Uninstall Field Toolbox configuration complete. - Desinstalação da configuração da Ferramenta de Classificação completa. + Desinstalação da configuração da Ferramenta de Classificação completa. - Install Field Toolbox configuration complete. + Install Field Toolbox configuration complete. - Instalação de configurações da Ferramenta de Classificação completa. + Instalação de configurações da Ferramenta de Classificação completa. @@ -9197,9 +9197,9 @@ Ao segurar a tecla Control, a obrigatoriedade de ângulos retos é desligada enq - Delete Field Toolbox configuration complete. + Delete Field Toolbox configuration complete. - Remoção da configuração da Ferramenta de Classificação completa. + Remoção da configuração da Ferramenta de Classificação completa. @@ -9773,13 +9773,13 @@ Feição(ões) não invertidas: Set Zoom: - Ajustar + Ajustar aproximação: Initial feat ID - ID iniciação + ID iniciação de feição @@ -9819,7 +9819,7 @@ de feição - Only on selected + Only on selected features Apenas Feições Selecionadas @@ -9832,7 +9832,7 @@ Selecionadas Set Zoom - Selecione + Selecione o Zoom @@ -11349,14 +11349,14 @@ Column Geometry Type - Tipo + Tipo Geométrico Layer Type - Tipo da + Tipo da Camada @@ -11611,28 +11611,28 @@ Camada Layer Name - Nome da + Nome da Camada Geometry Column - Coluna + Coluna Geométrica Geometry Type - Tipo + Tipo Geométrico Layer Type - Tipo da + Tipo da Camada @@ -11911,28 +11911,28 @@ Camada Layer Name - Nome da + Nome da Camada Geometry Column - Coluna + Coluna Geométrica Geometry Type - Tipo + Tipo Geométrico Layer Type - Tipo da + Tipo da Camada @@ -11956,28 +11956,28 @@ Camada Layer Name - Nome da + Nome da Camada Geometry Column - Coluna + Coluna Geométrica Geometry Type - Tipo + Tipo Geométrico Layer Type - Tipo da + Tipo da Camada @@ -12159,28 +12159,28 @@ Camada Layer Name - Nome da + Nome da Camada Geometry Column - Coluna + Coluna Geométrica Geometry Type - Tipo + Tipo Geométrico Layer Type - Tipo da + Tipo da Camada @@ -12390,28 +12390,28 @@ Camada Layer Name - Nome da + Nome da Camada Geometry Column - Coluna + Coluna Geométrica Geometry Type - Tipo + Tipo Geométrico Layer Type - Tipo da + Tipo da Camada @@ -12501,28 +12501,28 @@ Camada Layer Name - Nome da + Nome da Camada Geometry Column - Coluna + Coluna Geométrica Geometry Type - Tipo + Tipo Geométrico Layer Type - Tipo da + Tipo da Camada @@ -12647,28 +12647,28 @@ Camada Layer Name - Nome da + Nome da Camada Geometry Column - Coluna + Coluna Geométrica Geometry Type - Tipo + Tipo Geométrico Layer Type - Tipo da + Tipo da Camada @@ -12720,28 +12720,28 @@ Camada Layer Name - Nome da + Nome da Camada Geometry Column - Coluna + Coluna Geométrica Geometry Type - Tipo + Tipo Geométrico Layer Type - Tipo da + Tipo da Camada @@ -12933,28 +12933,28 @@ Camada Layer Name - Nome da + Nome da Camada Geometry Column - Coluna + Coluna Geométrica Geometry Type - Tipo + Tipo Geométrico Layer Type - Tipo da + Tipo da Camada @@ -13114,28 +13114,28 @@ Camada Layer Name - Nome da + Nome da Camada Geometry Column - Coluna + Coluna Geométrica Geometry Type - Tipo + Tipo Geométrico Layer Type - Tipo da + Tipo da Camada @@ -13416,28 +13416,28 @@ Camada Layer Name - Nome da + Nome da Camada Geometry Column - Coluna + Coluna Geométrica Geometry Type - Tipo + Tipo Geométrico Layer Type - Tipo da + Tipo da Camada @@ -13888,28 +13888,28 @@ Camada Layer Name - Nome da + Nome da Camada Geometry Column - Coluna + Coluna Geométrica Geometry Type - Tipo + Tipo Geométrico Layer Type - Tipo da + Tipo da Camada @@ -14563,14 +14563,14 @@ Mensagens de erro para cada banco de dados foram registradas no log do QGIS. Layer Name - Nome da + Nome da camada Geometry Column - Coluna + Coluna geométrica @@ -14584,7 +14584,7 @@ geométrico Layer Type - Tipo da + Tipo da camada @@ -15080,28 +15080,28 @@ Usuários com erro: Layer Name - Nome da + Nome da Camada Geometry Column - Coluna + Coluna Geométrica Geometry Type - Tipo + Tipo Geométrico Layer Type - Tipo da + Tipo da Camada @@ -16342,28 +16342,28 @@ Verificar o Direcionamento de Rede: linhas invertidas/unidas Layer Name - Nome da + Nome da Camada Geometry Column - Coluna + Coluna Geométrica Geometry Type - Tipo + Tipo Geométrico Layer Type - Tipo da + Tipo da Camada @@ -17911,28 +17911,28 @@ Camada Layer Name - Nome da + Nome da camada Geometry Column - Coluna + Coluna geométrica Geometry Type - Tipo + Tipo geométrico Layer Type - Tipo da + Tipo da camada @@ -18094,9 +18094,9 @@ camada - Problem saving file! + Problem saving file! - Problema ao tentar salvar arquivo! + Problema ao tentar salvar arquivo! @@ -18111,9 +18111,9 @@ camada - Problem deleting profile! + Problem deleting profile! - Problema ao tentar deletar perfil! + Problema ao tentar deletar perfil! @@ -18792,28 +18792,28 @@ Versão do modelo: {1} Layer Name - Nome da + Nome da Camada Geometry Column - Coluna + Coluna Geométrica Geometry Type - Tipo + Tipo Geométrico Layer Type - Tipo da + Tipo da Camada @@ -19094,16 +19094,16 @@ Camada - Problem reading file! + Problem reading file! - Problema lendo arquivo! + Problema lendo arquivo! - Problem saving file! + Problem saving file! - Problema ao tentar salvar arquivo! + Problema ao tentar salvar arquivo! @@ -19823,7 +19823,7 @@ Se existe um atributo restritivo na classe selecionada, clique com o botão dire - Problem saving into database! + Problem saving into database! Problema salvando no banco de dados! @@ -19844,16 +19844,16 @@ Se existe um atributo restritivo na classe selecionada, clique com o botão dire - 4- Choose the line classes that, along with the frame, build the areas of earth coverage + 4- Choose the line classes that, along with the frame, build the areas of earth coverage (only parent classes are listed here). - 4- Escolha as classes do tipo linha que, juntamente com a moldura, definem áreas da cobertura terrestre + 4- Escolha as classes do tipo linha que, juntamente com a moldura, definem áreas da cobertura terrestre (somente classes pai são listadas aqui). - 5- For each area class of earth coverage, define which lines are used to build it + 5- For each area class of earth coverage, define which lines are used to build it (note that frame is always used to close areas) - 5- Para cada classe da cobertura terrestre, defina quais linhas são usadas para construí-la + 5- Para cada classe da cobertura terrestre, defina quais linhas são usadas para construí-la (note que a moldura é sempre usada para fechar áreas) @@ -20218,28 +20218,28 @@ Se existe um atributo restritivo na classe selecionada, clique com o botão dire Layer Name - Nome da + Nome da Camada Geometry Column - Coluna + Coluna Geométrica Geometry Type - Tipo + Tipo Geométrico Layer Type - Tipo da + Tipo da Camada @@ -20487,28 +20487,28 @@ Camada Layer Name - Nome da + Nome da Camada Geometry Column - Coluna + Coluna Geométrica Geometry Type - Tipo + Tipo Geométrico Layer Type - Tipo da + Tipo da Camada @@ -20587,28 +20587,28 @@ Camada Layer Name - Nome da + Nome da Camada Geometry Column - Coluna + Coluna Geométrica Geometry Type - Tipo + Tipo Geométrico Layer Type - Tipo da + Tipo da Camada @@ -20750,28 +20750,28 @@ Camada Layer Name - Nome da + Nome da Camada Geometry Column - Coluna + Coluna Geométrica Geometry Type - Tipo + Tipo Geométrico Layer Type - Tipo da + Tipo da Camada @@ -20948,7 +20948,7 @@ Camada - Problem reading file! + Problem reading file! Problema lendo arquivo! @@ -21007,7 +21007,7 @@ Camada - Problem reading file! + Problem reading file! Problema lendo arquivo! @@ -21337,9 +21337,9 @@ Camada StyleManagerWidget - Update Style configuration complete. + Update Style configuration complete. - Configuração de atualização de estilo concluída. + Configuração de atualização de estilo concluída. @@ -21349,16 +21349,16 @@ Camada - Uninstall Style configuration complete. + Uninstall Style configuration complete. - Desinstalação de configuração de estilo concluída. + Desinstalação de configuração de estilo concluída. - Install Style configuration complete. + Install Style configuration complete. - Instalação de configuração de estilo concluída. + Instalação de configuração de estilo concluída. @@ -21368,9 +21368,9 @@ Camada - Delete Style configuration complete. + Delete Style configuration complete. - Remoção de configuração de estilo concluída. + Remoção de configuração de estilo concluída. @@ -21681,28 +21681,28 @@ Camada Layer Name - Nome da + Nome da Camada Geometry Column - Coluna + Coluna Geométrica Geometry Type - Tipo + Tipo Geométrico Layer Type - Tipo da + Tipo da Camada @@ -21940,28 +21940,28 @@ Camada Layer Name - Nome da + Nome da Camada Geometry Column - Coluna + Coluna Geométrica Geometry Type - Tipo + Tipo Geométrico Layer Type - Tipo da + Tipo da Camada diff --git a/DsgTools/metadata.txt b/DsgTools/metadata.txt index 40a9aed7a..ec7201f6a 100644 --- a/DsgTools/metadata.txt +++ b/DsgTools/metadata.txt @@ -10,7 +10,7 @@ name=DSG Tools qgisMinimumVersion=3.22 description=Brazilian Army Cartographic Production Tools -version=4.6.0 +version=4.7.0 author=Brazilian Army Geographic Service email=suporte.dsgtools@dsg.eb.mil.br about= @@ -44,6 +44,40 @@ about= # Uncomment the following line and add your changelog: changelog= + 4.7.0: + Novas funcionalidades: + - Novo processo de selecionar feições no canvas de camadas selecionadas; + - Novo processo de filtrar lista de camadas no processing por tipo geométrico; + - Novo processo de remover holes pequenos de camadas de cobertura; + - Novo processo de dissolver polígonos para vizinhos (heurística pelo maior comprimento da intersecção); + - Novo processo de construir grid de pontos dentro de polígonos; + - Novo processo de dividir polígonos; + - Novo processo de dividir polígonos por grid; + - Novo processo de selecionar por DE9IM; + - Novo processo de extrair feições por DE9IM; + - Processo de converter linha para multilinha portado do ferramentas experimentais; + + Melhorias: + - Adicionada a opção de dar pan na barra de ferramentas de revisão; + - Adicionada mudanca de ferramenta atual nos icones das ferramentas de filtro; + - Processing de construção do diagrama de elevação portado para o Ferramentas de Edição; + - Adicionado o comportamento no seletor genérico de selecionar somente na camada ativa quando a tecla Alt estiver selecionada; + - Adicionada a opção de rodar a construção de polígonos por polígono de área geográfica (por MI); + - Melhoria de desempenho na construção de polígonos (adicionado paralelismo em thread); + - Melhoria de desempenho na verificação de delimitadores não utilizados no processo de construção de polígonos; + - Adicionada a opção de verificar ou não delimitadores não utilizados no processo de construção de polígonos; + - Melhoria de desempenho na identificação de erros de construção do terreno (roda em thread por área geográfica); + - A ferramenta de verificação de erros de relacionamentos espaciais agora permite regras com de9im e relacionamentos espaciais simultaneamente; + - Adicionada a opção de desligar todas as imagens ativas na ferramenta de seleção de raster; + - Adicionado o id da geometria na flag do identificar geometrias inválidas; + - O menu de aquisição agora permite reclassificação de polígono para ponto (particularmente útil quando se está corrigindo flags de áreas sem centroide na construção de polígonos utilizando linha e centroide); + + + Correção de bug: + - Corrigido o bug de sempre apontar flags quando a geometria tem buraco do processo de identificar geometrias com densidade incorreta de vértices; + - Correção de bug no processo de adicionar vértice em segmento compartilhado; + - Correção de bug no processo de dissolver polígonos com mesmo conjunto de atributos quando é passada uma área mínima para o dissolve; + - Correção de bug no acesso ao BDGEx (a url do serviço mudou e o código teve de ser atualizado, mudando a url do serviço de https para http); 4.6.0: Novas funcionalidades: - Novo processo de estender linhas próximas da moldura; @@ -141,4 +175,3 @@ experimental=False # deprecated flag (applies to the whole plugin, not just a single version) deprecated=False - diff --git a/DsgTools/plugin_upload.py b/DsgTools/plugin_upload.py index 8494aa137..4c9791d2e 100644 --- a/DsgTools/plugin_upload.py +++ b/DsgTools/plugin_upload.py @@ -7,6 +7,7 @@ from __future__ import print_function from future import standard_library + standard_library.install_aliases() from builtins import input import sys @@ -15,10 +16,10 @@ from optparse import OptionParser # Configuration -PROTOCOL = 'http' -SERVER = 'plugins.qgis.org' -PORT = '80' -ENDPOINT = '/plugins/RPC2/' +PROTOCOL = "http" +SERVER = "plugins.qgis.org" +PORT = "80" +ENDPOINT = "/plugins/RPC2/" VERBOSE = False @@ -34,7 +35,8 @@ def main(parameters, arguments): parameters.password, parameters.server, parameters.port, - ENDPOINT) + ENDPOINT, + ) # fix_print_with_import print("Connecting to: %s" % hide_password(address)) @@ -42,7 +44,8 @@ def main(parameters, arguments): try: plugin_id, version_id = server.plugin.upload( - xmlrpc.client.Binary(open(arguments[0]).read())) + xmlrpc.client.Binary(open(arguments[0]).read()) + ) # fix_print_with_import print("Plugin ID: %s" % plugin_id) # fix_print_with_import @@ -76,28 +79,41 @@ def hide_password(url, start=6): :param start: Position of start of password. :type start: int """ - start_position = url.find(':', start) + 1 - end_position = url.find('@') + start_position = url.find(":", start) + 1 + end_position = url.find("@") return "%s%s%s" % ( url[:start_position], - '*' * (end_position - start_position), - url[end_position:]) + "*" * (end_position - start_position), + url[end_position:], + ) if __name__ == "__main__": parser = OptionParser(usage="%prog [options] plugin.zip") parser.add_option( - "-w", "--password", dest="password", - help="Password for plugin site", metavar="******") + "-w", + "--password", + dest="password", + help="Password for plugin site", + metavar="******", + ) parser.add_option( - "-u", "--username", dest="username", - help="Username of plugin site", metavar="user") + "-u", + "--username", + dest="username", + help="Username of plugin site", + metavar="user", + ) parser.add_option( - "-p", "--port", dest="port", - help="Server port to connect to", metavar="80") + "-p", "--port", dest="port", help="Server port to connect to", metavar="80" + ) parser.add_option( - "-s", "--server", dest="server", - help="Specify server name", metavar="plugins.qgis.org") + "-s", + "--server", + dest="server", + help="Specify server name", + metavar="plugins.qgis.org", + ) options, args = parser.parse_args() if len(args) != 1: # fix_print_with_import @@ -112,7 +128,7 @@ def hide_password(url, start=6): # interactive mode username = getpass.getuser() # fix_print_with_import - print("Please enter user name [%s] :" % username, end=' ') + print("Please enter user name [%s] :" % username, end=" ") res = input() if res != "": options.username = res diff --git a/DsgTools/resources.py b/DsgTools/resources.py index ae27ffe9c..f5f52acbf 100644 --- a/DsgTools/resources.py +++ b/DsgTools/resources.py @@ -78244,7 +78244,7 @@ \x00\x00\x01\x81\x5d\x7c\xdb\x3b\ " -qt_version = [int(v) for v in QtCore.qVersion().split('.')] +qt_version = [int(v) for v in QtCore.qVersion().split(".")] if qt_version < [5, 8, 0]: rcc_version = 1 qt_resource_struct = qt_resource_struct_v1 @@ -78252,10 +78252,17 @@ rcc_version = 2 qt_resource_struct = qt_resource_struct_v2 + def qInitResources(): - QtCore.qRegisterResourceData(rcc_version, qt_resource_struct, qt_resource_name, qt_resource_data) + QtCore.qRegisterResourceData( + rcc_version, qt_resource_struct, qt_resource_name, qt_resource_data + ) + def qCleanupResources(): - QtCore.qUnregisterResourceData(rcc_version, qt_resource_struct, qt_resource_name, qt_resource_data) + QtCore.qUnregisterResourceData( + rcc_version, qt_resource_struct, qt_resource_name, qt_resource_data + ) + qInitResources() diff --git a/DsgTools/resources.qrc b/DsgTools/resources.qrc index 35c977969..f312d48fc 100644 --- a/DsgTools/resources.qrc +++ b/DsgTools/resources.qrc @@ -40,12 +40,12 @@ icons/batchDatabase.png icons/page_white_wrench.png icons/custom_tools.png - icons/genericSelect.png - icons/attributeSelector.png - icons/refresh.png - icons/circle.png - icons/home.png - icons/bug.png + icons/genericSelect.png + icons/attributeSelector.png + icons/refresh.png + icons/circle.png + icons/home.png + icons/bug.png icons/free_hand.png icons/free_hand_reshape.png icons/flipLineTool.png diff --git a/DsgTools/resources_rc.py b/DsgTools/resources_rc.py index 2087fc919..918c71c0a 100644 --- a/DsgTools/resources_rc.py +++ b/DsgTools/resources_rc.py @@ -78244,7 +78244,7 @@ \x00\x00\x01\x81\x5d\x7c\xdb\x3b\ " -qt_version = [int(v) for v in QtCore.qVersion().split('.')] +qt_version = [int(v) for v in QtCore.qVersion().split(".")] if qt_version < [5, 8, 0]: rcc_version = 1 qt_resource_struct = qt_resource_struct_v1 @@ -78252,10 +78252,17 @@ rcc_version = 2 qt_resource_struct = qt_resource_struct_v2 + def qInitResources(): - QtCore.qRegisterResourceData(rcc_version, qt_resource_struct, qt_resource_name, qt_resource_data) + QtCore.qRegisterResourceData( + rcc_version, qt_resource_struct, qt_resource_name, qt_resource_data + ) + def qCleanupResources(): - QtCore.qUnregisterResourceData(rcc_version, qt_resource_struct, qt_resource_name, qt_resource_data) + QtCore.qUnregisterResourceData( + rcc_version, qt_resource_struct, qt_resource_name, qt_resource_data + ) + qInitResources() diff --git a/ISSUE_TEMPLATE.md b/ISSUE_TEMPLATE.md index 3045668ec..439ac0e4d 100644 --- a/ISSUE_TEMPLATE.md +++ b/ISSUE_TEMPLATE.md @@ -2,9 +2,9 @@ Describe your issue here. (Descreva seu problema aqui). ### Your environment (Seu ambiente) -* your operating system (Seu sistema operacional): -* version of QGIS (Versão do QGIS): -* version of DSGTools (Versão do DSGTools): +* your operating system (Seu sistema operacional): +* version of QGIS (Versão do QGIS): +* version of DSGTools (Versão do DSGTools): ### Steps to reproduce (Passos para reproduzir) Tell us how to reproduce this issue. Please provide screenshots to further information. (Descreva os passos para reproduzir o problema. Por favor informe capturas de tela para informaçes adicionais) diff --git a/hooks/pre-commit b/hooks/pre-commit index 9c2cbf4af..5d0fa9154 100755 --- a/hooks/pre-commit +++ b/hooks/pre-commit @@ -4,20 +4,30 @@ import os rootPath = os.path.join(os.path.dirname(__file__), "..") try: # check version in metadata - with open(os.path.join(rootPath, 'metadata.txt'), 'r') as meta: + with open(os.path.join(rootPath, "metadata.txt"), "r") as meta: metadata = meta.read() for line in metadata.split("\n"): if line.strip().startswith("version="): version = line.split("=")[1].strip() if "dev" in version: - version_raw = version.rsplit("_", 1)[0] if "_" in version.count("_") == 2 else version - commit = os.popen("cd {0} && git log -1".format(rootPath)).readlines()[0].strip().split(" ")[1] + version_raw = ( + version.rsplit("_", 1)[0] if "_" in version.count("_") == 2 else version + ) + commit = ( + os.popen("cd {0} && git log -1".format(rootPath)) + .readlines()[0] + .strip() + .split(" ")[1] + ) # add the last commit to version tag # if commit not in version: - with open(os.path.join(rootPath, 'metadata.txt'), 'w') as meta: - metadata = metadata.replace("version={0}".format(version), "version={0}_{1}".format(version_raw, commit)) + with open(os.path.join(rootPath, "metadata.txt"), "w") as meta: + metadata = metadata.replace( + "version={0}".format(version), + "version={0}_{1}".format(version_raw, commit), + ) meta.write(metadata) print("New dev version tag: {0}_{1}".format(version_raw, commit)) - os.popen('cd {0} && git add metadata.txt'.format(rootPath)) + os.popen("cd {0} && git add metadata.txt".format(rootPath)) except Exception as e: print("Could not apply version check (for dev versions): '{0}'".format(str(e))) diff --git a/setup.cfg b/setup.cfg index a3e468d07..3d80535c7 100644 --- a/setup.cfg +++ b/setup.cfg @@ -2,4 +2,4 @@ plugin_path = DsgTools github_organization_slug = dsgoficial project_slug = DsgTools -changelog_include = True \ No newline at end of file +changelog_include = True diff --git a/tests/__init__.py b/tests/__init__.py index 8d1c8b69c..e69de29bb 100644 --- a/tests/__init__.py +++ b/tests/__init__.py @@ -1 +0,0 @@ - diff --git a/tests/algorithmsTestBase.py b/tests/algorithmsTestBase.py index 8d5a6e084..791c85a67 100644 --- a/tests/algorithmsTestBase.py +++ b/tests/algorithmsTestBase.py @@ -19,9 +19,9 @@ *************************************************************************** """ -__author__ = 'Matthias Kuhn' -__date__ = 'January 2016' -__copyright__ = '(C) 2016, Matthias Kuhn' +__author__ = "Matthias Kuhn" +__date__ = "January 2016" +__copyright__ = "(C) 2016, Matthias Kuhn" import qgis # NOQA switch sip api @@ -40,20 +40,20 @@ from numpy import nan_to_num from copy import deepcopy -from qgis.core import (QgsVectorLayer, - QgsRasterLayer, - QgsCoordinateReferenceSystem, - QgsFeatureRequest, - QgsMapLayer, - QgsProject, - QgsApplication, - QgsProcessingContext, - QgsProcessingUtils, - QgsProcessingFeedback) -from qgis.analysis import (QgsNativeAlgorithms) -from qgis.testing import (_UnexpectedSuccess, - start_app, - unittest) +from qgis.core import ( + QgsVectorLayer, + QgsRasterLayer, + QgsCoordinateReferenceSystem, + QgsFeatureRequest, + QgsMapLayer, + QgsProject, + QgsApplication, + QgsProcessingContext, + QgsProcessingUtils, + QgsProcessingFeedback, +) +from qgis.analysis import QgsNativeAlgorithms +from qgis.testing import _UnexpectedSuccess, start_app, unittest import processing @@ -63,18 +63,26 @@ def processingTestDataPath(): class AlgorithmsTest(object): - def test_algorithms(self): """ This is the main test function. All others will be executed based on the definitions in testdata/algorithm_tests.yaml """ - with open(os.path.join(os.path.dirname(__file__), 'tests_yaml', self.get_definition_file()), 'r') as stream: + with open( + os.path.join( + os.path.dirname(__file__), "tests_yaml", self.get_definition_file() + ), + "r", + ) as stream: algorithm_tests = yaml.load(stream, Loader=yaml.SafeLoader) - if 'tests' in algorithm_tests and algorithm_tests['tests'] is not None: - for idx, algtest in enumerate(algorithm_tests['tests']): - print('About to start {} of {}: "{}"'.format(idx, len(algorithm_tests['tests']), algtest['name'])) - yield self.check_algorithm, algtest['name'], algtest + if "tests" in algorithm_tests and algorithm_tests["tests"] is not None: + for idx, algtest in enumerate(algorithm_tests["tests"]): + print( + 'About to start {} of {}: "{}"'.format( + idx, len(algorithm_tests["tests"]), algtest["name"] + ) + ) + yield self.check_algorithm, algtest["name"], algtest def check_algorithm(self, name, defs): """ @@ -85,25 +93,29 @@ def check_algorithm(self, name, defs): self.vector_layer_params = {} QgsProject.instance().clear() - if 'project' in defs: - full_project_path = os.path.join(processingTestDataPath(), defs['project']) + if "project" in defs: + full_project_path = os.path.join(processingTestDataPath(), defs["project"]) project_read_success = QgsProject.instance().read(full_project_path) - self.assertTrue(project_read_success, 'Failed to load project file: ' + defs['project']) - - if 'project_crs' in defs: - QgsProject.instance().setCrs(QgsCoordinateReferenceSystem(defs['project_crs'])) + self.assertTrue( + project_read_success, "Failed to load project file: " + defs["project"] + ) + + if "project_crs" in defs: + QgsProject.instance().setCrs( + QgsCoordinateReferenceSystem(defs["project_crs"]) + ) else: QgsProject.instance().setCrs(QgsCoordinateReferenceSystem()) - if 'ellipsoid' in defs: - QgsProject.instance().setEllipsoid(defs['ellipsoid']) + if "ellipsoid" in defs: + QgsProject.instance().setEllipsoid(defs["ellipsoid"]) else: - QgsProject.instance().setEllipsoid('') + QgsProject.instance().setEllipsoid("") - params = self.load_params(defs['params']) + params = self.load_params(defs["params"]) - print('Running alg: "{}"'.format(defs['algorithm'])) - alg = QgsApplication.processingRegistry().createAlgorithmById(defs['algorithm']) + print('Running alg: "{}"'.format(defs["algorithm"])) + alg = QgsApplication.processingRegistry().createAlgorithmById(defs["algorithm"]) parameters = {} if isinstance(params, list): @@ -113,45 +125,47 @@ def check_algorithm(self, name, defs): for k, p in params.items(): parameters[k] = p - for r, p in list(defs['results'].items()): - if not 'in_place_result' in p or not p['in_place_result']: + for r, p in list(defs["results"].items()): + if not "in_place_result" in p or not p["in_place_result"]: parameters[r] = self.load_result_param(p) expectFailure = False - if 'expectedFailure' in defs: - exec(('\n'.join(defs['expectedFailure'][:-1])), globals(), locals()) - expectFailure = eval(defs['expectedFailure'][-1]) + if "expectedFailure" in defs: + exec(("\n".join(defs["expectedFailure"][:-1])), globals(), locals()) + expectFailure = eval(defs["expectedFailure"][-1]) - if 'expectedException' in defs: + if "expectedException" in defs: expectFailure = True # ignore user setting for invalid geometry handling context = QgsProcessingContext() context.setProject(QgsProject.instance()) - if 'skipInvalid' in defs and defs['skipInvalid']: + if "skipInvalid" in defs and defs["skipInvalid"]: context.setInvalidGeometryCheck(QgsFeatureRequest.GeometrySkipInvalid) feedback = QgsProcessingFeedback() - print('Algorithm parameters are {}'.format(parameters)) + print("Algorithm parameters are {}".format(parameters)) # first check that algorithm accepts the parameters we pass... ok, msg = alg.checkParameterValues(parameters, context) - self.assertTrue(ok, 'Algorithm failed checkParameterValues with result {}'.format(msg)) + self.assertTrue( + ok, "Algorithm failed checkParameterValues with result {}".format(msg) + ) if expectFailure: try: results, ok = alg.run(parameters, context, feedback) - self.check_results(results, context, parameters, defs['results']) + self.check_results(results, context, parameters, defs["results"]) if ok: raise _UnexpectedSuccess except Exception: pass else: results, ok = alg.run(parameters, context, feedback) - self.assertTrue(ok, 'params: {}, results: {}'.format(parameters, results)) - self.check_results(results, context, parameters, defs['results']) + self.assertTrue(ok, "params: {}, results: {}".format(parameters, results)) + self.check_results(results, context, parameters, defs["results"]) def load_params(self, params): """ @@ -170,56 +184,61 @@ def load_param(self, param, id=None): parameter based on its key `type` and return the appropriate parameter to pass to the algorithm. """ try: - if param['type'] in ('vector', 'raster', 'table'): + if param["type"] in ("vector", "raster", "table"): return self.load_layer(id, param).id() - elif param['type'] == 'multi': - return [self.load_param(p) for p in param['params']] - elif param['type'] == 'file': + elif param["type"] == "multi": + return [self.load_param(p) for p in param["params"]] + elif param["type"] == "file": return self.filepath_from_param(param) - elif param['type'] == 'interpolation': + elif param["type"] == "interpolation": prefix = processingTestDataPath() - tmp = '' - for r in param['name'].split('::|::'): - v = r.split('::~::') - tmp += '{}::~::{}::~::{}::~::{};'.format(os.path.join(prefix, v[0]), - v[1], v[2], v[3]) + tmp = "" + for r in param["name"].split("::|::"): + v = r.split("::~::") + tmp += "{}::~::{}::~::{}::~::{};".format( + os.path.join(prefix, v[0]), v[1], v[2], v[3] + ) return tmp[:-1] except TypeError: # No type specified, use whatever is there return param - raise KeyError("Unknown type '{}' specified for parameter".format(param['type'])) + raise KeyError( + "Unknown type '{}' specified for parameter".format(param["type"]) + ) def load_result_param(self, param): """ Loads a result parameter. Creates a temporary destination where the result should go to and returns this location so it can be sent to the algorithm as parameter. """ - if param['type'] in ['vector', 'file', 'table', 'regex']: + if param["type"] in ["vector", "file", "table", "regex"]: outdir = tempfile.mkdtemp() self.cleanup_paths.append(outdir) - if isinstance(param['name'], str): - basename = os.path.basename(param['name']) + if isinstance(param["name"], str): + basename = os.path.basename(param["name"]) else: - basename = os.path.basename(param['name'][0]) + basename = os.path.basename(param["name"][0]) filepath = self.uri_path_join(outdir, basename) return filepath - elif param['type'] == 'directory': + elif param["type"] == "directory": outdir = tempfile.mkdtemp() return outdir - raise KeyError("Unknown type '{}' specified for parameter".format(param['type'])) + raise KeyError( + "Unknown type '{}' specified for parameter".format(param["type"]) + ) def load_layers(self, id, param): layers = [] - if param['type'] in ('vector', 'table'): - if isinstance(param['name'], str) or 'uri' in param: + if param["type"] in ("vector", "table"): + if isinstance(param["name"], str) or "uri" in param: layers.append(self.load_layer(id, param)) else: - for n in param['name']: + for n in param["name"]: layer_param = deepcopy(param) - layer_param['name'] = n + layer_param["name"] = n layers.append(self.load_layer(id, layer_param)) else: layers.append(self.load_layer(id, param)) @@ -232,31 +251,34 @@ def load_layer(self, id, param): filepath = self.filepath_from_param(param) - if 'in_place' in param and param['in_place']: + if "in_place" in param and param["in_place"]: # check if alg modifies layer in place tmpdir = tempfile.mkdtemp() self.cleanup_paths.append(tmpdir) path, file_name = os.path.split(filepath) base, ext = os.path.splitext(file_name) - for file in glob.glob(os.path.join(path, '{}.*'.format(base))): + for file in glob.glob(os.path.join(path, "{}.*".format(base))): shutil.copy(os.path.join(path, file), tmpdir) filepath = os.path.join(tmpdir, file_name) self.in_place_layers[id] = filepath - if param['type'] in ('vector', 'table'): + if param["type"] in ("vector", "table"): if filepath in self.vector_layer_params: return self.vector_layer_params[filepath] options = QgsVectorLayer.LayerOptions() options.loadDefaultStyle = False - lyr = QgsVectorLayer(filepath, param['name'], 'ogr', options) + lyr = QgsVectorLayer(filepath, param["name"], "ogr", options) self.vector_layer_params[filepath] = lyr - elif param['type'] == 'raster': + elif param["type"] == "raster": options = QgsRasterLayer.LayerOptions() options.loadDefaultStyle = False - lyr = QgsRasterLayer(filepath, param['name'], 'gdal', options) + lyr = QgsRasterLayer(filepath, param["name"], "gdal", options) - self.assertTrue(lyr.isValid(), 'Could not load layer "{}" from param {}'.format(filepath, param)) + self.assertTrue( + lyr.isValid(), + 'Could not load layer "{}" from param {}'.format(filepath, param), + ) QgsProject.instance().addMapLayer(lyr) return lyr @@ -265,18 +287,18 @@ def filepath_from_param(self, param): Creates a filepath from a param """ prefix = processingTestDataPath() - if 'location' in param and param['location'] == 'qgs': + if "location" in param and param["location"] == "qgs": prefix = unitTestDataPath() - if 'uri' in param: - path = param['uri'] + if "uri" in param: + path = param["uri"] else: - path = os.path.join(prefix, param['location']) + path = os.path.join(prefix, param["location"]) return self.uri_path_join(prefix, path) def uri_path_join(self, prefix, filepath): - if filepath.startswith('ogr:'): + if filepath.startswith("ogr:"): if not prefix[-1] == os.path.sep: prefix += os.path.sep filepath = re.sub(r"dbname='", "dbname='{}".format(prefix), filepath) @@ -290,72 +312,99 @@ def check_results(self, results, context, params, expected): Checks if result produced by an algorithm matches with the expected specification. """ for id, expected_result in expected.items(): - if expected_result['type'] in ('vector', 'table'): - if 'compare' in expected_result and not expected_result['compare']: + if expected_result["type"] in ("vector", "table"): + if "compare" in expected_result and not expected_result["compare"]: # skipping the comparison, so just make sure output is valid if isinstance(results[id], QgsMapLayer): result_lyr = results[id] else: - result_lyr = QgsProcessingUtils.mapLayerFromString(results[id], context) + result_lyr = QgsProcessingUtils.mapLayerFromString( + results[id], context + ) self.assertTrue(result_lyr.isValid()) continue expected_lyrs = self.load_layers(id, expected_result) - if 'in_place_result' in expected_result: - result_lyr = QgsProcessingUtils.mapLayerFromString(self.in_place_layers[id], context) + if "in_place_result" in expected_result: + result_lyr = QgsProcessingUtils.mapLayerFromString( + self.in_place_layers[id], context + ) self.assertTrue(result_lyr.isValid(), self.in_place_layers[id]) else: try: results[id] except KeyError as e: - raise KeyError('Expected result {} does not exist in {}'.format(str(e), list(results.keys()))) + raise KeyError( + "Expected result {} does not exist in {}".format( + str(e), list(results.keys()) + ) + ) if isinstance(results[id], QgsMapLayer): result_lyr = results[id] else: - result_lyr = QgsProcessingUtils.mapLayerFromString(results[id], context) + result_lyr = QgsProcessingUtils.mapLayerFromString( + results[id], context + ) self.assertTrue(result_lyr, results[id]) - compare = expected_result.get('compare', {}) - pk = expected_result.get('pk', None) - topo_equal_check = expected_result.get('topo_equal_check', False) + compare = expected_result.get("compare", {}) + pk = expected_result.get("pk", None) + topo_equal_check = expected_result.get("topo_equal_check", False) if len(expected_lyrs) == 1: - self.assertLayersEqual(expected_lyrs[0], result_lyr, compare=compare, pk=pk, geometry={'topo_equal_check': topo_equal_check}) + self.assertLayersEqual( + expected_lyrs[0], + result_lyr, + compare=compare, + pk=pk, + geometry={"topo_equal_check": topo_equal_check}, + ) else: res = False for l in expected_lyrs: - if self.checkLayersEqual(l, result_lyr, compare=compare, pk=pk, geometry={'topo_equal_check': topo_equal_check}): + if self.checkLayersEqual( + l, + result_lyr, + compare=compare, + pk=pk, + geometry={"topo_equal_check": topo_equal_check}, + ): res = True break - self.assertTrue(res, 'Could not find matching layer in expected results') + self.assertTrue( + res, "Could not find matching layer in expected results" + ) - elif 'rasterhash' == expected_result['type']: + elif "rasterhash" == expected_result["type"]: print("id:{} result:{}".format(id, results[id])) - self.assertTrue(os.path.exists(results[id]), 'File does not exist: {}, {}'.format(results[id], params)) + self.assertTrue( + os.path.exists(results[id]), + "File does not exist: {}, {}".format(results[id], params), + ) dataset = gdal.Open(results[id], GA_ReadOnly) dataArray = nan_to_num(dataset.ReadAsArray(0)) strhash = hashlib.sha224(dataArray.data).hexdigest() - if not isinstance(expected_result['hash'], str): - self.assertIn(strhash, expected_result['hash']) + if not isinstance(expected_result["hash"], str): + self.assertIn(strhash, expected_result["hash"]) else: - self.assertEqual(strhash, expected_result['hash']) - elif 'file' == expected_result['type']: + self.assertEqual(strhash, expected_result["hash"]) + elif "file" == expected_result["type"]: expected_filepath = self.filepath_from_param(expected_result) result_filepath = results[id] self.assertFilesEqual(expected_filepath, result_filepath) - elif 'directory' == expected_result['type']: + elif "directory" == expected_result["type"]: expected_dirpath = self.filepath_from_param(expected_result) result_dirpath = results[id] self.assertDirectoriesEqual(expected_dirpath, result_dirpath) - elif 'regex' == expected_result['type']: - with open(results[id], 'r') as file: + elif "regex" == expected_result["type"]: + with open(results[id], "r") as file: data = file.read() - for rule in expected_result.get('rules', []): + for rule in expected_result.get("rules", []): self.assertRegex(data, rule) @@ -369,6 +418,7 @@ class GenericAlgorithmsTest(unittest.TestCase): def setUpClass(cls): start_app() from processing.core.Processing import Processing + Processing.initialize() QgsApplication.processingRegistry().addProvider(QgsNativeAlgorithms()) cls.cleanup_paths = [] @@ -376,15 +426,16 @@ def setUpClass(cls): @classmethod def tearDownClass(cls): from processing.core.Processing import Processing + Processing.deinitialize() for path in cls.cleanup_paths: shutil.rmtree(path) def testAlgorithmCompliance(self): for p in QgsApplication.processingRegistry().providers(): - print('testing provider {}'.format(p.id())) + print("testing provider {}".format(p.id())) for a in p.algorithms(): - print('testing algorithm {}'.format(a.id())) + print("testing algorithm {}".format(a.id())) self.check_algorithm(a) def check_algorithm(self, alg): @@ -392,5 +443,5 @@ def check_algorithm(self, alg): alg.helpUrl() -if __name__ == '__main__': - nose2.main() \ No newline at end of file +if __name__ == "__main__": + nose2.main() diff --git a/tests/test_CustomButtonSetup.py b/tests/test_CustomButtonSetup.py index 304de0c6a..9c9dd0251 100644 --- a/tests/test_CustomButtonSetup.py +++ b/tests/test_CustomButtonSetup.py @@ -24,11 +24,13 @@ import sys from qgis.testing import unittest -from DsgTools.gui.ProductionTools.Toolboxes.CustomFeatureToolBox.customButtonSetup import (CustomButtonSetup, - CustomFeatureButton) +from DsgTools.gui.ProductionTools.Toolboxes.CustomFeatureToolBox.customButtonSetup import ( + CustomButtonSetup, + CustomFeatureButton, +) -class ButtonTester(unittest.TestCase): +class ButtonTester(unittest.TestCase): def test_constructorNoArgs(self): """Runs class constructor checks when no args are provided.""" b = CustomFeatureButton() @@ -47,6 +49,7 @@ def test_constructorNoArgs(self): self.assertEquals(b.isChecked(), False) self.assertEquals(b.isEnabled(), False) from qgis.PyQt.QtWidgets import QPushButton + p = { "name": "New button", "openForm": False, @@ -62,7 +65,7 @@ def test_constructorNoArgs(self): "digitizingTool": "default", "isCheckable": False, "isChecked": False, - "isEnabled": False + "isEnabled": False, } self.assertEquals(b.properties(), p) @@ -74,7 +77,7 @@ def test_supportedTools(self): "default": "QGIS default feature extraction tool", "freeHandAcquisiton": "DSGTools: Free Hand Acquisition", "circle2points": "QGIS Circle extraction tool", - "acquisition": "DSGTools: Right Degree Angle Digitizing" + "acquisition": "DSGTools: Right Degree Angle Digitizing", } self.assertEquals(b.supportedTools(), tools) @@ -99,8 +102,8 @@ def test_newWidget(self): # asserts whether "old" widgets are updated. self.assertEquals(pb.font().pointSize(), 100) -class SetupTester(unittest.TestCase): +class SetupTester(unittest.TestCase): def test_emptyConstructor(self): """Runs class constructor with no args passed to it""" s = CustomButtonSetup() @@ -117,7 +120,7 @@ def test_constructor(self): s = CustomButtonSetup( buttonsProps=[b.properties() for b in (b1, b2, b3)], displayName="My setup", - description="..." + description="...", ) self.assertEquals(s.name(), "My setup") self.assertEquals(s.description(), "...") @@ -157,11 +160,11 @@ def test_removeButton(self): def test_groupButtons(self): """Tests if grouping buttons work""" from collections import defaultdict + b1 = CustomFeatureButton({"name": "Button 1", "category": "Cat 1"}) b2 = CustomFeatureButton({"name": "Button 2", "isCheckable": True}) b3 = CustomFeatureButton({"name": "Button 3", "color": (10, 2, 45, 5)}) - s = CustomButtonSetup( - buttonsProps=[b.properties() for b in (b1, b2, b3)]) + s = CustomButtonSetup(buttonsProps=[b.properties() for b in (b1, b2, b3)]) groups = defaultdict(set) for b in s.buttons(): if b.name() == b1.name(): @@ -175,8 +178,7 @@ def test_setSize(self): b1 = CustomFeatureButton({"size": 5}) b2 = CustomFeatureButton({"size": 5}) b3 = CustomFeatureButton({"size": 5}) - s = CustomButtonSetup( - buttonsProps=[b.properties() for b in (b1, b2, b3)]) + s = CustomButtonSetup(buttonsProps=[b.properties() for b in (b1, b2, b3)]) for b in s.buttons(): self.assertEquals(b.size(), 5) s.setButtonsSize(10) @@ -188,8 +190,7 @@ def test_checkKeyword(self): b1 = CustomFeatureButton({"name": "B1", "keywords": set(["test"])}) b2 = CustomFeatureButton({"name": "B2", "keywords": set(["test"])}) b3 = CustomFeatureButton({"name": "B3"}) - s = CustomButtonSetup( - buttonsProps=[b.properties() for b in (b1, b2, b3)]) + s = CustomButtonSetup(buttonsProps=[b.properties() for b in (b1, b2, b3)]) self.assertEquals(s.checkKeyword("test"), [b1, b2]) def test_toggleButton(self): @@ -201,22 +202,23 @@ def test_toggleButton(self): s.toggleButton(s.button("New button 2"), True) self.assertEquals( {b.name(): b.isChecked() for b in s.buttons()}, - {"New button": False, "New button 1": False, "New button 2": True} + {"New button": False, "New button 1": False, "New button 2": True}, ) s.toggleButton(s.button("New button"), True) self.assertEquals( {b.name(): b.isChecked() for b in s.buttons()}, - {"New button": True, "New button 1": False, "New button 2": False} + {"New button": True, "New button 1": False, "New button 2": False}, ) s.toggleButton(s.button("New button 1"), True) self.assertEquals( {b.name(): b.isChecked() for b in s.buttons()}, - {"New button": False, "New button 1": True, "New button 2": False} + {"New button": False, "New button 1": True, "New button 2": False}, ) + def run_all(filterString=None): """Default function that is called by the runner if nothing else is specified""" - filterString = 'test_' if filterString is None else filterString + filterString = "test_" if filterString is None else filterString suite = unittest.TestSuite() suite.addTests(unittest.makeSuite(ButtonTester, filterString)) suite.addTests(unittest.makeSuite(SetupTester, filterString)) diff --git a/tests/test_DsgToolsProcessingModel.py b/tests/test_DsgToolsProcessingModel.py index 2a1ee5164..00937f11d 100644 --- a/tests/test_DsgToolsProcessingModel.py +++ b/tests/test_DsgToolsProcessingModel.py @@ -24,10 +24,12 @@ import sys from qgis.testing import unittest -from DsgTools.core.DSGToolsProcessingAlgs.Models.dsgToolsProcessingModel import DsgToolsProcessingModel +from DsgTools.core.DSGToolsProcessingAlgs.Models.dsgToolsProcessingModel import ( + DsgToolsProcessingModel, +) -class ModelTester(unittest.TestCase): +class ModelTester(unittest.TestCase): def test_constructor(self): """Runs class constructor checks.""" # name and set of parameters are mandatory, even if they're invalid @@ -38,9 +40,10 @@ def test_constructor(self): self.assertFalse(model.isValid()) self.assertEquals(model.name(), "Invalid model") + def run_all(filterString=None): """Default function that is called by the runner if nothing else is specified""" - filterString = 'test_' if filterString is None else filterString + filterString = "test_" if filterString is None else filterString suite = unittest.TestSuite() suite.addTests(unittest.makeSuite(ModelTester, filterString)) - unittest.TextTestRunner(verbosity=3, stream=sys.stdout).run(suite) \ No newline at end of file + unittest.TextTestRunner(verbosity=3, stream=sys.stdout).run(suite) diff --git a/tests/test_EnvironmentSetterAlgorithms.py b/tests/test_EnvironmentSetterAlgorithms.py index ef25d9c0f..00c06b6e8 100644 --- a/tests/test_EnvironmentSetterAlgorithms.py +++ b/tests/test_EnvironmentSetterAlgorithms.py @@ -26,39 +26,40 @@ from qgis.testing import unittest from qgis.core import QgsProcessingFeedback, QgsProcessingContext -class EnvironmentSetterAlgorithmsTest(unittest.TestCase): +class EnvironmentSetterAlgorithmsTest(unittest.TestCase): def test_setfreehandtoolparametersalgorithm(self): parameters = { - 'FREE_HAND_TOLERANCE' : 10, - 'FREE_HAND_SMOOTH_ITERATIONS' : 20, - 'FREE_HAND_SMOOTH_OFFSET' : 30, - 'ALG_ITERATIONS' : 40, - 'UNDO_POINTS' : 50, - 'FREE_HAND_FINAL_SIMPLIFY_TOLERANCE' : 60 - } + "FREE_HAND_TOLERANCE": 10, + "FREE_HAND_SMOOTH_ITERATIONS": 20, + "FREE_HAND_SMOOTH_OFFSET": 30, + "ALG_ITERATIONS": 40, + "UNDO_POINTS": 50, + "FREE_HAND_FINAL_SIMPLIFY_TOLERANCE": 60, + } QSETTINGS_DICT = { - 'FREE_HAND_TOLERANCE' : 'freeHandTolerance', - 'FREE_HAND_SMOOTH_ITERATIONS' : 'freeHandSmoothIterations', - 'FREE_HAND_SMOOTH_OFFSET' : 'freeHandSmoothOffset', - 'ALG_ITERATIONS' : 'algIterations', - 'UNDO_POINTS' : 'undoPoints', - 'FREE_HAND_FINAL_SIMPLIFY_TOLERANCE' : 'freeHandFinalSimplifyTolerance' + "FREE_HAND_TOLERANCE": "freeHandTolerance", + "FREE_HAND_SMOOTH_ITERATIONS": "freeHandSmoothIterations", + "FREE_HAND_SMOOTH_OFFSET": "freeHandSmoothOffset", + "ALG_ITERATIONS": "algIterations", + "UNDO_POINTS": "undoPoints", + "FREE_HAND_FINAL_SIMPLIFY_TOLERANCE": "freeHandFinalSimplifyTolerance", } processing.run( - 'dsgtools:setfreehandtoolparametersalgorithm', + "dsgtools:setfreehandtoolparametersalgorithm", parameters, - context = QgsProcessingContext(), - feedback = QgsProcessingFeedback() + context=QgsProcessingContext(), + feedback=QgsProcessingFeedback(), ) settings = QSettings() - settings.beginGroup('PythonPlugins/DsgTools/Options') + settings.beginGroup("PythonPlugins/DsgTools/Options") for key, value in parameters.items(): storedValue = settings.value(QSETTINGS_DICT[key]) self.assertEqual(storedValue, value) + def run_all(): """Default function that is called by the runner if nothing else is specified""" suite = unittest.TestSuite() - suite.addTests(unittest.makeSuite(EnvironmentSetterAlgorithmsTest, 'test')) - unittest.TextTestRunner(verbosity=3, stream=sys.stdout).run(suite) \ No newline at end of file + suite.addTests(unittest.makeSuite(EnvironmentSetterAlgorithmsTest, "test")) + unittest.TextTestRunner(verbosity=3, stream=sys.stdout).run(suite) diff --git a/tests/test_ExternalFilesHandler.py b/tests/test_ExternalFilesHandler.py index b1374d14b..730c20c20 100644 --- a/tests/test_ExternalFilesHandler.py +++ b/tests/test_ExternalFilesHandler.py @@ -26,8 +26,15 @@ from qgis.testing import unittest -from DsgTools.core.NetworkTools.ExternalFilesHandler import ExternalFilesHandler, ExternalFileDownloadProcessor -from DsgTools.core.DSGToolsProcessingAlgs.Algs.LayerManagementAlgs.spellChecker.datasets.ptBR import WordDatasetPtBRFileHandler, PalavrasFileHandler +from DsgTools.core.NetworkTools.ExternalFilesHandler import ( + ExternalFilesHandler, + ExternalFileDownloadProcessor, +) +from DsgTools.core.DSGToolsProcessingAlgs.Algs.LayerManagementAlgs.spellChecker.datasets.ptBR import ( + WordDatasetPtBRFileHandler, + PalavrasFileHandler, +) + class ExternalFilesHandlerTest(unittest.TestCase): @classmethod @@ -40,29 +47,23 @@ def setUpClass(cls): output_folder=os.path.abspath(os.path.dirname(__file__)) ), ] + @classmethod def tearDownClass(cls): for handler in cls.handlerList: - os.unlink( - handler.getFullPath() - ) + os.unlink(handler.getFullPath()) def test_downloadfilesalgorithm(self): filesHandler = ExternalFilesHandler() - output = filesHandler.downloadFilesAlgorithm( - self.handlerList - ) + output = filesHandler.downloadFilesAlgorithm(self.handlerList) self.assertTrue(output) for handler in self.handlerList: - self.assertTrue( - os.path.exists( - handler.getFullPath() - ) - ) + self.assertTrue(os.path.exists(handler.getFullPath())) + def run_all(filterString=None): """Default function that is called by the runner if nothing else is specified""" - filterString = 'test_' if filterString is None else filterString + filterString = "test_" if filterString is None else filterString suite = unittest.TestSuite() suite.addTests(unittest.makeSuite(ExternalFilesHandlerTest, filterString)) - unittest.TextTestRunner(verbosity=3, stream=sys.stdout).run(suite) \ No newline at end of file + unittest.TextTestRunner(verbosity=3, stream=sys.stdout).run(suite) diff --git a/tests/test_OtherAlgorithms.py b/tests/test_OtherAlgorithms.py index 5e0217595..918be84d9 100644 --- a/tests/test_OtherAlgorithms.py +++ b/tests/test_OtherAlgorithms.py @@ -36,19 +36,27 @@ import processing from qgis.utils import iface -from qgis.core import QgsDataSourceUri, QgsVectorLayer, QgsProcessingFeedback,\ - QgsProcessingContext, QgsLayerTreeLayer, QgsProject +from qgis.core import ( + QgsDataSourceUri, + QgsVectorLayer, + QgsProcessingFeedback, + QgsProcessingContext, + QgsLayerTreeLayer, + QgsProject, +) from qgis.PyQt.QtSql import QSqlDatabase from DsgTools.core.dsgEnums import DsgEnums from DsgTools.core.Factories.DbFactory.dbFactory import DbFactory -from DsgTools.core.Factories.LayerLoaderFactory.layerLoaderFactory import LayerLoaderFactory +from DsgTools.core.Factories.LayerLoaderFactory.layerLoaderFactory import ( + LayerLoaderFactory, +) from qgis.testing import unittest from DsgTools.tests.algorithmsTestBase import AlgorithmsTest, GenericAlgorithmsTest -class Tester(GenericAlgorithmsTest, AlgorithmsTest): +class Tester(GenericAlgorithmsTest, AlgorithmsTest): @classmethod def setUpClass(cls): cls.cleanup_paths = [] @@ -60,11 +68,12 @@ def tearDownClass(cls): shutil.rmtree(path) def get_definition_file(self): - return 'otherAlgorithms.yaml' + return "otherAlgorithms.yaml" + def run_all(filterString=None): """Default function that is called by the runner if nothing else is specified""" - filterString = 'test_' if filterString is None else filterString + filterString = "test_" if filterString is None else filterString suite = unittest.TestSuite() suite.addTests(unittest.makeSuite(Tester, filterString)) unittest.TextTestRunner(verbosity=3, stream=sys.stdout).run(suite) diff --git a/tests/test_TravisTest.py b/tests/test_TravisTest.py index 8441b41e1..a2839c0ce 100644 --- a/tests/test_TravisTest.py +++ b/tests/test_TravisTest.py @@ -2,13 +2,14 @@ import sys from qgis.testing import unittest -class TestTest(unittest.TestCase): +class TestTest(unittest.TestCase): def test_passes(self): self.assertTrue(True) + def run_all(): """Default function that is called by the runner if nothing else is specified""" suite = unittest.TestSuite() - suite.addTests(unittest.makeSuite(TestTest, 'test')) - unittest.TextTestRunner(verbosity=3, stream=sys.stdout).run(suite) \ No newline at end of file + suite.addTests(unittest.makeSuite(TestTest, "test")) + unittest.TextTestRunner(verbosity=3, stream=sys.stdout).run(suite) diff --git a/tests/test_ValidationAlgorithms.py b/tests/test_ValidationAlgorithms.py index efb51e03b..e776d7e74 100644 --- a/tests/test_ValidationAlgorithms.py +++ b/tests/test_ValidationAlgorithms.py @@ -34,27 +34,31 @@ import processing from qgis.utils import iface -from qgis.core import (QgsProject, - QgsVectorLayer, - QgsDataSourceUri, - QgsLayerTreeLayer, - QgsProcessingContext, - QgsProcessingFeedback, - QgsCoordinateReferenceSystem) +from qgis.core import ( + QgsProject, + QgsVectorLayer, + QgsDataSourceUri, + QgsLayerTreeLayer, + QgsProcessingContext, + QgsProcessingFeedback, + QgsCoordinateReferenceSystem, +) from qgis.PyQt.QtSql import QSqlDatabase from DsgTools.core.dsgEnums import DsgEnums from DsgTools.core.Factories.DbFactory.dbFactory import DbFactory -from DsgTools.core.Factories.LayerLoaderFactory.layerLoaderFactory import LayerLoaderFactory +from DsgTools.core.Factories.LayerLoaderFactory.layerLoaderFactory import ( + LayerLoaderFactory, +) from qgis.testing import unittest + class Tester(unittest.TestCase): - + CURRENT_PATH = os.path.dirname(__file__) DEFAULT_ALG_PATH = os.path.join( - CURRENT_PATH, '..', 'core', 'DSGToolsProcessingAlgs', - 'Algs', 'ValidationAlgs' - ) + CURRENT_PATH, "..", "core", "DSGToolsProcessingAlgs", "Algs", "ValidationAlgs" + ) datasets = dict() def readAvailableAlgs(self, path): @@ -65,7 +69,8 @@ def readAvailableAlgs(self, path): :return: (list-of-str) list of all found algorithms. """ return [ - "dsgtools:{0}".format(os.path.splitext(x)[0].lower()) for x in os.popen( + "dsgtools:{0}".format(os.path.splitext(x)[0].lower()) + for x in os.popen( "ls {path} | grep .py | grep -v __init__ | grep -v pycache".format( path=path ) @@ -85,7 +90,7 @@ def connectToSpatialite(self, path): db.connectDatabase(conn=path) return db - def setSqliteUri(self, uri, layer, geomColumn, sql, pkColumn='id'): + def setSqliteUri(self, uri, layer, geomColumn, sql, pkColumn="id"): """ Configures the URI for a layer from a SpatiaLite dataset. :param uri: (QgsDataSourceUri) URI object to be configured. @@ -95,8 +100,8 @@ def setSqliteUri(self, uri, layer, geomColumn, sql, pkColumn='id'): :param pkColumn: (str) string containing all columns names for attributes composing the table's primary key. """ - uri.setDataSource('', layer, geomColumn, sql, pkColumn) - if sql == '': + uri.setDataSource("", layer, geomColumn, sql, pkColumn) + if sql == "": uri.disableSelectAtId(False) else: uri.disableSelectAtId(True) @@ -128,9 +133,7 @@ def readGeopackage(self, path): for layer in ogr.Open(path): layername = layer.GetName() layers[layername] = QgsVectorLayer( - "{0}|layername={1}".format(path, layername), - layername, - "ogr" + "{0}|layername={1}".format(path, layername), layername, "ogr" ) return layers @@ -141,16 +144,12 @@ def readGeojson(self, path): :return: (dict) map to the geojson folder's layers. """ layers = dict() - fileList = [f for f in next(os.walk(path))[2] if '.geojson' in f] + fileList = [f for f in next(os.walk(path))[2] if ".geojson" in f] for f in fileList: fullPath = os.path.join(path, f) for layer in ogr.Open(fullPath): layername = os.path.splitext(f)[0] - layers[layername] = QgsVectorLayer( - fullPath, - layername, - "ogr" - ) + layers[layername] = QgsVectorLayer(fullPath, layername, "ogr") return layers def testingDataset(self, driver, dataset): @@ -161,36 +160,56 @@ def testingDataset(self, driver, dataset): be given. :return: (dict) a map from layer name to vector layer read from database. """ - spatiaLitePaths = os.path.join(self.CURRENT_PATH, "testing_datasets", 'SpatiaLite') - gpkgPaths = os.path.join(self.CURRENT_PATH, "testing_datasets", 'Geopackage') - geojsonPaths = os.path.join(self.CURRENT_PATH, "testing_datasets", 'GeoJSON') + spatiaLitePaths = os.path.join( + self.CURRENT_PATH, "testing_datasets", "SpatiaLite" + ) + gpkgPaths = os.path.join(self.CURRENT_PATH, "testing_datasets", "Geopackage") + geojsonPaths = os.path.join(self.CURRENT_PATH, "testing_datasets", "GeoJSON") datasets = { - "sqlite" : { - "banco_capacitacao" : os.path.join(spatiaLitePaths, 'banco_capacitacao.sqlite') + "sqlite": { + "banco_capacitacao": os.path.join( + spatiaLitePaths, "banco_capacitacao.sqlite" + ) + }, + "gpkg": { + "testes_wgs84": os.path.join(gpkgPaths, "testes_wgs84.gpkg"), + "testes_sirgas2000_23s": os.path.join( + gpkgPaths, "testes_sirgas2000_23s.gpkg" + ), + "test_dataset_unbuild_polygons": os.path.join( + gpkgPaths, "test_dataset_unbuild_polygons.gpkg" + ), }, - "gpkg" : { - "testes_wgs84" : os.path.join(gpkgPaths, 'testes_wgs84.gpkg'), - "testes_sirgas2000_23s" : os.path.join(gpkgPaths, 'testes_sirgas2000_23s.gpkg'), - "test_dataset_unbuild_polygons" : os.path.join(gpkgPaths, 'test_dataset_unbuild_polygons.gpkg') + "geojson": { + "land_cover_layers": os.path.join(geojsonPaths, "land_cover_layers"), + "terrain_model_layers": os.path.join( + geojsonPaths, "terrain_model_layers" + ), + "testes_sirgas2000_24s": os.path.join( + geojsonPaths, "testes_sirgas2000_24s" + ), + "spatial_rules_alg": os.path.join(geojsonPaths, "spatial_rules_alg"), + "create_frames_layers": os.path.join( + geojsonPaths, "create_frames_layers" + ), + "identify_angles_in_invalid_range_layers": os.path.join( + geojsonPaths, "identify_angles_in_invalid_range_layers" + ), + "douglas_peucker": os.path.join(geojsonPaths, "douglas_peucker"), + "build_polygons_from_center_points": os.path.join( + geojsonPaths, "build_polygons_from_center_points" + ), + "enforce_attribute_rules": os.path.join( + geojsonPaths, "enforce_attribute_rules" + ), + "polygon_sliver": os.path.join(geojsonPaths, "polygon_sliver"), }, - "geojson" : { - "land_cover_layers": os.path.join(geojsonPaths, 'land_cover_layers'), - "terrain_model_layers": os.path.join(geojsonPaths, 'terrain_model_layers'), - "testes_sirgas2000_24s": os.path.join(geojsonPaths, 'testes_sirgas2000_24s'), - "spatial_rules_alg": os.path.join(geojsonPaths, 'spatial_rules_alg'), - "create_frames_layers": os.path.join(geojsonPaths, 'create_frames_layers'), - "identify_angles_in_invalid_range_layers": os.path.join(geojsonPaths, 'identify_angles_in_invalid_range_layers'), - "douglas_peucker": os.path.join(geojsonPaths, 'douglas_peucker'), - "build_polygons_from_center_points": os.path.join(geojsonPaths, 'build_polygons_from_center_points'), - "enforce_attribute_rules": os.path.join(geojsonPaths, 'enforce_attribute_rules'), - "polygon_sliver": os.path.join(geojsonPaths, 'polygon_sliver') - } } # switch-case for dataset reading funcs = { - "sqlite" : lambda ds: self.readSpatiaLite(datasets["sqlite"][ds]), - "gpkg" : lambda ds: self.readGeopackage(datasets["gpkg"][ds]), - "geojson" : lambda ds: self.readGeojson(datasets["geojson"][ds]) + "sqlite": lambda ds: self.readSpatiaLite(datasets["sqlite"][ds]), + "gpkg": lambda ds: self.readGeopackage(datasets["gpkg"][ds]), + "geojson": lambda ds: self.readGeojson(datasets["geojson"][ds]), } layers = dict() if driver in datasets and dataset in datasets[driver]: @@ -202,8 +221,9 @@ def testingDataset(self, driver, dataset): layers = self.datasets[key] return layers - def getInputLayers(self, driver, dataset, layers, - addControlKey=False, idsToSelect=None): + def getInputLayers( + self, driver, dataset, layers, addControlKey=False, idsToSelect=None + ): """ Gets the vector layers from an input dataset. :param driver: (str) driver's to be read. @@ -219,33 +239,31 @@ def getInputLayers(self, driver, dataset, layers, for l in layers: if idsToSelect is not None: # vls[l].rollBack() - lyr = vls[l] if not addControlKey else \ - self.addControlKey(vls[l]) + lyr = vls[l] if not addControlKey else self.addControlKey(vls[l]) lyr.select(idsToSelect) out.append(lyr) else: vls[l].rollBack() - lyr = vls[l] if not addControlKey else \ - self.addControlKey(vls[l]) + lyr = vls[l] if not addControlKey else self.addControlKey(vls[l]) out.append(lyr) return out - + def addControlKey(self, lyr): return processing.run( - 'native:addautoincrementalfield', - { - 'INPUT' : lyr, - 'FIELD_NAME' : 'AUTO', - 'START' : 0, - 'GROUP_FIELDS' : [], - 'SORT_EXPRESSION' : '', - 'SORT_ASCENDING' : True, - 'SORT_NULLS_FIRST' : False, - 'OUTPUT' : 'memory:' - }, - context = QgsProcessingContext(), - feedback = QgsProcessingFeedback() - )['OUTPUT'] + "native:addautoincrementalfield", + { + "INPUT": lyr, + "FIELD_NAME": "AUTO", + "START": 0, + "GROUP_FIELDS": [], + "SORT_EXPRESSION": "", + "SORT_ASCENDING": True, + "SORT_NULLS_FIRST": False, + "OUTPUT": "memory:", + }, + context=QgsProcessingContext(), + feedback=QgsProcessingFeedback(), + )["OUTPUT"] def addLayerToGroup(self, layer, groupname): """ @@ -271,751 +289,785 @@ def algorithmParameters(self, algName): tests. """ parameters = { - "dsgtools:topologicaldouglaspeuckerareasimplification" : [ + "dsgtools:topologicaldouglaspeuckerareasimplification": [ { - '__comment' : "'Normal' test: checks if it works.", - 'INPUTLAYERS' : self.getInputLayers( - 'geojson', 'douglas_peucker', - ['cb_veg_campo_a'], + "__comment": "'Normal' test: checks if it works.", + "INPUTLAYERS": self.getInputLayers( + "geojson", + "douglas_peucker", + ["cb_veg_campo_a"], addControlKey=True, - idsToSelect=None + idsToSelect=None, )[0], - 'SELECTED' : False, - 'SNAP': 1, - 'DOUGLASPARAMETER': 150, - 'FLAGS' : "memory:", - 'OUTPUT' : "memory:" + "SELECTED": False, + "SNAP": 1, + "DOUGLASPARAMETER": 150, + "FLAGS": "memory:", + "OUTPUT": "memory:", }, { - '__comment' : "Second test: checks if it works with onlySelected=True.", - 'INPUTLAYERS' : self.getInputLayers( - 'geojson', 'douglas_peucker', - ['cb_veg_campo_a'], + "__comment": "Second test: checks if it works with onlySelected=True.", + "INPUTLAYERS": self.getInputLayers( + "geojson", + "douglas_peucker", + ["cb_veg_campo_a"], addControlKey=True, - idsToSelect=[1, 2] + idsToSelect=[1, 2], )[0], - 'SELECTED' : True, - 'SNAP': 1, - 'DOUGLASPARAMETER': 150, - 'FLAGS' : "memory:", - 'OUTPUT' : "memory:" - } + "SELECTED": True, + "SNAP": 1, + "DOUGLASPARAMETER": 150, + "FLAGS": "memory:", + "OUTPUT": "memory:", + }, ], - - "dsgtools:topologicaldouglaspeuckerlinesimplification" : [ + "dsgtools:topologicaldouglaspeuckerlinesimplification": [ { - '__comment' : "First test: checks if it works.", - 'INPUTLAYERS' : self.getInputLayers( - 'geojson', 'douglas_peucker', - ['cb_tra_trecho_rodoviario_l'], + "__comment": "First test: checks if it works.", + "INPUTLAYERS": self.getInputLayers( + "geojson", + "douglas_peucker", + ["cb_tra_trecho_rodoviario_l"], addControlKey=True, - idsToSelect=None + idsToSelect=None, )[0], - 'SELECTED' : False, - 'SNAP': 1, - 'DOUGLASPARAMETER': 2.5, - 'FLAGS' : "memory:", - 'OUTPUT' : "memory:" + "SELECTED": False, + "SNAP": 1, + "DOUGLASPARAMETER": 2.5, + "FLAGS": "memory:", + "OUTPUT": "memory:", }, { - '__comment' : "Second test: checks if it works with onlySelected=True.", - 'INPUTLAYERS' : self.getInputLayers( - 'geojson', 'douglas_peucker', - ['cb_tra_trecho_rodoviario_l'], + "__comment": "Second test: checks if it works with onlySelected=True.", + "INPUTLAYERS": self.getInputLayers( + "geojson", + "douglas_peucker", + ["cb_tra_trecho_rodoviario_l"], addControlKey=True, - idsToSelect=[19, 20, 21] + idsToSelect=[19, 20, 21], )[0], - 'SELECTED' : True, - 'SNAP': 1, - 'DOUGLASPARAMETER': 2.5, - 'FLAGS' : "memory:", - 'OUTPUT' : "memory:" - } + "SELECTED": True, + "SNAP": 1, + "DOUGLASPARAMETER": 2.5, + "FLAGS": "memory:", + "OUTPUT": "memory:", + }, ], - - "dsgtools:identifyduplicatedfeatures" : [ + "dsgtools:identifyduplicatedfeatures": [ { - '__comment' : "'Normal' test: checks if it works.", - 'ATTRIBUTE_BLACK_LIST' : [], - 'FLAGS' : "memory:", - 'IGNORE_PK_FIELDS' : True, - 'IGNORE_VIRTUAL_FIELDS' : True, - 'INPUT' : self.getInputLayers( - 'sqlite', 'banco_capacitacao', - ['cb_rel_ponto_cotado_altimetrico_p'] - )[0], - 'SELECTED' : False + "__comment": "'Normal' test: checks if it works.", + "ATTRIBUTE_BLACK_LIST": [], + "FLAGS": "memory:", + "IGNORE_PK_FIELDS": True, + "IGNORE_VIRTUAL_FIELDS": True, + "INPUT": self.getInputLayers( + "sqlite", + "banco_capacitacao", + ["cb_rel_ponto_cotado_altimetrico_p"], + )[0], + "SELECTED": False, } ], - - "dsgtools:identifyoutofboundsangles" : [ + "dsgtools:identifyoutofboundsangles": [ { - '__comment' : "'Normal' test: checks if it works.", - 'FLAGS' : 'memory:', - 'INPUT' : self.getInputLayers( - 'sqlite', 'banco_capacitacao', ['cb_hid_terreno_suj_inundacao_a'] - )[0], - 'SELECTED' : False, - 'TOLERANCE' : 10 + "__comment": "'Normal' test: checks if it works.", + "FLAGS": "memory:", + "INPUT": self.getInputLayers( + "sqlite", + "banco_capacitacao", + ["cb_hid_terreno_suj_inundacao_a"], + )[0], + "SELECTED": False, + "TOLERANCE": 10, } ], - - "dsgtools:identifyoutofboundsanglesincoverage" : [ + "dsgtools:identifyoutofboundsanglesincoverage": [ { - '__comment' : "'Normal' test: checks if it works.", - 'FLAGS' : 'memory:', - 'INPUTLAYERS' : self.getInputLayers( - 'sqlite', 'banco_capacitacao', ['cb_hid_trecho_drenagem_l'] - ), - 'SELECTED' : False, - 'TOLERANCE' : 10 + "__comment": "'Normal' test: checks if it works.", + "FLAGS": "memory:", + "INPUTLAYERS": self.getInputLayers( + "sqlite", "banco_capacitacao", ["cb_hid_trecho_drenagem_l"] + ), + "SELECTED": False, + "TOLERANCE": 10, } ], - - "dsgtools:identifyanglesininvalidrangealgorithm" : [ + "dsgtools:identifyanglesininvalidrangealgorithm": [ { - '__comment' : "'Normal' test: checks if it works.", - 'FLAGS' : 'memory:', - 'INPUT' : self.getInputLayers( - 'geojson', 'identify_angles_in_invalid_range_layers', ['lines1'] + "__comment": "'Normal' test: checks if it works.", + "FLAGS": "memory:", + "INPUT": self.getInputLayers( + "geojson", "identify_angles_in_invalid_range_layers", ["lines1"] )[0], - 'SELECTED' : False, - 'MIN_ANGLE' : 80, - 'MAX_ANGLE' : 100 + "SELECTED": False, + "MIN_ANGLE": 80, + "MAX_ANGLE": 100, } ], - - "dsgtools:identifygaps" : [ + "dsgtools:identifygaps": [ { - '__comment' : "'Normal' test: checks if it works.", - 'FLAGS' : 'memory:', - 'INPUT' : self.getInputLayers( - 'sqlite', 'banco_capacitacao', ['cb_hid_terreno_suj_inundacao_a'] - )[0], - 'SELECTED' : False + "__comment": "'Normal' test: checks if it works.", + "FLAGS": "memory:", + "INPUT": self.getInputLayers( + "sqlite", + "banco_capacitacao", + ["cb_hid_terreno_suj_inundacao_a"], + )[0], + "SELECTED": False, } ], - - "dsgtools:identifyandfixinvalidgeometries" : [ + "dsgtools:identifyandfixinvalidgeometries": [ { - '__comment' : "'Normal' test: checks if it works. This test does not check fixes!", - 'FLAGS' : 'memory:', - 'INPUT' : self.getInputLayers( - 'sqlite', 'banco_capacitacao', ['cb_veg_campo_a'] - )[0], - 'IGNORE_CLOSED' : False, - 'SELECTED' : False, - 'TYPE' : False + "__comment": "'Normal' test: checks if it works. This test does not check fixes!", + "FLAGS": "memory:", + "INPUT": self.getInputLayers( + "sqlite", "banco_capacitacao", ["cb_veg_campo_a"] + )[0], + "IGNORE_CLOSED": False, + "SELECTED": False, + "TYPE": False, } ], - - "dsgtools:identifyduplicatedgeometries" : [ + "dsgtools:identifyduplicatedgeometries": [ { - '__comment' : "'Normal' test: checks if it works.", - 'FLAGS' : 'memory:', - 'INPUT' : self.getInputLayers( - 'sqlite', 'banco_capacitacao', ['cb_rel_ponto_cotado_altimetrico_p'] - )[0], - 'SELECTED' : False + "__comment": "'Normal' test: checks if it works.", + "FLAGS": "memory:", + "INPUT": self.getInputLayers( + "sqlite", + "banco_capacitacao", + ["cb_rel_ponto_cotado_altimetrico_p"], + )[0], + "SELECTED": False, } ], - - "dsgtools:identifyduplicatedlinesoncoverage" : [ + "dsgtools:identifyduplicatedlinesoncoverage": [ { - '__comment' : "'Normal' test: checks if it works.", - 'FLAGS' : 'memory:', - 'INPUTLAYERS' : self.getInputLayers( - 'sqlite', 'banco_capacitacao', - ['cb_hid_corredeira_l', 'cb_hid_trecho_drenagem_l'] - ), - 'SELECTED' : False + "__comment": "'Normal' test: checks if it works.", + "FLAGS": "memory:", + "INPUTLAYERS": self.getInputLayers( + "sqlite", + "banco_capacitacao", + ["cb_hid_corredeira_l", "cb_hid_trecho_drenagem_l"], + ), + "SELECTED": False, } ], - - "dsgtools:identifysmalllines" : [ + "dsgtools:identifysmalllines": [ { - '__comment' : "'Normal' test: checks if it works.", - 'FLAGS' : 'memory:', - 'INPUT' : self.getInputLayers( - 'sqlite', 'banco_capacitacao', ['cb_hid_trecho_drenagem_l'] - )[0], - 'SELECTED' : False, - 'TOLERANCE' : 5 + "__comment": "'Normal' test: checks if it works.", + "FLAGS": "memory:", + "INPUT": self.getInputLayers( + "sqlite", "banco_capacitacao", ["cb_hid_trecho_drenagem_l"] + )[0], + "SELECTED": False, + "TOLERANCE": 5, } ], - - "dsgtools:identifyduplicatedpolygonsoncoverage" : [ + "dsgtools:identifyduplicatedpolygonsoncoverage": [ { - '__comment' : "'Normal' test: checks if it works.", - 'FLAGS' : 'memory:', - 'INPUTLAYERS' : self.getInputLayers( - 'sqlite', 'banco_capacitacao', - ['cb_veg_campo_a', 'cb_veg_floresta_a'] - ), - 'SELECTED' : False - + "__comment": "'Normal' test: checks if it works.", + "FLAGS": "memory:", + "INPUTLAYERS": self.getInputLayers( + "sqlite", + "banco_capacitacao", + ["cb_veg_campo_a", "cb_veg_floresta_a"], + ), + "SELECTED": False, } ], - - "dsgtools:identifysmallpolygons" : [ + "dsgtools:identifysmallpolygons": [ { - '__comment' : "'Normal' test: checks if it works.", - 'FLAGS': 'memory:', - 'INPUT': self.getInputLayers( - 'sqlite', 'banco_capacitacao', ['cb_veg_campo_a'] - )[0], - 'SELECTED': False, - 'TOLERANCE': 625 + "__comment": "'Normal' test: checks if it works.", + "FLAGS": "memory:", + "INPUT": self.getInputLayers( + "sqlite", "banco_capacitacao", ["cb_veg_campo_a"] + )[0], + "SELECTED": False, + "TOLERANCE": 625, } ], - - "dsgtools:identifydangles" : [ + "dsgtools:identifydangles": [ { - '__comment' : "'Normal' test: checks if it works.", - 'FLAGS' : 'memory:', - 'IGNOREINNER' : False, - 'INPUT' : self.getInputLayers( - 'sqlite', 'banco_capacitacao', ['cb_hid_trecho_drenagem_l'] - )[0], - 'LINEFILTERLAYERS' : '', - 'POLYGONFILTERLAYERS' : '', - 'SELECTED' : False, - 'TOLERANCE' : 2, - 'TYPE' : False + "__comment": "'Normal' test: checks if it works.", + "FLAGS": "memory:", + "IGNOREINNER": False, + "INPUT": self.getInputLayers( + "sqlite", "banco_capacitacao", ["cb_hid_trecho_drenagem_l"] + )[0], + "LINEFILTERLAYERS": "", + "POLYGONFILTERLAYERS": "", + "SELECTED": False, + "TOLERANCE": 2, + "TYPE": False, } ], - - "dsgtools:identifyduplicatedpointsoncoverage" : [ + "dsgtools:identifyduplicatedpointsoncoverage": [ { - '__comment' : "'Normal' test: checks if it works.", - 'FLAGS' : 'memory:', - 'INPUTLAYERS' : self.getInputLayers( - 'sqlite', 'banco_capacitacao', - ['cb_adm_edif_pub_civil_p', 'cb_rel_ponto_cotado_altimetrico_p'] - ), - 'SELECTED' : False + "__comment": "'Normal' test: checks if it works.", + "FLAGS": "memory:", + "INPUTLAYERS": self.getInputLayers( + "sqlite", + "banco_capacitacao", + [ + "cb_adm_edif_pub_civil_p", + "cb_rel_ponto_cotado_altimetrico_p", + ], + ), + "SELECTED": False, } ], - - "dsgtools:identifyoverlaps" : [ + "dsgtools:identifyoverlaps": [ { - '__comment' : "'Normal' test: checks if it works.", - 'FLAGS': "memory:", - 'INPUT': self.getInputLayers( - 'sqlite', 'banco_capacitacao', ['cb_hid_ilha_a'] - )[0], - 'SELECTED': False + "__comment": "'Normal' test: checks if it works.", + "FLAGS": "memory:", + "INPUT": self.getInputLayers( + "sqlite", "banco_capacitacao", ["cb_hid_ilha_a"] + )[0], + "SELECTED": False, } ], - "dsgtools:identifyvertexnearedges" : [ + "dsgtools:identifyvertexnearedges": [ { - '__comment' : "'Normal' test: checks if it works with polygon.", - 'FLAGS': "memory:", - 'INPUT': self.getInputLayers( - 'geojson', 'testes_sirgas2000_24s', ['test1_vertexnearedge_a'] - )[0], - 'SEARCH_RADIUS':1, - 'SELECTED': False + "__comment": "'Normal' test: checks if it works with polygon.", + "FLAGS": "memory:", + "INPUT": self.getInputLayers( + "geojson", "testes_sirgas2000_24s", ["test1_vertexnearedge_a"] + )[0], + "SEARCH_RADIUS": 1, + "SELECTED": False, }, { - '__comment' : "'Normal' test: checks if it works with line.", - 'FLAGS': "memory:", - 'INPUT': self.getInputLayers( - 'geojson', 'testes_sirgas2000_24s', ['test2_vertexnearedge_l'] - )[0], - 'SEARCH_RADIUS':1, - 'SELECTED': False - } + "__comment": "'Normal' test: checks if it works with line.", + "FLAGS": "memory:", + "INPUT": self.getInputLayers( + "geojson", "testes_sirgas2000_24s", ["test2_vertexnearedge_l"] + )[0], + "SEARCH_RADIUS": 1, + "SELECTED": False, + }, ], - "dsgtools:removeduplicatedfeatures" : [ + "dsgtools:removeduplicatedfeatures": [ { - '__comment' : "'Normal' test: checks if it works.", - 'ATTRIBUTE_BLACK_LIST' : [], - 'IGNORE_PK_FIELDS' : True, - 'IGNORE_VIRTUAL_FIELDS' : True, - 'INPUT' : self.getInputLayers( - 'sqlite', 'banco_capacitacao', ['cb_rel_ponto_cotado_altimetrico_p'] - )[0], - 'SELECTED' : False + "__comment": "'Normal' test: checks if it works.", + "ATTRIBUTE_BLACK_LIST": [], + "IGNORE_PK_FIELDS": True, + "IGNORE_VIRTUAL_FIELDS": True, + "INPUT": self.getInputLayers( + "sqlite", + "banco_capacitacao", + ["cb_rel_ponto_cotado_altimetrico_p"], + )[0], + "SELECTED": False, } ], - - "dsgtools:removeduplicatedgeometries" : [ + "dsgtools:removeduplicatedgeometries": [ { - '__comment' : "'Normal' test: checks if it works.", - 'FLAGS' : 'memory:', - 'INPUT' : self.getInputLayers( - 'sqlite', 'banco_capacitacao', ['cb_rel_ponto_cotado_altimetrico_p'] - )[0], - 'SELECTED' : False + "__comment": "'Normal' test: checks if it works.", + "FLAGS": "memory:", + "INPUT": self.getInputLayers( + "sqlite", + "banco_capacitacao", + ["cb_rel_ponto_cotado_altimetrico_p"], + )[0], + "SELECTED": False, } ], - - "dsgtools:removesmalllines" : [ + "dsgtools:removesmalllines": [ { - '__comment' : "'Normal' test: checks if it works.", - 'INPUT' : self.getInputLayers( - 'sqlite', 'banco_capacitacao', ['cb_hid_trecho_drenagem_l'] - )[0], - 'SELECTED' : False, - 'TOLERANCE' : 5 + "__comment": "'Normal' test: checks if it works.", + "INPUT": self.getInputLayers( + "sqlite", "banco_capacitacao", ["cb_hid_trecho_drenagem_l"] + )[0], + "SELECTED": False, + "TOLERANCE": 5, } ], - - "dsgtools:removesmallpolygons" : [ + "dsgtools:removesmallpolygons": [ { - '__comment' : "'Normal' test: checks if it works.", - 'INPUT' : self.getInputLayers( - 'sqlite', 'banco_capacitacao', ['cb_veg_campo_a'] - )[0], - 'SELECTED' : False, - 'TOLERANCE' : 625 + "__comment": "'Normal' test: checks if it works.", + "INPUT": self.getInputLayers( + "sqlite", "banco_capacitacao", ["cb_veg_campo_a"] + )[0], + "SELECTED": False, + "TOLERANCE": 625, } ], - - "dsgtools:overlayelementswithareas" : [ + "dsgtools:overlayelementswithareas": [ { - '__comment' : "'Normal' test: checks if it works.", - 'BEHAVIOR' : 0, - 'INPUT' : self.getInputLayers( - 'gpkg', 'testes_sirgas2000_23s', ['camada_linha_1'] - )[0], - 'OVERLAY' : self.getInputLayers( - 'gpkg', 'testes_sirgas2000_23s', ['camada_poligono_1'] - )[0], - 'SELECTED' : False, - 'SELECTED_OVERLAY' : False + "__comment": "'Normal' test: checks if it works.", + "BEHAVIOR": 0, + "INPUT": self.getInputLayers( + "gpkg", "testes_sirgas2000_23s", ["camada_linha_1"] + )[0], + "OVERLAY": self.getInputLayers( + "gpkg", "testes_sirgas2000_23s", ["camada_poligono_1"] + )[0], + "SELECTED": False, + "SELECTED_OVERLAY": False, } ], - - "dsgtools:deaggregategeometries" : [ + "dsgtools:deaggregategeometries": [ { - '__comment' : "'Normal' test: checks if it works.", - 'INPUT' : self.getInputLayers( - 'gpkg', 'testes_sirgas2000_23s', ['camada_linha_1'], addControlKey=True - )[0], - 'SELECTED' : False + "__comment": "'Normal' test: checks if it works.", + "INPUT": self.getInputLayers( + "gpkg", + "testes_sirgas2000_23s", + ["camada_linha_1"], + addControlKey=True, + )[0], + "SELECTED": False, } ], - - "dsgtools:dissolvepolygonswithsameattributes" : [ + "dsgtools:dissolvepolygonswithsameattributes": [ { - '__comment' : "'Normal' test: checks if it works.", - 'ATTRIBUTE_BLACK_LIST' : [], - 'IGNORE_PK_FIELDS' : True, - 'IGNORE_VIRTUAL_FIELDS' : True, - 'INPUT' : self.getInputLayers( - 'gpkg', 'testes_sirgas2000_23s', ['camada_poligono_1'] - )[0], - 'MIN_AREA' : None, - 'SELECTED' : False + "__comment": "'Normal' test: checks if it works.", + "ATTRIBUTE_BLACK_LIST": [], + "IGNORE_PK_FIELDS": True, + "IGNORE_VIRTUAL_FIELDS": True, + "INPUT": self.getInputLayers( + "gpkg", "testes_sirgas2000_23s", ["camada_poligono_1"] + )[0], + "MIN_AREA": None, + "SELECTED": False, } ], - - "dsgtools:removeemptyandupdate" : [ + "dsgtools:removeemptyandupdate": [ { - '__comment' : "'Normal' test: checks if it works.", - 'INPUT' : self.getInputLayers( - 'gpkg', 'testes_sirgas2000_23s', ['camada_linha_2'] - )[0], - 'SELECTED' : False + "__comment": "'Normal' test: checks if it works.", + "INPUT": self.getInputLayers( + "gpkg", "testes_sirgas2000_23s", ["camada_linha_2"] + )[0], + "SELECTED": False, } ], - - "dsgtools:lineonlineoverlayer" : [ + "dsgtools:lineonlineoverlayer": [ { - '__comment' : "'Normal' test: checks if it works.", - 'INPUT' : self.getInputLayers( - 'gpkg', 'testes_sirgas2000_23s', ['camada_linha_4'] - )[0], - 'SELECTED' : False, - 'TOLERANCE' : 1 + "__comment": "'Normal' test: checks if it works.", + "INPUT": self.getInputLayers( + "gpkg", "testes_sirgas2000_23s", ["camada_linha_4"] + )[0], + "SELECTED": False, + "TOLERANCE": 1, } ], - - "dsgtools:mergelineswithsameattributeset" : [ + "dsgtools:mergelineswithsameattributeset": [ { - '__comment' : "'Normal' test: checks if it works.", - 'ATTRIBUTE_BLACK_LIST' : ['OGC_FID'], - 'IGNORE_NETWORK' : True, - 'IGNORE_PK_FIELDS' : True, - 'IGNORE_VIRTUAL_FIELDS' : True, - 'INPUT' : self.getInputLayers( - 'gpkg', 'testes_sirgas2000_23s', ['camada_linha_3'] - )[0], - 'SELECTED' : False + "__comment": "'Normal' test: checks if it works.", + "ATTRIBUTE_BLACK_LIST": ["OGC_FID"], + "IGNORE_NETWORK": True, + "IGNORE_PK_FIELDS": True, + "IGNORE_VIRTUAL_FIELDS": True, + "INPUT": self.getInputLayers( + "gpkg", "testes_sirgas2000_23s", ["camada_linha_3"] + )[0], + "SELECTED": False, } ], - - "dsgtools:snaplayeronlayer" : [ + "dsgtools:snaplayeronlayer": [ { - '__comment' : "'Normal' test: checks if it works.", - 'BEHAVIOR' : 0, - 'INPUT' : self.getInputLayers( - 'gpkg', 'testes_sirgas2000_23s', ['camada_poligono_1'] - )[0], - 'REFERENCE_LAYER' : self.getInputLayers( - 'gpkg', 'testes_sirgas2000_23s', ['camada_poligono_2'] - )[0], - 'SELECTED' : False, - 'TOLERANCE' : 25 + "__comment": "'Normal' test: checks if it works.", + "BEHAVIOR": 0, + "INPUT": self.getInputLayers( + "gpkg", "testes_sirgas2000_23s", ["camada_poligono_1"] + )[0], + "REFERENCE_LAYER": self.getInputLayers( + "gpkg", "testes_sirgas2000_23s", ["camada_poligono_2"] + )[0], + "SELECTED": False, + "TOLERANCE": 25, } ], - - "dsgtools:adjustnetworkconnectivity" : [ + "dsgtools:adjustnetworkconnectivity": [ { - '__comment' : "'Normal' test: checks if it works.", - 'INPUT' : self.getInputLayers( - 'sqlite', 'banco_capacitacao', ['cb_hid_trecho_drenagem_l'] - )[0], - 'SELECTED' : False, - 'TOLERANCE' : 2 + "__comment": "'Normal' test: checks if it works.", + "INPUT": self.getInputLayers( + "sqlite", "banco_capacitacao", ["cb_hid_trecho_drenagem_l"] + )[0], + "SELECTED": False, + "TOLERANCE": 2, } ], - - "dsgtools:identifyunsharedvertexonintersectionsalgorithm" : [ + "dsgtools:identifyunsharedvertexonintersectionsalgorithm": [ { - '__comment' : "'Normal' test: checks if it works.", - 'INPUT_LINES' : self.getInputLayers( - 'gpkg', 'testes_wgs84', ['line_input'] + "__comment": "'Normal' test: checks if it works.", + "INPUT_LINES": self.getInputLayers( + "gpkg", "testes_wgs84", ["line_input"] )[0], - 'INPUT_POLYGONS' : self.getInputLayers( - 'gpkg', 'testes_wgs84', ['polygon_input'] + "INPUT_POLYGONS": self.getInputLayers( + "gpkg", "testes_wgs84", ["polygon_input"] )[0], - 'SELECTED' : False, - 'FLAGS' : "memory:" + "SELECTED": False, + "FLAGS": "memory:", } ], - - "dsgtools:unbuildpolygonsalgorithm" : [ + "dsgtools:unbuildpolygonsalgorithm": [ { - '__comment' : "'Normal' test: checks if it works.", - 'INPUT_POLYGONS' : self.getInputLayers( - 'geojson', 'land_cover_layers', ['vegetation'] + "__comment": "'Normal' test: checks if it works.", + "INPUT_POLYGONS": self.getInputLayers( + "geojson", "land_cover_layers", ["vegetation"] )[0], - 'SELECTED' : False, - 'CONSTRAINT_LINE_LAYERS' : self.getInputLayers( - 'geojson', 'land_cover_layers', ['fence', 'road'] + "SELECTED": False, + "CONSTRAINT_LINE_LAYERS": self.getInputLayers( + "geojson", "land_cover_layers", ["fence", "road"] ), - 'CONSTRAINT_POLYGON_LAYERS' : self.getInputLayers( - 'geojson', 'land_cover_layers', ['water'] + "CONSTRAINT_POLYGON_LAYERS": self.getInputLayers( + "geojson", "land_cover_layers", ["water"] ), - 'GEOGRAPHIC_BOUNDARY' : '', - 'OUTPUT_CENTER_POINTS' : "memory:", - 'OUTPUT_BOUNDARIES' : "memory:" + "GEOGRAPHIC_BOUNDARY": "", + "OUTPUT_CENTER_POINTS": "memory:", + "OUTPUT_BOUNDARIES": "memory:", } ], - "dsgtools:buildpolygonsfromcenterpointsandboundariesalgorithm" : [ + "dsgtools:buildpolygonsfromcenterpointsandboundariesalgorithm": [ { - '__comment' : "'Normal' test: checks if it works.", - "INPUT_CENTER_POINTS" : self.getInputLayers( - 'geojson', 'land_cover_layers', ['center_points_test1'] + "__comment": "'Normal' test: checks if it works.", + "INPUT_CENTER_POINTS": self.getInputLayers( + "geojson", "land_cover_layers", ["center_points_test1"] )[0], - 'SELECTED' : False, - 'ATTRIBUTE_BLACK_LIST' : [], - 'CONSTRAINT_LINE_LAYERS' : self.getInputLayers( - 'geojson', 'land_cover_layers', ['fence', 'road', 'boundaries'] + "SELECTED": False, + "ATTRIBUTE_BLACK_LIST": [], + "CONSTRAINT_LINE_LAYERS": self.getInputLayers( + "geojson", "land_cover_layers", ["fence", "road", "boundaries"] ), - 'CONSTRAINT_POLYGON_LAYERS' : self.getInputLayers( - 'geojson', 'land_cover_layers', ['water'] + "CONSTRAINT_POLYGON_LAYERS": self.getInputLayers( + "geojson", "land_cover_layers", ["water"] ), - 'GEOGRAPHIC_BOUNDARY' : '', - 'OUTPUT_POLYGONS' : "memory:", - 'FLAGS' : "memory:" + "GEOGRAPHIC_BOUNDARY": "", + "OUTPUT_POLYGONS": "memory:", + "FLAGS": "memory:", }, { - '__comment' : "'Normal' test: checks if it works.", - "INPUT_CENTER_POINTS" : self.getInputLayers( - 'geojson', 'land_cover_layers', ['center_points_test2'] + "__comment": "'Normal' test: checks if it works.", + "INPUT_CENTER_POINTS": self.getInputLayers( + "geojson", "land_cover_layers", ["center_points_test2"] )[0], - 'SELECTED' : False, - 'ATTRIBUTE_BLACK_LIST' : [], - 'CONSTRAINT_LINE_LAYERS' : self.getInputLayers( - 'geojson', 'land_cover_layers', ['fence', 'road', 'boundaries'] + "SELECTED": False, + "ATTRIBUTE_BLACK_LIST": [], + "CONSTRAINT_LINE_LAYERS": self.getInputLayers( + "geojson", "land_cover_layers", ["fence", "road", "boundaries"] ), - 'CONSTRAINT_POLYGON_LAYERS' : self.getInputLayers( - 'geojson', 'land_cover_layers', ['water'] + "CONSTRAINT_POLYGON_LAYERS": self.getInputLayers( + "geojson", "land_cover_layers", ["water"] ), - 'GEOGRAPHIC_BOUNDARY' : '', - 'OUTPUT_POLYGONS' : "memory:", - 'FLAGS' : "memory:" + "GEOGRAPHIC_BOUNDARY": "", + "OUTPUT_POLYGONS": "memory:", + "FLAGS": "memory:", }, { - '__comment' : "'Normal' test: checks if it works.", - "INPUT_CENTER_POINTS" : self.getInputLayers( - 'geojson', 'land_cover_layers', ['center_points_test3'] + "__comment": "'Normal' test: checks if it works.", + "INPUT_CENTER_POINTS": self.getInputLayers( + "geojson", "land_cover_layers", ["center_points_test3"] )[0], - 'SELECTED' : False, - 'ATTRIBUTE_BLACK_LIST' : [], - 'CONSTRAINT_LINE_LAYERS' : self.getInputLayers( - 'geojson', 'land_cover_layers', ['fence', 'road', 'boundaries'] + "SELECTED": False, + "ATTRIBUTE_BLACK_LIST": [], + "CONSTRAINT_LINE_LAYERS": self.getInputLayers( + "geojson", "land_cover_layers", ["fence", "road", "boundaries"] ), - 'CONSTRAINT_POLYGON_LAYERS' : self.getInputLayers( - 'geojson', 'land_cover_layers', ['water'] + "CONSTRAINT_POLYGON_LAYERS": self.getInputLayers( + "geojson", "land_cover_layers", ["water"] ), - 'GEOGRAPHIC_BOUNDARY' : '', - 'OUTPUT_POLYGONS' : "memory:", - 'FLAGS' : "memory:" + "GEOGRAPHIC_BOUNDARY": "", + "OUTPUT_POLYGONS": "memory:", + "FLAGS": "memory:", }, { - '__comment' : "'Normal' test: checks if it works.", - "INPUT_CENTER_POINTS" : self.getInputLayers( - 'geojson', 'land_cover_layers', ['center_points_test4'] + "__comment": "'Normal' test: checks if it works.", + "INPUT_CENTER_POINTS": self.getInputLayers( + "geojson", "land_cover_layers", ["center_points_test4"] )[0], - 'SELECTED' : False, - 'ATTRIBUTE_BLACK_LIST' : [], - 'CONSTRAINT_LINE_LAYERS' : self.getInputLayers( - 'geojson', 'land_cover_layers', ['fence', 'road', 'boundaries'] + "SELECTED": False, + "ATTRIBUTE_BLACK_LIST": [], + "CONSTRAINT_LINE_LAYERS": self.getInputLayers( + "geojson", "land_cover_layers", ["fence", "road", "boundaries"] ), - 'CONSTRAINT_POLYGON_LAYERS' : self.getInputLayers( - 'geojson', 'land_cover_layers', ['water'] + "CONSTRAINT_POLYGON_LAYERS": self.getInputLayers( + "geojson", "land_cover_layers", ["water"] ), - 'GEOGRAPHIC_BOUNDARY' : '', - 'OUTPUT_POLYGONS' : "memory:", - 'FLAGS' : "memory:" + "GEOGRAPHIC_BOUNDARY": "", + "OUTPUT_POLYGONS": "memory:", + "FLAGS": "memory:", }, { - '__comment' : "'Normal' test: checks if it works.", - "INPUT_CENTER_POINTS" : self.getInputLayers( - 'geojson', 'land_cover_layers', ['center_points_test5'] + "__comment": "'Normal' test: checks if it works.", + "INPUT_CENTER_POINTS": self.getInputLayers( + "geojson", "land_cover_layers", ["center_points_test5"] )[0], - 'SELECTED' : False, - 'ATTRIBUTE_BLACK_LIST' : [], - 'CONSTRAINT_LINE_LAYERS' : self.getInputLayers( - 'geojson', 'land_cover_layers', ['fence', 'road', 'boundaries'] + "SELECTED": False, + "ATTRIBUTE_BLACK_LIST": [], + "CONSTRAINT_LINE_LAYERS": self.getInputLayers( + "geojson", "land_cover_layers", ["fence", "road", "boundaries"] ), - 'CONSTRAINT_POLYGON_LAYERS' : self.getInputLayers( - 'geojson', 'land_cover_layers', ['water'] + "CONSTRAINT_POLYGON_LAYERS": self.getInputLayers( + "geojson", "land_cover_layers", ["water"] ), - 'GEOGRAPHIC_BOUNDARY' : '', - 'OUTPUT_POLYGONS' : "memory:", - 'FLAGS' : "memory:" + "GEOGRAPHIC_BOUNDARY": "", + "OUTPUT_POLYGONS": "memory:", + "FLAGS": "memory:", }, { - '__comment' : "test 6 - same as test 1, but with geo bounds", - "INPUT_CENTER_POINTS" : self.getInputLayers( - 'geojson', 'land_cover_layers', ['center_points_test1'] + "__comment": "test 6 - same as test 1, but with geo bounds", + "INPUT_CENTER_POINTS": self.getInputLayers( + "geojson", "land_cover_layers", ["center_points_test1"] )[0], - 'SELECTED' : False, - 'ATTRIBUTE_BLACK_LIST' : [], - 'CONSTRAINT_LINE_LAYERS' : self.getInputLayers( - 'geojson', 'land_cover_layers', ['fence', 'road', 'boundaries_within_geo_bounds'] + "SELECTED": False, + "ATTRIBUTE_BLACK_LIST": [], + "CONSTRAINT_LINE_LAYERS": self.getInputLayers( + "geojson", + "land_cover_layers", + ["fence", "road", "boundaries_within_geo_bounds"], ), - 'CONSTRAINT_POLYGON_LAYERS' : self.getInputLayers( - 'geojson', 'land_cover_layers', ['water'] + "CONSTRAINT_POLYGON_LAYERS": self.getInputLayers( + "geojson", "land_cover_layers", ["water"] ), - 'GEOGRAPHIC_BOUNDARY' : self.getInputLayers( - 'geojson', 'land_cover_layers', ['geographic_bounds'] + "GEOGRAPHIC_BOUNDARY": self.getInputLayers( + "geojson", "land_cover_layers", ["geographic_bounds"] )[0], - 'OUTPUT_POLYGONS' : "memory:", - 'FLAGS' : "memory:" + "OUTPUT_POLYGONS": "memory:", + "FLAGS": "memory:", }, { - '__comment' : "test 7 - same as test 2, but with geo bounds", - "INPUT_CENTER_POINTS" : self.getInputLayers( - 'geojson', 'land_cover_layers', ['center_points_test2'] + "__comment": "test 7 - same as test 2, but with geo bounds", + "INPUT_CENTER_POINTS": self.getInputLayers( + "geojson", "land_cover_layers", ["center_points_test2"] )[0], - 'SELECTED' : False, - 'ATTRIBUTE_BLACK_LIST' : [], - 'CONSTRAINT_LINE_LAYERS' : self.getInputLayers( - 'geojson', 'land_cover_layers', ['fence', 'road', 'boundaries_within_geo_bounds'] + "SELECTED": False, + "ATTRIBUTE_BLACK_LIST": [], + "CONSTRAINT_LINE_LAYERS": self.getInputLayers( + "geojson", + "land_cover_layers", + ["fence", "road", "boundaries_within_geo_bounds"], ), - 'CONSTRAINT_POLYGON_LAYERS' : self.getInputLayers( - 'geojson', 'land_cover_layers', ['water'] + "CONSTRAINT_POLYGON_LAYERS": self.getInputLayers( + "geojson", "land_cover_layers", ["water"] ), - 'GEOGRAPHIC_BOUNDARY' : self.getInputLayers( - 'geojson', 'land_cover_layers', ['geographic_bounds'] + "GEOGRAPHIC_BOUNDARY": self.getInputLayers( + "geojson", "land_cover_layers", ["geographic_bounds"] )[0], - 'OUTPUT_POLYGONS' : "memory:", - 'FLAGS' : "memory:" + "OUTPUT_POLYGONS": "memory:", + "FLAGS": "memory:", }, { - '__comment' : "test 8 - same as test 3, but with geo bounds", - "INPUT_CENTER_POINTS" : self.getInputLayers( - 'geojson', 'land_cover_layers', ['center_points_test3'] + "__comment": "test 8 - same as test 3, but with geo bounds", + "INPUT_CENTER_POINTS": self.getInputLayers( + "geojson", "land_cover_layers", ["center_points_test3"] )[0], - 'SELECTED' : False, - 'ATTRIBUTE_BLACK_LIST' : [], - 'CONSTRAINT_LINE_LAYERS' : self.getInputLayers( - 'geojson', 'land_cover_layers', ['fence', 'road', 'boundaries_within_geo_bounds'] + "SELECTED": False, + "ATTRIBUTE_BLACK_LIST": [], + "CONSTRAINT_LINE_LAYERS": self.getInputLayers( + "geojson", + "land_cover_layers", + ["fence", "road", "boundaries_within_geo_bounds"], ), - 'CONSTRAINT_POLYGON_LAYERS' : self.getInputLayers( - 'geojson', 'land_cover_layers', ['water'] + "CONSTRAINT_POLYGON_LAYERS": self.getInputLayers( + "geojson", "land_cover_layers", ["water"] ), - 'GEOGRAPHIC_BOUNDARY' : self.getInputLayers( - 'geojson', 'land_cover_layers', ['geographic_bounds'] + "GEOGRAPHIC_BOUNDARY": self.getInputLayers( + "geojson", "land_cover_layers", ["geographic_bounds"] )[0], - 'OUTPUT_POLYGONS' : "memory:", - 'FLAGS' : "memory:" + "OUTPUT_POLYGONS": "memory:", + "FLAGS": "memory:", }, { - '__comment' : "test 9 - same as test 4, but with geo bounds", - "INPUT_CENTER_POINTS" : self.getInputLayers( - 'geojson', 'land_cover_layers', ['center_points_test4'] + "__comment": "test 9 - same as test 4, but with geo bounds", + "INPUT_CENTER_POINTS": self.getInputLayers( + "geojson", "land_cover_layers", ["center_points_test4"] )[0], - 'SELECTED' : False, - 'ATTRIBUTE_BLACK_LIST' : [], - 'CONSTRAINT_LINE_LAYERS' : self.getInputLayers( - 'geojson', 'land_cover_layers', ['fence', 'road', 'boundaries_within_geo_bounds'] + "SELECTED": False, + "ATTRIBUTE_BLACK_LIST": [], + "CONSTRAINT_LINE_LAYERS": self.getInputLayers( + "geojson", + "land_cover_layers", + ["fence", "road", "boundaries_within_geo_bounds"], ), - 'CONSTRAINT_POLYGON_LAYERS' : self.getInputLayers( - 'geojson', 'land_cover_layers', ['water'] + "CONSTRAINT_POLYGON_LAYERS": self.getInputLayers( + "geojson", "land_cover_layers", ["water"] ), - 'GEOGRAPHIC_BOUNDARY' : self.getInputLayers( - 'geojson', 'land_cover_layers', ['geographic_bounds'] + "GEOGRAPHIC_BOUNDARY": self.getInputLayers( + "geojson", "land_cover_layers", ["geographic_bounds"] )[0], - 'OUTPUT_POLYGONS' : "memory:", - 'FLAGS' : "memory:" + "OUTPUT_POLYGONS": "memory:", + "FLAGS": "memory:", }, { - '__comment' : "test 10 - same as test 5, but with geo bounds", - "INPUT_CENTER_POINTS" : self.getInputLayers( - 'geojson', 'land_cover_layers', ['center_points_test5'] + "__comment": "test 10 - same as test 5, but with geo bounds", + "INPUT_CENTER_POINTS": self.getInputLayers( + "geojson", "land_cover_layers", ["center_points_test5"] )[0], - 'SELECTED' : False, - 'ATTRIBUTE_BLACK_LIST' : [], - 'CONSTRAINT_LINE_LAYERS' : self.getInputLayers( - 'geojson', 'land_cover_layers', ['fence', 'road', 'boundaries_within_geo_bounds'] + "SELECTED": False, + "ATTRIBUTE_BLACK_LIST": [], + "CONSTRAINT_LINE_LAYERS": self.getInputLayers( + "geojson", + "land_cover_layers", + ["fence", "road", "boundaries_within_geo_bounds"], ), - 'CONSTRAINT_POLYGON_LAYERS' : self.getInputLayers( - 'geojson', 'land_cover_layers', ['water'] + "CONSTRAINT_POLYGON_LAYERS": self.getInputLayers( + "geojson", "land_cover_layers", ["water"] ), - 'GEOGRAPHIC_BOUNDARY' : self.getInputLayers( - 'geojson', 'land_cover_layers', ['geographic_bounds'] + "GEOGRAPHIC_BOUNDARY": self.getInputLayers( + "geojson", "land_cover_layers", ["geographic_bounds"] )[0], - 'OUTPUT_POLYGONS' : "memory:", - 'FLAGS' : "memory:" + "OUTPUT_POLYGONS": "memory:", + "FLAGS": "memory:", }, { - '__comment' : "test 11 - without polygons, just lines, with attributeblacklist", - "INPUT_CENTER_POINTS" : self.getInputLayers( - 'geojson', 'build_polygons_from_center_points', ['pontos'] + "__comment": "test 11 - without polygons, just lines, with attributeblacklist", + "INPUT_CENTER_POINTS": self.getInputLayers( + "geojson", "build_polygons_from_center_points", ["pontos"] )[0], - 'SELECTED' : False, - 'ATTRIBUTE_BLACK_LIST' : ['id','nome','tipo_comprovacao','tipo_insumo','observacao', 'data_modificacao', 'controle_id', 'ultimo_usuario'], - 'CONSTRAINT_LINE_LAYERS' : self.getInputLayers( - 'geojson', 'build_polygons_from_center_points', ['linhas1', 'linhas2'] + "SELECTED": False, + "ATTRIBUTE_BLACK_LIST": [ + "id", + "nome", + "tipo_comprovacao", + "tipo_insumo", + "observacao", + "data_modificacao", + "controle_id", + "ultimo_usuario", + ], + "CONSTRAINT_LINE_LAYERS": self.getInputLayers( + "geojson", + "build_polygons_from_center_points", + ["linhas1", "linhas2"], ), - 'CONSTRAINT_POLYGON_LAYERS' : None, - 'GEOGRAPHIC_BOUNDARY' : None, - 'OUTPUT_POLYGONS' : "memory:", - 'FLAGS' : "memory:" + "CONSTRAINT_POLYGON_LAYERS": None, + "GEOGRAPHIC_BOUNDARY": None, + "OUTPUT_POLYGONS": "memory:", + "FLAGS": "memory:", }, { - '__comment' : "test 12 - without polygons, just lines, with attributeblacklist and geoboundary. Should create 5 pol, not 6. The tip of the triangle is outside of the boundary ", - "INPUT_CENTER_POINTS" : self.getInputLayers( - 'geojson', 'build_polygons_from_center_points', ['pontos'] + "__comment": "test 12 - without polygons, just lines, with attributeblacklist and geoboundary. Should create 5 pol, not 6. The tip of the triangle is outside of the boundary ", + "INPUT_CENTER_POINTS": self.getInputLayers( + "geojson", "build_polygons_from_center_points", ["pontos"] )[0], - 'SELECTED' : False, - 'ATTRIBUTE_BLACK_LIST' : ['id','nome','tipo_comprovacao','tipo_insumo','observacao', 'data_modificacao', 'controle_id', 'ultimo_usuario'], - 'CONSTRAINT_LINE_LAYERS' : self.getInputLayers( - 'geojson', 'build_polygons_from_center_points', ['linhas1', 'linhas2'] + "SELECTED": False, + "ATTRIBUTE_BLACK_LIST": [ + "id", + "nome", + "tipo_comprovacao", + "tipo_insumo", + "observacao", + "data_modificacao", + "controle_id", + "ultimo_usuario", + ], + "CONSTRAINT_LINE_LAYERS": self.getInputLayers( + "geojson", + "build_polygons_from_center_points", + ["linhas1", "linhas2"], ), - 'CONSTRAINT_POLYGON_LAYERS' : None, - 'GEOGRAPHIC_BOUNDARY' : self.getInputLayers( - 'geojson', 'build_polygons_from_center_points', ['moldura'] + "CONSTRAINT_POLYGON_LAYERS": None, + "GEOGRAPHIC_BOUNDARY": self.getInputLayers( + "geojson", "build_polygons_from_center_points", ["moldura"] )[0], - 'OUTPUT_POLYGONS' : "memory:", - 'FLAGS' : "memory:" + "OUTPUT_POLYGONS": "memory:", + "FLAGS": "memory:", }, { - '__comment' : "test 13 - without polygons, just lines, with a different attributeblacklist", - "INPUT_CENTER_POINTS" : self.getInputLayers( - 'geojson', 'build_polygons_from_center_points', ['pontos'] + "__comment": "test 13 - without polygons, just lines, with a different attributeblacklist", + "INPUT_CENTER_POINTS": self.getInputLayers( + "geojson", "build_polygons_from_center_points", ["pontos"] )[0], - 'SELECTED' : False, - 'ATTRIBUTE_BLACK_LIST' : ['id','nome','tipo_comprovacao','tipo_insumo','observacao'], - 'CONSTRAINT_LINE_LAYERS' : self.getInputLayers( - 'geojson', 'build_polygons_from_center_points', ['linhas1', 'linhas2'] + "SELECTED": False, + "ATTRIBUTE_BLACK_LIST": [ + "id", + "nome", + "tipo_comprovacao", + "tipo_insumo", + "observacao", + ], + "CONSTRAINT_LINE_LAYERS": self.getInputLayers( + "geojson", + "build_polygons_from_center_points", + ["linhas1", "linhas2"], ), - 'CONSTRAINT_POLYGON_LAYERS' : None, - 'GEOGRAPHIC_BOUNDARY' : None, - 'OUTPUT_POLYGONS' : "memory:", - 'FLAGS' : "memory:" - } + "CONSTRAINT_POLYGON_LAYERS": None, + "GEOGRAPHIC_BOUNDARY": None, + "OUTPUT_POLYGONS": "memory:", + "FLAGS": "memory:", + }, ], - "dsgtools:identifyterrainmodelerrorsalgorithm" : [ + "dsgtools:identifyterrainmodelerrorsalgorithm": [ { - '__comment' : "test 1", - "INPUT" : self.getInputLayers( - 'geojson', 'terrain_model_layers', ['contours_test1'] + "__comment": "test 1", + "INPUT": self.getInputLayers( + "geojson", "terrain_model_layers", ["contours_test1"] )[0], - 'SELECTED' : False, - 'CONTOUR_ATTR':'contour', - 'CONTOUR_INTERVAL':10, - 'TOPOLOGY_RADIUS':2, - 'GEOGRAPHIC_BOUNDS' : self.getInputLayers( - 'geojson', 'terrain_model_layers', ['geographic_bounds_test1'] + "SELECTED": False, + "CONTOUR_ATTR": "contour", + "CONTOUR_INTERVAL": 10, + "TOPOLOGY_RADIUS": 2, + "GEOGRAPHIC_BOUNDS": self.getInputLayers( + "geojson", "terrain_model_layers", ["geographic_bounds_test1"] )[0], - 'POINT_FLAGS' : "memory:", - 'LINE_FLAGS' : "memory:" + "POINT_FLAGS": "memory:", + "LINE_FLAGS": "memory:", }, { - '__comment' : "test 2", - "INPUT" : self.getInputLayers( - 'geojson', 'terrain_model_layers', ['contours_test2'] + "__comment": "test 2", + "INPUT": self.getInputLayers( + "geojson", "terrain_model_layers", ["contours_test2"] )[0], - 'SELECTED' : False, - 'CONTOUR_ATTR':'contour', - 'CONTOUR_INTERVAL':10, - 'TOPOLOGY_RADIUS':2, - 'GEOGRAPHIC_BOUNDS' : self.getInputLayers( - 'geojson', 'terrain_model_layers', ['geographic_bounds_test2'] + "SELECTED": False, + "CONTOUR_ATTR": "contour", + "CONTOUR_INTERVAL": 10, + "TOPOLOGY_RADIUS": 2, + "GEOGRAPHIC_BOUNDS": self.getInputLayers( + "geojson", "terrain_model_layers", ["geographic_bounds_test2"] )[0], - 'POINT_FLAGS' : "memory:", - 'LINE_FLAGS' : "memory:" + "POINT_FLAGS": "memory:", + "LINE_FLAGS": "memory:", }, { - '__comment' : "test 3", - "INPUT" : self.getInputLayers( - 'geojson', 'terrain_model_layers', ['contours_test3'] + "__comment": "test 3", + "INPUT": self.getInputLayers( + "geojson", "terrain_model_layers", ["contours_test3"] )[0], - 'SELECTED' : False, - 'CONTOUR_ATTR':'contour', - 'CONTOUR_INTERVAL':10, - 'TOPOLOGY_RADIUS':2, - 'GEOGRAPHIC_BOUNDS' : self.getInputLayers( - 'geojson', 'terrain_model_layers', ['geographic_bounds_test3'] + "SELECTED": False, + "CONTOUR_ATTR": "contour", + "CONTOUR_INTERVAL": 10, + "TOPOLOGY_RADIUS": 2, + "GEOGRAPHIC_BOUNDS": self.getInputLayers( + "geojson", "terrain_model_layers", ["geographic_bounds_test3"] )[0], - 'POINT_FLAGS' : "memory:", - 'LINE_FLAGS' : "memory:" + "POINT_FLAGS": "memory:", + "LINE_FLAGS": "memory:", }, { - '__comment' : "test 4", - "INPUT" : self.getInputLayers( - 'geojson', 'terrain_model_layers', ['contours_test4'] + "__comment": "test 4", + "INPUT": self.getInputLayers( + "geojson", "terrain_model_layers", ["contours_test4"] )[0], - 'SELECTED' : False, - 'CONTOUR_ATTR':'contour', - 'CONTOUR_INTERVAL':10, - 'TOPOLOGY_RADIUS':2, - 'GEOGRAPHIC_BOUNDS' : self.getInputLayers( - 'geojson', 'terrain_model_layers', ['geographic_bounds_test4'] + "SELECTED": False, + "CONTOUR_ATTR": "contour", + "CONTOUR_INTERVAL": 10, + "TOPOLOGY_RADIUS": 2, + "GEOGRAPHIC_BOUNDS": self.getInputLayers( + "geojson", "terrain_model_layers", ["geographic_bounds_test4"] )[0], - 'POINT_FLAGS' : "memory:", - 'LINE_FLAGS' : "memory:" + "POINT_FLAGS": "memory:", + "LINE_FLAGS": "memory:", }, { - '__comment' : "test 5", - "INPUT" : self.getInputLayers( - 'geojson', 'terrain_model_layers', ['contours_test5'] + "__comment": "test 5", + "INPUT": self.getInputLayers( + "geojson", "terrain_model_layers", ["contours_test5"] )[0], - 'SELECTED' : False, - 'CONTOUR_ATTR':'contour', - 'CONTOUR_INTERVAL':10, - 'TOPOLOGY_RADIUS':2, - 'GEOGRAPHIC_BOUNDS' : self.getInputLayers( - 'geojson', 'terrain_model_layers', ['geographic_bounds_test5'] + "SELECTED": False, + "CONTOUR_ATTR": "contour", + "CONTOUR_INTERVAL": 10, + "TOPOLOGY_RADIUS": 2, + "GEOGRAPHIC_BOUNDS": self.getInputLayers( + "geojson", "terrain_model_layers", ["geographic_bounds_test5"] )[0], - 'POINT_FLAGS' : "memory:", - 'LINE_FLAGS' : "memory:" - } + "POINT_FLAGS": "memory:", + "LINE_FLAGS": "memory:", + }, ], - # '__comment' : "'Normal' test: checks if it works." - - "dsgtools:enforcespatialrules" : [ + # '__comment' : "'Normal' test: checks if it works." + "dsgtools:enforcespatialrules": [ { - '__comment' : "Tests 1 - tests all topological relation", + "__comment": "Tests 1 - tests all topological relation", "RULES_SET": [ { "cardinality": "1..1", @@ -1026,7 +1078,7 @@ def algorithmParameters(self, algName): "layer_b": "rel_ponto_cotado_altimetrico_p", "name": "Pico deve estar em cima de um ponto cotado", "predicate": 0, - "useDE9IM": False + "useDE9IM": False, }, { "cardinality": "1..*", @@ -1037,7 +1089,7 @@ def algorithmParameters(self, algName): "layer_b": "hid_massa_dagua_a", "name": "Pontos cotados altimétricos não podem estar sobre massa d’água", "predicate": 2, - "useDE9IM": False + "useDE9IM": False, }, { "cardinality": "1..*", @@ -1048,7 +1100,7 @@ def algorithmParameters(self, algName): "layer_b": "enc_trecho_energia_l", "name": "Torres de energia devem estar sobre um ou mais trechos de energia", "predicate": 3, - "useDE9IM": False + "useDE9IM": False, }, { "cardinality": "2..2", @@ -1059,7 +1111,7 @@ def algorithmParameters(self, algName): "layer_b": "hid_trecho_drenagem_l", "name": "Barragens tipo ponto estão entre 2 e somente trechos de drenagem", "predicate": 5, - "useDE9IM": False + "useDE9IM": False, }, { "cardinality": "1..1", @@ -1070,7 +1122,7 @@ def algorithmParameters(self, algName): "layer_b": "hid_area_umida_a", "name": "Brejo/Pantano deve estar contido por uma Área Úmida", "predicate": 9, - "useDE9IM": False + "useDE9IM": False, }, { "cardinality": "1..*", @@ -1081,7 +1133,7 @@ def algorithmParameters(self, algName): "layer_b": "fer_trecho_ferroviario_l", "name": "O modalUso de Ponte deve ser Ferroviario se esta intersectar um Trecho Ferroviario.", "predicate": 3, - "useDE9IM": False + "useDE9IM": False, }, { "cardinality": "1..*", @@ -1092,7 +1144,7 @@ def algorithmParameters(self, algName): "layer_b": "fer_trecho_ferroviario_l", "name": "O modalUso de Ponte deve ser Ferroviario se esta intersectar um Trecho Ferroviario.", "predicate": 4, - "useDE9IM": False + "useDE9IM": False, }, { "cardinality": "1..*", @@ -1103,7 +1155,7 @@ def algorithmParameters(self, algName): "layer_b": "hid_vala_l", "name": "Valas não são sobrepostas por drenagens", "predicate": 12, - "useDE9IM": False + "useDE9IM": False, }, { "cardinality": "0..1", @@ -1114,7 +1166,7 @@ def algorithmParameters(self, algName): "layer_b": "hid_trecho_drenagem_l", "name": "Barragens do tipo área contêm até uma drenagem", "predicate": 13, - "useDE9IM": False + "useDE9IM": False, }, { "cardinality": "0..1", @@ -1125,7 +1177,7 @@ def algorithmParameters(self, algName): "layer_b": "poligonos", "name": "Teste: 'linhas' não cruza 'poligonos'", "predicate": 7, - "useDE9IM": False + "useDE9IM": False, }, { "cardinality": "1..*", @@ -1136,7 +1188,7 @@ def algorithmParameters(self, algName): "layer_b": "poligonos", "name": "Teste: 'poligonos_2' sobrepõe 'poligonos'", "predicate": 11, - "useDE9IM": False + "useDE9IM": False, }, { "cardinality": "1..*", @@ -1147,7 +1199,7 @@ def algorithmParameters(self, algName): "layer_b": "linhas", "name": "Teste: 'linhas_2' não é igual a 'linhas'", "predicate": 1, - "useDE9IM": False + "useDE9IM": False, }, { "cardinality": "1..*", @@ -1158,7 +1210,7 @@ def algorithmParameters(self, algName): "layer_b": "poligonos_2", "name": "Teste: 'poligonos' não toca 'poligonos_2'", "predicate": 6, - "useDE9IM": False + "useDE9IM": False, }, { "cardinality": "1..*", @@ -1169,7 +1221,7 @@ def algorithmParameters(self, algName): "layer_b": "poligonos_2", "name": "Teste: 'linhas_2' não cruza 'poligonos_2'", "predicate": 8, - "useDE9IM": False + "useDE9IM": False, }, { "cardinality": "1..*", @@ -1180,7 +1232,7 @@ def algorithmParameters(self, algName): "layer_b": "poligonos_2", "name": "Teste: 'points' não está contido em 'poligonos_2'", "predicate": 10, - "useDE9IM": False + "useDE9IM": False, }, { "cardinality": "1..*", @@ -1191,91 +1243,78 @@ def algorithmParameters(self, algName): "layer_b": "points", "name": "Teste: 'poligonos_2' não contém 'points'", "predicate": 14, - "useDE9IM": False - } + "useDE9IM": False, + }, ], "POINT_FLAGS": "memory:", "LINE_FLAGS": "memory:", - "POLYGON_FLAGS": "memory:" + "POLYGON_FLAGS": "memory:", } ], - "dsgtools:enforceattributerulesalgorithm" : [ + "dsgtools:enforceattributerulesalgorithm": [ { - '__comment' : "Test 1", - "RULES_SET":{ - "0": { - "description": "regime - Preencher atributo", - "layerField": [ - "hid_trecho_drenagem_l", - "regime" - ], - "expression": "\"regime\" not in (0,1,2,3,4,5)", - "errorType": "Preencher atributo", - "color": "#b6a500" - } + "__comment": "Test 1", + "RULES_SET": { + "0": { + "description": "regime - Preencher atributo", + "layerField": ["hid_trecho_drenagem_l", "regime"], + "expression": '"regime" not in (0,1,2,3,4,5)', + "errorType": "Preencher atributo", + "color": "#b6a500", + } }, - 'SELECTED' : False, - "POINT_FLAGS":"memory:", - "LINE_FLAGS":"memory:", - "POLYGON_FLAGS":"memory:" + "SELECTED": False, + "POINT_FLAGS": "memory:", + "LINE_FLAGS": "memory:", + "POLYGON_FLAGS": "memory:", }, { - '__comment' : "Test 2", - "RULES_SET":{ - "0": { - "description": "nome - Nome deve iniciar com letra maiuscula e nao deve ter espacos desnecessarios", - "layerField": [ - "hid_ilha_a", - "nome" - ], - "expression": "regexp_match ( \"nome\" , '^ ' ) or regexp_match ( \"nome\" , ' ' ) or regexp_match ( \"nome\" , ' $' ) or regexp_match ( \"nome\" , '^[a-z]' )", - "errorType": "Atributo com valor incorreto", - "color": "#ff0000" - } + "__comment": "Test 2", + "RULES_SET": { + "0": { + "description": "nome - Nome deve iniciar com letra maiuscula e nao deve ter espacos desnecessarios", + "layerField": ["hid_ilha_a", "nome"], + "expression": "regexp_match ( \"nome\" , '^ ' ) or regexp_match ( \"nome\" , ' ' ) or regexp_match ( \"nome\" , ' $' ) or regexp_match ( \"nome\" , '^[a-z]' )", + "errorType": "Atributo com valor incorreto", + "color": "#ff0000", + } }, - 'SELECTED' : True, - "POINT_FLAGS":"memory:", - "LINE_FLAGS":"memory:", - "POLYGON_FLAGS":"memory:" - } + "SELECTED": True, + "POINT_FLAGS": "memory:", + "LINE_FLAGS": "memory:", + "POLYGON_FLAGS": "memory:", + }, ], - - "dsgtools:identifypolygonsliver" : [ + "dsgtools:identifypolygonsliver": [ { - "__comment" : "Checks if simple cases are identified.", + "__comment": "Checks if simple cases are identified.", "INPUT_LAYERS": self.getInputLayers( - 'geojson', 'polygon_sliver', ['poligonos_1'] + "geojson", "polygon_sliver", ["poligonos_1"] ), "RATIO_TOL": 10, "SELECTED": False, "SILENT": True, - "FLAGS": "memory:" + "FLAGS": "memory:", }, { - "__comment" : "Checks if the algorithm works with selected" - " features option on.", + "__comment": "Checks if the algorithm works with selected" + " features option on.", "INPUT_LAYERS": self.getInputLayers( - 'geojson', - 'polygon_sliver', - ['poligonos_1'], - idsToSelect=[0, 1] + "geojson", "polygon_sliver", ["poligonos_1"], idsToSelect=[0, 1] ), "RATIO_TOL": 10, "SELECTED": True, "SILENT": True, - "FLAGS": "memory:" - } + "FLAGS": "memory:", + }, ], - - "dsgtools:ALG" : [ - { - '__comment' : "'Normal' test: checks if it works." - } - ] + "dsgtools:ALG": [{"__comment": "'Normal' test: checks if it works."}], } return parameters[algName] if algName in parameters else dict() - def runAlg(self, algName, parameters, feedback=None, context=None, addControlKey=False): + def runAlg( + self, algName, parameters, feedback=None, context=None, addControlKey=False + ): """ Executes a given algorithm. :param algName: (str) target algorithm's name. @@ -1283,18 +1322,23 @@ def runAlg(self, algName, parameters, feedback=None, context=None, addControlKey :param feedback: (QgsProcessingFeedback) QGIS progress tracking object. :param context: (QgsProcessingContext) execution's environmental parameters. """ - out = processing.run(algName, parameters, None,\ - feedback or QgsProcessingFeedback(), - context or QgsProcessingContext() - ) - outputstr = 'FLAGS' if 'FLAGS' in out else 'OUTPUT' if 'OUTPUT' in out else '' + out = processing.run( + algName, + parameters, + None, + feedback or QgsProcessingFeedback(), + context or QgsProcessingContext(), + ) + outputstr = "FLAGS" if "FLAGS" in out else "OUTPUT" if "OUTPUT" in out else "" if outputstr: out = out[outputstr] return out if not addControlKey else self.addControlKey(out) - - def runAlgWithMultipleOutputs(self, algName, parameters, feedback=None, context=None): + + def runAlgWithMultipleOutputs( + self, algName, parameters, feedback=None, context=None + ): """ - Executes a given algorithm that has multiple outputs. Returns a dict + Executes a given algorithm that has multiple outputs. Returns a dict with the returned layers in the format {'OUTPUT_LAYER_KEY':(QgsVectorLayer) OutputLayer} :param algName: (str) target algorithm's name. :param parameters: (dict) set of arguments for target algorithm. @@ -1313,40 +1357,54 @@ def expectedOutput(self, algName, test, multipleOutputs=False): :return: (QgsVectorLayer) expected output layer. """ rootPath = os.path.join( - self.CURRENT_PATH, 'expected_outputs', algName.split(':')[-1] + self.CURRENT_PATH, "expected_outputs", algName.split(":")[-1] ) gpkgOutput = False for f in next(os.walk(rootPath))[2]: # in case of test case outputs are placed in different folders, this # will not update the gpkgOutput - if '.gpkg' in f.lower(): + if ".gpkg" in f.lower(): gpkgOutput = True break # in case tests are placed as files inside algorithm's expected output # folder, this will retrieve only the output for current test, if not, # this will be evaluated to the path to all outputs in a folder test_TestNr path = os.path.join( - rootPath, - 'test_{test_number}{extension}'.format( - test_number=test, - extension='.gpkg' if gpkgOutput else '' - ) - ) + rootPath, + "test_{test_number}{extension}".format( + test_number=test, extension=".gpkg" if gpkgOutput else "" + ), + ) if os.path.exists(path): if multipleOutputs: - return self.readGeopackage(path) if gpkgOutput else self.readGeojson(path) + return ( + self.readGeopackage(path) if gpkgOutput else self.readGeojson(path) + ) else: - path = path if gpkgOutput else os.path.join( - path, - 'test_{test_number}.geojson'.format(test_number=test) + path = ( + path + if gpkgOutput + else os.path.join( + path, "test_{test_number}.geojson".format(test_number=test) + ) ) return QgsVectorLayer( - path, - "{alg}_test_{test}_output".format(alg=algName.split(':')[-1], test=test), - "ogr" - ) + path, + "{alg}_test_{test}_output".format( + alg=algName.split(":")[-1], test=test + ), + "ogr", + ) - def compareLayers(self, target, reference, attributeBlackList=None, addControlKey=False, distTol=1e-5, areaTol=1e-10): + def compareLayers( + self, + target, + reference, + attributeBlackList=None, + addControlKey=False, + distTol=1e-5, + areaTol=1e-10, + ): """ Compares two vector layers. The algorithm stops on the first difference found. :param target: (QgsVectorLayer) layer to be checked. @@ -1355,44 +1413,48 @@ def compareLayers(self, target, reference, attributeBlackList=None, addControlKe """ # geometry type check attributeBlackList = [] if attributeBlackList is None else attributeBlackList - attributeBlackList += ['AUTO'] if addControlKey else [] + attributeBlackList += ["AUTO"] if addControlKey else [] if target.featureCount() == 0 and reference.featureCount() == 0: return "" if target.geometryType() != reference.geometryType(): return "Incorrect geometry type for the output layer." # feature check - targetFeatDict = {f.id():f for f in target.getFeatures()} - refFeatDict = {f.id():f for f in reference.getFeatures()} + targetFeatDict = {f.id(): f for f in target.getFeatures()} + refFeatDict = {f.id(): f for f in reference.getFeatures()} targetFeaureIds = set(targetFeatDict.keys()) refFeaureIds = set(refFeatDict.keys()) - if target.featureCount() != reference.featureCount(): + if target.featureCount() != reference.featureCount(): msg = "" if targetFeaureIds - refFeaureIds: msg += "Output layer has more features than the control layer (Exceeding ID: {idlist}).\n".format( - idlist=", ".join(map(str, targetFeaureIds - refFeaureIds)) - ) + idlist=", ".join(map(str, targetFeaureIds - refFeaureIds)) + ) if refFeaureIds - targetFeaureIds: msg += "Output layer has fewer features than the control layer (Missing ID: {idlist}).".format( - idlist=", ".join(map(str, refFeaureIds - targetFeaureIds)) - ) + idlist=", ".join(map(str, refFeaureIds - targetFeaureIds)) + ) return msg # attribute names check targetFieldNames = [f.name() for f in target.fields()] for f in reference.fields(): fieldname = f.name() - if fieldname in ['fid', 'AUTO'] or '_otf' in fieldname: + if fieldname in ["fid", "AUTO"] or "_otf" in fieldname: # not sure if this should happen... continue if fieldname not in targetFieldNames: - return "Incorrect set of attributes for output layer (missing '{attr}').".format(attr=fieldname) + return "Incorrect set of attributes for output layer (missing '{attr}').".format( + attr=fieldname + ) msg = "" for featId, refFeat in refFeatDict.items(): if featId not in targetFeatDict: msg = "Feature id={0} was not found on output layer.".format(featId) break testFeat = targetFeatDict[featId] - if not (testFeat.geometry().isGeosEqual(refFeat.geometry()) or\ - testFeat.geometry().equals(refFeat.geometry())): + if not ( + testFeat.geometry().isGeosEqual(refFeat.geometry()) + or testFeat.geometry().equals(refFeat.geometry()) + ): msg = "Feature {fid} has incorrect geometry.".format(fid=featId) break for attr in targetFieldNames: @@ -1403,32 +1465,40 @@ def compareLayers(self, target, reference, attributeBlackList=None, addControlKe fid=featId, attr=attr, test_attr=testFeat[attr], - ref_attr=refFeat[attr] + ref_attr=refFeat[attr], ) break if not msg: return "" # in case a dataset exact match fails, we'll try an approximate comparison - areaSortedRefFeats = sorted(reference.getFeatures(), key=lambda f: f.geometry().area()) - areaSortedTargetFeats = sorted(target.getFeatures(), key=lambda f: f.geometry().area()) + areaSortedRefFeats = sorted( + reference.getFeatures(), key=lambda f: f.geometry().area() + ) + areaSortedTargetFeats = sorted( + target.getFeatures(), key=lambda f: f.geometry().area() + ) for refFeat, targetFeat in zip(areaSortedRefFeats, areaSortedTargetFeats): refGeom = refFeat.geometry() targetGeom = targetFeat.geometry() if refGeom.distance(targetGeom) > distTol: - return "Feature {fid} has incorrect geometry.".format(fid=targetFeat.id()) + return "Feature {fid} has incorrect geometry.".format( + fid=targetFeat.id() + ) refArea = refGeom.area() targetArea = targetGeom.area() if not refArea or abs(targetArea - refArea) / refArea > areaTol: # areas may be similar, but not too different from each other # (minimal CRS transforming and coordinate precision errors) - return "Feature {fid} has incorrect geometry.".format(fid=targetFeat.id()) + return "Feature {fid} has incorrect geometry.".format( + fid=targetFeat.id() + ) for attr in targetFieldNames: if attr not in attributeBlackList and targetFeat[attr] != refFeat[attr]: return "Incorrect set of attributes for feature {fid}:\nAttribute {attr} in the test feature is: {test_attr}\nAttribute {attr} in the reference feature is: {ref_attr}".format( fid=targetFeat.id(), attr=attr, test_attr=targetFeat[attr], - ref_attr=refFeat[attr] + ref_attr=refFeat[attr], ) return "" @@ -1449,9 +1519,16 @@ def clearProject(self): """ QgsProject.instance().clear() - def testAlg(self, algName, feedback=None, context=None, loadLayers=False, - multipleOutputs=False, attributeBlackList=None, - addControlKey=False): + def testAlg( + self, + algName, + feedback=None, + context=None, + loadLayers=False, + multipleOutputs=False, + attributeBlackList=None, + addControlKey=False, + ): """ Tests if the output of a given algorithm is the expected one. :param algName: (str) target algorithm's name. @@ -1475,16 +1552,19 @@ def testAlg(self, algName, feedback=None, context=None, loadLayers=False, expected = None if parameters == dict(): return "Unable to read a set of parameters for {alg}'s tests.".format( - alg=algName - ) + alg=algName + ) try: for i, param in enumerate(parameters): - output = self.runAlgWithMultipleOutputs(algName, param, feedback, context) \ - if multipleOutputs else self.runAlg(algName, param, feedback, context, addControlKey=addControlKey) + output = ( + self.runAlgWithMultipleOutputs(algName, param, feedback, context) + if multipleOutputs + else self.runAlg( + algName, param, feedback, context, addControlKey=addControlKey + ) + ) expected = self.expectedOutput( - algName, - i + 1, - multipleOutputs=multipleOutputs + algName, i + 1, multipleOutputs=multipleOutputs ) if isinstance(output, QgsVectorLayer): self.compareInputLayerWithOutputLayer( @@ -1494,7 +1574,7 @@ def testAlg(self, algName, feedback=None, context=None, loadLayers=False, expected, loadLayers=loadLayers, attributeBlackList=attributeBlackList, - addControlKey=addControlKey + addControlKey=addControlKey, ) if isinstance(output, QgsVectorLayer): output.rollBack() @@ -1507,8 +1587,9 @@ def testAlg(self, algName, feedback=None, context=None, loadLayers=False, if "{0}_{1}".format(key, idx) not in expected: raise Exception( "Output dictionary key {k} was not " - "found in expected output dictionary.".\ - format(k="{0}_{1}".format(key, idx)) + "found in expected output dictionary.".format( + k="{0}_{1}".format(key, idx) + ) ) expectedLyr = expected["{0}_{1}".format(key, idx)] self.compareInputLayerWithOutputLayer( @@ -1518,7 +1599,7 @@ def testAlg(self, algName, feedback=None, context=None, loadLayers=False, expectedLyr, loadLayers=loadLayers, addControlKey=addControlKey, - attributeBlackList=attributeBlackList + attributeBlackList=attributeBlackList, ) if isinstance(expectedLyr, QgsVectorLayer): expectedLyr.rollBack() @@ -1527,8 +1608,10 @@ def testAlg(self, algName, feedback=None, context=None, loadLayers=False, # from now on commands are for single output only continue elif key not in expected: - raise Exception("Output dictionary key was not found in expected output dictionary.".\ - format(alg=algName, nr=i + 1) + raise Exception( + "Output dictionary key was not found in expected output dictionary.".format( + alg=algName, nr=i + 1 + ) ) else: self.compareInputLayerWithOutputLayer( @@ -1538,7 +1621,7 @@ def testAlg(self, algName, feedback=None, context=None, loadLayers=False, expected[key], loadLayers=loadLayers, addControlKey=addControlKey, - attributeBlackList=attributeBlackList + attributeBlackList=attributeBlackList, ) if isinstance(outputLyr, QgsVectorLayer): outputLyr.rollBack() @@ -1549,11 +1632,19 @@ def testAlg(self, algName, feedback=None, context=None, loadLayers=False, if isinstance(output, QgsVectorLayer): output.rollBack() elif isinstance(output, dict): - [lyr.rollBack() for key, lyr in output.items() if isinstance(lyr, QgsVectorLayer)] + [ + lyr.rollBack() + for key, lyr in output.items() + if isinstance(lyr, QgsVectorLayer) + ] if isinstance(expected, QgsVectorLayer): expected.rollBack() elif isinstance(expected, dict): - [lyr.rollBack() for key, lyr in expected.items() if isinstance(lyr, QgsVectorLayer)] + [ + lyr.rollBack() + for key, lyr in expected.items() + if isinstance(lyr, QgsVectorLayer) + ] except: pass return "Test #{nr} for '{alg}' has failed:\n'{msg}'".format( @@ -1561,18 +1652,34 @@ def testAlg(self, algName, feedback=None, context=None, loadLayers=False, ) # missing the output testing return "" - - def compareInputLayerWithOutputLayer(self, i, algName, output, expected, loadLayers=False, attributeBlackList=None, addControlKey=False): + + def compareInputLayerWithOutputLayer( + self, + i, + algName, + output, + expected, + loadLayers=False, + attributeBlackList=None, + addControlKey=False, + ): if not output.isValid(): - raise Exception("Output is an INVALID vector layer.".\ - format(alg=algName, nr=i + 1) - ) + raise Exception( + "Output is an INVALID vector layer.".format(alg=algName, nr=i + 1) + ) if expected is None: - raise Exception("No expected output registered for the test, yet an output was generated.".\ - format(alg=algName, nr=i + 1) + raise Exception( + "No expected output registered for the test, yet an output was generated.".format( + alg=algName, nr=i + 1 ) + ) expected = self.addControlKey(expected) if addControlKey else expected - msg = self.compareLayers(output, expected, attributeBlackList=attributeBlackList, addControlKey=addControlKey) + msg = self.compareLayers( + output, + expected, + attributeBlackList=attributeBlackList, + addControlKey=addControlKey, + ) # once layer is compared, revert all modifications in order to not compromise layer reusage if isinstance(output, QgsVectorLayer): output.rollBack() @@ -1593,35 +1700,47 @@ def testAllAlgorithms(self): # still missing how to define default datasets results = dict() algs = [ - # identification algs - "dsgtools:identifyoutofboundsangles", "dsgtools:identifyoutofboundsanglesincoverage", - "dsgtools:identifygaps", "dsgtools:identifyandfixinvalidgeometries", - "dsgtools:identifyduplicatedfeatures", "dsgtools:identifyduplicatedgeometries", - "dsgtools:identifyduplicatedlinesoncoverage", "dsgtools:identifysmalllines", - "dsgtools:identifyduplicatedpolygonsoncoverage", "dsgtools:identifysmallpolygons", - "dsgtools:identifydangles", "dsgtools:identifyduplicatedpointsoncoverage", - "dsgtools:identifyoverlaps", "dsgtools:identifyvertexnearedges", - "dsgtools:identifyunsharedvertexonintersectionsalgorithm" - # correction algs - "dsgtools:removeduplicatedfeatures", "dsgtools:removeduplicatedgeometries", - "dsgtools:removesmalllines", "dsgtools:removesmallpolygons", - # manipulation algs - "dsgtools:lineonlineoverlayer", "dsgtools:mergelineswithsameattributeset", - "dsgtools:overlayelementswithareas", "dsgtools:deaggregategeometries", - "dsgtools:dissolvepolygonswithsameattributes", "dsgtools:removeemptyandupdate", - "dsgtools:snaplayeronlayer", - # network algs - "dsgtools:adjustnetworkconnectivity" - ] + # identification algs + "dsgtools:identifyoutofboundsangles", + "dsgtools:identifyoutofboundsanglesincoverage", + "dsgtools:identifygaps", + "dsgtools:identifyandfixinvalidgeometries", + "dsgtools:identifyduplicatedfeatures", + "dsgtools:identifyduplicatedgeometries", + "dsgtools:identifyduplicatedlinesoncoverage", + "dsgtools:identifysmalllines", + "dsgtools:identifyduplicatedpolygonsoncoverage", + "dsgtools:identifysmallpolygons", + "dsgtools:identifydangles", + "dsgtools:identifyduplicatedpointsoncoverage", + "dsgtools:identifyoverlaps", + "dsgtools:identifyvertexnearedges", + "dsgtools:identifyunsharedvertexonintersectionsalgorithm" + # correction algs + "dsgtools:removeduplicatedfeatures", + "dsgtools:removeduplicatedgeometries", + "dsgtools:removesmalllines", + "dsgtools:removesmallpolygons", + # manipulation algs + "dsgtools:lineonlineoverlayer", + "dsgtools:mergelineswithsameattributeset", + "dsgtools:overlayelementswithareas", + "dsgtools:deaggregategeometries", + "dsgtools:dissolvepolygonswithsameattributes", + "dsgtools:removeemptyandupdate", + "dsgtools:snaplayeronlayer", + # network algs + "dsgtools:adjustnetworkconnectivity", + ] multipleOutputAlgs = [ # identification algs "dsgtools:enforceattributerulesalgorithm", # manipulation algs "dsgtools:unbuildpolygonsalgorithm", "dsgtools:buildpolygonsfromcenterpointsandboundariesalgorithm", - # manipulation algs + # manipulation algs "dsgtools:topologicaldouglaspeuckerlinesimplification", - "dsgtools:topologicaldouglaspeuckerareasimplification" + "dsgtools:topologicaldouglaspeuckerareasimplification", ] # for alg in self.readAvailableAlgs(self.DEFAULT_ALG_PATH): for alg in algs: @@ -1632,26 +1751,23 @@ def testAllAlgorithms(self): for alg in multipleOutputAlgs: try: results[alg] = self.testAlg( - alg, - multipleOutputs=True, - attributeBlackList=['path'] + alg, multipleOutputs=True, attributeBlackList=["path"] ) except KeyError: results[alg] = "No tests registered." return results - + def test_identifyoutofboundsangles(self): - self.assertEqual( - self.testAlg("dsgtools:identifyoutofboundsangles"), "" - ) - + self.assertEqual(self.testAlg("dsgtools:identifyoutofboundsangles"), "") + def test_identifyanglesininvalidrangealgorithm(self): self.assertEqual( self.testAlg( "dsgtools:identifyanglesininvalidrangealgorithm", multipleOutputs=True, - addControlKey=True - ), "" + addControlKey=True, + ), + "", ) # def test_identifyoutofboundsanglesincoverage(self): @@ -1667,36 +1783,26 @@ def test_identifyanglesininvalidrangealgorithm(self): # self.assertEqual( # self.testAlg("dsgtools:identifygaps"), "" # ) - + def test_identifyandfixinvalidgeometries(self): - self.assertEqual( - self.testAlg("dsgtools:identifyandfixinvalidgeometries"), "" - ) - + self.assertEqual(self.testAlg("dsgtools:identifyandfixinvalidgeometries"), "") + def test_identifyduplicatedfeatures(self): - self.assertEqual( - self.testAlg("dsgtools:identifyduplicatedfeatures"), "" - ) + self.assertEqual(self.testAlg("dsgtools:identifyduplicatedfeatures"), "") def test_identifyduplicatedgeometries(self): - self.assertEqual( - self.testAlg("dsgtools:identifyduplicatedgeometries"), "" - ) + self.assertEqual(self.testAlg("dsgtools:identifyduplicatedgeometries"), "") def test_identifyduplicatedlinesoncoverage(self): - self.assertEqual( - self.testAlg("dsgtools:identifyduplicatedlinesoncoverage"), "" - ) - + self.assertEqual(self.testAlg("dsgtools:identifyduplicatedlinesoncoverage"), "") + def test_identifyduplicatedpointsoncoverage(self): self.assertEqual( self.testAlg("dsgtools:identifyduplicatedpointsoncoverage"), "" ) def test_identifysmalllines(self): - self.assertEqual( - self.testAlg("dsgtools:identifysmalllines"), "" - ) + self.assertEqual(self.testAlg("dsgtools:identifysmalllines"), "") def test_identifyduplicatedpolygonsoncoverage(self): self.assertEqual( @@ -1704,20 +1810,16 @@ def test_identifyduplicatedpolygonsoncoverage(self): ) def test_identifysmallpolygons(self): - self.assertEqual( - self.testAlg("dsgtools:identifysmallpolygons"), "" - ) + self.assertEqual(self.testAlg("dsgtools:identifysmallpolygons"), "") def test_identifydangles(self): - self.assertEqual( - self.testAlg("dsgtools:identifydangles"), "" - ) + self.assertEqual(self.testAlg("dsgtools:identifydangles"), "") def test_identifyunsharedvertexonintersectionsalgorithm(self): self.assertEqual( self.testAlg("dsgtools:identifyunsharedvertexonintersectionsalgorithm"), "" ) - + # def test_identifyvertexnearedges(self): # self.assertEqual( # self.testAlg( @@ -1726,56 +1828,53 @@ def test_identifyunsharedvertexonintersectionsalgorithm(self): # multipleOutputs=True # ), "" # ) - + # def test_overlayelementswithareas(self): # self.assertEqual( # self.testAlg("dsgtools:overlayelementswithareas"), "" # ) - + def test_deaggregategeometries(self): self.assertEqual( self.testAlg("dsgtools:deaggregategeometries", addControlKey=True), "" ) - + def test_dissolvepolygonswithsameattributes(self): self.assertEqual( - self.testAlg("dsgtools:dissolvepolygonswithsameattributes", addControlKey=True), "" + self.testAlg( + "dsgtools:dissolvepolygonswithsameattributes", addControlKey=True + ), + "", ) - + def test_removeemptyandupdate(self): - self.assertEqual( - self.testAlg("dsgtools:removeemptyandupdate"), "" - ) - + self.assertEqual(self.testAlg("dsgtools:removeemptyandupdate"), "") + def test_snaplayeronlayer(self): - self.assertEqual( - self.testAlg("dsgtools:snaplayeronlayer"), "" - ) + self.assertEqual(self.testAlg("dsgtools:snaplayeronlayer"), "") def test_adjustnetworkconnectivity(self): - self.assertEqual( - self.testAlg("dsgtools:adjustnetworkconnectivity"), "" - ) - + self.assertEqual(self.testAlg("dsgtools:adjustnetworkconnectivity"), "") + def test_unbuildpolygonsalgorithm(self): self.assertEqual( self.testAlg( "dsgtools:unbuildpolygonsalgorithm", multipleOutputs=True, - attributeBlackList=['path'], - addControlKey=True + attributeBlackList=["path"], + addControlKey=True, ), - "" + "", ) - + def test_buildpolygonsfromcenterpointsandboundariesalgorithm(self): self.assertEqual( self.testAlg( "dsgtools:buildpolygonsfromcenterpointsandboundariesalgorithm", multipleOutputs=True, - addControlKey=True + addControlKey=True, ), - "" + "", ) def test_identifyterrainmodelerrorsalgorithm(self): @@ -1783,9 +1882,9 @@ def test_identifyterrainmodelerrorsalgorithm(self): self.testAlg( "dsgtools:identifyterrainmodelerrorsalgorithm", multipleOutputs=True, - addControlKey=True + addControlKey=True, ), - "" + "", ) def test_topologicaldouglaspeuckerlinesimplification(self): @@ -1793,9 +1892,9 @@ def test_topologicaldouglaspeuckerlinesimplification(self): self.testAlg( "dsgtools:topologicaldouglaspeuckerlinesimplification", multipleOutputs=True, - addControlKey=True + addControlKey=True, ), - "" + "", ) def test_topologicaldouglaspeuckerareasimplification(self): @@ -1803,17 +1902,19 @@ def test_topologicaldouglaspeuckerareasimplification(self): self.testAlg( "dsgtools:topologicaldouglaspeuckerareasimplification", multipleOutputs=True, - addControlKey=True + addControlKey=True, ), - "" + "", ) def test_enforceattributerulesalgorithm(self): """Tests for Enforce Attribute Rules algorithm""" - + proj = QgsProject.instance() - idsToSelect=[0,3] - testsParams = self.algorithmParameters("dsgtools:enforceattributerulesalgorithm") + idsToSelect = [0, 3] + testsParams = self.algorithmParameters( + "dsgtools:enforceattributerulesalgorithm" + ) # this algorithm, specifically has to set layers Context-reading ready layers = self.testingDataset("geojson", "enforce_attribute_rules") @@ -1824,24 +1925,23 @@ def test_enforceattributerulesalgorithm(self): if isinstance(layers, list): vl = layers[0] proj.addMapLayer(vl) - if parameters['SELECTED']: + if parameters["SELECTED"]: vl.selectByIds(idsToSelect) else: vl = layers[values["layerField"][0]] proj.addMapLayer(vl) - if parameters['SELECTED']: + if parameters["SELECTED"]: vl.selectByIds(idsToSelect) msg = self.testAlg( - "dsgtools:enforceattributerulesalgorithm", - multipleOutputs=True, - addControlKey=True + "dsgtools:enforceattributerulesalgorithm", + multipleOutputs=True, + addControlKey=True, ) - + del self.datasets["geojson:enforce_attribute_rules"] self.clearProject() self.assertEqual(msg, "") - def test_identifypolygonsliver(self): """Tests for Polygon Sliver Algorithm""" @@ -1863,11 +1963,9 @@ def test_enforcespatialrules(self): # vl.setName(l) proj.addMapLayer(layers[l]) msg = self.testAlg( - "dsgtools:enforcespatialrules", - multipleOutputs=True, - addControlKey=True + "dsgtools:enforcespatialrules", multipleOutputs=True, addControlKey=True ) - # since layers were manually removed, cache is going to refer to + # since layers were manually removed, cache is going to refer to # non-existing layers del self.datasets["geojson:spatial_rules_alg"] proj.clear() @@ -1880,9 +1978,10 @@ def test_identifypolygonsliver(self): self.testAlg("dsgtools:identifypolygonsliver", addControlKey=True), "" ) + def run_all(filterString=None): """Default function that is called by the runner if nothing else is specified""" - filterString = 'test_' if filterString is None else filterString + filterString = "test_" if filterString is None else filterString suite = unittest.TestSuite() suite.addTests(unittest.makeSuite(Tester, filterString)) unittest.TextTestRunner(verbosity=3, stream=sys.stdout).run(suite) diff --git a/tests/testing_datasets/GeoJSON/reclassify_adjacent_polygons/polygons.geojson b/tests/testing_datasets/GeoJSON/reclassify_adjacent_polygons/polygons.geojson new file mode 100644 index 000000000..1f6479d13 --- /dev/null +++ b/tests/testing_datasets/GeoJSON/reclassify_adjacent_polygons/polygons.geojson @@ -0,0 +1,31 @@ +{ +"type": "FeatureCollection", +"name": "polygons", +"crs": { "type": "name", "properties": { "name": "urn:ogc:def:crs:OGC:1.3:CRS84" } }, +"features": [ +{ "type": "Feature", "properties": { "type": 1, "id": 1, "area_otf": 2129960642.5990794 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 0.150668887393618, 0.144423004393469 ], [ 0.050735603078626, 0.483085801238719 ], [ 0.111805943493344, 0.483085801238719 ], [ 0.170100359343755, 0.483085801238719 ], [ 0.186755906729588, 0.546932066217741 ], [ 0.186755906729588, 0.652417199661344 ], [ 0.297792889301801, 0.930009656091877 ], [ 0.45846162434825, 0.433584461909898 ], [ 0.514315005317616, 0.261011836094293 ], [ 0.37551877710235, 0.158302627214995 ], [ 0.150668887393618, 0.144423004393469 ] ], [ [ 0.283913266480274, 0.36372104497359 ], [ 0.247826247144305, 0.288771081737346 ], [ 0.289465115608885, 0.252684062401376 ], [ 0.411605796438319, 0.263787760658598 ], [ 0.41715764556693, 0.316530327380399 ], [ 0.372742852538045, 0.374824743230811 ], [ 0.283913266480274, 0.36372104497359 ] ] ] } }, +{ "type": "Feature", "properties": { "type": 1, "id": 1, "area_otf": 2129960642.5990794 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -0.390636402645921, 0.385928441488032 ], [ -0.435051195674806, 0.183285948293743 ], [ -0.523880781732577, 0.316530327380399 ], [ -0.518328932603966, 0.583019085553711 ], [ -0.38508455351731, 0.666296822482871 ], [ -0.390636402645921, 0.385928441488032 ] ], [ [ -0.478118362874304, 0.405366711264735 ], [ -0.445791998681367, 0.377448487643563 ], [ -0.410526874107255, 0.389203529168267 ], [ -0.409057493916667, 0.446509356601199 ], [ -0.422281915631959, 0.514100845368248 ], [ -0.435506337347251, 0.547896589751772 ], [ -0.478118362874304, 0.503815184034131 ], [ -0.478118362874304, 0.405366711264735 ] ] ] } }, +{ "type": "Feature", "properties": { "type": 2, "id": 2, "area_otf": 479688000.03070301 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -0.435051195674806, 0.183285948293743 ], [ -0.390636402645921, 0.385928441488032 ], [ -0.285151269202318, 0.183285948293743 ], [ -0.435051195674806, 0.183285948293743 ] ] ] } }, +{ "type": "Feature", "properties": { "type": 1, "id": 3, "area_otf": 186949980.79978365 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -0.285151269202318, 0.183285948293743 ], [ -0.390636402645921, 0.385928441488032 ], [ -0.38508455351731, 0.666296822482871 ], [ -0.271271646380792, 0.471982102981497 ], [ -0.285151269202318, 0.183285948293743 ] ] ] } }, +{ "type": "Feature", "properties": { "type": 4, "id": 4, "area_otf": 407752434.86128825 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 0.297792889301801, 0.930009656091877 ], [ -0.096388398829556, 0.719039389204672 ], [ -0.132475418165525, 0.877267089370076 ], [ 0.053497167704943, 1.027350228844489 ], [ 0.30470961076702, 0.999176870744069 ], [ 0.297792889301801, 0.930009656091877 ] ] ] } }, +{ "type": "Feature", "properties": { "type": 1, "id": 5, "area_otf": 875801743.60934222 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 0.053497167704943, 1.027350228844489 ], [ 0.30470961076702, 0.999176870744069 ], [ 0.297792889301801, 0.930009656091877 ], [ -0.096388398829556, 0.719039389204672 ], [ -0.132475418165525, 0.877267089370076 ], [ 0.053497167704943, 1.027350228844489 ] ] ] } }, +{ "type": "Feature", "properties": { "type": 1, "id": 7, "area_otf": 38496186.904446661 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 0.30470961076702, 0.999176870744069 ], [ 0.053497167704943, 1.027350228844489 ], [ 0.183979982165282, 1.132652149286166 ], [ 0.303344738430411, 1.129876224721861 ], [ 0.308896587559022, 1.04104663866409 ], [ 0.30470961076702, 0.999176870744069 ] ] ] } }, +{ "type": "Feature", "properties": { "type": 3, "id": 7, "area_otf": 38496186.904446661 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 0.186755906729588, 0.546932066217741 ], [ 0.170100359343755, 0.483085801238719 ], [ 0.111805943493344, 0.483085801238719 ], [ 0.097445501197784, 0.504652295080288 ], [ 0.186755906729588, 0.546932066217741 ] ] ] } }, +{ "type": "Feature", "properties": { "type": 3, "id": 9, "area_otf": 44782856.420115791 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 0.283913266480274, 0.36372104497359 ], [ 0.372742852538045, 0.374824743230811 ], [ 0.41715764556693, 0.316530327380399 ], [ 0.411605796438319, 0.263787760658598 ], [ 0.289465115608885, 0.252684062401376 ], [ 0.247826247144305, 0.288771081737346 ], [ 0.283913266480274, 0.36372104497359 ] ] ] } }, +{ "type": "Feature", "properties": { "type": 3, "id": 10, "area_otf": 97458908.758612499 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -0.009125233613568, 0.581770021847879 ], [ 0.067290807827111, 0.513587019041969 ], [ 0.050735603078626, 0.483085801238719 ], [ -0.00478288820748, 0.510845046881772 ], [ -0.009125233613568, 0.581770021847879 ] ] ] } }, +{ "type": "Feature", "properties": { "type": 1, "id": 11, "area_otf": 117501714.72702697 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 0.067290807827111, 0.513587019041969 ], [ -0.009125233613568, 0.581770021847879 ], [ -0.013110661900396, 0.646865350532733 ], [ 0.053511527642932, 0.685728294433008 ], [ 0.05277270426211, 0.631794187633039 ], [ 0.067290807827111, 0.513587019041969 ] ] ] } }, +{ "type": "Feature", "properties": { "type": 2, "id": 2, "area_otf": 51166743.468675479 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 0.186755906729588, 0.652417199661344 ], [ 0.186755906729588, 0.546932066217741 ], [ 0.097445501197784, 0.504652295080288 ], [ 0.067290807827111, 0.513587019041969 ], [ 0.12486628737915, 0.617477731411215 ], [ 0.186755906729588, 0.652417199661344 ] ] ] } }, +{ "type": "Feature", "properties": { "type": 4, "id": 13, "area_otf": 20486052.017498314 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 0.12486628737915, 0.617477731411215 ], [ 0.067290807827111, 0.513587019041969 ], [ 0.05277270426211, 0.631794187633039 ], [ 0.12486628737915, 0.617477731411215 ] ] ] } }, +{ "type": "Feature", "properties": { "type": 1, "id": 14, "area_otf": 14676439.753498212 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 0.053511527642932, 0.685728294433008 ], [ 0.153444811957924, 0.685728294433008 ], [ 0.186755906729588, 0.652417199661344 ], [ 0.053511527642932, 0.685728294433008 ] ] ] } }, +{ "type": "Feature", "properties": { "type": 2, "id": 15, "area_otf": 65332744.009487882 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 0.111805943493344, 0.483085801238719 ], [ 0.050735603078626, 0.483085801238719 ], [ 0.067290807827111, 0.513587019041969 ], [ 0.097445501197784, 0.504652295080288 ], [ 0.111805943493344, 0.483085801238719 ] ] ] } }, +{ "type": "Feature", "properties": { "type": 3, "id": 16, "area_otf": 32382417.072493128 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 0.12486628737915, 0.617477731411215 ], [ 0.05277270426211, 0.631794187633039 ], [ 0.053511527642932, 0.685728294433008 ], [ 0.186755906729588, 0.652417199661344 ], [ 0.12486628737915, 0.617477731411215 ] ] ] } }, +{ "type": "Feature", "properties": { "type": 4, "id": 17, "area_otf": 41843075.5596838 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -0.409057493916667, 0.446509356601199 ], [ -0.410526874107255, 0.389203529168267 ], [ -0.445791998681367, 0.377448487643563 ], [ -0.478118362874304, 0.405366711264735 ], [ -0.409057493916667, 0.446509356601199 ] ] ] } }, +{ "type": "Feature", "properties": { "type": 2, "id": 18, "area_otf": 36514358.998227134 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -0.409057493916667, 0.446509356601199 ], [ -0.478118362874304, 0.405366711264735 ], [ -0.478118362874304, 0.503815184034131 ], [ -0.409057493916667, 0.446509356601199 ] ] ] } }, +{ "type": "Feature", "properties": { "type": 3, "id": 18, "area_otf": 36514358.998227134 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -1.079125344641068, -0.433150083670526 ], [ -1.213191485894263, -0.170603890383019 ], [ -1.291396734958627, 0.175733641187735 ], [ -1.224363664332029, 0.723170384638282 ], [ -1.146158415267666, 1.181229700586699 ], [ -0.972989649482288, 1.304123663402128 ], [ -0.581963404160469, 1.427017626217557 ], [ -0.302658943216313, 1.427017626217557 ], [ -0.214309615315501, 1.125733944493769 ], [ -0.193545758580243, 1.054926261485617 ], [ -0.132475418165525, 0.877267089370076 ], [ -0.096388398829556, 0.719039389204672 ], [ -0.096388398829556, 0.549707990782047 ], [ -0.113043946215388, 0.324858101073315 ], [ -0.174114286630105, 0.025058248128339 ], [ -0.352933746186261, -0.31584221007398 ], [ -0.643410385568184, -0.438736172889409 ], [ -1.079125344641068, -0.433150083670526 ] ], [ [ -0.435051195674806, 0.183285948293743 ], [ -0.285151269202318, 0.183285948293743 ], [ -0.271271646380792, 0.471982102981497 ], [ -0.38508455351731, 0.666296822482871 ], [ -0.518328932603966, 0.583019085553711 ], [ -0.523880781732577, 0.316530327380399 ], [ -0.435051195674806, 0.183285948293743 ] ] ] } }, +{ "type": "Feature", "properties": { "type": 3, "id": 20, "area_otf": 1894984847.9037061 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 0.45846162434825, 0.433584461909898 ], [ 0.297792889301801, 0.930009656091877 ], [ 0.30470961076702, 0.999176870744069 ], [ 0.308896587559022, 1.04104663866409 ], [ 0.303344738430411, 1.129876224721861 ], [ 0.183979982165282, 1.132652149286166 ], [ 0.053497167704943, 1.027350228844489 ], [ -0.132475418165525, 0.877267089370076 ], [ -0.193545758580243, 1.054926261485617 ], [ -0.214309615315501, 1.125733944493769 ], [ 0.083323897645211, 1.256894475628998 ], [ 0.232021320111857, 1.256894475628998 ], [ 0.389465649782422, 1.248147568425078 ], [ 0.406959464190263, 1.064462517142751 ], [ 0.440326875020546, 0.789623373114332 ], [ 0.49101435706662, 0.627423430566897 ], [ 0.653214299614055, 0.404398509564173 ], [ 0.629560141325888, 0.221923574198308 ], [ 0.54846017005217, 0.117169444636423 ], [ 0.315297752640231, 0.059723631650873 ], [ 0.132822817274367, 0.049586135241658 ], [ -0.015860463394116, 0.150961099333805 ], [ -0.063168779970451, 0.127306941045638 ], [ -0.113856262016525, -0.061926325259704 ], [ -0.269297873624484, -0.352534555657192 ], [ -0.573422765900925, -0.545146987432272 ], [ -1.053264262603755, -0.589076138538869 ], [ -1.067953166203302, -0.522527511172656 ], [ -0.621066028692651, -0.522527511172656 ], [ -0.28031458634078, -0.31584221007398 ], [ -0.135076266649819, -0.030951659910941 ], [ -0.084801463679871, 0.164561462749969 ], [ -0.028940571491039, 0.192491908844385 ], [ 0.105125569762156, 0.097528392123372 ], [ 0.283880424766416, 0.103114481342255 ], [ 0.445877012114027, 0.114286659780021 ], [ 0.607873599461638, 0.265111068689865 ], [ 0.546426618053923, 0.376832853067528 ], [ 0.45846162434825, 0.433584461909898 ] ] ] } }, +{ "type": "Feature", "properties": { "type": 2, "id": 22, "area_otf": 1367791757.8140891 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 0.050735603078626, 0.483085801238719 ], [ 0.150668887393618, 0.144423004393469 ], [ -0.113043946215388, 0.324858101073315 ], [ -0.096388398829556, 0.549707990782047 ], [ -0.096388398829556, 0.719039389204672 ], [ 0.297792889301801, 0.930009656091877 ], [ 0.186755906729588, 0.652417199661344 ], [ 0.153444811957924, 0.685728294433008 ], [ 0.053511527642932, 0.685728294433008 ], [ -0.013110661900396, 0.646865350532733 ], [ -0.009125233613568, 0.581770021847879 ], [ -0.00478288820748, 0.510845046881772 ], [ 0.050735603078626, 0.483085801238719 ] ] ] } }, +{ "type": "Feature", "properties": { "type": 4, "id": 21, "area_otf": 3524380022.2334166 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 0.083323897645211, 1.256894475628998 ], [ 0.232021320111857, 1.256894475628998 ], [ 0.389465649782422, 1.248147568425078 ], [ 0.406959464190263, 1.064462517142751 ], [ 0.440326875020546, 0.789623373114332 ], [ 0.49101435706662, 0.627423430566897 ], [ 0.653214299614055, 0.404398509564173 ], [ 0.629560141325888, 0.221923574198308 ], [ 0.54846017005217, 0.117169444636423 ], [ 0.315297752640231, 0.059723631650873 ], [ 0.132822817274367, 0.049586135241658 ], [ -0.015860463394116, 0.150961099333805 ], [ -0.063168779970451, 0.127306941045638 ], [ -0.113856262016525, -0.061926325259704 ], [ -0.269297873624484, -0.352534555657192 ], [ -0.573422765900925, -0.545146987432272 ], [ -1.053264262603755, -0.589076138538869 ], [ -1.067953166203302, -0.522527511172656 ], [ -0.621066028692651, -0.522527511172656 ], [ -0.28031458634078, -0.31584221007398 ], [ -0.135076266649819, -0.030951659910941 ], [ -0.084801463679871, 0.164561462749969 ], [ -0.028940571491039, 0.192491908844385 ], [ 0.105125569762156, 0.097528392123372 ], [ 0.283880424766416, 0.103114481342255 ], [ 0.445877012114027, 0.114286659780021 ], [ 0.607873599461638, 0.265111068689865 ], [ 0.546426618053923, 0.376832853067528 ], [ 0.45846162434825, 0.433584461909898 ], [ 0.297792889301801, 0.930009656091877 ], [ 0.30470961076702, 0.999176870744069 ], [ 0.308896587559022, 1.04104663866409 ], [ 0.303344738430411, 1.129876224721861 ], [ 0.183979982165282, 1.132652149286166 ], [ 0.053497167704943, 1.027350228844489 ], [ -0.132475418165525, 0.877267089370076 ], [ -0.193545758580243, 1.054926261485617 ], [ -0.214309615315501, 1.125733944493769 ], [ 0.083323897645211, 1.256894475628998 ] ] ] } }, +{ "type": "Feature", "properties": { "type": 3, "id": 7, "area_otf": 38496186.904446661 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 0.186755906729588, 0.546932066217741 ], [ 0.170100359343755, 0.483085801238719 ], [ 0.111805943493344, 0.483085801238719 ], [ 0.097445501197784, 0.504652295080288 ], [ 0.186755906729588, 0.546932066217741 ] ] ] } }, +{ "type": "Feature", "properties": { "type": 1, "id": 23, "area_otf": 36514358.998227134 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -0.409057493916667, 0.446509356601199 ], [ -0.478118362874304, 0.503815184034131 ], [ -0.435506337347251, 0.547896589751772 ], [ -0.422281915631959, 0.514100845368248 ], [ -0.409057493916667, 0.446509356601199 ] ] ] } } +] +} diff --git a/tests/tests_yaml/otherAlgorithms.yaml b/tests/tests_yaml/otherAlgorithms.yaml index 71add3f68..3ecacf41a 100644 --- a/tests/tests_yaml/otherAlgorithms.yaml +++ b/tests/tests_yaml/otherAlgorithms.yaml @@ -25,4 +25,4 @@ tests: OUTPUT: location: 'expected_outputs/gridzonegenerator/test_1/OUTPUT.geojson' name: TEMPORARY_OUTPUT - type: vector \ No newline at end of file + type: vector