예제 #1
0
    def processAlgorithm(self, parameters, context, feedback):
        crs = self.parameterAsCrs(parameters, self.TARGET_CRS, context)
        extent = self.parameterAsExtent(parameters, self.EXTENT, context, crs)
        value = self.parameterAsDouble(parameters, self.NUMBER, context)
        pixelSize = self.parameterAsDouble(parameters, self.PIXEL_SIZE, context)

        outputFile = self.parameterAsOutputLayer(parameters, self.OUTPUT, context)
        outputFormat = QgsRasterFileWriter.driverForExtension(os.path.splitext(outputFile)[1])

        rows = max([math.ceil(extent.height() / pixelSize), 1.0])
        cols = max([math.ceil(extent.width() / pixelSize), 1.0])

        writer = QgsRasterFileWriter(outputFile)
        writer.setOutputProviderKey('gdal')
        writer.setOutputFormat(outputFormat)
        provider = writer.createOneBandRaster(Qgis.Float32, cols, rows, extent, crs)
        if provider is None:
            raise QgsProcessingException(self.tr("Could not create raster output: {}").format(outputFile))
        if not provider.isValid():
            raise QgsProcessingException(self.tr("Could not create raster output {}: {}").format(outputFile,
                                                                                                 provider.error().message(
                                                                                                     QgsErrorMessage.Text)))

        provider.setNoDataValue(1, -9999)

        data = [value] * cols
        block = QgsRasterBlock(Qgis.Float32, cols, 1)
        block.setData(struct.pack('{}f'.format(len(data)), *data))

        total = 100.0 / rows if rows else 0
        for i in range(rows):
            if feedback.isCanceled():
                break

            provider.writeBlock(block, 1, 0, i)
            feedback.setProgress(int(i * rows))

        provider.setEditable(False)

        return {self.OUTPUT: outputFile}
예제 #2
0
    def write(self, theRasterName):
        print(theRasterName)

        path = "%s/%s" % (self.testDataDir, theRasterName)
        rasterLayer = QgsRasterLayer(path, "test")
        if not rasterLayer.isValid():
            return False
        provider = rasterLayer.dataProvider()

        tmpFile = QTemporaryFile()
        tmpFile.open()  # fileName is no avialable until open
        tmpName = tmpFile.fileName()
        tmpFile.close()
        # do not remove when class is destroyed so that we can read
        # the file and see difference
        tmpFile.setAutoRemove(False)

        fileWriter = QgsRasterFileWriter(tmpName)
        pipe = QgsRasterPipe()
        if not pipe.set(provider.clone()):
            print("Cannot set pipe provider")
            return False

        projector = QgsRasterProjector()
        projector.setCrs(provider.crs(), provider.crs())
        if not pipe.insert(2, projector):
            print("Cannot set pipe projector")
            return False

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

        checker = QgsRasterChecker()
        ok = checker.runTest("gdal", tmpName, "gdal", path)
        self.report += checker.report()

        # All OK, we can delete the file
        tmpFile.setAutoRemove(ok)

        return ok
예제 #3
0
def exportLayer(layer, fields=None, toShapefile=False, path=None, force=False, log=None):
    filename = layer.source().split("|")[0]
    destFilename = layer.name()
    fields = fields or []
    if layer.type() == layer.VectorLayer:
        if toShapefile:
            if force or layer.fields().count() != len(fields) or (os.path.splitext(filename.lower())[1]  != ".shp"):
                attrs = [i for i, f in enumerate(layer.fields()) if len(fields) == 0 or f.name() in fields]
                output = path or tempFilenameInTempFolder(destFilename + ".shp")
                QgsVectorFileWriter.writeAsVectorFormat(layer, output, "UTF-8", attributes=attrs, driverName="ESRI Shapefile")
                if log is not None:
                    log.logInfo(QCoreApplication.translate("GeocatBridge", "Layer %s exported to %s") % (destFilename, output))
                return output
        elif (force or os.path.splitext(filename.lower())[1]  != ".gpkg"
                        or layer.fields().count() != len(fields) or not isSingleTableGpkg(filename)):
            attrs = [i for i, f in enumerate(layer.fields()) if len(fields) == 0 or f.name() in fields]
            output = path or tempFilenameInTempFolder(destFilename + ".gpkg")
            QgsVectorFileWriter.writeAsVectorFormat(layer, output, "UTF-8", attributes=attrs)
            if log is not None:
                log.logInfo(QCoreApplication.translate("GeocatBridge", "Layer %s exported to %s") % (destFilename, output))
            return output
        
        if log is not None:
            log.logInfo(QCoreApplication.translate("GeocatBridge", "No need to export layer %s stored at %s") % (destFilename, filename))
        return filename
    else:
        if (force or not filename.lower().endswith("tif")):        
            output = path or tempFilenameInTempFolder(destFilename + ".tif")
            writer = QgsRasterFileWriter(output)
            writer.setOutputFormat("GTiff");
            writer.writeRaster(layer.pipe(), layer.width(), layer.height(), layer.extent(), layer.crs())
            del writer
            if log is not None:
                log.logInfo(QCoreApplication.translate("GeocatBridge", "Layer %s exported to %s") % (destFilename, output))
            return output
        else:
            if log is not None:
                log.logInfo(QCoreApplication.translate("GeocatBridge", "No need to export layer %s stored at %s") % (destFilename, filename))
            return filename
예제 #4
0
    def testExportToGpkgWithExtraExtent(self):
        tmpName = tempfile.mktemp(suffix='.gpkg')
        source = QgsRasterLayer(
            os.path.join(self.testDataDir, 'raster',
                         'band3_byte_noct_epsg4326.tif'), 'my', 'gdal')
        self.assertTrue(source.isValid())
        provider = source.dataProvider()
        fw = QgsRasterFileWriter(tmpName)
        fw.setOutputFormat('gpkg')

        pipe = QgsRasterPipe()
        self.assertTrue(pipe.set(provider.clone()))

        self.assertEqual(
            fw.writeRaster(pipe,
                           provider.xSize() + 4,
                           provider.ySize() + 4,
                           QgsRectangle(-3 - 2, -4 - 2, 7 + 2, 6 + 2),
                           provider.crs()), 0)
        del fw

        # Check that the test geopackage contains the raster layer and compare
        rlayer = QgsRasterLayer(tmpName)
        self.assertTrue(rlayer.isValid())
        out_provider = rlayer.dataProvider()
        for i in range(3):
            src_data = provider.block(i + 1, provider.extent(), source.width(),
                                      source.height())
            out_data = out_provider.block(i + 1, provider.extent(),
                                          source.width(), source.height())
            self.assertEqual(src_data.data(), out_data.data())
        out_data = out_provider.block(1, QgsRectangle(7, -4, 7 + 2, 6), 2, 8)
        # band3_byte_noct_epsg4326 nodata is 255
        self.assertEqual(out_data.data().data(), b'\xff' * 2 * 8)
        del out_provider
        del rlayer

        # remove result file
        os.unlink(tmpName)
예제 #5
0
    def testImportIntoGpkg(self):
        # init target file
        test_gpkg = tempfile.mktemp(suffix='.gpkg', dir=self.testDataDir)
        gdal.GetDriverByName('GPKG').Create(test_gpkg, 1, 1, 1)
        source = QgsRasterLayer(
            os.path.join(self.testDataDir, 'raster',
                         'band3_byte_noct_epsg4326.tif'), 'my', 'gdal')
        self.assertTrue(source.isValid())
        provider = source.dataProvider()
        fw = QgsRasterFileWriter(test_gpkg)
        fw.setOutputFormat('gpkg')
        fw.setCreateOptions(
            ['RASTER_TABLE=imported_table', 'APPEND_SUBDATASET=YES'])

        pipe = QgsRasterPipe()
        self.assertTrue(pipe.set(provider.clone()))

        projector = QgsRasterProjector()
        projector.setCrs(provider.crs(), provider.crs())
        self.assertTrue(pipe.set(projector))

        self.assertEqual(
            fw.writeRaster(pipe, provider.xSize(), provider.ySize(),
                           provider.extent(), provider.crs()), 0)

        # Check that the test geopackage contains the raster layer and compare
        rlayer = QgsRasterLayer('GPKG:%s:imported_table' % test_gpkg)
        self.assertTrue(rlayer.isValid())
        out_provider = rlayer.dataProvider()
        for i in range(3):
            src_data = provider.block(i + 1, provider.extent(), source.width(),
                                      source.height())
            out_data = out_provider.block(i + 1, out_provider.extent(),
                                          rlayer.width(), rlayer.height())
            self.assertEqual(src_data.data(), out_data.data())

        # remove result file
        os.unlink(test_gpkg)
    def _testGeneratePyramids(self, pyramidFormat):
        tmpName = tempfile.mktemp(suffix='.tif')
        source = QgsRasterLayer(os.path.join(self.testDataDir, 'raster', 'byte.tif'), 'my', 'gdal')
        self.assertTrue(source.isValid())
        provider = source.dataProvider()
        fw = QgsRasterFileWriter(tmpName)

        fw.setBuildPyramidsFlag(QgsRaster.PyramidsFlagYes)
        fw.setPyramidsFormat(pyramidFormat)
        fw.setPyramidsList([2])

        pipe = QgsRasterPipe()
        self.assertTrue(pipe.set(provider.clone()))

        projector = QgsRasterProjector()
        projector.setCrs(provider.crs(), provider.crs())
        self.assertTrue(pipe.set(projector))

        self.assertEqual(fw.writeRaster(pipe,
                                        provider.xSize(),
                                        provider.ySize(),
                                        provider.extent(),
                                        provider.crs()), 0)
        del fw
        ds = gdal.Open(tmpName)
        self.assertEqual(ds.RasterCount, 1)
        self.assertEqual(ds.GetRasterBand(1).Checksum(), 4672)
        self.assertEqual(ds.GetRasterBand(1).GetOverviewCount(), 1)
        fl = ds.GetFileList()
        if pyramidFormat == QgsRaster.PyramidsGTiff:
            self.assertEqual(len(fl), 2, fl)
            self.assertIn('.ovr', fl[1])
        elif pyramidFormat == QgsRaster.PyramidsInternal:
            self.assertEqual(len(fl), 1, fl)
        elif pyramidFormat == QgsRaster.PyramidsErdas:
            self.assertEqual(len(fl), 2, fl)
            self.assertIn('.aux', fl[1])
        os.unlink(tmpName)
