Ejemplo n.º 1
0
class MenuDiretorioConsole(MatrizConsole):
    arquivoSelecionado = pyqtSignal(str)
    def __init__(self, initDir='.', parent=None):
        super().__init__(parent=parent)

        self._dir = QDir(initDir)
        self._dir.setSorting(QDir.Name)
        self._addItensDir()

    def _addItensDir(self):
        self.clear()
        di = self._dir.entryList()
        try:
            di.remove('.')
        except ValueError:
            pass

        self.addItens([LabelConsole(i) for i in di])

    def atualizarListaArquivos(self):
        self.cd('.')

    def cd(self, diret):
        if self._dir.cd(diret):
            self._addItensDir()
            return True

        return False

    def onEnter(self):
        if not self.cd(self.getItemSelecionado().getTexto()):
            self.arquivoSelecionado.emit(self.pathArquivoSelecionado())

    def path(self):
        return self._dir.absolutePath()

    def pathArquivoSelecionado(self):
        return self.path() + '/' + self.getItemSelecionado().getTexto()

    def desenhoTela(self, tam):
        s = '|{0:-<{1}}|\n'.format('',tam-2)
        s += '|Path: {0:<{1}}{2}|\n'.format(LabelConsole(self._dir.absolutePath()).desenhoTelaConsole(tam-9), tam-9, [' ','*'][self.hasFocus()])
        s += '|{0:-<{1}}|\n'.format('',tam-2)
        for i in super().desenhoTela(tam-2).split('\n'):
            s += '|{0:<{1}}|\n'.format(i, tam-2)
        s += '|{0:-<{1}}|'.format('',tam-2)

        return s
Ejemplo n.º 2
0
    def on_gen(self):
        '''生成工程'''
        if not self.currentConfig:
            return

        #获取工程名及有效路径
        project_name = self.et_project_name.text()
        project_location = self.et_project_location.text()
        qdir = QDir(project_location)
        if not qdir.exists():
            if not qdir.mkpath(project_location):
                QMessageBox.warning(self, '警告', '路径无效!')
                return
        project_location = qdir.absolutePath()
        if not project_location.endsWith(
                '/') and not project_location.endsWith('\\'):
            project_location += os.sep
            project_location.replace('\\', '/')
        if project_name.isEmpty() or project_location.isEmpty():
            QMessageBox.warning(self, '警告', '项目名称或路径不能为空!')
            return

        self.currentConfig.project_name = app.QString2str(project_name)
        self.currentConfig.project_location = app.QString2str(project_location)

        content = self.currentConfig.toJson()
        fileInfo = QFileInfo(self.path)
        if not self.path.isEmpty():
            path = app.QString2str(self.path)
            with open(path, 'w+') as f:
                f.write(content)
        item = self.lw.currentItem()
        item.setData(QtCore.Qt.UserRole, content)

        template_name = self.currentConfig.template_source
        template_dir = app.g_pwd + os.sep + 'templates' + os.sep + template_name.encode(
            'utf-8')
        with open(template_dir + os.sep + 'config.json', 'r') as f:
            self.currentConfig.config_content = f.read()
        ret_json = app.render(self.currentConfig.config_content,
                              config=self.currentConfig)
        self.currentConfig.config = json.loads(ret_json)
        for file in self.currentConfig.config['files']:
            sourcepath = template_dir + os.sep + file['source'].encode('utf-8')
            targetdir = self.currentConfig.project_location + self.currentConfig.project_name
            targetpath = targetdir + os.sep + file['target']
            fi = QFileInfo(targetpath)
            qdir = fi.absoluteDir()
            if not qdir.exists():
                qdir.mkpath(fi.absolutePath())
            with open(sourcepath, 'r') as f:
                content = f.read()
                content = app.render(content, config=self.currentConfig)  #渲染文件
            with open(targetpath, 'w+') as f:
                f.write(content.encode('utf-8'))
        QMessageBox.information(self, '提示', '生成成功!')
Ejemplo n.º 3
0
    def __init__(self, file='settings'):
        """
        @type  file: string
        @param file: the prefix of the settings files used.  Used for testing.
        """
        userDir = QDir(os.path.expanduser('~'))

        userDir.cd('Application Data') or userDir.cd('AppData') or userDir.cd('Library')
        if not userDir.cd('BootTunes'):
            userDir.mkdir('BootTunes')
            userDir.cd('BootTunes')

        self.settingsDir = unicode(userDir.absolutePath())

        basePath = unicode(userDir.absolutePath())
        self.settingsPath  = settingsPath  = basePath + '/' + file + '-settings'
        self.defaultsPath  = defaultsPath  = basePath + '/' + file + '-defaults'
        self.namesPath     = namesPath     = basePath + '/' + file + '-names'
        self.completedPath = completedPath = basePath + '/' + file + '-completed'

        pathsAndProperties = [
            (settingsPath,  'settings'),
            (defaultsPath,  'artistDefaults'),
            (namesPath,     'artistNames'),
            (completedPath, 'completed')
        ]

        for pathAndProperty in pathsAndProperties:
            filePath = pathAndProperty[0]
            property = pathAndProperty[1]
            setattr(self, property, {})
            if os.path.exists(filePath):
                fileObj = codecs.open(filePath, 'r')
                try:
                    setattr(self, property, cPickle.load(fileObj) or {})
                except (cPickle.UnpicklingError, AttributeError, EOFError, ImportError, IndexError):
                    pass
                fileObj.close()
Ejemplo n.º 4
0
def get_list_of_symbol_paths(symbolTopLevelPaths):
    """
    Given a list of top level paths to directories containting
    sconcho kitting symbols returns a QStringList of all paths to 
    individual sconcho patterns.
    """

    symbolPaths = []
    for path in symbolTopLevelPaths:
        aDir = QDir(path)
        for entry in aDir.entryList(QDir.AllDirs | QDir.NoDotAndDotDot):
            symbolPaths.append(aDir.absolutePath() + "/" + entry)

    return symbolPaths
Ejemplo n.º 5
0
 def checkTempDir():
     tempDir = QDir(WorkerPopulateGroup.TEMP_DIR)
     if not tempDir.exists():
         msgtrans1 = QCoreApplication.translate(
             "CatalogOTF",
             "Created temporary directory '%s' for GDAL_WMS")
         msgtrans2 = QCoreApplication.translate(
             "CatalogOTF",
             "Not possible create temporary directory '%s' for GDAL_WMS"
         )
         isOk = tempDir.mkpath(WorkerPopulateGroup.TEMP_DIR)
         msgtrans = msgtrans1 if isOk else msgtrans2
         tempDir.setPath(WorkerPopulateGroup.TEMP_DIR)
         msg = msgtrans % tempDir.absolutePath()
         msgBar.pushMessage(NAME_PLUGIN, msg,
                            QpluginNamegsMessageBar.CRITICAL, 5)
Ejemplo n.º 6
0
    def on_gen(self):
        '''生成工程'''
        if not self.currentConfig:
            return

        #获取工程名及有效路径
        project_name = self.et_project_name.text()
        project_location = self.et_project_location.text()
        qdir = QDir(project_location)
        if not qdir.exists():
            if not qdir.mkpath(project_location):
                QMessageBox.warning(self, '警告', '路径无效!')
                return
        project_location = qdir.absolutePath()
        if not project_location.endsWith('/') and not project_location.endsWith('\\'):
            project_location += os.sep
        if project_name.isEmpty() or project_location.isEmpty():
            QMessageBox.warning(self, '警告', '项目名称或路径不能为空!')
            return

        self.currentConfig.project_name = app.QString2str(project_name)
        self.currentConfig.project_location = app.QString2str(project_location)
        template_name = self.currentConfig.template_source
        template_dir = app.g_pwd + os.sep + 'templates' + os.sep + template_name
        with open(template_dir + os.sep + 'config.json', 'r') as f:
            self.currentConfig.config_content = f.read()
        ret_json = app.render(self.currentConfig.config_content, config=self.currentConfig)
        self.currentConfig.config = json.loads(ret_json)
        for file in self.currentConfig.config['files']:
            sourcepath = template_dir + os.sep + file['source']
            targetdir = self.currentConfig.project_location + self.currentConfig.project_name
            targetpath = targetdir + os.sep + file['target']
            fi = QFileInfo(targetpath)
            qdir = fi.absoluteDir()
            if not qdir.exists():
                qdir.mkpath(fi.absolutePath())
            with open(sourcepath, 'r') as f:
                content = f.read()
                content = app.render(content, config=self.currentConfig) #渲染文件
            with open(targetpath, 'w+') as f:
                f.write(content.encode('utf-8'))
        QMessageBox.information(self,'提示','生成成功!')
