Skip to content

Commit

Permalink
make converting to multi geometries to fullfil provider geometry
Browse files Browse the repository at this point in the history
constraints the last step and use earlier conversions (fixes #17643)
  • Loading branch information
jef-n committed Jan 27, 2018
1 parent 72ca8d7 commit 7e20fe4
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 16 deletions.
2 changes: 2 additions & 0 deletions src/core/geometry/qgsgeometrycollection.cpp
Expand Up @@ -852,5 +852,7 @@ int QgsGeometryCollection::childCount() const


QgsAbstractGeometry *QgsGeometryCollection::childGeometry( int index ) const QgsAbstractGeometry *QgsGeometryCollection::childGeometry( int index ) const
{ {
if ( index < 0 || index > mGeometries.count() )
return nullptr;
return mGeometries.at( index ); return mGeometries.at( index );
} }
30 changes: 17 additions & 13 deletions src/core/qgsvectordataprovider.cpp
Expand Up @@ -725,17 +725,6 @@ QgsGeometry QgsVectorDataProvider::convertToProviderType( const QgsGeometry &geo
} }
} }


//convert to multitype if necessary
if ( QgsWkbTypes::isMultiType( providerGeomType ) && !QgsWkbTypes::isMultiType( geometry->wkbType() ) )
{
outputGeom = QgsGeometryFactory::geomFromWkbType( providerGeomType );
QgsGeometryCollection *geomCollection = qgsgeometry_cast<QgsGeometryCollection *>( outputGeom.get() );
if ( geomCollection )
{
geomCollection->addGeometry( geometry->clone() );
}
}

//convert to curved type if necessary //convert to curved type if necessary
if ( !QgsWkbTypes::isCurvedType( geometry->wkbType() ) && QgsWkbTypes::isCurvedType( providerGeomType ) ) if ( !QgsWkbTypes::isCurvedType( geometry->wkbType() ) && QgsWkbTypes::isCurvedType( providerGeomType ) )
{ {
Expand All @@ -749,14 +738,27 @@ QgsGeometry QgsVectorDataProvider::convertToProviderType( const QgsGeometry &geo
//convert to linear type from curved type //convert to linear type from curved type
if ( QgsWkbTypes::isCurvedType( geometry->wkbType() ) && !QgsWkbTypes::isCurvedType( providerGeomType ) ) if ( QgsWkbTypes::isCurvedType( geometry->wkbType() ) && !QgsWkbTypes::isCurvedType( providerGeomType ) )
{ {
QgsAbstractGeometry *segmentizedGeom = nullptr; QgsAbstractGeometry *segmentizedGeom = outputGeom ? outputGeom->segmentize() : geometry->segmentize();
segmentizedGeom = outputGeom ? outputGeom->segmentize() : geometry->segmentize();
if ( segmentizedGeom ) if ( segmentizedGeom )
{ {
outputGeom.reset( segmentizedGeom ); outputGeom.reset( segmentizedGeom );
} }
} }


//convert to multitype if necessary
if ( QgsWkbTypes::isMultiType( providerGeomType ) && !QgsWkbTypes::isMultiType( geometry->wkbType() ) )
{
std::unique_ptr< QgsAbstractGeometry > collGeom( QgsGeometryFactory::geomFromWkbType( providerGeomType ) );
QgsGeometryCollection *geomCollection = qgsgeometry_cast<QgsGeometryCollection *>( collGeom.get() );
if ( geomCollection )
{
if ( geomCollection->addGeometry( outputGeom ? outputGeom->clone() : geometry->clone() ) )
{
outputGeom.reset( collGeom.release() );
}
}
}

//set z/m types //set z/m types
if ( QgsWkbTypes::hasZ( providerGeomType ) ) if ( QgsWkbTypes::hasZ( providerGeomType ) )
{ {
Expand All @@ -766,6 +768,7 @@ QgsGeometry QgsVectorDataProvider::convertToProviderType( const QgsGeometry &geo
} }
outputGeom->addZValue(); outputGeom->addZValue();
} }

if ( QgsWkbTypes::hasM( providerGeomType ) ) if ( QgsWkbTypes::hasM( providerGeomType ) )
{ {
if ( !outputGeom ) if ( !outputGeom )
Expand All @@ -779,6 +782,7 @@ QgsGeometry QgsVectorDataProvider::convertToProviderType( const QgsGeometry &geo
{ {
return QgsGeometry( outputGeom.release() ); return QgsGeometry( outputGeom.release() );
} }

return QgsGeometry(); return QgsGeometry();
} }


Expand Down
27 changes: 24 additions & 3 deletions tests/src/python/test_provider_postgres.py
Expand Up @@ -37,8 +37,9 @@
QgsReadWriteContext, QgsReadWriteContext,
QgsRectangle, QgsRectangle,
QgsDefaultValue, QgsDefaultValue,
QgsDataSourceUri, QgsProject,
QgsProject QgsWkbTypes,
QgsGeometry
) )
from qgis.gui import QgsGui from qgis.gui import QgsGui
from qgis.PyQt.QtCore import QDate, QTime, QDateTime, QVariant, QDir, QObject from qgis.PyQt.QtCore import QDate, QTime, QDateTime, QVariant, QDir, QObject
Expand Down Expand Up @@ -807,7 +808,7 @@ def _test(table, schema=None):


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


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


def testCurveToMultipolygon(self):
self.execSQLCommand('CREATE TABLE IF NOT EXISTS multicurve(pk SERIAL NOT NULL PRIMARY KEY, geom public.geometry(MultiPolygon, 4326))')
self.execSQLCommand('TRUNCATE multicurve')

vl = QgsVectorLayer(self.dbconn + ' sslmode=disable key=\'pk\' srid=4326 type=MULTIPOLYGON table="multicurve" (geom) sql=', 'test', 'postgres')

f = QgsFeature(vl.fields())
f.setGeometry(QgsGeometry.fromWkt('CurvePolygon(CircularString (20 30, 50 30, 50 90, 10 50, 20 30))'))
self.assertTrue(vl.startEditing())
self.assertTrue(vl.addFeatures([f]))
self.assertTrue(vl.commitChanges())

f = next(vl.getFeatures(QgsFeatureRequest()))

g = f.geometry().constGet()
self.assertTrue(g)
self.assertEqual(g.wkbType(), QgsWkbTypes.MultiPolygon)
self.assertEqual(g.childCount(), 1)
self.assertTrue(g.childGeometry(0).vertexCount() > 3)



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


Expand Down

0 comments on commit 7e20fe4

Please sign in to comment.