Esempio n. 1
0
    def processAlgorithm(self, progress):
        layer = dataobjects.getObjectFromUri(self.getParameterValue(self.INPUT_VECTOR))

        rasterPath = unicode(self.getParameterValue(self.INPUT_RASTER))

        rasterDS = gdal.Open(rasterPath, gdal.GA_ReadOnly)
        geoTransform = rasterDS.GetGeoTransform()
        rasterDS = None

        fields = QgsFields()
        fields.append(QgsField('id', QVariant.Int, '', 10, 0))
        fields.append(QgsField('line_id', QVariant.Int, '', 10, 0))
        fields.append(QgsField('point_id', QVariant.Int, '', 10, 0))

        writer = self.getOutputFromName(self.OUTPUT_LAYER).getVectorWriter(
            fields.toList(), QgsWkbTypes.Point, layer.crs())

        outFeature = QgsFeature()
        outFeature.setFields(fields)

        self.fid = 0
        self.lineId = 0
        self.pointId = 0

        features = vector.features(layer)
        total = 100.0 / len(features)
        for current, f in enumerate(features):
            geom = f.geometry()
            if geom.isMultipart():
                lines = geom.asMultiPolyline()
                for line in lines:
                    for i in xrange(len(line) - 1):
                        p1 = line[i]
                        p2 = line[i + 1]

                        (x1, y1) = raster.mapToPixel(p1.x(), p1.y(),
                                                     geoTransform)
                        (x2, y2) = raster.mapToPixel(p2.x(), p2.y(),
                                                     geoTransform)

                        self.buildLine(x1, y1, x2, y2, geoTransform,
                                       writer, outFeature)
            else:
                points = geom.asPolyline()
                for i in xrange(len(points) - 1):
                    p1 = points[i]
                    p2 = points[i + 1]

                    (x1, y1) = raster.mapToPixel(p1.x(), p1.y(), geoTransform)
                    (x2, y2) = raster.mapToPixel(p2.x(), p2.y(), geoTransform)

                    self.buildLine(x1, y1, x2, y2, geoTransform, writer,
                                   outFeature)

            self.pointId = 0
            self.lineId += 1

            progress.setPercentage(int(current * total))

        del writer
Esempio n. 2
0
    def processAlgorithm(self, parameters, context, feedback):
        layer = QgsProcessingUtils.mapLayerFromString(self.getParameterValue(self.INPUT_VECTOR), context)

        rasterPath = str(self.getParameterValue(self.INPUT_RASTER))

        rasterDS = gdal.Open(rasterPath, gdal.GA_ReadOnly)
        geoTransform = rasterDS.GetGeoTransform()
        rasterDS = None

        fields = QgsFields()
        fields.append(QgsField('id', QVariant.Int, '', 10, 0))
        fields.append(QgsField('line_id', QVariant.Int, '', 10, 0))
        fields.append(QgsField('point_id', QVariant.Int, '', 10, 0))

        writer = self.getOutputFromName(self.OUTPUT_LAYER).getVectorWriter(fields, QgsWkbTypes.Point,
                                                                           layer.crs(), context)

        outFeature = QgsFeature()
        outFeature.setFields(fields)

        self.fid = 0
        self.lineId = 0
        self.pointId = 0

        features = QgsProcessingUtils.getFeatures(layer, context)
        total = 100.0 / layer.featureCount() if layer.featureCount() else 0
        for current, f in enumerate(features):
            geom = f.geometry()
            if geom.isMultipart():
                lines = geom.asMultiPolyline()
                for line in lines:
                    for i in range(len(line) - 1):
                        p1 = line[i]
                        p2 = line[i + 1]

                        (x1, y1) = raster.mapToPixel(p1.x(), p1.y(),
                                                     geoTransform)
                        (x2, y2) = raster.mapToPixel(p2.x(), p2.y(),
                                                     geoTransform)

                        self.buildLine(x1, y1, x2, y2, geoTransform,
                                       writer, outFeature)
            else:
                points = geom.asPolyline()
                for i in range(len(points) - 1):
                    p1 = points[i]
                    p2 = points[i + 1]

                    (x1, y1) = raster.mapToPixel(p1.x(), p1.y(), geoTransform)
                    (x2, y2) = raster.mapToPixel(p2.x(), p2.y(), geoTransform)

                    self.buildLine(x1, y1, x2, y2, geoTransform, writer,
                                   outFeature)

            self.pointId = 0
            self.lineId += 1

            feedback.setProgress(int(current * total))

        del writer
Esempio n. 3
0
def numpy_stats(band, geometry, geo_transform, no_data, crs):
    """
        :param band: A valid band from a raster layer.
        :type band: GDALRasterBand
        
        :param geometry: A polygon geometry used to calculate statistics.
        :type geometry: QgsGeometry
        
        :param geo_transform: Geo-referencing transform from raster metadata.
        :type geo_transform: list (six floats)
        
        :param no_data: Value for no data in the raster.
        :type no_data: int, float
        
        :param crs: Coordinate reference system of the vector layer.
        :type crs: OGRSpatialReference
        
        :returns: Count, Freq - total number of pixels that intersect with the geometry
        and the frequency distribution of these pixel values.
        :rtype: (int, dict)
        """
    
    mem_drv = ogr.GetDriverByName('Memory')
    driver = gdal.GetDriverByName('MEM')
    
    geom = ogr.CreateGeometryFromWkt(str(geometry.exportToWkt()))
    
    bbox = geometry.boundingBox()
    
    x_min = bbox.xMinimum()
    x_max = bbox.xMaximum()
    y_min = bbox.yMinimum()
    y_max = bbox.yMaximum()
    
    start_column, start_row = mapToPixel(x_min, y_max, geo_transform)
    end_column, end_row = mapToPixel(x_max, y_min, geo_transform)
    
    width = end_column - start_column
    height = end_row - start_row
    
    if width == 0 or height == 0:
        return 0, None

    src_offset = (start_column, start_row, width, height)