Ejemplo n.º 7
0
    def initialize_ui(self):
        global debug

        if debug:
            self.line.setMinimumSize(400, 30)
            self.line.setStyleSheet("font-size: 15px;")

        self.enterButton.resize(0, 0)
        self.enterButton.clicked.connect(self.press_enter)
        self.enterButton.setShortcut("Return")

        self.progressBar.setMaximumWidth(120)

        self.webView = QWebView(loadProgress=self.progressBar.setValue, loadFinished=self.progressBar.hide,
                                loadStarted=self.progressBar.show,
                                titleChanged=self.setWindowTitle)
        self.webView.setMinimumSize(400, 400)
        direct = QDir('resources/index.html')
        self.webView.load(QUrl('file:///' + direct.absolutePath()))

        self.webView.urlChanged.connect(self.update_url)
        self.webView.page().linkHovered.connect(self.show_link_hovered)

        grid = QGridLayout()

        if debug:
            grid.addWidget(self.line, 0, 3, 1, 1)

        grid.addWidget(self.webView, 2, 0, 1, 6)

        self.mainWidget.setLayout(grid)

        self.setGeometry(50, 50, 1360, 768)
        self.setWindowTitle("SRSS")

        self.statusBar.addPermanentWidget(self.progressBar)
        self.statusBar.hide()

        self.setCentralWidget(self.mainWidget)
Ejemplo n.º 8
0
class Folder(DataStore):
    """
    Folder DataStore

    A folder based data store is a collection of shape files and tiff images
    stored in a common folder.

    .. versionadded:: 4.0
    """
    def __init__(self, uri):
        """
        Constructor for the folder DataStore.

        :param uri: A directory object or the path to the folder
        :type uri: QDir, str

        .. versionadded:: 4.0
        """
        super(Folder, self).__init__(uri)
        self._default_vector_format = 'shp'

        if isinstance(uri, QDir):
            self._uri = uri
        elif isinstance(uri, basestring):
            self._uri = QDir(uri)
        else:
            raise ErrorDataStore('Unknown type')

    @property
    def default_vector_format(self):
        """Default vector format for the folder datastore.

        :return: The default vector format.
        :rtype: str.
        """
        return self._default_vector_format

    @default_vector_format.setter
    def default_vector_format(self, default_format):
        """Set the default vector format for the folder datastore.

        :param default_format: The default output format.
            It can be 'shp', 'geojson' or 'kml'.
        :param default_format: str
        """
        if default_format in VECTOR_EXTENSIONS:
            self._default_vector_format = default_format

    @property
    def uri_path(self):
        """Return the URI of the datastore as a path. It's not a layer URI.

        :return: The URI.
        :rtype: str

        .. versionadded:: 4.0
        """
        return self.uri.absolutePath()

    def is_writable(self):
        """Check if the folder is writable.

        :return: If it's writable or not.
        :rtype: bool

        .. versionadded:: 4.0
        """
        return QFileInfo(self._uri.absolutePath()).isWritable()

    def supports_rasters(self):
        """Check if we can support raster in the datastore.

        :return: If it's writable or not.
        :rtype: bool

        .. versionadded:: 4.0
        """
        return True

    def layers(self):
        """Return a list of layers available.

        :return: List of layers available in the datastore.
        :rtype: list

        .. versionadded:: 4.0
        """
        extensions = ['*.%s' % f for f in EXTENSIONS]
        self.uri.setNameFilters(extensions)
        files = self.uri.entryList()
        self.uri.setNameFilters('')
        files = human_sorting([QFileInfo(f).baseName() for f in files])
        return files

    def layer_uri(self, layer_name):
        """Get layer URI.

        :param layer_name: The name of the layer to fetch.
        :type layer_name: str

        :return: The URI to the layer.
        :rtype: str

        .. versionadded:: 4.0
        """
        layers = self.layers()
        for layer, extension in product(layers, EXTENSIONS):
            one_file = QFileInfo(self.uri.filePath(layer + '.' + extension))
            if one_file.exists():
                if one_file.baseName() == layer_name:
                    return one_file.absoluteFilePath()
        else:
            return None

    def _add_tabular_layer(self, tabular_layer, layer_name):
        """Add a tabular layer to the folder.

        :param tabular_layer: The layer to add.
        :type tabular_layer: QgsVectorLayer

        :param layer_name: The name of the layer in the datastore.
        :type layer_name: str

        :returns: A two-tuple. The first element will be True if we could add
            the layer to the datastore. The second element will be the layer
            name which has been used or the error message.
        :rtype: (bool, str)

        .. versionadded:: 4.0
        """
        output = QFileInfo(self.uri.filePath(layer_name + '.csv'))

        QgsVectorFileWriter.writeAsVectorFormat(tabular_layer,
                                                output.absoluteFilePath(),
                                                'utf-8', None, 'CSV')

        assert output.exists()
        return True, output.baseName()

    def _add_vector_layer(self, vector_layer, layer_name):
        """Add a vector layer to the folder.

        :param vector_layer: The layer to add.
        :type vector_layer: QgsVectorLayer

        :param layer_name: The name of the layer in the datastore.
        :type layer_name: str

        :returns: A two-tuple. The first element will be True if we could add
            the layer to the datastore. The second element will be the layer
            name which has been used or the error message.
        :rtype: (bool, str)

        .. versionadded:: 4.0
        """

        if not self.is_writable():
            return False, 'The destination is not writable.'

        output = QFileInfo(
            self.uri.filePath(layer_name + '.' + self._default_vector_format))

        driver_mapping = {
            'shp': 'ESRI Shapefile',
            'kml': 'KML',
            'geojson': 'GeoJSON',
        }

        QgsVectorFileWriter.writeAsVectorFormat(
            vector_layer, output.absoluteFilePath(), 'utf-8',
            vector_layer.crs(), driver_mapping[self._default_vector_format])

        assert output.exists()
        return True, output.baseName()

    def _add_raster_layer(self, raster_layer, layer_name):
        """Add a raster layer to the folder.

        :param raster_layer: The layer to add.
        :type raster_layer: QgsRasterLayer

        :param layer_name: The name of the layer in the datastore.
        :type layer_name: str

        :returns: A two-tuple. The first element will be True if we could add
            the layer to the datastore. The second element will be the layer
            name which has been used or the error message.
        :rtype: (bool, str)

        .. versionadded:: 4.0
        """
        if not self.is_writable():
            return False, 'The destination is not writable.'

        output = QFileInfo(self.uri.filePath(layer_name + '.tif'))

        source = QFileInfo(raster_layer.source())
        if source.exists() and source.suffix() in ['tiff', 'tif']:
            # If it's tiff file based.
            QFile.copy(source.absoluteFilePath(), output.absoluteFilePath())

        else:
            # If it's not file based.
            renderer = raster_layer.renderer()
            provider = raster_layer.dataProvider()
            crs = raster_layer.crs()

            pipe = QgsRasterPipe()
            pipe.set(provider.clone())
            pipe.set(renderer.clone())

            file_writer = QgsRasterFileWriter(output.absoluteFilePath())
            file_writer.Mode(1)

            file_writer.writeRaster(pipe, provider.xSize(), provider.ySize(),
                                    provider.extent(), crs)

            del file_writer

        assert output.exists()
        return True, output.baseName()
