如何将列表中的图层(形状文件和 GTiff)导出到一个 gpkg 文件中?
它分别适用于矢量和栅格图层,但输出中仅保存一种类型的图层。
我已经意识到在编写栅格图层时哪些地理包不会更新,所以我决定创建临时地理包,然后更新 self.output
您可以在我的代码中看到下面的内容:
def save_as_gpkg(self, layers: List[QgsVectorLayer]):
for layer in layers:
layer_name = layer.name()
context = QgsProject.instance().transformContext()
if layer.type() == QgsMapLayer.VectorLayer:
options = QgsVectorFileWriter.SaveVectorOptions()
options.layerName = layer_name
options.fileEncoding = layer.dataProvider().encoding()
options.driverName = "GPKG"
if os.path.exists(self.output):
options.actionOnExistingFile = QgsVectorFileWriter.CreateOrOverwriteLayer
else:
options.actionOnExistingFile = QgsVectorFileWriter.CreateOrOverwriteFile
options.EditionCapability = 0
res = QgsVectorFileWriter.writeAsVectorFormatV3(layer,
self.output,
context,
options)
elif layer.type() == QgsMapLayer.RasterLayer:
if layer.isValid():
overwrite = [f"RASTER_TABLE={layer_name}",
"OVERWRITE=YES",
"APPEND_SUBDATASET=YES"]
if os.path.exists(self.output):
temp_gpkg = tempfile.NamedTemporaryFile(suffix='.gpkg', delete=False)
writer = QgsRasterFileWriter(temp_gpkg.name)
writer.setCreateOptions(overwrite)
pipe = QgsRasterPipe()
pipe.set(layer.dataProvider().clone())
res = writer.writeRaster(pipe, layer.width(), layer.height(),layer.extent(),
layer.crs(), context)
temp_gpkg.close()
raster_ds = gdal.Open(temp_gpkg.name)
raster_driver = gdal.GetDriverByName('GPKG')
new_raster_ds = raster_driver.Create(self.output, raster_ds.RasterXSize,
raster_ds.RasterYSize,
raster_ds.RasterCount,
gdal.GDT_Float32)
geotransform = raster_ds.GetGeoTransform()
new_raster_ds.SetGeoTransform(geotransform)
for i in range(1, raster_ds.RasterCount + 1):
band = raster_ds.GetRasterBand(i)
data = band.ReadAsArray()
new_raster_ds.GetRasterBand(i).WriteArray(data)
new_raster_ds.FlushCache()
else:
writer = QgsRasterFileWriter(self.output)
writer.setCreateOptions(overwrite)
pipe = QgsRasterPipe()
pipe.set(layer.dataProvider().clone())
res = writer.writeRaster(pipe, layer.width(), layer.height(), layer.extent(), layer.crs(), context)
有趣的是,这个字符串的工作原理是正确的:
QgsProject.instance().write(f"geopackage:{self.output}")
gdal.Translate(self.output, raster_dataset, format='GPKG',
creationOptions=['APPEND_SUBDATASET=YES'])
它有效。