예제 #7
0
    def read_from_qgis_native(self, qgis_layer):
        """Read raster data from qgis layer QgsRasterLayer.

            A stub is used now:
                save all data in a file,
                then call safe.read_from_file

            Raises:
                * TypeError         if qgis is not avialable
                * IOError           if can't store temporary file
                * GetDataError      if can't create copy of qgis_layer's
                                        dataProvider
        """
        if not qgis_imported:   # FIXME (DK): this branch isn't covered by test
            msg = ('Used data is QgsRasterLayer instance, '
                   'but QGIS is not available.')
            raise TypeError(msg)

        base_name = unique_filename()
        file_name = base_name + '.tif'

        file_writer = QgsRasterFileWriter(file_name)
        pipe = QgsRasterPipe()
        provider = qgis_layer.dataProvider()
        if not pipe.set(provider.clone()):
            msg = "Cannot set pipe provider"
            raise GetDataError(msg)

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

        # Write keywords if any
        write_keywords(self.keywords, base_name + '.keywords')
        self.read_from_file(file_name)
    def testWriteAsImage(self):
        tmpName = tempfile.mktemp(suffix='.tif')
        source = QgsRasterLayer(os.path.join(self.testDataDir, 'raster', 'byte.tif'), 'my', 'gdal')
        source.setContrastEnhancement(algorithm=QgsContrastEnhancement.NoEnhancement)
        self.assertTrue(source.isValid())
        provider = source.dataProvider()
        fw = QgsRasterFileWriter(tmpName)

        self.assertEqual(fw.writeRaster(source.pipe(),
                                        provider.xSize(),
                                        provider.ySize(),
                                        provider.extent(),
                                        provider.crs()), QgsRasterFileWriter.NoError)
        ds = gdal.Open(tmpName)
        self.assertEqual(ds.RasterCount, 4)
        self.assertEqual(ds.GetRasterBand(1).Checksum(), 4672)
        self.assertEqual(ds.GetRasterBand(2).Checksum(), 4672)
        self.assertEqual(ds.GetRasterBand(3).Checksum(), 4672)
        self.assertEqual(ds.GetRasterBand(4).Checksum(), 4873)
        ds = None

        del fw
        os.unlink(tmpName)
예제 #9
0
    def testFail(self):
        """test error writing a layer"""
        path = os.path.join(unitTestDataPath(), 'raster', 'with_color_table.tif')
        raster_layer = QgsRasterLayer(path, "test")
        self.assertTrue(raster_layer.isValid())

        pipe = QgsRasterPipe()
        self.assertTrue(pipe.set(raster_layer.dataProvider().clone()))

        tmp = create_temp_filename("/this/is/invalid/file.tif")
        writer = QgsRasterFileWriter(tmp)

        task = QgsRasterFileWriterTask(writer, pipe, 100, 100, raster_layer.extent(), raster_layer.crs(), QgsCoordinateTransformContext())

        task.writeComplete.connect(self.onSuccess)
        task.errorOccurred.connect(self.onFail)

        QgsApplication.taskManager().addTask(task)
        while not self.success and not self.fail:
            QCoreApplication.processEvents()

        self.assertFalse(self.success)
        self.assertTrue(self.fail)
예제 #10
0
def clip_raster(raster, n_cols, n_rows, output_extent):
    """Clip raster to specified extent, width and height.

    Note there is similar utility in safe_qgis.utilities.clipper, but it uses
    gdal whereas this one uses native QGIS.

    :param raster: Raster
    :type raster: QgsRasterLayer

    :param n_cols: Desired width in pixels of new raster
    :type n_cols: Int

    :param n_rows: Desired height in pixels of new raster
    :type n_rows: Int

    :param output_extent: Extent of the clipped region
    :type output_extent: QgsRectangle

    :returns: Clipped region of the raster
    :rtype: QgsRasterLayer
    """

    provider = raster.dataProvider()
    pipe = QgsRasterPipe()
    pipe.set(provider.clone())

    base_name = unique_filename()
    file_name = base_name + '.tif'
    file_writer = QgsRasterFileWriter(file_name)
    file_writer.writeRaster(
        pipe,
        n_cols,
        n_rows,
        output_extent,
        raster.crs())

    return QgsRasterLayer(file_name, 'clipped_raster')
    def processAlgorithm(self, parameters, context, feedback):
        "Compute orographic precipitation."

        dem = raster_to_array(self.orography, self.bandNumber)

        x, y = grid(self.orography)

        dx = x[1] - x[0]
        dy = y[0] - y[1]  # note: y is decreasing

        assert dx > 0
        assert dy > 0

        P = self.model.run(dem, dx, dy, self.truncate)

        outputFormat = QgsRasterFileWriter.driverForExtension(
            os.path.splitext(self.outputFile)[1])

        writer = QgsRasterFileWriter(self.outputFile)
        writer.setOutputProviderKey('gdal')
        writer.setOutputFormat(outputFormat)
        provider = writer.createOneBandRaster(Qgis.Float64, x.size, y.size,
                                              self.orography.extent(),
                                              self.orography.crs())
        provider.setNoDataValue(1, -9999)

        provider.write(
            bytes(P.data),
            1,  # band
            x.size,  # width
            y.size,  # height
            0,
            0)  # offset

        provider.setEditable(False)

        return {self.OUTPUT: self.outputFile}
    def create_rgb(self, raster_layer, output):
        '''Render and write RGB file

        Parameters
        ----------
        raster_layer : QgsRasterLayer
            input raster layer with singleband pseudocolor
        output : str
            output file path

        Returns
        -------
        error : boolean
            0/1 - no error/error
        result : str or None
            output or error msg if error == 1
    
        '''
        # get raster_layer properties
        extent = raster_layer.extent()
        width, height = raster_layer.width(), raster_layer.height()
        renderer = raster_layer.renderer()
        provider = raster_layer.dataProvider()
        crs_raster = raster_layer.crs()

        # create pipe for export
        pipe = QgsRasterPipe()
        pipe.set(provider.clone())
        pipe.set(renderer.clone())

        # create FileWriter and write file
        fwriter = QgsRasterFileWriter(output)
        error = fwriter.writeRaster(pipe, width, height, extent, crs_raster)
        if error != fwriter.NoError:
            return 1, 'RGB file could not be rendered!'

        return 0, output
예제 #13
0
 def convertUnsupportedFormats(self, progress):
     i = 0
     progress.setText(self.tr('Converting outputs'))
     for out in self.outputs:
         if isinstance(out, OutputVector):
             if out.compatible is not None:
                 layer = dataobjects.getObjectFromUri(out.compatible)
                 if layer is None:
                     # For the case of memory layer, if the
                     # getCompatible method has been called
                     continue
                 provider = layer.dataProvider()
                 writer = out.getVectorWriter(provider.fields(),
                                              provider.geometryType(),
                                              layer.crs())
                 features = vector.features(layer)
                 for feature in features:
                     writer.addFeature(feature)
         elif isinstance(out, OutputRaster):
             if out.compatible is not None:
                 layer = dataobjects.getObjectFromUri(out.compatible)
                 provider = layer.dataProvider()
                 writer = QgsRasterFileWriter(out.value)
                 format = self.getFormatShortNameFromFilename(out.value)
                 writer.setOutputFormat(format)
                 writer.writeRaster(layer.pipe(), layer.width(),
                                    layer.height(), layer.extent(),
                                    layer.crs())
         elif isinstance(out, OutputTable):
             if out.compatible is not None:
                 layer = dataobjects.getObjectFromUri(out.compatible)
                 provider = layer.dataProvider()
                 writer = out.getTableWriter(provider.fields())
                 features = vector.features(layer)
                 for feature in features:
                     writer.addRecord(feature)
         progress.setPercentage(100 * i / float(len(self.outputs)))
    def testWriteAsRawGS7BG(self):
        ''' Test that despite writing a Byte raster, we correctly handle GS7BG creating a Float64 '''
        tmpName = tempfile.mktemp(suffix='.grd')
        source = QgsRasterLayer(os.path.join(self.testDataDir, 'raster', 'byte.tif'), 'my', 'gdal')
        self.assertTrue(source.isValid())
        provider = source.dataProvider()
        fw = QgsRasterFileWriter(tmpName)
        fw.setOutputFormat('GS7BG')

        pipe = QgsRasterPipe()
        self.assertTrue(pipe.set(provider.clone()))

        self.assertEqual(fw.writeRaster(pipe,
                                        provider.xSize(),
                                        provider.ySize(),
                                        provider.extent(),
                                        provider.crs()), QgsRasterFileWriter.NoError)
        del fw

        ds = gdal.Open(tmpName)
        self.assertEqual(ds.RasterCount, 1)
        self.assertEqual(ds.GetRasterBand(1).Checksum(), 4672)
        ds = None
        os.unlink(tmpName)