Ejemplo n.º 9
0
class EasyImport:
    """QGIS Plugin Implementation."""

    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
        """
        # Save reference to the QGIS interface
        self.iface = iface
        # initialize plugin directory
        self.plugin_dir = os.path.dirname(__file__)
        # initialize locale
        locale = QSettings().value('locale/userLocale')[0:2]
        locale_path = os.path.join(
            self.plugin_dir,
            'i18n',
            'EasyImport_{}.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)

        # Create the dialog (after translation) and keep reference
        self.dlg = EasyImportDialog()

        # Declare instance attributes
        self.actions = []
        self.menu = self.tr(u'&EasyImport')
        # TODO: We are going to let the user set this up in a future iteration
        self.toolbar = self.iface.addToolBar(u'EasyImport')
        self.toolbar.setObjectName(u'EasyImport')
        
        # Root folder where shape files are stored
        self.shapeDirectory =  QDir()
        
        # XML Config file
        self.configXML = QtXml.QDomDocument()
        
        # XML current Config
        self.currentConfigXML = QtXml.QDomElement()
        
        # XML Config path
        self.configFileName = 'config.xml'
        
        # Shape file dictionnary
        # shapeFiles[shape filename] = shapefile absolute path
        self.shapeFiles = {}
        
        # Shape file dictionnary
        # pointsLayersConfig[shape filename] = Import rules XML nodes
        self.pointsLayersConfig = {}

    # 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('EasyImport', 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)

        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/EasyImport/icon.png'
        self.add_action(
            icon_path,
            text=self.tr(u'EasyImport'),
            callback=self.run,
            parent=self.iface.mainWindow())
            
        # Load settings from XML
        self.loadConfig()
        
        # Set event handlers
        self.dlg.btnBrowse.clicked.connect(self.setShapeDirectory)
        self.dlg.btnImport.clicked.connect(self.runImport)
        self.dlg.cbxConfig.currentIndexChanged.connect(self.cbxConfigChanged)
        self.dlg.txtDirectory.textEdited.connect(self.txtDirectoryChanged)
        
    
    def txtDirectoryChanged(self, text):
        self.shapeDirectory = QDir(text)
        self.getShapeFiles()
    
    def setShapeDirectory(self):
        """Display folder browser dialog."""
    
        file = QFileDialog.getExistingDirectory(None, 'Select gps/shape file directory.')
        self.dlg.txtDirectory.setText(file)
        self.shapeDirectory = QDir(file)
    
    def cbxConfigChanged(self, id):
        """Reset config on configuration combox box changes."""
         
        self.pointsLayersConfig.clear()
        self.setCurrentConfig(self.dlg.cbxConfig.itemData(id))
    
    def getShapeFiles(self):
        """Get each shapefile in defined folder."""
    
        self.shapeFiles.clear()
        shapefiles = self.shapeDirectory.entryList(['*.shp'],QDir.Files,QDir.Name)
        for file in shapefiles:
            # Populate the shape dictionnary
            self.shapeFiles[file.split('.',1)[0]] = file
            # print self.shapeFiles.keys()
            
    def removeShapeFiles(self, shapeFiles):
        """Removes generated shapefiles"""
        
        for code in shapeFiles.keys():
            paths = str(self.shapeDirectory.absolutePath() + '/' + code + '.*')
            files = glob(paths)
            # print paths
            for file in files:
                os.remove(file)
            
    def getAsciiFiles(self):
        """Get each asciifile in defined folder."""
        
#        self.asciiFiles.clear()
        asciifiles = self.shapeDirectory.entryList(['*.asc'],QDir.Files,QDir.Name)
        for file in asciifiles:            
            # Convert into shapefile
            self.ascii2shape(file)
            
    def ascii2shape(self, file):
        """Convert every input from the ascii file to the corresponding
        shapefile and creates it if it does not exists yet.
        :param file: ascii file to be converted"""

        # Read ascii
        with open(self.shapeDirectory.absolutePath() + '/' + file,'r') as f:
            content = f.readlines()

        ind = 0

        # Set spatial ref and driver
        driver = ogr.GetDriverByName('ESRI Shapefile')
        srs = osr.SpatialReference()
        epsg21781wkt = 'PROJCS["CH1903 / LV03",GEOGCS["CH1903",DATUM["CH1903",SPHEROID["Bessel 1841",6377397.155,299.1528128,AUTHORITY["EPSG","7004"]],TOWGS84[674.374,15.056,405.346,0,0,0,0],AUTHORITY["EPSG","6149"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.01745329251994328,AUTHORITY["EPSG","9122"]],AUTHORITY["EPSG","4149"]],UNIT["metre",1,AUTHORITY["EPSG","9001"]],PROJECTION["Hotine_Oblique_Mercator"],PARAMETER["latitude_of_center",46.95240555555556],PARAMETER["longitude_of_center",7.439583333333333],PARAMETER["azimuth",90],PARAMETER["rectified_grid_angle",90],PARAMETER["scale_factor",1],PARAMETER["false_easting",600000],PARAMETER["false_northing",200000],AUTHORITY["EPSG","21781"],AXIS["Y",EAST],AXIS["X",NORTH]]'
        srs.ImportFromWkt(epsg21781wkt)
        
        # Start iteration on features
        for line in content:
            # Remove undesirables tabs and double spaces
            removedTabs = re.sub(r"\s+", " ", content[ind])
        
            # split fields values
            line_fields = removedTabs.split(' ')
            
            # Avoid uncompleted lines
            if (len(line_fields)>4):

                # Create the dictionnary
                featureDict = ['GPSID','TYPE', 'CODE', 'Y', 'X', 'Z', 'DELTA', 'COMMENT']
                
                # Extract the information
                featureDict[0] = str(line_fields[0])
                #    featureDict[0] = int(re.findall(r'\d+', line_fields[0])[0])
                featureDict[1] = str(re.findall('[a-zA-Z]+', line_fields[0])[0])
                
                try:
                    featureDict[2] = int(line_fields[5])
                except ValueError:
                    featureDict[2] = 999
    
                featureDict[3] = str(line_fields[1])
                featureDict[4] = str(line_fields[2])
                featureDict[5] = str(line_fields[3])
                featureDict[6] = float(line_fields[4])
                featureDict[7] = ' '.join(line_fields[6:])
                
                ofilepath = self.shapeDirectory.absolutePath() + '/' + str(featureDict[2]) + '.shp'
                
                if not os.path.exists(ofilepath):
                    dataSource = driver.CreateDataSource(ofilepath)
                    olayer = dataSource.CreateLayer("points", srs, geom_type=ogr.wkbPoint25D)
                    olayer.CreateField(ogr.FieldDefn("Point_ID", ogr.OFTString))
                    olayer.CreateField(ogr.FieldDefn("Ortho_Heig", ogr.OFTReal))
                else:
                    dataSource = driver.Open(ofilepath,1)
                    olayer = dataSource.GetLayer()
                
                # print ofilepath
                
                # Set feature fields            
                feature = ogr.Feature(olayer.GetLayerDefn())
                feature.SetField("Point_ID", featureDict[0])
                feature.SetField("Ortho_Heig", featureDict[5])
                
                # Set geometry
                geom_wkt = 'POINT (' + featureDict[3] + ' ' + featureDict[4] + ' ' + featureDict[5] + ')'
                point = ogr.CreateGeometryFromWkt(geom_wkt)
                feature.SetGeometry(point)
                
                # Create feature            
                olayer.CreateFeature(feature)
                
                # remove feature and datasource from memory
                feature.Destroy()
                dataSource.Destroy()
            
#            else:
                #additional behaviour in case of uncompleted line
            
            
            # increment            
            ind+=1
                
        
    def setCurrentConfig(self, idConfig):
        """Load configuration from XML based on configuration id.
        :param idConfig: configuration id's stored in XML.
        :type text: str
        """
        
        # Get config node childrens if config id = idConfig
        root = self.configXML.documentElement()
        configs = root.elementsByTagName('config')
        for index in range(configs.count()):
            if configs.at(index).hasAttributes():
                nodeAttributes = configs.at(index).attributes()
                if nodeAttributes.namedItem('id').nodeValue() == idConfig:
                    self.currentConfigXML = configs.at(index)
        
        # Get all pointlayer nodes
        layerspoints = self.currentConfigXML.toElement().elementsByTagName('pointlayer')
        
        # Populate import rules (pointsLayersConfig)
        for index in range(layerspoints.count()):
            if layerspoints.at(index).hasAttributes():
                self.pointsLayersConfig[layerspoints.at(index).toElement().attributeNode('code').value()] = layerspoints.at(index).toElement()
        
    
    def loadConfig(self):
        """Load configuration combobox with configurations stored in XML configuration file."""
    
        XMLFile = QFile(self.plugin_dir  + '/' +  self.configFileName)
        if not XMLFile.open(QFile.ReadOnly | QFile.Text):
            QMessageBox.warning(self.iface.mainWindow(), "XML Configuration","Cannot read file %s:\n%s." % (self.plugin_dir + '/' + self.configFileName, XMLFile.errorString()),QMessageBox.Ok)
            return False
        ok, errorStr, errorLine, errorColumn = self.configXML.setContent(XMLFile, True)
        if not ok:
            QMessageBox.information(self.iface.mainWindow(), "XML Configuration","Parse error at line %d, column %d:\n%s" % (errorLine, errorColumn, errorStr))
            return False
        
        root = self.configXML.documentElement()
        
        configs = root.elementsByTagName('config')
        
        for index in range(configs.count()):
            if configs.at(index).hasAttributes():
                nodeAttributes = configs.at(index).attributes()
                self.dlg.cbxConfig.addItem(nodeAttributes.namedItem('name').nodeValue(), nodeAttributes.namedItem('id').nodeValue())
                
        self.setCurrentConfig(self.dlg.cbxConfig.itemData(self.dlg.cbxConfig.currentIndex()))
        return True
  
    
    def runImport(self):
        self.getAsciiFiles()
        self.getShapeFiles()        
        
        if len(self.shapeFiles) <= 0:
            QMessageBox.warning(self.iface.mainWindow(), "Shape import","No shape file found.")
            return  
        
        #Shapefiles that match the config code
        codes = set(self.shapeFiles.keys()) & set(self.pointsLayersConfig.keys())

        # Maximum value of progress bar is the number of shapefile
        self.dlg.pgbImport.setMaximum(len(codes))
        
        # For each Shapefiles that match the config code
        for k in codes:
            # Import data based on config
            self.importData(self.shapeDirectory.absolutePath() + "/" + self.shapeFiles[k], k)
            # Increment progress bar
            self.dlg.pgbImport.setValue(self.dlg.pgbImport.value() + 1)
            
        self.removeShapeFiles(self.shapeFiles)
    
    def importData(self, filename, code):
        """Import data from shapefile to an specified layer in project.
        :param filename: shapefile filename.
        :type text: str
        :param code: shapefile name.
        :type text: str
        """
        
        driver = ogr.GetDriverByName('ESRI Shapefile')
        layers = QgsMapLayerRegistry.instance().mapLayers()
        destinationlayer = None
        colunmMappingDict = {}
        staticMappingDict = {}
        regexMappingDict = {}
        
        destinationLayerName = self.pointsLayersConfig[code].elementsByTagName('destinationlayer').item(0).toElement().text()
        columnMappings = self.pointsLayersConfig[code].elementsByTagName('columnmapping')
        staticMappings = self.pointsLayersConfig[code].elementsByTagName('staticmapping')
        
        # No destination layer found in XML
        if destinationLayerName is None:
            return
        
        for k in layers.keys():
            if layers[k].name() == destinationLayerName:
                destinationlayer = layers[k]
        
        # No destination layer found in QGis Project
        if destinationlayer is None:
            return
        
        dataSource = driver.Open(filename, 0)
        
        if dataSource is None:
            self.dlg.txtOut.appendPlainText('Could not open %s \n' % (filename))
        else:
            self.dlg.txtOut.appendPlainText('Opened %s' % (filename))
            layer = dataSource.GetLayer()
            featureCount = layer.GetFeatureCount()
        
        # Get import rules with column mappings
        
        for index in range(columnMappings.count()):
                sourcecolumnname = columnMappings.at(index).toElement().elementsByTagName('source').item(0).toElement().text()
                destinationcolumnname = columnMappings.at(index).toElement().elementsByTagName('destination').item(0).toElement().text()
                regex = columnMappings.at(index).toElement().elementsByTagName('regex')
                if not (regex is None):
                    regexMappingDict[sourcecolumnname] = regex.item(0).toElement().text()
                colunmMappingDict[sourcecolumnname] = destinationcolumnname
        
        # Get import rules with static value mappings        
              
        for index in range(staticMappings.count()):
                staticValue = staticMappings.at(index).toElement().elementsByTagName('value').item(0).toElement().text()
                destinationcolumnname = staticMappings.at(index).toElement().elementsByTagName('destination').item(0).toElement().text()
                staticMappingDict[destinationcolumnname] = staticValue
        
        # Enable edit mode on destination layer
        destinationlayer.startEditing()
        
        # Retrieve all column off destination layer
        fields = destinationlayer.pendingFields()
        
        # For each data in shapefile
        for feature in layer:
        
            #Create new feature in destination layer and get geometry from shapefile
            newFeature = QgsFeature(fields)
            newFeature.setGeometry(QgsGeometry.fromWkt(str(feature.GetGeometryRef())))
                        
            # For each column mapping
            for k in colunmMappingDict.keys():
                # print "source %s -> destination %s" % (k,colunmMappingDict[k])
                
                # With regex
                if regexMappingDict[k]:
                    regexp = re.compile(regexMappingDict[k])
                    # print str(k)
                    # print feature.GetField(str(k))
                    
                    m = regexp.match(feature.GetField(str(k)))
                    if not (m is None):
                        # print 'Regex : %s   --> Value : %s' % (regexMappingDict[k], m.group('group'))
                        newFeature.setAttribute(fields.fieldNameIndex(colunmMappingDict[k]), m.group('group'))
                
                # Without regex
                else:
                    newFeature.setAttribute(fields.fieldNameIndex(colunmMappingDict[k]), feature.GetField(str(k)))
            
            # For each static value mapping
            for k in staticMappingDict.keys():
                #print "destination %s -> value %s" % (k,staticMappingDict[k])
                newFeature.setAttribute(fields.fieldNameIndex(k), staticMappingDict[k])
            
            # Add new feature in destination layer
            destinationlayer.addFeature(newFeature, True)
            
        self.dlg.txtOut.appendPlainText('Shape %s : %s features imported \n' % (code, featureCount))

    
    def unload(self):
        """Removes the plugin menu item and icon from QGIS GUI."""
        for action in self.actions:
            self.iface.removePluginMenu(
                self.tr(u'&EasyImport'),
                action)
            self.iface.removeToolBarIcon(action)

    def run(self):
        """Run method that performs all the real work"""
        # show the dialog
        self.dlg.show()
        # Run the dialog event loop
        result = self.dlg.exec_()
        
        # Reset progress bar value
        self.dlg.pgbImport.setValue(0)
        
        # Reset output text box
        self.dlg.txtOut.clear()
        
        
        # See if OK was pressed
        if result:
            # Do something useful here - delete the line containing pass and
            # substitute with your code.
            pass
Ejemplo n.º 10
0
class EkdSaveDialog(QDialog):
    '''
    EkdSaveDialog : Classe représentant la boite de dialogue utiliser lors de
                    l'enregistrement des modification sur un fichier donné
        attributs : suffix   - Suffix utilisé en filtre
                    filter   - Filtre (déduit à partir du suffix)
                    chemin   - Chemin du dernier fichier enregistré
                    multiple - va-t-on enregistrer plus d'un fichier ?
                                (ex: extraction d'image d'une vidéo)
        méthodes  : getFile - Invoque la boite de dialogue et retourne
                    le fichier saisi
    '''
    ### Pourquoi avoir réimplémenté cette classe au lieu de passer par
    ### QFileDialog ?
    ## Correction du bug de consommation mémoire
    ##
    ##  Explication du problème :
    ##   Par défaut un QFileDialog utilise un QFileSystemModel qui lui
    ##   crée un QWatchFileSystem
    ##   Hors QWatchFileSystem scan régulièrement les changement
    ##   dans le répertoire courant
    ##   Ce phénomène provoque une réaction en chaine :
    ##     1 - je choisi mon répertoire de destination d'enregistrement
    ##         de mes images
    ##     2 - ffmpeg se lance
    ##     3 - ffmpeg crée un fichier dans l'arborescence
    ##     4 - QWatchFileSystem (est toujours dans le répertoire courant)
    ##         détecte un changement
    ##         et recharge l'ensemble du contenue du répertoire
    ##     5 - goto 3 jusqu'à plus de mémoire ou fin du process ffmpeg
    ##
    ##

    def __init__(self, parent, path = None, suffix = '', title = u"Sauver",
                                            multiple = False, mode = None):

        if type(suffix) == tuple or type(suffix) == list :
            sfilter=""
            for s in suffix :
                sfilter += "*"+s+" "
            self.filter=sfilter[:-1]
            # Si on a plusieur suffix, on prend le premier par défaut pour
            # la sauvegarde
            self.suffix = suffix[0]
        else :
            self.suffix = suffix
            self.filter = "*" + self.suffix

        QDialog.__init__(self, parent)

        self.setWindowTitle(title)
        self.multiple = multiple
        self.mode = mode

        if not path:
            if self.mode == "image" :
                path = EkdConfig.get("general", "image_output_path")
            elif self.mode == "video" :
                path = EkdConfig.get("general", "video_output_path")
            elif self.mode == "audio" :
                path = EkdConfig.get("general", "sound_output_path")
            else :
                path = unicode(QDir.homePath())

        # Nom du répertoire courant
        self.location = QLabel("<b>%s</b>" % path)
        # Variable permettant de savoir à tout moment le répertoire courant.
        self.currentDir = path
        self.mkdirButton = QPushButton(u"  Créer un répertoire")
        self.mkdirButton.setIcon(QIcon("Icones" + os.sep + "add_sub_task.png"))
        if int(EkdConfig.get("general", "show_hidden_files")) :
            #print "hidden shown"
	    EkdPrint(u"hidden shown")
            shf = QDir.Hidden
        else : shf = QDir.Readable
        # Liste des fichiers
        self.dirList = QListView()
        sorting = QDir.DirsFirst
        if int(EkdConfig.get("general", "ignore_case")):
            sorting |= QDir.IgnoreCase
        self.sorting = sorting
        self.flags = QDir.Files | QDir.Readable | shf
        self.dirModel = QStandardItemModel()
        self.dirList.setModel(self.dirModel)
        self.updateDir(path)
        self.dirList.setWrapping(True)

        #panneau latéral
        self.dirTree = QTreeView()
        self.dirModelLight = QDirModel(QStringList(""), QDir.AllDirs |
                                    QDir.NoDotAndDotDot | shf, QDir.DirsFirst |
                                    QDir.Name | QDir.IgnoreCase)
        self.dirTree.setModel(self.dirModelLight)
        self.dirTree.setColumnHidden(1,True)
        self.dirTree.setColumnHidden(2,True)
        self.dirTree.setColumnHidden(3,True)
        self.dirTree.setMaximumWidth(200)
        self.dirTree.setMinimumWidth(150)
        self.dirTree.setCurrentIndex(self.dirModelLight.index(path))
        self.dirTree.resizeColumnToContents(0)
        self.connect(self.dirTree, SIGNAL("pressed(QModelIndex)"),
                                                    self.updateLatDir)
        self.connect(self.dirTree, SIGNAL("expanded(QModelIndex)"),
                                                        self.treeMAJ)
        self.connect(self.dirTree, SIGNAL("collapsed(QModelIndex)"),
                                                        self.treeMAJ)

        # Nom du fichier
        self.fileField = QLineEdit()

        # Nom du filtre
        self.filterField = QComboBox()
        self.filterField.addItems(QStringList(self.filter))

        # Bouton de sauvegarde et d'annulation
        self.saveButton = QPushButton(_(u"  Enregistrer"))
        self.saveButton.setIcon(QIcon("Icones" + os.sep + "action.png"))
        self.cancelButton = QPushButton(_(u"  Annuler"))
        self.cancelButton.setIcon(QIcon("Icones" + os.sep + "annuler.png"))

        # Organisation des différents objets de la boite de dialogue
        self.layout = QHBoxLayout(self)
        self.layout.addWidget(self.dirTree)
        self.filelinelayout = QGridLayout()
        self.filelinelayout.addWidget(self.location, 0, 0, 1, 0)
        self.filelinelayout.addWidget(self.mkdirButton, 0, 2)
        self.filelinelayout.addWidget(self.dirList, 1, 0, 1, 0)
        self.filelinelayout.addWidget(QLabel(_("Nom de fichier : ")), 2, 0)
        self.filelinelayout.addWidget(self.fileField, 2, 1)
        self.filelinelayout.addWidget(self.saveButton, 2, 2)
        self.filelinelayout.addWidget(QLabel(_("Filtre extension : ")), 3, 0)
        self.filelinelayout.addWidget(self.filterField, 3, 1)
        self.filelinelayout.addWidget(self.cancelButton, 3, 2)

        self.layout.addLayout(self.filelinelayout)

        # Connexion des différents objets
        self.connect(self.dirList, SIGNAL("clicked(QModelIndex)"),
                                                        self.updateFile)
        self.connect(self.saveButton, SIGNAL("clicked()"), self.accept)
        self.connect(self.cancelButton, SIGNAL("clicked()"), self.reject)
        self.connect(self.mkdirButton, SIGNAL("clicked()"), self.mkdir)
        self.connect(self.dirList,
                    SIGNAL("indexesMoved (const QModelIndexList&)"),
                    self.updateFile)
        self.connect(self.fileField, SIGNAL("textChanged (const QString&)"),
                    self.activate)
        self.connect(self.fileField, SIGNAL("returnPressed()"), self.accept)

        # Taille minimum
        self.setMinimumSize(700, 480)

        # Par défaut, on désactive
        self.deactivate()

        # Completion des fichiers
        self.completion = QCompleter(self.dirModel, self.dirList)

    def updateLatDir(self, item) :
        """ Fonction permettant de naviguer dans la listes des répertoires """
        self.updateDir(self.dirModelLight.filePath(item))

    def treeMAJ(self, item) :
        self.dirTree.resizeColumnToContents(0)

    def activate(self, filename=None):
        """ Activation des boutton de sauvegarde """
        self.dirList.clearSelection()
        if filename != "":
            self.saveButton.setEnabled(True)
        else:
            self.saveButton.setEnabled(False)

    def deactivate(self):
        """ Désactivation des boutton de sauvegarde """
        self.saveButton.setEnabled(False)

    def updateDir(self, path = None):
        """ Fonction permettant de naviguer dans la listes des répertoires """

        if path :
            self.currentDir = path
            self.location.setText("<b>%s</b>" % path)
        self.dirModel.clear()
        self.tmpdir = QDir()
        self.tmpdir.setPath(self.currentDir)
        self.tmpdir.setNameFilters(QStringList(self.filter))

        # Une icône pour les images, un autre icône pour les vidéos, et
        # une pour audio
        if self.mode == "image" :
            icone = QIcon("Icones" + os.sep + "image_image.png")
        elif self.mode == "video" :
            icone = QIcon("Icones" + os.sep + "image_video.png")
        elif self.mode == "audio" :
            icone = QIcon("Icones" + os.sep + "image_audio.png")
        else:
            icone = QIcon("Icones" + os.sep + "image_default.png")

        for wlfile in self.tmpdir.entryList(QDir.Files):
            if self.mode == "image" :
                icone = QIcon(EkdPreview("Icones" + os.sep + "image_default.png").get_preview())
            item = QStandardItem(icone, QString(wlfile))
            item.setToolTip(wlfile)
            item.setData(QVariant(self.tmpdir.absolutePath() + os.sep + wlfile), Qt.UserRole + 2)
            item.setData(QVariant(wlfile), Qt.UserRole + 3)
            self.dirModel.appendRow(item)


    def updateFile(self, item):
        """ Fonction appelée par la listView lors d'un changement de repertoire"""
        # On récupère le QModel parent du QModelItem
        path = "%s" % item.data(Qt.UserRole + 2).toString()
        name = os.path.basename(path)
        self.fileField.selectAll()
        self.fileField.setFocus()
        self.fileField.setText(name)
        self.activate(name)

    def selectedFile(self):
        """ Renvoi le fichier selectionné pour la sauvegarde"""
        # Récupération du fichier selectionné
        fichier = self.fileField.text()
        output = "%s%s%s" % (self.currentDir, os.sep, fichier)
        info = QFileInfo(output)
        # Si l'utilisateur n'a pas spécifié de suffix, on l'ajoute
        if info.suffix() != self.suffix[1:]:
            output = "%s%s" % (output, self.suffix)
        return output

    def mkdir(self):
        """ Crée un répertoire dans le répertoire courant """
        (dirname, ok) = QInputDialog.getText(self, _(u"Nouveau répertoire"), _(u"Nom du répertoire"), QLineEdit.Normal, _(u"Nouveau répertoire"))
        if ok :
            try :
                os.mkdir("%s%s%s" % (self.currentDir, os.sep,dirname))
                #print u"Création de : %s%s%s" % (self.currentDir, os.sep, dirname)
		EkdPrint(u"Création de : %s%s%s" % (self.currentDir, os.sep, dirname))
                self.updateDir()
                self.dirModelLight.refresh()
            except Exception, e:
                #print _(u"Impossible de crée un nouveau répertoire : %s" % e)
		EkdPrint(_(u"Impossible de crée un nouveau répertoire : %s" % e))