Esempio n. 4
0
    def processAlgorithm(self, progress):
        """ Based on code by Matthew Perry
            https://gist.github.com/perrygeo/5667173
        """

        layer = dataobjects.getObjectFromUri(self.getParameterValue(self.INPUT_VECTOR))

        rasterPath = unicode(self.getParameterValue(self.INPUT_RASTER))
        bandNumber = self.getParameterValue(self.RASTER_BAND)
        columnPrefix = self.getParameterValue(self.COLUMN_PREFIX)
        useGlobalExtent = self.getParameterValue(self.GLOBAL_EXTENT)

        rasterDS = gdal.Open(rasterPath, gdal.GA_ReadOnly)
        geoTransform = rasterDS.GetGeoTransform()
        rasterBand = rasterDS.GetRasterBand(bandNumber)
        noData = rasterBand.GetNoDataValue()

        cellXSize = abs(geoTransform[1])
        cellYSize = abs(geoTransform[5])
        rasterXSize = rasterDS.RasterXSize
        rasterYSize = rasterDS.RasterYSize

        rasterBBox = QgsRectangle(geoTransform[0], geoTransform[3] - cellYSize
                                  * rasterYSize, geoTransform[0] + cellXSize
                                  * rasterXSize, geoTransform[3])

        rasterGeom = QgsGeometry.fromRect(rasterBBox)

        crs = osr.SpatialReference()
        crs.ImportFromProj4(str(layer.crs().toProj4()))

        if useGlobalExtent:
            xMin = rasterBBox.xMinimum()
            xMax = rasterBBox.xMaximum()
            yMin = rasterBBox.yMinimum()
            yMax = rasterBBox.yMaximum()

            (startColumn, startRow) = mapToPixel(xMin, yMax, geoTransform)
            (endColumn, endRow) = mapToPixel(xMax, yMin, geoTransform)

            width = endColumn - startColumn
            height = endRow - startRow

            srcOffset = (startColumn, startRow, width, height)
            srcArray = rasterBand.ReadAsArray(*srcOffset)

            newGeoTransform = (
                geoTransform[0] + srcOffset[0] * geoTransform[1],
                geoTransform[1],
                0.0,
                geoTransform[3] + srcOffset[1] * geoTransform[5],
                0.0,
                geoTransform[5],
            )

        memVectorDriver = ogr.GetDriverByName('Memory')
        memRasterDriver = gdal.GetDriverByName('MEM')

        fields = layer.pendingFields()
        (idxMin, fields) = vector.findOrCreateField(layer, fields,
                columnPrefix + 'min', 21, 6)
        (idxMax, fields) = vector.findOrCreateField(layer, fields,
                columnPrefix + 'max', 21, 6)
        (idxSum, fields) = vector.findOrCreateField(layer, fields,
                columnPrefix + 'sum', 21, 6)
        (idxCount, fields) = vector.findOrCreateField(layer, fields,
                columnPrefix + 'count', 21, 6)
        (idxMean, fields) = vector.findOrCreateField(layer, fields,
                columnPrefix + 'mean', 21, 6)
        (idxStd, fields) = vector.findOrCreateField(layer, fields,
                columnPrefix + 'std', 21, 6)
        (idxUnique, fields) = vector.findOrCreateField(layer, fields,
                columnPrefix + 'unique', 21, 6)
        (idxRange, fields) = vector.findOrCreateField(layer, fields,
                columnPrefix + 'range', 21, 6)
        (idxVar, fields) = vector.findOrCreateField(layer, fields, columnPrefix
                + 'var', 21, 6)

        # idxMedian, fields = ftools_utils.findOrCreateField(layer, fields,
        #        columnPrefix + "median", 21, 6)

        writer = self.getOutputFromName(self.OUTPUT_LAYER).getVectorWriter(
            fields.toList(), layer.dataProvider().geometryType(), layer.crs())

        outFeat = QgsFeature()

        outFeat.initAttributes(len(fields))
        outFeat.setFields(fields)

        current = 0
        features = vector.features(layer)
        total = 100.0 / len(features)
        for f in features:
            geom = f.geometry()

            intersectedGeom = rasterGeom.intersection(geom)
            ogrGeom = ogr.CreateGeometryFromWkt(intersectedGeom.exportToWkt())

            if not useGlobalExtent:
                bbox = intersectedGeom.boundingBox()

                xMin = bbox.xMinimum()
                xMax = bbox.xMaximum()
                yMin = bbox.yMinimum()
                yMax = bbox.yMaximum()

                (startColumn, startRow) = mapToPixel(xMin, yMax, geoTransform)
                (endColumn, endRow) = mapToPixel(xMax, yMin, geoTransform)

                width = endColumn - startColumn
                height = endRow - startRow

                if width == 0 or height == 0:
                    continue

                srcOffset = (startColumn, startRow, width, height)
                srcArray = rasterBand.ReadAsArray(*srcOffset)

                newGeoTransform = (
                    geoTransform[0] + srcOffset[0] * geoTransform[1],
                    geoTransform[1],
                    0.0,
                    geoTransform[3] + srcOffset[1] * geoTransform[5],
                    0.0,
                    geoTransform[5],
                )

            # Create a temporary vector layer in memory
            memVDS = memVectorDriver.CreateDataSource('out')
            memLayer = memVDS.CreateLayer('poly', crs, ogr.wkbPolygon)

            ft = ogr.Feature(memLayer.GetLayerDefn())
            ft.SetGeometry(ogrGeom)
            memLayer.CreateFeature(ft)
            ft.Destroy()

            # Rasterize it
            rasterizedDS = memRasterDriver.Create('', srcOffset[2],
                    srcOffset[3], 1, gdal.GDT_Byte)
            rasterizedDS.SetGeoTransform(newGeoTransform)
            gdal.RasterizeLayer(rasterizedDS, [1], memLayer, burn_values=[1])
            rasterizedArray = rasterizedDS.ReadAsArray()

            srcArray = numpy.nan_to_num(srcArray)
            masked = numpy.ma.MaskedArray(srcArray,
                    mask=numpy.logical_or(srcArray == noData,
                    numpy.logical_not(rasterizedArray)))

            outFeat.setGeometry(geom)

            attrs = f.attributes()
            attrs.insert(idxMin, float(masked.min()))
            attrs.insert(idxMax, float(masked.max()))
            attrs.insert(idxSum, float(masked.sum()))
            attrs.insert(idxCount, int(masked.count()))
            attrs.insert(idxMean, float(masked.mean()))
            attrs.insert(idxStd, float(masked.std()))
            attrs.insert(idxUnique, numpy.unique(masked.compressed()).size)
            attrs.insert(idxRange, float(masked.max()) - float(masked.min()))
            attrs.insert(idxVar, float(masked.var()))
            # attrs.insert(idxMedian, float(masked.median()))

            outFeat.setAttributes(attrs)
            writer.addFeature(outFeat)

            memVDS = None
            rasterizedDS = None

            current += 1
            progress.setPercentage(int(current * total))

        rasterDS = None

        del writer
Esempio n. 5
0
    def processAlgorithm(self, progress):
        layer = dataobjects.getObjectFromUri(
                self.getParameterValue(self.INPUT_VECTOR))

        rasterPath = unicode(self.getParameterValue(self.INPUT_RASTER))

        rasterDS = gdal.Open(rasterPath, gdal.GA_ReadOnly)
        geoTransform = rasterDS.GetGeoTransform()
        rasterDS = None

        fields = QgsFields()
        fields.append(QgsField('id', QVariant.Int, '', 10, 0))
        fields.append(QgsField('poly_id', QVariant.Int, '', 10, 0))
        fields.append(QgsField('point_id', QVariant.Int, '', 10, 0))

        writer = self.getOutputFromName(
                self.OUTPUT_LAYER).getVectorWriter(fields.toList(),
                                                   QGis.WKBPoint,
                                                   layer.crs())

        outFeature = QgsFeature()
        outFeature.setFields(fields)
        point = QgsPoint()

        fid = 0
        polyId = 0
        pointId = 0

        current = 0
        features = vector.features(layer)
        total = 100.0 / len(features)
        for f in features:
            geom = f.geometry()
            bbox = geom.boundingBox()

            xMin = bbox.xMinimum()
            xMax = bbox.xMaximum()
            yMin = bbox.yMinimum()
            yMax = bbox.yMaximum()

            (startRow, startColumn) = raster.mapToPixel(xMin, yMax, geoTransform)
            (endRow, endColumn) = raster.mapToPixel(xMax, yMin, geoTransform)

            for row in xrange(startRow, endRow + 1):
                for col in xrange(startColumn, endColumn + 1):
                    (x, y) = raster.pixelToMap(row, col, geoTransform)
                    point.setX(x)
                    point.setY(y)

                    if geom.contains(point):
                        outFeature.setGeometry(QgsGeometry.fromPoint(point))
                        outFeature['id'] = fid
                        outFeature['poly_id'] = polyId
                        outFeature['point_id'] = pointId

                        fid += 1
                        pointId += 1

                        writer.addFeature(outFeature)

            pointId = 0
            polyId += 1

            current += 1
            progress.setPercentage(int(current * total))

        del writer
Esempio n. 6
0
    def processAlgorithm(self, parameters, context, feedback):
        layer = QgsProcessingUtils.mapLayerFromString(self.getParameterValue(self.INPUT_VECTOR), context)

        rasterPath = str(self.getParameterValue(self.INPUT_RASTER))

        rasterDS = gdal.Open(rasterPath, gdal.GA_ReadOnly)
        geoTransform = rasterDS.GetGeoTransform()
        rasterDS = None

        fields = QgsFields()
        fields.append(QgsField('id', QVariant.Int, '', 10, 0))
        fields.append(QgsField('poly_id', QVariant.Int, '', 10, 0))
        fields.append(QgsField('point_id', QVariant.Int, '', 10, 0))

        writer = self.getOutputFromName(self.OUTPUT_LAYER).getVectorWriter(fields, QgsWkbTypes.Point,
                                                                           layer.crs(), context)

        outFeature = QgsFeature()
        outFeature.setFields(fields)

        fid = 0
        polyId = 0
        pointId = 0

        features = QgsProcessingUtils.getFeatures(layer, context)
        total = 100.0 / layer.featureCount() if layer.featureCount() else 0
        for current, f in enumerate(features):
            geom = f.geometry()
            bbox = geom.boundingBox()

            xMin = bbox.xMinimum()
            xMax = bbox.xMaximum()
            yMin = bbox.yMinimum()
            yMax = bbox.yMaximum()

            (startRow, startColumn) = raster.mapToPixel(xMin, yMax, geoTransform)
            (endRow, endColumn) = raster.mapToPixel(xMax, yMin, geoTransform)

            # use prepared geometries for faster intersection tests
            engine = QgsGeometry.createGeometryEngine(geom.geometry())
            engine.prepareGeometry()

            for row in range(startRow, endRow + 1):
                for col in range(startColumn, endColumn + 1):
                    (x, y) = raster.pixelToMap(row, col, geoTransform)
                    point = QgsPointXY()
                    point.setX(x)
                    point.setY(y)

                    if engine.contains(point):
                        outFeature.setGeometry(QgsGeometry(point))
                        outFeature['id'] = fid
                        outFeature['poly_id'] = polyId
                        outFeature['point_id'] = pointId

                        fid += 1
                        pointId += 1

                        writer.addFeature(outFeature, QgsFeatureSink.FastInsert)

            pointId = 0
            polyId += 1

            feedback.setProgress(int(current * total))

        del writer
