Exemple #1
1
def save2PointShape(shapePath, geodata, attribName,
                    attribData, label, spatialRef):
    """
    :param label:
    :param shapePath: Pfad wo Shapefile agespeichert wird
    :param geodata: Koordinaten der Punkte
    :param attribName: Attributname (Feldname) von zusätzlichen Werten
    :param attribData: Werte für Attribute
    :param spatialRef: Räumliche Referenz
    """

    # define fields for feature attributes. A QgsFields object is needed
    fields = QgsFields()
    fields.append(QgsField("StuetzenNr", QVariant.String))
    fields.append(QgsField(attribName, QVariant.Int))
    writer = QgsVectorFileWriter(shapePath, "UTF8", fields, QgsWkbTypes.PointZ,
                                 spatialRef, "ESRI Shapefile")

    if writer.hasError() != QgsVectorFileWriter.NoError:
        # TODO
        raise Exception("Vector Writer")

    for idx, (coords, attrib) in enumerate(zip(geodata, attribData)):
        feature = QgsFeature()
        feature.setFields(fields)
        # TODO: Nicht 3D weil Methode fromPoint() nicht existiert. Wird evtl. in der Zukunft implementiert
        feature.setGeometry(QgsGeometry.fromPointXY(QgsPointXY(coords[0], coords[1])))
        feature.setId(idx)
        feature.setAttribute("StuetzenNr", label[idx])
        feature.setAttribute(attribName, attrib)
        writer.addFeature(feature)
        del feature

    # delete the writer to flush features to disk
    del writer
Exemple #2
0
 def extract_nodes( self ):
   vprovider = self.vlayer.dataProvider()
   writer = QgsVectorFileWriter( self.myName, self.myEncoding, vprovider.fields(),
                                 QGis.WKBPoint, vprovider.crs() )
   inFeat = QgsFeature()
   outFeat = QgsFeature()
   inGeom = QgsGeometry()
   outGeom = QgsGeometry()
   nFeat = vprovider.featureCount()
   nElement = 0
   self.emit( SIGNAL( "runStatus( PyQt_PyObject )" ), 0 )
   self.emit( SIGNAL( "runRange( PyQt_PyObject )" ), ( 0, nFeat ) )
   fit = vprovider.getFeatures()
   while fit.nextFeature( inFeat ):
     nElement += 1
     self.emit( SIGNAL( "runStatus( PyQt_PyObject )" ),  nElement )
     inGeom = inFeat.geometry()
     atMap = inFeat.attributes()
     pointList = ftools_utils.extractPoints( inGeom )
     outFeat.setAttributes( atMap )
     for i in pointList:
       outFeat.setGeometry( outGeom.fromPoint( i ) )
       writer.addFeature( outFeat )
   del writer
   return True
Exemple #3
0
  def polygons_to_lines( self ):
    vprovider = self.vlayer.dataProvider()
    writer = QgsVectorFileWriter( self.myName, self.myEncoding, vprovider.fields(),
                                  QGis.WKBLineString, vprovider.crs() )
    inFeat = QgsFeature()
    outFeat = QgsFeature()
    inGeom = QgsGeometry()
    outGeom = QgsGeometry()
    nFeat = vprovider.featureCount()
    nElement = 0
    self.emit( SIGNAL( "runStatus( PyQt_PyObject )" ), 0)
    self.emit( SIGNAL( "runRange( PyQt_PyObject )" ), ( 0, nFeat ) )

    fit = vprovider.getFeatures()
    while fit.nextFeature( inFeat ):
      nElement += 1
      self.emit( SIGNAL( "runStatus( PyQt_PyObject )" ),  nElement )
      inGeom = inFeat.geometry()
      atMap = inFeat.attributes()
      lineList = self.extractAsLine( inGeom )
      outFeat.setAttributes( atMap )
      for h in lineList:
        outFeat.setGeometry( outGeom.fromPolyline( h ) )
        writer.addFeature( outFeat )
    del writer
    return True
Exemple #4
0
  def lines_to_polygons( self ):
    vprovider = self.vlayer.dataProvider()
    writer = QgsVectorFileWriter( self.myName, self.myEncoding, vprovider.fields(),
                                  QGis.WKBPolygon, vprovider.crs() )
    inFeat = QgsFeature()
    outFeat = QgsFeature()
    nFeat = vprovider.featureCount()
    nElement = 0
    self.emit( SIGNAL( "runStatus( PyQt_PyObject )" ), 0)
    self.emit( SIGNAL( "runRange( PyQt_PyObject )" ), ( 0, nFeat ) )

    fit = vprovider.getFeatures()
    while fit.nextFeature( inFeat ):
      outGeomList = []
      nElement += 1
      self.emit( SIGNAL( "runStatus( PyQt_PyObject )" ),  nElement )
      if inFeat.geometry().isMultipart():
        outGeomList = inFeat.geometry().asMultiPolyline()
      else:
        outGeomList.append( inFeat.geometry().asPolyline() )
      polyGeom = self.remove_bad_lines( outGeomList )
      if len( polyGeom ) != 0:
        outFeat.setGeometry( QgsGeometry.fromPolygon( polyGeom ) )
        atMap = inFeat.attributes()
        outFeat.setAttributes( atMap )
        writer.addFeature( outFeat )
    del writer
    return True
Exemple #5
0
    def _create_grid(self, grid_name, grid_file, x_min, y_min, x_max, y_max, x_off, y_off):
        x_off2, y_off2 = x_off / 2.0, y_off / 2.0
        x_min = floor(x_min / x_off) * x_off
        x_max = ceil(x_max / x_off) * x_off
        y_min = floor(y_min / y_off) * y_off
        y_max = ceil(y_max / y_off) * y_off

        xtotal = int((x_max - x_min) / x_off) + 1
        ytotal = int((y_max - y_min) / y_off) + 1

        logAPICall.log(
            "x_min %f x_max %f y_min %f y_max %f x_off %f y_off %f xtotal %d, ytotal %d"
            % (x_min, x_max, y_min, y_max, x_off, y_off, xtotal, ytotal),
            logAPICall.DEBUG_L2,
        )
        fields = {0: QgsField("GRID_GID", QVariant.String)}
        writer = QgsVectorFileWriter(grid_file, "utf-8", fields, QGis.WKBPolygon, self._crs, "ESRI Shapefile")
        f = QgsFeature()
        for x in range(xtotal):
            for y in range(ytotal):
                lon = x_min + (x * x_off) + (x_off2)
                lat = y_min + (y * y_off) + (y_off2)
                # out_geom = QgsGeometry.fromRect(QgsRectangle(lon-x_off2, lat-y_off2,
                #                                             lon+x_off2, lat+y_off2))
                f.setGeometry(self._outputGeometryFromLatLon(lat, lon))
                f.addAttribute(0, QVariant(latlon_to_grid(lat, lon)))
                writer.addFeature(f)
        del writer
        return load_shapefile(grid_file, grid_name)
Exemple #6
0
    def do_operation(self):
        """ perform create mapping scheme operation """
        
        # input/output verification already performed during set input/ouput
        zone_layer = self.inputs[0].value
        zone_field = self.inputs[1].value                
        fp_layer = self.inputs[2].value
        
        # merge with zone to get assignment
        tmp_join = 'joined_%s' % get_unique_filename()
        tmp_join_file = '%s%s.shp' % (self._tmp_dir, tmp_join)        
        analyzer = QgsOverlayAnalyzer()        
        try:
            analyzer.intersection(fp_layer, zone_layer, tmp_join_file)
            tmp_join_layer = load_shapefile_verify(tmp_join_file, tmp_join,[zone_field])
        except AssertionError as err:
            raise OperatorError(str(err), self.__class__)
        except Exception as err:
            raise OperatorError(str(err), self.__class__)
        
        fields = {
            0 : QgsField(self._lon_field, QVariant.Double),
            1 : QgsField(self._lat_field, QVariant.Double),
            2 : QgsField(zone_field, QVariant.String),
        }
        zone_idx = layer_field_index(tmp_join_layer, zone_field)
        fp_layername = 'fpc_%s' % get_unique_filename()
        fp_file = '%s%s.shp' % (self._tmp_dir, fp_layername)
        try:
            writer = QgsVectorFileWriter(fp_file, "utf-8", fields, QGis.WKBPoint, self._crs, "ESRI Shapefile")
            f = QgsFeature()
            for _f in layer_features(tmp_join_layer):                
                centroid = _f.geometry().centroid().asPoint()
                lon = centroid.x()
                lat = centroid.y()
                zone_str = str(_f.attributeMap()[zone_idx].toString()).upper()

                f.setGeometry(QgsGeometry.fromPoint(QgsPoint(lon, lat)))
                f.addAttribute(0, QVariant(lon))
                f.addAttribute(1, QVariant(lat))
                f.addAttribute(2, QVariant(zone_str))
                writer.addFeature(f)
            
            del writer
        except Exception as err:
            logAPICall.log(err, logAPICall.ERROR)
            remove_shapefile(fp_file)
            raise OperatorError("error creating joined grid: %s" % err, self.__class__)
        
        # load shapefile as layer
        fp_layer = load_shapefile(fp_file, fp_layername)
        if not fp_layer:
            raise OperatorError('Error loading footprint centroid file' % (fp_file), self.__class__)        
                
        # clean up
        del tmp_join_layer        
        remove_shapefile(tmp_join_file)
        
        self.outputs[0].value = fp_layer
        self.outputs[1].value = fp_file
Exemple #7
0
 def _write_grid_shapefile(self, path, x_min, y_min, x_max, y_max, x_off, y_off):
     x_off = self._x_off        
     y_off = self._y_off        
     x_min = floor(x_min / x_off) * x_off
     x_max = ceil(x_max / x_off) * x_off
     y_min = floor(y_min / y_off) * y_off
     y_max = ceil(y_max / y_off) * y_off
     
     xtotal = int((x_max - x_min) / x_off)
     ytotal = int((y_max - y_min) / y_off)
     
     logAPICall.log('x_min %f x_max %f y_min %f y_max %f x_off %f y_off %f xtotal %d, ytotal %d'
                    % (x_min, x_max, y_min, y_max, x_off, y_off, xtotal, ytotal),
                    logAPICall.DEBUG_L2)
     
     writer = QgsVectorFileWriter(path, "utf-8", self._fields, QGis.WKBPoint, self._crs, "ESRI Shapefile")
     f = QgsFeature()
     for x in range(xtotal):
         for y in range(ytotal):
             lon = x_min + (x * x_off) + (x_off/2.0)
             lat = y_min + (y * y_off) + (y_off/2.0)
             f.setGeometry(QgsGeometry.fromPoint(QgsPoint(lon, lat)))
             f.addAttribute(0, QVariant(lon))
             f.addAttribute(1, QVariant(lat))
             writer.addFeature(f)
     del writer
Exemple #8
0
 def getOgrCompatibleSource(self, parameter_name, parameters, context, feedback):
     """
     Interprets a parameter as an OGR compatible source and layer name
     """
     input_layer = self.parameterAsVectorLayer(parameters, parameter_name, context)
     ogr_data_path = None
     ogr_layer_name = None
     if input_layer is None:
         # parameter is not a vector layer - try to convert to a source compatible with OGR
         # and extract selection if required
         ogr_data_path = self.parameterAsCompatibleSourceLayerPath(parameters, parameter_name, context,
                                                                   QgsVectorFileWriter.supportedFormatExtensions(),
                                                                   feedback=feedback)
         ogr_layer_name = GdalUtils.ogrLayerName(ogr_data_path)
     elif input_layer.dataProvider().name() == 'ogr':
         # parameter is a vector layer, with OGR data provider
         # so extract selection if required
         ogr_data_path = self.parameterAsCompatibleSourceLayerPath(parameters, parameter_name, context,
                                                                   QgsVectorFileWriter.supportedFormatExtensions(),
                                                                   feedback=feedback)
         ogr_layer_name = GdalUtils.ogrLayerName(input_layer.dataProvider().dataSourceUri())
     else:
         # vector layer, but not OGR - get OGR compatible path
         # TODO - handle "selected features only" mode!!
         ogr_data_path = GdalUtils.ogrConnectionString(input_layer.dataProvider().dataSourceUri(), context)[1:-1]
         ogr_layer_name = GdalUtils.ogrLayerName(input_layer.dataProvider().dataSourceUri())
     return ogr_data_path, ogr_layer_name
Exemple #9
0
    def processAlgorithm(self, progress):
        """Here is where the processing itself takes place."""

        # The first thing to do is retrieve the values of the parameters
        # entered by the user
        inputFilename = self.getParameterValue(self.INPUT_LAYER)
        output = self.getOutputValue(self.OUTPUT_LAYER)

        # Input layers vales are always a string with its location.
        # That string can be converted into a QGIS object (a
        # QgsVectorLayer in this case) using the
        # processing.getObjectFromUri() method.
        vectorLayer = dataobjects.getObjectFromUri(inputFilename)

        # And now we can process

        # First we create the output layer. The output value entered by
        # the user is a string containing a filename, so we can use it
        # directly
        settings = QSettings()
        systemEncoding = settings.value('/UI/encoding', 'System')
        writer = QgsVectorFileWriter(output,
                                     systemEncoding,
                                     vectorLayer.fields(),
                                     vectorLayer.wkbType(),
                                     vectorLayer.crs())

        # Now we take the features from input layer and add them to the
        # output. Method features() returns an iterator, considering the
        # selection that might exist in layer and the configuration that
        # indicates should algorithm use only selected features or all
        # of them
        features = vector.features(vectorLayer)
        for f in features:
            writer.addFeature(f)
Exemple #10
0
def to_shp(path, any_features_list, layer_fields, crs, name, encoding, geom_type):
    if path is None:
        if geom_type == 0:
            network = QgsVectorLayer('Point?crs=' + crs.toWkt(), name, "memory")
        else:
            network = QgsVectorLayer('LineString?crs=' + crs.toWkt(), name, "memory")
    else:
        fields = QgsFields()
        for field in layer_fields:
            fields.append(field)
        file_writer = QgsVectorFileWriter(path, encoding, fields, geom_type, crs, "ESRI Shapefile")
        if file_writer.hasError() != QgsVectorFileWriter.NoError:
            print "Error when creating shapefile: ", file_writer.errorMessage()
        del file_writer
        network = QgsVectorLayer(path, name, "ogr")
    pr = network.dataProvider()
    if path is None:
        pr.addAttributes(layer_fields)
    new_features = []
    for i in any_features_list:
        new_feat = QgsFeature()
        new_feat.setFeatureId(i[0])
        new_feat.setAttributes([attr[0] for attr in i[1]])
        new_feat.setGeometry(QgsGeometry(QgsGeometry.fromWkt(str(i[2]))))
        #QgsGeometry()
        new_features.append(new_feat)
    network.startEditing()
    pr.addFeatures(new_features)
    network.commitChanges()
    return network
    def testOgrDriverList(self):
        # test with drivers in recommended order
        drivers = QgsVectorFileWriter.ogrDriverList(QgsVectorFileWriter.SortRecommended)
        self.assertEqual(drivers[0].longName, 'GeoPackage')
        self.assertEqual(drivers[0].driverName, 'GPKG')
        self.assertEqual(drivers[1].longName, 'ESRI Shapefile')
        self.assertEqual(drivers[1].driverName, 'ESRI Shapefile')
        self.assertTrue('ODS' in [f.driverName for f in drivers])

        # ensure that XLSX comes before SQLite, because we should sort on longName, not driverName!
        ms_xlsx_index = next(i for i, v in enumerate(drivers) if v.driverName == 'XLSX')
        sqlite_index = next(i for i, v in enumerate(drivers) if v.driverName == 'SQLite')
        self.assertLess(ms_xlsx_index, sqlite_index)

        self.assertIn('[XLSX]', drivers[ms_xlsx_index].longName)

        # alphabetical sorting
        drivers2 = QgsVectorFileWriter.ogrDriverList(QgsVectorFileWriter.VectorFormatOptions())
        self.assertTrue(drivers2[0].longName < drivers2[1].longName)
        self.assertCountEqual([d.driverName for d in drivers], [d.driverName for d in drivers2])
        self.assertNotEqual(drivers2[0].driverName, 'GPKG')

        # skip non-spatial
        formats = QgsVectorFileWriter.ogrDriverList(QgsVectorFileWriter.SkipNonSpatialFormats)
        self.assertFalse('ODS' in [f.driverName for f in formats])
 def export_filter_layer(self, ext='xlsx'):
     '''
     export a filter-layer (opens user-input) to excel or kml
     '''
     try:
         res = self.get_filterlayer()
     except:
         traceback.print_exc()
         return
     if not res:
         return
     category, layer = res
     
     file_filter = EXCEL_FILTER if ext == 'xlsx' else KML_FILTER
     filepath = browse_file(None, 'Export', file_filter, save=True, 
                            parent=self)
     if not filepath:
         return
     driver = 'XLSX' if ext == 'xlsx'else 'KML'
     #fields = []
     #for i, f in enumerate(layer.fields()):
         #if layer.editorWidgetV2(i) == 'Hidden':
             #continue
         #fields.append(f.name())
     try:
         QgsVectorFileWriter.writeAsVectorFormat(
             layer, filepath, "utf-8", None, driver, False)
             #attributes=fields)
         title = 'Speicherung erfolgreich'
         msg = 'Die Daten wurden erfolgreich exportiert.'
     except Exception as e:
         title = 'Fehler'
         msg = 'Fehler bei der Speicherung: \n {}'.format(str(e))
     QtGui.QMessageBox.information(
         self, title, msg)
