mirror of
https://github.com/qgis/QGIS.git
synced 2025-04-13 00:03:09 -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
|
||||
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
|
||||
in a smoother geometry
|
||||
:param offset: fraction of line to create new vertices along, between 0 and 1.0,
|
||||
|
@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "smooth",
|
||||
"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"},
|
||||
{"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."},
|
||||
|
@ -67,7 +67,9 @@ QString QgsSmoothAlgorithm::shortHelpString() const
|
||||
"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 "
|
||||
"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
|
||||
|
@ -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 )
|
||||
{
|
||||
double deltaX = p2.x() - p1.x();
|
||||
double deltaY = p2.y() - p1.y();
|
||||
return QgsPoint( p1.x() + deltaX * offset, p1.y() + deltaY * offset );
|
||||
const double _offset = 1 - offset;
|
||||
return QgsPoint( p1.wkbType(),
|
||||
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,
|
||||
|
@ -1675,6 +1675,10 @@ class CORE_EXPORT QgsGeometry
|
||||
/**
|
||||
* Smooths a geometry by rounding off corners using the Chaikin algorithm. This operation
|
||||
* 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
|
||||
* in a smoother geometry
|
||||
* \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 );
|
||||
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
|
||||
wkt = QStringLiteral( "LineString(0 0, 10 0, 10 10, 15 10, 15 20)" );
|
||||
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 ) );
|
||||
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
|
||||
wkt = QStringLiteral( "Polygon ((0 0, 10 0, 10 10, 0 10, 0 0))" );
|
||||
geom = QgsGeometry::fromWkt( wkt );
|
||||
|
Loading…
x
Reference in New Issue
Block a user