Esempio n. 7
0
def numpy_stats(band, geometry, geo_transform, no_data, crs):
    """
:param band: A valid band from a raster layer.
:type band: GDALRasterBand

:param geometry: A polygon geometry used to calculate statistics.
:type geometry: QgsGeometry

:param geo_transform: Geo-referencing transform from raster metadata.
:type geo_transform: list (six floats)

:param no_data: Value for no data in the raster.
:type no_data: int, float

:param crs: Coordinate reference system of the vector layer.
:type crs: OGRSpatialReference

:returns: Count, Freq - total number of pixels that intersect with the geometry
and the frequency distribution of these pixel values.
:rtype: (int, dict)
"""

    mem_drv = ogr.GetDriverByName("Memory")
    driver = gdal.GetDriverByName("MEM")

    geom = ogr.CreateGeometryFromWkt(str(geometry.exportToWkt()))

    bbox = geometry.boundingBox()

    x_min = bbox.xMinimum()
    x_max = bbox.xMaximum()
    y_min = bbox.yMinimum()
    y_max = bbox.yMaximum()

    start_column, start_row = mapToPixel(x_min, y_max, geo_transform)
    end_column, end_row = mapToPixel(x_max, y_min, geo_transform)

    width = end_column - start_column
    height = end_row - start_row

    if width == 0 or height == 0:
        return 0, None

    src_offset = (start_column, start_row, width, height)

    new_geo_transform = (
        (geo_transform[0] + (src_offset[0] * geo_transform[1])),
        geo_transform[1],
        0.0,
        (geo_transform[3] + (src_offset[1] * geo_transform[5])),
        0.0,
        geo_transform[5],
    )

    # Create a temporary vector layer in memory
    mem_ds = mem_drv.CreateDataSource("out")
    mem_layer = mem_ds.CreateLayer("poly", crs, ogr.wkbMultiPolygon)

    feat = ogr.Feature(mem_layer.GetLayerDefn())
    feat.SetGeometry(geom)
    mem_layer.CreateFeature(feat)
    feat.Destroy()

    # Rasterize it
    rasterized_ds = driver.Create("", src_offset[2], src_offset[3], 1, gdal.GDT_Byte)
    rasterized_ds.SetGeoTransform(new_geo_transform)
    gdal.RasterizeLayer(rasterized_ds, [1], mem_layer, burn_values=[1])

    # scan the original raster row-by-row to gather statistics
    count = 0
    freq = {}
    for r in range(height):
        src_array = band.ReadAsArray(start_column, r + start_row, width, 1)
        rv_array = rasterized_ds.ReadAsArray(0, r, width, 1)

        # Mask the source data array with our current feature
        # we take the logical_not to flip 0<->1 to get the correct mask effect
        # we also mask out no data values explicitly
        src_array = numpy.nan_to_num(src_array)
        masked = numpy.ma.MaskedArray(
            src_array, mask=numpy.logical_or(src_array == no_data, numpy.logical_not(rv_array))
        )

        # get sorted frequency counts
        compressed = masked.compressed()
        if compressed.any():
            for (k, v) in unique_count(compressed):
                if k in freq:
                    freq[k] = freq[k] + v
                else:
                    freq[k] = v
            count = count + compressed.size
    return count, freq
Esempio n. 8
0
    def processAlgorithm(self, progress):
        rasterPath = self.getParameterValue(self.INPUT_DEM)
        layer = dataobjects.getObjectFromUri(
            self.getParameterValue(self.BOUNDARY_LAYER))
        step = self.getParameterValue(self.STEP)
        percentage = self.getParameterValue(self.USE_PERCENTAGE)

        outputPath = self.getOutputValue(self.OUTPUT_DIRECTORY)

        rasterDS = gdal.Open(rasterPath, gdal.GA_ReadOnly)
        geoTransform = rasterDS.GetGeoTransform()
        rasterBand = rasterDS.GetRasterBand(1)
        noData = rasterBand.GetNoDataValue()

        cellXSize = abs(geoTransform[1])
        cellYSize = abs(geoTransform[5])
        rasterXSize = rasterDS.RasterXSize
        rasterYSize = rasterDS.RasterYSize

        rasterBBox = QgsRectangle(geoTransform[0],
                                  geoTransform[3] - cellYSize * rasterYSize,
                                  geoTransform[0] + cellXSize * rasterXSize,
                                  geoTransform[3])
        rasterGeom = QgsGeometry.fromRect(rasterBBox)

        crs = osr.SpatialReference()
        crs.ImportFromProj4(str(layer.crs().toProj4()))

        memVectorDriver = ogr.GetDriverByName('Memory')
        memRasterDriver = gdal.GetDriverByName('MEM')

        features = vector.features(layer)
        total = 100.0 / len(features)

        for current, f in enumerate(features):
            geom = f.geometry()
            intersectedGeom = rasterGeom.intersection(geom)

            if intersectedGeom.isGeosEmpty():
                progress.setInfo(
                    self.tr('Feature %d does not intersect raster or '
                            'entirely located in NODATA area' % f.id()))
                continue

            fName = os.path.join(
                outputPath, 'hystogram_%s_%s.csv' % (layer.name(), f.id()))

            ogrGeom = ogr.CreateGeometryFromWkt(intersectedGeom.exportToWkt())
            bbox = intersectedGeom.boundingBox()
            xMin = bbox.xMinimum()
            xMax = bbox.xMaximum()
            yMin = bbox.yMinimum()
            yMax = bbox.yMaximum()

            (startColumn,
             startRow) = raster.mapToPixel(xMin, yMax, geoTransform)
            (endColumn, endRow) = raster.mapToPixel(xMax, yMin, geoTransform)

            width = endColumn - startColumn
            height = endRow - startRow

            srcOffset = (startColumn, startRow, width, height)
            srcArray = rasterBand.ReadAsArray(*srcOffset)

            if srcOffset[2] == 0 or srcOffset[3] == 0:
                progress.setInfo(
                    self.tr('Feature %d is smaller than raster '
                            'cell size' % f.id()))
                continue

            newGeoTransform = (geoTransform[0] +
                               srcOffset[0] * geoTransform[1], geoTransform[1],
                               0.0, geoTransform[3] +
                               srcOffset[1] * geoTransform[5], 0.0,
                               geoTransform[5])

            memVDS = memVectorDriver.CreateDataSource('out')
            memLayer = memVDS.CreateLayer('poly', crs, ogr.wkbPolygon)

            ft = ogr.Feature(memLayer.GetLayerDefn())
            ft.SetGeometry(ogrGeom)
            memLayer.CreateFeature(ft)
            ft.Destroy()

            rasterizedDS = memRasterDriver.Create('', srcOffset[2],
                                                  srcOffset[3], 1,
                                                  gdal.GDT_Byte)
            rasterizedDS.SetGeoTransform(newGeoTransform)
            gdal.RasterizeLayer(rasterizedDS, [1], memLayer, burn_values=[1])
            rasterizedArray = rasterizedDS.ReadAsArray()

            srcArray = numpy.nan_to_num(srcArray)
            masked = numpy.ma.MaskedArray(
                srcArray,
                mask=numpy.logical_or(srcArray == noData,
                                      numpy.logical_not(rasterizedArray)))

            self.calculateHypsometry(f.id(), fName, progress, masked,
                                     cellXSize, cellYSize, percentage, step)

            memVDS = None
            rasterizedDS = None
            progress.setPercentage(int(current * total))

        rasterDS = None