Exemple #13
0
    def _add_tabular_layer(self, tabular_layer, layer_name, save_style=False):
        """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

        :param save_style: If we have to save a QML too. Default to False.
        :type save_style: bool

        :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',
            QgsCoordinateTransform(),
            'CSV')

        if save_style:
            style_path = QFileInfo(self.uri.filePath(layer_name + '.qml'))
            tabular_layer.saveNamedStyle(style_path.absoluteFilePath())

        assert output.exists()
        return True, output.baseName()
def convert_geojson_to_shapefile(geojson_path):
    """Convert geojson file to shapefile.

    It will create a necessary file next to the geojson file. It will not
    affect another files (e.g. .xml, .qml, etc).

    :param geojson_path: The path to geojson file.
    :type geojson_path: basestring

    :returns: True if shapefile layer created, False otherwise.
    :rtype: bool
    """
    layer = QgsVectorLayer(geojson_path, 'vector layer', 'ogr')
    if not layer.isValid():
        return False
    # Construct shapefile path
    shapefile_path = os.path.splitext(geojson_path)[0] + '.shp'
    QgsVectorFileWriter.writeAsVectorFormat(
        layer,
        shapefile_path,
        'utf-8',
        layer.crs(),
        'ESRI Shapefile')
    if os.path.exists(shapefile_path):
        return True
    return False
Exemple #15
0
 def multi_to_single( self ):
   vprovider = self.vlayer.dataProvider()
   geomType = self.multiToSingleGeom( vprovider.geometryType() )
   writer = QgsVectorFileWriter( self.myName, self.myEncoding, vprovider.fields(),
                                 geomType, vprovider.crs() )
   inFeat = QgsFeature()
   outFeat = QgsFeature()
   inGeom = QgsGeometry()
   nFeat = vprovider.featureCount()
   nElement = 0
   self.emit( SIGNAL( "runStatus( PyQt_PyObject )" ), 0 )
   self.emit( SIGNAL( "runRange( PyQt_PyObject )" ), ( 0, nFeat ) )
   fit = vprovider.getFeatures()
   while fit.nextFeature( inFeat ):
     nElement += 1
     self.emit( SIGNAL( "runStatus( PyQt_PyObject )" ), nElement )
     inGeom = inFeat.geometry()
     atMap = inFeat.attributes()
     featList = self.extractAsSingle( inGeom )
     outFeat.setAttributes( atMap )
     for i in featList:
       outFeat.setGeometry( i )
       writer.addFeature( outFeat )
   del writer
   return True
Exemple #16
0
    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()
Exemple #17
0
def exportVector(layer, sln, layersFolder, restrictToExtent, iface,
                 extent, precision, crs, minify):
    canvas = iface.mapCanvas()
    cleanLayer = writeTmpLayer(layer, restrictToExtent, iface, extent)
    if is25d(layer, canvas, restrictToExtent, extent):
        add25dAttributes(cleanLayer, layer, canvas)
    tmpPath = os.path.join(layersFolder, sln + ".json")
    path = os.path.join(layersFolder, sln + ".js")
    options = []
    if precision != "maintain":
        options.append("COORDINATE_PRECISION=" + unicode(precision))
    QgsVectorFileWriter.writeAsVectorFormat(cleanLayer, tmpPath, "utf-8", crs,
                                            'GeoJson', 0,
                                            layerOptions=options)
    with open(path, mode="w", encoding="utf8") as f:
        f.write("var %s = " % ("json_" + sln))
        with open(tmpPath, encoding="utf8") as tmpFile:
            for line in tmpFile:
                if minify:
                    line = line.strip("\n\t ")
                    line = removeSpaces(line)
                f.write(line)
    os.remove(tmpPath)
    fields = layer.fields()
    for field in fields:
        exportImages(layer, field.name(), layersFolder + "/tmp.tmp")
Exemple #18
0
def writeVectorLayerToShape(vlayer, outputPath, encoding):
    mCodec = QTextCodec.codecForName(encoding)
    if not mCodec:
        return False
    #Here we should check that the output path is valid
    QgsVectorFileWriter.writeAsVectorFormat(vlayer, outputPath, encoding, vlayer.dataProvider().crs(), "ESRI Shapefile", False)
    return True
Exemple #19
0
def TussenTelling(selectie_gebouwen, outputTable, outputFeatures):
    if outputTable:
        statistics_fields = ["AZ_T","PZ_T","PVT_T","WZC_T","SOM_T"]
        MaakOverzichtstabel(selectie_gebouwen, statistics_fields, outputTable)
    if outputFeatures:
        flType = findOGRtype(outputFeatures)
        QgsVectorFileWriter.writeAsVectorFormat(selectie_gebouwen , outputFeatures, "utf-8", None, flType )
    def run(self):
        tempLayer = self.createGridLayer('temp', 'Multipolygon', self.crs.geographicCRSAuthId())

        self.populateQgsLayer(self.index, self.stopScale, tempLayer, self.mi)
        
        useMemory = True
        if not self.layer:
            useMemory = False
            self.layer = self.createGridLayer('Grid Zones', 'Multipolygon', self.crs.authid())
        
        for feature in tempLayer.getFeatures():
            if self.stopped:
                del tempLayer
                tempLayer = None
                self.aux.userCanceled.emit()
                return

            geom = feature.geometry()
            reprojected = self.reprojectGridZone(geom)
            self.insertGridZoneIntoQgsLayer(self.layer, reprojected, feature.attributes())
            self.aux.stepProcessed.emit()

        del tempLayer
        tempLayer = None
        
        self.aux.stepProcessed.emit()

        if not useMemory:
            QgsVectorFileWriter.writeAsVectorFormat(self.layer, self.output, "utf-8", None, "ESRI Shapefile")

        self.aux.processFinished.emit()
Exemple #21
0
def getFileFilter(param):
    """
    Returns a suitable file filter pattern for the specified parameter definition
    :param param:
    :return:
    """
    if param.type() == 'multilayer':
        if param.layerType() == QgsProcessingParameterDefinition.TypeRaster:
            exts = dataobjects.getSupportedOutputRasterLayerExtensions()
        elif param.layerType() == QgsProcessingParameterDefinition.TypeFile:
            return tr('All files (*.*)', 'QgsProcessingParameterMultipleLayers')
        else:
            exts = QgsVectorFileWriter.supportedFormatExtensions()
        for i in range(len(exts)):
            exts[i] = tr('{0} files (*.{1})', 'QgsProcessingParameterMultipleLayers').format(exts[i].upper(), exts[i].lower())
        return ';;'.join(exts)
    elif param.type() in ('raster', 'rasterOut'):
        exts = dataobjects.getSupportedOutputRasterLayerExtensions()
        for i in range(len(exts)):
            exts[i] = tr('{0} files (*.{1})', 'QgsProcessingParameterRasterOutput').format(exts[i].upper(), exts[i].lower())
        return ';;'.join(exts)
    elif param.type() == 'table':
        exts = ['csv', 'dbf']
        for i in range(len(exts)):
            exts[i] = tr('{0} files (*.{1})', 'ParameterTable').format(exts[i].upper(), exts[i].lower())
        return ';;'.join(exts)
    elif param.type() == 'sink':
        exts = QgsVectorFileWriter.supportedFormatExtensions()
        for i in range(len(exts)):
            exts[i] = tr('{0} files (*.{1})', 'ParameterVector').format(exts[i].upper(), exts[i].lower())
        return ';;'.join(exts)
    return ''
Exemple #22
0
class VectorWriter:

    MEMORY_LAYER_PREFIX = 'memory:'

    def __init__(self, fileName, encoding, fields, geometryType,
                 crs, options=None):
        self.fileName = fileName
        self.isMemory = False
        self.memLayer = None
        self.writer = None

        if encoding is None:
            settings = QSettings()
            encoding = settings.value('/Processing/encoding', 'System', type=str)

        if self.fileName.startswith(self.MEMORY_LAYER_PREFIX):
            self.isMemory = True

            uri = GEOM_TYPE_MAP[geometryType] + "?uuid=" + unicode(uuid.uuid4())
            if crs.isValid():
                uri += '&crs=' + crs.authid()
            fieldsdesc = []
            for f in fields:
                qgsfield = _toQgsField(f)
                fieldsdesc.append('field=%s:%s' %(qgsfield.name(),
                                TYPE_MAP_MEMORY_LAYER.get(qgsfield.type(), "string")))
            if fieldsdesc:
                uri += '&' + '&'.join(fieldsdesc)

            self.memLayer = QgsVectorLayer(uri, self.fileName, 'memory')
            self.writer = self.memLayer.dataProvider()
        else:
            formats = QgsVectorFileWriter.supportedFiltersAndFormats()
            OGRCodes = {}
            for (key, value) in formats.items():
                extension = unicode(key)
                extension = extension[extension.find('*.') + 2:]
                extension = extension[:extension.find(' ')]
                OGRCodes[extension] = value

            extension = self.fileName[self.fileName.rfind('.') + 1:]
            if extension not in OGRCodes:
                extension = 'shp'
                self.filename = self.filename + 'shp'

            qgsfields = QgsFields()
            for field in fields:
                qgsfields.append(_toQgsField(field))

            self.writer = QgsVectorFileWriter(
                self.fileName, encoding,
                qgsfields, geometryType, crs, OGRCodes[extension])

    def addFeature(self, feature):
        if self.isMemory:
            self.writer.addFeatures([feature])
        else:
            self.writer.addFeature(feature)
Exemple #23
0
    def run(self):
        self.mutex.lock()
        self.stopMe = 0
        self.mutex.unlock()

        interrupted = False

        outPath = self.outDir

        if outPath.find("\\") != -1:
            outPath.replace("\\", "/")

        if not outPath.endswith("/"):
            outPath = outPath + "/"

        provider = self.layer.dataProvider()
        index = provider.fieldNameIndex(self.field)
        unique = ftools_utils.getUniqueValues(provider, int(index))
        baseName = unicode( outPath + self.layer.name() + "_" + self.field + "_" )

        fieldList = ftools_utils.getFieldList(self.layer)
        sRs = provider.crs()
        geom = self.layer.wkbType()
        inFeat = QgsFeature()

        self.emit(SIGNAL("rangeCalculated(PyQt_PyObject)"), len(unique))


        for i in unique:
            check = QFile(baseName + "_" + unicode(i).strip() + ".shp")
            fName = check.fileName()
            if check.exists():
                if not QgsVectorFileWriter.deleteShapeFile(fName):
                    self.errors.append( fName )
                    continue

            writer = QgsVectorFileWriter(fName, self.encoding, fieldList, geom, sRs)

            fit = provider.getFeatures()
            while fit.nextFeature(inFeat):
                atMap = inFeat.attributes()
                if atMap[index] == i:
                    writer.addFeature(inFeat)
            del writer

            self.emit(SIGNAL("valueProcessed()"))

            self.mutex.lock()
            s = self.stopMe
            self.mutex.unlock()
            if s == 1:
                interrupted = True
                break

        if not interrupted:
            self.emit(SIGNAL("processFinished( PyQt_PyObject )"), self.errors)
        else:
            self.emit(SIGNAL("processInterrupted()"))
Exemple #24
0
    def on_file_browse(self):
        settings = QSettings()

        # look for directory
        path = QgsProject.instance().homePath()
        if path == '':
            path = settings.value("mask/file_dir", '')
            if path == '':
                path = QDir.homePath()

        drivers = QgsVectorFileWriter.ogrDriverList()
        filterList = []
        filterMap = {}
        for ln, n in drivers.items():
            # grrr, driverMetadata is not really consistent
            if n == "ESRI Shapefile":
                ext = "shp"
                glob = "*.shp"
            else:
                md = QgsVectorFileWriter.MetaData()
                if QgsVectorFileWriter.driverMetadata(n, md):
                    ext = md.ext
                    glob = md.glob
                else:
                    continue

            fn = "%s (%s)" % (ln, glob)
            filterMap[fn] = (n, ext, glob)
            filterList += [fn]

        fileFilters = ';;'.join(filterList)
        fd = QFileDialog(None, self.tr("Select a filename to save the mask layer to"),
                         path, fileFilters)
        save_format_name = self.parameters.file_format
        self.save_format = None
        for k, v in filterMap.items():
            if v[0] == save_format_name:
                self.save_format = v
                fd.selectNameFilter(k)
                break

        def on_filter_selected(ff):
            self.save_format = filterMap[ff]

        fd.filterSelected.connect(on_filter_selected)
        fd.setAcceptMode(QFileDialog.AcceptSave)
        r = fd.exec_()
        if r == 1:
            fn = fd.selectedFiles()[0]
            driver, ext, glob = self.save_format
            if not fn.endswith("." + ext):
                fn += "." + ext

            self.ui.filePath.setText(fn)
            self.ui.formatLbl.setText(self.save_format[0])
            self.parameters.file_format = self.save_format[0]
            self.parameters.file_path = fn
Exemple #25
0
def createShapefile(filePath, name, wkbType, crs, fields, styleURI=None, symbology=None):
    # WARNING This will overwrite existing files
    writer = QgsVectorFileWriter(filePath, 'System', fields, wkbType, crs)
    if writer.hasError():
        utils.debug(writer.errorMessage())
    del writer
    layer = QgsVectorLayer(filePath, name, 'ogr')
    loadStyle(layer, styleURI, symbology)
    return layer
Exemple #26
0
 def test03_SaveAsCSV(self):
   """Save layer to a CSV file"""
   self._testAvailable() or self.skipTest("Not available")
   layer = self._testLayer(self.fileName)
   outfile = self.testDataPath(u"{}.csv".format(self.layerName), output=True)
   QgsVectorFileWriter.writeAsVectorFormat(layer, outfile, "UTF-8", layer.crs(),
                                           "CSV", layerOptions=["LINEFORMAT=LF", "GEOMETRY=AS_XY"])
   expfile = unitTestDataPath("{}.csv".format(TC01_Attribute.layerName), own=True)
   assert compareFile(outfile, expfile, delimiter=",") == 0, "unexpected csv output"
Exemple #27
0
 def randomize(self, inLayer, outPath, minimum, design, value):
     outFeat = QgsFeature()
     outFeat.initAttributes(1)
     if design == self.tr("unstratified"):
         ext = inLayer.extent()
         if inLayer.type() == QgsMapLayer.RasterLayer:
             points = self.simpleRandom(
                 int(value), ext, ext.xMinimum(),
                 ext.xMaximum(), ext.yMinimum(), ext.yMaximum())
         else:
             points = self.vectorRandom(
                 int(value), inLayer,
                 ext.xMinimum(), ext.xMaximum(), ext.yMinimum(), ext.yMaximum())
     else:
         points, featErrors = self.loopThruPolygons(inLayer, value, design)
         if featErrors:
             if len(featErrors) >= 10:
                 err_msg = "Too many features couldn't be calculated due to conversion error. "
                 err_msg += "Please check out message log for more info."
                 msgLogInstance = QgsMessageLog.instance()
                 msgLogInstance.logMessage("WARNING - fTools: " + self.tr("Random Points"))
                 msgLogInstance.logMessage("The following feature ids should be checked.")
                 for feat in featErrors:
                     msgLogInstance.logMessage("Feature id: %d" % feat.id())
                 msgLogInstance.logMessage("End of features to be checked.")
             else:
                 features_ids = []
                 for feat in featErrors:
                     features_ids.append(unicode(feat.id()))
                 erroneous_ids = ', '.join(features_ids)
                 err_msg = "The following features IDs couldn't be calculated due to conversion error: %s" % erroneous_ids
             self.iface.messageBar().pushMessage("Errors", err_msg)
     if len(points):
         crs = self.iface.mapCanvas().mapRenderer().destinationCrs()
         if not crs.isValid():
             crs = None
         fields = QgsFields()
         fields.append(QgsField("ID", QVariant.Int))
         outFeat.setFields(fields)
         check = QFile(self.shapefileName)
         if check.exists():
             if not QgsVectorFileWriter.deleteShapeFile(self.shapefileName):
                 return
         writer = QgsVectorFileWriter(self.shapefileName, self.encoding, fields, QGis.WKBPoint, crs)
         idVar = 0
         count = 70.00
         add = (100.00 - 70.00) / len(points)
         for i in points:
             outFeat.setGeometry(i)
             outFeat.setAttribute(0, idVar)
             writer.addFeature(outFeat)
             idVar = idVar + 1
             count = count + add
             self.progressBar.setValue(count)
         del writer
         return True
     return False
    def testDefaultLayerOptions(self):
        """ Test retrieving default layer options for a format """

        # NOTE - feel free to adapt these if the defaults change!
        options = QgsVectorFileWriter.defaultLayerOptions('not a format')
        self.assertEqual(options, [])
        options = QgsVectorFileWriter.defaultLayerOptions('ESRI Shapefile')
        self.assertEqual(options, ['RESIZE=NO'])
        options = QgsVectorFileWriter.defaultLayerOptions('GML')
        self.assertEqual(options, [])
    def testGeoPackage(self):
        '''Test GeoPackage'''
        layer = QgsVectorLayer(os.path.join(os.path.dirname(__file__), "data","airports.gpkg"),
                                    "test", "ogr")

        self.assertTrue(layer.isValid())
        filepath = os.path.join(tempfile.mkdtemp(), str(time.time()) + ".gpkg")
        QgsVectorFileWriter.writeAsVectorFormat(layer, filepath, 'utf-8', layer.crs(), 'GPKG')
        layer = QgsVectorLayer(filepath, "test", "ogr")
        self.assertTrue(layer.isValid())
def conversion(input_name,output_name,input_json,output_json):
    vlayer = QgsVectorLayer(input_name,'shp','ogr')
    error=QW.writeAsVectorFormat(vlayer, input_json,'utf-8',None,'GeoJSON')
    if error == QW.NoError:
        print "succeed in json conversion"
        convert(input_json+'.geojson',output_json+'.geojson')
        jlayer = QgsVectorLayer(output_json+'.geojson','json','ogr')
        err_shp = QW.writeAsVectorFormat(jlayer, output_name, "utf-8", None, "ESRI Shapefile")
        if error == QW.NoError:
            print "succeed in shp conversion"
Exemple #31
0
    def getOgrCompatibleSource(self, parameter_name, parameters, context,
                               feedback, executing):
        """
        Interprets a parameter as an OGR compatible source and layer name
        :param executing:
        """
        if not executing and parameter_name in parameters and isinstance(
                parameters[parameter_name],
                QgsProcessingFeatureSourceDefinition):
            # if not executing, then we throw away all 'selected features only' settings
            # since these have no meaning for command line gdal use, and we don't want to force
            # an export of selected features only to a temporary file just to show the command!
            parameters = {parameter_name: parameters[parameter_name].source}

        input_layer = self.parameterAsVectorLayer(parameters, parameter_name,
                                                  context)
        ogr_data_path = None
        ogr_layer_name = None
        if input_layer is None or input_layer.dataProvider().name(
        ) == 'memory':
            if executing:
                # parameter is not a vector layer - try to convert to a source compatible with OGR
                # and extract selection if required
                ogr_data_path = self.parameterAsCompatibleSourceLayerPath(
                    parameters,
                    parameter_name,
                    context,
                    QgsVectorFileWriter.supportedFormatExtensions(),
                    feedback=feedback)
                ogr_layer_name = GdalUtils.ogrLayerName(ogr_data_path)
            else:
                #not executing - don't waste time converting incompatible sources, just return dummy strings
                #for the command preview (since the source isn't compatible with OGR, it has no meaning anyway and can't
                #be run directly in the command line)
                ogr_data_path = 'path_to_data_file'
                ogr_layer_name = 'layer_name'
        elif input_layer.dataProvider().name() == 'ogr':
            if executing and isinstance(
                    parameters[parameter_name],
                    QgsProcessingFeatureSourceDefinition
            ) and parameters[parameter_name].selectedFeaturesOnly:
                # parameter is a vector layer, with OGR data provider
                # so extract selection if required
                ogr_data_path = self.parameterAsCompatibleSourceLayerPath(
                    parameters,
                    parameter_name,
                    context,
                    QgsVectorFileWriter.supportedFormatExtensions(),
                    feedback=feedback)
                parts = QgsProviderRegistry.instance().decodeUri(
                    'ogr', ogr_data_path)
                ogr_data_path = parts['path']
                if 'layerName' in parts and parts['layerName']:
                    ogr_layer_name = parts['layerName']
                else:
                    ogr_layer_name = GdalUtils.ogrLayerName(ogr_data_path)
            else:
                #either not using the selection, or
                #not executing - don't worry about 'selected features only' handling. It has no meaning
                #for the command line preview since it has no meaning outside of a QGIS session!
                ogr_data_path = GdalUtils.ogrConnectionStringAndFormatFromLayer(
                    input_layer)[0]
                ogr_layer_name = GdalUtils.ogrLayerName(
                    input_layer.dataProvider().dataSourceUri())
        else:
            # vector layer, but not OGR - get OGR compatible path
            # TODO - handle "selected features only" mode!!
            ogr_data_path = GdalUtils.ogrConnectionStringFromLayer(input_layer)
            ogr_layer_name = GdalUtils.ogrLayerName(
                input_layer.dataProvider().dataSourceUri())
        return ogr_data_path, ogr_layer_name
Exemple #32
0
def create_preview_group(
    group_name: str,
    images: List[dict],
    footprints_filename=None,
    catalog_layer_name=None,
    tile_service: str = "xyz",
    search_query: str = None,
    sort_order: Tuple[str, str] = None,
) -> None:

    if tile_service.lower() not in ["wmts", "xyz"]:
        log.debug("Incorrect tile service passed for preview group: "
                  f"{tile_service} (must be wmts or xyz)")
        return

    item_ids = [f"{img['properties'][ITEM_TYPE]}:{img[ID]}" for img in images]
    uri = tile_service_data_src_uri(item_ids, service=tile_service)

    if uri:
        log.debug(f"Tile datasource URI:\n{uri}")

        rlayer = QgsRasterLayer(uri, "Image previews", "wms")
        rlayer.setCustomProperty(PLANET_PREVIEW_ITEM_IDS, json.dumps(item_ids))

        if tile_service == "xyz" and catalog_layer_name is not None:
            url = uri.split("url=")[-1]
            s = QSettings()
            s.setValue(f"qgis/connections-xyz/{catalog_layer_name}/username",
                       "")
            s.setValue(f"qgis/connections-xyz/{catalog_layer_name}/password",
                       "")
            s.setValue(f"qgis/connections-xyz/{catalog_layer_name}/authcfg",
                       "")
            s.setValue(
                f"qgis/connections-xyz/{catalog_layer_name}/url",
                url.replace(PlanetClient.getInstance().api_key(), ""),
            )
    else:
        log.debug("No tile URI for preview group")
        return

    vlayer = None
    if images:
        vlayer = create_preview_vector_layer(images[0])

        vlayer.startEditing()
        dp = vlayer.dataProvider()
        fields: List[QgsField] = vlayer.fields()

        for img in images:
            feat = QgsFeature()
            feat.setFields(fields)
            qgs_geom = qgsgeometry_from_geojson(img["geometry"])
            feat.setGeometry(qgs_geom)

            f_names = [f.name() for f in fields]

            if "item_id" in f_names:
                feat["item_id"] = img[ID]

            if search_query and "search_query" in f_names:
                feat["search_query"] = json.dumps(search_query)
            if sort_order and "sort_order" in f_names and len(sort_order) > 1:
                feat["sort_order"] = " ".join(sort_order)

            props: dict = img["properties"]
            for k, v in props.items():
                if k in f_names:
                    feat[k] = v

            dp.addFeature(feat)

        vlayer.commitChanges()

        if footprints_filename:
            QgsVectorFileWriter.writeAsVectorFormat(vlayer,
                                                    footprints_filename,
                                                    "UTF-8")
            gpkglayer = QgsVectorLayer(footprints_filename, "Footprints")
            gpkglayer.setRenderer(vlayer.renderer().clone())
            vlayer = gpkglayer
        QgsProject.instance().addMapLayer(vlayer, False)

    # noinspection PyArgumentList
    QgsProject.instance().addMapLayer(rlayer, False)

    # noinspection PyArgumentList
    root: QgsLayerTree = QgsProject.instance().layerTreeRoot()
    group = root.insertGroup(0, f"{group_name} {tile_service.upper()} preview")
    if vlayer:
        group.addLayer(vlayer)
    group.addLayer(rlayer)
    if vlayer:
        iface.setActiveLayer(vlayer)
    def runAndCreateLayer(parent):
        geomDialog = QgsNewVectorLayerDialog(parent)
        if (geomDialog.exec_() == QDialog.Rejected):
            return ""

        geometrytype = geomDialog.selectedType()
        fileformat = geomDialog.selectedFileFormat()
        enc = geomDialog.selectedFileEncoding()
        crsId = geomDialog.selectedCrsId()
        print(QString("New file format will be: %1").arg(fileformat))

        attributes = dict()
        geomDialog.attributes(attributes)

        settings = QSettings()
        lastUsedDir = settings.value("/UI/lastVectorFileFilterDir",
                                     QDir.homePath()).toString()
        filterString = QgsVectorFileWriter.filterForDriver(fileformat)
        fileName = QFileDialog.getSaveFileName(parent, "Save layer as...",
                                               lastUsedDir, filterString)
        if (fileName.isNull()):
            return ""

        if (fileformat == "ESRI Shapefile"
                and not fileName.endsWith(".shp", Qt.CaseInsensitive)):
            fileName += ".shp"

        settings.setValue("/UI/lastVectorFileFilterDir",
                          QFileInfo(fileName).absolutePath())
        settings.setValue("/UI/encoding", enc)

        #try to create the new layer with OGRProvider instead of QgsVectorFileWriter
        pReg = QgsProviderRegistry.instance()
        ogrlib = pReg.library("ogr")
        # load the data provider
        myLib = QLibrary(ogrlib)
        loaded = myLib.load()

        constructionLineLayer = None
        mapUnits = define._canvas.mapUnits()
        layerName = String.QString2Str(fileName).split("\\")[-1]
        path = "memory"
        selectedCrs = geomDialog.selectedCrs()
        if geometrytype == QGis.Line:
            # if mapUnits == QGis.Meters:
            constructionLineLayer = QgsVectorLayer(
                "linestring?crs=%s" % selectedCrs.authid(), layerName, path)
            # else:
            #     constructionLineLayer = QgsVectorLayer("linestring?crs=%s"%define._latLonCrs.authid (), layerName, path)

        elif geometrytype == QGis.Polygon:
            # if mapUnits == QGis.Meters:
            constructionLineLayer = QgsVectorLayer(
                "polygon?crs=%s" % selectedCrs.authid(), layerName, path)
            # else:
            #     constructionLineLayer = QgsVectorLayer("polygon?crs=%s"%define._latLonCrs.authid (), layerName, path)

        elif geometrytype == QGis.Point:
            # if mapUnits == QGis.Meters:
            constructionLineLayer = QgsVectorLayer(
                "Point?crs=%s" % selectedCrs.authid(), layerName, path)
            # else:
            #     constructionLineLayer = QgsVectorLayer("Point?crs=%s"%define._latLonCrs.authid (), layerName, path)
        fieldList = []
        for key in attributes.iterkeys():
            fieldList.append(QgsField(key, attributes[key][0]))
        constructionLineLayer.startEditing()
        constructionLineLayer.dataProvider().addAttributes(fieldList)
        constructionLineLayer.commitChanges()

        er = QgsVectorFileWriter.writeAsVectorFormat(
            constructionLineLayer, fileName, "utf-8",
            constructionLineLayer.crs())
        constructionLineLayer = QgsVectorLayer(fileName, layerName, "ogr")

        QgisHelper.appendToCanvas(define._canvas, [constructionLineLayer],
                                  "NewLayers")

        # if ( loaded ):
        #     print( "ogr provider loaded" )
        #
        #     typedef bool ( *createEmptyDataSourceProc )( const QString&, const QString&, const QString&, QGis::WkbType,
        #     const QList< QPair<QString, QString> >&, const QgsCoordinateReferenceSystem * )
        #     createEmptyDataSourceProc createEmptyDataSource = ( createEmptyDataSourceProc ) cast_to_fptr( myLib.resolve( "createEmptyDataSource" ) )
        #     if ( createEmptyDataSource )
        #     {
        #         if ( geometrytype not = QGis::WKBUnknown )
        #         {
        #             QgsCoordinateReferenceSystem srs = QgsCRSCache::instance().crsBySrsId( crsId )
        #             if ( not createEmptyDataSource( fileName, fileformat, enc, geometrytype, attributes, &srs ) )
        #             {
        #                 return QString::null
        #             }
        #         }
        #         else
        #         {
        #             QgsDebugMsg( "geometry type not recognised" )
        #             return QString::null
        #         }
        #     }
        #     else
        #     {
        #         QgsDebugMsg( "Resolving newEmptyDataSource(...) failed" )
        #         return QString::null
        #     }
        # }
        #
        # if ( pEnc )
        # *pEnc = enc

        return fileName
Exemple #34
0
    def ogrConnectionStringAndFormat(uri, context):
        """Generates OGR connection string and format string from layer source
        Returned values are a tuple of the connection string and format string
        """
        ogrstr = None
        format = None

        layer = QgsProcessingUtils.mapLayerFromString(uri, context, False)
        if layer is None:
            path, ext = os.path.splitext(uri)
            format = QgsVectorFileWriter.driverForExtension(ext)
            return '"' + uri + '"', '"' + format + '"'

        provider = layer.dataProvider().name()
        if provider == 'spatialite':
            # dbname='/geodata/osm_ch.sqlite' table="places" (Geometry) sql=
            regex = re.compile("dbname='(.+)'")
            r = regex.search(str(layer.source()))
            ogrstr = r.groups()[0]
            format = 'SQLite'
        elif provider == 'postgres':
            # dbname='ktryjh_iuuqef' host=spacialdb.com port=9999
            # user='******' password='******' sslmode=disable
            # key='gid' estimatedmetadata=true srid=4326 type=MULTIPOLYGON
            # table="t4" (geom) sql=
            dsUri = QgsDataSourceUri(layer.dataProvider().dataSourceUri())
            conninfo = dsUri.connectionInfo()
            conn = None
            ok = False
            while not conn:
                try:
                    conn = psycopg2.connect(dsUri.connectionInfo())
                except psycopg2.OperationalError:
                    (ok, user, passwd) = QgsCredentials.instance().get(
                        conninfo, dsUri.username(), dsUri.password())
                    if not ok:
                        break

                    dsUri.setUsername(user)
                    dsUri.setPassword(passwd)

            if not conn:
                raise RuntimeError(
                    'Could not connect to PostgreSQL database - check connection info'
                )

            if ok:
                QgsCredentials.instance().put(conninfo, user, passwd)

            ogrstr = "PG:%s" % dsUri.connectionInfo()
            format = 'PostgreSQL'
        elif provider == "oracle":
            # OCI:user/password@host:port/service:table
            dsUri = QgsDataSourceUri(layer.dataProvider().dataSourceUri())
            ogrstr = "OCI:"
            if dsUri.username() != "":
                ogrstr += dsUri.username()
                if dsUri.password() != "":
                    ogrstr += "/" + dsUri.password()
                delim = "@"

            if dsUri.host() != "":
                ogrstr += delim + dsUri.host()
                delim = ""
                if dsUri.port() != "" and dsUri.port() != '1521':
                    ogrstr += ":" + dsUri.port()
                ogrstr += "/"
                if dsUri.database() != "":
                    ogrstr += dsUri.database()
            elif dsUri.database() != "":
                ogrstr += delim + dsUri.database()

            if ogrstr == "OCI:":
                raise RuntimeError(
                    'Invalid oracle data source - check connection info')

            ogrstr += ":"
            if dsUri.schema() != "":
                ogrstr += dsUri.schema() + "."

            ogrstr += dsUri.table()
            format = 'OCI'
        else:
            ogrstr = str(layer.source()).split("|")[0]
            path, ext = os.path.splitext(ogrstr)
            format = QgsVectorFileWriter.driverForExtension(ext)

        return '"' + ogrstr + '"', '"' + format + '"'
    def accept(self, *args, **kwargs):
        if not self.validate():
            return False

        try:
            # disable form via a frame, this will still allow interaction with the message bar
            self.stackedWidget.setDisabled(True)

            # clean gui and Qgis messagebars
            self.cleanMessageBars(True)
            # self.iface.messageBar().clearWidgets()

            # Change cursor to Wait cursor
            QApplication.setOverrideCursor(QtCore.Qt.WaitCursor)

            self.iface.mainWindow().statusBar().showMessage('Processing {}'.format(self.windowTitle()))
            self.send_to_messagebar("Please wait.. QGIS will be locked... See log panel for progress.",
                                    level=Qgis.Warning,
                                    duration=0, addToLog=False, core_QGIS=False, showLogPanel=True)
            gp_layer_name = ''

            LOGGER.info('{st}\nProcessing {}'.format(self.windowTitle(), st='*' * 50))

            # Add settings to log
            settingsStr = 'Parameters:---------------------------------------'
            if self.optFile.isChecked():
                settingsStr += '\n    {:30}\t{}'.format('File:', self.lneInCSVFile.text())
                settingsStr += '\n    {:30}\t{}, {}'.format('Geometry Fields:', self.cboXField.currentText(),
                                                            self.cboYField.currentText())
                settingsStr += '\n    {:30}\t{} - {}'.format('CSV Coordinate System:', self.qgsCRScsv.crs().authid(),
                                                              self.qgsCRScsv.crs().description())
            else:
                if self.chkUseSelected.isChecked():
                    settingsStr += '\n    {:30}\t{} with {} selected features'.format('Layer:',
                                                                                      self.mcboTargetLayer.currentLayer().name(),
                                                                                      self.mcboTargetLayer.currentLayer().selectedFeatureCount())
                else:
                    settingsStr += '\n    {:30}\t{}'.format('Layer:', self.mcboTargetLayer.currentLayer().name())

            crs_units = QgsUnitTypes.toString(self.mCRSoutput.crs().mapUnits())
            settingsStr += '\n    {:30}\t{} {}'.format('Thinning Distance:', self.dsbThinDist.value(),crs_units)
            settingsStr += '\n    {:30}\t{} {}'.format("Aggregate Distance:", self.dsbAggregateDist.value(),crs_units)
            settingsStr += '\n    {:30}\t{} {}'.format("Buffer Distance:", self.dsbBufferDist.value(),crs_units)
            settingsStr += '\n    {:30}\t{} {}'.format("Shrink Distance:", self.dsbShrinkDist.value(),crs_units)

            settingsStr += '\n    {:30}\t{}'.format('Output Polygon Shapefile:', self.lneSavePolyFile.text())

            if self.lneSavePointsFile.text() == '':
                settingsStr += '\n    {:30}\t{}'.format('Saved Points Shapefile:', self.lneSavePointsFile.text())

            settingsStr += '\n    {:30}\t{} - {}\n\n'.format('Output Projected Coordinate System:',
                                                              self.mCRSoutput.crs().authid(),
                                                              self.mCRSoutput.crs().description())

            LOGGER.info(settingsStr)
            stepTime = time.time()

            if self.optFile.isChecked():
                in_epsg = int(self.qgsCRScsv.crs().authid().replace('EPSG:',''))
                in_crs = self.qgsCRScsv.crs()
            else:
                in_epsg =self.mcboTargetLayer.currentLayer().crs().authid().replace('EPSG:','')
                in_crs = self.mcboTargetLayer.currentLayer().crs()

            out_epsg = int(self.mCRSoutput.crs().authid().replace('EPSG:',''))

            filePoly = None

            gdfPoints = None
            filePoints = None

            if self.optFile.isChecked():
                if self.DEBUG:
                    filePoints = os.path.join(TEMPDIR, os.path.splitext(os.path.basename(self.lneSavePolyFile.text()))[0] + '_table2pts.shp')

                if os.path.splitext(self.lneInCSVFile.text())[-1] == '.csv':
                    gdfPoints, gdfPtsCrs = convert.convert_csv_to_points(self.lneInCSVFile.text() , out_shapefilename=filePoints,
                                                                         coord_columns=[self.cboXField.currentText(),
                                                                                        self.cboYField.currentText()],
                                                                         coord_columns_epsg=in_epsg)

                elif os.path.splitext(self.lneInCSVFile.text())[-1] in ['.xls', '.xlsx', '.ods']:
                    xls_file = pd.ExcelFile(self.lneInCSVFile.text())
                    pdfxls = xls_file.parse(self.sheet(), skiprows=self.linesToIgnore() - 1)
                    del xls_file

                    gdfPoints, gdfPtsCrs = convert.add_point_geometry_to_dataframe(pdfxls,
                                                                                   coord_columns=[
                                                                                       self.cboXField.currentText(),
                                                                                       self.cboYField.currentText()],
                                                                                   coord_columns_epsg=in_epsg)
                    del pdfxls

                LOGGER.info('{:<30} {d:<15} {}'.format('Add Geometry to Table','',
                                                          d=str(timedelta(seconds=time.time() - stepTime))))
                stepTime = time.time()
                
                if filePoints is not None:
                    describe.save_geopandas_tofile(gdfPoints, filePoints) #, file_encoding=self.file_encoding)

                if self.DISP_TEMP_LAYERS and filePoints is not None:
                    addVectorFileToQGIS(filePoints, layer_name=os.path.splitext(os.path.basename(filePoints))[0],
                                        group_layer_name='DEBUG', atTop=True)

            else:
                layerPts = self.mcboTargetLayer.currentLayer()

                if layerPts.providerType() == 'delimitedtext' or \
                        os.path.splitext(get_layer_source(layerPts))[-1] == '.vrt' or \
                        self.chkUseSelected.isChecked() or self.optFile.isChecked():

                    filePoints = os.path.join(TEMPDIR, "{}_points.shp".format(layerPts.name()))

                    if self.chkUseSelected.isChecked():
                        filePoints = os.path.join(TEMPDIR, "{}_selected_points.shp".format(layerPts.name()))

                    if os.path.exists(filePoints):
                        removeFileFromQGIS(filePoints)

                    ptsLayer = copyLayerToMemory(layerPts, layerPts.name() + "_memory", bAddUFI=True,
                                                 bOnlySelectedFeat=self.chkUseSelected.isChecked())

                    _writer = QgsVectorFileWriter.writeAsVectorFormat(ptsLayer, filePoints, "utf-8",
                                                                      self.mCRSoutput.crs(), driverName="ESRI Shapefile")

                    LOGGER.info('{:<30} {d:<15} {}'.format('Save layer/selection to file',filePoints,
                                                          d=str(timedelta(seconds=time.time() - stepTime) )))
                    stepTime = time.time()

                    del ptsLayer

                    if self.DISP_TEMP_LAYERS:
                        addVectorFileToQGIS(filePoints, layer_name=os.path.splitext(os.path.basename(filePoints))[0],
                                            group_layer_name='DEBUG', atTop=True)

                else:
                    filePoints = get_layer_source(layerPts)

            if gdfPoints is None:
                ptsDesc = describe.VectorDescribe(filePoints)
                gdfPtsCrs = ptsDesc.crs
                gdfPoints = ptsDesc.open_geo_dataframe()

            if in_crs.authid() != self.mCRSoutput.crs().authid():

                gdfPoints = gdfPoints.to_crs(epsg=out_epsg)
                gdfPtsCrs = pyprecag_crs.crs()
                gdfPtsCrs.getFromEPSG(out_epsg)

                LOGGER.info('{:<30} {d:<15} {} to {}'.format('Reproject points', in_crs.authid(),
                                                             self.mCRSoutput.crs().authid(),
                                                             d=str(timedelta(seconds=time.time() - stepTime))))

                if self.DEBUG:
                    filePoints = os.path.join(TEMPDIR, os.path.basename(self.lneSavePolyFile.text().replace('.csv', '_ptsprj.shp')))

                    removeFileFromQGIS(filePoints)
                    describe.save_geopandas_tofile(gdfPoints, filePoints)
                    if self.DISP_TEMP_LAYERS:
                        if self.DEBUG:
                            addVectorFileToQGIS(filePoints,
                                                layer_name=os.path.splitext(os.path.basename(filePoints))[0],
                                                group_layer_name='DEBUG', atTop=True)
                        else:
                            addVectorFileToQGIS(filePoints,
                                                layer_name=os.path.splitext(os.path.basename(filePoints))[0],
                                                atTop=True)
            stepTime = time.time()
            result = processing.create_polygon_from_point_trail(gdfPoints, gdfPtsCrs,
                                                                out_filename=self.lneSavePolyFile.text(),
                                                                thin_dist_m=self.dsbThinDist.value(),
                                                                aggregate_dist_m=self.dsbAggregateDist.value(),
                                                                buffer_dist_m=self.dsbBufferDist.value(),
                                                                shrink_dist_m=self.dsbShrinkDist.value())

            addVectorFileToQGIS(self.lneSavePolyFile.text(), atTop=True)

            self.cleanMessageBars(True)
            self.stackedWidget.setDisabled(False)
            QApplication.restoreOverrideCursor()
            self.iface.messageBar().popWidget()
            self.iface.mainWindow().statusBar().clearMessage()

            if result is not None:
                self.fraMain.setDisabled(False)
                self.send_to_messagebar(result, level=Qgis.Warning, duration=0, addToLog=False)
                return False  # leave dialog open

            return super(PointTrailToPolygonDialog, self).accept(*args, **kwargs)

        except Exception as err:
            QApplication.restoreOverrideCursor()
            self.iface.mainWindow().statusBar().clearMessage()
            self.cleanMessageBars(True)
            self.stackedWidget.setDisabled(False)

            self.send_to_messagebar(str(err), level=Qgis.Critical,
                                    duration=0, addToLog=True, core_QGIS=False, showLogPanel=True,
                                    exc_info=sys.exc_info())

            return False  # leave dialog open
Exemple #36
0
def create_conv_runoff(self):
    QSWATMOD_path_dict = self.dirs_and_paths()

    # Create swatmf_results tree inside 
    root = QgsProject.instance().layerTreeRoot()
    if root.findGroup("SWAT-MODFLOW"):
        SM = root.findGroup("SWAT-MODFLOW")
        SM.insertGroup(0, "Scenarios")
        scenario_tree = root.findGroup("Scenarios")
        scenario_tree.addGroup("Pumping from MODFLOW")
        input1 = QgsProject.instance().mapLayersByName("sub (SWAT)")[0]

        # Copy sub shapefile to be under "p from mf"
        name = "conv_runoff"
        name_ext = "conv_runoff.shp"
        output_dir = QSWATMOD_path_dict['Scenarios']

        # Check if there is an exsting mf_head shapefile
        # if not any(lyr.name() == ("conv_runoff") for lyr in QgsProject.instance().mapLayers().values()):
        conv_runoff_shapfile = os.path.join(output_dir, name_ext)
        QgsVectorFileWriter.writeAsVectorFormat(
            input1, conv_runoff_shapfile,
            "utf-8", input1.crs(), "ESRI Shapefile")
        layer = QgsVectorLayer(conv_runoff_shapfile, '{0}'.format("conv_runoff"), 'ogr')

        # Put in the group
        # root = QgsProject.instance().layerTreeRoot()
        # conv_runoff = root.findGroup("Pumping from MODFLOW")
        QgsProject.instance().addMapLayer(layer, False)
        p_mf_tree = root.findGroup("Pumping from MODFLOW")
        p_mf_tree.insertChildNode(0, QgsLayerTreeLayer(layer))

        input2 = QgsProject.instance().mapLayersByName("conv_runoff")[0]
        fields = input2.dataProvider()

        # DEBUG: fixed: AttributeError: 'QgsVectorDataProvider' object has no attribute 'indexFromName' 
        fdname = [
                fields.fields().indexFromName(field.name()) for field in fields.fields()
                if not field.name() == 'Subbasin'
                ]
        fields.deleteAttributes(fdname)
        input2.updateFields()

        cvy = QgsField('Conveyance', QVariant.Double, 'double', 20, 5)
        runoff = QgsField('Runoff', QVariant.Double, 'double', 20, 5)
        fields.addAttributes([cvy, runoff])
        input2.updateFields()
        cvy_idx = fields.fields().indexFromName('Conveyance')
        runoff_idx = fields.fields().indexFromName('Runoff')
        feats = input2.getFeatures()
        input2.startEditing()

        for feat in feats:
            # attr = feat.attributes() #  this can be used for changing value based on value from other column
            input2.changeAttributeValue(feat.id(), cvy_idx, 1)
            input2.changeAttributeValue(feat.id(), runoff_idx, 0.05)    
        input2.commitChanges()

        # msgBox = QMessageBox()
        # msgBox.setWindowIcon(QtGui.QIcon(':/QSWATMOD2/pics/sm_icon.png'))
        msgBox.setWindowTitle("Created!")
        msgBox.setText("'conv_runoff.shp' file has been created!")
        msgBox.exec_()

        # FIXME, TODO: require escapting code to check *.wel file.
        # Find *.wel file and read number of grid cells and set maximum grid cells
        try:
            for filename in glob.glob(str(QSWATMOD_path_dict['SMfolder'])+"/*.wel"):
                with open(filename, "r") as f:
                    data = []
                    for line in f.readlines():
                        if not line.startswith("#"):
                            data.append(line.replace('\n', '').split())
            wel_max = int(data[0][0])
            self.dlg.spinBox_irrig_mf.setMaximum(wel_max)
        except:
            msgBox.setWindowTitle("No Well package found!")
            msgBox.setText("Please, provide a well package to your MODFLOW model first!")
            self.dlg.spinBox_irrig_mf.setEnabled(False)
            msgBox.exec_()
    else:
        msgBox.setWindowTitle("Error!")
        msgBox.setText("Your project couldn't be read.\nPlease, go back to the linking process!")
        msgBox.exec_()
Exemple #37
0
def getFileFilter(param):
    """
    Returns a suitable file filter pattern for the specified parameter definition
    :param param:
    :return:
    """
    if param.type() == 'layer':
        vectors = QgsProviderRegistry.instance().fileVectorFilters().split(
            ';;')
        vectors.pop(0)
        rasters = QgsProviderRegistry.instance().fileRasterFilters().split(
            ';;')
        rasters.pop(0)
        filters = set(vectors + rasters)
        filters = sorted(filters)
        return tr('All files (*.*)') + ';;' + ";;".join(filters)
    elif param.type() == 'multilayer':
        if param.layerType() == QgsProcessing.TypeRaster:
            exts = QgsRasterFileWriter.supportedFormatExtensions()
        elif param.layerType() == QgsProcessing.TypeFile:
            return tr('All files (*.*)',
                      'QgsProcessingParameterMultipleLayers')
        else:
            exts = QgsVectorFileWriter.supportedFormatExtensions()
        for i in range(len(exts)):
            exts[i] = tr('{0} files (*.{1})',
                         'QgsProcessingParameterMultipleLayers').format(
                             exts[i].upper(), exts[i].lower())
        return tr('All files (*.*)') + ';;' + ';;'.join(exts)
    elif param.type() == 'raster':
        return QgsProviderRegistry.instance().fileRasterFilters()
    elif param.type() == 'rasterDestination':
        if param.provider() is not None:
            exts = param.provider().supportedOutputRasterLayerExtensions()
        else:
            exts = QgsRasterFileWriter.supportedFormatExtensions()
        for i in range(len(exts)):
            exts[i] = tr('{0} files (*.{1})',
                         'ParameterRaster').format(exts[i].upper(),
                                                   exts[i].lower())
        return ';;'.join(exts) + ';;' + tr('All files (*.*)')
    elif param.type() in ('sink', 'vectorDestination'):
        if param.provider() is not None:
            exts = param.provider().supportedOutputVectorLayerExtensions()
        else:
            exts = QgsVectorFileWriter.supportedFormatExtensions()
        for i in range(len(exts)):
            exts[i] = tr('{0} files (*.{1})',
                         'ParameterVector').format(exts[i].upper(),
                                                   exts[i].lower())
        return ';;'.join(exts) + ';;' + tr('All files (*.*)')
    elif param.type() == 'source':
        return QgsProviderRegistry.instance().fileVectorFilters()
    elif param.type() == 'vector':
        return QgsProviderRegistry.instance().fileVectorFilters()
    elif param.type() == 'fileDestination':
        return param.fileFilter() + ';;' + tr('All files (*.*)')

    if param.defaultFileExtension():
        return tr(
            'Default extension') + ' (*.' + param.defaultFileExtension() + ')'
    else:
        return ''
    def testWriteWithBinaryField(self):
        """
        Test writing with a binary field
        :return:
        """
        basetestpath = tempfile.mkdtemp()

        tmpfile = os.path.join(basetestpath, 'binaryfield.sqlite')
        ds = ogr.GetDriverByName('SQLite').CreateDataSource(tmpfile)
        lyr = ds.CreateLayer('test',
                             geom_type=ogr.wkbPoint,
                             options=['FID=fid'])
        lyr.CreateField(ogr.FieldDefn('strfield', ogr.OFTString))
        lyr.CreateField(ogr.FieldDefn('intfield', ogr.OFTInteger))
        lyr.CreateField(ogr.FieldDefn('binfield', ogr.OFTBinary))
        lyr.CreateField(ogr.FieldDefn('binfield2', ogr.OFTBinary))
        f = None
        ds = None

        vl = QgsVectorLayer(tmpfile)
        self.assertTrue(vl.isValid())

        # check that 1 of its fields is a bool
        fields = vl.fields()
        self.assertEqual(
            fields.at(fields.indexFromName('binfield')).type(),
            QVariant.ByteArray)

        dp = vl.dataProvider()
        f = QgsFeature(fields)
        bin_1 = b'xxx'
        bin_2 = b'yyy'
        bin_val1 = QByteArray(bin_1)
        bin_val2 = QByteArray(bin_2)
        f.setAttributes([1, 'str', 100, bin_val1, bin_val2])
        self.assertTrue(dp.addFeature(f))

        # write a gpkg package with a binary field
        filename = os.path.join(str(QDir.tempPath()), 'with_bin_field')
        rc, errmsg = QgsVectorFileWriter.writeAsVectorFormat(
            vl, filename, 'utf-8', vl.crs(), 'GPKG')

        self.assertEqual(rc, QgsVectorFileWriter.NoError)

        # open the resulting geopackage
        vl = QgsVectorLayer(filename + '.gpkg', '', 'ogr')
        self.assertTrue(vl.isValid())
        fields = vl.fields()

        # test type of converted field
        idx = fields.indexFromName('binfield')
        self.assertEqual(fields.at(idx).type(), QVariant.ByteArray)
        idx2 = fields.indexFromName('binfield2')
        self.assertEqual(fields.at(idx2).type(), QVariant.ByteArray)

        # test values
        self.assertEqual(vl.getFeature(1).attributes()[idx], bin_val1)
        self.assertEqual(vl.getFeature(1).attributes()[idx2], bin_val2)

        del vl
        os.unlink(filename + '.gpkg')
Exemple #39
0
    def initialize():
        icon = QgsApplication.getThemeIcon("/processingAlgorithm.svg")
        ProcessingConfig.settingIcons['General'] = icon
        ProcessingConfig.addSetting(
            Setting(ProcessingConfig.tr('General'),
                    ProcessingConfig.SHOW_DEBUG_IN_DIALOG,
                    ProcessingConfig.tr('Show extra info in Log panel'), True))
        ProcessingConfig.addSetting(
            Setting(
                ProcessingConfig.tr('General'),
                ProcessingConfig.KEEP_DIALOG_OPEN,
                ProcessingConfig.tr(
                    'Keep dialog open after running an algorithm'), True))
        ProcessingConfig.addSetting(
            Setting(ProcessingConfig.tr('General'),
                    ProcessingConfig.USE_FILENAME_AS_LAYER_NAME,
                    ProcessingConfig.tr('Use filename as layer name'), False))
        ProcessingConfig.addSetting(
            Setting(ProcessingConfig.tr('General'),
                    ProcessingConfig.SHOW_RECENT_ALGORITHMS,
                    ProcessingConfig.tr('Show recently executed algorithms'),
                    True))
        ProcessingConfig.addSetting(
            Setting(
                ProcessingConfig.tr('General'),
                ProcessingConfig.SHOW_PROVIDERS_TOOLTIP,
                ProcessingConfig.tr(
                    'Show tooltip when there are disabled providers'), True))
        ProcessingConfig.addSetting(
            Setting(ProcessingConfig.tr('General'),
                    ProcessingConfig.OUTPUT_FOLDER,
                    ProcessingConfig.tr('Output folder'),
                    defaultOutputFolder(),
                    valuetype=Setting.FOLDER))
        ProcessingConfig.addSetting(
            Setting(
                ProcessingConfig.tr('General'), ProcessingConfig.SHOW_CRS_DEF,
                ProcessingConfig.tr(
                    'Show layer CRS definition in selection boxes'), True))
        ProcessingConfig.addSetting(
            Setting(
                ProcessingConfig.tr('General'),
                ProcessingConfig.WARN_UNMATCHING_CRS,
                ProcessingConfig.tr(
                    "Warn before executing if layer CRS's do not match"),
                True))
        ProcessingConfig.addSetting(
            Setting(
                ProcessingConfig.tr('General'),
                ProcessingConfig.WARN_UNMATCHING_EXTENT_CRS,
                ProcessingConfig.
                tr("Warn before executing if extent CRS might not match layers CRS"
                   ), True))
        ProcessingConfig.addSetting(
            Setting(ProcessingConfig.tr('General'),
                    ProcessingConfig.RASTER_STYLE,
                    ProcessingConfig.tr('Style for raster layers'),
                    '',
                    valuetype=Setting.FILE))
        ProcessingConfig.addSetting(
            Setting(ProcessingConfig.tr('General'),
                    ProcessingConfig.VECTOR_POINT_STYLE,
                    ProcessingConfig.tr('Style for point layers'),
                    '',
                    valuetype=Setting.FILE))
        ProcessingConfig.addSetting(
            Setting(ProcessingConfig.tr('General'),
                    ProcessingConfig.VECTOR_LINE_STYLE,
                    ProcessingConfig.tr('Style for line layers'),
                    '',
                    valuetype=Setting.FILE))
        ProcessingConfig.addSetting(
            Setting(ProcessingConfig.tr('General'),
                    ProcessingConfig.VECTOR_POLYGON_STYLE,
                    ProcessingConfig.tr('Style for polygon layers'),
                    '',
                    valuetype=Setting.FILE))
        ProcessingConfig.addSetting(
            Setting(ProcessingConfig.tr('General'),
                    ProcessingConfig.PRE_EXECUTION_SCRIPT,
                    ProcessingConfig.tr('Pre-execution script'),
                    '',
                    valuetype=Setting.FILE))
        ProcessingConfig.addSetting(
            Setting(ProcessingConfig.tr('General'),
                    ProcessingConfig.POST_EXECUTION_SCRIPT,
                    ProcessingConfig.tr('Post-execution script'),
                    '',
                    valuetype=Setting.FILE))
        ProcessingConfig.addSetting(
            Setting(ProcessingConfig.tr('General'),
                    ProcessingConfig.RECENT_ALGORITHMS,
                    ProcessingConfig.tr('Recent algorithms'),
                    '',
                    hidden=True))
        ProcessingConfig.addSetting(
            Setting(
                ProcessingConfig.tr('General'),
                ProcessingConfig.MODELS_SCRIPTS_REPO,
                ProcessingConfig.tr('Scripts and models repository'),
                'https://raw.githubusercontent.com/qgis/QGIS-Processing/master'
            ))

        invalidFeaturesOptions = [
            ProcessingConfig.tr('Do not filter (better performance)'),
            ProcessingConfig.tr('Ignore features with invalid geometries'),
            ProcessingConfig.tr(
                'Stop algorithm execution when a geometry is invalid')
        ]
        ProcessingConfig.addSetting(
            Setting(ProcessingConfig.tr('General'),
                    ProcessingConfig.FILTER_INVALID_GEOMETRIES,
                    ProcessingConfig.tr('Invalid features filtering'),
                    invalidFeaturesOptions[2],
                    valuetype=Setting.SELECTION,
                    options=invalidFeaturesOptions))

        extensions = QgsVectorFileWriter.supportedFormatExtensions()
        ProcessingConfig.addSetting(
            Setting(
                ProcessingConfig.tr('General'),
                ProcessingConfig.DEFAULT_OUTPUT_VECTOR_LAYER_EXT,
                ProcessingConfig.tr('Default output vector layer extension'),
                extensions[0],
                valuetype=Setting.SELECTION,
                options=extensions))

        extensions = QgsRasterFileWriter.supportedFormatExtensions()
        ProcessingConfig.addSetting(
            Setting(
                ProcessingConfig.tr('General'),
                ProcessingConfig.DEFAULT_OUTPUT_RASTER_LAYER_EXT,
                ProcessingConfig.tr('Default output raster layer extension'),
                extensions[0],
                valuetype=Setting.SELECTION,
                options=extensions))
    def processAlgorithm(self, parameters, context, feedback):
        """
        Here is where the processing itself takes place.
        """

        outflowPoints = self.parameterAsVectorLayer(parameters,
                                                    self.INPUT_POINTS, context)
        input_dem = self.parameterAsRasterLayer(parameters, self.INPUT_DEM,
                                                context)

        out_folder = self.parameterAsString(parameters, self.OUTPUT_FOLDER,
                                            context)

        total_points = outflowPoints.featureCount()

        # Iterate over point features
        for i, pnt in enumerate(outflowPoints.getFeatures()):

            # Get x and y coordinate from point feature
            geom = pnt.geometry()
            p = geom.asPoint()
            x = p.x()
            y = p.y()

            feedback.pushInfo(
                'Creating upslope area for point ({:.2f}, {:.2f}) - {} of {}'.
                format(x, y, i + 1, total_points))
            feedback.setProgress(i / total_points * 100.)

            # Calculate catchment raster from point feature
            catchraster = processing.run(
                "saga:upslopearea", {
                    'TARGET': None,
                    'TARGET_PT_X': x,
                    'TARGET_PT_Y': y,
                    'ELEVATION': input_dem,
                    'SINKROUTE': None,
                    'METHOD': 0,
                    'CONVERGE': 1.1,
                    'AREA': 'TEMPORARY_OUTPUT'
                })

            # Polygonize raster catchment
            catchpoly = processing.run(
                "gdal:polygonize", {
                    'INPUT': catchraster['AREA'],
                    'BAND': 1,
                    'FIELD': 'DN',
                    'EIGHT_CONNECTEDNESS': False,
                    'OUTPUT': 'TEMPORARY_OUTPUT'
                })

            # Select features having DN = 100 and export them to a SHP file
            catch_lyr = QgsVectorLayer(catchpoly['OUTPUT'], 'catchmments',
                                       'ogr')
            catch_lyr.selectByExpression('"DN"=100')
            catch_filename = os.path.join(out_folder, 'area_{}'.format(i + 1))
            # Save only selected features (last argument is onlySelected = True)
            QgsVectorFileWriter.writeAsVectorFormat(catch_lyr,
                                                    catch_filename, 'UTF-8',
                                                    outflowPoints.crs(),
                                                    'ESRI Shapefile', True)

        feedback.setProgress(100)
        return {self.OUTPUT_FOLDER: out_folder}
Exemple #41
0
 def testSupportedFormatExtensions(self):
     formats = QgsVectorFileWriter.supportedFormatExtensions()
     self.assertTrue('gpkg' in formats)
     self.assertFalse('exe' in formats)
     self.assertEqual(formats[0], 'shp')
Exemple #42
0
    def testOverwriteLayer(self):
        """Tests writing a layer with a field value converter."""

        ml = QgsVectorLayer('Point?field=firstfield:int', 'test', 'memory')
        provider = ml.dataProvider()

        ft = QgsFeature()
        ft.setAttributes([1])
        provider.addFeatures([ft])

        options = QgsVectorFileWriter.SaveVectorOptions()
        options.driverName = 'GPKG'
        options.layerName = 'test'
        filename = '/vsimem/out.gpkg'
        write_result = QgsVectorFileWriter.writeAsVectorFormat(
            ml, filename, options)
        self.assertEqual(write_result, QgsVectorFileWriter.NoError)

        ds = ogr.Open(filename, update=1)
        lyr = ds.GetLayerByName('test')
        self.assertIsNotNone(lyr)
        f = lyr.GetNextFeature()
        self.assertEqual(f['firstfield'], 1)
        ds.CreateLayer('another_layer')
        del f
        del lyr
        del ds

        caps = QgsVectorFileWriter.editionCapabilities(filename)
        self.assertTrue((caps & QgsVectorFileWriter.CanAddNewLayer))
        self.assertTrue((caps & QgsVectorFileWriter.CanAppendToExistingLayer))
        self.assertTrue(
            (caps & QgsVectorFileWriter.CanAddNewFieldsToExistingLayer))
        self.assertTrue((caps & QgsVectorFileWriter.CanDeleteLayer))

        self.assertTrue(QgsVectorFileWriter.targetLayerExists(
            filename, 'test'))

        self.assertFalse(
            QgsVectorFileWriter.areThereNewFieldsToCreate(
                filename, 'test', ml, [0]))

        # Test CreateOrOverwriteLayer
        ml = QgsVectorLayer('Point?field=firstfield:int', 'test', 'memory')
        provider = ml.dataProvider()

        ft = QgsFeature()
        ft.setAttributes([2])
        provider.addFeatures([ft])

        options = QgsVectorFileWriter.SaveVectorOptions()
        options.driverName = 'GPKG'
        options.layerName = 'test'
        options.actionOnExistingFile = QgsVectorFileWriter.CreateOrOverwriteLayer
        filename = '/vsimem/out.gpkg'
        write_result = QgsVectorFileWriter.writeAsVectorFormat(
            ml, filename, options)
        self.assertEqual(write_result, QgsVectorFileWriter.NoError)

        ds = ogr.Open(filename)
        lyr = ds.GetLayerByName('test')
        self.assertIsNotNone(lyr)
        f = lyr.GetNextFeature()
        self.assertEqual(f['firstfield'], 2)
        # another_layer should still exist
        self.assertIsNotNone(ds.GetLayerByName('another_layer'))
        del f
        del lyr
        del ds

        # Test CreateOrOverwriteFile
        ml = QgsVectorLayer('Point?field=firstfield:int', 'test', 'memory')
        provider = ml.dataProvider()

        ft = QgsFeature()
        ft.setAttributes([3])
        provider.addFeatures([ft])

        options = QgsVectorFileWriter.SaveVectorOptions()
        options.driverName = 'GPKG'
        options.layerName = 'test'
        filename = '/vsimem/out.gpkg'
        write_result = QgsVectorFileWriter.writeAsVectorFormat(
            ml, filename, options)
        self.assertEqual(write_result, QgsVectorFileWriter.NoError)

        ds = ogr.Open(filename)
        lyr = ds.GetLayerByName('test')
        self.assertIsNotNone(lyr)
        f = lyr.GetNextFeature()
        self.assertEqual(f['firstfield'], 3)
        # another_layer should no longer exist
        self.assertIsNone(ds.GetLayerByName('another_layer'))
        del f
        del lyr
        del ds

        # Test AppendToLayerNoNewFields
        ml = QgsVectorLayer('Point?field=firstfield:int&field=secondfield:int',
                            'test', 'memory')
        provider = ml.dataProvider()

        ft = QgsFeature()
        ft.setAttributes([4, -10])
        provider.addFeatures([ft])

        self.assertTrue(
            QgsVectorFileWriter.areThereNewFieldsToCreate(
                filename, 'test', ml, [0, 1]))

        options = QgsVectorFileWriter.SaveVectorOptions()
        options.driverName = 'GPKG'
        options.layerName = 'test'
        options.actionOnExistingFile = QgsVectorFileWriter.AppendToLayerNoNewFields
        filename = '/vsimem/out.gpkg'
        write_result = QgsVectorFileWriter.writeAsVectorFormat(
            ml, filename, options)
        self.assertEqual(write_result, QgsVectorFileWriter.NoError)

        ds = ogr.Open(filename)
        lyr = ds.GetLayerByName('test')
        self.assertEqual(lyr.GetLayerDefn().GetFieldCount(), 1)
        self.assertIsNotNone(lyr)
        f = lyr.GetNextFeature()
        self.assertEqual(f['firstfield'], 3)
        f = lyr.GetNextFeature()
        self.assertEqual(f['firstfield'], 4)
        del f
        del lyr
        del ds

        # Test AppendToLayerAddFields
        ml = QgsVectorLayer('Point?field=firstfield:int&field=secondfield:int',
                            'test', 'memory')
        provider = ml.dataProvider()

        ft = QgsFeature()
        ft.setAttributes([5, -1])
        provider.addFeatures([ft])

        self.assertTrue(
            QgsVectorFileWriter.areThereNewFieldsToCreate(
                filename, 'test', ml, [0, 1]))

        options = QgsVectorFileWriter.SaveVectorOptions()
        options.driverName = 'GPKG'
        options.layerName = 'test'
        options.actionOnExistingFile = QgsVectorFileWriter.AppendToLayerAddFields
        filename = '/vsimem/out.gpkg'
        write_result = QgsVectorFileWriter.writeAsVectorFormat(
            ml, filename, options)
        self.assertEqual(write_result, QgsVectorFileWriter.NoError)

        ds = ogr.Open(filename)
        lyr = ds.GetLayerByName('test')
        self.assertEqual(lyr.GetLayerDefn().GetFieldCount(), 2)
        self.assertIsNotNone(lyr)
        f = lyr.GetNextFeature()
        self.assertEqual(f['firstfield'], 3)
        self.assertFalse(f.IsFieldSet('secondfield'))
        f = lyr.GetNextFeature()
        self.assertEqual(f['firstfield'], 4)
        self.assertFalse(f.IsFieldSet('secondfield'))
        f = lyr.GetNextFeature()
        self.assertEqual(f['firstfield'], 5)
        self.assertEqual(f['secondfield'], -1)
        del f
        del lyr
        del ds

        gdal.Unlink(filename)
Exemple #43
0
    def testWriteShapefileWithAttributeSubsets(self):
        """Tests writing subsets of attributes to files."""
        ml = QgsVectorLayer((
            'Point?crs=epsg:4326&field=id:int&field=field1:int&field=field2:int&field=field3:int'
        ), 'test', 'memory')

        self.assertIsNotNone(ml, 'Provider not initialized')
        self.assertTrue(ml.isValid(), 'Source layer not valid')
        provider = ml.dataProvider()
        self.assertIsNotNone(provider)

        ft = QgsFeature()
        ft.setGeometry(QgsGeometry.fromWkt('Point (1 2)'))
        ft.setAttributes([1, 11, 12, 13])
        res, features = provider.addFeatures([ft])
        self.assertTrue(res)
        self.assertTrue(features)

        # first write out with all attributes
        dest_file_name = os.path.join(str(QDir.tempPath()),
                                      'all_attributes.shp')
        crs = QgsCoordinateReferenceSystem()
        crs.createFromId(4326, QgsCoordinateReferenceSystem.EpsgCrsId)
        write_result = QgsVectorFileWriter.writeAsVectorFormat(
            ml, dest_file_name, 'utf-8', crs, 'ESRI Shapefile', attributes=[])
        self.assertEqual(write_result, QgsVectorFileWriter.NoError)

        # Open result and check
        created_layer = QgsVectorLayer('{}|layerid=0'.format(dest_file_name),
                                       'test', 'ogr')
        self.assertEqual(created_layer.fields().count(), 4)
        f = next(created_layer.getFeatures(QgsFeatureRequest()))
        self.assertEqual(f['id'], 1)
        self.assertEqual(f['field1'], 11)
        self.assertEqual(f['field2'], 12)
        self.assertEqual(f['field3'], 13)

        # now test writing out only a subset of attributes
        dest_file_name = os.path.join(str(QDir.tempPath()),
                                      'subset_attributes.shp')
        write_result = QgsVectorFileWriter.writeAsVectorFormat(
            ml,
            dest_file_name,
            'utf-8',
            crs,
            'ESRI Shapefile',
            attributes=[1, 3])
        self.assertEqual(write_result, QgsVectorFileWriter.NoError)

        # Open result and check
        created_layer = QgsVectorLayer('{}|layerid=0'.format(dest_file_name),
                                       'test', 'ogr')
        self.assertEqual(created_layer.fields().count(), 2)
        f = next(created_layer.getFeatures(QgsFeatureRequest()))
        self.assertEqual(f['field1'], 11)
        self.assertEqual(f['field3'], 13)

        # finally test writing no attributes
        dest_file_name = os.path.join(str(QDir.tempPath()),
                                      'no_attributes.shp')
        write_result = QgsVectorFileWriter.writeAsVectorFormat(
            ml,
            dest_file_name,
            'utf-8',
            crs,
            'ESRI Shapefile',
            skipAttributeCreation=True)
        self.assertEqual(write_result, QgsVectorFileWriter.NoError)

        # Open result and check
        created_layer = QgsVectorLayer('{}|layerid=0'.format(dest_file_name),
                                       'test', 'ogr')
        # expect only a default 'FID' field for shapefiles
        self.assertEqual(created_layer.fields().count(), 1)
        self.assertEqual(created_layer.fields()[0].name(), 'FID')
        # in this case we also check that the geometry exists, to make sure feature has been correctly written
        # even without attributes
        f = next(created_layer.getFeatures(QgsFeatureRequest()))
        g = f.geometry()
        wkt = g.exportToWkt()
        expWkt = 'Point (1 2)'
        self.assertTrue(
            compareWkt(expWkt, wkt),
            "geometry not saved correctly when saving without attributes : mismatch Expected:\n%s\nGot:\n%s\n"
            % (expWkt, wkt))
        self.assertEqual(f['FID'], 0)
Exemple #44
0
    def __init__(self,
                 destination,
                 encoding,
                 fields,
                 geometryType,
                 crs,
                 options=None):
        self.destination = destination
        self.isNotFileBased = False
        self.layer = None
        self.writer = None

        if encoding is None:
            settings = QSettings()
            encoding = settings.value('/Processing/encoding',
                                      'System',
                                      type=str)

        if self.destination.startswith(self.MEMORY_LAYER_PREFIX):
            self.isNotFileBased = True

            uri = GEOM_TYPE_MAP[geometryType] + "?uuid=" + unicode(
                uuid.uuid4())
            if crs.isValid():
                uri += '&crs=' + crs.authid()
            fieldsdesc = []
            for f in fields:
                qgsfield = _toQgsField(f)
                fieldsdesc.append(
                    'field=%s:%s' %
                    (qgsfield.name(),
                     TYPE_MAP_MEMORY_LAYER.get(qgsfield.type(), "string")))
            if fieldsdesc:
                uri += '&' + '&'.join(fieldsdesc)

            self.layer = QgsVectorLayer(uri, self.destination, 'memory')
            self.writer = self.layer.dataProvider()
        elif self.destination.startswith(self.POSTGIS_LAYER_PREFIX):
            self.isNotFileBased = True
            uri = QgsDataSourceURI(
                self.destination[len(self.POSTGIS_LAYER_PREFIX):])
            connInfo = uri.connectionInfo()
            (success, user,
             passwd) = QgsCredentials.instance().get(connInfo, None, None)
            if success:
                QgsCredentials.instance().put(connInfo, user, passwd)
            else:
                raise GeoAlgorithmExecutionException(
                    "Couldn't connect to database")
            print uri.uri()
            try:
                db = postgis_utils.GeoDB(host=uri.host(),
                                         port=int(uri.port()),
                                         dbname=uri.database(),
                                         user=user,
                                         passwd=passwd)
            except postgis_utils.DbError as e:
                raise GeoAlgorithmExecutionException(
                    "Couldn't connect to database:\n%s" % e.message)

            def _runSQL(sql):
                try:
                    db._exec_sql_and_commit(unicode(sql))
                except postgis_utils.DbError as e:
                    raise GeoAlgorithmExecutionException(
                        'Error creating output PostGIS table:\n%s' % e.message)

            fields = [_toQgsField(f) for f in fields]
            fieldsdesc = ",".join(
                '%s %s' %
                (f.name(), TYPE_MAP_POSTGIS_LAYER.get(f.type(), "VARCHAR"))
                for f in fields)

            _runSQL("CREATE TABLE %s.%s (%s)" %
                    (uri.schema(), uri.table().lower(), fieldsdesc))
            if geometryType != QGis.WKBNoGeometry:
                _runSQL(
                    "SELECT AddGeometryColumn('{schema}', '{table}', 'the_geom', {srid}, '{typmod}', 2)"
                    .format(table=uri.table().lower(),
                            schema=uri.schema(),
                            srid=crs.authid().split(":")[-1],
                            typmod=GEOM_TYPE_MAP[geometryType].upper()))

            self.layer = QgsVectorLayer(uri.uri(), uri.table(), "postgres")
            self.writer = self.layer.dataProvider()
        elif self.destination.startswith(self.SPATIALITE_LAYER_PREFIX):
            self.isNotFileBased = True
            uri = QgsDataSourceURI(
                self.destination[len(self.SPATIALITE_LAYER_PREFIX):])
            print uri.uri()
            try:
                db = spatialite_utils.GeoDB(uri=uri)
            except spatialite_utils.DbError as e:
                raise GeoAlgorithmExecutionException(
                    "Couldn't connect to database:\n%s" % e.message)

            def _runSQL(sql):
                try:
                    db._exec_sql_and_commit(unicode(sql))
                except spatialite_utils.DbError as e:
                    raise GeoAlgorithmExecutionException(
                        'Error creating output Spatialite table:\n%s' %
                        unicode(e))

            fields = [_toQgsField(f) for f in fields]
            fieldsdesc = ",".join(
                '%s %s' %
                (f.name(), TYPE_MAP_SPATIALITE_LAYER.get(f.type(), "VARCHAR"))
                for f in fields)

            _runSQL("DROP TABLE IF EXISTS %s" % uri.table().lower())
            _runSQL("CREATE TABLE %s (%s)" % (uri.table().lower(), fieldsdesc))
            if geometryType != QGis.WKBNoGeometry:
                _runSQL(
                    "SELECT AddGeometryColumn('{table}', 'the_geom', {srid}, '{typmod}', 2)"
                    .format(table=uri.table().lower(),
                            srid=crs.authid().split(":")[-1],
                            typmod=GEOM_TYPE_MAP[geometryType].upper()))

            self.layer = QgsVectorLayer(uri.uri(), uri.table(), "spatialite")
            self.writer = self.layer.dataProvider()
        else:
            formats = QgsVectorFileWriter.supportedFiltersAndFormats()
            OGRCodes = {}
            for (key, value) in formats.items():
                extension = unicode(key)
                extension = extension[extension.find('*.') + 2:]
                extension = extension[:extension.find(' ')]
                OGRCodes[extension] = value
            OGRCodes['dbf'] = "DBF file"

            extension = self.destination[self.destination.rfind('.') + 1:]

            if extension not in OGRCodes:
                extension = 'shp'
                self.destination = self.destination + '.shp'

            if geometryType == QGis.WKBNoGeometry:
                if extension == 'shp':
                    extension = 'dbf'
                    self.destination = self.destination[:self.destination.
                                                        rfind('.')] + '.dbf'
                if extension not in self.nogeometry_extensions:
                    raise GeoAlgorithmExecutionException(
                        "Unsupported format for tables with no geometry")

            qgsfields = QgsFields()
            for field in fields:
                qgsfields.append(_toQgsField(field))

            self.writer = QgsVectorFileWriter(self.destination, encoding,
                                              qgsfields, geometryType, crs,
                                              OGRCodes[extension])
Exemple #45
0
    def compute(self, bound, xOffset, yOffset, polygon):
        crs = None
        layer = ftools_utils.getMapLayerByName(
            unicode(self.inShape.currentText()))

        if self.angle.value() != 0.0:
            bound = self.initRotation(bound)

        if layer is None:
            crs = self.iface.mapCanvas().mapRenderer().destinationCrs()
        else:
            crs = layer.crs()
        if not crs.isValid(): crs = None

        fields = QgsFields()
        fields.append(QgsField("ID", QVariant.Int))
        fieldCount = 1

        if polygon:
            fields.append(QgsField("X_MIN", QVariant.Double))
            fields.append(QgsField("X_MAX", QVariant.Double))
            fields.append(QgsField("Y_MIN", QVariant.Double))
            fields.append(QgsField("Y_MAX", QVariant.Double))
            fieldCount = 5
            check = QFile(self.shapefileName)
            if check.exists():
                if not QgsVectorFileWriter.deleteShapeFile(self.shapefileName):
                    return
            writer = QgsVectorFileWriter(self.shapefileName, self.encoding,
                                         fields, QGis.WKBPolygon, crs)
        else:
            fields.append(QgsField("COORD", QVariant.Double))
            fieldCount = 2
            check = QFile(self.shapefileName)
            if check.exists():
                if not QgsVectorFileWriter.deleteShapeFile(self.shapefileName):
                    return
            writer = QgsVectorFileWriter(self.shapefileName, self.encoding,
                                         fields, QGis.WKBLineString, crs)
        outFeat = QgsFeature()
        outFeat.initAttributes(fieldCount)
        outFeat.setFields(fields)
        outGeom = QgsGeometry()
        idVar = 0
        self.progressBar.setValue(0)
        if not polygon:
            # counters for progressbar - update every 5%
            count = 0
            count_max = (bound.yMaximum() - bound.yMinimum()) / yOffset
            count_update = count_max * 0.10
            y = bound.yMaximum()
            while y >= bound.yMinimum():
                pt1 = QgsPoint(bound.xMinimum(), y)
                pt2 = QgsPoint(bound.xMaximum(), y)

                if self.angle.value() != 0.0:
                    self.rotatePoint(pt1)
                    self.rotatePoint(pt2)

                line = [pt1, pt2]
                outFeat.setGeometry(outGeom.fromPolyline(line))
                outFeat.setAttribute(0, idVar)
                outFeat.setAttribute(1, y)
                writer.addFeature(outFeat)
                y = y - yOffset
                idVar = idVar + 1
                count += 1
                if int(math.fmod(count, count_update)) == 0:
                    prog = int(count / count_max * 50)
                    self.progressBar.setValue(prog)
            self.progressBar.setValue(50)
            # counters for progressbar - update every 5%
            count = 0
            count_max = (bound.xMaximum() - bound.xMinimum()) / xOffset
            count_update = count_max * 0.10
            x = bound.xMinimum()
            while x <= bound.xMaximum():
                pt1 = QgsPoint(x, bound.yMaximum())
                pt2 = QgsPoint(x, bound.yMinimum())

                if self.angle.value() != 0.0:
                    self.rotatePoint(pt1)
                    self.rotatePoint(pt2)

                line = [pt1, pt2]
                outFeat.setGeometry(outGeom.fromPolyline(line))
                outFeat.setAttribute(0, idVar)
                outFeat.setAttribute(1, x)
                writer.addFeature(outFeat)
                x = x + xOffset
                idVar = idVar + 1
                count += 1
                if int(math.fmod(count, count_update)) == 0:
                    prog = 50 + int(count / count_max * 50)
                    self.progressBar.setValue(prog)
        else:
            # counters for progressbar - update every 5%
            count = 0
            count_max = (bound.yMaximum() - bound.yMinimum()) / yOffset
            count_update = count_max * 0.05
            y = bound.yMaximum()
            while y >= bound.yMinimum():
                x = bound.xMinimum()
                while x <= bound.xMaximum():

                    pt1 = QgsPoint(x, y)
                    pt2 = QgsPoint(x + xOffset, y)
                    pt3 = QgsPoint(x + xOffset, y - yOffset)
                    pt4 = QgsPoint(x, y - yOffset)
                    pt5 = QgsPoint(x, y)

                    if self.angle.value() != 0.0:
                        self.rotatePoint(pt1)
                        self.rotatePoint(pt2)
                        self.rotatePoint(pt3)
                        self.rotatePoint(pt4)
                        self.rotatePoint(pt5)

                    polygon = [[pt1, pt2, pt3, pt4, pt5]]
                    outFeat.setGeometry(outGeom.fromPolygon(polygon))
                    outFeat.setAttribute(0, idVar)
                    outFeat.setAttribute(1, x)
                    outFeat.setAttribute(2, x + xOffset)
                    outFeat.setAttribute(3, y - yOffset)
                    outFeat.setAttribute(4, y)
                    writer.addFeature(outFeat)
                    idVar = idVar + 1
                    x = x + xOffset
                y = y - yOffset
                count += 1
                if int(math.fmod(count, count_update)) == 0:
                    prog = int(count / count_max * 100)

        self.progressBar.setValue(100)
        del writer
Exemple #46
0
 def getSupportedOutputVectorLayerExtensions(self):
     exts = QgsVectorFileWriter.supportedFormatExtensions()
     if not self.hasGeometry():
         exts = ['dbf'] + [ext for ext in exts if ext in NOGEOMETRY_EXTENSIONS]
     return exts
Exemple #47
0
def link_drain(self):
    # Create Scenarios tree inside 
    root = QgsProject.instance().layerTreeRoot()
    
    if not root.findGroup("Scenarios"):
        sm_tree = root.findGroup("SWAT-MODFLOW")
        sm_tree.addGroup("Scenarios")
    if not root.findGroup("Drains to SWAT Channels"):
        scenario_tree = root.findGroup("Scenarios")
        scenario_tree.addGroup("Drains to SWAT Channels")


    try:
        QSWATMOD_path_dict = self.dirs_and_paths()
        self.layer = QgsProject.instance().mapLayersByName("mf_grid (MODFLOW)")[0]
        input1 = QgsProject.instance().mapLayersByName("mf_grid (MODFLOW)")[0]
        provider = self.layer.dataProvider()
        # Find *.drn file and read number of grid cells
        for filename in glob.glob(str(QSWATMOD_path_dict['SMfolder'])+"/*.drn"):
            with open(filename, "r") as f:
                data = []
                for line in f.readlines():
                    if not line.startswith("#"):
                        data.append(line.replace('\n', '').split())
        nDrain = int(data[0][0])
        drn_lyr = []
        drn_row = []
        drn_col = []

        # Skip two lines in Riv package and get row and col
        for i in range(2, nDrain+2):
            drn_lyr.append(int(data[i][0]))
            drn_row.append(int(data[i][1]))
            drn_col.append(int(data[i][2]))

        # Find grid cells according to the drnl package
        feats = self.layer.getFeatures()
        drn_matched = []

        for f in feats:
            rowNo = f.attribute("row")
            colNo = f.attribute("col")
            for i in range(len(drn_row)):
                if ((rowNo == drn_row[i]) and (colNo == drn_col[i])):
                    drn_matched.append(f.id())
        self.layer.selectByIds(drn_matched)

        name_ext = "drain2sub.shp"
        output_dir = QSWATMOD_path_dict['Scenarios']

        # Save just the selected features of the target layer
        drn_chn = os.path.join(output_dir, name_ext)
        QgsVectorFileWriter.writeAsVectorFormat(
            input1, drn_chn,
            "utf-8", input1.crs(), "ESRI Shapefile", 1)

        # Deselect the features
        self.layer.removeSelection()

        # Join sub and drn
        n2_ext = "drain2sub_f.shp"
        drn_chn_f = os.path.join(output_dir, n2_ext)
        # QgsVectorFileWriter.deleteShapeFile(irrig_mf_s)
        sub_shp = QgsProject.instance().mapLayersByName("sub (SWAT)")[0]
        processing.run(
                        "qgis:joinattributesbylocation",
                        drn_chn,
                        sub_shp,
                        ['intersects'],0,0,"sum,mean,min,max,median",0,
                        drn_chn_f)

        # delete unnecessary fields
        layer_drn = QgsVectorLayer(drn_chn_f, '{0}'.format("drain2sub"), 'ogr')
        QgsProject.instance().addMapLayer(layer_drn, False)
        root = QgsProject.instance().layerTreeRoot()
        p_mf_tree = root.findGroup("Drains to SWAT Channels")
        p_mf_tree.insertChildNode(0, QgsLayerTreeLayer(layer_drn))

        input2 = QgsProject.instance().mapLayersByName("drain2sub")[0]
        fields = input2.dataProvider()
        fdname = [
                    fields.indexFromName(field.name()) for field in fields.fields() if not (
                        field.name() == 'Subbasin' or
                        field.name() == 'row' or
                        field.name() == 'col' or
                        field.name() == 'layer')]

        fields.deleteAttributes(fdname)
        input2.updateFields()

        msgBox.setWindowTitle("Created!")
        msgBox.setText("'drain2sub.shp' file has been created!")
        msgBox.exec_()
    except:
        msgBox.setWindowTitle("No Drain package found!")
        msgBox.setText("Please, provide a drain package to your MODFLOW model first!")
 
 
        self.dlg.spinBox_irrig_mf.setEnabled(False)
        self.dlg.pushButton_irrig_mf.setEnabled(False)
        self.dlg.pushButton_irrig_mf_create.setEnabled(False)
        msgBox.exec_()
Exemple #48
0
    def processCommand(self, parameters, context, feedback, delOutputs=False):
        """
        Prepare the GRASS algorithm command
        :param parameters:
        :param context:
        :param delOutputs: do not add outputs to commands.
        """
        noOutputs = [o for o in self.parameterDefinitions() if o not in self.destinationParameterDefinitions()]
        command = '{} '.format(self.grass7Name)
        command += '{}'.join(self.hardcodedStrings)

        # Add algorithm command
        for param in noOutputs:
            paramName = param.name()
            value = None

            # Exclude default GRASS parameters
            if paramName in [self.GRASS_REGION_CELLSIZE_PARAMETER,
                             self.GRASS_REGION_EXTENT_PARAMETER,
                             self.GRASS_MIN_AREA_PARAMETER,
                             self.GRASS_SNAP_TOLERANCE_PARAMETER,
                             self.GRASS_OUTPUT_TYPE_PARAMETER,
                             self.GRASS_REGION_ALIGN_TO_RESOLUTION,
                             self.GRASS_RASTER_FORMAT_OPT,
                             self.GRASS_RASTER_FORMAT_META]:
                continue

            # Raster and vector layers
            if isinstance(param, (QgsProcessingParameterRasterLayer,
                                  QgsProcessingParameterVectorLayer,
                                  QgsProcessingParameterFeatureSource)):
                if paramName in self.exportedLayers:
                    value = self.exportedLayers[paramName]
                else:
                    value = self.parameterAsCompatibleSourceLayerPath(
                        parameters, paramName, context,
                        QgsVectorFileWriter.supportedFormatExtensions()
                    )
            # MultipleLayers
            elif isinstance(param, QgsProcessingParameterMultipleLayers):
                layers = self.parameterAsLayerList(parameters, paramName, context)
                values = []
                for idx in range(len(layers)):
                    layerName = '{}_{}'.format(paramName, idx)
                    values.append(self.exportedLayers[layerName])
                value = ','.join(values)
            # For booleans, we just add the parameter name
            elif isinstance(param, QgsProcessingParameterBoolean):
                if self.parameterAsBool(parameters, paramName, context):
                    command += ' {}'.format(paramName)
            # For Extents, remove if the value is null
            elif isinstance(param, QgsProcessingParameterExtent):
                if self.parameterAsExtent(parameters, paramName, context):
                    value = self.parameterAsString(parameters, paramName, context)
            # For enumeration, we need to grab the string value
            elif isinstance(param, QgsProcessingParameterEnum):
                # Handle multiple values
                if param.allowMultiple():
                    indexes = self.parameterAsEnums(parameters, paramName, context)
                else:
                    indexes = [self.parameterAsEnum(parameters, paramName, context)]
                if indexes:
                    value = '"{}"'.format(','.join([param.options()[i] for i in indexes]))
            # For strings, we just translate as string
            elif isinstance(param, QgsProcessingParameterString):
                data = self.parameterAsString(parameters, paramName, context)
                # if string is empty, we don't add it
                if len(data) > 0:
                    value = '"{}"'.format(
                        self.parameterAsString(parameters, paramName, context)
                    )
            # For fields, we just translate as string
            elif isinstance(param, QgsProcessingParameterField):
                value = ','.join(
                    self.parameterAsFields(parameters, paramName, context)
                )
            elif isinstance(param, QgsProcessingParameterFile):
                if self.parameterAsString(parameters, paramName, context):
                    value = '"{}"'.format(
                        self.parameterAsString(parameters, paramName, context)
                    )
            elif isinstance(param, QgsProcessingParameterPoint):
                if self.parameterAsString(parameters, paramName, context):
                    # parameter specified, evaluate as point
                    # TODO - handle CRS transform
                    point = self.parameterAsPoint(parameters, paramName, context)
                    value = '{},{}'.format(point.x(), point.y())
            # For numbers, we translate as a string
            elif isinstance(param, (QgsProcessingParameterNumber,
                                    QgsProcessingParameterPoint)):
                value = self.parameterAsString(parameters, paramName, context)
            # For everything else, we assume that it is a string
            else:
                value = '"{}"'.format(
                    self.parameterAsString(parameters, paramName, context)
                )
            if value:
                command += ' {}={}'.format(paramName.replace('~', ''), value)

        # Handle outputs
        if not delOutputs:
            for out in self.destinationParameterDefinitions():
                # We exclude hidden parameters
                if out.flags() & QgsProcessingParameterDefinition.FlagHidden:
                    continue
                outName = out.name()
                # For File destination
                if isinstance(out, QgsProcessingParameterFileDestination):
                    # for HTML reports, we need to redirect stdout
                    if out.defaultFileExtension().lower() == 'html':
                        command += ' > "{}"'.format(
                            self.parameterAsFileOutput(
                                parameters, outName, context)
                        )
                    else:
                        command += ' {}="{}"'.format(
                            outName,
                            self.parameterAsFileOutput(
                                parameters, outName, context))
                # For folders destination
                elif isinstance(out, QgsProcessingParameterFolderDestination):
                    # We need to add a unique temporary basename
                    uniqueBasename = outName + self.uniqueSuffix
                    command += ' {}={}'.format(outName, uniqueBasename)
                else:
                    # We add an output name to make sure it is unique if the session
                    # uses this algorithm several times.
                    #value = self.parameterAsOutputLayer(parameters, outName, context)
                    uniqueOutputName = outName + self.uniqueSuffix
                    command += ' {}={}'.format(outName, uniqueOutputName)

                    # Add output file to exported layers, to indicate that
                    # they are present in GRASS
                    self.exportedLayers[outName] = uniqueOutputName

        command += ' --overwrite'
        self.commands.append(command)
        QgsMessageLog.logMessage(self.tr('processCommands end. Commands: {}').format(self.commands), 'Grass7', Qgis.Info)
Exemple #49
0
def link_irrig_mf(self):
    QSWATMOD_path_dict = self.dirs_and_paths()
    self.layer = QgsProject.instance().mapLayersByName("mf_grid (MODFLOW)")[0]
    input1 = QgsProject.instance().mapLayersByName("mf_grid (MODFLOW)")[0]
    provider = self.layer.dataProvider()
    welnum = self.dlg.spinBox_irrig_mf.value()
    # Find *.wel file and read number of grid cells
    try:
        for filename in glob.glob(str(QSWATMOD_path_dict['SMfolder'])+"/*.wel"):
            with open(filename, "r") as f:
                data = []
                for line in f.readlines():
                    if not line.startswith("#"):
                        data.append(line.replace('\n', '').split())
        wel_row = []
        wel_col = []

        # Skip two lines in Riv package and get row and col
        for i in range(2, welnum+2):
            wel_row.append(int(data[i][1]))
            wel_col.append(int(data[i][2]))

        # Find grid cells according to the well package
        feats = self.layer.getFeatures()
        wel_matched = []

        for f in feats:
            rowNo = f.attribute("row")
            colNo = f.attribute("col")
            # rowNo = f.attribute["row"]
            # colNo = f.attribute["col"]
            for i in range(len(wel_row)):
                if ((rowNo == wel_row[i]) and (colNo == wel_col[i])):
                    wel_matched.append(f.id())
        self.layer.selectByIds(wel_matched)

        name = "irrig_mf"
        name_ext = "irrig_mf.shp"
        output_dir = QSWATMOD_path_dict['Scenarios']

        # Save just the selected features of the target layer
        irrig_mf = os.path.join(output_dir, name_ext)

        # QgsVectorFileWriter.deleteShapeFile(irrig_mf)

        QgsVectorFileWriter.writeAsVectorFormat(
            input1, irrig_mf,
            "utf-8", input1.crs(), "ESRI Shapefile", 1)

        # Deselect the features
        self.layer.removeSelection()

        # Join sub and hru id
        n3_ext = "irrig_mf_s.shp"
        irrig_mf_s = os.path.join(output_dir, n3_ext)
        # QgsVectorFileWriter.deleteShapeFile(irrig_mf_s)
        sub_shp = QgsProject.instance().mapLayersByName("sub (SWAT)")[0]
        processing.run(
                        "qgis:joinattributesbylocation",
                        irrig_mf,
                        sub_shp,
                        ['intersects'],0,0,"sum,mean,min,max,median",0,
                        irrig_mf_s)

        # Join sub id
        n4_ext = "irrig_mf_f.shp"
        irrig_mf_f = os.path.join(output_dir, n4_ext)
        # QgsVectorFileWriter.deleteShapeFile(irrig_mf_f)
        hru_shp = QgsProject.instance().mapLayersByName("hru (SWAT)")[0]
        processing.run(
                        "qgis:joinattributesbylocation",
                        irrig_mf_s,
                        hru_shp,
                        ['intersects'],0,0,"sum,mean,min,max,median",0,
                        irrig_mf_f)

        # delete unnecessary fields
        layer_mf = QgsVectorLayer(irrig_mf_f, '{0}'.format("irrig_mf"), 'ogr')
        QgsProject.instance().addMapLayer(layer_mf, False)
        root = QgsProject.instance().layerTreeRoot()
        p_mf_tree = root.findGroup("Pumping from MODFLOW")
        p_mf_tree.insertChildNode(0, QgsLayerTreeLayer(layer_mf))
        input2 = QgsProject.instance().mapLayersByName("irrig_mf")[0]
        fields = input2.dataProvider()
        fdname = [
                fields.indexFromName(field.name()) for field in fields.fields() if not (
                    field.name() == 'Subbasin' or
                    field.name() == 'row' or
                    field.name() == 'col' or
                    field.name() == 'HRU_ID'
                    )
                ]

        fields.deleteAttributes(fdname)
        input2.updateFields()

        msgBox.setWindowTitle("Created!")
        msgBox.setText(
                        "'irrig_mf.shp' file has been created!\n"+
                        "If you have multiple HRUs, open its Attribute table and modify it."
                        )
        msgBox.exec_()
    except:
        msgBox.setWindowTitle("No Well package found!")
        msgBox.setText("Please, provide a well package to your MODFLOW model first!")
        self.dlg.spinBox_irrig_mf.setEnabled(False)
        self.dlg.pushButton_irrig_mf.setEnabled(False)
        self.dlg.pushButton_irrig_mf_create.setEnabled(False)
        msgBox.exec_()
Exemple #50
0
    def run(self):
        """Risk plugin for classified polygon hazard on polygon population.

        Counts population in an area exposed to hazard zones and then
        computes the proportion of each area that is affected.
        The population in each area is then calculated as the proportion
        of the original population to the affected area.

        :returns: Impact layer
        :rtype: Vector
        """
        self.validate()
        self.prepare()

        self.provenance.append_step(
            'Calculating Step',
            'Impact function is calculating the impact.')

        # Identify hazard and exposure layers
        hazard = self.hazard.layer
        exposure = self.exposure.layer

        # prepare objects for re-projection of geometries
        crs_wgs84 = QgsCoordinateReferenceSystem("EPSG:4326")
        hazard_to_exposure = QgsCoordinateTransform(
            hazard.crs(), exposure.crs())
        wgs84_to_hazard = QgsCoordinateTransform(
            crs_wgs84, hazard.crs())
        wgs84_to_exposure = QgsCoordinateTransform(
            crs_wgs84, exposure.crs())

        extent = QgsRectangle(
            self.requested_extent[0], self.requested_extent[1],
            self.requested_extent[2], self.requested_extent[3])
        extent_hazard = wgs84_to_hazard.transformBoundingBox(extent)
        extent_exposure = wgs84_to_exposure.transformBoundingBox(extent)
        extent_exposure_geom = QgsGeometry.fromRect(extent_exposure)

        # make spatial index of hazard
        hazard_index = QgsSpatialIndex()
        hazard_features = {}
        for feature in hazard.getFeatures(QgsFeatureRequest(extent_hazard)):
            feature.geometry().transform(hazard_to_exposure)
            hazard_index.insertFeature(feature)
            hazard_features[feature.id()] = QgsFeature(feature)

        # create impact layer
        filename = unique_filename(suffix='.shp')
        impact_fields = exposure.dataProvider().fields()
        impact_fields.append(QgsField(self.target_field, QVariant.Int))
        unaffected_fields = exposure.dataProvider().fields()
        unaffected_fields.append(QgsField(self.target_field, QVariant.Int))

        writer = QgsVectorFileWriter(
            filename, "utf-8", impact_fields, QGis.WKBPolygon, exposure.crs())

        # Evaluating the impact
        self.evaluate_impact(
            exposure,
            extent_exposure,
            extent_exposure_geom,
            hazard_index,
            hazard_features,
            writer,
            unaffected_fields,
            impact_fields)

        del writer
        impact_layer = QgsVectorLayer(filename, "Impacted People", "ogr")

        # Generate the report of affected populations in the areas
        # To avoid Null
        for value in self.all_areas_population.values():
            if isinstance(value, QPyNullVariant):
                value = 0
            self.total_population += value
        self.areas = self.all_areas_ids
        self.affected_areas = self.all_affected_areas
        self.areas_population = self.all_areas_population

        # Calculating number of people affected
        # This will help area report mixin to know how
        # to calculate the all row values before other
        # rows values in the report table

        self.evaluate_affected_people()

        impact_summary = self.html_report()

        # Define style for the impact layer
        transparent_color = QColor()
        transparent_color.setAlpha(0)

        # Retrieve the classification that is used by the hazard layer.
        vector_hazard_classification = self.hazard.keyword(
            'vector_hazard_classification')
        # Get the dictionary that contains the definition of the classification
        vector_hazard_classification = definition(vector_hazard_classification)
        # Get the list classes in the classification
        vector_hazard_classes = vector_hazard_classification['classes']

        classes = self.hazard_class_mapping

        classes_colours = {}

        color_mapping = {
            'wet': '#F31A1C',
            'low': '#1EFC7C',
            'medium': '#FFA500',
            'high': '#F31A1C'
            }
        classes_values = {
            'wet': 1,
            'low': 1,
            'medium': 2,
            'high': 3
        }
        # Assigning colors
        for vector_hazard_class in vector_hazard_classes:
            key = vector_hazard_class['key']
            if key in classes.keys() and key in color_mapping.keys():
                classes_colours[key] = color_mapping[key]

        # Define style info for output polygons showing population counts
        style_classes = []
        index = 0
        for class_key, colour in classes_colours.items():
            style_class = dict()
            if class_key in classes.keys():
                label = classes[class_key][0]
            else:
                continue
            transparency = 0
            style_class['label'] = label
            style_class['value'] = classes_values[class_key]
            style_class['colour'] = colour
            style_class['transparency'] = transparency
            style_classes.append(style_class)

            index = index + 1

        style_info = dict(
            target_field=self.target_field,
            style_classes=style_classes,
            style_type='categorizedSymbol')

        extra_keywords = {
            'impact_summary': impact_summary,
            'target_field': self.target_field,
            'map_title': tr('Affected People'),
        }

        self.set_if_provenance()

        impact_layer_keywords = self.generate_impact_keywords(extra_keywords)

        # Create vector layer and return
        impact_layer = Vector(
            data=impact_layer,
            name=tr('People affected by each hazard zone'),
            keywords=impact_layer_keywords,
            style_info=style_info)

        self._impact = impact_layer
        return impact_layer
Exemple #51
0
    def calculate(self):
        ''' Prepare environment to run the alg and run it. After run, merge produced 
        data basing on plugin configuration.
        Before calculation a parametere validation will be executed
        '''
        # perform validation
        if not self.gui.validate():
            return
        else:
            # notify successful validation
            message = self.tr(
                "QTraffic: Parameters validation passed successfully")
            iface.messageBar().pushMessage(message, QgsMessageBar.SUCCESS)

        # set number of classes in the project config (that is the temporary one... but equal to the official one)
        fleetDistributionRoadTypes = self.gui.getRoadTypes()
        self.project.setValue('Processing.Parameters/maximum_type',
                              len(fleetDistributionRoadTypes))
        self.project.sync()

        # create the algorithm
        self.alg = Algorithm()
        roadLayer = self.gui.getRoadLayer()

        # prepare layer where to add result
        addToInputLayer = self.gui.addToOriginaLayer_RButton.isChecked()
        newOutputLayer = self.gui.outFile_LEdit.text()

        if addToInputLayer:
            self.outLayer = roadLayer
            self.outLayerId = self.outLayer.id()
        else:
            # if layer is present... remove it
            # out layer would not be the same of input road layer... in thi scase don't remove it
            if self.outLayer and self.outLayer.isValid():
                # to be sure, remove only if roadLayer and outLayer are different
                if self.outLayer.publicSource() != roadLayer.publicSource():
                    self.outLayerRemoved = False
                    QgsMapLayerRegistry.instance().layerRemoved.connect(
                        self.checkOutLayerRemoved)
                    QgsMapLayerRegistry.instance().removeMapLayer(
                        self.outLayer.id())

                    # remove file when it has been removed from qgis
                    while not self.outLayerRemoved:
                        sleep(0.1)
                    QgsMapLayerRegistry.instance().layerRemoved.disconnect(
                        self.checkOutLayerRemoved)

                    # reinit outLayer variables
                    # If not, under windws remain a locking of the related file creating
                    # an error during QgsVectorFileWriter.deleteShapeFile
                    self.outLayer = None
                    self.outLayerId = None

                    if os.path.exists(newOutputLayer):
                        if not QgsVectorFileWriter.deleteShapeFile(
                                newOutputLayer):
                            message = self.tr(
                                "Error removing shape: {}".format(
                                    newOutputLayer))
                            iface.messageBar().pushMessage(
                                message, QgsMessageBar.CRITICAL)
                            return

            # copy input layer to the new one
            writeError = QgsVectorFileWriter.writeAsVectorFormat(
                roadLayer, newOutputLayer, 'utf-8', roadLayer.crs())
            if writeError != QgsVectorFileWriter.NoError:
                message = self.tr(
                    'Error writing vector file {}'.format(newOutputLayer))
                QgsMessageLog.logMessage(message, 'QTraffic',
                                         QgsMessageLog.CRITICAL)
                iface.messageBar().pushCritical('QTraffic', message)
                return

            # load the layer
            newLayerName = os.path.splitext(
                os.path.basename(newOutputLayer))[0]
            self.outLayer = QgsVectorLayer(newOutputLayer, newLayerName, 'ogr')
            if not self.outLayer.isValid():
                message = self.tr(
                    'Error loading vector file {}'.format(newOutputLayer))
                QgsMessageLog.logMessage(message, 'QTraffic',
                                         QgsMessageLog.CRITICAL)
                iface.messageBar().pushCritical('QTraffic', message)
                return

            self.outLayerId = self.outLayer.id()

        # prepare environment
        try:
            self.alg.setProject(self.project)
            self.alg.setLayer(roadLayer)
            self.alg.initConfig()
            self.alg.prepareRun()
        except Exception as ex:
            traceback.print_exc()
            message = self.tr(
                'Error preparing running contex for the algoritm: %s' %
                str(ex))
            QgsMessageLog.logMessage(message, 'QTraffic',
                                     QgsMessageLog.CRITICAL)
            iface.messageBar().pushCritical('QTraffic', message)
            return

        # run the self.alg
        self.thread = QtCore.QThread(self)
        self.thread.started.connect(self.alg.run)
        self.thread.finished.connect(self.threadCleanup)
        self.thread.terminated.connect(self.threadCleanup)

        self.alg.moveToThread(self.thread)
        self.alg.started.connect(self.manageStarted)
        self.alg.progress.connect(self.manageProgress)
        self.alg.message.connect(self.manageMessage)
        self.alg.error.connect(self.manageError)
        self.alg.finished.connect(self.manageFinished)

        # set wait cursor and start
        QgsApplication.instance().setOverrideCursor(QtCore.Qt.WaitCursor)
        self.thread.start()
Exemple #52
0
    def accept(self, *args, **kwargs):
        """Run the processing"""
        try:

            if not self.validate():
                return False

            # disable form via a frame, this will still allow interaction with the message bar
            self.fraMain.setDisabled(True)
            # clean gui and Qgis messagebars
            self.cleanMessageBars(True)

            # Change cursor to Wait cursor
            QtGui.qApp.setOverrideCursor(QtGui.QCursor(QtCore.Qt.WaitCursor))
            self.iface.mainWindow().statusBar().showMessage(
                'Processing {}'.format(self.windowTitle()))
            LOGGER.info('{st}\nProcessing {}'.format(self.windowTitle(),
                                                     st='*' * 50))

            self.send_to_messagebar(
                "Please wait.. QGIS will be locked... See log panel for progress.",
                level=QgsMessageBar.WARNING,
                duration=0,
                addToLog=False,
                core_QGIS=False,
                showLogPanel=True)

            selectedIndices = [
                x.text() for x in self.chkgrpIndices.buttons()
                if x.isChecked()
            ]

            # Add settings to log
            settingsStr = 'Parameters:---------------------------------------'

            settingsStr += '\n    {:20}\t{}'.format(
                'Image layer:',
                self.mcboRasterLayer.currentLayer().name())
            settingsStr += '\n    {:20}\t{}'.format('Image nodata value:',
                                                    self.spnNoDataVal.value())

            if self.chkUsePoly.isChecked():
                if self.chkUseSelected.isChecked():
                    settingsStr += '\n    {:20}\t{} with {} selected features'.format(
                        'Layer:',
                        self.mcboPolygonLayer.currentLayer().name(),
                        len(self.mcboPolygonLayer.currentLayer().
                            selectedFeatures()))
                else:
                    settingsStr += '\n    {:20}\t{}'.format(
                        'Boundary layer:',
                        self.mcboPolygonLayer.currentLayer().name())

                if self.mFieldComboBox.currentField():
                    settingsStr += '\n    {:20}\t{}'.format(
                        'Block ID field:', self.mFieldComboBox.currentField())

            settingsStr += '\n    {:20}\t{}'.format('Resample pixel size: ',
                                                    self.dsbPixelSize.value())

            for k, v in self.band_mapping.iteritems():
                if v > 0:
                    settingsStr += '\n    {:20}\t{}'.format(
                        '{} Band:'.format(k.title()), v)

            settingsStr += '\n    {:20}\t{}'.format('Calculate Indices: ',
                                                    ', '.join(selectedIndices))
            settingsStr += '\n    {:30}\t{}'.format(
                'Output Coordinate System:', self.lblOutCRS.text())
            settingsStr += '\n    {:30}\t{}\n'.format(
                'Output Folder:', self.lneOutputFolder.text())

            LOGGER.info(settingsStr)

            lyrRaster = self.mcboRasterLayer.currentLayer()

            if self.chkUsePoly.isChecked():
                lyrBoundary = self.mcboPolygonLayer.currentLayer()

                if self.chkUseSelected.isChecked():
                    savePlyName = lyrBoundary.name() + '_poly.shp'
                    filePoly = os.path.join(TEMPDIR, savePlyName)
                    if os.path.exists(filePoly): removeFileFromQGIS(filePoly)

                    QgsVectorFileWriter.writeAsVectorFormat(lyrBoundary,
                                                            filePoly,
                                                            "utf-8",
                                                            lyrBoundary.crs(),
                                                            "ESRI Shapefile",
                                                            onlySelected=True)

                    if self.DISP_TEMP_LAYERS:
                        addVectorFileToQGIS(filePoly,
                                            layer_name=os.path.splitext(
                                                os.path.basename(filePoly))[0],
                                            group_layer_name='DEBUG',
                                            atTop=True)
                else:
                    filePoly = lyrBoundary.source()

            files = calc_indices_for_block(
                lyrRaster.source(),
                self.dsbPixelSize.value(),
                self.band_mapping,
                self.lneOutputFolder.text(),
                indices=selectedIndices,
                image_epsg=int(lyrRaster.crs().authid().replace('EPSG:', '')),
                image_nodata=self.spnNoDataVal.value(),
                polygon_shapefile=filePoly
                if self.chkUsePoly.isChecked() else None,
                groupby=self.mFieldComboBox.currentField()
                if self.mFieldComboBox.currentField() else None,
                out_epsg=int(self.outQgsCRS.authid().replace('EPSG:', '')))

            if self.chkAddToDisplay.isChecked():
                for ea_file in files:
                    raster_sym = RASTER_SYMBOLOGY[
                        'Image Indices (ie PCD, NDVI)']
                    raster_lyr = addRasterFileToQGIS(
                        ea_file,
                        atTop=False,
                        group_layer_name=os.path.basename(
                            os.path.dirname(ea_file)))
                    raster_apply_classified_renderer(
                        raster_lyr,
                        rend_type=raster_sym['type'],
                        num_classes=raster_sym['num_classes'],
                        color_ramp=raster_sym['colour_ramp'])

            self.cleanMessageBars(True)
            self.fraMain.setDisabled(False)

            self.iface.mainWindow().statusBar().clearMessage()
            self.iface.messageBar().popWidget()
            QtGui.qApp.restoreOverrideCursor()
            return super(CalculateImageIndicesDialog,
                         self).accept(*args, **kwargs)

        except Exception as err:

            QtGui.qApp.restoreOverrideCursor()
            self.iface.mainWindow().statusBar().clearMessage()
            self.cleanMessageBars(True)
            self.fraMain.setDisabled(False)

            self.send_to_messagebar(str(err),
                                    level=QgsMessageBar.CRITICAL,
                                    duration=0,
                                    addToLog=True,
                                    core_QGIS=False,
                                    showLogPanel=True,
                                    exc_info=sys.exc_info())

            return False  # leave dialog open
Exemple #53
0
    def initialize():
        icon = QgsApplication.getThemeIcon("/processingAlgorithm.svg")
        ProcessingConfig.settingIcons['General'] = icon
        ProcessingConfig.addSetting(
            Setting(
                ProcessingConfig.tr('General'),
                ProcessingConfig.KEEP_DIALOG_OPEN,
                ProcessingConfig.tr(
                    'Keep dialog open after running an algorithm'), True))
        ProcessingConfig.addSetting(
            Setting(
                ProcessingConfig.tr('General'),
                ProcessingConfig.PREFER_FILENAME_AS_LAYER_NAME,
                ProcessingConfig.tr('Prefer output filename for layer names'),
                True))
        ProcessingConfig.addSetting(
            Setting(
                ProcessingConfig.tr('General'),
                ProcessingConfig.SHOW_PROVIDERS_TOOLTIP,
                ProcessingConfig.tr(
                    'Show tooltip when there are disabled providers'), True))
        ProcessingConfig.addSetting(
            Setting(ProcessingConfig.tr('General'),
                    ProcessingConfig.OUTPUT_FOLDER,
                    ProcessingConfig.tr('Output folder'),
                    defaultOutputFolder(),
                    valuetype=Setting.FOLDER))
        ProcessingConfig.addSetting(
            Setting(
                ProcessingConfig.tr('General'), ProcessingConfig.SHOW_CRS_DEF,
                ProcessingConfig.tr(
                    'Show layer CRS definition in selection boxes'), True))
        ProcessingConfig.addSetting(
            Setting(
                ProcessingConfig.tr('General'),
                ProcessingConfig.WARN_UNMATCHING_CRS,
                ProcessingConfig.tr(
                    "Warn before executing if parameter CRS's do not match"),
                True))
        ProcessingConfig.addSetting(
            Setting(ProcessingConfig.tr('General'),
                    ProcessingConfig.SHOW_ALGORITHMS_KNOWN_ISSUES,
                    ProcessingConfig.tr("Show algorithms with known issues"),
                    False))
        ProcessingConfig.addSetting(
            Setting(ProcessingConfig.tr('General'),
                    ProcessingConfig.RASTER_STYLE,
                    ProcessingConfig.tr('Style for raster layers'),
                    '',
                    valuetype=Setting.FILE))
        ProcessingConfig.addSetting(
            Setting(ProcessingConfig.tr('General'),
                    ProcessingConfig.VECTOR_POINT_STYLE,
                    ProcessingConfig.tr('Style for point layers'),
                    '',
                    valuetype=Setting.FILE))
        ProcessingConfig.addSetting(
            Setting(ProcessingConfig.tr('General'),
                    ProcessingConfig.VECTOR_LINE_STYLE,
                    ProcessingConfig.tr('Style for line layers'),
                    '',
                    valuetype=Setting.FILE))
        ProcessingConfig.addSetting(
            Setting(ProcessingConfig.tr('General'),
                    ProcessingConfig.VECTOR_POLYGON_STYLE,
                    ProcessingConfig.tr('Style for polygon layers'),
                    '',
                    valuetype=Setting.FILE))
        ProcessingConfig.addSetting(
            Setting(ProcessingConfig.tr('General'),
                    ProcessingConfig.PRE_EXECUTION_SCRIPT,
                    ProcessingConfig.tr('Pre-execution script'),
                    '',
                    valuetype=Setting.FILE))
        ProcessingConfig.addSetting(
            Setting(ProcessingConfig.tr('General'),
                    ProcessingConfig.POST_EXECUTION_SCRIPT,
                    ProcessingConfig.tr('Post-execution script'),
                    '',
                    valuetype=Setting.FILE))

        invalidFeaturesOptions = [
            ProcessingConfig.tr('Do not filter (better performance)'),
            ProcessingConfig.tr(
                'Skip (ignore) features with invalid geometries'),
            ProcessingConfig.tr(
                'Stop algorithm execution when a geometry is invalid')
        ]
        ProcessingConfig.addSetting(
            Setting(ProcessingConfig.tr('General'),
                    ProcessingConfig.FILTER_INVALID_GEOMETRIES,
                    ProcessingConfig.tr('Invalid features filtering'),
                    invalidFeaturesOptions[2],
                    valuetype=Setting.SELECTION,
                    options=invalidFeaturesOptions))

        threads = QgsApplication.maxThreads(
        )  # if user specified limit for rendering, lets keep that as default here, otherwise max
        threads = cpu_count(
        ) if threads == -1 else threads  # if unset, maxThreads() returns -1
        ProcessingConfig.addSetting(
            Setting(ProcessingConfig.tr('General'),
                    ProcessingConfig.MAX_THREADS,
                    ProcessingConfig.tr('Max Threads'),
                    threads,
                    valuetype=Setting.INT))

        extensions = QgsVectorFileWriter.supportedFormatExtensions()
        ProcessingConfig.addSetting(
            Setting(
                ProcessingConfig.tr('General'),
                ProcessingConfig.DEFAULT_OUTPUT_VECTOR_LAYER_EXT,
                ProcessingConfig.tr('Default output vector layer extension'),
                QgsVectorFileWriter.supportedFormatExtensions()[0],
                valuetype=Setting.SELECTION,
                options=extensions))

        extensions = QgsRasterFileWriter.supportedFormatExtensions()
        ProcessingConfig.addSetting(
            Setting(
                ProcessingConfig.tr('General'),
                ProcessingConfig.DEFAULT_OUTPUT_RASTER_LAYER_EXT,
                ProcessingConfig.tr('Default output raster layer extension'),
                'tif',
                valuetype=Setting.SELECTION,
                options=extensions))

        ProcessingConfig.addSetting(
            Setting(ProcessingConfig.tr('General'),
                    ProcessingConfig.TEMP_PATH,
                    ProcessingConfig.tr('Temporary output folder path'),
                    QgsProcessingUtils.tempFolder(),
                    valuetype=Setting.FOLDER))
Exemple #54
0
 def supportedOutputVectorLayerExtensions(self):
     # We use the same extensions than QGIS because:
     # - QGIS is using OGR like GRASS
     # - There are very chances than OGR version used in GRASS is
     # different from QGIS OGR version.
     return QgsVectorFileWriter.supportedFormatExtensions()
Exemple #55
0
 def recogerRuta(self, event):  # Funcion para cargar las capas que necesitaremos, si no existen se crean
     ruta = QFileDialog.getExistingDirectory(self, 'Selecciona directorio')
     print(ruta)
     file_punto = ruta + '/edit_topo_punto.shp'
     file_linea = ruta + '/edit_topo_linea.shp'
     file_poligono = ruta + '/edit_topo_poligono.shp'
     mensaje = ''
     print(file_linea)
     crs = QgsCoordinateReferenceSystem('EPSG:25830')
     if os.path.isfile(file_punto):
         mensaje = mensaje + 'La capa edit_topo_punto.shp existe' + "\n"
         layer_punto = iface.addVectorLayer(file_punto, "", "ogr")
     else:
         vlpoint = QgsVectorLayer('point', 'edit_topo_punto', 'memory')
         prpoint = vlpoint.dataProvider()
         prpoint.addAttributes([QgsField("id", QVariant.Int),
                                QgsField("clave_top", QVariant.String, len=15),
                                QgsField("elemento", QVariant.String),
                                QgsField("texto_norm", QVariant.String, len=100),
                                QgsField("top_mayor", QVariant.String, len=20),
                                QgsField("globalid", QVariant.String, len=38),
                                QgsField("usuario", QVariant.String, len=100),
                                QgsField("fechaalta", QVariant.String, len=20),
                                QgsField("elemento", QVariant.String, len=1)])
         vlpoint.updateFields()
         msg_point = QgsVectorFileWriter.writeAsVectorFormat(vlpoint, file_punto, 'utf-8', crs,
                                                             driverName="ESRI Shapefile")
         if msg_point[0] != 0:
             print(msg_point)
         else:
             print("El fichero se ha creado correctamente")
             layer_punto = iface.addVectorLayer(file_punto, "", "ogr")
         mensaje = mensaje + 'La capa edit_topo_punto.shp no existe, se ha creado' + "\n"
     if os.path.isfile(file_linea):
         mensaje = mensaje + 'La capa edit_topo_linea.shp existe' + "\n"
         layer_linea = iface.addVectorLayer(file_linea, "", "ogr")
     else:
         vllinea = QgsVectorLayer('line', 'edit_topo_linea', 'memory')
         prlinea = vllinea.dataProvider()
         prlinea.addAttributes([QgsField("id", QVariant.Int),
                                QgsField("clave_top", QVariant.String, len=15),
                                QgsField("elemento", QVariant.String),
                                QgsField("texto_norm", QVariant.String, len=100),
                                QgsField("top_mayor", QVariant.String, len=20),
                                QgsField("globalid", QVariant.String, len=38),
                                QgsField("usuario", QVariant.String, len=100),
                                QgsField("fechaalta", QVariant.String, len=20),
                                QgsField("elemento", QVariant.String, len=1)])
         vllinea.updateFields()
         msg_linea = QgsVectorFileWriter.writeAsVectorFormat(vllinea, file_linea, 'utf-8', crs,
                                                             driverName="ESRI Shapefile")
         if msg_linea[0] != 0:
             print(msg_linea)
         else:
             print("El fichero se ha creado correctamente")
             layer_linea = iface.addVectorLayer(file_linea, "", "ogr")
         mensaje = mensaje + 'La capa edit_topo_linea.shp no existe, se ha creado' + "\n"
     if os.path.isfile(file_poligono):
         mensaje = mensaje + 'La capa edit_topo_poligono.shp existe' + "\n"
         layer_polygon = iface.addVectorLayer(file_poligono, "", "ogr")
     else:
         vlpoly = QgsVectorLayer('polygon', 'edit_topo_poligono', 'memory')
         prpoly = vlpoly.dataProvider()
         prpoly.addAttributes([QgsField("id", QVariant.Int),
                               QgsField("clave_top", QVariant.String, len=15),
                               QgsField("elemento", QVariant.String),
                               QgsField("texto_norm", QVariant.String, len=100),
                               QgsField("top_mayor", QVariant.String, len=20),
                               QgsField("globalid", QVariant.String, len=38),
                               QgsField("usuario", QVariant.String, len=100),
                               QgsField("fechaalta", QVariant.String, len=20),
                               QgsField("elemento", QVariant.String, len=1)])
         vlpoly.updateFields()
         msg_poly = QgsVectorFileWriter.writeAsVectorFormat(vlpoly, file_poligono, 'utf-8', crs,
                                                            driverName="ESRI Shapefile")
         if (msg_poly[0] != 0):
             print(msg_poly)
         else:
             print('El fichero se ha creado correctamente')
             layer_polygon = iface.addVectorLayer(file_poligono, "", "ogr")
         mensaje = mensaje + 'La capa edit_topo_poligono.shp no existe, se ha creado' + "\n"
     QMessageBox.information(self.iface.mainWindow(), 'informacion de capas', mensaje)
     self.txt_ruta.setText('Ruta: ' + ruta)
     dic_path = os.path.dirname(os.path.realpath(__file__)) + '/datos/dic_toponimia.dbf'
     if os.path.isfile(dic_path):
         dic_layer = iface.addVectorLayer(dic_path, "dic_toponimia", "ogr")
         dic_layer.setProviderEncoding(u'Latin1')
         if not dic_layer.isValid():
             print("Layer failed to load!")
         else:
             print("Layer valido")
             self.cbx_uno.setEnabled(True)
             features = dic_layer.getFeatures()
             for feature in features:  # Rellenamos el primer combobox con los elementos de primer nivel toponimico
                 if len(str(feature["clave"])) == 1:
                     self.cbx_uno.addItem(feature["elemento"])
Exemple #56
0
    def ogrConnectionStringAndFormatFromLayer(layer):
        provider = layer.dataProvider().name()
        if provider == 'spatialite':
            # dbname='/geodata/osm_ch.sqlite' table="places" (Geometry) sql=
            regex = re.compile("dbname='(.+)'")
            r = regex.search(str(layer.source()))
            ogrstr = r.groups()[0]
            format = 'SQLite'
        elif provider == 'postgres':
            # dbname='ktryjh_iuuqef' host=spacialdb.com port=9999
            # user='******' password='******' sslmode=disable
            # key='gid' estimatedmetadata=true srid=4326 type=MULTIPOLYGON
            # table="t4" (geom) sql=
            dsUri = QgsDataSourceUri(layer.dataProvider().dataSourceUri())
            conninfo = dsUri.connectionInfo()
            conn = None
            ok = False
            while not conn:
                try:
                    conn = psycopg2.connect(dsUri.connectionInfo())
                except psycopg2.OperationalError:
                    (ok, user, passwd) = QgsCredentials.instance().get(
                        conninfo, dsUri.username(), dsUri.password())
                    if not ok:
                        break

                    dsUri.setUsername(user)
                    dsUri.setPassword(passwd)

            if not conn:
                raise RuntimeError(
                    'Could not connect to PostgreSQL database - check connection info'
                )

            if ok:
                QgsCredentials.instance().put(conninfo, user, passwd)

            ogrstr = "PG:%s" % dsUri.connectionInfo()
            format = 'PostgreSQL'
        elif provider == 'mssql':
            #'dbname=\'db_name\' host=myHost estimatedmetadata=true
            # srid=27700 type=MultiPolygon table="dbo"."my_table"
            # #(Shape) sql='
            dsUri = layer.dataProvider().uri()
            ogrstr = 'MSSQL:'
            ogrstr += 'database={0};'.format(dsUri.database())
            ogrstr += 'server={0};'.format(dsUri.host())
            if dsUri.username() != "":
                ogrstr += 'uid={0};'.format(dsUri.username())
            else:
                ogrstr += 'trusted_connection=yes;'
            if dsUri.password() != '':
                ogrstr += 'pwd={0};'.format(dsUri.password())
            ogrstr += 'tables={0}'.format(dsUri.table())
            format = 'MSSQL'
        elif provider == "oracle":
            # OCI:user/password@host:port/service:table
            dsUri = QgsDataSourceUri(layer.dataProvider().dataSourceUri())
            ogrstr = "OCI:"
            if dsUri.username() != "":
                ogrstr += dsUri.username()
                if dsUri.password() != "":
                    ogrstr += "/" + dsUri.password()
                delim = "@"

            if dsUri.host() != "":
                ogrstr += delim + dsUri.host()
                delim = ""
                if dsUri.port() != "" and dsUri.port() != '1521':
                    ogrstr += ":" + dsUri.port()
                ogrstr += "/"
                if dsUri.database() != "":
                    ogrstr += dsUri.database()
            elif dsUri.database() != "":
                ogrstr += delim + dsUri.database()

            if ogrstr == "OCI:":
                raise RuntimeError(
                    'Invalid oracle data source - check connection info')

            ogrstr += ":"
            if dsUri.schema() != "":
                ogrstr += dsUri.schema() + "."

            ogrstr += dsUri.table()
            format = 'OCI'
        else:
            ogrstr = str(layer.source()).split("|")[0]
            path, ext = os.path.splitext(ogrstr)
            format = QgsVectorFileWriter.driverForExtension(ext)

        return ogrstr, '"' + format + '"'
Exemple #57
0
    def run_blur(self):

        self.progressBar_blur.setValue(0)
        self.label_progress.setText('')

        # Get all the fields.
        layer_to_blur = self.comboBox_layerToBlur.currentLayer()
        radius = self.spinBox_radius.value()
        display = self.checkBox_addToMap.isChecked()
        selected_features_only = self.checkBox_selectedOnlyFeatures.isChecked()
        file_name = self.lineEdit_outputFile.text()
        export_radius = self.checkBox_exportRadius.isChecked()
        export_centroid = self.checkBox_exportCentroid.isChecked()

        if self.checkBox_envelope.isChecked():
            layer_envelope = self.comboBox_envelope.currentLayer()
        else:
            layer_envelope = None

        # Test values
        try:
            if not layer_to_blur:
                raise NoLayerProvidedException

            if not file_name and not display:
                raise NoFileNoDisplayException

            if layer_to_blur.crs().mapUnits() != 0:
                msg = tr('The projection of the map or of the layer is not '
                         'in meters. These parameters should be in meters.')
                display_message_bar(msg,
                                    level=QgsMessageBar.WARNING,
                                    duration=5)

            if not file_name:
                file_name = getTempFilenameInTempFolder('blurring.shp')

            if layer_envelope:

                if layer_to_blur.crs() != layer_envelope.crs():
                    raise DifferentCrsException(
                        epsg1=layer_to_blur.crs().authid(),
                        epsg2=layer_envelope.crs().authid())

                self.label_progress.setText('Creating index ...')
                layer_envelope = LayerIndex(layer_envelope)
                self.progressBar_blur.setValue(0)

            self.label_progress.setText('Blurring ...')

            if selected_features_only:
                features = layer_to_blur.selectedFeatures()
                nb_features = layer_to_blur.selectedFeatureCount()
            else:
                features = layer_to_blur.getFeatures()
                nb_features = layer_to_blur.featureCount()

            # Fields
            fields = layer_to_blur.pendingFields()
            if export_radius:
                fields.append(QgsField(u"Radius", QVariant.Int))
            if export_centroid:
                fields.append(QgsField(u"X centroid", QVariant.Int))
                fields.append(QgsField(u"Y centroid", QVariant.Int))

            # Creating the output shapefile
            file_writer = QgsVectorFileWriter(file_name, 'utf-8', fields,
                                              QGis.WKBPolygon,
                                              layer_to_blur.crs(),
                                              'ESRI Shapefile')

            if file_writer.hasError() != QgsVectorFileWriter.NoError:
                raise CreatingShapeFileException(suffix=file_writer.hasError())

            # Creating the algorithm with radius
            algo = Blur(radius, layer_envelope, export_radius, export_centroid)

            for j, feature in enumerate(features):
                feature = algo.blur(feature)
                file_writer.addFeature(feature)

                # Update progress bar
                percent = int((j + 1) * 100 / nb_features)
                self.progressBar_blur.setValue(percent)

            # Write all features in the file
            del file_writer

            if display:
                old_default_projection = self.settings.value(
                    '/Projections/defaultBehaviour')
                self.settings.setValue('/Projections/defaultBehaviour',
                                       'useProject')

                layer_name = basename(file_name)
                new_layer = QgsVectorLayer(file_name, layer_name, 'ogr')
                new_layer.commitChanges()
                new_layer.clearCacheImage()
                # noinspection PyArgumentList
                QgsMapLayerRegistry.instance().addMapLayers([new_layer])

                self.settings.setValue('/Projections/defaultBehaviour',
                                       old_default_projection)

            msg = tr('Successful export in %s' % file_name)
            iface.messageBar().pushMessage(msg,
                                           level=QgsMessageBar.INFO,
                                           duration=5)

            self.signalAskCloseWindow.emit()

        except GeoHealthException, e:
            self.label_progress.setText('')
            display_message_bar(msg=e.msg, level=e.level, duration=e.duration)
    def testDateTimeWriteShapefile(self):
        """Check writing date and time fields to an ESRI shapefile."""
        ml = QgsVectorLayer(
            ('Point?crs=epsg:4326&field=id:int&'
             'field=date_f:date&field=time_f:time&field=dt_f:datetime'),
            'test', 'memory')

        self.assertTrue(ml.isValid())
        provider = ml.dataProvider()
        self.assertIsNotNone(provider)

        ft = QgsFeature()
        ft.setGeometry(QgsGeometry.fromPointXY(QgsPointXY(10, 10)))
        ft.setAttributes([
            1,
            QDate(2014, 3, 5),
            QTime(13, 45, 22),
            QDateTime(QDate(2014, 3, 5), QTime(13, 45, 22))
        ])
        res, features = provider.addFeatures([ft])
        self.assertTrue(res)
        self.assertTrue(features)

        dest_file_name = os.path.join(str(QDir.tempPath()), 'datetime.shp')
        crs = QgsCoordinateReferenceSystem()
        crs.createFromId(4326, QgsCoordinateReferenceSystem.EpsgCrsId)
        write_result, error_message = QgsVectorFileWriter.writeAsVectorFormat(
            ml, dest_file_name, 'utf-8', crs, 'ESRI Shapefile')
        self.assertEqual(write_result, QgsVectorFileWriter.NoError,
                         error_message)

        # Open result and check
        created_layer = QgsVectorLayer('{}|layerid=0'.format(dest_file_name),
                                       'test', 'ogr')

        fields = created_layer.dataProvider().fields()
        self.assertEqual(
            fields.at(fields.indexFromName('date_f')).type(), QVariant.Date)
        # shapefiles do not support time types, result should be string
        self.assertEqual(
            fields.at(fields.indexFromName('time_f')).type(), QVariant.String)
        # shapefiles do not support datetime types, result should be string
        self.assertEqual(
            fields.at(fields.indexFromName('dt_f')).type(), QVariant.String)

        f = next(created_layer.getFeatures(QgsFeatureRequest()))

        date_idx = created_layer.fields().lookupField('date_f')
        self.assertIsInstance(f.attributes()[date_idx], QDate)
        self.assertEqual(f.attributes()[date_idx], QDate(2014, 3, 5))
        time_idx = created_layer.fields().lookupField('time_f')
        # shapefiles do not support time types
        self.assertIsInstance(f.attributes()[time_idx], str)
        self.assertEqual(f.attributes()[time_idx], '13:45:22')
        # shapefiles do not support datetime types
        datetime_idx = created_layer.fields().lookupField('dt_f')
        self.assertIsInstance(f.attributes()[datetime_idx], str)
        self.assertEqual(
            f.attributes()[datetime_idx],
            QDateTime(QDate(2014, 3, 5),
                      QTime(13, 45, 22)).toString("yyyy/MM/dd hh:mm:ss.zzz"))
Exemple #59
0
    def testWriteShapefileWithZ(self):
        """Check writing geometries with Z dimension to an ESRI shapefile."""

        # start by saving a memory layer and forcing z
        ml = QgsVectorLayer(('Point?crs=epsg:4326&field=id:int'), 'test',
                            'memory')

        self.assertIsNotNone(ml, 'Provider not initialized')
        self.assertTrue(ml.isValid(), 'Source layer not valid')
        provider = ml.dataProvider()
        self.assertIsNotNone(provider)

        ft = QgsFeature()
        ft.setGeometry(QgsGeometry.fromWkt('PointZ (1 2 3)'))
        ft.setAttributes([1])
        res, features = provider.addFeatures([ft])
        self.assertTrue(res)
        self.assertTrue(features)

        # check with both a standard PointZ and 25d style Point25D type
        for t in [QgsWkbTypes.PointZ, QgsWkbTypes.Point25D]:
            dest_file_name = os.path.join(
                str(QDir.tempPath()),
                'point_{}.shp'.format(QgsWkbTypes.displayString(t)))
            crs = QgsCoordinateReferenceSystem()
            crs.createFromId(4326, QgsCoordinateReferenceSystem.EpsgCrsId)
            write_result = QgsVectorFileWriter.writeAsVectorFormat(
                ml,
                dest_file_name,
                'utf-8',
                crs,
                'ESRI Shapefile',
                overrideGeometryType=t)
            self.assertEqual(write_result, QgsVectorFileWriter.NoError)

            # Open result and check
            created_layer = QgsVectorLayer(
                '{}|layerid=0'.format(dest_file_name), 'test', 'ogr')
            f = next(created_layer.getFeatures(QgsFeatureRequest()))
            g = f.geometry()
            wkt = g.exportToWkt()
            expWkt = 'PointZ (1 2 3)'
            self.assertTrue(
                compareWkt(expWkt, wkt),
                "saving geometry with Z failed: mismatch Expected:\n%s\nGot:\n%s\n"
                % (expWkt, wkt))

            # also try saving out the shapefile version again, as an extra test
            # this tests that saving a layer with z WITHOUT explicitly telling the writer to keep z values,
            # will stay retain the z values
            dest_file_name = os.path.join(
                str(QDir.tempPath()),
                'point_{}_copy.shp'.format(QgsWkbTypes.displayString(t)))
            crs = QgsCoordinateReferenceSystem()
            crs.createFromId(4326, QgsCoordinateReferenceSystem.EpsgCrsId)
            write_result = QgsVectorFileWriter.writeAsVectorFormat(
                created_layer, dest_file_name, 'utf-8', crs, 'ESRI Shapefile')
            self.assertEqual(write_result, QgsVectorFileWriter.NoError)

            # Open result and check
            created_layer_from_shp = QgsVectorLayer(
                '{}|layerid=0'.format(dest_file_name), 'test', 'ogr')
            f = next(created_layer_from_shp.getFeatures(QgsFeatureRequest()))
            g = f.geometry()
            wkt = g.exportToWkt()
            self.assertTrue(
                compareWkt(expWkt, wkt),
                "saving geometry with Z failed: mismatch Expected:\n%s\nGot:\n%s\n"
                % (expWkt, wkt))
Exemple #60
0
def _clip_vector_layer(layer,
                       extent,
                       extra_keywords=None,
                       explode_flag=True,
                       hard_clip_flag=False,
                       explode_attribute=None):
    """Clip a Hazard or Exposure layer to the extents provided.

    The layer must be a vector layer or an exception will be thrown.

    The output layer will always be in WGS84/Geographic.

    :param layer: A valid QGIS vector or raster layer
    :type layer:

    :param extent: Either an array representing the exposure layer extents
        in the form [xmin, ymin, xmax, ymax]. It is assumed that the
        coordinates are in EPSG:4326 although currently no checks are made to
        enforce this.
        or:
        A QgsGeometry of type polygon.
        **Polygon clipping is currently only supported for vector datasets.**
    :type extent: list(float, float, float, float)

    :param extra_keywords: Optional keywords dictionary to be added to
        output layer.
    :type extra_keywords: dict

    :param explode_flag: A bool specifying whether multipart features
        should be 'exploded' into singleparts.
        **This parameter is ignored for raster layer clipping.**
    :type explode_flag: bool

    :param hard_clip_flag: A bool specifying whether line and polygon
        features that extend beyond the extents should be clipped such that
        they are reduced in size to the part of the geometry that intersects
        the extent only. Default is False.
        **This parameter is ignored for raster layer clipping.**
    :type hard_clip_flag: bool

    :param explode_attribute: A str specifying to which attribute #1,
        #2 and so on will be added in case of explode_flag being true. The
        attribute is modified only if there are at least 2 parts.
    :type explode_attribute: str

    :returns: Clipped layer (placed in the system temp dir). The output layer
        will be reprojected to EPSG:4326 if needed.
    :rtype: QgsVectorLayer

    """
    if not layer or not extent:
        message = tr('Layer or Extent passed to clip is None.')
        raise InvalidParameterError(message)

    if layer.type() != QgsMapLayer.VectorLayer:
        message = tr('Expected a vector layer but received a %s.' %
                     str(layer.type()))
        raise InvalidParameterError(message)

    #handle, file_name = tempfile.mkstemp('.sqlite', 'clip_',
    #    temp_dir())
    handle, file_name = tempfile.mkstemp('.shp', 'clip_', temp_dir())

    # Ensure the file is deleted before we try to write to it
    # fixes windows specific issue where you get a message like this
    # ERROR 1: c:\temp\inasafe\clip_jpxjnt.shp is not a directory.
    # This is because mkstemp creates the file handle and leaves
    # the file open.
    os.close(handle)
    os.remove(file_name)

    # Get the clip extents in the layer's native CRS
    geo_crs = QgsCoordinateReferenceSystem()
    geo_crs.createFromSrid(4326)
    transform = QgsCoordinateTransform(geo_crs, layer.crs())
    allowed_clip_values = [QGis.WKBPolygon, QGis.WKBPolygon25D]
    if type(extent) is list:
        rectangle = QgsRectangle(extent[0], extent[1], extent[2], extent[3])
        # noinspection PyCallByClass
        #noinspection PyTypeChecker
        polygon = QgsGeometry.fromRect(rectangle)
    elif (type(extent) is QgsGeometry
          and extent.wkbType in allowed_clip_values):
        rectangle = extent.boundingBox().toRectF()
        polygon = extent
    else:
        raise InvalidClipGeometryError(
            tr('Clip geometry must be an extent or a single part'
               'polygon based geometry.'))

    projected_extent = transform.transformBoundingBox(rectangle)

    # Get vector layer
    provider = layer.dataProvider()
    if provider is None:
        message = tr('Could not obtain data provider from '
                     'layer "%s"' % layer.source())
        raise Exception(message)

    # Get the layer field list, select by our extent then write to disk
    # .. todo:: FIXME - for different geometry types we should implement
    #    different clipping behaviour e.g. reject polygons that
    #    intersect the edge of the bbox. Tim
    request = QgsFeatureRequest()
    if not projected_extent.isEmpty():
        request.setFilterRect(projected_extent)
        request.setFlags(QgsFeatureRequest.ExactIntersect)

    field_list = provider.fields()

    writer = QgsVectorFileWriter(
        file_name,
        'UTF-8',
        field_list,
        layer.wkbType(),
        geo_crs,
        #'SQLite')  # FIXME (Ole): This works but is far too slow
        'ESRI Shapefile')
    if writer.hasError() != QgsVectorFileWriter.NoError:
        message = tr('Error when creating shapefile: <br>Filename:'
                     '%s<br>Error: %s' % (file_name, writer.hasError()))
        raise Exception(message)

    # Reverse the coordinate xform now so that we can convert
    # geometries from layer crs to geocrs.
    transform = QgsCoordinateTransform(layer.crs(), geo_crs)
    # Retrieve every feature with its geometry and attributes
    count = 0
    has_multipart = False

    for feature in provider.getFeatures(request):
        geometry = feature.geometry()

        # Loop through the parts adding them to the output file
        # we write out single part features unless explode_flag is False
        if explode_flag:
            geometry_list = explode_multipart_geometry(geometry)
        else:
            geometry_list = [geometry]

        for part_index, part in enumerate(geometry_list):
            part.transform(transform)
            if hard_clip_flag:
                # Remove any dangling bits so only intersecting area is
                # kept.
                part = clip_geometry(polygon, part)
            if part is None:
                continue

            feature.setGeometry(part)
            # There are multiple parts and we want to show it in the
            # explode_attribute
            if part_index > 0 and explode_attribute is not None:
                has_multipart = True

            writer.addFeature(feature)
        count += 1
    del writer  # Flush to disk

    if count < 1:
        message = tr(
            'No features fall within the clip extents. Try panning / zooming '
            'to an area containing data and then try to run your analysis '
            'again. If hazard and exposure data doesn\'t overlap at all, it '
            'is not possible to do an analysis. Another possibility is that '
            'the layers do overlap but because they may have different '
            'spatial references, they appear to be disjointed. If this is the '
            'case, try to turn on reproject on-the-fly in QGIS.')
        raise NoFeaturesInExtentError(message)

    keyword_io = KeywordIO()
    if extra_keywords is None:
        extra_keywords = {}
    extra_keywords['had multipart polygon'] = has_multipart
    keyword_io.copy_keywords(layer, file_name, extra_keywords=extra_keywords)
    base_name = '%s clipped' % layer.name()
    layer = QgsVectorLayer(file_name, base_name, 'ogr')

    return layer