예제 #15
0
def exportRaster(layer, count, layersFolder, feedback):
    feedback.showFeedback("Exporting %s to PNG..." % layer.name())
    name_ts = (safeName(layer.name()) + unicode(count) +
               unicode(int(time.time())))

    # We need to create a new file to export style
    piped_file = os.path.join(tempfile.gettempdir(), name_ts + '_piped.tif')

    piped_extent = layer.extent()
    piped_width = layer.height()
    piped_height = layer.width()
    piped_crs = layer.crs()
    piped_renderer = layer.renderer()
    piped_provider = layer.dataProvider()

    pipe = QgsRasterPipe()
    pipe.set(piped_provider.clone())
    pipe.set(piped_renderer.clone())

    file_writer = QgsRasterFileWriter(piped_file)

    file_writer.writeRaster(pipe, piped_width, piped_height, piped_extent,
                            piped_crs)

    # Extent of the layer in EPSG:3857
    crsSrc = layer.crs()
    crsDest = QgsCoordinateReferenceSystem(3857)
    xform = QgsCoordinateTransform(crsSrc, crsDest)
    extentRep = xform.transform(layer.extent())

    extentRepNew = ','.join([
        unicode(extentRep.xMinimum()),
        unicode(extentRep.xMaximum()),
        unicode(extentRep.yMinimum()),
        unicode(extentRep.yMaximum())
    ])

    # Reproject in 3857
    piped_3857 = os.path.join(tempfile.gettempdir(),
                              name_ts + '_piped_3857.tif')
    # Export layer as PNG
    out_raster = os.path.join(layersFolder,
                              safeName(layer.name()) + unicode(count) + ".png")

    qgis_version = QGis.QGIS_VERSION

    old_stdout = sys.stdout
    sys.stdout = mystdout = StringIO()
    try:
        processing.runalg("gdalogr:warpreproject")
    except:
        pass
    sys.stdout = old_stdout

    params = {
        "INPUT": piped_file,
        "SOURCE_SRS": layer.crs().authid(),
        "DEST_SRS": "EPSG:3857",
        "NO_DATA": "",
        "TR": 0,
        "METHOD": 2,
        "RAST_EXT": extentRepNew,
        "EXT_CRS": "EPSG:3857",
        "RTYPE": 0,
        "COMPRESS": 4,
        "JPEGCOMPRESSION": 75,
        "ZLEVEL": 6,
        "PREDICTOR": 1,
        "TILED": False,
        "BIGTIFF": 0,
        "TFW": False,
        "EXTRA": "",
        "OUTPUT": piped_3857
    }

    warpArgs = {}

    lines = mystdout.getvalue()
    for count, line in enumerate(lines.split("\n\t")):
        if count != 0 and line != " ":
            try:
                k = line.split(" ")[0]
                warpArgs[k] = params[k]
            except:
                pass

    if int(qgis_version.split('.')[1]) < 15:
        processing.runalg("gdalogr:warpreproject", piped_file,
                          layer.crs().authid(), "EPSG:3857", "", 0, 1, 0, -1,
                          75, 6, 1, False, 0, False, "", piped_3857)
        processing.runalg("gdalogr:translate", piped_3857, 100, True, "", 0,
                          "", extentRepNew, False, 0, 0, 75, 6, 1, False, 0,
                          False, "", out_raster)
    else:
        try:
            procRtn = processing.runalg("gdalogr:warpreproject", warpArgs)
        except:
            shutil.copyfile(piped_file, piped_3857)

        try:
            processing.runalg("gdalogr:translate", piped_3857, 100, True, "",
                              0, "", extentRepNew, False, 5, 4, 75, 6, 1,
                              False, 0, False, "", out_raster)
        except:
            shutil.copyfile(piped_3857, out_raster)
예제 #16
0
def exportRasterLayer(layer, safeLayerName, dataPath):
    name_ts = safeLayerName + unicode(int(time.time()))

    # We need to create a new file to export style
    piped_file = os.path.join(tempfile.gettempdir(), name_ts + '_piped.tif')

    piped_extent = layer.extent()
    piped_width = layer.height()
    piped_height = layer.width()
    piped_crs = layer.crs()
    piped_renderer = layer.renderer()
    piped_provider = layer.dataProvider()

    pipe = QgsRasterPipe()
    pipe.set(piped_provider.clone())
    pipe.set(piped_renderer.clone())

    file_writer = QgsRasterFileWriter(piped_file)

    file_writer.writeRaster(pipe, piped_width, piped_height, piped_extent,
                            piped_crs)

    # Extent of the layer in EPSG:3857
    crsSrc = layer.crs()
    crsDest = QgsCoordinateReferenceSystem(3857)
    xform = QgsCoordinateTransform(crsSrc, crsDest)
    extentRep = xform.transform(layer.extent())

    extentRepNew = ','.join([
        unicode(extentRep.xMinimum()),
        unicode(extentRep.xMaximum()),
        unicode(extentRep.yMinimum()),
        unicode(extentRep.yMaximum())
    ])

    # Reproject in 3857
    piped_3857 = os.path.join(tempfile.gettempdir(),
                              name_ts + '_piped_3857.tif')

    # Export layer as PNG
    out_raster = dataPath + '.png'

    qgis_version = QGis.QGIS_VERSION

    if int(qgis_version.split('.')[1]) < 15:

        processing.runalg("gdalogr:warpreproject", piped_file,
                          layer.crs().authid(), "EPSG:3857", "", 0, 1, 0, -1,
                          75, 6, 1, False, 0, False, "", piped_3857)
        processing.runalg("gdalogr:translate", piped_3857, 100, True, "", 0,
                          "", extentRepNew, False, 0, 0, 75, 6, 1, False, 0,
                          False, "", out_raster)
    else:
        try:
            warpArgs = {
                "INPUT": piped_file,
                "SOURCE_SRS": layer.crs().authid(),
                "DEST_SRS": "EPSG:3857",
                "NO_DATA": "",
                "TR": 0,
                "METHOD": 2,
                "RAST_EXT": extentRepNew,
                "EXT_CRS": "EPSG:3857",
                "RTYPE": 0,
                "COMPRESS": 4,
                "JPEGCOMPRESSION": 75,
                "ZLEVEL": 6,
                "PREDICTOR": 1,
                "TILED": False,
                "BIGTIFF": 0,
                "TFW": False,
                "EXTRA": "",
                "OUTPUT": piped_3857
            }
            procRtn = processing.runalg("gdalogr:warpreproject", warpArgs)
            # force exception on algorithm fail
            for val in procRtn:
                pass
        except:
            try:
                warpArgs = {
                    "INPUT": piped_file,
                    "SOURCE_SRS": layer.crs().authid(),
                    "DEST_SRS": "EPSG:3857",
                    "NO_DATA": "",
                    "TR": 0,
                    "METHOD": 2,
                    "RAST_EXT": extentRepNew,
                    "RTYPE": 0,
                    "COMPRESS": 4,
                    "JPEGCOMPRESSION": 75,
                    "ZLEVEL": 6,
                    "PREDICTOR": 1,
                    "TILED": False,
                    "BIGTIFF": 0,
                    "TFW": False,
                    "EXTRA": "",
                    "OUTPUT": piped_3857
                }
                procRtn = processing.runalg("gdalogr:warpreproject", warpArgs)
                # force exception on algorithm fail
                for val in procRtn:
                    pass
            except:
                try:
                    warpArgs = {
                        "INPUT": piped_file,
                        "SOURCE_SRS": layer.crs().authid(),
                        "DEST_SRS": "EPSG:3857",
                        "NO_DATA": "",
                        "TR": 0,
                        "METHOD": 2,
                        "RTYPE": 0,
                        "COMPRESS": 4,
                        "JPEGCOMPRESSION": 75,
                        "ZLEVEL": 6,
                        "PREDICTOR": 1,
                        "TILED": False,
                        "BIGTIFF": 0,
                        "TFW": False,
                        "EXTRA": "",
                        "OUTPUT": piped_3857
                    }
                    procRtn = processing.runalg("gdalogr:warpreproject",
                                                warpArgs)
                    for val in procRtn:
                        pass
                except:
                    shutil.copyfile(piped_file, piped_3857)

        try:
            processing.runalg("gdalogr:translate", piped_3857, 100, True, "",
                              0, "", extentRepNew, False, 5, 4, 75, 6, 1,
                              False, 0, False, "", out_raster)
        except:
            shutil.copyfile(piped_3857, out_raster)
예제 #17
0
        dataOut = tempfile.mktemp('.tif')
    except Exception, e:
        raise Exception(
            'Problem creating temporary file to store raster data: ' + str(e))
    # TODO: Work out if the response is an XML error
    update.emit({'progress': 10, 'message': 'Downloading file...'})

    urllib.urlretrieve(bigURL, dataOut)

    # Load data as QgsRasterLayer and then re-save it, ensuring it has the correct projection info
    a = QgsRasterLayer(dataOut, "temporary raster layer")
    # Double-confirm projection info (sometimes WCS has it in the meta but not the file)
    crs = a.crs()
    crs.createFromId(int(srs.split(':')[1]))
    a.setCrs(crs)
    update.emit({'progress': 90, 'message': 'Saving file...'})
    writer = QgsRasterFileWriter(output_file)

    pipe = QgsRasterPipe()
    width, height = a.width(), a.height()
    extent = a.extent()
    provider = a.dataProvider()
    pipe.set(provider.clone())
    writer.writeRaster(pipe, width, height, extent, a.crs())
    a = None
    pipe = None
    provider = None
    # Delete temp file
    os.remove(dataOut)
    return output_file
