Skip to content

Commit

Permalink
Merge pull request #35960 from qgis-bot/backport-35877-to-release-3_10
Browse files Browse the repository at this point in the history
[Backport release-3_10] QgsAbstractGeometry->segmentize() not returning correct WkbType for multi-geometries
  • Loading branch information
m-kuhn committed Apr 24, 2020
2 parents 6a27a82 + 20e18b8 commit ea2ec2b
Show file tree
Hide file tree
Showing 5 changed files with 210 additions and 2 deletions.
21 changes: 21 additions & 0 deletions python/core/auto_generated/geometry/qgswkbtypes.sip.in
Expand Up @@ -136,6 +136,8 @@ Returns the curve type for a WKB type. For example, for Polygon WKB types the cu

Returns `CompoundCurve` for `CircularString` (and its Z/M variants)

.. seealso:: :py:func:`linearType`

.. seealso:: :py:func:`isMultiType`

.. seealso:: :py:func:`isCurvedType`
Expand All @@ -148,6 +150,25 @@ Returns the curve type for a WKB type. For example, for Polygon WKB types the cu


.. versionadded:: 3.10
%End

static Type linearType( Type type );
%Docstring
Returns the linear type for a WKB type. For example, for a CompoundCurve, the linear type would be LineString.

.. seealso:: :py:func:`curveType`

.. seealso:: :py:func:`isMultiType`

.. seealso:: :py:func:`isCurvedType`

.. seealso:: :py:func:`singleType`

.. seealso:: :py:func:`flatType`

.. seealso:: :py:func:`multiType`

.. versionadded:: 3.14
%End

static Type flatType( Type type );
Expand Down
2 changes: 1 addition & 1 deletion src/core/geometry/qgsgeometrycollection.cpp
Expand Up @@ -735,7 +735,7 @@ bool QgsGeometryCollection::hasCurvedSegments() const