Ejemplo n.º 11
0
class Folder(DataStore):
    """
    Folder DataStore

    A folder based data store is a collection of shape files and tiff images
    stored in a common folder.

    .. versionadded:: 4.0
    """

    def __init__(self, uri):
        """
        Constructor for the folder DataStore.

        :param uri: A directory object or the path to the folder
        :type uri: QDir, str

        .. versionadded:: 4.0
        """
        super(Folder, self).__init__(uri)
        self._default_vector_format = 'shp'

        if isinstance(uri, QDir):
            self._uri = uri
        elif isinstance(uri, basestring):
            self._uri = QDir(uri)
        else:
            raise ErrorDataStore('Unknown type')

    @property
    def default_vector_format(self):
        """Default vector format for the folder datastore.

        :return: The default vector format.
        :rtype: str.
        """
        return self._default_vector_format

    @default_vector_format.setter
    def default_vector_format(self, default_format):
        """Set the default vector format for the folder datastore.

        :param default_format: The default output format.
            It can be 'shp', 'geojson' or 'kml'.
        :param default_format: str
        """
        if default_format in VECTOR_EXTENSIONS:
            self._default_vector_format = default_format

    @property
    def uri_path(self):
        """Return the URI of the datastore as a path. It's not a layer URI.

        :return: The URI.
        :rtype: str

        .. versionadded:: 4.0
        """
        return self.uri.absolutePath()

    def is_writable(self):
        """Check if the folder is writable.

        :return: If it's writable or not.
        :rtype: bool

        .. versionadded:: 4.0
        """
        return QFileInfo(self._uri.absolutePath()).isWritable()

    def supports_rasters(self):
        """Check if we can support raster in the datastore.

        :return: If it's writable or not.
        :rtype: bool

        .. versionadded:: 4.0
        """
        return True

    def layers(self):
        """Return a list of layers available.

        :return: List of layers available in the datastore.
        :rtype: list

        .. versionadded:: 4.0
        """
        extensions = ['*.%s' % f for f in EXTENSIONS]
        self.uri.setNameFilters(extensions)
        files = self.uri.entryList()
        self.uri.setNameFilters('')
        files = human_sorting([QFileInfo(f).baseName() for f in files])
        return files

    def layer_uri(self, layer_name):
        """Get layer URI.

        :param layer_name: The name of the layer to fetch.
        :type layer_name: str

        :return: The URI to the layer.
        :rtype: str

        .. versionadded:: 4.0
        """
        layers = self.layers()
        for layer, extension in product(layers, EXTENSIONS):
            one_file = QFileInfo(
                self.uri.filePath(layer + '.' + extension))
            if one_file.exists():
                if one_file.baseName() == layer_name:
                    return one_file.absoluteFilePath()
        else:
            return None

    def _add_tabular_layer(self, tabular_layer, layer_name):
        """Add a tabular layer to the folder.

        :param tabular_layer: The layer to add.
        :type tabular_layer: QgsVectorLayer

        :param layer_name: The name of the layer in the datastore.
        :type layer_name: str

        :returns: A two-tuple. The first element will be True if we could add
            the layer to the datastore. The second element will be the layer
            name which has been used or the error message.
        :rtype: (bool, str)

        .. versionadded:: 4.0
        """
        output = QFileInfo(
            self.uri.filePath(layer_name + '.csv'))

        QgsVectorFileWriter.writeAsVectorFormat(
            tabular_layer,
            output.absoluteFilePath(),
            'utf-8',
            None,
            'CSV')

        assert output.exists()
        return True, output.baseName()

    def _add_vector_layer(self, vector_layer, layer_name):
        """Add a vector layer to the folder.

        :param vector_layer: The layer to add.
        :type vector_layer: QgsVectorLayer

        :param layer_name: The name of the layer in the datastore.
        :type layer_name: str

        :returns: A two-tuple. The first element will be True if we could add
            the layer to the datastore. The second element will be the layer
            name which has been used or the error message.
        :rtype: (bool, str)

        .. versionadded:: 4.0
        """

        if not self.is_writable():
            return False, 'The destination is not writable.'

        output = QFileInfo(
            self.uri.filePath(layer_name + '.' + self._default_vector_format))

        driver_mapping = {
            'shp': 'ESRI Shapefile',
            'kml': 'KML',
            'geojson': 'GeoJSON',
        }

        QgsVectorFileWriter.writeAsVectorFormat(
            vector_layer,
            output.absoluteFilePath(),
            'utf-8',
            vector_layer.crs(),
            driver_mapping[self._default_vector_format])

        assert output.exists()
        return True, output.baseName()

    def _add_raster_layer(self, raster_layer, layer_name):
        """Add a raster layer to the folder.

        :param raster_layer: The layer to add.
        :type raster_layer: QgsRasterLayer

        :param layer_name: The name of the layer in the datastore.
        :type layer_name: str

        :returns: A two-tuple. The first element will be True if we could add
            the layer to the datastore. The second element will be the layer
            name which has been used or the error message.
        :rtype: (bool, str)

        .. versionadded:: 4.0
        """
        if not self.is_writable():
            return False, 'The destination is not writable.'

        output = QFileInfo(self.uri.filePath(layer_name + '.tif'))

        source = QFileInfo(raster_layer.source())
        if source.exists() and source.suffix() in ['tiff', 'tif']:
            # If it's tiff file based.
            QFile.copy(source.absoluteFilePath(), output.absoluteFilePath())

        else:
            # If it's not file based.
            renderer = raster_layer.renderer()
            provider = raster_layer.dataProvider()
            crs = raster_layer.crs()

            pipe = QgsRasterPipe()
            pipe.set(provider.clone())
            pipe.set(renderer.clone())

            file_writer = QgsRasterFileWriter(output.absoluteFilePath())
            file_writer.Mode(1)

            file_writer.writeRaster(
                pipe,
                provider.xSize(),
                provider.ySize(),
                provider.extent(),
                crs)

            del file_writer

        assert output.exists()
        return True, output.baseName()
