def initGui(self): ''' Create the menu entries and toolbar icons inside the QGIS GUI ''' icon_path = ':/plugins/SearchPlus/icons/icon_searchplus.png' self.add_action(icon_path, self.tr('Advanced searcher'), self.run, parent=self.iface.mainWindow(), add_to_toolbar=self.pluginToolbarEnabled) if self.removeMemoryLayersAction: icon_path = ':/plugins/SearchPlus/icons/remove_mem_layers.png' self.add_action(icon_path, self.tr('Remove memory layers'), self.removeMemoryLayers, parent=self.iface.mainWindow(), add_to_toolbar=self.pluginToolbarEnabled) # Create the dock widget and dock it but hide it waiting the ond of qgis loading self.dlg = SearchPlusDockWidget(self.iface.mainWindow()) self.iface.mainWindow().addDockWidget(Qt.TopDockWidgetArea, self.dlg) self.dlg.setVisible(False) # add first level combo box events self.dlg.cboStreet.currentIndexChanged.connect(self.getStreetNumbers) self.dlg.cboStreet.currentIndexChanged.connect(self.zoomOnStreet) self.dlg.cboType.currentIndexChanged.connect(self.getEquipments) self.dlg.cboUrbanCore.currentIndexChanged.connect(self.getPlots) self.dlg.cboUrbanCore.currentIndexChanged.connect(self.zoomOnCore) # add events to show information o the canvas self.dlg.cboNumber.currentIndexChanged.connect(self.displayStreetData) self.dlg.cboTopo.currentIndexChanged.connect(self.displayToponym) self.dlg.cboEquipment.currentIndexChanged.connect(self.displayEquipment) self.dlg.cboCadastre.currentIndexChanged.connect(self.displayCadastre) self.dlg.cboPlot.currentIndexChanged.connect(self.displayPlot) self.dlg.txtCoordX.returnPressed.connect(self.displayUTM) self.dlg.txtCoordY.returnPressed.connect(self.displayUTM)
def __init__(self, iface, srid): ''' Constructor ''' self.iface = iface self.srid = srid # initialize plugin directory and locale self.plugin_dir = os.path.dirname(__file__) locale = QSettings().value('locale/userLocale')[0:2] locale_path = os.path.join(self.plugin_dir, 'i18n', 'SearchPlus_{}.qm'.format(locale)) if os.path.exists(locale_path): self.translator = QTranslator() self.translator.load(locale_path) if qVersion() > '4.3.3': QCoreApplication.installTranslator(self.translator) else: print "Locale file not found at: "+locale_path # load local settings of the plugin self.app_name = "searchplus" self.setting_file = os.path.join(self.plugin_dir, 'config', self.app_name+'.config') if not os.path.isfile(self.setting_file): message = "Config file not found at: "+self.setting_file self.iface.messageBar().pushMessage(message, QgsMessageBar.WARNING, 5) return False self.settings = QSettings(self.setting_file, QSettings.IniFormat) self.stylesFolder = self.plugin_dir+"/styles/" # load plugin settings self.loadPluginSettings() # create dialog self.dlg = SearchPlusDockWidget(self.iface.mainWindow()) # set signals self.dlg.cboStreet.currentIndexChanged.connect(self.getStreetNumbers) self.dlg.cboStreet.currentIndexChanged.connect(self.zoomOnStreet) self.dlg.cboNumber.currentIndexChanged.connect(self.displayStreetData)
def __init__(self, iface, srid, controller): ''' Constructor ''' self.iface = iface self.srid = srid self.controller = controller # initialize plugin directory and locale self.plugin_dir = os.path.dirname(__file__) locale = QSettings().value('locale/userLocale')[0:2] locale_path = os.path.join(self.plugin_dir, 'i18n', 'SearchPlus_{}.qm'.format(locale)) if os.path.exists(locale_path): self.translator = QTranslator() self.translator.load(locale_path) if qVersion() > '4.3.3': QCoreApplication.installTranslator(self.translator) # load local settings of the plugin self.app_name = "searchplus" self.setting_file = os.path.join(self.plugin_dir, 'config', self.app_name+'.config') if not os.path.isfile(self.setting_file): message = "Config file not found at: "+self.setting_file self.controller.show_warning(message) return False self.settings = QSettings(self.setting_file, QSettings.IniFormat) self.stylesFolder = self.plugin_dir+"/styles/" # create dialog self.dlg = SearchPlusDockWidget(self.iface.mainWindow()) # Load configuration data from tables if not self.load_config_data(): self.enabled = False return # set signals self.dlg.ppoint_field_zone.activated.connect(self.ppoint_field_zone) self.dlg.ppoint_number.activated.connect(self.ppoint_zoom) self.dlg.adress_street.activated.connect(self.address_get_numbers) self.dlg.adress_street.activated.connect(self.address_zoom_street) self.dlg.adress_number.activated.connect(self.address_zoom_portal) self.dlg.hydrometer_code.activated.connect(partial(self.hydrometer_zoom, self.params['hydrometer_urban_propierties_field_code'], self.dlg.hydrometer_code)) self.dlg.urban_properties_zone.activated.connect(self.urban_field_zone) self.dlg.urban_properties_block.activated.connect(self.urban_field_block) self.dlg.urban_properties_number.activated.connect(self.urban_zoom) self.enabled = True
class SearchPlus(QObject): ''' QGIS Plugin Implementation. ''' connectionEstablished = pyqtSignal() def __init__(self, iface): ''' Constructor. :param iface: An interface instance that will be passed to this class which provides the hook by which you can manipulate the QGIS application at run time. :type iface: QgsInterface ''' super(SearchPlus, self).__init__() # Save reference to the QGIS interface self.iface = iface # initialize plugin directory and locale self.plugin_dir = os.path.dirname(__file__) self.pluginName = os.path.basename(self.plugin_dir) locale = QSettings().value('locale/userLocale')[0:2] locale_path = os.path.join(self.plugin_dir, 'i18n', 'SearchPlus_{}.qm'.format(locale)) if os.path.exists(locale_path): self.translator = QTranslator() self.translator.load(locale_path) if qVersion() > '4.3.3': QCoreApplication.installTranslator(self.translator) # load local settings of the plugin self.app_name = "searchplus" self.setting_file = os.path.join(self.plugin_dir, 'config', self.app_name+'.config') if not os.path.isfile(self.setting_file): message = "Config file not found at: "+self.setting_file self.iface.messageBar().pushMessage(message, QgsMessageBar.WARNING, 5) return False self.settings = QSettings(self.setting_file, QSettings.IniFormat) self.stylesFolder = self.plugin_dir+"/styles/" # load plugin settings self.loadPluginSettings() # Declare instance attributes self.actions = [] self.menu = self.tr(self.app_name) self.annotations = [] self.streetLayer = None self.placenameLayer = None self.cadastreLayer = None self.equipmentLayer = None self.portalLayer = None self.placenameMemLayer = None self.cadastreMemLayer = None self.equipmentMemLayer = None self.portalMemLayer = None self.coreLayer = None self.plotLayer = None self.plotMemLayer = None self.iface.initializationCompleted.connect(self.populateGui) def loadPluginSettings(self): ''' Load plugin settings ''' # get layers configuration to populate the GUI self.STREET_LAYER = '"'+self.settings.value('layers/STREET_LAYER', '').lower()+'"' self.STREET_FIELD_CODE = self.settings.value('layers/STREET_FIELD_CODE', '').lower() self.STREET_FIELD_NAME = self.settings.value('layers/STREET_FIELD_NAME', '').lower() self.PORTAL_LAYER = '"'+self.settings.value('layers/PORTAL_LAYER', '').lower()+'"' self.PORTAL_FIELD_CODE = self.settings.value('layers/PORTAL_FIELD_CODE', '').lower() self.PORTAL_FIELD_NUMBER = self.settings.value('layers/PORTAL_FIELD_NUMBER', '').lower() self.PLACENAME_LAYER = '"'+self.settings.value('layers/PLACENAME_LAYER', '').lower()+'"' self.PLACENAME_FIELD = self.settings.value('layers/PLACENAME_FIELD', '').lower() self.EQUIPMENT_SCHEMA = '"'+self.settings.value('layers/EQUIPMENT_SCHEMA', '').lower()+'"' self.EQUIPMENT_LAYER = '"'+self.settings.value('layers/EQUIPMENT_LAYER', '').lower()+'"' self.EQUIPMENT_FIELD_TYPE = self.settings.value('layers/EQUIPMENT_FIELD_TYPE', '').lower() self.EQUIPMENT_FIELD_NAME = self.settings.value('layers/EQUIPMENT_FIELD_NAME', '').lower() self.CADASTRE_LAYER = '"'+self.settings.value('layers/CADASTRE_LAYER', '').lower()+'"' self.CADASTRE_FIELD_CODE = self.settings.value('layers/CADASTRE_FIELD_CODE', '').lower() self.CORE_LAYER = '"'+self.settings.value('layers/CORE_LAYER', '').lower()+'"' self.CORE_FIELD_CODE = '"'+self.settings.value('layers/CORE_FIELD_CODE', '').lower()+'"' self.CORE_FIELD_NAME = '"'+self.settings.value('layers/CORE_FIELD_NAME', '').lower()+'"' self.PLOT_LAYER = '"'+self.settings.value('layers/PLOT_LAYER', '').lower()+'"' self.PLOT_FIELD_CODE = '"'+self.settings.value('layers/PLOT_FIELD_CODE', '').lower()+'"' self.PLOT_FIELD_ADDRESS = '"'+self.settings.value('layers/PLOT_FIELD_ADDRESS', '').lower()+'"' self.QML_PORTAL = self.settings.value('layers/QML_PORTAL', 'portal.qml').lower() self.QML_TOPONYM = self.settings.value('layers/QML_TOPONYM', 'toponym.qml').lower() self.QML_EQUIPMENT = self.settings.value('layers/QML_EQUIPMENT', 'equipment.qml').lower() self.QML_CADASTRE = self.settings.value('layers/QML_CADASTRE', 'cadastre.qml').lower() self.QML_PLOT = self.settings.value('layers/QML_PLOT', 'plot.qml').lower() # get initial Scale self.defaultZoomScale = self.settings.value('status/defaultZoomScale', 2500) # Create own plugin toolbar or not? self.pluginToolbarEnabled = bool(int(self.settings.value('status/pluginToolbarEnabled', 1))) if self.pluginToolbarEnabled: self.toolbar = self.iface.addToolBar(u'SearchPlus') self.toolbar.setObjectName(u'SearchPlus') # Enable action Remove Memory Layers? self.removeMemoryLayersAction = bool(int(self.settings.value('status/removeMemoryLayersAction', 0))) def initialization(self): self.getLayers() self.getFullExtent() def getLayers(self): # Iterate over all layers to get the ones set in config file layers = self.iface.legendInterface().layers() for cur_layer in layers: uri = cur_layer.dataProvider().dataSourceUri().lower() pos_ini = uri.find('table=') pos_fi = uri.find('" ') uri_table = uri if pos_ini <> -1 and pos_fi <> -1: uri_table = uri[pos_ini+6:pos_fi+1] if self.STREET_LAYER in uri_table: self.streetLayer = cur_layer if self.PLACENAME_LAYER in uri_table: self.placenameLayer = cur_layer if self.CADASTRE_LAYER in uri_table: self.cadastreLayer = cur_layer if self.EQUIPMENT_LAYER in uri_table: self.equipmentLayer = cur_layer if self.PORTAL_LAYER in uri_table: self.portalLayer = cur_layer if self.CORE_LAYER in uri_table: self.coreLayer = cur_layer if self.PLOT_LAYER in uri_table: self.plotLayer = cur_layer def getFullExtent(self): # get full extent canvas = self.iface.mapCanvas() self.xMax = int(canvas.fullExtent().xMaximum()) self.xMin = int(canvas.fullExtent().xMinimum()) self.yMax = int(canvas.fullExtent().yMaximum()) self.yMin = int(canvas.fullExtent().yMinimum()) try: self.xOffset = (self.xMax - self.xMin) * 0.10 self.yOffset = (self.yMax - self.yMin) * 0.10 except: self.xOffset = 1000 self.yOffset = 1000 # set validators for UTM text edit self.xMinVal = int(self.xMin - self.xOffset) self.xMaxVal = int(self.xMax + self.xOffset) self.yMinVal = int(self.yMin - self.yOffset) self.yMaxVal = int(self.yMax + self.yOffset) try: self.intValidatorX = QIntValidator(self.xMinVal, self.xMaxVal, self.dlg) # assumed that E and W are inserted as - + self.intValidatorY = QIntValidator(self.yMinVal, self.yMaxVal, self.dlg) # assumed that S and N are inserted as - + self.dlg.txtCoordX.setValidator(self.intValidatorX) self.dlg.txtCoordY.setValidator(self.intValidatorY) except: pass # noinspection PyMethodMayBeStatic def tr(self, message): ''' Get the translation for a string using Qt translation API. We implement this ourselves since we do not inherit QObject. :param message: String for translation. :type message: str, QString :returns: Translated version of message. :rtype: QString ''' # noinspection PyTypeChecker,PyArgumentList,PyCallByClass return QCoreApplication.translate('SearchPlus', message) def add_action(self, icon_path, text, callback, enabled_flag=True, add_to_menu=True, add_to_toolbar=True, status_tip=None, whats_this=None, parent=None): ''' Add a toolbar icon to the 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. :type icon_path: str :param text: Text that should be shown in menu items for this action. :type text: str :param callback: Function to be called when the action is triggered. :type callback: function :param enabled_flag: A flag indicating if the action should be enabled by default. Defaults to True. :type enabled_flag: bool :param add_to_menu: Flag indicating whether the action should also be added to the menu. Defaults to True. :type add_to_menu: bool :param add_to_toolbar: Flag indicating whether the action should also be added to the toolbar. Defaults to True. :type add_to_toolbar: bool :param status_tip: Optional text to show in a popup when mouse pointer hovers over the action. :type status_tip: str :param parent: Parent widget for the new action. Defaults None. :type parent: QWidget :param whats_this: Optional text to show in the status bar when the mouse pointer hovers over the action. :returns: The action that was created. Note that the action is also added to self.actions list. :rtype: QAction ''' icon = QIcon(icon_path) action = QAction(icon, text, parent) action.triggered.connect(callback) action.setEnabled(enabled_flag) if status_tip is not None: action.setStatusTip(status_tip) if whats_this is not None: action.setWhatsThis(whats_this) if add_to_toolbar: self.toolbar.addAction(action) else: self.iface.addToolBarIcon(action) if add_to_menu: self.iface.addPluginToMenu(self.menu, action) self.actions.append(action) return action def initGui(self): ''' Create the menu entries and toolbar icons inside the QGIS GUI ''' icon_path = ':/plugins/SearchPlus/icons/icon_searchplus.png' self.add_action(icon_path, self.tr('Advanced searcher'), self.run, parent=self.iface.mainWindow(), add_to_toolbar=self.pluginToolbarEnabled) if self.removeMemoryLayersAction: icon_path = ':/plugins/SearchPlus/icons/remove_mem_layers.png' self.add_action(icon_path, self.tr('Remove memory layers'), self.removeMemoryLayers, parent=self.iface.mainWindow(), add_to_toolbar=self.pluginToolbarEnabled) # Create the dock widget and dock it but hide it waiting the ond of qgis loading self.dlg = SearchPlusDockWidget(self.iface.mainWindow()) self.iface.mainWindow().addDockWidget(Qt.TopDockWidgetArea, self.dlg) self.dlg.setVisible(False) # add first level combo box events self.dlg.cboStreet.currentIndexChanged.connect(self.getStreetNumbers) self.dlg.cboStreet.currentIndexChanged.connect(self.zoomOnStreet) self.dlg.cboType.currentIndexChanged.connect(self.getEquipments) self.dlg.cboUrbanCore.currentIndexChanged.connect(self.getPlots) self.dlg.cboUrbanCore.currentIndexChanged.connect(self.zoomOnCore) # add events to show information o the canvas self.dlg.cboNumber.currentIndexChanged.connect(self.displayStreetData) self.dlg.cboTopo.currentIndexChanged.connect(self.displayToponym) self.dlg.cboEquipment.currentIndexChanged.connect(self.displayEquipment) self.dlg.cboCadastre.currentIndexChanged.connect(self.displayCadastre) self.dlg.cboPlot.currentIndexChanged.connect(self.displayPlot) self.dlg.txtCoordX.returnPressed.connect(self.displayUTM) self.dlg.txtCoordY.returnPressed.connect(self.displayUTM) def unload(self): ''' Removes the plugin menu item and icon from QGIS GUI ''' for action in self.actions: self.iface.removePluginMenu(self.tr(self.app_name), action) self.iface.removeToolBarIcon(action) if self.pluginToolbarEnabled: del self.toolbar if self.dlg: self.dlg.deleteLater() del self.dlg def populateGui(self): ''' Populate the interface with values get from layers ''' # Get layers and full extent self.initialization() # tab Plots self.populatePlots() # tab Cadastre self.populateCadastre() # tab Equipments self.populateEquipments() # tab Toponyms self.populateToponyms() # tab Streets self.populateStreets() def populateCadastre(self): # Check if we have this search option available if self.cadastreLayer is None: self.dlg.searchPlusTabMain.removeTab(3) return layer = self.cadastreLayer records = [(-1, '', '')] idx_id = layer.fieldNameIndex('id') idx_field_code = layer.fieldNameIndex(self.CADASTRE_FIELD_CODE) for feature in layer.getFeatures(): geom = feature.geometry() attrs = feature.attributes() field_id = attrs[idx_id] field_code = attrs[idx_field_code] if not type(field_code) is QPyNullVariant: elem = [field_id, field_code, geom.exportToWkt()] records.append(elem) # Fill cadastre combo self.dlg.cboCadastre.blockSignals(True) self.dlg.cboCadastre.clear() records_sorted = sorted(records, key = operator.itemgetter(1)) for i in range(len(records_sorted)): record = records_sorted[i] self.dlg.cboCadastre.addItem(record[1], record) self.dlg.cboCadastre.blockSignals(False) def populateEquipments(self): # Check if we have this search option available if self.equipmentLayer is None: self.dlg.searchPlusTabMain.removeTab(2) return # Get layer features layer = self.equipmentLayer records = [''] idx_field_type = layer.fieldNameIndex(self.EQUIPMENT_FIELD_TYPE) for feature in layer.getFeatures(): attrs = feature.attributes() field_type = attrs[idx_field_type] if not type(idx_field_type) is QPyNullVariant: elem = field_type records.append(elem) # Fill equipment type combo (remove duplicates)km records_set = list(set(records)) records_sorted = records_set self.dlg.cboType.blockSignals(True) self.dlg.cboType.clear() # records_sorted = sorted(records_set, key = operator.itemgetter(1)) for i in range(len(records_sorted)): record = records_sorted[i] self.dlg.cboType.addItem(record, record) self.dlg.cboType.blockSignals(False) def populateToponyms(self): # Check if we have this search option available if self.placenameLayer is None: self.dlg.searchPlusTabMain.removeTab(1) return # Get layer features layer = self.placenameLayer records = [(-1, '', '')] idx_id = layer.fieldNameIndex('id') idx_field = layer.fieldNameIndex(self.PLACENAME_FIELD) for feature in layer.getFeatures(): geom = feature.geometry() attrs = feature.attributes() field_id = attrs[idx_id] field = attrs[idx_field] if not type(field) is QPyNullVariant: elem = [field_id, field, geom.exportToWkt()] records.append(elem) # Fill toponym combo self.dlg.cboTopo.blockSignals(True) self.dlg.cboTopo.clear() records_sorted = sorted(records, key = operator.itemgetter(1)) for i in range(len(records_sorted)): record = records_sorted[i] self.dlg.cboTopo.addItem(record[1], record) self.dlg.cboTopo.blockSignals(False) def populateStreets(self): # Check if we have this search option available if self.streetLayer is None or self.portalLayer is None: self.dlg.searchPlusTabMain.removeTab(0) return # Get layer features layer = self.streetLayer records = [(-1, '', '', '')] idx_id = layer.fieldNameIndex('id') idx_field_name = layer.fieldNameIndex(self.STREET_FIELD_NAME) idx_field_code = layer.fieldNameIndex(self.STREET_FIELD_CODE) for feature in layer.getFeatures(): geom = feature.geometry() attrs = feature.attributes() field_id = attrs[idx_id] field_name = attrs[idx_field_name] field_code = attrs[idx_field_code] if not type(field_code) is QPyNullVariant and geom is not None: elem = [field_id, field_name, field_code, geom.exportToWkt()] records.append(elem) # Fill street combo self.dlg.cboStreet.blockSignals(True) self.dlg.cboStreet.clear() records_sorted = sorted(records, key = operator.itemgetter(1)) for i in range(len(records_sorted)): record = records_sorted[i] self.dlg.cboStreet.addItem(record[1], record) self.dlg.cboStreet.blockSignals(False) def populatePlots(self): if self.plotLayer is None or self.coreLayer is None: self.dlg.searchPlusTabMain.removeTab(4) return # Get layer features layer = self.coreLayer records = [(-1, '', '', '')] idx_id = layer.fieldNameIndex('id') idx_field_name = layer.fieldNameIndex(self.CORE_FIELD_NAME) idx_field_code = layer.fieldNameIndex(self.CORE_FIELD_CODE) for feature in layer.getFeatures(): geom = feature.geometry() attrs = feature.attributes() field_id = attrs[idx_id] field_name = attrs[idx_field_name] field_code = attrs[idx_field_code] if not type(field_code) is QPyNullVariant and geom is not None: elem = [field_id, field_name, field_code, geom.exportToWkt()] records.append(elem) # Fill core combo self.dlg.cboUrbanCore.blockSignals(True) self.dlg.cboUrbanCore.clear() records_sorted = sorted(records, key=operator.itemgetter(1)) for record in records_sorted: self.dlg.cboUrbanCore.addItem(record[1], record) self.dlg.cboUrbanCore.blockSignals(False) def zoomOnStreet(self): ''' Zoom on the street with the prefined scale ''' # get selected street selected = self.dlg.cboStreet.currentText() if selected == '': return # get code data = self.dlg.cboStreet.itemData(self.dlg.cboStreet.currentIndex()) wkt = data[3] # to know the index see the query that populate the combo geom = QgsGeometry.fromWkt(wkt) if not geom: message = self.tr('Can not correctly get geometry') self.iface.messageBar().pushMessage(message, QgsMessageBar.WARNING, 5) return # zoom on it's centroid centroid = geom.centroid() self.iface.mapCanvas().setCenter(centroid.asPoint()) self.iface.mapCanvas().zoomScale(float(self.defaultZoomScale)) def zoomOnCore(self): # get selected core selected = self.dlg.cboUrbanCore.currentText() if selected == '': return # get code data = self.dlg.cboUrbanCore.itemData(self.dlg.cboUrbanCore.currentIndex()) wkt = data[3] # to know the index see the query that populate the combo geom = QgsGeometry.fromWkt(wkt) if not geom: message = self.tr('Can not correctly get geometry') self.iface.messageBar().pushMessage(message, QgsMessageBar.WARNING, 5) return # zoom on it self.iface.mapCanvas().setExtent(geom.boundingBox()) self.iface.mapCanvas().refresh() def getStreetNumbers(self): ''' Populate civic numbers depending on selected street. Available civic numbers are linked with self.STREET_FIELD_CODE column code in self.PORTAL_LAYER and self.STREET_LAYER ''' # get selected street selected = self.dlg.cboStreet.currentText() if selected == '': return # get street code sel_street = self.dlg.cboStreet.itemData(self.dlg.cboStreet.currentIndex()) code = sel_street[2] # to know the index see the query that populate the combo records = [[-1, '']] # Set filter expression layer = self.portalLayer idx_field_code = layer.fieldNameIndex(self.PORTAL_FIELD_CODE) idx_field_number = layer.fieldNameIndex(self.PORTAL_FIELD_NUMBER) aux = self.PORTAL_FIELD_CODE+"='"+str(code)+"'" # Check filter and existence of fields expr = QgsExpression(aux) if expr.hasParserError(): self.iface.messageBar().pushMessage(expr.parserErrorString() + ": " + aux, self.app_name, QgsMessageBar.WARNING, 10) return if idx_field_code == -1: message = self.tr("Field '{}' not found in layer '{}'. Open '{}' and check parameter '{}'". format(self.PORTAL_FIELD_CODE, layer.name(), self.setting_file, 'PORTAL_FIELD_CODE')) self.iface.messageBar().pushMessage(message, '', QgsMessageBar.WARNING) return if idx_field_number == -1: message = self.tr("Field '{}' not found in layer '{}'. Open '{}' and check parameter '{}'". format(self.PORTAL_FIELD_NUMBER, layer.name(), self.setting_file, 'PORTAL_FIELD_NUMBER')) self.iface.messageBar().pushMessage(message, '', QgsMessageBar.WARNING) return # Get a featureIterator from an expression: # Get features from the iterator and do something it = layer.getFeatures(QgsFeatureRequest(expr)) for feature in it: attrs = feature.attributes() field_number = attrs[idx_field_number] if not type(field_number) is QPyNullVariant: elem = [code, field_number] records.append(elem) # Fill numbers combo records_sorted = sorted(records, key = operator.itemgetter(1)) self.dlg.cboNumber.blockSignals(True) self.dlg.cboNumber.clear() for record in records_sorted: self.dlg.cboNumber.addItem(record[1], record) self.dlg.cboNumber.blockSignals(False) def getPlots(self): # get selected urban core selected = self.dlg.cboUrbanCore.currentText() if selected == '': return # get urban core code sel_core = self.dlg.cboUrbanCore.itemData(self.dlg.cboUrbanCore.currentIndex()) code = sel_core[2] # to know the index see the query that populate the combo records = [[-1, '']] # Set filter expression layer = self.plotLayer idx_field_code = layer.fieldNameIndex(self.PLOT_FIELD_CODE) idx_field_number = layer.fieldNameIndex(self.PLOT_FIELD_ADDRESS) idx_field_id = layer.fieldNameIndex('id') aux = self.PLOT_FIELD_CODE+"='"+str(code)+"'" # Check filter and existence of fields expr = QgsExpression(aux) if expr.hasParserError(): self.iface.messageBar().pushMessage(expr.parserErrorString() + ": " + aux, self.app_name, QgsMessageBar.WARNING, 10) return if idx_field_code == -1: message = self.tr("Field '{}' not found in layer '{}'. Open '{}' and check parameter '{}'". format(self.PLOT_FIELD_CODE, layer.name(), self.setting_file, 'PLOT_FIELD_CODE')) self.iface.messageBar().pushMessage(message, '', QgsMessageBar.WARNING) return if idx_field_number == -1: message = self.tr("Field '{}' not found in layer '{}'. Open '{}' and check parameter '{}'". format(self.PLOT_FIELD_ADDRESS, layer.name(), self.setting_file, 'PLOT_FIELD_ADDRESS')) self.iface.messageBar().pushMessage(message, '', QgsMessageBar.WARNING) return # Get a featureIterator from an expression: # Get features from the iterator and do something it = layer.getFeatures(QgsFeatureRequest(expr)) for feature in it: attrs = feature.attributes() plot_id = attrs[idx_field_id] field_number = attrs[idx_field_number] if not type(field_number) is QPyNullVariant: elem = [plot_id, field_number] records.append(elem) # Fill numbers combo records_sorted = sorted(records, key = operator.itemgetter(1)) self.dlg.cboPlot.blockSignals(True) self.dlg.cboPlot.clear() for record in records_sorted: self.dlg.cboPlot.addItem(record[1], record) self.dlg.cboPlot.blockSignals(False) def getEquipments(self): ''' Populate equipments combo depending on selected type. Available equipments EQUIPMENT_FIELD_NAME belonging to the same EQUIPMENT_FIELD_TYPE of the same layer EQUIPMENT_LAYER ''' # get selected street selectedCode = self.dlg.cboType.currentText() if selectedCode == '': return # get street code sel_type = self.dlg.cboType.itemData(self.dlg.cboType.currentIndex()) records = [[-1, '']] # Set filter expression layer = self.equipmentLayer idx_id = layer.fieldNameIndex('id') idx_field_name = layer.fieldNameIndex(self.EQUIPMENT_FIELD_NAME) aux = self.EQUIPMENT_FIELD_TYPE+"='"+unicode(sel_type)+"'" expr = QgsExpression(aux) if expr.hasParserError(): self.iface.messageBar().pushMessage(expr.parserErrorString() + ": " + aux, self.app_name, QgsMessageBar.WARNING, 5) return # Get a featureIterator from an expression: # Get features from the iterator and do something it = layer.getFeatures(QgsFeatureRequest(expr)) for feature in it: attrs = feature.attributes() field_id = attrs[idx_id] field_name = attrs[idx_field_name] if not type(field_name) is QPyNullVariant: elem = [field_id, field_name] records.append(elem) # Fill numbers combo records_sorted = sorted(records, key = operator.itemgetter(1)) self.dlg.cboEquipment.blockSignals(True) self.dlg.cboEquipment.clear() for record in records_sorted: self.dlg.cboEquipment.addItem(record[1], record) self.dlg.cboEquipment.blockSignals(False) def validateX(self): X = int(self.dlg.txtCoordX.text()) if X > self.xMinVal and X < self.xMaxVal: return True else: return False def validateY(self): Y = int(self.dlg.txtCoordY.text()) if Y > self.yMinVal and Y < self.yMaxVal: return True else: return False def manageMemLayer(self, layer): ''' Delete previous features from all memory layers Make layer not visible ''' if layer is not None: layer.startEditing() it = layer.getFeatures() ids = [i.id() for i in it] layer.dataProvider().deleteFeatures(ids) layer.commitChanges() self.iface.legendInterface().setLayerVisible(layer, False) def manageMemLayers(self): ''' Delete previous features from all memory layers ''' self.manageMemLayer(self.placenameMemLayer) self.manageMemLayer(self.cadastreMemLayer) self.manageMemLayer(self.equipmentMemLayer) self.manageMemLayer(self.portalMemLayer) self.manageMemLayer(self.plotMemLayer) def copySelected(self, layer, mem_layer, geom_type): ''' Copy from selected layer to memory layer ''' self.manageMemLayers() # Create memory layer if not already set if mem_layer is None: uri = geom_type+"?crs=epsg:25831" mem_layer = QgsVectorLayer(uri, "selected_"+layer.name(), "memory") # Copy attributes from main layer to memory layer attrib_names = layer.dataProvider().fields() names_list = attrib_names.toList() newattributeList = [] for attrib in names_list: aux = mem_layer.fieldNameIndex(attrib.name()) if aux == -1: newattributeList.append(QgsField(attrib.name(), attrib.type())) mem_layer.dataProvider().addAttributes(newattributeList) mem_layer.updateFields() # Insert layer in the top of the TOC root = QgsProject.instance().layerTreeRoot() QgsMapLayerRegistry.instance().addMapLayer(mem_layer, False) node_layer = QgsLayerTreeLayer(mem_layer) root.insertChildNode(0, node_layer) # Prepare memory layer for editing mem_layer.startEditing() # Iterate over selected features cfeatures = [] for sel_feature in layer.selectedFeatures(): attributes = [] attributes.extend(sel_feature.attributes()) cfeature = QgsFeature() cfeature.setGeometry(sel_feature.geometry()) cfeature.setAttributes(attributes) cfeatures.append(cfeature) # Add features, commit changes and refresh canvas mem_layer.dataProvider().addFeatures(cfeatures) mem_layer.commitChanges() self.iface.mapCanvas().refresh() self.iface.mapCanvas().zoomToSelected(layer) # Make sure layer is always visible self.iface.legendInterface().setLayerVisible(mem_layer, True) return mem_layer def loadStyle(self, layer, qml): path_qml = self.stylesFolder+qml if os.path.exists(path_qml): layer.loadNamedStyle(path_qml) def displayUTM(self): ''' Show UTM location on the canvas when set it in the relative tab ''' X = self.dlg.txtCoordX.text() if not X: message = "Coordinate X not specified" self.iface.messageBar().pushMessage(message, QgsMessageBar.WARNING, 5) return Y = self.dlg.txtCoordY.text() if not Y: message = "Coordinate Y not specified" self.iface.messageBar().pushMessage(message, QgsMessageBar.WARNING, 5) return # check if coordinates are within the interval valX = self.validateX() if not valX: message = "Coordinate X is out of the valid interval. It should be between "+str(self.xMinVal)+" and "+str(self.xMaxVal) self.iface.messageBar().pushMessage(message, QgsMessageBar.WARNING, 5) return valY = self.validateY() if not valY: message = "Coordinate Y is out of the valid interval, It should be between "+str(self.yMinVal)+" and "+str(self.yMaxVal) self.iface.messageBar().pushMessage(message, QgsMessageBar.WARNING, 5) return geom = QgsGeometry.fromPoint(QgsPoint(float(X), float(Y))) message = 'X: {}\nY: {}'.format(X,Y) # display annotation with message at a specified position self.displayAnnotation(geom, message) def displayCadastre(self): ''' Show cadastre data on the canvas when selected it in the relative tab ''' cadastre = self.dlg.cboCadastre.currentText() if cadastre == '': return # get selected item elem = self.dlg.cboCadastre.itemData(self.dlg.cboCadastre.currentIndex()) if not elem: # that means that user has edited manually the combo but the element # does not correspond to any combo element message = self.tr('Element {} does not exist'.format(cadastre)) self.iface.messageBar().pushMessage(message, QgsMessageBar.WARNING, 5) return # select this feature in order to copy to memory layer aux = "id = "+str(elem[0]) expr = QgsExpression(aux) if expr.hasParserError(): self.iface.messageBar().pushMessage(expr.parserErrorString() + ": " + aux, self.app_name, QgsMessageBar.WARNING, 5) return # Get a featureIterator from an expression # Build a list of feature Ids from the previous result # Select features with the ids obtained it = self.cadastreLayer.getFeatures(QgsFeatureRequest(expr)) ids = [i.id() for i in it] self.cadastreLayer.setSelectedFeatures(ids) # Copy selected features to memory layer self.cadastreMemLayer = self.copySelected(self.cadastreLayer, self.cadastreMemLayer, "Polygon") # Load style self.loadStyle(self.cadastreMemLayer, self.QML_CADASTRE) # Zoom to scale self.iface.mapCanvas().zoomScale(float(self.defaultZoomScale)) def displayEquipment(self): ''' Show equipment data on the canvas when selected it in the relative tab ''' typ = self.dlg.cboType.currentText() equipment = self.dlg.cboEquipment.currentText() if typ == '' or equipment == '': return # get selected item elem = self.dlg.cboEquipment.itemData(self.dlg.cboEquipment.currentIndex()) if not elem: # that means that user has edited manually the combo but the element # does not correspond to any combo element message = self.tr('Element {} does not exist'.format(equipment)) self.iface.messageBar().pushMessage(message, QgsMessageBar.WARNING, 5) return # select this feature in order to copy to memory layer aux = "id = "+str(elem[0]) expr = QgsExpression(aux) if expr.hasParserError(): self.iface.messageBar().pushMessage(expr.parserErrorString() + ": " + aux, self.app_name, QgsMessageBar.WARNING, 5) return # Get a featureIterator from an expression # Build a list of feature Ids from the previous result # Select features with the ids obtained it = self.equipmentLayer.getFeatures(QgsFeatureRequest(expr)) ids = [i.id() for i in it] self.equipmentLayer.setSelectedFeatures(ids) # Copy selected features to memory layer self.equipmentMemLayer = self.copySelected(self.equipmentLayer, self.equipmentMemLayer, "Point") # Zoom to point layer self.iface.mapCanvas().zoomScale(float(self.defaultZoomScale)) # Load style self.loadStyle(self.equipmentMemLayer, self.QML_EQUIPMENT) # Zoom to scale self.iface.mapCanvas().zoomScale(float(self.defaultZoomScale)) def displayToponym(self): ''' Show toponym data on the canvas when selected it in the relative tab ''' toponym = self.dlg.cboTopo.currentText() if toponym == '': return # get selected toponym elem = self.dlg.cboTopo.itemData(self.dlg.cboTopo.currentIndex()) if not elem: # that means that user has edited manually the combo but the element # does not correspond to any combo element message = self.tr('Element {} does not exist'.format(toponym)) self.iface.messageBar().pushMessage(message, QgsMessageBar.WARNING, 5) return # select this feature in order to copy to memory layer aux = "id = "+str(elem[0]) expr = QgsExpression(aux) if expr.hasParserError(): self.iface.messageBar().pushMessage(expr.parserErrorString() + ": " + aux, self.app_name, QgsMessageBar.WARNING, 5) return # Get a featureIterator from an expression # Build a list of feature Ids from the previous result # Select features with the ids obtained it = self.placenameLayer.getFeatures(QgsFeatureRequest(expr)) ids = [i.id() for i in it] self.placenameLayer.setSelectedFeatures(ids) # Copy selected features to memory layer self.placenameMemLayer = self.copySelected(self.placenameLayer, self.placenameMemLayer, "Linestring") # Load style self.loadStyle(self.placenameMemLayer, self.QML_TOPONYM) # Zoom to scale self.iface.mapCanvas().zoomScale(float(self.defaultZoomScale)) def displayStreetData(self): ''' Show street data on the canvas when selected street and number in street tab ''' street = self.dlg.cboStreet.currentText() civic = self.dlg.cboNumber.currentText() if street == '' or civic == '': return # get selected portal elem = self.dlg.cboNumber.itemData(self.dlg.cboNumber.currentIndex()) if not elem: # that means that user has edited manually the combo but the element # does not correspond to any combo element message = self.tr('Element {} does not exist'.format(civic)) self.iface.messageBar().pushMessage(message, QgsMessageBar.WARNING, 5) return # select this feature in order to copy to memory layer aux = self.PORTAL_FIELD_CODE+"='"+str(elem[0])+"' AND "+self.PORTAL_FIELD_NUMBER+"='"+str(elem[1])+"'" expr = QgsExpression(aux) if expr.hasParserError(): self.iface.messageBar().pushMessage(expr.parserErrorString() + ": " + aux, self.app_name, QgsMessageBar.WARNING, 5) return # Get a featureIterator from an expression # Build a list of feature Ids from the previous result # Select featureswith the ids obtained it = self.portalLayer.getFeatures(QgsFeatureRequest(expr)) ids = [i.id() for i in it] self.portalLayer.setSelectedFeatures(ids) # Copy selected features to memory layer self.portalMemLayer = self.copySelected(self.portalLayer, self.portalMemLayer, "Point") # Zoom to point layer self.iface.mapCanvas().zoomScale(float(self.defaultZoomScale)) # Load style self.loadStyle(self.portalMemLayer, self.QML_PORTAL) def displayPlot(self): core = self.dlg.cboUrbanCore.currentText() plot = self.dlg.cboPlot.currentText() if core == '' or plot == '': return # get selected item elem = self.dlg.cboPlot.itemData(self.dlg.cboPlot.currentIndex()) if not elem: # that means that user has edited manually the combo but the element # does not correspond to any combo element message = self.tr('Element {} does not exist'.format(equipment)) self.iface.messageBar().pushMessage(message, QgsMessageBar.WARNING, 5) return # select this feature in order to copy to memory layer aux = "id = "+str(elem[0]) expr = QgsExpression(aux) if expr.hasParserError(): self.iface.messageBar().pushMessage(expr.parserErrorString() + ": " + aux, self.app_name, QgsMessageBar.WARNING, 5) return # Get a featureIterator from an expression # Build a list of feature Ids from the previous result # Select features with the ids obtained it = self.plotLayer.getFeatures(QgsFeatureRequest(expr)) ids = [i.id() for i in it] self.plotLayer.setSelectedFeatures(ids) # Copy selected features to memory layer self.plotMemLayer = self.copySelected(self.plotLayer, self.plotMemLayer, "Polygon") # Load style self.loadStyle(self.plotMemLayer, self.QML_PLOT) # Zoom to scale self.iface.mapCanvas().zoomScale(float(self.defaultZoomScale)) def displayAnnotation(self, geom, message): ''' Display a specific message in the centroid of a specific geometry ''' centroid = geom.centroid() # clean previous annotations: for annotation in self.annotations: try: scene = annotation.scene() if scene: scene.removeItem(annotation) except: # annotation can be erased by QGIS interface pass self.annotations = [] # build annotation textDoc = QTextDocument(message) item = QgsTextAnnotationItem(self.iface.mapCanvas()) item.setMapPosition(centroid.asPoint()) item.setFrameSize(textDoc.size()) item.setDocument(textDoc) item.update() # add to annotations self.annotations.append(item) # center in the centroid self.iface.mapCanvas().setCenter(centroid.asPoint()) self.iface.mapCanvas().zoomScale(float(self.defaultZoomScale)) self.iface.mapCanvas().refresh() def run(self): ''' Run method activated byt the toolbar action button ''' if self.dlg and not self.dlg.isVisible(): # check if the plugin is active if not self.pluginName in active_plugins: return self.populateGui() self.dlg.show() def removeMemoryLayers(self): ''' Iterate over all layers and remove memory ones ''' layers = self.iface.legendInterface().layers() for cur_layer in layers: layer_name = cur_layer.name().lower() if "selected_" in layer_name: QgsMapLayerRegistry.instance().removeMapLayer(cur_layer.id())
class SearchPlus(QObject): def __init__(self, iface, srid, controller): ''' Constructor ''' self.iface = iface self.srid = srid self.controller = controller # initialize plugin directory and locale self.plugin_dir = os.path.dirname(__file__) locale = QSettings().value('locale/userLocale')[0:2] locale_path = os.path.join(self.plugin_dir, 'i18n', 'SearchPlus_{}.qm'.format(locale)) if os.path.exists(locale_path): self.translator = QTranslator() self.translator.load(locale_path) if qVersion() > '4.3.3': QCoreApplication.installTranslator(self.translator) # load local settings of the plugin self.app_name = "searchplus" self.setting_file = os.path.join(self.plugin_dir, 'config', self.app_name+'.config') if not os.path.isfile(self.setting_file): message = "Config file not found at: "+self.setting_file self.controller.show_warning(message) return False self.settings = QSettings(self.setting_file, QSettings.IniFormat) self.stylesFolder = self.plugin_dir+"/styles/" # create dialog self.dlg = SearchPlusDockWidget(self.iface.mainWindow()) # Load configuration data from tables if not self.load_config_data(): self.enabled = False return # set signals self.dlg.ppoint_field_zone.activated.connect(self.ppoint_field_zone) self.dlg.ppoint_number.activated.connect(self.ppoint_zoom) self.dlg.adress_street.activated.connect(self.address_get_numbers) self.dlg.adress_street.activated.connect(self.address_zoom_street) self.dlg.adress_number.activated.connect(self.address_zoom_portal) self.dlg.hydrometer_code.activated.connect(partial(self.hydrometer_zoom, self.params['hydrometer_urban_propierties_field_code'], self.dlg.hydrometer_code)) self.dlg.urban_properties_zone.activated.connect(self.urban_field_zone) self.dlg.urban_properties_block.activated.connect(self.urban_field_block) self.dlg.urban_properties_number.activated.connect(self.urban_zoom) self.enabled = True def load_plugin_settings(self): ''' Load plugin settings ''' self.QML_PORTAL = self.settings.value('layers/QML_PORTAL', 'portal.qml').lower() self.QML_PPOINT = self.settings.value('layers/QML_PPOINT', 'point.qml').lower() self.QML_HYDROMETER = self.settings.value('layers/QML_HYDROMETER', 'hydrometer.qml').lower() self.QML_URBAN = self.settings.value('layers/QML_URBAN', 'urban.qml').lower() # get initial Scale self.scale_zoom = self.settings.value('status/scale_zoom', 2500) def load_config_data(self): ''' Load configuration data from tables ''' self.load_plugin_settings() self.params = {} sql = "SELECT * FROM "+self.controller.schema_name+".config_search_plus" row = self.controller.dao.get_row(sql) if not row: self.controller.show_warning("No data found in configuration table 'config_search_plus'") return False for i in range(0, len(row)): column_name = self.controller.dao.get_column_name(i) self.params[column_name] = str(row[i]) return True def get_layers(self): ''' Iterate over all layers to get the ones set in config file ''' # Initialize class variables self.portalMemLayer = None self.ppointMemLayer = None self.hydrometerMemLayerTo = None self.urbanMemLayer = None # Check if we have any layer loaded layers = self.iface.legendInterface().layers() if len(layers) == 0: return # Iterate over all layers to get the ones specified in 'db' config section self.layers = {} for cur_layer in layers: (uri_schema, uri_table) = self.controller.get_layer_source(cur_layer) #@UnusedVariable if uri_table is not None: if self.params['street_layer'] in uri_table: self.layers['street_layer'] = cur_layer elif self.params['portal_layer'] in uri_table: self.layers['portal_layer'] = cur_layer elif self.params['ppoint_layer'] in uri_table: self.layers['ppoint_layer'] = cur_layer elif self.params['hydrometer_layer'] in uri_table: self.layers['hydrometer_layer'] = cur_layer elif self.params['urban_propierties_layer'] in uri_table: self.layers['urban_propierties_layer'] = cur_layer def populate_dialog(self): ''' Populate the interface with values get from layers ''' if not self.enabled: return False # Get layers and full extent self.get_layers() # Tab 'Hydrometer' status = self.populate_combo('hydrometer_layer', self.dlg.hydrometer_code, self.params['hydrometer_field_urban_propierties_code'], self.params['hydrometer_field_code']) if not status: #print "Error populating Tab 'Hydrometer'" self.dlg.tab_main.removeTab(3) # Tab 'Address' status = self.address_populate('street_layer') if not status: #print "Error populating Tab 'Address'" self.dlg.tab_main.removeTab(2) # Tab 'Ppoint' status = self.populate_combo('ppoint_layer', self.dlg.ppoint_field_zone, self.params['ppoint_field_zone']) status_2 = self.populate_combo('ppoint_layer', self.dlg.ppoint_number, self.params['ppoint_field_number']) if not status or not status_2: #print "Error populating Tab 'Ppoint'" self.dlg.tab_main.removeTab(1) # Tab 'Urban Properties' status = self.urban_populate('urban_propierties_layer') if not status: #print "Error populating Tab 'Urban Properties'" self.dlg.tab_main.removeTab(0) return True def address_populate(self, parameter): ''' Populate combo 'address_street' ''' # Check if we have this search option available if not parameter in self.layers: #message = "Layer '{}' not found in parameter '{}'".format(self.params[parameter], parameter) #print message return False # Get layer features layer = self.layers[parameter] records = [(-1, '', '')] idx_field_code = layer.fieldNameIndex(self.params['street_field_code']) idx_field_name = layer.fieldNameIndex(self.params['street_field_name']) for feature in layer.getFeatures(): geom = feature.geometry() attrs = feature.attributes() field_code = attrs[idx_field_code] field_name = attrs[idx_field_name] if not type(field_code) is QPyNullVariant and geom is not None: elem = [field_code, field_name, geom.exportToWkt()] else: elem = [field_code, field_name, None] records.append(elem) # Fill combo 'address_street' self.dlg.adress_street.blockSignals(True) self.dlg.adress_street.clear() records_sorted = sorted(records, key = operator.itemgetter(1)) for i in range(len(records_sorted)): record = records_sorted[i] self.dlg.adress_street.addItem(record[1], record) self.dlg.adress_street.blockSignals(False) return True def address_get_numbers(self): ''' Populate civic numbers depending on selected street. Available civic numbers are linked with self.street_field_code column code in self.portal_layer and self.street_layer ''' # get selected street selected = self.dlg.adress_street.currentText() if selected == '': print "Any record selected" return # get street code elem = self.dlg.adress_street.itemData(self.dlg.adress_street.currentIndex()) code = elem[0] # to know the index see the query that populate the combo records = [[-1, '']] # Set filter expression layer = self.layers['portal_layer'] idx_field_code = layer.fieldNameIndex(self.params['portal_field_code']) idx_field_number = layer.fieldNameIndex(self.params['portal_field_number']) aux = self.params['portal_field_code']+" = '"+str(code)+"'" # Check filter and existence of fields expr = QgsExpression(aux) if expr.hasParserError(): message = expr.parserErrorString() + ": " + aux self.controller.show_warning(message) return if idx_field_code == -1: message = "Field '{}' not found in layer '{}'. Open '{}' and check parameter '{}'" \ .format(self.params['portal_field_code'], layer.name(), self.setting_file, 'portal_field_code') self.controller.show_warning(message) return if idx_field_number == -1: message = "Field '{}' not found in layer '{}'. Open '{}' and check parameter '{}'" \ .format(self.params['portal_field_number'], layer.name(), self.setting_file, 'portal_field_number') self.controller.show_warning(message) return # Get a featureIterator from an expression: # Get features from the iterator and do something it = layer.getFeatures(QgsFeatureRequest(expr)) for feature in it: attrs = feature.attributes() field_number = attrs[idx_field_number] if not type(field_number) is QPyNullVariant: elem = [code, field_number] records.append(elem) # Fill numbers combo records_sorted = sorted(records, key = operator.itemgetter(1)) self.dlg.adress_number.blockSignals(True) self.dlg.adress_number.clear() for record in records_sorted: self.dlg.adress_number.addItem(str(record[1]), record) self.dlg.adress_number.blockSignals(False) def address_zoom_street(self): ''' Zoom on the street with the prefined scale ''' # Get selected street selected = self.dlg.adress_street.currentText() if selected == '': print "Any record selected" return data = self.dlg.adress_street.itemData(self.dlg.adress_street.currentIndex()) wkt = data[2] # to know the index see the query that populate the combo geom = QgsGeometry.fromWkt(wkt) if not geom: message = "Geometry not valid or not defined" self.controller.show_warning(message) return # zoom on it's centroid centroid = geom.centroid() self.iface.mapCanvas().setCenter(centroid.asPoint()) self.iface.mapCanvas().zoomScale(float(self.scale_zoom)) # Toggles 'Show feature count' self.show_feature_count() def address_zoom_portal(self): ''' Show street data on the canvas when selected street and number in street tab ''' street = self.dlg.adress_street.currentText() civic = self.dlg.adress_number.currentText() if street == '' or civic == '': print "Any record selected" return # Get selected portal elem = self.dlg.adress_number.itemData(self.dlg.adress_number.currentIndex()) if not elem: # that means that user has edited manually the combo but the element # does not correspond to any combo element message = 'Element {} does not exist'.format(civic) self.controller.show_warning(message) return # select this feature in order to copy to memory layer aux = self.params['portal_field_code']+"='"+str(elem[0])+"' AND "+self.params['portal_field_number']+"='"+str(elem[1])+"'" expr = QgsExpression(aux) if expr.hasParserError(): message = expr.parserErrorString() + ": " + aux self.controller.show_warning(message) return # Get a featureIterator from an expression # Build a list of feature Ids from the previous result # Select featureswith the ids obtained layer = self.layers['portal_layer'] it = self.layers['portal_layer'].getFeatures(QgsFeatureRequest(expr)) ids = [i.id() for i in it] layer.setSelectedFeatures(ids) # Copy selected features to memory layer self.portalMemLayer = self.copy_selected(layer, self.portalMemLayer, "Point") # Zoom to generated memory layer self.zoom_to_scale() # Load style if self.QML_PORTAL is not None: self.load_style(self.portalMemLayer, self.QML_PORTAL) # Toggles 'Show feature count' self.show_feature_count() def generic_zoom(self, fieldname, combo, field_index=0): ''' Get selected element from the combo, and returns a feature request expression ''' # Get selected element from combo element = combo.currentText() if element.strip() == '': print "Any record selected" return None elem = combo.itemData(combo.currentIndex()) if not elem: # that means that user has edited manually the combo but the element # does not correspond to any combo element message = 'Element {} does not exist'.format(element) self.controller.show_warning(message) return None # Select this feature in order to copy to memory layer aux = fieldname+" = '"+str(elem[field_index])+"'" expr = QgsExpression(aux) if expr.hasParserError(): message = expr.parserErrorString() + ": " + aux self.controller.show_warning(message) return return expr def ppoint_field_zone(self): ''' Executed when field_zone is activated ''' # Filter combo 'ppoint_number' with value selected in combo 'ppoint_field_zone' text = utils_giswater.getSelectedItem(self.dlg.ppoint_field_zone) sql = "SELECT DISTINCT("+self.params['ppoint_field_number']+"::int4)" sql+= " FROM "+self.controller.schema_name+"."+self.params['ppoint_layer'] if text != 'null': sql+= " WHERE "+self.params['ppoint_field_zone']+" = '"+str(text)+"'" sql+= " ORDER BY "+self.params['ppoint_field_number'] rows = self.controller.dao.get_rows(sql) utils_giswater.fillComboBox(self.dlg.ppoint_number, rows) # Make zoom to selected elements self.ppoint_zoom() def ppoint_zoom(self): ''' Zoom to layer 'point' filtering values of all combos ''' # Build expresion search aux = "" layer = self.layers['ppoint_layer'] fieldname = self.params['ppoint_field_zone'] combo = self.dlg.ppoint_field_zone text = utils_giswater.getSelectedItem(combo) if text != "null": if aux != "": aux+= " AND " aux+= fieldname+" = '"+str(text)+"'" fieldname = self.params['ppoint_field_number'] combo = self.dlg.ppoint_number text = utils_giswater.getSelectedItem(combo) if text != "null": if aux != "": aux+= " AND " aux+= fieldname+" = '"+str(text)+"'" # Build a list of feature id's from the expression and select them if aux != '': expr = QgsExpression(aux) if expr.hasParserError(): message = expr.parserErrorString() + ": " + aux self.controller.show_warning(message) return it = layer.getFeatures(QgsFeatureRequest(expr)) ids = [i.id() for i in it] layer.setSelectedFeatures(ids) # Select all features else: layer.selectAll() # Copy selected features to memory layer self.ppointMemLayer = self.copy_selected(layer, self.ppointMemLayer, "Point") # Zoom to generated memory layer self.zoom_to_scale() # Load style if self.QML_PPOINT is not None: self.load_style(self.ppointMemLayer, self.QML_PPOINT) # Toggles 'Show feature count' self.show_feature_count() def hydrometer_zoom(self, fieldname, combo): ''' Zoom to layer 'v_edit_connec' ''' expr = self.generic_zoom(fieldname, combo) if expr is None: return # Get a featureIterator from an expression # Build a list of feature Ids from the previous result # Select featureswith the ids obtained layer = self.layers['hydrometer_layer'] it = layer.getFeatures(QgsFeatureRequest(expr)) ids = [i.id() for i in it] layer.setSelectedFeatures(ids) # Copy selected features to memory layer self.hydrometerMemLayerTo = self.copy_selected(layer, self.hydrometerMemLayerTo, "Point") # Zoom to generated memory layer self.zoom_to_scale() # Load style if self.QML_HYDROMETER is not None: self.load_style(self.hydrometerMemLayerTo, self.QML_HYDROMETER) # Toggles 'Show feature count' self.show_feature_count() def urban_populate(self, layer): ''' Populate combos tab 'urban properties' ''' status = self.populate_combo(layer, self.dlg.urban_properties_zone, self.params['urban_propierties_field_pzone']) if not status: return False status = self.populate_combo(layer, self.dlg.urban_properties_block, self.params['urban_propierties_field_block']) if not status: return False status = self.populate_combo(layer, self.dlg.urban_properties_number, self.params['urban_propierties_field_number']) if not status: return False return True def urban_field_zone(self): ''' Executed when 'urban_propierties_field_pzone' is activated ''' # Filter combo 'urban_properties_block' with value selected in combo 'urban_properties_zone' text = utils_giswater.getSelectedItem(self.dlg.urban_properties_zone) sql = "SELECT DISTINCT("+self.params['urban_propierties_field_block']+"::int4)" sql+= " FROM "+self.controller.schema_name+"."+self.params['urban_propierties_layer'] if text != 'null': sql+= " WHERE "+self.params['urban_propierties_field_pzone']+" = '"+str(text)+"'" sql+= " ORDER BY "+self.params['urban_propierties_field_block'] print sql rows = self.controller.dao.get_rows(sql) utils_giswater.fillComboBox(self.dlg.urban_properties_block, rows) # Make zoom to selected elements self.urban_zoom() def urban_field_block(self): ''' Executed when 'urban_propierties_field_block' is activated ''' text_zone = utils_giswater.getSelectedItem(self.dlg.urban_properties_zone) text_block = utils_giswater.getSelectedItem(self.dlg.urban_properties_block) # Filter combo 'urban_properties_number' with values selected in combos 'urban_properties_zone' and 'urban_properties_block' sql = "SELECT DISTINCT("+self.params['urban_propierties_field_number']+"::int4)" sql+= " FROM "+self.controller.schema_name+"."+self.params['urban_propierties_layer'] if text_zone != 'null': sql+= " WHERE "+self.params['urban_propierties_field_pzone']+" = '"+str(text_zone)+"'" if text_block != 'null': sql+= " AND "+self.params['urban_propierties_field_block']+" = '"+str(text_block)+"'" sql+= " ORDER BY "+self.params['urban_propierties_field_number'] rows = self.controller.dao.get_rows(sql) utils_giswater.fillComboBox(self.dlg.urban_properties_number, rows) # Make zoom to selected elements self.urban_zoom() def urban_zoom(self): ''' Zoom to layer 'urban' filtering values of all combos ''' # Build expresion search aux = "" layer = self.layers['urban_propierties_layer'] fieldname = self.params['urban_propierties_field_pzone'] combo = self.dlg.urban_properties_zone text = utils_giswater.getSelectedItem(combo) if text != "null": if aux != "": aux+= " AND " aux+= fieldname+" = '"+str(text)+"'" fieldname = self.params['urban_propierties_field_block'] combo = self.dlg.urban_properties_block text = utils_giswater.getSelectedItem(combo) if text != "null": if aux != "": aux+= " AND " aux+= fieldname+" = '"+str(text)+"'" fieldname = self.params['urban_propierties_field_number'] combo = self.dlg.urban_properties_number text = utils_giswater.getSelectedItem(combo) if text != "null": if aux != "": aux+= " AND " aux+= fieldname+" = '"+str(text)+"'" # Build a list of feature id's from the expression and select them if aux != '': expr = QgsExpression(aux) if expr.hasParserError(): message = expr.parserErrorString() + ": " + aux self.controller.show_warning(message) return it = layer.getFeatures(QgsFeatureRequest(expr)) ids = [i.id() for i in it] layer.setSelectedFeatures(ids) # Select all features else: layer.selectAll() # Copy selected features to memory layer self.urbanMemLayer = self.copy_selected(layer, self.urbanMemLayer, "Polygon") # Zoom to generated memory layer self.zoom_to_scale() # Load style if self.QML_URBAN is not None: self.load_style(self.urbanMemLayer, self.QML_URBAN) # Toggles 'Show feature count' self.show_feature_count() def populate_combo(self, parameter, combo, fieldname, fieldname_2=None): ''' Populate selected combo from features of selected layer ''' # Check if we have this search option available if not parameter in self.layers: message = "Layer '{}' not found in parameter '{}'".format(self.params[parameter], parameter) print(message) return False # Fields management layer = self.layers[parameter] #records = [(-1, '')] records = [] idx_field = layer.fieldNameIndex(fieldname) if idx_field == -1: message = "Field '{}' not found in the layer specified in parameter '{}'".format(fieldname, parameter) self.controller.show_warning(message) return False if fieldname_2 is not None: idx_field_2 = layer.fieldNameIndex(fieldname_2) if idx_field_2 == -1: message = "Field '{}' not found in the layer specified in parameter '{}'".format(fieldname_2, parameter) self.controller.show_warning(message) return False else: idx_field_2 = idx_field fieldname_2 = fieldname # Iterate over all features to get distinct records list_elements = [] for feature in layer.getFeatures(): attrs = feature.attributes() field = attrs[idx_field] field_2 = attrs[idx_field_2] if not type(field) is QPyNullVariant: if field not in list_elements: elem = [field, field_2] list_elements.append(field) records.append(elem) # Fill combo box combo.blockSignals(True) combo.clear() records_sorted = sorted(records, key = operator.itemgetter(1)) combo.addItem('', '') for i in range(len(records_sorted)): record = records_sorted[i] combo.addItem(str(record[1]), record) combo.blockSignals(False) return True def show_feature_count(self): ''' Toggles 'Show Feature Count' of all the layers in the root path of the TOC ''' root = QgsProject.instance().layerTreeRoot() for child in root.children(): if isinstance(child, QgsLayerTreeLayer): child.setCustomProperty("showFeatureCount", True) def zoom_to_scale(self): ''' Zoom to scale ''' scale = self.iface.mapCanvas().scale() if int(scale) < int(self.scale_zoom): self.iface.mapCanvas().zoomScale(float(self.scale_zoom)) def manage_mem_layer(self, layer): ''' Delete previous features from all memory layers Make layer not visible ''' if layer is not None: try: layer.startEditing() it = layer.getFeatures() ids = [i.id() for i in it] layer.dataProvider().deleteFeatures(ids) layer.commitChanges() self.iface.legendInterface().setLayerVisible(layer, False) except RuntimeError as e: self.controller.show_warning(str(e)) def manage_mem_layers(self): ''' Delete previous features from all memory layers ''' self.manage_mem_layer(self.portalMemLayer) self.manage_mem_layer(self.ppointMemLayer) self.manage_mem_layer(self.hydrometerMemLayerTo) self.manage_mem_layer(self.urbanMemLayer) def copy_selected(self, layer, mem_layer, geom_type): ''' Copy from selected layer to memory layer ''' self.manage_mem_layers() # Create memory layer if not already set if mem_layer is None: uri = geom_type+"?crs=epsg:"+str(self.srid) mem_layer = QgsVectorLayer(uri, "selected_"+layer.name(), "memory") # Copy attributes from main layer to memory layer attrib_names = layer.dataProvider().fields() names_list = attrib_names.toList() newattributeList = [] for attrib in names_list: aux = mem_layer.fieldNameIndex(attrib.name()) if aux == -1: newattributeList.append(QgsField(attrib.name(), attrib.type())) mem_layer.dataProvider().addAttributes(newattributeList) mem_layer.updateFields() # Insert layer in the top of the TOC root = QgsProject.instance().layerTreeRoot() QgsMapLayerRegistry.instance().addMapLayer(mem_layer, False) node_layer = QgsLayerTreeLayer(mem_layer) root.insertChildNode(0, node_layer) # Prepare memory layer for editing mem_layer.startEditing() # Iterate over selected features cfeatures = [] for sel_feature in layer.selectedFeatures(): attributes = [] attributes.extend(sel_feature.attributes()) cfeature = QgsFeature() cfeature.setGeometry(sel_feature.geometry()) cfeature.setAttributes(attributes) cfeatures.append(cfeature) # Add features, commit changes and refresh canvas mem_layer.dataProvider().addFeatures(cfeatures) mem_layer.commitChanges() self.iface.mapCanvas().refresh() self.iface.mapCanvas().zoomToSelected(layer) # Make sure layer is always visible self.iface.legendInterface().setLayerVisible(mem_layer, True) return mem_layer def load_style(self, layer, qml): ''' Load QML style file into selected layer ''' if layer is None: return path_qml = self.stylesFolder+qml if os.path.exists(path_qml) and os.path.isfile(path_qml): layer.loadNamedStyle(path_qml) def remove_memory_layers(self): ''' Iterate over all layers and remove memory ones ''' layers = self.iface.legendInterface().layers() for cur_layer in layers: layer_name = cur_layer.name().lower() if "selected_" in layer_name: QgsMapLayerRegistry.instance().removeMapLayer(cur_layer.id()) def unload(self): ''' Removes dialog ''' if self.dlg: self.dlg.deleteLater() del self.dlg
class SearchPlus(QObject): def __init__(self, iface, srid): ''' Constructor ''' self.iface = iface self.srid = srid # initialize plugin directory and locale self.plugin_dir = os.path.dirname(__file__) locale = QSettings().value('locale/userLocale')[0:2] locale_path = os.path.join(self.plugin_dir, 'i18n', 'SearchPlus_{}.qm'.format(locale)) if os.path.exists(locale_path): self.translator = QTranslator() self.translator.load(locale_path) if qVersion() > '4.3.3': QCoreApplication.installTranslator(self.translator) else: print "Locale file not found at: "+locale_path # load local settings of the plugin self.app_name = "searchplus" self.setting_file = os.path.join(self.plugin_dir, 'config', self.app_name+'.config') if not os.path.isfile(self.setting_file): message = "Config file not found at: "+self.setting_file self.iface.messageBar().pushMessage(message, QgsMessageBar.WARNING, 5) return False self.settings = QSettings(self.setting_file, QSettings.IniFormat) self.stylesFolder = self.plugin_dir+"/styles/" # load plugin settings self.loadPluginSettings() # create dialog self.dlg = SearchPlusDockWidget(self.iface.mainWindow()) # set signals self.dlg.cboStreet.currentIndexChanged.connect(self.getStreetNumbers) self.dlg.cboStreet.currentIndexChanged.connect(self.zoomOnStreet) self.dlg.cboNumber.currentIndexChanged.connect(self.displayStreetData) def loadPluginSettings(self): ''' Load plugin settings ''' # get layers configuration to populate the GUI self.STREET_LAYER = self.settings.value('layers/STREET_LAYER', '').lower() self.STREET_FIELD_CODE = self.settings.value('layers/STREET_FIELD_CODE', '').lower() self.STREET_FIELD_NAME = self.settings.value('layers/STREET_FIELD_NAME', '').lower() self.PORTAL_LAYER = self.settings.value('layers/PORTAL_LAYER', '').lower() self.PORTAL_FIELD_CODE = self.settings.value('layers/PORTAL_FIELD_CODE', '').lower() self.PORTAL_FIELD_NUMBER = self.settings.value('layers/PORTAL_FIELD_NUMBER', '').lower() self.QML_PORTAL = self.settings.value('layers/QML_PORTAL', 'portal.qml').lower() # get initial Scale self.defaultZoomScale = self.settings.value('status/defaultZoomScale', 2500) def getLayers(self): ''' Iterate over all layers to get the ones set in config file ''' self.streetLayer = None self.portalLayer = None self.portalMemLayer = None layers = self.iface.legendInterface().layers() for cur_layer in layers: name = cur_layer.name().lower() if self.STREET_LAYER in name: self.streetLayer = cur_layer elif self.PORTAL_LAYER in name: self.portalLayer = cur_layer # noinspection PyMethodMayBeStatic def tr(self, message): ''' Get the translation for a string using Qt translation API ''' return QCoreApplication.translate('SearchPlus', message) def populateGui(self): ''' Populate the interface with values get from layers ''' # Remove unused tabs self.dlg.searchPlusTabMain.removeTab(4) self.dlg.searchPlusTabMain.removeTab(3) self.dlg.searchPlusTabMain.removeTab(2) self.dlg.searchPlusTabMain.removeTab(1) # Get layers and full extent self.getLayers() # tab Streets status = self.populateStreets() return status def populateStreets(self): # Check if we have this search option available if self.streetLayer is None or self.portalLayer is None: return False # Get layer features layer = self.streetLayer records = [(-1, '', '', '')] idx_id = layer.fieldNameIndex('id') idx_field_name = layer.fieldNameIndex(self.STREET_FIELD_NAME) idx_field_code = layer.fieldNameIndex(self.STREET_FIELD_CODE) for feature in layer.getFeatures(): geom = feature.geometry() attrs = feature.attributes() field_id = attrs[idx_id] field_name = attrs[idx_field_name] field_code = attrs[idx_field_code] if not type(field_code) is QPyNullVariant and geom is not None: elem = [field_id, field_name, field_code, geom.exportToWkt()] records.append(elem) # Fill street combo self.dlg.cboStreet.blockSignals(True) self.dlg.cboStreet.clear() records_sorted = sorted(records, key = operator.itemgetter(1)) for i in range(len(records_sorted)): record = records_sorted[i] self.dlg.cboStreet.addItem(record[1], record) self.dlg.cboStreet.blockSignals(False) return True def zoomOnStreet(self): ''' Zoom on the street with the prefined scale ''' # get selected street selected = self.dlg.cboStreet.currentText() if selected == '': return # get code data = self.dlg.cboStreet.itemData(self.dlg.cboStreet.currentIndex()) wkt = data[3] # to know the index see the query that populate the combo geom = QgsGeometry.fromWkt(wkt) if not geom: message = self.tr('Can not correctly get geometry') self.iface.messageBar().pushMessage(message, QgsMessageBar.WARNING, 5) return # zoom on it's centroid centroid = geom.centroid() self.iface.mapCanvas().setCenter(centroid.asPoint()) self.iface.mapCanvas().zoomScale(float(self.defaultZoomScale)) def getStreetNumbers(self): ''' Populate civic numbers depending on selected street. Available civic numbers are linked with self.STREET_FIELD_CODE column code in self.PORTAL_LAYER and self.STREET_LAYER ''' # get selected street selected = self.dlg.cboStreet.currentText() if selected == '': return # get street code sel_street = self.dlg.cboStreet.itemData(self.dlg.cboStreet.currentIndex()) code = sel_street[2] # to know the index see the query that populate the combo records = [[-1, '']] # Set filter expression layer = self.portalLayer idx_field_code = layer.fieldNameIndex(self.PORTAL_FIELD_CODE) idx_field_number = layer.fieldNameIndex(self.PORTAL_FIELD_NUMBER) aux = self.PORTAL_FIELD_CODE+"='"+str(code)+"'" # Check filter and existence of fields expr = QgsExpression(aux) if expr.hasParserError(): self.iface.messageBar().pushMessage(expr.parserErrorString() + ": " + aux, self.app_name, QgsMessageBar.WARNING, 10) return if idx_field_code == -1: message = self.tr("Field '{}' not found in layer '{}'. Open '{}' and check parameter '{}'". format(self.PORTAL_FIELD_CODE, layer.name(), self.setting_file, 'PORTAL_FIELD_CODE')) self.iface.messageBar().pushMessage(message, '', QgsMessageBar.WARNING) return if idx_field_number == -1: message = self.tr("Field '{}' not found in layer '{}'. Open '{}' and check parameter '{}'". format(self.PORTAL_FIELD_NUMBER, layer.name(), self.setting_file, 'PORTAL_FIELD_NUMBER')) self.iface.messageBar().pushMessage(message, '', QgsMessageBar.WARNING) return # Get a featureIterator from an expression: # Get features from the iterator and do something it = layer.getFeatures(QgsFeatureRequest(expr)) for feature in it: attrs = feature.attributes() field_number = attrs[idx_field_number] if not type(field_number) is QPyNullVariant: elem = [code, field_number] records.append(elem) # Fill numbers combo records_sorted = sorted(records, key = operator.itemgetter(1)) self.dlg.cboNumber.blockSignals(True) self.dlg.cboNumber.clear() for record in records_sorted: self.dlg.cboNumber.addItem(str(record[1]), record) self.dlg.cboNumber.blockSignals(False) def manageMemLayer(self, layer): ''' Delete previous features from all memory layers Make layer not visible ''' if layer is not None: try: layer.startEditing() it = layer.getFeatures() ids = [i.id() for i in it] layer.dataProvider().deleteFeatures(ids) layer.commitChanges() self.iface.legendInterface().setLayerVisible(layer, False) except RuntimeError as e: self.iface.messageBar().pushMessage(str(e), '', QgsMessageBar.WARNING) def manageMemLayers(self): ''' Delete previous features from all memory layers ''' self.manageMemLayer(self.portalMemLayer) def copySelected(self, layer, mem_layer, geom_type): ''' Copy from selected layer to memory layer ''' self.manageMemLayers() # Create memory layer if not already set if mem_layer is None: uri = geom_type+"?crs=epsg:"+self.srid mem_layer = QgsVectorLayer(uri, "selected_"+layer.name(), "memory") # Copy attributes from main layer to memory layer attrib_names = layer.dataProvider().fields() names_list = attrib_names.toList() newattributeList = [] for attrib in names_list: aux = mem_layer.fieldNameIndex(attrib.name()) if aux == -1: newattributeList.append(QgsField(attrib.name(), attrib.type())) mem_layer.dataProvider().addAttributes(newattributeList) mem_layer.updateFields() # Insert layer in the top of the TOC root = QgsProject.instance().layerTreeRoot() QgsMapLayerRegistry.instance().addMapLayer(mem_layer, False) node_layer = QgsLayerTreeLayer(mem_layer) root.insertChildNode(0, node_layer) # Prepare memory layer for editing mem_layer.startEditing() # Iterate over selected features cfeatures = [] for sel_feature in layer.selectedFeatures(): attributes = [] attributes.extend(sel_feature.attributes()) cfeature = QgsFeature() cfeature.setGeometry(sel_feature.geometry()) cfeature.setAttributes(attributes) cfeatures.append(cfeature) # Add features, commit changes and refresh canvas mem_layer.dataProvider().addFeatures(cfeatures) mem_layer.commitChanges() self.iface.mapCanvas().refresh() self.iface.mapCanvas().zoomToSelected(layer) # Make sure layer is always visible self.iface.legendInterface().setLayerVisible(mem_layer, True) return mem_layer def displayStreetData(self): ''' Show street data on the canvas when selected street and number in street tab ''' street = self.dlg.cboStreet.currentText() civic = self.dlg.cboNumber.currentText() if street == '' or civic == '': return # get selected portal elem = self.dlg.cboNumber.itemData(self.dlg.cboNumber.currentIndex()) if not elem: # that means that user has edited manually the combo but the element # does not correspond to any combo element message = self.tr('Element {} does not exist'.format(civic)) self.iface.messageBar().pushMessage(message, QgsMessageBar.WARNING, 5) return # select this feature in order to copy to memory layer aux = self.PORTAL_FIELD_CODE+"='"+str(elem[0])+"' AND "+self.PORTAL_FIELD_NUMBER+"='"+str(elem[1])+"'" expr = QgsExpression(aux) if expr.hasParserError(): self.iface.messageBar().pushMessage(expr.parserErrorString() + ": " + aux, self.app_name, QgsMessageBar.WARNING, 5) return # Get a featureIterator from an expression # Build a list of feature Ids from the previous result # Select featureswith the ids obtained it = self.portalLayer.getFeatures(QgsFeatureRequest(expr)) ids = [i.id() for i in it] self.portalLayer.setSelectedFeatures(ids) # Copy selected features to memory layer self.portalMemLayer = self.copySelected(self.portalLayer, self.portalMemLayer, "Point") # Zoom to point layer self.iface.mapCanvas().zoomScale(float(self.defaultZoomScale)) # Load style self.loadStyle(self.portalMemLayer, self.QML_PORTAL) def loadStyle(self, layer, qml): path_qml = self.stylesFolder+qml if os.path.exists(path_qml): layer.loadNamedStyle(path_qml) def removeMemoryLayers(self): ''' Iterate over all layers and remove memory ones ''' layers = self.iface.legendInterface().layers() for cur_layer in layers: layer_name = cur_layer.name().lower() if "selected_" in layer_name: QgsMapLayerRegistry.instance().removeMapLayer(cur_layer.id()) def unload(self): ''' Removes dialog ''' if self.dlg: self.dlg.deleteLater() del self.dlg