Fix browser DD on GPKG/PG with multi geom

Fixes #32362
This commit is contained in:
Alessandro Pasotti 2019-10-23 16:35:26 +02:00
parent 3119209334
commit 2d5027b1ae
4 changed files with 69 additions and 7 deletions

View File

@ -267,6 +267,7 @@ QgsVectorLayerExporter::exportLayer( QgsVectorLayer *layer,
}
QgsFields fields = layer->fields();
QgsWkbTypes::Type wkbType = layer->wkbType();
// Special handling for Shapefiles
@ -286,9 +287,6 @@ QgsVectorLayerExporter::exportLayer( QgsVectorLayer *layer,
// convert wkbtype to multipart (see #5547)
switch ( wkbType )
{
case QgsWkbTypes::Point:
wkbType = QgsWkbTypes::MultiPoint;
break;
case QgsWkbTypes::LineString:
wkbType = QgsWkbTypes::MultiLineString;
break;

View File

@ -496,7 +496,6 @@ bool QgsGeoPackageItemGuiProvider::handleDropGeopackage( QgsGeoPackageCollection
options.insert( QStringLiteral( "update" ), true );
options.insert( QStringLiteral( "overwrite" ), true );
options.insert( QStringLiteral( "layerName" ), dropUri.name );
options.insert( QStringLiteral( "forceSinglePartGeometryType" ), true );
QgsVectorLayerExporterTask *exportTask = new QgsVectorLayerExporterTask( vectorSrcLayer, uri, QStringLiteral( "ogr" ), vectorSrcLayer->crs(), options, owner );
mainTask->addSubTask( exportTask, importTasks );
importTasks << exportTask;

View File

@ -272,9 +272,7 @@ bool QgsPGConnectionItem::handleDrop( const QMimeData *data, const QString &toSc
uri.setSchema( toSchema );
}
QVariantMap options;
options.insert( QStringLiteral( "forceSinglePartGeometryType" ), true );
std::unique_ptr< QgsVectorLayerExporterTask > exportTask( new QgsVectorLayerExporterTask( srcLayer, uri.uri( false ), QStringLiteral( "postgres" ), srcLayer->crs(), options, owner ) );
std::unique_ptr< QgsVectorLayerExporterTask > exportTask( new QgsVectorLayerExporterTask( srcLayer, uri.uri( false ), QStringLiteral( "postgres" ), srcLayer->crs(), QVariantMap(), owner ) );
// when export is successful:
connect( exportTask.get(), &QgsVectorLayerExporterTask::exportComplete, this, [ = ]()

View File

@ -1361,6 +1361,73 @@ class TestPyQgsOGRProviderGpkg(unittest.TestCase):
fids = set([f['fid'] for f in vl.getFeatures()])
self.assertEqual(len(fids), 1)
def testExportMultiFromShp(self):
"""Test if a Point is imported as single geom and MultiPoint as multi"""
single_tmpfile = os.path.join(self.basetestpath, 'testExportMultiFromShp_point.shp')
ds = ogr.GetDriverByName('ESRI Shapefile').CreateDataSource(single_tmpfile)
lyr = ds.CreateLayer('test', geom_type=ogr.wkbPoint)
lyr.CreateField(ogr.FieldDefn('str_field', ogr.OFTString))
f = ogr.Feature(lyr.GetLayerDefn())
f.SetGeometry(ogr.CreateGeometryFromWkt('POINT (0 0)'))
f.SetField('str_field', 'one')
lyr.CreateFeature(f)
f = ogr.Feature(lyr.GetLayerDefn())
f.SetGeometry(ogr.CreateGeometryFromWkt('POINT (1 1)'))
f.SetField('str_field', 'two')
lyr.CreateFeature(f)
f = None
ds = None
multi_tmpfile = os.path.join(self.basetestpath, 'testExportMultiFromShp_multipoint.shp')
ds = ogr.GetDriverByName('ESRI Shapefile').CreateDataSource(multi_tmpfile)
lyr = ds.CreateLayer('test', geom_type=ogr.wkbMultiPoint)
lyr.CreateField(ogr.FieldDefn('str_field', ogr.OFTString))
f = ogr.Feature(lyr.GetLayerDefn())
f.SetGeometry(ogr.CreateGeometryFromWkt('MULTIPOINT ((0 0))'))
f.SetField('str_field', 'one')
lyr.CreateFeature(f)
f = ogr.Feature(lyr.GetLayerDefn())
f.SetGeometry(ogr.CreateGeometryFromWkt('MULTIPOINT ((1 1), (2 2))'))
f.SetField('str_field', 'two')
lyr.CreateFeature(f)
f = None
ds = None
tmpfile = os.path.join(self.basetestpath, 'testExportMultiFromShpMulti.gpkg')
options = {}
options['driverName'] = 'GPKG'
lyr = QgsVectorLayer(multi_tmpfile, 'y', 'ogr')
self.assertTrue(lyr.isValid())
self.assertEqual(lyr.featureCount(), 2)
err, _ = QgsVectorLayerExporter.exportLayer(lyr, tmpfile, "ogr", lyr.crs(), False, options)
self.assertEqual(err, 0)
lyr = QgsVectorLayer(tmpfile, "y", "ogr")
self.assertTrue(lyr.isValid())
self.assertEqual(lyr.wkbType(), QgsWkbTypes.MultiPoint)
features = lyr.getFeatures()
f = next(features)
self.assertEqual(f.geometry().asWkt().upper(), 'MULTIPOINT ((0 0))')
f = next(features)
self.assertEqual(f.geometry().asWkt().upper(), 'MULTIPOINT ((1 1),(2 2))')
tmpfile = os.path.join(self.basetestpath, 'testExportMultiFromShpSingle.gpkg')
options = {}
options['driverName'] = 'GPKG'
lyr = QgsVectorLayer(single_tmpfile, 'y', 'ogr')
self.assertTrue(lyr.isValid())
self.assertEqual(lyr.featureCount(), 2)
err, _ = QgsVectorLayerExporter.exportLayer(lyr, tmpfile, "ogr", lyr.crs(), False, options)
self.assertEqual(err, 0)
lyr = QgsVectorLayer(tmpfile, "y", "ogr")
self.assertTrue(lyr.isValid())
self.assertEqual(lyr.wkbType(), QgsWkbTypes.Point)
features = lyr.getFeatures()
f = next(features)
self.assertEqual(f.geometry().asWkt().upper(), 'POINT (0 0)')
f = next(features)
self.assertEqual(f.geometry().asWkt().upper(), 'POINT (1 1)')
if __name__ == '__main__':
unittest.main()