예제 #18
0
def styleRaster(filename):
    # Create outfile name
    outfile = "".join(filename.strip().split('.raw'))

    # Open layer from filename
    rasterfile = filename.strip().split('/')[-1]
    rasterlayer = rasterfile.split('.')[0]
    rlayer = QgsRasterLayer(filename, rasterlayer, 'gdal')

    # Check if layer is valid
    if rlayer.isValid() is True:
        # Get layer data provider
        provider = rlayer.dataProvider()

        # Calculate histrogram
        provider.initHistogram(QgsRasterHistogram(), 1, 100)
        hist = provider.histogram(1)

        # Get histograms stats
        nbins = hist.binCount
        minv = hist.minimum
        maxv = hist.maximum

        # Create histogram array, bin array, and histogram index
        hista = np.array(hist.histogramVector)
        bins = np.arange(minv, maxv, (maxv - minv) / nbins)
        index = np.where(hista > 5)

        # Get bottom and top color values from bin values
        bottomcolor = bins[index[0][0]]
        topcolor = bins[index[0][-1]]

        # Calculate range value between the bottom and top color values
        if bottomcolor < 0:
            vrange = topcolor + bottomcolor
        else:
            vrange = topcolor - bottomcolor

        # Calculate values for bottom middle, and top middle color values
        if rasterlayer == 'maxele':
            bottommiddle = vrange * 0.3333
            topmiddle = vrange * 0.6667
        else:
            bottommiddle = vrange * 0.375
            topmiddle = vrange * 0.75

        # Create list of color values
        valueList = [bottomcolor, bottommiddle, topmiddle, topcolor]

        # Create color dictionary
        if rasterlayer == 'maxele':
            colDic = {
                'bottomcolor': '#0000ff',
                'bottommiddle': '#00ffff',
                'topmiddle': '#ffff00',
                'topcolor': '#ff0000'
            }
        else:
            colDic = {
                'bottomcolor': '#000000',
                'bottommiddle': '#ff0000',
                'topmiddle': '#ffff00',
                'topcolor': '#ffffff'
            }

        # Create color ramp function and add colors
        fnc = QgsColorRampShader()
        fnc.setColorRampType(QgsColorRampShader.Interpolated)
        lst = [QgsColorRampShader.ColorRampItem(valueList[0], QColor(colDic['bottomcolor'])),\
               QgsColorRampShader.ColorRampItem(valueList[1], QColor(colDic['bottommiddle'])), \
               QgsColorRampShader.ColorRampItem(valueList[2], QColor(colDic['topmiddle'])), \
               QgsColorRampShader.ColorRampItem(valueList[3], QColor(colDic['topcolor']))]
        fnc.setColorRampItemList(lst)

        # Create raster shader and add color ramp function
        shader = QgsRasterShader()
        shader.setRasterShaderFunction(fnc)

        # Create color render and set opacity
        renderer = QgsSingleBandPseudoColorRenderer(provider, 1, shader)
        renderer.setOpacity(0.75)

        # Get output format
        output_format = QgsRasterFileWriter.driverForExtension(
            os.path.splitext(outfile)[1])

        # Open output file for writing
        rfw = QgsRasterFileWriter(outfile)
        rfw.setOutputProviderKey('gdal')
        rfw.setOutputFormat(output_format)

        # Add EPSG 4326 to layer crs
        crs = QgsCoordinateReferenceSystem()
        crs.createFromSrid(4326)

        # Create Raster pipe and set provider and renderer
        pipe = QgsRasterPipe()
        pipe.set(provider.clone())
        pipe.set(renderer.clone())

        # Get transform context
        transform_context = QgsProject.instance().transformContext()

        # Write to file
        rfw.writeRaster(pipe, provider.xSize(), provider.ySize(),
                        provider.extent(), crs, transform_context)

        logger.info(
            'Conveted data in ' + rasterfile +
            ' from float64 to 8bit, added color palette and saved to tiff (' +
            outfile.split('/')[-1] + ') file')

    if not rlayer.isValid():
        raise Exception('Invalid raster')

    return (valueList)
예제 #19
0
def exportLayer(layer,
                fields=None,
                to_shapefile=False,
                path=None,
                force=False,
                logger=None):
    logger = logger or feedback
    filepath, _, ext = lyr_utils.getLayerSourceInfo(layer)
    lyr_name, safe_name = lyr_utils.getLayerTitleAndName(layer)
    fields = fields or []
    if layer.type() == layer.VectorLayer:
        if to_shapefile and (force or layer.fields().count() != len(fields)
                             or ext != EXT_SHAPEFILE):
            # Export with Shapefile extension
            ext = EXT_SHAPEFILE
        elif force or ext != EXT_GEOPACKAGE or layer.fields().count() != len(fields) \
                or not isSingleTableGpkg(filepath):
            # Export with GeoPackage extension
            ext = EXT_GEOPACKAGE
        else:
            # No need to export
            logger.logInfo(
                f"No need to export layer {lyr_name} stored at {filepath}")
            return filepath

        # Perform GeoPackage or Shapefile export
        attrs = [
            i for i, f in enumerate(layer.fields())
            if len(fields) == 0 or f.name() in fields
        ]
        output = path or tempFileInSubFolder(safe_name + ext)
        encoding = "UTF-8"
        driver = "ESRI Shapefile" if ext == EXT_SHAPEFILE else "GPKG"
        options = None
        if hasattr(QgsVectorFileWriter, 'SaveVectorOptions'):
            # QGIS v3.x has the SaveVectorOptions object
            options = QgsVectorFileWriter.SaveVectorOptions()
            options.fileEncoding = encoding
            options.attributes = attrs
            options.driverName = driver
        # Make sure that we are using the latest (non-deprecated) write method
        if hasattr(QgsVectorFileWriter, 'writeAsVectorFormatV3'):
            # Use writeAsVectorFormatV3 for QGIS versions >= 3.20 to avoid DeprecationWarnings
            result = QgsVectorFileWriter.writeAsVectorFormatV3(
                layer, output, QgsCoordinateTransformContext(),
                options)  # noqa
        elif hasattr(QgsVectorFileWriter, 'writeAsVectorFormatV2'):
            # Use writeAsVectorFormatV2 for QGIS versions >= 3.10.3 to avoid DeprecationWarnings
            result = QgsVectorFileWriter.writeAsVectorFormatV2(
                layer, output, QgsCoordinateTransformContext(),
                options)  # noqa
        else:
            # Use writeAsVectorFormat for QGIS versions < 3.10.3 for backwards compatibility
            result = QgsVectorFileWriter.writeAsVectorFormat(
                layer,
                output,
                fileEncoding=encoding,
                attributes=attrs,
                driverName=driver)  # noqa
        # Check if first item in result tuple is an error code
        if result[0] == QgsVectorFileWriter.NoError:
            logger.logInfo(f"Layer {lyr_name} exported to {output}")
        else:
            # Dump the result tuple as-is when there are errors (the tuple size depends on the QGIS version)
            logger.logError(
                f"Layer {lyr_name} failed to export.\n\tResult object: {str(result)}"
            )
        return output
    else:
        # Export raster
        if force or not filepath.lower().endswith("tif"):
            output = path or tempFileInSubFolder(safe_name + ".tif")
            writer = QgsRasterFileWriter(output)
            writer.setOutputFormat("GTiff")
            writer.writeRaster(layer.pipe(), layer.width(), layer.height(),
                               layer.extent(), layer.crs())
            del writer
            logger.logInfo(f"Layer {lyr_name} exported to {output}")
            return output
        else:
            logger.logInfo(
                f"No need to export layer {lyr_name} stored at {filepath}")
            return filepath
예제 #20
0
    def response_geotiff_mode(self, request):
        """
        Export raster as geotiff
        i.e:
        192.168.1.137:8006/raster/api/geotiff/qdjango/190/sfondo_clip_c60533a4_743e_4734_9b95_514ac765ec4e/
        192.168.1.137:8006/raster/api/geotiff/qdjango/190/europa_dem_8f0a9c30_5b96_4661_b747_8ce4f2679d6b/?map_extent=10.515901325263899%2C43.875701513907146%2C10.55669628723769%2C43.92294901234999

        :param request: Http Django request object
        :return: http response with attached file
        """

        #if not self.layer.download:
        #     return HttpResponseForbidden()


        tmp_dir = tempfile.TemporaryDirectory()

        filename = f"{self.metadata_layer.qgis_layer.name()}.tif"

        file_path = os.path.join(tmp_dir.name, filename)

        writer = QgsRasterFileWriter(file_path)
        provider = self.metadata_layer.qgis_layer.dataProvider()
        renderer = self.metadata_layer.qgis_layer.renderer()

        # Check for Url Params
        if request.query_params.get('map_extent'):
            me = request.query_params.get('map_extent').split(',')
            orig_extent =provider.extent()
            extent = QgsRectangle(float(me[0]), float(me[1]), float(me[2]), float(me[3]))

            # If crs layer is not equal to project crs
            if self.reproject:
                ct = QgsCoordinateTransform(
                    QgsCoordinateReferenceSystem(f'EPSG:{self.layer.project.group.srid.srid}'),
                    self.metadata_layer.qgis_layer.crs(),
                    QgsCoordinateTransformContext()
                )
                extent = ct.transform(extent)

            # Calc columns and rows
            cols = int((extent.xMaximum() - extent.xMinimum()) /
                      (orig_extent.xMaximum() - orig_extent.xMinimum()) * provider.xSize())
            rows = int((extent.yMaximum() - extent.yMinimum()) /
                      (orig_extent.yMaximum() - orig_extent.yMinimum()) * provider.ySize())

            # For cols or rows lower than 0, we have to recalculate extent to guarantee minimal raster cell
            if cols < 1:
                cols = 1
                new_wide_x_extent = (orig_extent.xMaximum() - orig_extent.xMinimum()) / provider.xSize()
                off = (new_wide_x_extent - (extent.xMaximum() - extent.xMinimum())) / 2
                extent.setXMinimum(extent.xMinimum() - off)
                extent.setXMaximum(extent.xMaximum() + off)

            if rows < 1:
                rows = 1
                new_wide_y_extent = (orig_extent.yMaximum() - orig_extent.yMinimum()) / provider.ySize()
                off = (new_wide_y_extent - (extent.yMaximum() - extent.yMinimum())) / 2
                extent.setYMinimum(extent.yMinimum() - off)
                extent.setYMaximum(extent.yMaximum() + off)

        else:
            extent = provider.extent()
            cols = provider.xSize()
            rows = provider.ySize()

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

        error_code = writer.writeRaster(
            pipe,
            cols,
            rows,
            extent,
            self.metadata_layer.qgis_layer.crs(),
            self.metadata_layer.qgis_layer.transformContext()
        )

        if error_code != QgsRasterFileWriter.NoError:
            tmp_dir.cleanup()
            raise APIException(f"An error occoured on create raster file for export")

        # Grab ZIP file from in-memory, make response with correct MIME-type
        response = HttpResponse(
            open(file_path, 'rb').read(), content_type='image/tif')

        response['Content-Disposition'] = f'attachment; filename={filename}'
        response.set_cookie('fileDownload', 'true')
        return response
