2

I am developing a QGIS plugin. Part of the plugin generates some memory layers that the user interacts with. When the user is done with the project session, there is a button to save the memory layers to a geopackage. I have successfully written the memory layers to the geopackage.

I also have a button for the user to load the geopackage layers back into memory when they open the project back up. The reason to load the layers into memory is 1) for speed for when the layer data gets loaded into a calculation engine and 2) so that if the user damages the layers somehow, they can just reload the layers again from the geopackage and just start the session over.

I have tried:

transform_context = QgsProject.instance().transformContext()
vector_save_options = QgsVectorFileWriter.SaveVectorOptions()
layer = QgsVectorLayer(db_path, 'Pipes', 'ogr')
vector_save_options.layerName = 'Pipes'
QgsVectorFileWriter.writeAsVectorFormatV3(layer, 'memory', transform_context, vector_save_options)

The problem is that this seems to just create a geopackage named "memory.gpkg" in the project directory. I feel like I have done a pretty thorough search of this site and the QGIS and pyQGIS documentation but am coming up with no solutions.

I would also say that I could just create an empty memory layer again and manually load each feature from the geopackage version to the memory version but this seems like it would be slow and not the best way to do it

  • Welcome to GIS SE. As a new user, please take the [Tour]. Comments exist so that others can request clarifications. Please do not comment on your own Question. Instead [Edit] the Question. – Vince Jan 07 '23 at 15:02
  • This should help you: https://gis.stackexchange.com/questions/205947/duplicating-layer-in-memory-using-pyqgis Check out Taras answer about layer.materialize() – MrXsquared Jan 07 '23 at 15:54
  • That looks promising. I will report back. It also looks like that method is included in a cheat sheet that I just found by googling "materialize". https://github.com/All4Gis/QGIS-cheat-sheet/blob/master/QGIS3.md Materialize method looks like it comes from the QgsFeatureSource base class. https://qgis.org/pyqgis/3.2/core/Feature/QgsFeatureSource.html – Mark Wilson Jan 07 '23 at 16:38

1 Answers1

2

Thanks to @MrXsquared and @Taras.

My final code that works:

    def load_db_layers_from_gpkg(self):
        db_path = os.path.join(self.project.project_data_dir(), DB_NAME)
        for layername in ['Pipes', 'Tanks', 'Reservoirs', 'Junctions', 'ValveLinks', 'PumpLinks', 'ValveNodes', 'PumpNodes',
                      'Demand_BASE', 'Status', 'Controls', 'Rules', 'Pump_Patterns', 'Patterns', 'Curves',
                      'Options']:
            uri = f'{db_path}|layername={layername}'
            gpkg_layer = QgsVectorLayer(uri, layername, 'ogr')
            request = QgsFeatureRequest().setFilterFids(gpkg_layer.allFeatureIds())
            self.layer_objects[layername] = gpkg_layer.materialize(request)
            del gpkg_layer