Skip to content

Commit 7e20fe4

Browse files
committedJan 27, 2018
make converting to multi geometries to fullfil provider geometry
constraints the last step and use earlier conversions (fixes #17643)
1 parent 72ca8d7 commit 7e20fe4

File tree

3 files changed

+43
-16
lines changed

3 files changed

+43
-16
lines changed
 

‎src/core/geometry/qgsgeometrycollection.cpp‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -852,5 +852,7 @@ int QgsGeometryCollection::childCount() const
852852

853853
QgsAbstractGeometry *QgsGeometryCollection::childGeometry( int index ) const
854854
{
855+
if ( index < 0 || index > mGeometries.count() )
856+
return nullptr;
855857
return mGeometries.at( index );
856858
}

‎src/core/qgsvectordataprovider.cpp‎

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -725,17 +725,6 @@ QgsGeometry QgsVectorDataProvider::convertToProviderType( const QgsGeometry &geo
725725
}
726726
}
727727

728-
//convert to multitype if necessary
729-
if ( QgsWkbTypes::isMultiType( providerGeomType ) && !QgsWkbTypes::isMultiType( geometry->wkbType() ) )
730-
{
731-
outputGeom = QgsGeometryFactory::geomFromWkbType( providerGeomType );
732-
QgsGeometryCollection *geomCollection = qgsgeometry_cast<QgsGeometryCollection *>( outputGeom.get() );
733-
if ( geomCollection )
734-
{
735-
geomCollection->addGeometry( geometry->clone() );
736-
}
737-
}
738-
739728
//convert to curved type if necessary
740729
if ( !QgsWkbTypes::isCurvedType( geometry->wkbType() ) && QgsWkbTypes::isCurvedType( providerGeomType ) )
741730
{
@@ -749,14 +738,27 @@ QgsGeometry QgsVectorDataProvider::convertToProviderType( const QgsGeometry &geo
749738
//convert to linear type from curved type
750739
if ( QgsWkbTypes::isCurvedType( geometry->wkbType() ) && !QgsWkbTypes::isCurvedType( providerGeomType ) )
751740
{
752-
QgsAbstractGeometry *segmentizedGeom = nullptr;
753-
segmentizedGeom = outputGeom ? outputGeom->segmentize() : geometry->segmentize();
741+
QgsAbstractGeometry *segmentizedGeom = outputGeom ? outputGeom->segmentize() : geometry->segmentize();
754742
if ( segmentizedGeom )
755743
{
756744
outputGeom.reset( segmentizedGeom );
757745
}
758746
}
759747

748+
//convert to multitype if necessary
749+
if ( QgsWkbTypes::isMultiType( providerGeomType ) && !QgsWkbTypes::isMultiType( geometry->wkbType() ) )
750+
{
751+
std::unique_ptr< QgsAbstractGeometry > collGeom( QgsGeometryFactory::geomFromWkbType( providerGeomType ) );
752+
QgsGeometryCollection *geomCollection = qgsgeometry_cast<QgsGeometryCollection *>( collGeom.get() );
753+
if ( geomCollection )
754+
{
755+
if ( geomCollection->addGeometry( outputGeom ? outputGeom->clone() : geometry->clone() ) )
756+
{
757+
outputGeom.reset( collGeom.release() );
758+
}
759+
}
760+
}
761+
760762
//set z/m types
761763
if ( QgsWkbTypes::hasZ( providerGeomType ) )
762764
{
@@ -766,6 +768,7 @@ QgsGeometry QgsVectorDataProvider::convertToProviderType( const QgsGeometry &geo
766768
}
767769
outputGeom->addZValue();
768770
}
771+
769772
if ( QgsWkbTypes::hasM( providerGeomType ) )
770773
{
771774
if ( !outputGeom )
@@ -779,6 +782,7 @@ QgsGeometry QgsVectorDataProvider::convertToProviderType( const QgsGeometry &geo
779782
{
780783
return QgsGeometry( outputGeom.release() );
781784
}
785+
782786
return QgsGeometry();
783787
}
784788

‎tests/src/python/test_provider_postgres.py‎

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,9 @@
3737
QgsReadWriteContext,
3838
QgsRectangle,
3939
QgsDefaultValue,
40-
QgsDataSourceUri,
41-
QgsProject
40+
QgsProject,
41+
QgsWkbTypes,
42+
QgsGeometry
4243
)
4344
from qgis.gui import QgsGui
4445
from qgis.PyQt.QtCore import QDate, QTime, QDateTime, QVariant, QDir, QObject
@@ -807,7 +808,7 @@ def _test(table, schema=None):
807808

808809
table = ("%s" % table) if schema is None else ("\"%s\".\"%s\"" % (schema, table))
809810
dest_uri = "%s sslmode=disable table=%s (geom) sql" % (self.dbconn, table)
810-
err = QgsVectorLayerExporter.exportLayer(lyr, dest_uri, "postgres", lyr.crs())
811+
QgsVectorLayerExporter.exportLayer(lyr, dest_uri, "postgres", lyr.crs())
811812
olyr = QgsVectorLayer(dest_uri, "y", "postgres")
812813
self.assertTrue(olyr.isValid(), "Failed URI: %s" % dest_uri)
813814

@@ -1035,6 +1036,26 @@ def testStyleDatabaseWithService(self):
10351036
ids = styles[1]
10361037
self.assertEqual(len(ids), 0)
10371038

1039+
def testCurveToMultipolygon(self):
1040+
self.execSQLCommand('CREATE TABLE IF NOT EXISTS multicurve(pk SERIAL NOT NULL PRIMARY KEY, geom public.geometry(MultiPolygon, 4326))')
1041+
self.execSQLCommand('TRUNCATE multicurve')
1042+
1043+
vl = QgsVectorLayer(self.dbconn + ' sslmode=disable key=\'pk\' srid=4326 type=MULTIPOLYGON table="multicurve" (geom) sql=', 'test', 'postgres')
1044+
1045+
f = QgsFeature(vl.fields())
1046+
f.setGeometry(QgsGeometry.fromWkt('CurvePolygon(CircularString (20 30, 50 30, 50 90, 10 50, 20 30))'))
1047+
self.assertTrue(vl.startEditing())
1048+
self.assertTrue(vl.addFeatures([f]))
1049+
self.assertTrue(vl.commitChanges())
1050+
1051+
f = next(vl.getFeatures(QgsFeatureRequest()))
1052+
1053+
g = f.geometry().constGet()
1054+
self.assertTrue(g)
1055+
self.assertEqual(g.wkbType(), QgsWkbTypes.MultiPolygon)
1056+
self.assertEqual(g.childCount(), 1)
1057+
self.assertTrue(g.childGeometry(0).vertexCount() > 3)
1058+
10381059

10391060
class TestPyQgsPostgresProviderCompoundKey(unittest.TestCase, ProviderTestCase):
10401061

0 commit comments

Comments
 (0)
Please sign in to comment.