mirror of
https://github.com/qgis/QGIS.git
synced 2025-10-05 00:09:32 -04:00
add a flag to coerceToType() to control whether duplicated nodes should
be kept
This commit is contained in:
parent
559844d7d3
commit
3cf314fcdd
@ -2310,7 +2310,7 @@ Exports the geometry to a GeoJSON string.
|
||||
%End
|
||||
|
||||
|
||||
QVector< QgsGeometry > coerceToType( Qgis::WkbType type, double defaultZ = 0, double defaultM = 0 ) const;
|
||||
QVector< QgsGeometry > coerceToType( Qgis::WkbType type, double defaultZ = 0, double defaultM = 0, bool avoidDuplicates = true ) const;
|
||||
%Docstring
|
||||
Attempts to coerce this geometry into the specified destination
|
||||
``type``.
|
||||
@ -2333,6 +2333,10 @@ Since QGIS 3.24, the parameters ``defaultZ`` and ``defaultM`` control
|
||||
the dimension value added when promoting geometries to Z, M or ZM
|
||||
versions. By default 0.0 is used for Z and M.
|
||||
|
||||
Since QGIS 3.44, the parameters ``avoidDuplicates`` controls whether to
|
||||
keep duplicated nodes (e.g. start/end of rings) when promoting polygon
|
||||
geometries to points. By default duplicated nodes are ignored.
|
||||
|
||||
.. note::
|
||||
|
||||
This method is much stricter than :py:func:`~QgsGeometry.convertToType`, as it considers the exact WKB type
|
||||
|
@ -2310,7 +2310,7 @@ Exports the geometry to a GeoJSON string.
|
||||
%End
|
||||
|
||||
|
||||
QVector< QgsGeometry > coerceToType( Qgis::WkbType type, double defaultZ = 0, double defaultM = 0 ) const;
|
||||
QVector< QgsGeometry > coerceToType( Qgis::WkbType type, double defaultZ = 0, double defaultM = 0, bool avoidDuplicates = true ) const;
|
||||
%Docstring
|
||||
Attempts to coerce this geometry into the specified destination
|
||||
``type``.
|
||||
@ -2333,6 +2333,10 @@ Since QGIS 3.24, the parameters ``defaultZ`` and ``defaultM`` control
|
||||
the dimension value added when promoting geometries to Z, M or ZM
|
||||
versions. By default 0.0 is used for Z and M.
|
||||
|
||||
Since QGIS 3.44, the parameters ``avoidDuplicates`` controls whether to
|
||||
keep duplicated nodes (e.g. start/end of rings) when promoting polygon
|
||||
geometries to points. By default duplicated nodes are ignored.
|
||||
|
||||
.. note::
|
||||
|
||||
This method is much stricter than :py:func:`~QgsGeometry.convertToType`, as it considers the exact WKB type
|
||||
|
@ -168,7 +168,7 @@ const QVector< QgsGeometry > QgsConvertGeometryTypeAlgorithm::convertGeometry( c
|
||||
}
|
||||
else
|
||||
{
|
||||
geometries = geom.coerceToType( outputWkbType );
|
||||
geometries = geom.coerceToType( outputWkbType, 0, 0, false );
|
||||
}
|
||||
|
||||
return geometries;
|
||||
|
@ -1695,7 +1695,7 @@ json QgsGeometry::asJsonObject( int precision ) const
|
||||
|
||||
}
|
||||
|
||||
QVector<QgsGeometry> QgsGeometry::coerceToType( const Qgis::WkbType type, double defaultZ, double defaultM ) const
|
||||
QVector<QgsGeometry> QgsGeometry::coerceToType( const Qgis::WkbType type, double defaultZ, double defaultM, bool avoidDuplicates ) const
|
||||
{
|
||||
QVector< QgsGeometry > res;
|
||||
if ( isNull() )
|
||||
@ -1768,7 +1768,7 @@ QVector<QgsGeometry> QgsGeometry::coerceToType( const Qgis::WkbType type, double
|
||||
QSet< QgsPoint > added;
|
||||
for ( auto vertex = source.vertices_begin(); vertex != source.vertices_end(); ++vertex )
|
||||
{
|
||||
if ( added.contains( *vertex ) )
|
||||
if ( avoidDuplicates && added.contains( *vertex ) )
|
||||
continue; // avoid duplicate points, e.g. start/end of rings
|
||||
mp->addGeometry( ( *vertex ).clone() );
|
||||
added.insert( *vertex );
|
||||
|
@ -2223,6 +2223,10 @@ class CORE_EXPORT QgsGeometry
|
||||
* to Z, M or ZM versions.
|
||||
* By default 0.0 is used for Z and M.
|
||||
*
|
||||
* Since QGIS 3.44, the parameters \a avoidDuplicates controls whether to keep duplicated nodes (e.g. start/end of rings)
|
||||
* when promoting polygon geometries to points.
|
||||
* By default duplicated nodes are ignored.
|
||||
*
|
||||
* \note This method is much stricter than convertToType(), as it considers the exact WKB type
|
||||
* of geometries instead of the geometry family (point/line/polygon), and tries more exhaustively
|
||||
* to coerce geometries to the desired \a type. It also correctly maintains curves and z/m values
|
||||
@ -2230,7 +2234,7 @@ class CORE_EXPORT QgsGeometry
|
||||
*
|
||||
* \since QGIS 3.14
|
||||
*/
|
||||
QVector< QgsGeometry > coerceToType( Qgis::WkbType type, double defaultZ = 0, double defaultM = 0 ) const;
|
||||
QVector< QgsGeometry > coerceToType( Qgis::WkbType type, double defaultZ = 0, double defaultM = 0, bool avoidDuplicates = true ) const;
|
||||
|
||||
/**
|
||||
* Try to convert the geometry to the requested type
|
||||
|
@ -12002,15 +12002,22 @@ class TestQgsGeometry(QgisTestCase):
|
||||
def testCoerce(self):
|
||||
"""Test coerce function"""
|
||||
|
||||
def coerce_to_wkt(wkt, type, defaultZ=None, defaultM=None):
|
||||
def coerce_to_wkt(
|
||||
wkt, type, defaultZ=None, defaultM=None, avoidDuplicates=True
|
||||
):
|
||||
geom = QgsGeometry.fromWkt(wkt)
|
||||
if defaultZ is not None or defaultM is not None:
|
||||
return [
|
||||
g.asWkt(2)
|
||||
for g in geom.coerceToType(type, defaultZ or 0, defaultM or 0)
|
||||
for g in geom.coerceToType(
|
||||
type, defaultZ or 0, defaultM or 0, avoidDuplicates
|
||||
)
|
||||
]
|
||||
else:
|
||||
return [g.asWkt(2) for g in geom.coerceToType(type)]
|
||||
return [
|
||||
g.asWkt(2)
|
||||
for g in geom.coerceToType(type, avoidDuplicates=avoidDuplicates)
|
||||
]
|
||||
|
||||
self.assertEqual(
|
||||
coerce_to_wkt("Point (1 1)", QgsWkbTypes.Type.Point), ["Point (1 1)"]
|
||||
@ -12036,6 +12043,15 @@ class TestQgsGeometry(QgisTestCase):
|
||||
coerce_to_wkt("Polygon((1 1, 2 2, 1 2, 1 1))", QgsWkbTypes.Type.Point),
|
||||
["Point (1 1)", "Point (2 2)", "Point (1 2)"],
|
||||
)
|
||||
# keep duplicated nodes
|
||||
self.assertEqual(
|
||||
coerce_to_wkt(
|
||||
"Polygon((1 1, 2 2, 1 2, 1 1))",
|
||||
QgsWkbTypes.Type.Point,
|
||||
avoidDuplicates=False,
|
||||
),
|
||||
["Point (1 1)", "Point (2 2)", "Point (1 2)", "Point (1 1)"],
|
||||
)
|
||||
self.assertEqual(
|
||||
coerce_to_wkt("Polygon((1 1, 2 2, 1 2, 1 1))", QgsWkbTypes.Type.LineString),
|
||||
["LineString (1 1, 2 2, 1 2, 1 1)"],
|
||||
@ -12290,6 +12306,14 @@ class TestQgsGeometry(QgisTestCase):
|
||||
coerce_to_wkt("Polygon ((1 1, 1 2, 2 2, 1 1))", QgsWkbTypes.Type.Point),
|
||||
["Point (1 1)", "Point (1 2)", "Point (2 2)"],
|
||||
)
|
||||
self.assertEqual(
|
||||
coerce_to_wkt(
|
||||
"Polygon ((1 1, 1 2, 2 2, 1 1))",
|
||||
QgsWkbTypes.Type.Point,
|
||||
avoidDuplicates=False,
|
||||
),
|
||||
["Point (1 1)", "Point (1 2)", "Point (2 2)", "Point (1 1)"],
|
||||
)
|
||||
|
||||
self.assertEqual(
|
||||
coerce_to_wkt(
|
||||
@ -12297,6 +12321,14 @@ class TestQgsGeometry(QgisTestCase):
|
||||
),
|
||||
["MultiPoint ((1 1),(1 2),(2 2))"],
|
||||
)
|
||||
self.assertEqual(
|
||||
coerce_to_wkt(
|
||||
"Polygon ((1 1, 1 2, 2 2, 1 1))",
|
||||
QgsWkbTypes.Type.MultiPoint,
|
||||
avoidDuplicates=False,
|
||||
),
|
||||
["MultiPoint ((1 1),(1 2),(2 2),(1 1))"],
|
||||
)
|
||||
|
||||
self.assertEqual(
|
||||
coerce_to_wkt(
|
||||
@ -12312,6 +12344,23 @@ class TestQgsGeometry(QgisTestCase):
|
||||
"Point (4 4)",
|
||||
],
|
||||
)
|
||||
self.assertEqual(
|
||||
coerce_to_wkt(
|
||||
"MultiPolygon (((1 1, 1 2, 2 2, 1 1)),((3 3, 4 3, 4 4, 3 3)))",
|
||||
QgsWkbTypes.Type.Point,
|
||||
avoidDuplicates=False,
|
||||
),
|
||||
[
|
||||
"Point (1 1)",
|
||||
"Point (1 2)",
|
||||
"Point (2 2)",
|
||||
"Point (1 1)",
|
||||
"Point (3 3)",
|
||||
"Point (4 3)",
|
||||
"Point (4 4)",
|
||||
"Point (3 3)",
|
||||
],
|
||||
)
|
||||
|
||||
self.assertEqual(
|
||||
coerce_to_wkt(
|
||||
@ -12320,6 +12369,14 @@ class TestQgsGeometry(QgisTestCase):
|
||||
),
|
||||
["MultiPoint ((1 1),(1 2),(2 2),(3 3),(4 3),(4 4))"],
|
||||
)
|
||||
self.assertEqual(
|
||||
coerce_to_wkt(
|
||||
"MultiPolygon (((1 1, 1 2, 2 2, 1 1)),((3 3, 4 3, 4 4, 3 3)))",
|
||||
QgsWkbTypes.Type.MultiPoint,
|
||||
avoidDuplicates=False,
|
||||
),
|
||||
["MultiPoint ((1 1),(1 2),(2 2),(1 1),(3 3),(4 3),(4 4),(3 3))"],
|
||||
)
|
||||
|
||||
# polygon -> lines
|
||||
self.assertEqual(
|
||||
|
Loading…
x
Reference in New Issue
Block a user