From 5b629e03ded854e50e06adf762dcdc632b790cc1 Mon Sep 17 00:00:00 2001 From: Patryk Date: Thu, 28 Jul 2022 13:55:56 +0200 Subject: [PATCH] Poprawki --- Searcher/searchAddress.py | 11 ++-- Searcher/searchParcel.py | 12 ++--- Searcher/searchTool.py | 105 ++++++++++++-------------------------- utils.py | 70 ++++++++++++++++++++++--- 4 files changed, 105 insertions(+), 93 deletions(-) diff --git a/Searcher/searchAddress.py b/Searcher/searchAddress.py index ac2fa6e..f9156b9 100644 --- a/Searcher/searchAddress.py +++ b/Searcher/searchAddress.py @@ -1,6 +1,7 @@ import json import os from http.client import IncompleteRead +from json import JSONDecodeError from typing import Union, Tuple from urllib.error import HTTPError, URLError from urllib.parse import quote @@ -8,10 +9,10 @@ from qgis.PyQt.QtCore import QVariant from qgis.core import QgsGeometry, QgsFeature, QgsField, QgsFields, \ - QgsProject, QgsVectorLayer, QgsMessageLog, Qgis + QgsVectorLayer, QgsMessageLog, Qgis from qgis.utils import iface -from ..utils import tr, add_map_layer_to_group, search_group_name +from ..utils import tr, add_map_layer_to_group, search_group_name, project class SearchAddress: @@ -75,7 +76,7 @@ def get_layer(self) -> Union[bool,Tuple[str]]: return org, obj_type, qml def get_layer_data(self, org: str, obj_type: str, qml: str) -> QgsVectorLayer: - lyr = QgsProject.instance().mapLayersByName(obj_type) + lyr = project.mapLayersByName(obj_type) if lyr: return lyr[0] @@ -98,7 +99,7 @@ def get_layer_data(self, org: str, obj_type: str, qml: str) -> QgsVectorLayer: def process_results(self) -> Union[Tuple[bool,str], Tuple[bool,QgsFeature]]: try: self.jres = json.loads(self.res) - except Exception: + except JSONDecodeError: return False, tr('Cannot parse results.') if 'found objects' in self.jres: @@ -147,7 +148,7 @@ def process_results(self) -> Union[Tuple[bool,str], Tuple[bool,QgsFeature]]: return True, feats def zoom_to_feature(self, layer: str) -> None: - layer = QgsProject.instance().mapLayersByName(layer)[0] + layer = project.mapLayersByName(layer)[0] iface.mapCanvas().zoomScale(500) layer.selectByIds([len(layer)]) iface.mapCanvas().zoomToSelected(layer) diff --git a/Searcher/searchParcel.py b/Searcher/searchParcel.py index 9bd86a3..31c39a9 100644 --- a/Searcher/searchParcel.py +++ b/Searcher/searchParcel.py @@ -7,11 +7,11 @@ from urllib.request import urlopen from qgis.core import QgsGeometry, QgsFeature, \ - QgsProject, QgsVectorLayer, Qgis + QgsVectorLayer, Qgis from qgis.utils import iface from ..utils import tr, CustomMessageBox, search_group_name, \ - add_map_layer_to_group + add_map_layer_to_group, project class FetchULDK: @@ -39,10 +39,6 @@ def fetch_parcel(self, teryt: str) -> bool: 'geom_wkt,teryt,voivodeship,county,region,commune,parcel' return self.fetch() - def fetch_in_point(self, coords): - # TODO: Dodac pobieranie działki w pkt po kliknieciu - pass - def fetch(self) -> bool: if '- gmina' in self.params or '- miasto' in self.params: flag = self.params.find('-') @@ -99,7 +95,7 @@ def __init__(self): ) def get_layer(self) -> None: - lyr = QgsProject.instance().mapLayersByName(self.lyr_name) + lyr = project.mapLayersByName(self.lyr_name) if len(lyr) > 0: self.lyr = lyr[0] return @@ -131,7 +127,7 @@ def parse_responce(self, resp: List[str]) -> None: ) def zoom_to_feature(self, layer: str) -> None: - layer = QgsProject.instance().mapLayersByName(layer)[0] + layer = project.mapLayersByName(layer)[0] iface.mapCanvas().zoomScale(500) layer.selectByIds([len(layer)]) iface.mapCanvas().zoomToSelected(layer) diff --git a/Searcher/searchTool.py b/Searcher/searchTool.py index e841972..879a138 100644 --- a/Searcher/searchTool.py +++ b/Searcher/searchTool.py @@ -1,20 +1,22 @@ import json +from json import JSONDecodeError from urllib.parse import quote from urllib.request import urlopen import requests from qgis.PyQt.QtCore import Qt -from qgis.PyQt.QtGui import QFont, QFontMetrics, QKeySequence +from qgis.PyQt.QtGui import QFont, QFontMetrics from qgis.PyQt.QtCore import QStringListModel from qgis.PyQt.QtCore import QTimer -from qgis.PyQt.QtWidgets import QCompleter, QProgressDialog -from qgis._core import QgsVectorLayer, QgsProject +from qgis.PyQt.QtWidgets import QCompleter +from qgis.core import QgsVectorLayer from qgis.utils import iface from typing import Union, Dict, List from .searchAddress import SearchAddress from .searchParcel import FetchULDK, ParseResponce -from ..utils import tr, CustomMessageBox, add_map_layer_to_group +from ..utils import tr, CustomMessageBox, add_map_layer_to_group, \ + ProgressDialog, identify_layer_in_group, root, WFS_PRG class SearcherTool: @@ -82,11 +84,11 @@ def tips(self) -> None: if obj_type == 'address': self.names.setStringList([ f"{obj['1']['city']}, {obj['1']['street']} {obj['1']['number']}"]) - if limit == 0: + if not limit: return self.completer.setCompletionPrefix(f"{address.split(',')[0]}, ") self.completer.complete() - except Exception: + except (JSONDecodeError, TypeError): return def getStreets(self, simc: str, city: str) -> None: @@ -96,7 +98,7 @@ def getStreets(self, simc: str, city: str) -> None: obj = data['results'] self.names.setStringList( [f"{city}, {obj[element]['street']}" for element in obj]) - except Exception: + except TypeError: self.names.setStringList([]) def validateCity(self, obj: Dict[str, Dict[str, int]]) -> None: @@ -151,87 +153,47 @@ def validate_lineedit(self) -> bool: f" {tr('Invalid')} {tr('Empty address field')}").button_ok() def add_chosen_border(self, mess: str) -> None: - prg_dlg = QProgressDialog(self.dock,Qt.Dialog) - prg_dlg.setLabelText(tr("Adding layers...")) - prg_dlg.setCancelButton(None) - prg_dlg.setAutoClose(True) - prg_dlg.setMaximum(100) - prg_dlg.setWindowFlags( - Qt.Dialog | - Qt.WindowTitleHint - ) - prg_dlg.show() - - prg_dlg.setValue(0) - if self.dock.comboBox_obr.currentIndex() != 0: - jpt_kod_je = self.dock.comboBox_obr.currentText().split("|")[1] - adres = "A06_Granice_obrebow_ewidencyjnych" - lay_name = 'Obręby_ewidencyjne' - - - elif self.dock.comboBox_gmina.currentIndex() != 0: - jpt_kod_je = self.dock.comboBox_gmina.currentText().split("|")[1] - jpt_kod_je = jpt_kod_je.replace("_", "") - adres = "A03_Granice_gmin" - lay_name = 'Gminy' - - - elif self.dock.comboBox_pow.currentIndex() != 0: - jpt_kod_je = self.dock.comboBox_pow.currentText().split("|")[1] - adres = "A02_Granice_powiatow" - lay_name = 'Powiaty' - - - elif self.dock.comboBox_woj.currentIndex() != 0: - jpt_kod_je = self.dock.comboBox_woj.currentText().split("|")[1] - adres = "A01_Granice_wojewodztw" - lay_name = 'Województwa' - - else: + # lay_keys = ['Obręby_ewidencyjne', 'Gminy', 'Powiaty', 'Województwa'] + lay_data = {'Obręby_ewidencyjne': ["A06_Granice_obrebow_ewidencyjnych", self.dock.comboBox_obr], + 'Gminy': ["A03_Granice_gmin", self.dock.comboBox_gmina], + 'Powiaty': ["A02_Granice_powiatow", self.dock.comboBox_pow], + 'Województwa': ["A01_Granice_wojewodztw", self.dock.comboBox_woj]} + for lay_key in lay_data: + if lay_data[lay_key][1].currentIndex() != 0: + _, jpt_kod_je = lay_data[lay_key][1].currentText().split("|") + if lay_key == "Gminy": + jpt_kod_je = jpt_kod_je.replace("_", "") + adres = lay_data[lay_key][0] + lay_name = lay_key + break + if not jpt_kod_je or not adres or not lay_name: CustomMessageBox(None, mess).button_ok() return - - url = f"https://mapy.geoportal.gov.pl/wss/service/PZGIK/PRG/WFS/AdministrativeBoundaries?SERVICE=WFS&REQUEST=GetFeature&VERSION=2.0.0&TYPENAME=ms:{adres}&TYPENAMES=ms:{adres}" - + prg_dlg = ProgressDialog() + prg_dlg.start_steped(tr("Adding layers...")) + prg_dlg.start() + url = f"{WFS_PRG}?SERVICE=WFS&REQUEST=GetFeature&VERSION=2.0.0&TYPENAME=ms:{adres}&TYPENAMES=ms:{adres}" vlayer = QgsVectorLayer(url, "wfs_lay", "WFS") vlayer.setSubsetString(f"""SELECT * FROM {adres} WHERE JPT_KOD_JE = '{jpt_kod_je}'""") - - prg_dlg.setValue(25) - root = QgsProject.instance().layerTreeRoot() - granice_group = root.findGroup("GRANICE") - if not root.findGroup("GRANICE"): - granice_group = root.addGroup("GRANICE") - - lay = None - - if granice_group.children(): - for child in granice_group.children(): - if child.name() == lay_name: - lay = child.layer() - break - + group_name = "GRANICE" + granice_group = root.findGroup(group_name) + if not granice_group: + root.addGroup(group_name) + lay = identify_layer_in_group(group_name, lay_name) if not lay: lay = QgsVectorLayer("Polygon", lay_name, "memory") attr = vlayer.dataProvider().fields().toList() lay.dataProvider().addAttributes(attr) lay.updateFields() add_map_layer_to_group(lay, "GRANICE") - - prg_dlg.setValue(50) - vlayer.selectAll() feat = vlayer.selectedFeatures()[0] - - prg_dlg.setValue(75) - lay.dataProvider().addFeature(feat) lay.updateExtents() self.searchaddress_call.zoom_to_feature(lay.name()) - prg_dlg.setValue(100) - - + prg_dlg.stop() def widthforview(self, result: List[str]) -> int: longest = max(result, key=len) @@ -358,7 +320,6 @@ def _get_mun_code(self) -> Union[str,bool]: return mun_txt.split('|')[1] def search_parcel(self) -> None: - adr = '' # ful address of parcel parc = self.dock.lineEdit_parcel.text() if '.' in parc and '_' in parc: # user input whole address in parcel adr = parc diff --git a/utils.py b/utils.py index 94f5906..c61720a 100644 --- a/utils.py +++ b/utils.py @@ -14,6 +14,7 @@ from qgis.utils import iface project = QgsProject.instance() +root = project.layerTreeRoot() class CustomMessageBox(QMessageBox): @@ -135,6 +136,55 @@ def __new__(cls, *args): SingletonModel.__instance = object.__new__(cls, *args) return SingletonModel.__instance +class ProgressDialog(QProgressDialog, SingletonModel): + + def __init__(self, parent=None, title='GIAP-PolaMap'): + super(ProgressDialog, self).__init__(parent) + self.setWindowTitle(title) + self.setWindowIcon(QIcon(':/plugins/GIAP-PolaMap/icons/giap_logo.png')) + self.setLabelText('Proszę czekać...') + self.setFixedWidth(300) + self.setFixedHeight(100) + self.setMaximum(100) + self.setCancelButton(None) + # self.setStyleSheet(self.stylesheet) + self.setWindowFlags(Qt.Dialog | Qt.WindowCloseButtonHint) + self.rejected.connect(self.stop) + self.setWindowModality(Qt.WindowModal) + + def make_percent_step(self, step=100, new_text=None): + self.setStyleSheet(self.stylesheet) + if new_text: + self.setLabelText(new_text) + if "wczytywanie" in new_text: + for pos in range(100 - self.value()): + QApplication.processEvents() + self.setValue(self.value() + 1) + return + for pos in range(step): + QApplication.processEvents() + self.setValue(self.value() + 1) + QApplication.sendPostedEvents() + QApplication.processEvents() + + def start_steped(self, title='Trwa ładowanie danych.\n Proszę czekać...'): + self.setLabelText(title) + self.setValue(1) + self.show() + QApplication.sendPostedEvents() + QApplication.processEvents() + + def start(self): + self.setFixedWidth(250) + self.setMaximum(0) + self.setCancelButton(None) + self.show() + QApplication.sendPostedEvents() + QApplication.processEvents() + + def stop(self): + self.setValue(100) + self.close() def identify_layer(ls, layer_to_find): for layer in list(ls.values()): @@ -257,6 +307,7 @@ def paint(self, painter, option, index): GIAP_NEWS_WEB_PAGE = 'https://www.giap.pl/aktualnosci/' +WFS_PRG = "https://mapy.geoportal.gov.pl/wss/service/PZGIK/PRG/WFS/AdministrativeBoundaries" # oba poniższe słowniki powinny być spójne WMS_SERVERS = { @@ -1244,14 +1295,13 @@ def add_map_layer_to_group( f'Warstwa nieprawidłowa {layer.name()}. Wymagana interwencja.', "GIAP - PolaMap Lite", Qgis.Info) - root = project.layerTreeRoot() if main_group_name and root.findGroup(main_group_name): group = root.findGroup(main_group_name).findGroup(group_name) else: group = root.findGroup(group_name) if not group: if force_create: - group = project.layerTreeRoot().addGroup(group_name) + group = root.addGroup(group_name) else: project.addMapLayer(layer) return @@ -1259,6 +1309,7 @@ def add_map_layer_to_group( if group_name: group.insertLayer(position, layer) + def find_widget_with_menu_in_toolbar(toolbar: QToolBar) -> List[QToolButton]: lista_widgets = toolbar.children() qmenu_list = [] @@ -1268,6 +1319,7 @@ def find_widget_with_menu_in_toolbar(toolbar: QToolBar) -> List[QToolButton]: qmenu_list.append(widget) return qmenu_list + def get_action_from_toolbar(toolbar: QToolBar) -> List[QAction]: lista_widgets = toolbar.children() act_list = [] @@ -1277,9 +1329,10 @@ def get_action_from_toolbar(toolbar: QToolBar) -> List[QAction]: act_list.append(widget.actions()[0]) return act_list + def add_action_from_toolbar(iface: iface, sec, btn: list) -> None: if iface.mainWindow().findChild(QToolBar, btn[0].split('_')[0]): - dlu = len(btn[0].split('_')) + dlu = len(btn[0].split('_')) if dlu == max_ele_nazwy: objname_toolbar, ind, typ, ind_menu = btn[0].split('_') else: @@ -1298,22 +1351,23 @@ def add_action_from_toolbar(iface: iface, sec, btn: list) -> None: if dlu == max_ele_nazwy: if widg.menu(): - #Wyciąganie i dodawanie pojdeynczej akcji z menu + # Wyciąganie i dodawanie pojdeynczej akcji z menu sel_act_from_menu = widg.menu().actions()[int(ind_menu)] objname = sel_act_from_menu.objectName() sel_act_from_menu.setObjectName(btn[0]) sec.add_action(sel_act_from_menu, btn[1], btn[2]) sel_act_from_menu.setObjectName(objname) else: - #Dodawanie wybranej akcji + # Dodawanie wybranej akcji sel_act = widg.actions()[int(ind_menu)] objname = sel_act.objectName() sel_act.setObjectName(btn[0]) sec.add_action(sel_act, btn[1], btn[2]) sel_act.setObjectName(objname) else: - #Dodawanie menu i domyślnej akcji + # Dodawanie menu i domyślnej akcji objname = widg.defaultAction().objectName() widg.defaultAction().setObjectName(btn[0]) - sec.add_action(widg.defaultAction(), btn[1], btn[2], widg.menu()) - widg.defaultAction().setObjectName(objname) \ No newline at end of file + sec.add_action(widg.defaultAction(), btn[1], btn[2], + widg.menu()) + widg.defaultAction().setObjectName(objname)