5

QgsVectorFileWriter allows you to overwrite an existing layer with your output, but I have not found a similar option with QgsRasterFileWriter. Here's my code that is writing a raster layer out to a geopackage:

ds = ogr.Open(gpkg, True)
pipe = QgsRasterPipe()
provider=layer_in.dataProvider()

file_writer = QgsRasterFileWriter(gpkg)
file_writer.setOutputFormat('gpkg')
file_writer.setCreateOptions([f"RASTER_TABLE={layer_name}", 'APPEND_SUBDATASET=YES'])

if pipe.set(provider.clone()):
    projector = QgsRasterProjector()
    projector.setCrs(provider.crs(), provider.crs())
    if pipe.insert(2, projector) is True:
        if file_writer.writeRaster(pipe, provider.xSize(),provider.ySize(),provider.extent(),provider.crs()) == 0:
                feedback.pushInfo(f"ok")
        else:
                feedback.pushInfo(f"error: {file_writer.writeRaster(pipe, provider.xSize(),provider.ySize(),provider.extent(),provider.crs())}   {help(file_writer.setCreateOptions)}")
ds = None
1
  • Overwriting a raster layer in geopackage is not supported in the GPKG raster driver. Do you know the name of the existing layer?
    – Dror Bogin
    Commented Nov 1, 2020 at 7:17

1 Answer 1

2
+50

I tried looking for the overwrite creation option in the GPKG Raster provider details in GDAL.
It seems it does not exist, as opposed to GPKG Vector.

You can however delete the raster layer from the GeoPackage and then write one with the same name.
This part will delete the raster from the GeoPackage by name:

import os
import sqlite3
gpkg = 'path/to/your/db.gpkg'
layer_name= 'superawesomeraster'


conn = sqlite3.connect(gpkg)
conn.execute('DROP TABLE IF EXISTS {}'.format(layer_name))
conn.execute('DELETE FROM gpkg_2d_gridded_coverage_ancillary WHERE tile_matrix_set_name = "{}"'.format(layer_name))
conn.execute('DELETE FROM gpkg_2d_gridded_tile_ancillary WHERE tpudt_name="{}"'.format(layer_name));
conn.execute('DELETE FROM gpkg_tile_matrix WHERE table_name="{}"'.format(layer_name));
conn.execute('DELETE FROM gpkg_tile_matrix_set WHERE table_name="{}"'.format(layer_name));
conn.execute('DELETE FROM gpkg_contents WHERE table_name="{}"'.format(layer_name));
conn.execute('DELETE FROM gpkg_extensions WHERE table_name="{}"'.format(layer_name));
conn.commit()
conn.execute('VACUUM')

conn.close()

And this part will use GDAL CLI to save your input to the GeoPackage. I have never used the QgsRasterFileWriter class but your code seems like it will be valid if the GeoPackage will allow writing (which should be possible if all the previous values are cleared).
This GDAL statement does the exact same thing if you use the correct source.

# layer_in = iface.activeLayer() # Using the currently active raster as input
inputRas = layer_in.source()
outputRas = gpkg
gdal_string = 'gdal_translate -of GPKG "{}" "{}" -co RASTER_TABLE={} -co APPEND_SUBDATASET=YES'.format(inputRas, outputRas,lyr) 
os.system(gdal_string)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.