Esempio n. 9
0
    def processAlgorithm(self, parameters, context, feedback):
        raster_layer = self.parameterAsRasterLayer(parameters, self.INPUT_DEM, context)
        target_crs = raster_layer.crs()
        rasterPath = raster_layer.source()

        source = self.parameterAsSource(parameters, self.BOUNDARY_LAYER, context)
        if source is None:
            raise QgsProcessingException(self.invalidSourceError(parameters, self.BOUNDARY_LAYER))

        step = self.parameterAsDouble(parameters, self.STEP, context)
        percentage = self.parameterAsBool(parameters, self.USE_PERCENTAGE, context)

        outputPath = self.parameterAsString(parameters, self.OUTPUT_DIRECTORY, context)

        rasterDS = gdal.Open(rasterPath, gdal.GA_ReadOnly)
        geoTransform = rasterDS.GetGeoTransform()
        rasterBand = rasterDS.GetRasterBand(1)
        noData = rasterBand.GetNoDataValue()

        cellXSize = abs(geoTransform[1])
        cellYSize = abs(geoTransform[5])
        rasterXSize = rasterDS.RasterXSize
        rasterYSize = rasterDS.RasterYSize

        rasterBBox = QgsRectangle(geoTransform[0],
                                  geoTransform[3] - cellYSize * rasterYSize,
                                  geoTransform[0] + cellXSize * rasterXSize,
                                  geoTransform[3])
        rasterGeom = QgsGeometry.fromRect(rasterBBox)

        crs = osr.SpatialReference()
        crs.ImportFromProj4(str(target_crs.toProj4()))

        memVectorDriver = ogr.GetDriverByName('Memory')
        memRasterDriver = gdal.GetDriverByName('MEM')

        features = source.getFeatures(QgsFeatureRequest().setDestinationCrs(target_crs, context.transformContext()))
        total = 100.0 / source.featureCount() if source.featureCount() else 0

        for current, f in enumerate(features):
            if not f.hasGeometry():
                continue

            if feedback.isCanceled():
                break

            geom = f.geometry()
            intersectedGeom = rasterGeom.intersection(geom)

            if intersectedGeom.isEmpty():
                feedback.pushInfo(
                    self.tr('Feature {0} does not intersect raster or '
                            'entirely located in NODATA area').format(f.id()))
                continue

            fName = os.path.join(
                outputPath, 'hystogram_%s_%s.csv' % (source.sourceName(), f.id()))

            ogrGeom = ogr.CreateGeometryFromWkt(intersectedGeom.asWkt())
            bbox = intersectedGeom.boundingBox()
            xMin = bbox.xMinimum()
            xMax = bbox.xMaximum()
            yMin = bbox.yMinimum()
            yMax = bbox.yMaximum()

            (startColumn, startRow) = raster.mapToPixel(xMin, yMax, geoTransform)
            (endColumn, endRow) = raster.mapToPixel(xMax, yMin, geoTransform)

            width = endColumn - startColumn
            height = endRow - startRow

            srcOffset = (startColumn, startRow, width, height)
            srcArray = rasterBand.ReadAsArray(*srcOffset)

            if srcOffset[2] == 0 or srcOffset[3] == 0:
                feedback.pushInfo(
                    self.tr('Feature {0} is smaller than raster '
                            'cell size').format(f.id()))
                continue

            newGeoTransform = (
                geoTransform[0] + srcOffset[0] * geoTransform[1],
                geoTransform[1],
                0.0,
                geoTransform[3] + srcOffset[1] * geoTransform[5],
                0.0,
                geoTransform[5]
            )

            memVDS = memVectorDriver.CreateDataSource('out')
            memLayer = memVDS.CreateLayer('poly', crs, ogr.wkbPolygon)

            ft = ogr.Feature(memLayer.GetLayerDefn())
            ft.SetGeometry(ogrGeom)
            memLayer.CreateFeature(ft)
            ft.Destroy()

            rasterizedDS = memRasterDriver.Create('', srcOffset[2],
                                                  srcOffset[3], 1, gdal.GDT_Byte)
            rasterizedDS.SetGeoTransform(newGeoTransform)
            gdal.RasterizeLayer(rasterizedDS, [1], memLayer, burn_values=[1])
            rasterizedArray = rasterizedDS.ReadAsArray()

            srcArray = numpy.nan_to_num(srcArray)
            masked = numpy.ma.MaskedArray(srcArray,
                                          mask=numpy.logical_or(srcArray == noData,
                                                                numpy.logical_not(rasterizedArray)))

            self.calculateHypsometry(f.id(), fName, feedback, masked,
                                     cellXSize, cellYSize, percentage, step)

            memVDS = None
            rasterizedDS = None
            feedback.setProgress(int(current * total))

        rasterDS = None

        return {self.OUTPUT_DIRECTORY: outputPath}
Esempio n. 10
0
    def processAlgorithm(self, parameters, context, feedback):
        source = self.parameterAsSource(parameters, self.INPUT_VECTOR, context)

        raster_layer = self.parameterAsRasterLayer(parameters,
                                                   self.INPUT_RASTER, context)
        rasterPath = exportRasterLayer(raster_layer)

        rasterDS = gdal.Open(rasterPath, gdal.GA_ReadOnly)
        geoTransform = rasterDS.GetGeoTransform()

        fields = QgsFields()
        fields.append(QgsField('id', QVariant.Int, '', 10, 0))
        fields.append(QgsField('poly_id', QVariant.Int, '', 10, 0))
        fields.append(QgsField('point_id', QVariant.Int, '', 10, 0))

        (sink, dest_id) = self.parameterAsSink(parameters, self.OUTPUT,
                                               context, fields,
                                               QgsWkbTypes.Point,
                                               raster_layer.crs())

        outFeature = QgsFeature()
        outFeature.setFields(fields)

        fid = 0
        polyId = 0
        pointId = 0

        features = source.getFeatures(QgsFeatureRequest().setDestinationCrs(
            raster_layer.crs()))
        total = 100.0 / source.featureCount() if source.featureCount() else 0
        for current, f in enumerate(features):
            if feedback.isCanceled():
                break

            if not f.hasGeometry():
                continue

            geom = f.geometry()
            bbox = geom.boundingBox()

            xMin = bbox.xMinimum()
            xMax = bbox.xMaximum()
            yMin = bbox.yMinimum()
            yMax = bbox.yMaximum()

            (startRow,
             startColumn) = raster.mapToPixel(xMin, yMax, geoTransform)
            (endRow, endColumn) = raster.mapToPixel(xMax, yMin, geoTransform)

            # use prepared geometries for faster intersection tests
            engine = QgsGeometry.createGeometryEngine(geom.constGet())
            engine.prepareGeometry()

            for row in range(startRow, endRow + 1):
                for col in range(startColumn, endColumn + 1):
                    if feedback.isCanceled():
                        break

                    (x, y) = raster.pixelToMap(row, col, geoTransform)
                    point = QgsPoint(x, y)

                    if engine.contains(point):
                        outFeature.setGeometry(QgsGeometry(point))
                        outFeature['id'] = fid
                        outFeature['poly_id'] = polyId
                        outFeature['point_id'] = pointId

                        fid += 1
                        pointId += 1

                        sink.addFeature(outFeature, QgsFeatureSink.FastInsert)

            pointId = 0
            polyId += 1

            feedback.setProgress(int(current * total))

        return {self.OUTPUT: dest_id}
Esempio n. 11
0
    def processAlgorithm(self, parameters, context, feedback):
        source = self.parameterAsSource(parameters, self.INPUT_VECTOR, context)
        if source is None:
            raise QgsProcessingException(self.invalidSourceError(parameters, self.INPUT_VECTOR))

        raster_layer = self.parameterAsRasterLayer(parameters, self.INPUT_RASTER, context)
        rasterPath = raster_layer.source()

        rasterDS = gdal.Open(rasterPath, gdal.GA_ReadOnly)
        geoTransform = rasterDS.GetGeoTransform()
        rasterDS = None

        fields = QgsFields()
        fields.append(QgsField('id', QVariant.Int, '', 10, 0))
        fields.append(QgsField('line_id', QVariant.Int, '', 10, 0))
        fields.append(QgsField('point_id', QVariant.Int, '', 10, 0))

        (sink, dest_id) = self.parameterAsSink(parameters, self.OUTPUT, context,
                                               fields, QgsWkbTypes.Point, raster_layer.crs())
        if sink is None:
            raise QgsProcessingException(self.invalidSinkError(parameters, self.OUTPUT))

        outFeature = QgsFeature()
        outFeature.setFields(fields)

        self.fid = 0
        self.lineId = 0
        self.pointId = 0

        features = source.getFeatures(QgsFeatureRequest().setDestinationCrs(raster_layer.crs(), context.transformContext()))
        total = 100.0 / source.featureCount() if source.featureCount() else 0
        for current, f in enumerate(features):
            if feedback.isCanceled():
                break
            geom = f.geometry()
            if geom.isMultipart():
                lines = geom.asMultiPolyline()
                for line in lines:
                    for i in range(len(line) - 1):
                        p1 = line[i]
                        p2 = line[i + 1]

                        (x1, y1) = raster.mapToPixel(p1.x(), p1.y(),
                                                     geoTransform)
                        (x2, y2) = raster.mapToPixel(p2.x(), p2.y(),
                                                     geoTransform)

                        self.buildLine(x1, y1, x2, y2, geoTransform,
                                       sink, outFeature)
            else:
                points = geom.asPolyline()
                for i in range(len(points) - 1):
                    p1 = points[i]
                    p2 = points[i + 1]

                    (x1, y1) = raster.mapToPixel(p1.x(), p1.y(), geoTransform)
                    (x2, y2) = raster.mapToPixel(p2.x(), p2.y(), geoTransform)

                    self.buildLine(x1, y1, x2, y2, geoTransform, sink,
                                   outFeature)

            self.pointId = 0
            self.lineId += 1

            feedback.setProgress(int(current * total))

        return {self.OUTPUT: dest_id}
Esempio n. 12
0
    def processAlgorithm(self, parameters, context, feedback):
        raster_layer = self.parameterAsRasterLayer(parameters, self.INPUT_DEM,
                                                   context)
        target_crs = raster_layer.crs()
        rasterPath = raster_layer.source()

        source = self.parameterAsSource(parameters, self.BOUNDARY_LAYER,
                                        context)
        step = self.parameterAsDouble(parameters, self.STEP, context)
        percentage = self.parameterAsBool(parameters, self.USE_PERCENTAGE,
                                          context)

        outputPath = self.parameterAsString(parameters, self.OUTPUT_DIRECTORY,
                                            context)

        rasterDS = gdal.Open(rasterPath, gdal.GA_ReadOnly)
        geoTransform = rasterDS.GetGeoTransform()
        rasterBand = rasterDS.GetRasterBand(1)
        noData = rasterBand.GetNoDataValue()

        cellXSize = abs(geoTransform[1])
        cellYSize = abs(geoTransform[5])
        rasterXSize = rasterDS.RasterXSize
        rasterYSize = rasterDS.RasterYSize

        rasterBBox = QgsRectangle(geoTransform[0],
                                  geoTransform[3] - cellYSize * rasterYSize,
                                  geoTransform[0] + cellXSize * rasterXSize,
                                  geoTransform[3])
        rasterGeom = QgsGeometry.fromRect(rasterBBox)

        crs = osr.SpatialReference()
        crs.ImportFromProj4(str(target_crs.toProj4()))

        memVectorDriver = ogr.GetDriverByName('Memory')
        memRasterDriver = gdal.GetDriverByName('MEM')

        features = source.getFeatures(QgsFeatureRequest().setDestinationCrs(
            target_crs, context.transformContext()))
        total = 100.0 / source.featureCount() if source.featureCount() else 0

        for current, f in enumerate(features):
            if not f.hasGeometry():
                continue

            if feedback.isCanceled():
                break

            geom = f.geometry()
            intersectedGeom = rasterGeom.intersection(geom)

            if intersectedGeom.isEmpty():
                feedback.pushInfo(
                    self.tr('Feature {0} does not intersect raster or '
                            'entirely located in NODATA area').format(f.id()))
                continue

            fName = os.path.join(
                outputPath,
                'hystogram_%s_%s.csv' % (source.sourceName(), f.id()))

            ogrGeom = ogr.CreateGeometryFromWkt(intersectedGeom.asWkt())
            bbox = intersectedGeom.boundingBox()
            xMin = bbox.xMinimum()
            xMax = bbox.xMaximum()
            yMin = bbox.yMinimum()
            yMax = bbox.yMaximum()

            (startColumn,
             startRow) = raster.mapToPixel(xMin, yMax, geoTransform)
            (endColumn, endRow) = raster.mapToPixel(xMax, yMin, geoTransform)

            width = endColumn - startColumn
            height = endRow - startRow

            srcOffset = (startColumn, startRow, width, height)
            srcArray = rasterBand.ReadAsArray(*srcOffset)

            if srcOffset[2] == 0 or srcOffset[3] == 0:
                feedback.pushInfo(
                    self.tr('Feature {0} is smaller than raster '
                            'cell size').format(f.id()))
                continue

            newGeoTransform = (geoTransform[0] +
                               srcOffset[0] * geoTransform[1], geoTransform[1],
                               0.0, geoTransform[3] +
                               srcOffset[1] * geoTransform[5], 0.0,
                               geoTransform[5])

            memVDS = memVectorDriver.CreateDataSource('out')
            memLayer = memVDS.CreateLayer('poly', crs, ogr.wkbPolygon)

            ft = ogr.Feature(memLayer.GetLayerDefn())
            ft.SetGeometry(ogrGeom)
            memLayer.CreateFeature(ft)
            ft.Destroy()

            rasterizedDS = memRasterDriver.Create('', srcOffset[2],
                                                  srcOffset[3], 1,
                                                  gdal.GDT_Byte)
            rasterizedDS.SetGeoTransform(newGeoTransform)
            gdal.RasterizeLayer(rasterizedDS, [1], memLayer, burn_values=[1])
            rasterizedArray = rasterizedDS.ReadAsArray()

            srcArray = numpy.nan_to_num(srcArray)
            masked = numpy.ma.MaskedArray(
                srcArray,
                mask=numpy.logical_or(srcArray == noData,
                                      numpy.logical_not(rasterizedArray)))

            self.calculateHypsometry(f.id(), fName, feedback, masked,
                                     cellXSize, cellYSize, percentage, step)

            memVDS = None
            rasterizedDS = None
            feedback.setProgress(int(current * total))

        rasterDS = None

        return {self.OUTPUT_DIRECTORY: outputPath}
Esempio n. 13
0
    def processAlgorithm(self, feedback):
        layer = dataobjects.getLayerFromString(
            self.getParameterValue(self.INPUT_VECTOR))

        rasterPath = str(self.getParameterValue(self.INPUT_RASTER))

        rasterDS = gdal.Open(rasterPath, gdal.GA_ReadOnly)
        geoTransform = rasterDS.GetGeoTransform()
        rasterDS = None

        fields = QgsFields()
        fields.append(QgsField('id', QVariant.Int, '', 10, 0))
        fields.append(QgsField('line_id', QVariant.Int, '', 10, 0))
        fields.append(QgsField('point_id', QVariant.Int, '', 10, 0))

        writer = self.getOutputFromName(self.OUTPUT_LAYER).getVectorWriter(
            fields.toList(), QgsWkbTypes.Point, layer.crs())

        outFeature = QgsFeature()
        outFeature.setFields(fields)

        self.fid = 0
        self.lineId = 0
        self.pointId = 0

        features = vector.features(layer)
        total = 100.0 / len(features)
        for current, f in enumerate(features):
            geom = f.geometry()
            if geom.isMultipart():
                lines = geom.asMultiPolyline()
                for line in lines:
                    for i in range(len(line) - 1):
                        p1 = line[i]
                        p2 = line[i + 1]

                        (x1, y1) = raster.mapToPixel(p1.x(), p1.y(),
                                                     geoTransform)
                        (x2, y2) = raster.mapToPixel(p2.x(), p2.y(),
                                                     geoTransform)

                        self.buildLine(x1, y1, x2, y2, geoTransform, writer,
                                       outFeature)
            else:
                points = geom.asPolyline()
                for i in range(len(points) - 1):
                    p1 = points[i]
                    p2 = points[i + 1]

                    (x1, y1) = raster.mapToPixel(p1.x(), p1.y(), geoTransform)
                    (x2, y2) = raster.mapToPixel(p2.x(), p2.y(), geoTransform)

                    self.buildLine(x1, y1, x2, y2, geoTransform, writer,
                                   outFeature)

            self.pointId = 0
            self.lineId += 1

            feedback.setProgress(int(current * total))

        del writer
