Ejemplo n.º 1
0
    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)
Ejemplo n.º 2
0
 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)        
Ejemplo n.º 3
0
    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
Ejemplo n.º 4
0
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())   
Ejemplo n.º 5
0
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            
Ejemplo n.º 6
0
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            
                                                         
Ejemplo n.º 7
0
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