Ejemplo n.º 12
0
class Georeferencer(QObject):

    # Step enum
    Start = 0
    Crop = 1
    Translate = 2
    Warp = 3
    Overview = 4
    Stop = 5
    Step = [0, 1, 2, 3, 4, 5]
    Label = ['Start', 'Crop', 'Translate', 'Warp', 'Overview', 'Stop']

    # Georeferencer.Step, ProcessStatus
    status = pyqtSignal(int, int)
    # Georeferencer.Step, Message
    error = pyqtSignal(int, str)

    def __init__(self, parent=None):
        super(Georeferencer, self).__init__(parent)

        # Internal variables
        self._debug = True
        self._gdalDir = QDir()
        self._step = 0
        self._status = 0
        self._translate = QFileInfo()
        self._warp = QFileInfo()
        self._overview = QFileInfo()
        self._command = ''
        self._args = ''
        self._process = QProcess()
        self._gc = Transform()
        self._rawFile = QFileInfo()
        self._pointFile = QFileInfo()
        self._cropFile = QFileInfo()
        self._translateFile = QFileInfo()
        self._geoFile = QFileInfo()

        tempDir = QDir.temp()
        self._cropFile.setFile(
            tempDir.absoluteFilePath('.ark_georef_crop.png'))
        self._translateFile = QFileInfo(
            tempDir.absoluteFilePath('.ark_georef_translate.tiff'))

        self._gdalDir = QDir(self.gdalPath())
        if self._debug:
            debug('GDAL Path: ' + self._gdalDir.absolutePath())
        self._translate.setFile(self._gdalDir, 'gdal_translate')
        self._warp.setFile(self._gdalDir, 'gdalwarp')
        self._overview.setFile(self._gdalDir, 'gdaladdo')
        if (not self._translate.exists() or not self._warp.exists()
                or not self._overview.exists()):
            self._signalError(
                'GDAL commands not found, please ensure GDAL Tools plugin is installed and has correct path set!'
            )
            return

        self._process.started.connect(self._processStarted)
        self._process.finished.connect(self._processFinished)
        self._process.error.connect(self._processError)
        self._process.readyReadStandardError.connect(self._processError)

    def step(self):
        return self._step

    def processStatus(self):
        return self._status

    def run(self, gc, rawFile, pointFile, geoFile):
        self._step = Georeferencer.Start
        if (not gc.isValid()):
            self._signalError('Invalid ground control points.')
            return
        self._gc = gc

        if (not rawFile.exists()):
            self._signalError('Raw file not found.')
            return
        self._rawFile = rawFile

        self._pointFile = pointFile
        self._geoFile = geoFile
        if not self._geoFile.absoluteDir().exists():
            self._geoFile.absoluteDir().mkpath('.')

        if (self._debug):
            debug('Raw File: \'' + self._rawFile.absoluteFilePath() + '\'')
            debug('GCP File: \'' + self._pointFile.absoluteFilePath() + '\'')
            debug('Crop File: \'' + self._cropFile.absoluteFilePath() + '\'')
            debug('Translate File: \'' +
                  self._translateFile.absoluteFilePath() + '\'')
            debug('Geo File: \'' + self._geoFile.absoluteFilePath() + '\'')

        QCoreApplication.processEvents()
        self._runCropStep()

    def _runCropStep(self):
        if self._debug:
            debug('Crop')
        self._step = Georeferencer.Crop
        self._args = []
        self._command = ''
        pixmap = QPixmap(self._rawFile.absoluteFilePath())
        if pixmap.isNull():
            self._signalError('Loading of raw image failed.')
            return
        pixmap = pixmap.copy(0, 0, pixmap.width(), int(pixmap.height() * 0.84))
        image = pixmap.toImage()
        if image.isNull():
            self._signalError('Cropping of raw image failed.')
            return
        if not image.save(self._cropFile.absoluteFilePath(), 'PNG', 100):
            self._signalError('Saving of cropped image failed.')
            return
        self._signalStatus()
        self._runTranslateStep()

    def _formatGcp(self, point):
        point = self._gc.point(point)
        return "{0:f} {1:f} {2:f} {3:f}".format(point.raw().x(),
                                                point.raw().y(),
                                                point.map().x(),
                                                point.map().y())

    def _runTranslateStep(self):
        self._step = Georeferencer.Translate
        self._args = []
        self._args.extend(['-of', 'GTiff'])
        self._args.extend(['-a_srs', self._gc.crs])
        # self._args.extend(['-gcp', self._formatGcp(1)])
        # self._args.extend(['-gcp', self._formatGcp(2)])
        # self._args.extend(['-gcp', self._formatGcp(3)])
        # self._args.extend(['-gcp', self._formatGcp(4)])
        self._args.extend([
            '-gcp',
            str(self._gc.point(1).raw().x()),
            str(self._gc.point(1).raw().y()),
            str(self._gc.point(1).map().x()),
            str(self._gc.point(1).map().y())
        ])
        self._args.extend([
            '-gcp',
            str(self._gc.point(2).raw().x()),
            str(self._gc.point(2).raw().y()),
            str(self._gc.point(2).map().x()),
            str(self._gc.point(2).map().y())
        ])
        self._args.extend([
            '-gcp',
            str(self._gc.point(3).raw().x()),
            str(self._gc.point(3).raw().y()),
            str(self._gc.point(3).map().x()),
            str(self._gc.point(3).map().y())
        ])
        self._args.extend([
            '-gcp',
            str(self._gc.point(4).raw().x()),
            str(self._gc.point(4).raw().y()),
            str(self._gc.point(4).map().x()),
            str(self._gc.point(4).map().y())
        ])
        self._args.append(self._cropFile.absoluteFilePath())
        self._args.append(self._translateFile.absoluteFilePath())
        self._command = self._translate.absoluteFilePath() + ' ' + ' '.join(
            self._args)
        self._process.start(self._translate.absoluteFilePath(), self._args)

    def _runWarpStep(self):
        self._step = Georeferencer.Warp
        self._args = []
        self._args.extend(['-order', '1'])
        self._args.extend(['-r', 'cubic'])
        self._args.extend(['-t_srs', self._gc.crs])
        self._args.extend(['-of', 'GTiff'])
        self._args.extend(['-co', 'COMPRESS=JPEG'])
        self._args.extend(['-co', 'JPEG_QUALITY=50'])
        self._args.extend(['-co', 'TILED=YES'])
        self._args.append('-dstalpha')
        self._args.append('-overwrite')
        self._args.append('\"' + self._translateFile.absoluteFilePath() + '\"')
        self._args.append('\"' + self._geoFile.absoluteFilePath() + '\"')
        self._command = self._warp.absoluteFilePath() + ' ' + ' '.join(
            self._args)
        self._process.start(self._command)

    def _runOverviewStep(self):
        self._step = Georeferencer.Overview
        self._args = []
        self._args.extend(['--config', 'COMPRESS_OVERVIEW JPEG'])
        self._args.extend(['--config', 'INTERLEAVE_OVERVIEW PIXEL'])
        self._args.extend(['-r', 'cubic'])
        self._args.append('\"' + self._geoFile.absoluteFilePath() + '\"')
        self._args.append('2 4 8 16')
        self._command = self._overview.absoluteFilePath() + ' ' + ' '.join(
            self._args)
        self._process.start(self._command)

    def _processStarted(self):
        self._status = ProcessStatus.Running
        self._signalStatus()
        if self._debug:
            debug(self.Label[self._step])
            debug(self._command)

    def _processFinished(self):
        self._status = ProcessStatus.Success
        self._signalStatus()
        if (self._step == Georeferencer.Translate):
            self._runWarpStep()
        elif (self._step == Georeferencer.Warp):
            self._runOverviewStep()
        elif (self._step == Georeferencer.Overview):
            self.writeGcpFile(self._gc, self._pointFile.absoluteFilePath())
            self._step = Georeferencer.Stop
            self._signalStatus()

    def _processError(self):
        self._status = ProcessStatus.Failure
        msg = str(self._process.readAllStandardError())
        debug(msg)
        self._signalError(msg)

    def _signalStatus(self):
        self.status.emit(self._step, self._status)

    def _signalError(self, msg):
        self.error.emit(self._step, msg)

    @staticmethod
    def gdalPath():
        return QSettings().value('/GdalTools/gdalPath', '/usr/bin')

    @staticmethod
    def loadGcpFile(path):
        inFile = QFile(path)
        if (not inFile.open(QIODevice.ReadOnly | QIODevice.Text)):
            return 'ERROR: Unable to open GCP file for reading'
        inStream = QTextStream(inFile)
        line = inStream.readLine()
        # Skip the header line if found
        if (line == 'mapX,mapY,pixelX,pixelY,enable'):
            line = inStream.readLine()
        lines = 0
        gc = Transform()
        while (line):
            lines += 1
            vals = line.split(',')
            if (len(vals) != 5):
                return None
            map = QgsPoint(float(vals[0]), float(vals[1]))
            raw = QPointF(float(vals[2]), float(vals[3]))
            enabled = bool(vals[4])
            point = GroundControlPoint(raw, map, enabled)
            gc.setPoint(lines, point)
            line = inStream.readLine()
        inFile.close()
        return gc

    @staticmethod
    def writeGcpFile(gc, path):
        outFile = QFile(path)
        if (not outFile.open(QIODevice.WriteOnly | QIODevice.Text)):
            return 'Unable to open GCP file for writing'
        outStream = QTextStream(outFile)
        outStream << gc.asCsv()
        outFile.close()