예제 #21
0
def exportLayers(iface, layers, folder, precision, optimize, popupField, json,
                 restrictToExtent, extent, feedback):
    canvas = iface.mapCanvas()
    epsg4326 = QgsCoordinateReferenceSystem("EPSG:4326")
    layersFolder = os.path.join(folder, "layers")
    QDir().mkpath(layersFolder)
    for count, (layer, encode2json,
                popup) in enumerate(zip(layers, json, popupField)):
        if (layer.type() == layer.VectorLayer
                and (layer.providerType() != "WFS" or encode2json)):
            feedback.showFeedback("Exporting %s to JSON..." % layer.name())
            cleanLayer = writeTmpLayer(layer, popup, restrictToExtent, iface,
                                       extent)
            fields = layer.pendingFields()
            for field in fields:
                exportImages(layer, field.name(), layersFolder + "/tmp.tmp")
            if is25d(layer, canvas, restrictToExtent, extent):
                provider = cleanLayer.dataProvider()
                provider.addAttributes([
                    QgsField("height", QVariant.Double),
                    QgsField("wallColor", QVariant.String),
                    QgsField("roofColor", QVariant.String)
                ])
                cleanLayer.updateFields()
                fields = cleanLayer.pendingFields()
                renderer = layer.rendererV2()
                renderContext = QgsRenderContext.fromMapSettings(
                    canvas.mapSettings())
                feats = layer.getFeatures()
                context = QgsExpressionContext()
                context.appendScope(
                    QgsExpressionContextUtils.layerScope(layer))
                expression = QgsExpression('eval(@qgis_25d_height)')
                heightField = fields.indexFromName("height")
                wallField = fields.indexFromName("wallColor")
                roofField = fields.indexFromName("roofColor")
                renderer.startRender(renderContext, fields)
                cleanLayer.startEditing()
                for feat in feats:
                    context.setFeature(feat)
                    height = expression.evaluate(context)
                    if isinstance(renderer, QgsCategorizedSymbolRendererV2):
                        classAttribute = renderer.classAttribute()
                        attrValue = feat.attribute(classAttribute)
                        catIndex = renderer.categoryIndexForValue(attrValue)
                        categories = renderer.categories()
                        symbol = categories[catIndex].symbol()
                    elif isinstance(renderer, QgsGraduatedSymbolRendererV2):
                        classAttribute = renderer.classAttribute()
                        attrValue = feat.attribute(classAttribute)
                        ranges = renderer.ranges()
                        for range in ranges:
                            if (attrValue >= range.lowerValue()
                                    and attrValue <= range.upperValue()):
                                symbol = range.symbol().clone()
                    else:
                        symbol = renderer.symbolForFeature2(
                            feat, renderContext)
                    sl1 = symbol.symbolLayer(1)
                    sl2 = symbol.symbolLayer(2)
                    wallColor = sl1.subSymbol().color().name()
                    roofColor = sl2.subSymbol().color().name()
                    provider.changeAttributeValues({
                        feat.id() + 1: {
                            heightField: height,
                            wallField: wallColor,
                            roofField: roofColor
                        }
                    })
                cleanLayer.commitChanges()
                renderer.stopRender(renderContext)

            sln = safeName(cleanLayer.name()) + unicode(count)
            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",
                                                    epsg4326,
                                                    'GeoJson',
                                                    0,
                                                    layerOptions=options)
            with open(path, "w") as f:
                f.write("var %s = " % ("geojson_" + sln))
                with open(tmpPath, "r") as f2:
                    for line in f2:
                        if optimize:
                            line = line.strip("\n\t ")
                            line = removeSpaces(line)
                        f.write(line)
            os.remove(tmpPath)

        elif (layer.type() == layer.RasterLayer
              and layer.providerType() != "wms"):

            feedback.showFeedback("Exporting %s to PNG..." % layer.name())
            name_ts = (safeName(layer.name()) + unicode(count) +
                       unicode(int(time.time())))

            # We need to create a new file to export style
            piped_file = os.path.join(tempfile.gettempdir(),
                                      name_ts + '_piped.tif')

            piped_extent = layer.extent()
            piped_width = layer.height()
            piped_height = layer.width()
            piped_crs = layer.crs()
            piped_renderer = layer.renderer()
            piped_provider = layer.dataProvider()

            pipe = QgsRasterPipe()
            pipe.set(piped_provider.clone())
            pipe.set(piped_renderer.clone())

            file_writer = QgsRasterFileWriter(piped_file)

            file_writer.writeRaster(pipe, piped_width, piped_height,
                                    piped_extent, piped_crs)

            # Extent of the layer in EPSG:3857
            crsSrc = layer.crs()
            crsDest = QgsCoordinateReferenceSystem(3857)
            xform = QgsCoordinateTransform(crsSrc, crsDest)
            extentRep = xform.transform(layer.extent())

            extentRepNew = ','.join([
                unicode(extentRep.xMinimum()),
                unicode(extentRep.xMaximum()),
                unicode(extentRep.yMinimum()),
                unicode(extentRep.yMaximum())
            ])

            # Reproject in 3857
            piped_3857 = os.path.join(tempfile.gettempdir(),
                                      name_ts + '_piped_3857.tif')
            # Export layer as PNG
            out_raster = os.path.join(
                layersFolder,
                safeName(layer.name()) + unicode(count) + ".png")

            qgis_version = QGis.QGIS_VERSION

            if int(qgis_version.split('.')[1]) < 15:
                processing.runalg("gdalogr:warpreproject", piped_file,
                                  layer.crs().authid(), "EPSG:3857", "", 0, 1,
                                  0, -1, 75, 6, 1, False, 0, False, "",
                                  piped_3857)
                processing.runalg("gdalogr:translate", piped_3857, 100, True,
                                  "", 0, "", extentRepNew, False, 0, 0, 75, 6,
                                  1, False, 0, False, "", out_raster)
            else:
                try:
                    warpArgs = {
                        "INPUT": piped_file,
                        "SOURCE_SRS": layer.crs().authid(),
                        "DEST_SRS": "EPSG:3857",
                        "NO_DATA": "",
                        "TR": 0,
                        "METHOD": 2,
                        "RAST_EXT": extentRepNew,
                        "EXT_CRS": "EPSG:3857",
                        "RTYPE": 0,
                        "COMPRESS": 4,
                        "JPEGCOMPRESSION": 75,
                        "ZLEVEL": 6,
                        "PREDICTOR": 1,
                        "TILED": False,
                        "BIGTIFF": 0,
                        "TFW": False,
                        "EXTRA": "",
                        "OUTPUT": piped_3857
                    }
                    procRtn = processing.runalg("gdalogr:warpreproject",
                                                warpArgs)
                    # force exception on algorithm fail
                    for val in procRtn:
                        pass
                except:
                    try:
                        warpArgs = {
                            "INPUT": piped_file,
                            "SOURCE_SRS": layer.crs().authid(),
                            "DEST_SRS": "EPSG:3857",
                            "NO_DATA": "",
                            "TR": 0,
                            "METHOD": 2,
                            "RAST_EXT": extentRepNew,
                            "RTYPE": 0,
                            "COMPRESS": 4,
                            "JPEGCOMPRESSION": 75,
                            "ZLEVEL": 6,
                            "PREDICTOR": 1,
                            "TILED": False,
                            "BIGTIFF": 0,
                            "TFW": False,
                            "EXTRA": "",
                            "OUTPUT": piped_3857
                        }
                        procRtn = processing.runalg("gdalogr:warpreproject",
                                                    warpArgs)
                        # force exception on algorithm fail
                        for val in procRtn:
                            pass
                    except:
                        try:
                            warpArgs = {
                                "INPUT": piped_file,
                                "SOURCE_SRS": layer.crs().authid(),
                                "DEST_SRS": "EPSG:3857",
                                "NO_DATA": "",
                                "TR": 0,
                                "METHOD": 2,
                                "RTYPE": 0,
                                "COMPRESS": 4,
                                "JPEGCOMPRESSION": 75,
                                "ZLEVEL": 6,
                                "PREDICTOR": 1,
                                "TILED": False,
                                "BIGTIFF": 0,
                                "TFW": False,
                                "EXTRA": "",
                                "OUTPUT": piped_3857
                            }
                            procRtn = processing.runalg(
                                "gdalogr:warpreproject", warpArgs)
                            # force exception on algorithm fail
                            for val in procRtn:
                                pass
                        except:
                            shutil.copyfile(piped_file, piped_3857)

                try:
                    processing.runalg("gdalogr:translate", piped_3857, 100,
                                      True, "", 0, "", extentRepNew, False, 5,
                                      4, 75, 6, 1, False, 0, False, "",
                                      out_raster)
                except:
                    shutil.copyfile(piped_3857, out_raster)
    feedback.completeStep()
    def processAlgorithm(self, parameters, context, feedback):
        """
        Here is where the processing itself takes place.
        """

        if self.parameterAsRasterLayer(parameters, self.INITIAL_ROAD_NETWORK,
                                       context):
            initial_road_network_raster = self.parameterAsRasterLayer(
                parameters, self.INITIAL_ROAD_NETWORK, context)
        else:
            initial_road_network_raster = None

        basic_distance_cost = self.parameterAsDouble(parameters,
                                                     self.BASIC_DISTANCE_COST,
                                                     context)

        if self.parameterAsRasterLayer(parameters,
                                       self.COARSE_ELEVATION_RASTER, context):
            coarse_elevation_raster = self.parameterAsRasterLayer(
                parameters, self.COARSE_ELEVATION_RASTER, context)
        else:
            coarse_elevation_raster = None

        if self.parameterAsMatrix(parameters, self.COARSE_ELEVATION_COSTS,
                                  context):
            coarse_elevation_costs = self.parameterAsMatrix(
                parameters, self.COARSE_ELEVATION_COSTS, context)
            coarse_elevation_costs = CostRasterCreatorHelper.CollapsedTableToMatrix(
                coarse_elevation_costs, 3)
        else:
            coarse_elevation_costs = None

        if self.parameterAsRasterLayer(parameters, self.FINE_ELEVATION_RASTER,
                                       context):
            fine_elevation_raster = self.parameterAsRasterLayer(
                parameters, self.FINE_ELEVATION_RASTER, context)
        else:
            fine_elevation_raster = None

        if self.parameterAsMatrix(parameters, self.FINE_ELEVATION_COSTS,
                                  context):
            fine_elevation_costs = self.parameterAsMatrix(
                parameters, self.FINE_ELEVATION_COSTS, context)
            fine_elevation_costs = CostRasterCreatorHelper.CollapsedTableToMatrix(
                fine_elevation_costs, 3)
        else:
            fine_elevation_costs = None

        if self.parameterAsRasterLayer(parameters, self.COARSE_WATER_RASTER,
                                       context):
            coarse_water_raster = self.parameterAsRasterLayer(
                parameters, self.COARSE_WATER_RASTER, context)
        else:
            coarse_water_raster = None

        if self.parameterAsDouble(parameters, self.COARSE_WATER_COST, context):
            coarse_water_cost = self.parameterAsDouble(parameters,
                                                       self.COARSE_WATER_COST,
                                                       context)
        else:
            coarse_water_cost = None

        if self.parameterAsRasterLayer(parameters, self.FINE_WATER_RASTER,
                                       context):
            fine_water_raster = self.parameterAsRasterLayer(
                parameters, self.FINE_WATER_RASTER, context)
        else:
            fine_water_raster = None

        if self.parameterAsDouble(parameters, self.FINE_WATER_COST, context):
            fine_water_cost = self.parameterAsDouble(parameters,
                                                     self.FINE_WATER_COST,
                                                     context)
        else:
            fine_water_cost = None

        if self.parameterAsRasterLayer(parameters, self.SOIL_RASTER, context):
            soil_raster = self.parameterAsRasterLayer(parameters,
                                                      self.SOIL_RASTER,
                                                      context)
        else:
            soil_raster = None

        if self.parameterAsRasterLayer(parameters, self.ADDITIONAL_COST_RASTER,
                                       context):
            special_raster = self.parameterAsRasterLayer(
                parameters, self.ADDITIONAL_COST_RASTER, context)
        else:
            special_raster = None

        feedback.pushInfo(self.tr("Checking inputs..."))
        # If source was not found, throw an exception to indicate that the algorithm
        # encountered a fatal error. The exception text can be any string, but in this
        # case we use the pre-built invalidSourceError method to return a standard
        # helper text for when a source cannot be evaluated
        if basic_distance_cost is None or basic_distance_cost == 0:
            raise QgsProcessingException(
                self.invalidSourceError(parameters, self.BASIC_DISTANCE_COST))

        # Now, we check to see if the CRS, extent and resolution of every raster is equal, so that their align properly.
        listOfRastersToCheck = list()
        if initial_road_network_raster is not None:
            listOfRastersToCheck.append(initial_road_network_raster)
        if coarse_elevation_raster is not None:
            listOfRastersToCheck.append(coarse_elevation_raster)
        if fine_elevation_raster is not None:
            listOfRastersToCheck.append(fine_elevation_raster)
        if coarse_water_raster is not None:
            listOfRastersToCheck.append(coarse_water_raster)
        if fine_water_raster is not None:
            listOfRastersToCheck.append(fine_water_raster)
        if soil_raster is not None:
            listOfRastersToCheck.append(soil_raster)
        if special_raster is not None:
            listOfRastersToCheck.append(special_raster)

        if len(listOfRastersToCheck) == 0:
            raise QgsProcessingException(
                self.
                tr("At least one input raster is needed ! Please, input one raster."
                   ))

        # We check that every raster has the same CRS, extent and resolution.
        CostRasterCreatorHelper.CheckRastersCompatibility(listOfRastersToCheck)

        # We also check that the matrix of parameters entered for the coarse elevation costs and fine elevation costs
        # are correct : meaning that there are no holes between the thresholds, and that every lower threshold is lower
        # than the upper threshold.
        if coarse_elevation_costs is not None:
            CostRasterCreatorHelper.CheckThresholds(coarse_elevation_costs,
                                                    "Coarse elevation costs")
        if fine_elevation_costs is not None:
            CostRasterCreatorHelper.CheckThresholds(fine_elevation_costs,
                                                    "Fine elevation costs")

        # Then, we create the raster blocks
        if initial_road_network_raster is not None:
            initial_road_network_raster_block = CostRasterCreatorHelper.get_all_block(
                initial_road_network_raster)
        else:
            initial_road_network_raster_block = None

        if coarse_elevation_raster is not None:
            coarse_elevation_raster_block = CostRasterCreatorHelper.get_all_block(
                coarse_elevation_raster)
        else:
            coarse_elevation_raster_block = None

        if fine_elevation_raster is not None:
            fine_elevation_raster_block = CostRasterCreatorHelper.get_all_block(
                fine_elevation_raster)
        else:
            fine_elevation_raster_block = None

        if coarse_water_raster is not None:
            coarse_water_raster_block = CostRasterCreatorHelper.get_all_block(
                coarse_water_raster)
        else:
            coarse_water_raster_block = None

        if fine_water_raster is not None:
            fine_water_raster_block = CostRasterCreatorHelper.get_all_block(
                fine_water_raster)
        else:
            fine_water_raster_block = None

        if soil_raster is not None:
            soil_raster_block = CostRasterCreatorHelper.get_all_block(
                soil_raster)
        else:
            soil_raster_block = None

        if special_raster is not None:
            special_raster_block = CostRasterCreatorHelper.get_all_block(
                special_raster)
        else:
            special_raster_block = None

        feedback.pushInfo(self.tr("Preparing output..."))
        # We set the output to be ready : It is a QgsDataProvider
        outputFile = self.parameterAsOutputLayer(parameters, self.OUTPUT,
                                                 context)
        outputFormat = QgsRasterFileWriter.driverForExtension(
            os.path.splitext(outputFile)[1])

        crs = listOfRastersToCheck[0].crs()
        extent = listOfRastersToCheck[0].extent()
        rows = max([
            math.ceil(extent.height() /
                      listOfRastersToCheck[0].rasterUnitsPerPixelY()), 1.0
        ])
        cols = max([
            math.ceil(extent.width() /
                      listOfRastersToCheck[0].rasterUnitsPerPixelX()), 1.0
        ])
        # We will need this value for the fine water computation later
        pixelSide = (listOfRastersToCheck[0].rasterUnitsPerPixelY() +
                     listOfRastersToCheck[0].rasterUnitsPerPixelX()) / 2

        writer = QgsRasterFileWriter(outputFile)
        writer.setOutputProviderKey('gdal')
        writer.setOutputFormat(outputFormat)
        provider = writer.createOneBandRaster(Qgis.Float32, cols, rows, extent,
                                              crs)

        if provider is None:
            raise QgsProcessingException(
                self.tr("Could not create raster output: {}").format(
                    outputFile))
        if not provider.isValid():
            raise QgsProcessingException(
                self.tr("Could not create raster output {}").format(
                    outputFile))

        provider.setNoDataValue(1, -9999)

        # We create the data block for the output raster, and we fill it with the values we need
        dataBlock = QgsRasterBlock(Qgis.Float32, cols, rows)
        # i = float(1.0)

        feedback.pushInfo(self.tr("Calculating cost raster..."))
        progress = 0
        feedback.setProgress(0)
        errorMessages = list()
        for y in range(dataBlock.height()):
            for x in range(dataBlock.width()):
                if feedback.isCanceled():
                    raise QgsProcessingException(
                        self.tr("ERROR: Operation was cancelled."))

                    # If there is a road already on this pixel, then the cost is 0.
                if initial_road_network_raster_block is not None and \
                     (initial_road_network_raster_block.value(y,
                                                              x) != 0 and not initial_road_network_raster_block.isNoData(
                         y, x)):
                    finalValue = 0

                # If there is a water body on this pixel, we stop everything :
                # The cost will be the construction of a bridge
                elif coarse_water_raster_block is not None and coarse_water_raster_block.value(
                        y, x) != 0:
                    if coarse_water_cost is not None:
                        finalValue = coarse_water_cost
                    else:
                        raise QgsProcessingException(
                            self.
                            tr("A coarse water raster has been given, but no coarse "
                               +
                               "water cost. Please input a coarse water cost.")
                        )
                    # feedback.pushInfo("Seems like there was a road on this pixel. Final value is " + str(finalValue))

                # Else, if we are not on a road or on a body of water...
                else:
                    # We start with the base cost of crossing the pixel
                    finalValue = basic_distance_cost
                    # feedback.pushInfo("No road on this pixel, we put basic distance cost. Final value is " + str(finalValue))
                    # Then, if we have it, we add the soil cost
                    if soil_raster_block is not None:
                        finalValue += soil_raster_block.value(y, x)
                        # feedback.pushInfo("After soils, final value is " + str(finalValue))
                    if special_raster_block is not None:
                        finalValue += special_raster_block.value(y, x)
                    # Then the coarse elevation value
                    if coarse_elevation_raster_block is not None:
                        additionalValue, errorMessage = CostRasterCreatorHelper.CalculateCoarseElevationCost(
                            y, x, coarse_elevation_raster_block,
                            coarse_elevation_costs, pixelSide)
                        finalValue += additionalValue
                        if errorMessage is not None:
                            errorMessages.append(errorMessage)
                        # feedback.pushInfo("After coarse elevation, final value is " + str(finalValue))
                    # Then the fine water value
                    if fine_water_raster_block is not None:
                        finalValue += CostRasterCreatorHelper.CalculateFineWaterCost(
                            y, x, fine_water_raster_block, fine_water_cost,
                            pixelSide)
                        # feedback.pushInfo("After fine water, final value is " + str(finalValue))
                    # Then, we multiply everything with the fine elevation cost.
                    if fine_elevation_raster_block is not None:
                        finalValue, errorMessage = CostRasterCreatorHelper.CalculateFineElevationCost(
                            y, x, fine_elevation_raster_block,
                            fine_elevation_costs, finalValue)
                        if errorMessage is not None:
                            errorMessages.append(errorMessage)
                        # feedback.pushInfo("After fine elevation, final value is " + str(finalValue))
                dataBlock.setValue(y, x, float(finalValue))

                progress += 1
                feedback.setProgress(
                    100 * (progress /
                           (dataBlock.height() * dataBlock.width())))

        # We write the values in the provider of our files
        provider.writeBlock(dataBlock, 1)

        # We stop the edition of the output raster
        provider.setEditable(False)

        # We display the warning messages about the thresholds
        if len(errorMessages) > 0:
            above = 0
            below = 0
            for errorMessage in errorMessages:
                if errorMessage == "Above":
                    above += 1
                elif errorMessage == "Below":
                    below += 1
            feedback.pushInfo(
                self.
                tr("WARNING : There were " + str(below) +
                   " situations where the value of a pixel was under"
                   " the lowest threshold given as a parameter; and " +
                   str(above) + " when it was above the"
                   " highest. In those cases, the lowest or highest value of the parameter range was used."
                   " To avoid that, please make sure to use thresholds that cover all of the range of values in"
                   " your rasters."))

        # We make the output
        return {self.OUTPUT: outputFile}
예제 #23
0
def exportRaster(layer, count, layersFolder, feedback, iface, matchCRS):
    feedback.showFeedback("Exporting %s to PNG..." % layer.name())
    name_ts = (safeName(layer.name()) + unicode(count) +
               unicode(int(time.time())))

    # We need to create a new file to export style
    piped_file = os.path.join(tempfile.gettempdir(), name_ts + '_piped.tif')

    piped_extent = layer.extent()
    piped_width = layer.height()
    piped_height = layer.width()
    piped_crs = layer.crs()
    piped_renderer = layer.renderer()
    piped_provider = layer.dataProvider()

    pipe = QgsRasterPipe()
    pipe.set(piped_provider.clone())
    pipe.set(piped_renderer.clone())

    file_writer = QgsRasterFileWriter(piped_file)

    file_writer.writeRaster(pipe, piped_height, -1, piped_extent, piped_crs)

    # Export layer as PNG
    out_raster = os.path.join(layersFolder, safeName(layer.name()) + "_" +
                              unicode(count) + ".png")

    projectCRS = iface.mapCanvas().mapSettings().destinationCrs()
    if not (matchCRS and layer.crs() == projectCRS):
        # Extent of the layer in EPSG:3857
        crsSrc = layer.crs()
        crsDest = QgsCoordinateReferenceSystem(3857)
        try:
            xform = QgsCoordinateTransform(crsSrc, crsDest,
                                           QgsProject.instance())
        except:
            xform = QgsCoordinateTransform(crsSrc, crsDest)
        extentRep = xform.transformBoundingBox(layer.extent())

        extentRepNew = ','.join([unicode(extentRep.xMinimum()),
                                 unicode(extentRep.xMaximum()),
                                 unicode(extentRep.yMinimum()),
                                 unicode(extentRep.yMaximum())])

        # Reproject in 3857
        piped_3857 = os.path.join(tempfile.gettempdir(),
                                  name_ts + '_piped_3857.tif')
        qgis_version = Qgis.QGIS_VERSION

        old_stdout = sys.stdout
        sys.stdout = mystdout = StringIO()
        try:
            processing.algorithmHelp("gdal:warpreproject")
        except:
            pass
        sys.stdout = old_stdout

        params = {
            "INPUT": piped_file,
            "SOURCE_CRS": layer.crs().authid(),
            "TARGET_CRS": "EPSG:3857",
            "NODATA": 0,
            "TARGET_RESOLUTION": 0,
            "RESAMPLING": 2,
            "TARGET_EXTENT": extentRepNew,
            "EXT_CRS": "EPSG:3857",
            "TARGET_EXTENT_CRS": "EPSG:3857",
            "DATA_TYPE": 0,
            "COMPRESS": 4,
            "JPEGCOMPRESSION": 75,
            "ZLEVEL": 6,
            "PREDICTOR": 1,
            "TILED": False,
            "BIGTIFF": 0,
            "TFW": False,
            "MULTITHREADING": False,
            "COPY_SUBDATASETS": False,
            "EXTRA": "",
            "OUTPUT": piped_3857
        }

        warpArgs = {}

        lines = mystdout.getvalue()
        for count, line in enumerate(lines.split("\n")):
            if count != 0 and ":" in line:
                try:
                    k = line.split(":")[0]
                    warpArgs[k] = params[k]
                except:
                    pass

        try:
            processing.run("gdal:warpreproject", warpArgs)
        except:
            shutil.copyfile(piped_file, piped_3857)

        try:
            processing.run("gdal:translate", {"INPUT": piped_3857,
                                              "OUTSIZE": 100,
                                              "OUTSIZE_PERC": True,
                                              "NODATA": 0,
                                              "EXPAND": 0,
                                              "TARGET_CRS": "",
                                              "PROJWIN": extentRepNew,
                                              "SDS": False,
                                              "DATA_TYPE": 0,
                                              "COMPRESS": 4,
                                              "JPEGCOMPRESSION": 75,
                                              "ZLEVEL": 6,
                                              "PREDICTOR": 1,
                                              "TILED": False,
                                              "BIGTIFF": 0,
                                              "TFW": False,
                                              "COPY_SUBDATASETS": False,
                                              "OPTIONS": "",
                                              "OUTPUT": out_raster})
        except:
            shutil.copyfile(piped_3857, out_raster)
    else:
        srcExtent = ','.join([unicode(piped_extent.xMinimum()),
                              unicode(piped_extent.xMaximum()),
                              unicode(piped_extent.yMinimum()),
                              unicode(piped_extent.yMaximum())])
        processing.run("gdal:translate", {"INPUT": piped_file,
                                          "OUTSIZE": 100,
                                          "OUTSIZE_PERC": True,
                                          "NODATA": 0,
                                          "EXPAND": 0,
                                          "TARGET_CRS": "",
                                          "PROJWIN": srcExtent,
                                          "SDS": False,
                                          "DATA_TYPE": 0,
                                          "COMPRESS": 4,
                                          "JPEGCOMPRESSION": 75,
                                          "ZLEVEL": 6,
                                          "PREDICTOR": 1,
                                          "TILED": False,
                                          "BIGTIFF": 0,
                                          "TFW": False,
                                          "COPY_SUBDATASETS": False,
                                          "OPTIONS": "",
                                          "OUTPUT": out_raster})