QgsAbstractGeometry *QgsGeometryCollection::segmentize( double tolerance, SegmentationToleranceType toleranceType ) const
{
std::unique_ptr< QgsAbstractGeometry > geom( QgsGeometryFactory::geomFromWkbType( mWkbType ) );
std::unique_ptr< QgsAbstractGeometry > geom( QgsGeometryFactory::geomFromWkbType( QgsWkbTypes::linearType( mWkbType ) ) );
QgsGeometryCollection *geomCollection = qgsgeometry_cast<QgsGeometryCollection *>( geom.get() );
if ( !geomCollection )
{
Expand Down
116 changes: 116 additions & 0 deletions src/core/geometry/qgswkbtypes.h
Expand Up @@ -429,6 +429,7 @@ class CORE_EXPORT QgsWkbTypes
*
* \note Returns `CompoundCurve` for `CircularString` (and its Z/M variants)
*
* \see linearType()
* \see isMultiType()
* \see isCurvedType()
* \see singleType()
Expand Down Expand Up @@ -566,6 +567,121 @@ class CORE_EXPORT QgsWkbTypes
return Unknown;
}

/**
* Returns the linear type for a WKB type. For example, for a CompoundCurve, the linear type would be LineString.
*
* \see curveType()
* \see isMultiType()
* \see isCurvedType()
* \see singleType()
* \see flatType()
* \see multiType()
*
* \since QGIS 3.14
*/
static Type linearType( Type type )
{
switch ( type )
{

case CircularString:
case CompoundCurve:
return LineString;

case CircularStringM:
case CompoundCurveM:
return LineStringM;

case CircularStringZ:
case CompoundCurveZ:
return LineStringZ;

case CircularStringZM:
case CompoundCurveZM:
return LineStringZM;

case MultiCurve:
return MultiLineString;

case MultiCurveM:
return MultiLineStringM;

case MultiCurveZ:
return MultiLineStringZ;

case MultiCurveZM:
return MultiLineStringZM;

case CurvePolygon:
return Polygon;

case CurvePolygonM:
return PolygonM;

case CurvePolygonZ:
return PolygonZ;

case CurvePolygonZM:
return PolygonZM;

case MultiSurface:
return MultiPolygon;

case MultiSurfaceM:
return MultiPolygonM;

case MultiSurfaceZ:
return MultiPolygonZ;

case MultiSurfaceZM:
return MultiPolygonZM;

case GeometryCollection:
case GeometryCollectionM:
case GeometryCollectionZ:
case GeometryCollectionZM:
case LineString:
case LineString25D:
case LineStringM:
case LineStringZ:
case LineStringZM:
case MultiLineString:
case MultiLineString25D:
case MultiLineStringM:
case MultiLineStringZ:
case MultiLineStringZM:
case MultiPoint:
case MultiPoint25D:
case MultiPointM:
case MultiPointZ:
case MultiPointZM:
case MultiPolygon:
case MultiPolygon25D:
case MultiPolygonM:
case MultiPolygonZ:
case MultiPolygonZM:
case NoGeometry:
case Point:
case Point25D:
case PointM:
case PointZ:
case PointZM:
case Polygon:
case Polygon25D:
case PolygonM:
case PolygonZ:
case PolygonZM:
case Triangle:
case TriangleM:
case TriangleZ:
case TriangleZM:
case Unknown:
return type;

}
return Unknown;
}

/**
* Returns the flat type for a WKB type. This is the WKB type minus any Z or M dimensions.
* For example, for PolygonZM WKB types the single type would be Polygon.
Expand Down
15 changes: 14 additions & 1 deletion tests/src/core/testqgsgeometry.cpp
Expand Up @@ -1740,7 +1740,6 @@ void TestQgsGeometry::circularString()
QVERIFY( !segmentized->isMeasure() );
QCOMPARE( segmentized->wkbType(), QgsWkbTypes::LineString );


//to/from WKB
QgsCircularString l15;
l15.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZM, 1, 2, 3, 4 )
Expand Down Expand Up @@ -13535,6 +13534,20 @@ void TestQgsGeometry::multiCurve()
QCOMPARE( ls->pointN( 0 ), QgsPoint( QgsWkbTypes::PointZM, 27, 53, 21, 52 ) );
QCOMPARE( ls->pointN( 1 ), QgsPoint( QgsWkbTypes::PointZM, 43, 43, 11, 5 ) );
QCOMPARE( ls->pointN( 2 ), QgsPoint( QgsWkbTypes::PointZM, 27, 37, 6, 2 ) );

// segmentize
QgsMultiCurve multiCurve2;
QgsCompoundCurve compoundCurve2;
QgsCircularString circularString2;
circularString2.setPoints( QgsPointSequence() << QgsPoint( 1, 2 ) << QgsPoint( 11, 10 ) << QgsPoint( 21, 2 ) );
compoundCurve2.addCurve( circularString2.clone() );
multiCurve2.addGeometry( compoundCurve2.clone() );
QgsMultiLineString *segmentized2 = static_cast<QgsMultiLineString *>( multiCurve2.segmentize() );
QCOMPARE( segmentized2->vertexCount(), 156 );
QCOMPARE( segmentized2->partCount(), 1 );
QVERIFY( !segmentized2->is3D() );
QVERIFY( !segmentized2->isMeasure() );
QCOMPARE( segmentized2->wkbType(), QgsWkbTypes::Type::MultiLineString );
}

void TestQgsGeometry::multiSurface()
Expand Down
58 changes: 58 additions & 0 deletions tests/src/python/test_qgsgeometry.py
Expand Up @@ -2806,6 +2806,64 @@ def testWkbTypes(self):
self.assertEqual(QgsWkbTypes.curveType(QgsWkbTypes.MultiLineString25D), QgsWkbTypes.MultiCurveZ)
self.assertEqual(QgsWkbTypes.curveType(QgsWkbTypes.MultiPolygon25D), QgsWkbTypes.MultiSurfaceZ)

# test linearType method
self.assertEqual(QgsWkbTypes.linearType(QgsWkbTypes.Unknown), QgsWkbTypes.Unknown)
self.assertEqual(QgsWkbTypes.linearType(QgsWkbTypes.Point), QgsWkbTypes.Point)
self.assertEqual(QgsWkbTypes.linearType(QgsWkbTypes.PointZ), QgsWkbTypes.PointZ)
self.assertEqual(QgsWkbTypes.linearType(QgsWkbTypes.PointM), QgsWkbTypes.PointM)
self.assertEqual(QgsWkbTypes.linearType(QgsWkbTypes.PointZM), QgsWkbTypes.PointZM)
self.assertEqual(QgsWkbTypes.linearType(QgsWkbTypes.MultiPoint), QgsWkbTypes.MultiPoint)
self.assertEqual(QgsWkbTypes.linearType(QgsWkbTypes.MultiPointZ), QgsWkbTypes.MultiPointZ)
self.assertEqual(QgsWkbTypes.linearType(QgsWkbTypes.MultiPointM), QgsWkbTypes.MultiPointM)
self.assertEqual(QgsWkbTypes.linearType(QgsWkbTypes.MultiPointZM), QgsWkbTypes.MultiPointZM)
self.assertEqual(QgsWkbTypes.linearType(QgsWkbTypes.LineString), QgsWkbTypes.LineString)
self.assertEqual(QgsWkbTypes.linearType(QgsWkbTypes.LineStringZ), QgsWkbTypes.LineStringZ)
self.assertEqual(QgsWkbTypes.linearType(QgsWkbTypes.LineStringM), QgsWkbTypes.LineStringM)
self.assertEqual(QgsWkbTypes.linearType(QgsWkbTypes.LineStringZM), QgsWkbTypes.LineStringZM)
self.assertEqual(QgsWkbTypes.linearType(QgsWkbTypes.MultiLineString), QgsWkbTypes.MultiLineString)
self.assertEqual(QgsWkbTypes.linearType(QgsWkbTypes.MultiLineStringZ), QgsWkbTypes.MultiLineStringZ)
self.assertEqual(QgsWkbTypes.linearType(QgsWkbTypes.MultiLineStringM), QgsWkbTypes.MultiLineStringM)
self.assertEqual(QgsWkbTypes.linearType(QgsWkbTypes.MultiLineStringZM), QgsWkbTypes.MultiLineStringZM)
self.assertEqual(QgsWkbTypes.linearType(QgsWkbTypes.Polygon), QgsWkbTypes.Polygon)
self.assertEqual(QgsWkbTypes.linearType(QgsWkbTypes.PolygonZ), QgsWkbTypes.PolygonZ)
self.assertEqual(QgsWkbTypes.linearType(QgsWkbTypes.PolygonM), QgsWkbTypes.PolygonM)
self.assertEqual(QgsWkbTypes.linearType(QgsWkbTypes.PolygonZM), QgsWkbTypes.PolygonZM)
self.assertEqual(QgsWkbTypes.linearType(QgsWkbTypes.MultiPolygon), QgsWkbTypes.MultiPolygon)
self.assertEqual(QgsWkbTypes.linearType(QgsWkbTypes.MultiPolygonZ), QgsWkbTypes.MultiPolygonZ)
self.assertEqual(QgsWkbTypes.linearType(QgsWkbTypes.MultiPolygonM), QgsWkbTypes.MultiPolygonM)
self.assertEqual(QgsWkbTypes.linearType(QgsWkbTypes.MultiPolygonZM), QgsWkbTypes.MultiPolygonZM)
self.assertEqual(QgsWkbTypes.linearType(QgsWkbTypes.GeometryCollection), QgsWkbTypes.GeometryCollection)
self.assertEqual(QgsWkbTypes.linearType(QgsWkbTypes.GeometryCollectionZ), QgsWkbTypes.GeometryCollectionZ)
self.assertEqual(QgsWkbTypes.linearType(QgsWkbTypes.GeometryCollectionM), QgsWkbTypes.GeometryCollectionM)
self.assertEqual(QgsWkbTypes.linearType(QgsWkbTypes.GeometryCollectionZM), QgsWkbTypes.GeometryCollectionZM)
self.assertEqual(QgsWkbTypes.linearType(QgsWkbTypes.CircularString), QgsWkbTypes.LineString)
self.assertEqual(QgsWkbTypes.linearType(QgsWkbTypes.CircularStringZ), QgsWkbTypes.LineStringZ)
self.assertEqual(QgsWkbTypes.linearType(QgsWkbTypes.CircularStringM), QgsWkbTypes.LineStringM)
self.assertEqual(QgsWkbTypes.linearType(QgsWkbTypes.CircularStringZM), QgsWkbTypes.LineStringZM)
self.assertEqual(QgsWkbTypes.linearType(QgsWkbTypes.CompoundCurve), QgsWkbTypes.LineString)
self.assertEqual(QgsWkbTypes.linearType(QgsWkbTypes.CompoundCurveZ), QgsWkbTypes.LineStringZ)
self.assertEqual(QgsWkbTypes.linearType(QgsWkbTypes.CompoundCurveM), QgsWkbTypes.LineStringM)
self.assertEqual(QgsWkbTypes.linearType(QgsWkbTypes.CompoundCurveZM), QgsWkbTypes.LineStringZM)
self.assertEqual(QgsWkbTypes.linearType(QgsWkbTypes.CurvePolygon), QgsWkbTypes.Polygon)
self.assertEqual(QgsWkbTypes.linearType(QgsWkbTypes.CurvePolygonZ), QgsWkbTypes.PolygonZ)
self.assertEqual(QgsWkbTypes.linearType(QgsWkbTypes.CurvePolygonM), QgsWkbTypes.PolygonM)
self.assertEqual(QgsWkbTypes.linearType(QgsWkbTypes.CurvePolygonZM), QgsWkbTypes.PolygonZM)
self.assertEqual(QgsWkbTypes.linearType(QgsWkbTypes.MultiCurve), QgsWkbTypes.MultiLineString)
self.assertEqual(QgsWkbTypes.linearType(QgsWkbTypes.MultiCurveZ), QgsWkbTypes.MultiLineStringZ)
self.assertEqual(QgsWkbTypes.linearType(QgsWkbTypes.MultiCurveM), QgsWkbTypes.MultiLineStringM)
self.assertEqual(QgsWkbTypes.linearType(QgsWkbTypes.MultiCurveZM), QgsWkbTypes.MultiLineStringZM)
self.assertEqual(QgsWkbTypes.linearType(QgsWkbTypes.MultiSurface), QgsWkbTypes.MultiPolygon)
self.assertEqual(QgsWkbTypes.linearType(QgsWkbTypes.MultiSurfaceZ), QgsWkbTypes.MultiPolygonZ)
self.assertEqual(QgsWkbTypes.linearType(QgsWkbTypes.MultiSurfaceM), QgsWkbTypes.MultiPolygonM)
self.assertEqual(QgsWkbTypes.linearType(QgsWkbTypes.MultiSurfaceZM), QgsWkbTypes.MultiPolygonZM)
self.assertEqual(QgsWkbTypes.linearType(QgsWkbTypes.NoGeometry), QgsWkbTypes.NoGeometry)
self.assertEqual(QgsWkbTypes.linearType(QgsWkbTypes.Point25D), QgsWkbTypes.Point25D)
self.assertEqual(QgsWkbTypes.linearType(QgsWkbTypes.LineString25D), QgsWkbTypes.LineString25D)
self.assertEqual(QgsWkbTypes.linearType(QgsWkbTypes.Polygon25D), QgsWkbTypes.Polygon25D)
self.assertEqual(QgsWkbTypes.linearType(QgsWkbTypes.MultiPoint25D), QgsWkbTypes.MultiPoint25D)
self.assertEqual(QgsWkbTypes.linearType(QgsWkbTypes.MultiLineString25D), QgsWkbTypes.MultiLineString25D)
self.assertEqual(QgsWkbTypes.linearType(QgsWkbTypes.MultiPolygon25D), QgsWkbTypes.MultiPolygon25D)

# test flatType method
self.assertEqual(QgsWkbTypes.flatType(QgsWkbTypes.Unknown), QgsWkbTypes.Unknown)
self.assertEqual(QgsWkbTypes.flatType(QgsWkbTypes.Point), QgsWkbTypes.Point)
Expand Down

0 comments on commit ea2ec2b

Please sign in to comment.