Esempio n. 14
0
    def processAlgorithm(self, progress):
        """ Based on code by Matthew Perry
            https://gist.github.com/perrygeo/5667173
        """

        layer = dataobjects.getObjectFromUri(
            self.getParameterValue(self.INPUT_VECTOR))

        rasterPath = str(self.getParameterValue(self.INPUT_RASTER))
        bandNumber = self.getParameterValue(self.RASTER_BAND)
        columnPrefix = self.getParameterValue(self.COLUMN_PREFIX)
        useGlobalExtent = self.getParameterValue(self.GLOBAL_EXTENT)

        rasterDS = gdal.Open(rasterPath, gdal.GA_ReadOnly)
        geoTransform = rasterDS.GetGeoTransform()
        rasterBand = rasterDS.GetRasterBand(bandNumber)
        noData = rasterBand.GetNoDataValue()

        cellXSize = abs(geoTransform[1])
        cellYSize = abs(geoTransform[5])
        rasterXSize = rasterDS.RasterXSize
        rasterYSize = rasterDS.RasterYSize

        rasterBBox = QgsRectangle(geoTransform[0],
                                  geoTransform[3] - cellYSize * rasterYSize,
                                  geoTransform[0] + cellXSize * rasterXSize,
                                  geoTransform[3])

        rasterGeom = QgsGeometry.fromRect(rasterBBox)

        crs = osr.SpatialReference()
        crs.ImportFromProj4(str(layer.crs().toProj4()))

        if useGlobalExtent:
            xMin = rasterBBox.xMinimum()
            xMax = rasterBBox.xMaximum()
            yMin = rasterBBox.yMinimum()
            yMax = rasterBBox.yMaximum()

            (startColumn, startRow) = mapToPixel(xMin, yMax, geoTransform)
            (endColumn, endRow) = mapToPixel(xMax, yMin, geoTransform)

            width = endColumn - startColumn
            height = endRow - startRow

            srcOffset = (startColumn, startRow, width, height)
            srcArray = rasterBand.ReadAsArray(*srcOffset)
            srcArray = srcArray * rasterBand.GetScale() + rasterBand.GetOffset(
            )

            newGeoTransform = (
                geoTransform[0] + srcOffset[0] * geoTransform[1],
                geoTransform[1],
                0.0,
                geoTransform[3] + srcOffset[1] * geoTransform[5],
                0.0,
                geoTransform[5],
            )

        memVectorDriver = ogr.GetDriverByName('Memory')
        memRasterDriver = gdal.GetDriverByName('MEM')

        fields = layer.fields()
        (idxMin, fields) = vector.findOrCreateField(layer, fields,
                                                    columnPrefix + 'min', 21,
                                                    6)
        (idxMax, fields) = vector.findOrCreateField(layer, fields,
                                                    columnPrefix + 'max', 21,
                                                    6)
        (idxSum, fields) = vector.findOrCreateField(layer, fields,
                                                    columnPrefix + 'sum', 21,
                                                    6)
        (idxCount, fields) = vector.findOrCreateField(layer, fields,
                                                      columnPrefix + 'count',
                                                      21, 6)
        (idxMean, fields) = vector.findOrCreateField(layer, fields,
                                                     columnPrefix + 'mean', 21,
                                                     6)
        (idxStd, fields) = vector.findOrCreateField(layer, fields,
                                                    columnPrefix + 'std', 21,
                                                    6)
        (idxUnique, fields) = vector.findOrCreateField(layer, fields,
                                                       columnPrefix + 'unique',
                                                       21, 6)
        (idxRange, fields) = vector.findOrCreateField(layer, fields,
                                                      columnPrefix + 'range',
                                                      21, 6)
        (idxVar, fields) = vector.findOrCreateField(layer, fields,
                                                    columnPrefix + 'var', 21,
                                                    6)
        (idxMedian, fields) = vector.findOrCreateField(layer, fields,
                                                       columnPrefix + 'median',
                                                       21, 6)
        if hasSciPy:
            (idxMode,
             fields) = vector.findOrCreateField(layer, fields,
                                                columnPrefix + 'mode', 21, 6)

        writer = self.getOutputFromName(self.OUTPUT_LAYER).getVectorWriter(
            fields.toList(), layer.wkbType(), layer.crs())

        outFeat = QgsFeature()

        outFeat.initAttributes(len(fields))
        outFeat.setFields(fields)

        features = vector.features(layer)
        total = 100.0 / len(features)
        for current, f in enumerate(features):
            geom = f.geometry()

            intersectedGeom = rasterGeom.intersection(geom)
            ogrGeom = ogr.CreateGeometryFromWkt(intersectedGeom.exportToWkt())

            if not useGlobalExtent:
                bbox = intersectedGeom.boundingBox()

                xMin = bbox.xMinimum()
                xMax = bbox.xMaximum()
                yMin = bbox.yMinimum()
                yMax = bbox.yMaximum()

                (startColumn, startRow) = mapToPixel(xMin, yMax, geoTransform)
                (endColumn, endRow) = mapToPixel(xMax, yMin, geoTransform)

                width = endColumn - startColumn
                height = endRow - startRow

                if width == 0 or height == 0:
                    continue

                srcOffset = (startColumn, startRow, width, height)
                srcArray = rasterBand.ReadAsArray(*srcOffset)
                srcArray = srcArray * rasterBand.GetScale(
                ) + rasterBand.GetOffset()

                newGeoTransform = (
                    geoTransform[0] + srcOffset[0] * geoTransform[1],
                    geoTransform[1],
                    0.0,
                    geoTransform[3] + srcOffset[1] * geoTransform[5],
                    0.0,
                    geoTransform[5],
                )

            # Create a temporary vector layer in memory
            memVDS = memVectorDriver.CreateDataSource('out')
            memLayer = memVDS.CreateLayer('poly', crs, ogr.wkbPolygon)

            ft = ogr.Feature(memLayer.GetLayerDefn())
            ft.SetGeometry(ogrGeom)
            memLayer.CreateFeature(ft)
            ft.Destroy()

            # Rasterize it
            rasterizedDS = memRasterDriver.Create('', srcOffset[2],
                                                  srcOffset[3], 1,
                                                  gdal.GDT_Byte)
            rasterizedDS.SetGeoTransform(newGeoTransform)
            gdal.RasterizeLayer(rasterizedDS, [1], memLayer, burn_values=[1])
            rasterizedArray = rasterizedDS.ReadAsArray()

            srcArray = numpy.nan_to_num(srcArray)
            masked = numpy.ma.MaskedArray(
                srcArray,
                mask=numpy.logical_or(srcArray == noData,
                                      numpy.logical_not(rasterizedArray)))

            outFeat.setGeometry(geom)

            attrs = f.attributes()
            v = float(masked.min())
            attrs.insert(idxMin, None if numpy.isnan(v) else v)
            v = float(masked.max())
            attrs.insert(idxMax, None if numpy.isnan(v) else v)
            v = float(masked.sum())
            attrs.insert(idxSum, None if numpy.isnan(v) else v)
            attrs.insert(idxCount, int(masked.count()))
            v = float(masked.mean())
            attrs.insert(idxMean, None if numpy.isnan(v) else v)
            v = float(masked.std())
            attrs.insert(idxStd, None if numpy.isnan(v) else v)
            attrs.insert(idxUnique, numpy.unique(masked.compressed()).size)
            v = float(masked.max()) - float(masked.min())
            attrs.insert(idxRange, None if numpy.isnan(v) else v)
            v = float(masked.var())
            attrs.insert(idxVar, None if numpy.isnan(v) else v)
            v = float(numpy.ma.median(masked))
            attrs.insert(idxMedian, None if numpy.isnan(v) else v)
            if hasSciPy:
                attrs.insert(idxMode, float(mode(masked, axis=None)[0][0]))

            outFeat.setAttributes(attrs)
            writer.addFeature(outFeat)

            memVDS = None
            rasterizedDS = None

            progress.setPercentage(int(current * total))

        rasterDS = None

        del writer