예제 #24
0
    def processAlgorithm(self, parameters, context, feedback):
        '''
        Here is where the processing itself takes place.
        '''

        from PIL import (
            Image,
            ImageDraw,
        )
        import numpy

        source = self.parameterAsSource(parameters, self.INPUT, context)
        resolution = self.parameterAsDouble(parameters, self.RESOLUTION,
                                            context)
        outpath = self.parameterAsOutputLayer(parameters, self.OUTPUT, context)
        result = {self.OUTPUT: outpath}

        # Compute the number of steps to display within the progress bar
        total = 100.0 / source.featureCount() if source.featureCount() else 0

        # Calculate the output extent
        extent = source.sourceExtent()
        xmin = extent.xMinimum()
        ymax = extent.yMaximum()
        xsize = int((extent.xMaximum() - xmin) / resolution) + 1
        ysize = int((ymax - extent.yMinimum()) / resolution) + 1
        if xsize > 50000 or ysize > 50000:
            feedback.reportError(
                self.tr('Output raster size is too big: {}x{}!').format(
                    xsize, ysize), True)
            # fatalError = true has no effect
            feedback.cancel()
            return result
        feedback.pushConsoleInfo(
            self.tr('Output raster size is {}x{}').format(xsize, ysize))

        # Create output buffer
        density = numpy.zeros((ysize, xsize), dtype=numpy.uint16)
        # Create geometry mask buffer
        mask = Image.new('1', (xsize, ysize), 0)
        draw = ImageDraw.Draw(mask)

        # Iterate over features from source
        features = source.getFeatures()
        for current, feature in enumerate(features):
            # Stop the algorithm if cancel button has been clicked
            if feedback.isCanceled():
                return result

            # Convert feature geometry to the image coordinates
            geometry = feature.geometry()
            geometry.convertToSingleType()
            polygon = geometry.asPolygon()
            points = []
            for p in polygon:
                for x, y in p:
                    x = (x - xmin) / resolution
                    y = (ymax - y) / resolution
                    points.append((x, y))

            # Generate geometry mask
            draw.polygon(points, 1)
            # Add geometry mask to the result raster
            density = numpy.add(density, numpy.array(mask))
            # Reset the mask
            draw.rectangle([0, 0, xsize, ysize], fill=0)

            # Update the progress bar
            feedback.setProgress(int(current * total))

        # Write output raster
        writer = QgsRasterFileWriter(outpath)
        provider = writer.createOneBandRaster(Qgis.UInt16, xsize, ysize,
                                              extent, source.sourceCrs())
        provider.write(density.astype('H').tostring(), 1, xsize, ysize, 0, 0)
        density = None
        draw = None
        mask = None

        return result
예제 #25
0
pcolor = []

pcolor.append(QgsColorRampShader.ColorRampItem(1, QColor("#d2ca97")))
pcolor.append(QgsColorRampShader.ColorRampItem(2, QColor("#f7f7f7")))
pcolor.append(QgsColorRampShader.ColorRampItem(3, QColor("#a1d99b")))
pcolor.append(QgsColorRampShader.ColorRampItem(4, QColor("#41ab5d")))
pcolor.append(QgsColorRampShader.ColorRampItem(5, QColor("#006d2c")))
pcolor.append(QgsColorRampShader.ColorRampItem(6, QColor("#00441b")))

renderer = QgsPalettedRasterRenderer(layer.dataProvider(), 1,
                                     QgsPalettedRasterRenderer.colorTableToClassData(pcolor))
layer.setRenderer(renderer)

extent = layer.extent()
width, height = layer.width(), layer.height()
renderer = layer.renderer()
provider = layer.dataProvider()
crs = layer.crs().toWkt()
pipe = QgsRasterPipe()
pipe.set(provider.clone())
pipe.set(renderer.clone())
file_writer = QgsRasterFileWriter("C:/temp/naip/classified_res.tif")
file_writer.writeRaster(pipe,
                        width,
                        height,
                        extent,
                        layer.crs())

