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
|
%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
|
%Docstring
|
||||||
Attempts to coerce this geometry into the specified destination
|
Attempts to coerce this geometry into the specified destination
|
||||||
``type``.
|
``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
|
the dimension value added when promoting geometries to Z, M or ZM
|
||||||
versions. By default 0.0 is used for Z and M.
|
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::
|
.. note::
|
||||||
|
|
||||||
This method is much stricter than :py:func:`~QgsGeometry.convertToType`, as it considers the exact WKB type
|
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
|
%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
|
%Docstring
|
||||||
Attempts to coerce this geometry into the specified destination
|
Attempts to coerce this geometry into the specified destination
|
||||||
``type``.
|
``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
|
the dimension value added when promoting geometries to Z, M or ZM
|
||||||
versions. By default 0.0 is used for Z and M.
|
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::
|
.. note::
|
||||||
|
|
||||||
This method is much stricter than :py:func:`~QgsGeometry.convertToType`, as it considers the exact WKB type
|
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
|
else
|
||||||
{
|
{
|
||||||
geometries = geom.coerceToType( outputWkbType );
|
geometries = geom.coerceToType( outputWkbType, 0, 0, false );
|
||||||
}
|
}
|
||||||
|
|
||||||
return geometries;
|
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;
|
QVector< QgsGeometry > res;
|
||||||
if ( isNull() )
|
if ( isNull() )
|
||||||
@ -1768,7 +1768,7 @@ QVector<QgsGeometry> QgsGeometry::coerceToType( const Qgis::WkbType type, double
|
|||||||
QSet< QgsPoint > added;
|
QSet< QgsPoint > added;
|
||||||
for ( auto vertex = source.vertices_begin(); vertex != source.vertices_end(); ++vertex )
|
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
|
continue; // avoid duplicate points, e.g. start/end of rings
|
||||||
mp->addGeometry( ( *vertex ).clone() );
|
mp->addGeometry( ( *vertex ).clone() );
|
||||||
added.insert( *vertex );
|
added.insert( *vertex );
|
||||||
|
@ -2223,6 +2223,10 @@ class CORE_EXPORT QgsGeometry
|
|||||||
* to Z, M or ZM versions.
|
* to Z, M or ZM versions.
|
||||||
* By default 0.0 is used for Z and M.
|
* 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
|
* \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
|
* 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
|
* 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
|
* \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
|
* Try to convert the geometry to the requested type
|
||||||
|
@ -12002,15 +12002,22 @@ class TestQgsGeometry(QgisTestCase):
|
|||||||
def testCoerce(self):
|
def testCoerce(self):
|
||||||
"""Test coerce function"""
|
"""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)
|
geom = QgsGeometry.fromWkt(wkt)
|
||||||
if defaultZ is not None or defaultM is not None:
|
if defaultZ is not None or defaultM is not None:
|
||||||
return [
|
return [
|
||||||
g.asWkt(2)
|
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:
|
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(
|
self.assertEqual(
|
||||||
coerce_to_wkt("Point (1 1)", QgsWkbTypes.Type.Point), ["Point (1 1)"]
|
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),
|
coerce_to_wkt("Polygon((1 1, 2 2, 1 2, 1 1))", QgsWkbTypes.Type.Point),
|
||||||
["Point (1 1)", "Point (2 2)", "Point (1 2)"],
|
["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(
|
self.assertEqual(
|
||||||
coerce_to_wkt("Polygon((1 1, 2 2, 1 2, 1 1))", QgsWkbTypes.Type.LineString),
|
coerce_to_wkt("Polygon((1 1, 2 2, 1 2, 1 1))", QgsWkbTypes.Type.LineString),
|
||||||
["LineString (1 1, 2 2, 1 2, 1 1)"],
|
["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),
|
coerce_to_wkt("Polygon ((1 1, 1 2, 2 2, 1 1))", QgsWkbTypes.Type.Point),
|
||||||
["Point (1 1)", "Point (1 2)", "Point (2 2)"],
|
["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(
|
self.assertEqual(
|
||||||
coerce_to_wkt(
|
coerce_to_wkt(
|
||||||
@ -12297,6 +12321,14 @@ class TestQgsGeometry(QgisTestCase):
|
|||||||
),
|
),
|
||||||
["MultiPoint ((1 1),(1 2),(2 2))"],
|
["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(
|
self.assertEqual(
|
||||||
coerce_to_wkt(
|
coerce_to_wkt(
|
||||||
@ -12312,6 +12344,23 @@ class TestQgsGeometry(QgisTestCase):
|
|||||||
"Point (4 4)",
|
"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(
|
self.assertEqual(
|
||||||
coerce_to_wkt(
|
coerce_to_wkt(
|
||||||
@ -12320,6 +12369,14 @@ class TestQgsGeometry(QgisTestCase):
|
|||||||
),
|
),
|
||||||
["MultiPoint ((1 1),(1 2),(2 2),(3 3),(4 3),(4 4))"],
|
["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
|
# polygon -> lines
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
|
Loading…
x
Reference in New Issue
Block a user