Esempio n. 15
0
    def processAlgorithm(self, progress):
        layer = dataobjects.getObjectFromUri(
            self.getParameterValue(self.INPUT_VECTOR))

        rasterPath = str(self.getParameterValue(self.INPUT_RASTER))

        rasterDS = gdal.Open(rasterPath, gdal.GA_ReadOnly)
        geoTransform = rasterDS.GetGeoTransform()
        rasterDS = None

        fields = QgsFields()
        fields.append(QgsField('id', QVariant.Int, '', 10, 0))
        fields.append(QgsField('poly_id', QVariant.Int, '', 10, 0))
        fields.append(QgsField('point_id', QVariant.Int, '', 10, 0))

        writer = self.getOutputFromName(self.OUTPUT_LAYER).getVectorWriter(
            fields.toList(), QgsWkbTypes.Point, layer.crs())

        outFeature = QgsFeature()
        outFeature.setFields(fields)

        fid = 0
        polyId = 0
        pointId = 0

        features = vector.features(layer)
        total = 100.0 / len(features)
        for current, f in enumerate(features):
            geom = f.geometry()
            bbox = geom.boundingBox()

            xMin = bbox.xMinimum()
            xMax = bbox.xMaximum()
            yMin = bbox.yMinimum()
            yMax = bbox.yMaximum()

            (startRow,
             startColumn) = raster.mapToPixel(xMin, yMax, geoTransform)
            (endRow, endColumn) = raster.mapToPixel(xMax, yMin, geoTransform)

            # use prepared geometries for faster intersection tests
            engine = QgsGeometry.createGeometryEngine(geom.geometry())
            engine.prepareGeometry()

            for row in range(startRow, endRow + 1):
                for col in range(startColumn, endColumn + 1):
                    (x, y) = raster.pixelToMap(row, col, geoTransform)
                    point = QgsPointV2()
                    point.setX(x)
                    point.setY(y)

                    if engine.contains(point):
                        outFeature.setGeometry(QgsGeometry(point))
                        outFeature['id'] = fid
                        outFeature['poly_id'] = polyId
                        outFeature['point_id'] = pointId

                        fid += 1
                        pointId += 1

                        writer.addFeature(outFeature)

            pointId = 0
            polyId += 1

            progress.setPercentage(int(current * total))

        del writer
Esempio n. 16
0
    def processAlgorithm(self, progress):
        rasterPath = self.getParameterValue(self.INPUT_DEM)
        layer = dataobjects.getObjectFromUri(
            self.getParameterValue(self.BOUNDARY_LAYER))
        step = self.getParameterValue(self.STEP)
        percentage = self.getParameterValue(self.USE_PERCENTAGE)

        outputPath = self.getOutputValue(self.OUTPUT_DIRECTORY)

        rasterDS = gdal.Open(rasterPath, gdal.GA_ReadOnly)
        geoTransform = rasterDS.GetGeoTransform()
        rasterBand = rasterDS.GetRasterBand(1)
        noData = rasterBand.GetNoDataValue()

        cellXSize = abs(geoTransform[1])
        cellYSize = abs(geoTransform[5])
        rasterXSize = rasterDS.RasterXSize
        rasterYSize = rasterDS.RasterYSize

        rasterBBox = QgsRectangle(geoTransform[0], geoTransform[3] - cellYSize
                                  * rasterYSize, geoTransform[0] + cellXSize
                                  * rasterXSize, geoTransform[3])
        rasterGeom = QgsGeometry.fromRect(rasterBBox)

        crs = osr.SpatialReference()
        crs.ImportFromProj4(str(layer.crs().toProj4()))

        memVectorDriver = ogr.GetDriverByName('Memory')
        memRasterDriver = gdal.GetDriverByName('MEM')

        features = vector.features(layer)
        count = len(features)
        total = 100.0 / float(count)

        for count, f in enumerate(features):
            geom = f.geometry()
            intersectedGeom = rasterGeom.intersection(geom)

            if intersectedGeom.isGeosEmpty():
                progress.setInfo(
                    self.tr('Feature %d does not intersect raster or '
                            'entirely located in NODATA area' % f.id()))
                continue

            fName = os.path.join(
                outputPath, 'hystogram_%s_%s.csv' % (layer.name(), f.id()))

            ogrGeom = ogr.CreateGeometryFromWkt(intersectedGeom.exportToWkt())
            bbox = intersectedGeom.boundingBox()
            xMin = bbox.xMinimum()
            xMax = bbox.xMaximum()
            yMin = bbox.yMinimum()
            yMax = bbox.yMaximum()

            (startColumn, startRow) = raster.mapToPixel(xMin, yMax, geoTransform)
            (endColumn, endRow) = raster.mapToPixel(xMax, yMin, geoTransform)

            width = endColumn - startColumn
            height = endRow - startRow

            srcOffset = (startColumn, startRow, width, height)
            srcArray = rasterBand.ReadAsArray(*srcOffset)

            if srcOffset[2] == 0 or srcOffset[3] == 0:
                progress.setInfo(
                    self.tr('Feature %d is smaller than raster '
                            'cell size' % f.id()))
                continue

            newGeoTransform = (
                geoTransform[0] + srcOffset[0] * geoTransform[1],
                geoTransform[1],
                0.0,
                geoTransform[3] + srcOffset[1] * geoTransform[5],
                0.0,
                geoTransform[5]
            )

            memVDS = memVectorDriver.CreateDataSource('out')
            memLayer = memVDS.CreateLayer('poly', crs, ogr.wkbPolygon)

            ft = ogr.Feature(memLayer.GetLayerDefn())
            ft.SetGeometry(ogrGeom)
            memLayer.CreateFeature(ft)
            ft.Destroy()

            rasterizedDS = memRasterDriver.Create('', srcOffset[2],
                srcOffset[3], 1, gdal.GDT_Byte)
            rasterizedDS.SetGeoTransform(newGeoTransform)
            gdal.RasterizeLayer(rasterizedDS, [1], memLayer, burn_values=[1])
            rasterizedArray = rasterizedDS.ReadAsArray()

            srcArray = numpy.nan_to_num(srcArray)
            masked = numpy.ma.MaskedArray(srcArray,
                mask=numpy.logical_or(srcArray == noData,
                    numpy.logical_not(rasterizedArray)))

            self.calculateHypsometry(f.id(), fName, progress, masked,
                cellXSize, cellYSize, percentage, step)

            memVDS = None
            rasterizedDS = None
            progress.setPercentage(int(count * total))

        rasterDS = None