print("Done!")
예제 #26
0
    def processAlgorithm(self, parameters, context, feedback):
        inp_rast = self.parameterAsRasterLayer(parameters, self.INPUT, context)

        grib_filename = self.parameterAsString(parameters, self.OUTPUT,
                                               context)
        if not grib_filename:
            raise QgsProcessingException(
                self.tr('You need to specify output filename.'))

        idp = inp_rast.dataProvider()
        map_settings = iface.mapCanvas().mapSettings()
        crs = map_settings.destinationCrs()
        outputFormat = QgsRasterFileWriter.driverForExtension('.tif')

        height = inp_rast.height()
        width = inp_rast.width()
        inp_block = idp.block(1, idp.extent(), width, height)

        rfw = QgsRasterFileWriter(grib_filename + '.tif')
        rfw.setOutputProviderKey('gdal')
        rfw.setOutputFormat(outputFormat)
        rdp = rfw.createMultiBandRaster(Qgis.Float32, width, height,
                                        idp.extent(), crs, 2)

        rdp.setEditable(True)
        x_block = QgsRasterBlock(Qgis.Float32, width, height)
        y_block = QgsRasterBlock(Qgis.Float32, width, height)
        diag = 1. / sqrt(2)

        # resulting raster has no NODATA value set, which
        # is not treated correctly in MDAL 0.2.0. See
        # see https://github.com/lutraconsulting/MDAL/issues/104
        # therefore set some small value to overcome the issue
        dir_map = {
            0: (1e-7, 1),
            1: (diag, diag),
            2: (1, 1e-7),
            3: (diag, -diag),
            4: (1e-7, -1),
            5: (-diag, -diag),
            6: (-1, 1e-7),
            7: (-diag, diag),
            255: (0, 0)
        }
        for row in range(height):
            for col in range(width):
                dir_ind = inp_block.value(row, col)
                try:
                    x_val, y_val = dir_map.get(dir_ind, 255)
                except TypeError:
                    x_val, y_val = (0, 0)
                x_block.setValue(row, col, x_val)
                y_block.setValue(row, col, y_val)

        rdp.writeBlock(x_block, 1)
        rdp.writeBlock(y_block, 2)
        rdp.setNoDataValue(1, inp_block.noDataValue())
        rdp.setNoDataValue(2, inp_block.noDataValue())
        rdp.setEditable(False)

        # rewrite the resulting raster as GRIB using GDAL for setting metadata
        res_tif = gdal.Open(grib_filename + '.tif')
        grib_driver = gdal.GetDriverByName('GRIB')
        grib = grib_driver.CreateCopy(grib_filename, res_tif)
        band_names = ('x-flow', 'y-flow')
        for i in range(2):
            band_nr = i + 1
            band_name = band_names[i]
            grib_band = grib.GetRasterBand(band_nr)
            grib_band.SetMetadataItem('grib_comment', band_name)
            grib_band.SetNoDataValue(255)
            grib_band.SetDescription(band_name)
            res_tif_band_array = res_tif.GetRasterBand(band_nr).ReadAsArray()
            grib_band.WriteArray(res_tif_band_array)
            feedback.setProgress(band_nr * 50)
        grib = None
        return {self.OUTPUT: grib_filename}
예제 #27
0
    def Color(self, file_in, calcType=None):
        """
        Color the Inbound file (Essentially the File we JUST exported) and display it to screen)

        :param file_in: The file that was just exported
        :type file_in: FileImport

        :return: TO SCREEN Rendered Image
        :rtype: None
        """
        k = self.iface.addRasterLayer(file_in.filePath, file_in.baseName)
        stats = k.dataProvider().bandStatistics(1, QgsRasterBandStats.All,
                                                k.extent(), 0)
        minimum = stats.minimumValue
        maximum = stats.maximumValue

        self.com.log("Color func: [Min val: {0} | Max val: {1}".format(
            str(minimum), str(maximum)),
                     level=0)

        ramp_shader = QgsColorRampShader()
        ramp_shader.setColorRampType(QgsColorRampShader.INTERPOLATED)

        if calcType is None:
            color_list = [
                QgsColorRampShader.ColorRampItem(minimum, QColor(255, 0, 0)),
                QgsColorRampShader.ColorRampItem(0, QColor(255, 207, 74, 255)),
                QgsColorRampShader.ColorRampItem(maximum, QColor(0, 255, 0))
            ]

        elif calcType == "EVI":
            color_list = [
                QgsColorRampShader.ColorRampItem(-2, QColor(255, 0, 0)),
                QgsColorRampShader.ColorRampItem(0, QColor(255, 207, 74, 255)),
                QgsColorRampShader.ColorRampItem(2, QColor(0, 255, 0))
            ]

        else:
            color_list = [
                QgsColorRampShader.ColorRampItem(minimum, QColor(255, 0, 0)),
                QgsColorRampShader.ColorRampItem(0, QColor(255, 207, 74, 255)),
                QgsColorRampShader.ColorRampItem(maximum, QColor(0, 255, 0))
            ]

        ramp_shader.setColorRampItemList(color_list)

        shader = QgsRasterShader()
        shader.setRasterShaderFunction(ramp_shader)

        renderer = QgsSingleBandPseudoColorRenderer(k.dataProvider(), 1,
                                                    shader)
        k.setRenderer(renderer)
        """
        Export colored image to file
        """
        export_path = file_in.filePath + ".colored.tif"
        file_writer = QgsRasterFileWriter(export_path)
        pipe = QgsRasterPipe()
        provide = k.dataProvider()

        # Pipe Setter
        if not pipe.set(provide.clone()):
            self.com.error(Bold="PipeProviderError:",
                           String="Cannot set pipe provider",
                           level=1,
                           duration=3)
            self.com.log(
                "mainPlug - Color: Pipe provider error on line 473, Continuing...",
                level=1)

        self.com.log(str(pipe.renderer()), level=0)
        pipe.set(renderer.clone())
        file_writer.writeRaster(pipe, provide.xSize(), provide.ySize(),
                                provide.extent(), provide.crs())
예제 #28
0
    def exportRasterLayer(self, layer, destinationFile, options=None):
        outputFormat = self.settings[
            'rasterFormat'] if 'rasterFormat' in self.settings else 'GTiff'

        if os.path.splitext(destinationFile)[1] == '':
            formats = QgsRasterFileWriter.extensionsForFormat(outputFormat)
            if len(formats) > 0:
                destinationFile = '{}.{}'.format(destinationFile, formats[0])

        provider = layer.dataProvider()

        cols = provider.xSize()
        rows = provider.ySize()
        if not provider.capabilities() & QgsRasterDataProvider.Size:
            k = float(provider.extent().width()) / float(
                provider.extent().height())
            cols = RASTER_SIZE * k
            rows = RASTER_SIZE

        pipe = QgsRasterPipe()
        if not pipe.set(provider.clone()):
            QgsMessageLog.logMessage(
                self.
                tr('Failed to export layer "{layer}": Cannot set pipe provider.'
                   ).format(layer=layer.name()), 'QConsolidate', Qgis.Warning)
            return False, None

        nodata = {}
        for i in range(1, provider.bandCount() + 1):
            if provider.sourceHasNoDataValue(i):
                value = provider.sourceNoDataValue(i)
                nodata[i] = QgsRasterRange(value, value)

        nuller = QgsRasterNuller()
        for band, value in nodata.items():
            nuller.setNoData(band, [value])

        if not pipe.insert(1, nuller):
            QgsMessageLog.logMessage(
                self.tr(
                    'Failed to export layer "{layer}": Cannot set pipe nuller.'
                ).format(layer=layer.name()), 'QConsolidate', Qgis.Warning)
            return False, None

        writer = QgsRasterFileWriter(destinationFile)
        writer.setOutputFormat(outputFormat)

        if options is not None:
            writer.setCreateOptions(options)

        success = True
        error = writer.writeRaster(pipe, cols, rows, provider.extent(),
                                   provider.crs())
        if error != QgsRasterFileWriter.NoError:
            QgsMessageLog.logMessage(
                self.tr('Failed to export layer "{layer}": {message}.').format(
                    layer=layer.name(), message=error), 'QConsolidate',
                Qgis.Warning)
            success = False

        return success, destinationFile
예제 #29
0
def exportLayer(layer,
                fields=None,
                toShapefile=False,
                path=None,
                force=False,
                log=None):
    filename = layer.source().split("|")[0]
    destFilename = layer.name()
    fields = fields or []
    if layer.type() == layer.VectorLayer:
        if toShapefile and (
                force or layer.fields().count() != len(fields) or
            (os.path.splitext(filename.lower())[1] != EXT_SHAPEFILE)):
            # Export with Shapefile extension
            ext = EXT_SHAPEFILE
        elif force or os.path.splitext(filename.lower())[1] != EXT_GEOPACKAGE or \
                layer.fields().count() != len(fields) or not isSingleTableGpkg(filename):
            # Export with GeoPackage extension
            ext = EXT_GEOPACKAGE
        else:
            # No need to export
            if log is not None:
                log.logInfo(
                    QCoreApplication.translate(
                        "GeocatBridge",
                        f"No need to export layer {destFilename} stored at {filename}"
                    ))
            return filename

        # Perform GeoPackage or Shapefile export
        attrs = [
            i for i, f in enumerate(layer.fields())
            if len(fields) == 0 or f.name() in fields
        ]
        output = path or tempFilenameInTempFolder(destFilename + ext)
        if Qgis.QGIS_VERSION_INT < 31003:
            # Use writeAsVectorFormat for QGIS versions < 3.10.3 for backwards compatibility
            QgsVectorFileWriter.writeAsVectorFormat(
                layer,
                output,
                fileEncoding="UTF-8",
                attributes=attrs,
                driverName="ESRI Shapefile" if ext == EXT_SHAPEFILE else "")
        else:
            # Use writeAsVectorFormatV2 for QGIS versions >= 3.10.3 to avoid DeprecationWarnings
            transform_ctx = QgsProject.instance().transformContext()
            options = QgsVectorFileWriter.SaveVectorOptions()
            options.fileEncoding = "UTF-8"
            options.attributes = attrs
            options.driverName = "ESRI Shapefile" if ext == EXT_SHAPEFILE else ""
            QgsVectorFileWriter.writeAsVectorFormatV2(layer, output,
                                                      transform_ctx, options)
        if log is not None:
            log.logInfo(
                QCoreApplication.translate(
                    "GeocatBridge",
                    f"Layer {destFilename} exported to {output}"))
        return output
    else:
        # Export raster
        if force or not filename.lower().endswith("tif"):
            output = path or tempFilenameInTempFolder(destFilename + ".tif")
            writer = QgsRasterFileWriter(output)
            writer.setOutputFormat("GTiff")
            writer.writeRaster(layer.pipe(), layer.width(), layer.height(),
                               layer.extent(), layer.crs())
            del writer
            if log is not None:
                log.logInfo(
                    QCoreApplication.translate(
                        "GeocatBridge",
                        f"Layer {destFilename} exported to {output}"))
            return output
        else:
            if log is not None:
                log.logInfo(
                    QCoreApplication.translate(
                        "GeocatBridge",
                        f"No need to export layer {destFilename} stored at {filename}"
                    ))
            return filename