Ejemplo n.º 13
0
class EasyImport:
    """QGIS Plugin Implementation."""
    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
        """
        # Save reference to the QGIS interface
        self.iface = iface
        # initialize plugin directory
        self.plugin_dir = os.path.dirname(__file__)
        # initialize locale
        locale = QSettings().value('locale/userLocale')[0:2]
        locale_path = os.path.join(self.plugin_dir, 'i18n',
                                   'EasyImport_{}.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)

        # Create the dialog (after translation) and keep reference
        self.dlg = EasyImportDialog()

        # Declare instance attributes
        self.actions = []
        self.menu = self.tr(u'&EasyImport')
        # TODO: We are going to let the user set this up in a future iteration
        self.toolbar = self.iface.addToolBar(u'EasyImport')
        self.toolbar.setObjectName(u'EasyImport')

        # Root folder where shape files are stored
        self.shapeDirectory = QDir()

        # XML Config file
        self.configXML = QtXml.QDomDocument()

        # XML current Config
        self.currentConfigXML = QtXml.QDomElement()

        # XML Config path
        self.configFileName = 'config.xml'

        # Shape file dictionnary
        # shapeFiles[shape filename] = shapefile absolute path
        self.shapeFiles = {}

        # Shape file dictionnary
        # pointsLayersConfig[shape filename] = Import rules XML nodes
        self.pointsLayersConfig = {}

    # 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('EasyImport', 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)

        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/EasyImport/icon.png'
        self.add_action(icon_path,
                        text=self.tr(u'EasyImport'),
                        callback=self.run,
                        parent=self.iface.mainWindow())

        # Load settings from XML
        self.loadConfig()

        # Set event handlers
        self.dlg.btnBrowse.clicked.connect(self.setShapeDirectory)
        self.dlg.btnImport.clicked.connect(self.runImport)
        self.dlg.cbxConfig.currentIndexChanged.connect(self.cbxConfigChanged)
        self.dlg.txtDirectory.textEdited.connect(self.txtDirectoryChanged)

    def txtDirectoryChanged(self, text):
        self.shapeDirectory = QDir(text)
        self.getShapeFiles()

    def setShapeDirectory(self):
        """Display folder browser dialog."""

        file = QFileDialog.getExistingDirectory(
            None, 'Select gps/shape file directory.')
        self.dlg.txtDirectory.setText(file)
        self.shapeDirectory = QDir(file)

    def cbxConfigChanged(self, id):
        """Reset config on configuration combox box changes."""

        self.pointsLayersConfig.clear()
        self.setCurrentConfig(self.dlg.cbxConfig.itemData(id))

    def getShapeFiles(self):
        """Get each shapefile in defined folder."""

        self.shapeFiles.clear()
        shapefiles = self.shapeDirectory.entryList(['*.shp'], QDir.Files,
                                                   QDir.Name)
        for file in shapefiles:
            # Populate the shape dictionnary
            self.shapeFiles[file.split('.', 1)[0]] = file
            # print self.shapeFiles.keys()

    def removeShapeFiles(self, shapeFiles):
        """Removes generated shapefiles"""

        for code in shapeFiles.keys():
            paths = str(self.shapeDirectory.absolutePath() + '/' + code + '.*')
            files = glob(paths)
            # print paths
            for file in files:
                os.remove(file)

    def getAsciiFiles(self):
        """Get each asciifile in defined folder."""

        #        self.asciiFiles.clear()
        asciifiles = self.shapeDirectory.entryList(['*.asc'], QDir.Files,
                                                   QDir.Name)
        for file in asciifiles:
            # Convert into shapefile
            self.ascii2shape(file)

    def ascii2shape(self, file):
        """Convert every input from the ascii file to the corresponding
        shapefile and creates it if it does not exists yet.
        :param file: ascii file to be converted"""

        # Read ascii
        with open(self.shapeDirectory.absolutePath() + '/' + file, 'r') as f:
            content = f.readlines()

        ind = 0

        # Set spatial ref and driver
        driver = ogr.GetDriverByName('ESRI Shapefile')
        srs = osr.SpatialReference()
        epsg21781wkt = 'PROJCS["CH1903 / LV03",GEOGCS["CH1903",DATUM["CH1903",SPHEROID["Bessel 1841",6377397.155,299.1528128,AUTHORITY["EPSG","7004"]],TOWGS84[674.374,15.056,405.346,0,0,0,0],AUTHORITY["EPSG","6149"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.01745329251994328,AUTHORITY["EPSG","9122"]],AUTHORITY["EPSG","4149"]],UNIT["metre",1,AUTHORITY["EPSG","9001"]],PROJECTION["Hotine_Oblique_Mercator"],PARAMETER["latitude_of_center",46.95240555555556],PARAMETER["longitude_of_center",7.439583333333333],PARAMETER["azimuth",90],PARAMETER["rectified_grid_angle",90],PARAMETER["scale_factor",1],PARAMETER["false_easting",600000],PARAMETER["false_northing",200000],AUTHORITY["EPSG","21781"],AXIS["Y",EAST],AXIS["X",NORTH]]'
        srs.ImportFromWkt(epsg21781wkt)

        # Start iteration on features
        for line in content:
            # Remove undesirables tabs and double spaces
            removedTabs = re.sub(r"\s+", " ", content[ind])

            # split fields values
            line_fields = removedTabs.split(' ')

            # Avoid uncompleted lines
            if (len(line_fields) > 4):

                # Create the dictionnary
                featureDict = [
                    'GPSID', 'TYPE', 'CODE', 'Y', 'X', 'Z', 'DELTA', 'COMMENT'
                ]

                # Extract the information
                featureDict[0] = str(line_fields[0])
                #    featureDict[0] = int(re.findall(r'\d+', line_fields[0])[0])
                featureDict[1] = str(
                    re.findall('[a-zA-Z]+', line_fields[0])[0])

                try:
                    featureDict[2] = int(line_fields[5])
                except ValueError:
                    featureDict[2] = 999

                featureDict[3] = str(line_fields[1])
                featureDict[4] = str(line_fields[2])
                featureDict[5] = str(line_fields[3])
                featureDict[6] = float(line_fields[4])
                featureDict[7] = ' '.join(line_fields[6:])

                ofilepath = self.shapeDirectory.absolutePath() + '/' + str(
                    featureDict[2]) + '.shp'

                if not os.path.exists(ofilepath):
                    dataSource = driver.CreateDataSource(ofilepath)
                    olayer = dataSource.CreateLayer("points",
                                                    srs,
                                                    geom_type=ogr.wkbPoint25D)
                    olayer.CreateField(ogr.FieldDefn("Point_ID",
                                                     ogr.OFTString))
                    olayer.CreateField(ogr.FieldDefn("Ortho_Heig",
                                                     ogr.OFTReal))
                else:
                    dataSource = driver.Open(ofilepath, 1)
                    olayer = dataSource.GetLayer()

                # print ofilepath

                # Set feature fields
                feature = ogr.Feature(olayer.GetLayerDefn())
                feature.SetField("Point_ID", featureDict[0])
                feature.SetField("Ortho_Heig", featureDict[5])

                # Set geometry
                geom_wkt = 'POINT (' + featureDict[3] + ' ' + featureDict[
                    4] + ' ' + featureDict[5] + ')'
                point = ogr.CreateGeometryFromWkt(geom_wkt)
                feature.SetGeometry(point)

                # Create feature
                olayer.CreateFeature(feature)

                # remove feature and datasource from memory
                feature.Destroy()
                dataSource.Destroy()

#            else:
#additional behaviour in case of uncompleted line

# increment
            ind += 1

    def setCurrentConfig(self, idConfig):
        """Load configuration from XML based on configuration id.
        :param idConfig: configuration id's stored in XML.
        :type text: str
        """

        # Get config node childrens if config id = idConfig
        root = self.configXML.documentElement()
        configs = root.elementsByTagName('config')
        for index in range(configs.count()):
            if configs.at(index).hasAttributes():
                nodeAttributes = configs.at(index).attributes()
                if nodeAttributes.namedItem('id').nodeValue() == idConfig:
                    self.currentConfigXML = configs.at(index)

        # Get all pointlayer nodes
        layerspoints = self.currentConfigXML.toElement().elementsByTagName(
            'pointlayer')

        # Populate import rules (pointsLayersConfig)
        for index in range(layerspoints.count()):
            if layerspoints.at(index).hasAttributes():
                self.pointsLayersConfig[layerspoints.at(
                    index).toElement().attributeNode(
                        'code').value()] = layerspoints.at(index).toElement()

    def loadConfig(self):
        """Load configuration combobox with configurations stored in XML configuration file."""

        XMLFile = QFile(self.plugin_dir + '/' + self.configFileName)
        if not XMLFile.open(QFile.ReadOnly | QFile.Text):
            QMessageBox.warning(
                self.iface.mainWindow(), "XML Configuration",
                "Cannot read file %s:\n%s." %
                (self.plugin_dir + '/' + self.configFileName,
                 XMLFile.errorString()), QMessageBox.Ok)
            return False
        ok, errorStr, errorLine, errorColumn = self.configXML.setContent(
            XMLFile, True)
        if not ok:
            QMessageBox.information(
                self.iface.mainWindow(), "XML Configuration",
                "Parse error at line %d, column %d:\n%s" %
                (errorLine, errorColumn, errorStr))
            return False

        root = self.configXML.documentElement()

        configs = root.elementsByTagName('config')

        for index in range(configs.count()):
            if configs.at(index).hasAttributes():
                nodeAttributes = configs.at(index).attributes()
                self.dlg.cbxConfig.addItem(
                    nodeAttributes.namedItem('name').nodeValue(),
                    nodeAttributes.namedItem('id').nodeValue())

        self.setCurrentConfig(
            self.dlg.cbxConfig.itemData(self.dlg.cbxConfig.currentIndex()))
        return True

    def runImport(self):
        self.getAsciiFiles()
        self.getShapeFiles()

        if len(self.shapeFiles) <= 0:
            QMessageBox.warning(self.iface.mainWindow(), "Shape import",
                                "No shape file found.")
            return

        #Shapefiles that match the config code
        codes = set(self.shapeFiles.keys()) & set(
            self.pointsLayersConfig.keys())

        # Maximum value of progress bar is the number of shapefile
        self.dlg.pgbImport.setMaximum(len(codes))

        # For each Shapefiles that match the config code
        for k in codes:
            # Import data based on config
            self.importData(
                self.shapeDirectory.absolutePath() + "/" + self.shapeFiles[k],
                k)
            # Increment progress bar
            self.dlg.pgbImport.setValue(self.dlg.pgbImport.value() + 1)

        self.removeShapeFiles(self.shapeFiles)

    def importData(self, filename, code):
        """Import data from shapefile to an specified layer in project.
        :param filename: shapefile filename.
        :type text: str
        :param code: shapefile name.
        :type text: str
        """

        driver = ogr.GetDriverByName('ESRI Shapefile')
        layers = QgsMapLayerRegistry.instance().mapLayers()
        destinationlayer = None
        colunmMappingDict = {}
        staticMappingDict = {}
        regexMappingDict = {}

        destinationLayerName = self.pointsLayersConfig[code].elementsByTagName(
            'destinationlayer').item(0).toElement().text()
        columnMappings = self.pointsLayersConfig[code].elementsByTagName(
            'columnmapping')
        staticMappings = self.pointsLayersConfig[code].elementsByTagName(
            'staticmapping')

        # No destination layer found in XML
        if destinationLayerName is None:
            return

        for k in layers.keys():
            if layers[k].name() == destinationLayerName:
                destinationlayer = layers[k]

        # No destination layer found in QGis Project
        if destinationlayer is None:
            return

        dataSource = driver.Open(filename, 0)

        if dataSource is None:
            self.dlg.txtOut.appendPlainText('Could not open %s \n' %
                                            (filename))
        else:
            self.dlg.txtOut.appendPlainText('Opened %s' % (filename))
            layer = dataSource.GetLayer()
            featureCount = layer.GetFeatureCount()

        # Get import rules with column mappings

        for index in range(columnMappings.count()):
            sourcecolumnname = columnMappings.at(index).toElement(
            ).elementsByTagName('source').item(0).toElement().text()
            destinationcolumnname = columnMappings.at(index).toElement(
            ).elementsByTagName('destination').item(0).toElement().text()
            regex = columnMappings.at(index).toElement().elementsByTagName(
                'regex')
            if not (regex is None):
                regexMappingDict[sourcecolumnname] = regex.item(
                    0).toElement().text()
            colunmMappingDict[sourcecolumnname] = destinationcolumnname

        # Get import rules with static value mappings

        for index in range(staticMappings.count()):
            staticValue = staticMappings.at(index).toElement(
            ).elementsByTagName('value').item(0).toElement().text()
            destinationcolumnname = staticMappings.at(index).toElement(
            ).elementsByTagName('destination').item(0).toElement().text()
            staticMappingDict[destinationcolumnname] = staticValue

        # Enable edit mode on destination layer
        destinationlayer.startEditing()

        # Retrieve all column off destination layer
        fields = destinationlayer.pendingFields()

        # For each data in shapefile
        for feature in layer:

            #Create new feature in destination layer and get geometry from shapefile
            newFeature = QgsFeature(fields)
            newFeature.setGeometry(
                QgsGeometry.fromWkt(str(feature.GetGeometryRef())))

            # For each column mapping
            for k in colunmMappingDict.keys():
                # print "source %s -> destination %s" % (k,colunmMappingDict[k])

                # With regex
                if regexMappingDict[k]:
                    regexp = re.compile(regexMappingDict[k])
                    # print str(k)
                    # print feature.GetField(str(k))

                    m = regexp.match(feature.GetField(str(k)))
                    if not (m is None):
                        # print 'Regex : %s   --> Value : %s' % (regexMappingDict[k], m.group('group'))
                        newFeature.setAttribute(
                            fields.fieldNameIndex(colunmMappingDict[k]),
                            m.group('group'))

                # Without regex
                else:
                    newFeature.setAttribute(
                        fields.fieldNameIndex(colunmMappingDict[k]),
                        feature.GetField(str(k)))

            # For each static value mapping
            for k in staticMappingDict.keys():
                #print "destination %s -> value %s" % (k,staticMappingDict[k])
                newFeature.setAttribute(fields.fieldNameIndex(k),
                                        staticMappingDict[k])

            # Add new feature in destination layer
            destinationlayer.addFeature(newFeature, True)

        self.dlg.txtOut.appendPlainText('Shape %s : %s features imported \n' %
                                        (code, featureCount))

    def unload(self):
        """Removes the plugin menu item and icon from QGIS GUI."""
        for action in self.actions:
            self.iface.removePluginMenu(self.tr(u'&EasyImport'), action)
            self.iface.removeToolBarIcon(action)

    def run(self):
        """Run method that performs all the real work"""
        # show the dialog
        self.dlg.show()
        # Run the dialog event loop
        result = self.dlg.exec_()

        # Reset progress bar value
        self.dlg.pgbImport.setValue(0)

        # Reset output text box
        self.dlg.txtOut.clear()

        # See if OK was pressed
        if result:
            # Do something useful here - delete the line containing pass and
            # substitute with your code.
            pass