mirror of
https://github.com/qgis/QGIS.git
synced 2025-04-14 00:07:35 -04:00
[needs-docs] geometry smooth algorithm now also retains and smooths z/m values
...instead of just discarding them Applies to processing algorithm and expression function (and QgsGeometry::smooth method)
This commit is contained in:
parent
bf252d68d2
commit
f02602b9bb
@ -1668,6 +1668,9 @@ tolerance
|
|||||||
Smooths a geometry by rounding off corners using the Chaikin algorithm. This operation
|
Smooths a geometry by rounding off corners using the Chaikin algorithm. This operation
|
||||||
roughly doubles the number of vertices in a geometry.
|
roughly doubles the number of vertices in a geometry.
|
||||||
|
|
||||||
|
If input geometries contain Z or M values, these will also be smoothed and the output
|
||||||
|
geometry will retain the same dimensionality as the input geometry.
|
||||||
|
|
||||||
:param iterations: number of smoothing iterations to run. More iterations results
|
:param iterations: number of smoothing iterations to run. More iterations results
|
||||||
in a smoother geometry
|
in a smoother geometry
|
||||||
:param offset: fraction of line to create new vertices along, between 0 and 1.0,
|
:param offset: fraction of line to create new vertices along, between 0 and 1.0,
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "smooth",
|
"name": "smooth",
|
||||||
"type": "function",
|
"type": "function",
|
||||||
"description":"Smooths a geometry by adding extra nodes which round off corners in the geometry.",
|
"description":"Smooths a geometry by adding extra nodes which round off corners in the geometry. If input geometries contain Z or M values, these will also be smoothed and the output geometry will retain the same dimensionality as the input geometry.",
|
||||||
"arguments": [ {"arg":"geometry","description":"a geometry"},
|
"arguments": [ {"arg":"geometry","description":"a geometry"},
|
||||||
{"arg":"iterations", "optional":true,"description":"number of smoothing iterations to apply. Larger numbers result in smoother but more complex geometries."},
|
{"arg":"iterations", "optional":true,"description":"number of smoothing iterations to apply. Larger numbers result in smoother but more complex geometries."},
|
||||||
{"arg":"offset", "optional":true,"description":"value between 0 and 0.5 which controls how tightly the smoothed geometry follow the original geometry. Smaller values result in a tighter smoothing, larger values result in looser smoothing."},
|
{"arg":"offset", "optional":true,"description":"value between 0 and 0.5 which controls how tightly the smoothed geometry follow the original geometry. Smaller values result in a tighter smoothing, larger values result in looser smoothing."},
|
||||||
|
@ -67,7 +67,9 @@ QString QgsSmoothAlgorithm::shortHelpString() const
|
|||||||
"The maximum angle parameter can be used to prevent smoothing of "
|
"The maximum angle parameter can be used to prevent smoothing of "
|
||||||
"nodes with large angles. Any node where the angle of the segments to either "
|
"nodes with large angles. Any node where the angle of the segments to either "
|
||||||
"side is larger than this will not be smoothed. For example, setting the maximum "
|
"side is larger than this will not be smoothed. For example, setting the maximum "
|
||||||
"angle to 90 degrees or lower would preserve right angles in the geometry." );
|
"angle to 90 degrees or lower would preserve right angles in the geometry.\n\n"
|
||||||
|
"If input geometries contain Z or M values, these will also be smoothed and the output "
|
||||||
|
"geometry will retain the same dimensionality as the input geometry." );
|
||||||
}
|
}
|
||||||
|
|
||||||
QgsSmoothAlgorithm *QgsSmoothAlgorithm::createInstance() const
|
QgsSmoothAlgorithm *QgsSmoothAlgorithm::createInstance() const
|
||||||
|
@ -2711,9 +2711,12 @@ QgsGeometry QgsGeometry::smooth( const unsigned int iterations, const double off
|
|||||||
|
|
||||||
inline QgsPoint interpolatePointOnLine( const QgsPoint &p1, const QgsPoint &p2, const double offset )
|
inline QgsPoint interpolatePointOnLine( const QgsPoint &p1, const QgsPoint &p2, const double offset )
|
||||||
{
|
{
|
||||||
double deltaX = p2.x() - p1.x();
|
const double _offset = 1 - offset;
|
||||||
double deltaY = p2.y() - p1.y();
|
return QgsPoint( p1.wkbType(),
|
||||||
return QgsPoint( p1.x() + deltaX * offset, p1.y() + deltaY * offset );
|
p1.x() * _offset + p2.x() * offset,
|
||||||
|
p1.y() * _offset + p2.y() * offset,
|
||||||
|
p1.is3D() ? p1.z() * _offset + p2.z() * offset : std::numeric_limits<double>::quiet_NaN(),
|
||||||
|
p1.isMeasure() ? p1.m() * _offset + p2.m() * offset : std::numeric_limits<double>::quiet_NaN() );
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr< QgsLineString > smoothCurve( const QgsLineString &line, const unsigned int iterations,
|
std::unique_ptr< QgsLineString > smoothCurve( const QgsLineString &line, const unsigned int iterations,
|
||||||
|
@ -1675,6 +1675,10 @@ class CORE_EXPORT QgsGeometry
|
|||||||
/**
|
/**
|
||||||
* Smooths a geometry by rounding off corners using the Chaikin algorithm. This operation
|
* Smooths a geometry by rounding off corners using the Chaikin algorithm. This operation
|
||||||
* roughly doubles the number of vertices in a geometry.
|
* roughly doubles the number of vertices in a geometry.
|
||||||
|
*
|
||||||
|
* If input geometries contain Z or M values, these will also be smoothed and the output
|
||||||
|
* geometry will retain the same dimensionality as the input geometry.
|
||||||
|
*
|
||||||
* \param iterations number of smoothing iterations to run. More iterations results
|
* \param iterations number of smoothing iterations to run. More iterations results
|
||||||
* in a smoother geometry
|
* in a smoother geometry
|
||||||
* \param offset fraction of line to create new vertices along, between 0 and 1.0,
|
* \param offset fraction of line to create new vertices along, between 0 and 1.0,
|
||||||
|
@ -15606,6 +15606,24 @@ void TestQgsGeometry::smoothCheck()
|
|||||||
<< QgsPointXY( 10.0, 7.5 ) << QgsPointXY( 12.5, 10.0 ) << QgsPointXY( 20.0, 10.0 );
|
<< QgsPointXY( 10.0, 7.5 ) << QgsPointXY( 12.5, 10.0 ) << QgsPointXY( 20.0, 10.0 );
|
||||||
QVERIFY( QgsGeometry::compare( line, expectedLine ) );
|
QVERIFY( QgsGeometry::compare( line, expectedLine ) );
|
||||||
|
|
||||||
|
//linestringM
|
||||||
|
wkt = QStringLiteral( "LineStringM(0 0 1, 10 0 2, 10 10 6, 20 10 4)" );
|
||||||
|
geom = QgsGeometry::fromWkt( wkt );
|
||||||
|
result = geom.smooth( 1, 0.25 );
|
||||||
|
QCOMPARE( result.asWkt(), QStringLiteral( "LineStringM (0 0 1, 7.5 0 1.75, 10 2.5 3, 10 7.5 5, 12.5 10 5.5, 20 10 4)" ) );
|
||||||
|
|
||||||
|
//linestringZ
|
||||||
|
wkt = QStringLiteral( "LineStringZ(0 0 1, 10 0 2, 10 10 6, 20 10 4)" );
|
||||||
|
geom = QgsGeometry::fromWkt( wkt );
|
||||||
|
result = geom.smooth( 1, 0.25 );
|
||||||
|
QCOMPARE( result.asWkt(), QStringLiteral( "LineStringZ (0 0 1, 7.5 0 1.75, 10 2.5 3, 10 7.5 5, 12.5 10 5.5, 20 10 4)" ) );
|
||||||
|
|
||||||
|
//linestringZM
|
||||||
|
wkt = QStringLiteral( "LineStringZM(0 0 1 4, 10 0 2 8, 10 10 6 2, 20 10 4 0)" );
|
||||||
|
geom = QgsGeometry::fromWkt( wkt );
|
||||||
|
result = geom.smooth( 1, 0.25 );
|
||||||
|
QCOMPARE( result.asWkt(), QStringLiteral( "LineStringZM (0 0 1 4, 7.5 0 1.75 7, 10 2.5 3 6.5, 10 7.5 5 3.5, 12.5 10 5.5 1.5, 20 10 4 0)" ) );
|
||||||
|
|
||||||
//linestring, with min distance
|
//linestring, with min distance
|
||||||
wkt = QStringLiteral( "LineString(0 0, 10 0, 10 10, 15 10, 15 20)" );
|
wkt = QStringLiteral( "LineString(0 0, 10 0, 10 10, 15 10, 15 20)" );
|
||||||
geom = QgsGeometry::fromWkt( wkt );
|
geom = QgsGeometry::fromWkt( wkt );
|
||||||
@ -15670,6 +15688,24 @@ void TestQgsGeometry::smoothCheck()
|
|||||||
<< QgsPointXY( 2.0, 3.5 ) << QgsPointXY( 2.0, 2.5 ) << QgsPointXY( 2.5, 2.0 ) );
|
<< QgsPointXY( 2.0, 3.5 ) << QgsPointXY( 2.0, 2.5 ) << QgsPointXY( 2.5, 2.0 ) );
|
||||||
QVERIFY( QgsGeometry::compare( poly, expectedPolygon ) );
|
QVERIFY( QgsGeometry::compare( poly, expectedPolygon ) );
|
||||||
|
|
||||||
|
//polygonM
|
||||||
|
wkt = QStringLiteral( "PolygonM ((0 0 1, 10 0 4, 10 10 6, 0 10 8, 0 0 1 ),(2 2 3, 4 2 5, 4 4 7, 2 4 9, 2 2 3))" );
|
||||||
|
geom = QgsGeometry::fromWkt( wkt );
|
||||||
|
result = geom.smooth( 1, 0.25 );
|
||||||
|
QCOMPARE( result.asWkt(), QStringLiteral( "PolygonM ((2.5 0 1.75, 7.5 0 3.25, 10 2.5 4.5, 10 7.5 5.5, 7.5 10 6.5, 2.5 10 7.5, 0 7.5 6.25, 0 2.5 2.75, 2.5 0 1.75),(2.5 2 3.5, 3.5 2 4.5, 4 2.5 5.5, 4 3.5 6.5, 3.5 4 7.5, 2.5 4 8.5, 2 3.5 7.5, 2 2.5 4.5, 2.5 2 3.5))" ) );
|
||||||
|
|
||||||
|
//polygonZ
|
||||||
|
wkt = QStringLiteral( "PolygonZ ((0 0 1, 10 0 4, 10 10 6, 0 10 8, 0 0 1 ),(2 2 3, 4 2 5, 4 4 7, 2 4 9, 2 2 3))" );
|
||||||
|
geom = QgsGeometry::fromWkt( wkt );
|
||||||
|
result = geom.smooth( 1, 0.25 );
|
||||||
|
QCOMPARE( result.asWkt(), QStringLiteral( "PolygonZ ((2.5 0 1.75, 7.5 0 3.25, 10 2.5 4.5, 10 7.5 5.5, 7.5 10 6.5, 2.5 10 7.5, 0 7.5 6.25, 0 2.5 2.75, 2.5 0 1.75),(2.5 2 3.5, 3.5 2 4.5, 4 2.5 5.5, 4 3.5 6.5, 3.5 4 7.5, 2.5 4 8.5, 2 3.5 7.5, 2 2.5 4.5, 2.5 2 3.5))" ) );
|
||||||
|
|
||||||
|
//polygonZM
|
||||||
|
wkt = QStringLiteral( "PolygonZ ((0 0 1 6, 10 0 4 2, 10 10 6 0, 0 10 8 4, 0 0 1 6 ))" );
|
||||||
|
geom = QgsGeometry::fromWkt( wkt );
|
||||||
|
result = geom.smooth( 1, 0.25 );
|
||||||
|
QCOMPARE( result.asWkt(), QStringLiteral( "PolygonZM ((2.5 0 1.75 5, 7.5 0 3.25 3, 10 2.5 4.5 1.5, 10 7.5 5.5 0.5, 7.5 10 6.5 1, 2.5 10 7.5 3, 0 7.5 6.25 4.5, 0 2.5 2.75 5.5, 2.5 0 1.75 5))" ) );
|
||||||
|
|
||||||
//polygon with max angle - should be unchanged
|
//polygon with max angle - should be unchanged
|
||||||
wkt = QStringLiteral( "Polygon ((0 0, 10 0, 10 10, 0 10, 0 0))" );
|
wkt = QStringLiteral( "Polygon ((0 0, 10 0, 10 10, 0 10, 0 0))" );
|
||||||
geom = QgsGeometry::fromWkt( wkt );
|
geom = QgsGeometry::fromWkt( wkt );
|
||||||
|
Loading…
x
Reference in New Issue
Block a user