Esempio n. 17
0
    def processAlgorithm(self, parameters, context, feedback):
        source = self.parameterAsSource(parameters, self.INPUT_VECTOR, context)
        if source is None:
            raise QgsProcessingException(self.invalidSourceError(parameters, self.INPUT_VECTOR))

        raster_layer = self.parameterAsRasterLayer(parameters, self.INPUT_RASTER, context)
        rasterPath = raster_layer.source()

        rasterDS = gdal.Open(rasterPath, gdal.GA_ReadOnly)
        geoTransform = rasterDS.GetGeoTransform()
        rasterDS = None

        fields = QgsFields()
        fields.append(QgsField('id', QVariant.Int, '', 10, 0))
        fields.append(QgsField('line_id', QVariant.Int, '', 10, 0))
        fields.append(QgsField('point_id', QVariant.Int, '', 10, 0))

        (sink, dest_id) = self.parameterAsSink(parameters, self.OUTPUT, context,
                                               fields, QgsWkbTypes.Point, raster_layer.crs())
        if sink is None:
            raise QgsProcessingException(self.invalidSinkError(parameters, self.OUTPUT))

        outFeature = QgsFeature()
        outFeature.setFields(fields)

        self.fid = 0
        self.lineId = 0
        self.pointId = 0

        features = source.getFeatures(QgsFeatureRequest().setDestinationCrs(raster_layer.crs(), context.transformContext()))
        total = 100.0 / source.featureCount() if source.featureCount() else 0
        for current, f in enumerate(features):
            if feedback.isCanceled():
                break

            if not f.hasGeometry():
                continue

            geom = f.geometry()
            if geom.isMultipart():
                lines = geom.asMultiPolyline()
                for line in lines:
                    for i in range(len(line) - 1):
                        p1 = line[i]
                        p2 = line[i + 1]

                        (x1, y1) = raster.mapToPixel(p1.x(), p1.y(),
                                                     geoTransform)
                        (x2, y2) = raster.mapToPixel(p2.x(), p2.y(),
                                                     geoTransform)

                        self.buildLine(x1, y1, x2, y2, geoTransform,
                                       sink, outFeature)
            else:
                points = geom.asPolyline()
                for i in range(len(points) - 1):
                    p1 = points[i]
                    p2 = points[i + 1]

                    (x1, y1) = raster.mapToPixel(p1.x(), p1.y(), geoTransform)
                    (x2, y2) = raster.mapToPixel(p2.x(), p2.y(), geoTransform)

                    self.buildLine(x1, y1, x2, y2, geoTransform, sink,
                                   outFeature)

            self.pointId = 0
            self.lineId += 1

            feedback.setProgress(int(current * total))

        return {self.OUTPUT: dest_id}
    rasterBand = raster.GetRasterBand(i + 1)
    data = rasterBand.ReadAsArray()
    layer.ResetReading()
    feature = layer.GetNextFeature()
    while feature is not None:
        current += 1
        progress.setPercentage(int(current * total))

        geometry = feature.GetGeometryRef()
        x = geometry.GetX()
        y = geometry.GetY()
        if Transform_vector_to_raster_CRS:
            pnt = coordTransform.TransformPoint(x, y, 0)
            x = pnt[0]
            y = pnt[1]
        rX, rY = mapToPixel(x, y, geoTransform)
        if rX > rasterXSize or rY > rasterYSize:
            feature = layer.GetNextFeature()
            continue
        value = data[rY, rX]

        feature.SetField(columnName + "_" + str(i + 1), float(value))
        if layer.SetFeature(feature) != 0:
            raise GeoAlgorithmExecutionException("Failed to update feature.")

        feature = layer.GetNextFeature()

    rasterBand = None

raster = None
vector.Destroy()
Esempio n. 19
0
    def processAlgorithm(self, parameters, context, feedback):
        source = self.parameterAsSource(parameters, self.INPUT_VECTOR, context)
        if source is None:
            raise QgsProcessingException(self.invalidSourceError(parameters, self.INPUT_VECTOR))

        raster_layer = self.parameterAsRasterLayer(parameters, self.INPUT_RASTER, context)
        rasterPath = raster_layer.source()

        rasterDS = gdal.Open(rasterPath, gdal.GA_ReadOnly)
        geoTransform = rasterDS.GetGeoTransform()

        fields = QgsFields()
        fields.append(QgsField('id', QVariant.Int, '', 10, 0))
        fields.append(QgsField('poly_id', QVariant.Int, '', 10, 0))
        fields.append(QgsField('point_id', QVariant.Int, '', 10, 0))

        (sink, dest_id) = self.parameterAsSink(parameters, self.OUTPUT, context,
                                               fields, QgsWkbTypes.Point, raster_layer.crs())
        if sink is None:
            raise QgsProcessingException(self.invalidSinkError(parameters, self.OUTPUT))

        outFeature = QgsFeature()
        outFeature.setFields(fields)

        fid = 0
        polyId = 0
        pointId = 0

        features = source.getFeatures(QgsFeatureRequest().setDestinationCrs(raster_layer.crs(), context.transformContext()))
        total = 100.0 / source.featureCount() if source.featureCount() else 0
        for current, f in enumerate(features):
            if feedback.isCanceled():
                break

            if not f.hasGeometry():
                continue

            geom = f.geometry()
            bbox = geom.boundingBox()

            xMin = bbox.xMinimum()
            xMax = bbox.xMaximum()
            yMin = bbox.yMinimum()
            yMax = bbox.yMaximum()

            (startRow, startColumn) = raster.mapToPixel(xMin, yMax, geoTransform)
            (endRow, endColumn) = raster.mapToPixel(xMax, yMin, geoTransform)

            # use prepared geometries for faster intersection tests
            engine = QgsGeometry.createGeometryEngine(geom.constGet())
            engine.prepareGeometry()

            for row in range(startRow, endRow + 1):
                for col in range(startColumn, endColumn + 1):
                    if feedback.isCanceled():
                        break

                    (x, y) = raster.pixelToMap(row, col, geoTransform)
                    point = QgsPoint(x, y)

                    if engine.contains(point):
                        outFeature.setGeometry(QgsGeometry(point))
                        outFeature['id'] = fid
                        outFeature['poly_id'] = polyId
                        outFeature['point_id'] = pointId

                        fid += 1
                        pointId += 1

                        sink.addFeature(outFeature, QgsFeatureSink.FastInsert)

            pointId = 0
            polyId += 1

            feedback.setProgress(int(current * total))

        return {self.OUTPUT: dest_id}
Esempio n. 20
0
def numpy_stats(band, geometry, geo_transform, no_data, crs):
    """
:param band: A valid band from a raster layer.
:type band: GDALRasterBand

:param geometry: A polygon geometry used to calculate statistics.
:type geometry: QgsGeometry

:param geo_transform: Geo-referencing transform from raster metadata.
:type geo_transform: list (six floats)

:param no_data: Value for no data in the raster.
:type no_data: int, float

:param crs: Coordinate reference system of the vector layer.
:type crs: OGRSpatialReference

:returns: Count, Freq - total number of pixels that intersect with the geometry
and the frequency distribution of these pixel values.
:rtype: (int, dict)
"""

    mem_drv = ogr.GetDriverByName('Memory')
    driver = gdal.GetDriverByName('MEM')

    geom = ogr.CreateGeometryFromWkt(str(geometry.exportToWkt()))

    bbox = geometry.boundingBox()

    x_min = bbox.xMinimum()
    x_max = bbox.xMaximum()
    y_min = bbox.yMinimum()
    y_max = bbox.yMaximum()
    
    start_column, start_row = mapToPixel(x_min, y_max, geo_transform)
    end_column, end_row = mapToPixel(x_max, y_min, geo_transform)

    width = end_column - start_column
    height = end_row - start_row

    if width == 0 or height == 0:
        return 0, None

    src_offset = (start_column, start_row, width, height)

    new_geo_transform = (
        (geo_transform[0] + (src_offset[0] * geo_transform[1])),
        geo_transform[1],
        0.0,
        (geo_transform[3] + (src_offset[1] * geo_transform[5])),
        0.0,
        geo_transform[5]
    )

    # Create a temporary vector layer in memory
    mem_ds = mem_drv.CreateDataSource('out')
    mem_layer = mem_ds.CreateLayer('poly', crs, ogr.wkbMultiPolygon)

    feat = ogr.Feature(mem_layer.GetLayerDefn())
    feat.SetGeometry(geom)
    mem_layer.CreateFeature(feat)
    feat.Destroy()

    # Rasterize it
    rasterized_ds = driver.Create('', src_offset[2], src_offset[3], 1, gdal.GDT_Byte)
    rasterized_ds.SetGeoTransform(new_geo_transform)
    gdal.RasterizeLayer(rasterized_ds, [1], mem_layer, burn_values=[1])

    # scan the original raster row-by-row to gather statistics
    count = 0
    freq = {}
    for r in range(height):
        src_array = band.ReadAsArray(start_column, r + start_row, width, 1)
        rv_array = rasterized_ds.ReadAsArray(0, r, width, 1)

        # Mask the source data array with our current feature
        # we take the logical_not to flip 0<->1 to get the correct mask effect
        # we also mask out no data values explicitly
        src_array = numpy.nan_to_num(src_array)
        masked = numpy.ma.MaskedArray(
            src_array,
            mask=numpy.logical_or(
                src_array == no_data,
                numpy.logical_not(rv_array)
            )
        )

        # get sorted frequency counts
        compressed = masked.compressed()
        if compressed.any():
            for (k, v) in unique_count(compressed):
                if k in freq:
                    freq[k] = freq[k] + v
                else:
                    freq[k] = v
            count = count + compressed.size
    return count, freq