New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
GDAL/OGR vector geoprocessing algorithms not working with GPKG, SQLite, FileGDB, etc inputs #27760
Comments
Author Name: Giovanni Manghi (@gioman) I have nticed this too today, while trying to import data in PostGIS using the ogr based tools. Your analysis is correct, anyway there are cases (not yet sure how/why) where the datasources like gpkg, sqlite, shapes are NOT translated to a temporary INPUT.shp, and so the tools works. On the other hand it seems that PostGIS inputs are completely broken for such tools. More notes to come.
|
Author Name: Giovanni Manghi (@gioman) Processing seems to work in different ways, depending on how a datasource like a gpkg, SL or shp was loaded in the project:
GDAL command: Execution completed in 47.39 seconds
|
Author Name: Giovanni Manghi (@gioman)
See the following error for GDAL "Buffer vector" alg. as example, with a GPKG input vector layer:
It seems that before the GDAL/OGR vector geoprocessing algs run their tasks, every input layer contained in GPKG, SQLite, FileGDB, is converted in a temporary INPUT.SHP shapefile which is used as new input layer for the ogr2ogr command. This happens because in QgsProcessingUtils::convertToCompatibleFormat the layer suffix (QFileInfo.suffix()) for those layer types is something like: 'gpkg|layername=points_layer' and this string does not match with any of the QgsVectorFileWriter.supportedFormatExtensions(), due to the presence of "|layername=points_layer", leading to always convert (translate) those types of layers in the temporary shapefile INPUT.SHP. If this is a bug, I think it could be fixed in QgsProcessingUtils::convertToCompatibleFormat just changing QFileInfo fi( vl->source() ); requiresTranslation = !compatibleFormats.contains( fi.suffix(), Qt::CaseInsensitive ); with QFileInfo fi( vl->source() ); requiresTranslation = !compatibleFormats.contains( fi.suffix().split('|')[0], Qt::CaseInsensitive ); Anyway, algorithms fail to properly build the sql statement: in fact if INPUT.SHP must be used as new input layer, then the table name after FROM should be 'INPUT' and not the original layer name 'points_layer'. This problem could be fixed in https://github.com/qgis/QGIS/blob/master/python/plugins/processing/algs/gdal/GdalAlgorithm.py#L104-L109 # parameter is a vector layer, with OGR data provider # so extract selection if required ogr_data_path = self.parameterAsCompatibleSourceLayerPath(parameters, parameter_name, context, QgsVectorFileWriter.supportedFormatExtensions(), feedback=feedback) ogr_layer_name = GdalUtils.ogrLayerName(input_layer.dataProvider().dataSourceUri()) where ogr_layer_name = GdalUtils.ogrLayerName(input_layer.dataProvider().dataSourceUri()) should be ogr_layer_name = GdalUtils.ogrLayerName(ogr_data_path) This works for me, changing my local copy of GdalAlgorithm.py, but I cannot say if this is the right way to solve the problem or if it's possible to completely avoid the needing of convert GPKG, SQLite, FileGDB layers, and probably other formats, to a temporary shapefile. Moreover, it is not possible to add the output layer to an exiting GPKG, SQLite... container without completely overwrite it. Furthermore, it is not possible to properly select a layer ("Select file" in the algorithm window) from GPKG, SQLite, FileGDB containers in the case it is not already present in the map. to See also https://issues.qgis.org/issues/19938#note-4 for a better understanding of the issue. Original description: The GDAL/OGR vector geoprocessing algorithms do not work with GPKG, SQLite, FileGDB, (probably other formats), as input vector layer. See the following error for GDAL "Buffer vector" alg. as example, with a GPKG input vector layer:
It seems that before the GDAL/OGR vector geoprocessing algs run their tasks, every input layer contained in GPKG, SQLite, FileGDB, is converted in a temporary INPUT.SHP shapefile which is used as new input layer for the ogr2ogr command. This happens because in QgsProcessingUtils::convertToCompatibleFormat the layer suffix (QFileInfo.suffix()) for those layer types is something like: 'gpkg|layername=points_layer' and this string does not match with any of the QgsVectorFileWriter.supportedFormatExtensions(), due to the presence of "|layername=points_layer", leading to always convert (translate) those types of layers in the temporary shapefile INPUT.SHP. If this is a bug, I think it could be fixed in QgsProcessingUtils::convertToCompatibleFormat just changing QFileInfo fi( vl->source() ); requiresTranslation = !compatibleFormats.contains( fi.suffix(), Qt::CaseInsensitive ); with QFileInfo fi( vl->source() ); requiresTranslation = !compatibleFormats.contains( fi.suffix().split('|')[0], Qt::CaseInsensitive ); Anyway, algorithms fail to properly build the sql statement: in fact if INPUT.SHP must be used as new input layer, then the table name after FROM should be 'INPUT' and not the original layer name 'points_layer'. This problem could be fixed in https://github.com/qgis/QGIS/blob/master/python/plugins/processing/algs/gdal/GdalAlgorithm.py#L104-L109 # parameter is a vector layer, with OGR data provider # so extract selection if required ogr_data_path = self.parameterAsCompatibleSourceLayerPath(parameters, parameter_name, context, QgsVectorFileWriter.supportedFormatExtensions(), feedback=feedback) ogr_layer_name = GdalUtils.ogrLayerName(input_layer.dataProvider().dataSourceUri()) where ogr_layer_name = GdalUtils.ogrLayerName(input_layer.dataProvider().dataSourceUri()) should be ogr_layer_name = GdalUtils.ogrLayerName(ogr_data_path) This works for me, changing my local copy of GdalAlgorithm.py, but I cannot say if this is the right way to solve the problem or if it's possible to completely avoid the needing of convert GPKG, SQLite, FileGDB layers, and probably other formats, to a temporary shapefile. Moreover, it is not possible to add the output layer to an exiting GPKG, SQLite... container without completely overwrite it. Furthermore, it is not possible to properly select a layer ("Select file" in the algorithm window) from GPKG, SQLite, FileGDB containers in the case it is not already present in the map.
|
Author Name: Andrea Giudiceandrea (@agiudiceandrea) Giovanni Manghi wrote:
During my tests, this only happens when there is only 1 layer in a gpkg/sqlite container and it is added to the map through the Data Source Manager / Vector or dragging and dropping it in the map from outside. In fact, in this case (e.g. test_polygons.gpkg with only 1 layer named 'polygons') the layer is added with a source like 'test_polygons.gpkg' (instead of a more correct 'test_polygons.gpkg|layername=polygons') and so the suffix string will be 'gpkg' which is in QgsVectorFileWriter.supportedFormatExtensions() thus QgsProcessingUtils::convertToCompatibleFormat will not covert it in a temporary shapefile. When the layer in a single layer gpkg/sqlite container is added to the map through the Browser panel instead, its source will be 'test_polygons.gpkg|layername=polygons'. |
Author Name: Nyall Dawson (@nyalldawson)
|
Author Name: Nyall Dawson (@nyalldawson) See #8028 -- testing would be appreciated! |
Author Name: Jürgen Fischer (@jef-n)
Original description: The GDAL/OGR vector geoprocessing algorithms do not work with GPKG, SQLite, FileGDB, (probably other formats), as input vector layer. See the following error for GDAL "Buffer vector" alg. as example, with a GPKG input vector layer:
It seems that before the GDAL/OGR vector geoprocessing algs run their tasks, every input layer contained in GPKG, SQLite, FileGDB, is converted in a temporary INPUT.SHP shapefile which is used as new input layer for the ogr2ogr command. This happens because in QgsProcessingUtils::convertToCompatibleFormat the layer suffix (QFileInfo.suffix()) for those layer types is something like: 'gpkg|layername=points_layer' and this string does not match with any of the QgsVectorFileWriter.supportedFormatExtensions(), due to the presence of "|layername=points_layer", leading to always convert (translate) those types of layers in the temporary shapefile INPUT.SHP. If this is a bug, I think it could be fixed in QgsProcessingUtils::convertToCompatibleFormat just changing QFileInfo fi( vl->source() ); requiresTranslation = !compatibleFormats.contains( fi.suffix(), Qt::CaseInsensitive ); with QFileInfo fi( vl->source() ); requiresTranslation = !compatibleFormats.contains( fi.suffix().split('|')[0], Qt::CaseInsensitive ); Anyway, algorithms fail to properly build the sql statement: in fact if INPUT.SHP must be used as new input layer, then the table name after FROM should be 'INPUT' and not the original layer name 'points_layer'. This problem could be fixed in https://github.com/qgis/QGIS/blob/master/python/plugins/processing/algs/gdal/GdalAlgorithm.py#L104-L109 # parameter is a vector layer, with OGR data provider # so extract selection if required ogr_data_path = self.parameterAsCompatibleSourceLayerPath(parameters, parameter_name, context, QgsVectorFileWriter.supportedFormatExtensions(), feedback=feedback) ogr_layer_name = GdalUtils.ogrLayerName(input_layer.dataProvider().dataSourceUri()) where ogr_layer_name = GdalUtils.ogrLayerName(input_layer.dataProvider().dataSourceUri()) should be ogr_layer_name = GdalUtils.ogrLayerName(ogr_data_path) This works for me, changing my local copy of GdalAlgorithm.py, but I cannot say if this is the right way to solve the problem or if it's possible to completely avoid the needing of convert GPKG, SQLite, FileGDB layers, and probably other formats, to a temporary shapefile. Moreover, it is not possible to add the output layer to an exiting GPKG, SQLite... container without completely overwrite it. Furthermore, it is not possible to properly select a layer ("Select file" in the algorithm window) from GPKG, SQLite, FileGDB containers in the case it is not already present in the map. to See also #27760 (comment) for a better understanding of the issue. Original description: The GDAL/OGR vector geoprocessing algorithms do not work with GPKG, SQLite, FileGDB, (probably other formats), as input vector layer. See the following error for GDAL "Buffer vector" alg. as example, with a GPKG input vector layer: Processing algorithm… Algorithm 'Buffer vectors' starting… Input parameters: { 'DISSOLVE' : False, 'DISTANCE' : 10, 'EXPLODE_COLLECTIONS' : False, 'FIELD' : None, 'GEOMETRY' : 'geometry', *'INPUT' : 'C:\\test\\demo\\test.gpkg|layername=points_layer'*, 'OPTIONS' : '', 'OUTPUT' : 'C:/Users/Andrea/AppData/Local/Temp/processing_a2e42c246f5c42e7b34ff0883d38d602/d685014df90f4511a2d43058c7d3cc2e/OUTPUT.shp' } GDAL command: ogr2ogr C:/Users/Andrea/AppData/Local/Temp/processing_a2e42c246f5c42e7b34ff0883d38d602/d685014df90f4511a2d43058c7d3cc2e/OUTPUT.shp *C:/Users/Andrea/AppData/Local/Temp/processing_a2e42c246f5c42e7b34ff0883d38d602/2e08c2dab752494ebc42763c1f331c53/INPUT.shp* -dialect sqlite -sql "SELECT ST_Buffer(geometry, 10.0) AS geometry, fid,field1 FROM *'points_layer'*" -f "ESRI Shapefile" GDAL command output: ERROR 1: In ExecuteSQL(): sqlite3_prepare_v2(SELECT ST_Buffer(geometry, 10.0) AS geometry, fid,field1 FROM 'points_layer'): *no such table: points_layer* It seems that before the GDAL/OGR vector geoprocessing algs run their tasks, every input layer contained in GPKG, SQLite, FileGDB, is converted in a temporary INPUT.SHP shapefile which is used as new input layer for the ogr2ogr command. This happens because in QgsProcessingUtils::convertToCompatibleFormat the layer suffix (QFileInfo.suffix()) for those layer types is something like: 'gpkg|layername=points_layer' and this string does not match with any of the QgsVectorFileWriter.supportedFormatExtensions(), due to the presence of "|layername=points_layer", leading to always convert (translate) those types of layers in the temporary shapefile INPUT.SHP. If this is a bug, I think it could be fixed in QgsProcessingUtils::convertToCompatibleFormat just changing QFileInfo fi( vl->source() ); requiresTranslation = !compatibleFormats.contains( fi.suffix(), Qt::CaseInsensitive ); with QFileInfo fi( vl->source() ); requiresTranslation = !compatibleFormats.contains( fi.suffix().split('|')[0], Qt::CaseInsensitive ); Anyway, algorithms fail to properly build the sql statement: in fact if INPUT.SHP must be used as new input layer, then the table name after FROM should be 'INPUT' and not the original layer name 'points_layer'. This problem could be fixed in https://github.com/qgis/QGIS/blob/master/python/plugins/processing/algs/gdal/GdalAlgorithm.py#L104-L109 # parameter is a vector layer, with OGR data provider # so extract selection if required ogr_data_path = self.parameterAsCompatibleSourceLayerPath(parameters, parameter_name, context, QgsVectorFileWriter.supportedFormatExtensions(), feedback=feedback) ogr_layer_name = GdalUtils.ogrLayerName(input_layer.dataProvider().dataSourceUri()) where ogr_layer_name = GdalUtils.ogrLayerName(input_layer.dataProvider().dataSourceUri()) should be ogr_layer_name = GdalUtils.ogrLayerName(ogr_data_path) This works for me, changing my local copy of GdalAlgorithm.py, but I cannot say if this is the right way to solve the problem or if it's possible to completely avoid the needing of convert GPKG, SQLite, FileGDB layers, and probably other formats, to a temporary shapefile. Moreover, it is not possible to add the output layer to an exiting GPKG, SQLite... container without completely overwrite it. Furthermore, it is not possible to properly select a layer ("Select file" in the algorithm window) from GPKG, SQLite, FileGDB containers in the case it is not already present in the map. |
Author Name: Andrea Giudiceandrea (@agiudiceandrea) Nyall Dawson wrote:
Unfortunately, I cannot test it before it is merged. |
Author Name: Jürgen Fischer (@jef-n)
|
Author Name: Jürgen Fischer (@jef-n)
|
Author Name: Giovanni Manghi (@gioman) Andrea Giudiceandrea wrote:
just extract the processing folder from here https://github.com/nyalldawson/QGIS/archive/gdal_layers.zip and drop it in the QGIS plugins folder. Then restart QGIS and test it, after it remove the processing folder inside the plugins one, otherwise this will mask processing as it is shipped by qgis installer. |
Author Name: Nyall Dawson (@nyalldawson) That process won't work here - there's core changes too |
Author Name: Andrea Giudiceandrea (@agiudiceandrea) Andrea Giudiceandrea wrote:
Nyall, will your PR also address those two additional problems or should I issue as many new separate bug reports? |
Author Name: Nyall Dawson (@nyalldawson) Applied in changeset 737ab30.
|
Author Name: Andrea Giudiceandrea (@agiudiceandrea) Andrea Giudiceandrea wrote:
See Andrea Giudiceandrea wrote:
See #27853 "The only layer contained in a singlelayer GPKG / SQLite / FileGDB is incorrectly added to the map without "|layername=" in some circumstances" |
Author Name: Andrea Giudiceandrea (@agiudiceandrea)
Original Redmine Issue: 19938
Affected QGIS version: 3.3(master)
Redmine category:processing/ogr
Assignee: Nyall Dawson
See also #27760-4 for a better understanding of the issue.
Original description:
The GDAL/OGR vector geoprocessing algorithms do not work with GPKG, SQLite, FileGDB, (probably other formats), as input vector layer.
See the following error for GDAL "Buffer vector" alg. as example, with a GPKG input vector layer:
It seems that before the GDAL/OGR vector geoprocessing algs run their tasks, every input layer contained in GPKG, SQLite, FileGDB, is converted in a temporary INPUT.SHP shapefile which is used as new input layer for the ogr2ogr command.
This happens because in QgsProcessingUtils::convertToCompatibleFormat the layer suffix (QFileInfo.suffix()) for those layer types is something like:
and this string does not match with any of the QgsVectorFileWriter.supportedFormatExtensions(), due to the presence of "|layername=points_layer", leading to always convert (translate) those types of layers in the temporary shapefile INPUT.SHP.
I don't know if this is a normal behaviour or a bug, but I think they can be normally used by ogr2ogr as input layer without conversion, provided we specify the right geometry column name.
If this is a bug, I think it could be fixed in QgsProcessingUtils::convertToCompatibleFormat just changing
with
Anyway, algorithms fail to properly build the sql statement: in fact if INPUT.SHP must be used as new input layer, then the table name after FROM should be 'INPUT' and not the original layer name 'points_layer'.
This problem could be fixed in https://github.com/qgis/QGIS/blob/master/python/plugins/processing/algs/gdal/GdalAlgorithm.py#L104-L109
where
should be
This works for me, changing my local copy of GdalAlgorithm.py, but I cannot say if this is the right way to solve the problem or if it's possible to completely avoid the needing of convert GPKG, SQLite, FileGDB layers, and probably other formats, to a temporary shapefile.
Moreover, it is not possible to add the output layer to an exiting GPKG, SQLite... container without completely overwrite it.
Furthermore, it is not possible to properly select a layer ("Select file" in the algorithm window) from GPKG, SQLite, FileGDB containers in the case it is not already present in the map.
Related issue(s): #27767 (relates), #27768 (relates)
Redmine related issue(s): 19945, 19946
The text was updated successfully, but these errors were encountered: