From 77e0016acec1364bd3849e485150bc792de24ed6 Mon Sep 17 00:00:00 2001 From: Denis Rouzaud Date: Fri, 23 Aug 2024 10:56:01 +0200 Subject: [PATCH 01/26] add new signature to create wedge buffers from start and end angles --- src/core/geometry/qgsgeometry.cpp | 6 +++++- src/core/geometry/qgsgeometry.h | 16 ++++++++++++++++ 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/src/core/geometry/qgsgeometry.cpp b/src/core/geometry/qgsgeometry.cpp index 219170facf6c..17d42e0e8ba3 100644 --- a/src/core/geometry/qgsgeometry.cpp +++ b/src/core/geometry/qgsgeometry.cpp @@ -437,6 +437,11 @@ QgsGeometry QgsGeometry::createWedgeBuffer( const QgsPoint ¢er, const double const double startAngle = azimuth - angularWidth * 0.5; const double endAngle = azimuth + angularWidth * 0.5; + return createWedgeBufferV2( center, startAngle, endAngle, outerRadius, innerRadius ); +} + +QgsGeometry QgsGeometry::createWedgeBufferV2( const QgsPoint ¢er, double startAngle, double endAngle, double outerRadius, double innerRadius = 0 ) +{ const QgsPoint outerP1 = center.project( outerRadius, startAngle ); const QgsPoint outerP2 = center.project( outerRadius, endAngle ); @@ -488,7 +493,6 @@ Qgis::WkbType QgsGeometry::wkbType() const } } - Qgis::GeometryType QgsGeometry::type() const { if ( !d->geometry ) diff --git a/src/core/geometry/qgsgeometry.h b/src/core/geometry/qgsgeometry.h index 7a4603cc60b3..de3129b7dd3d 100644 --- a/src/core/geometry/qgsgeometry.h +++ b/src/core/geometry/qgsgeometry.h @@ -345,6 +345,22 @@ class CORE_EXPORT QgsGeometry static QgsGeometry createWedgeBuffer( const QgsPoint ¢er, double azimuth, double angularWidth, double outerRadius, double innerRadius = 0 ); + /** + * Creates a wedge shaped buffer from a \a center point. + * + * The wedges goes from the \a startAngle to \a endAngle in degrees. + * + * The outer radius of the buffer is specified via \a outerRadius, and optionally an + * \a innerRadius can also be specified. + * + * The returned geometry will be a CurvePolygon geometry containing circular strings. It may + * need to be segmentized to convert to a standard Polygon geometry. + * + * \since QGIS 3.40 + */ + static QgsGeometry createWedgeBufferV2( const QgsPoint ¢er, double startAngle, double endAngle, + double outerRadius, double innerRadius = 0 ); + /** * Set the geometry, feeding in the buffer containing OGC Well-Known Binary and the buffer's length. * This class will take ownership of the buffer. From 0c81e549c5e6582b9f2faf86804b1a1e563c2171 Mon Sep 17 00:00:00 2001 From: Denis Rouzaud Date: Fri, 23 Aug 2024 11:04:49 +0200 Subject: [PATCH 02/26] code layout --- src/core/geometry/qgsgeometry.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/geometry/qgsgeometry.h b/src/core/geometry/qgsgeometry.h index de3129b7dd3d..e9d26f20e96c 100644 --- a/src/core/geometry/qgsgeometry.h +++ b/src/core/geometry/qgsgeometry.h @@ -359,7 +359,7 @@ class CORE_EXPORT QgsGeometry * \since QGIS 3.40 */ static QgsGeometry createWedgeBufferV2( const QgsPoint ¢er, double startAngle, double endAngle, - double outerRadius, double innerRadius = 0 ); + double outerRadius, double innerRadius = 0 ); /** * Set the geometry, feeding in the buffer containing OGC Well-Known Binary and the buffer's length. From a565071563dd8e7aaa43477514c66a0ab89f5b3c Mon Sep 17 00:00:00 2001 From: Denis Rouzaud Date: Mon, 26 Aug 2024 15:23:07 +0200 Subject: [PATCH 03/26] support for geographic coordinates --- src/core/geometry/qgsgeometry.cpp | 65 ++++++++++++++++++++++++------- src/core/geometry/qgsgeometry.h | 10 +++-- 2 files changed, 58 insertions(+), 17 deletions(-) diff --git a/src/core/geometry/qgsgeometry.cpp b/src/core/geometry/qgsgeometry.cpp index 17d42e0e8ba3..cee5ce2d418b 100644 --- a/src/core/geometry/qgsgeometry.cpp +++ b/src/core/geometry/qgsgeometry.cpp @@ -407,7 +407,7 @@ QgsGeometry QgsGeometry::collectGeometry( const QVector< QgsGeometry > &geometri return collected; } -QgsGeometry QgsGeometry::createWedgeBuffer( const QgsPoint ¢er, const double azimuth, const double angularWidth, const double outerRadius, const double innerRadius ) +QgsGeometry QgsGeometry::createWedgeBuffer( const QgsPoint ¢er, const double azimuth, const double angularWidth, const double outerRadius, const double innerRadius, const QgsCoordinateReferenceSystem &crs ) { if ( std::abs( angularWidth ) >= 360.0 ) { @@ -432,34 +432,71 @@ QgsGeometry QgsGeometry::createWedgeBuffer( const QgsPoint ¢er, const double return QgsGeometry( std::move( cp ) ); } - std::unique_ptr< QgsCompoundCurve > wedge = std::make_unique< QgsCompoundCurve >(); - const double startAngle = azimuth - angularWidth * 0.5; const double endAngle = azimuth + angularWidth * 0.5; - return createWedgeBufferV2( center, startAngle, endAngle, outerRadius, innerRadius ); + return createWedgeBufferFromAngles( center, startAngle, endAngle, outerRadius, innerRadius, crs ); } -QgsGeometry QgsGeometry::createWedgeBufferV2( const QgsPoint ¢er, double startAngle, double endAngle, double outerRadius, double innerRadius = 0 ) +QgsGeometry QgsGeometry::createWedgeBufferAngles( const QgsPoint ¢er, double startAngle, double endAngle, double outerRadius, double innerRadius, const QgsCoordinateReferenceSystem &crs ) { - const QgsPoint outerP1 = center.project( outerRadius, startAngle ); - const QgsPoint outerP2 = center.project( outerRadius, endAngle ); + std::unique_ptr< QgsCompoundCurve > wedge = std::make_unique< QgsCompoundCurve >(); - const bool useShortestArc = angularWidth <= 180.0; + double angularWidth = endAngle - startAngle; + double averageAngle = QgsGeometryUtils::averageAngle( endAngle * M_PI / 180, startAngle * M_PI / 180 ) * 180 / M_PI; - wedge->addCurve( new QgsCircularString( QgsCircularString::fromTwoPointsAndCenter( outerP1, outerP2, center, useShortestArc ) ) ); + bool useShortestArc = angularWidth >= 0 && angularWidth <= 180.0 || angularWidth <= 0 && angularWidth >= -360.0; + if ( !useShortestArc ) + averageAngle += 180; + + QgsDistanceArea da; + if ( crs.isValid() && crs.isGeographic() ) + { + da.setSourceCrs( crs, QgsProject::instance()->transformContext() ); + da.setEllipsoid( crs.ellipsoidAcronym() ); + } + + QgsPoint outerP1; + QgsPoint outerP2; + QgsPoint outerP3; + if ( crs.isGeographic() ) + { + outerP1 = QgsPoint( da.computeSpheroidProject( center, outerRadius, startAngle * M_PI / 180 ) ); + outerP2 = QgsPoint( da.computeSpheroidProject( center, outerRadius, averageAngle * M_PI / 180 ) ); + outerP3 = QgsPoint( da.computeSpheroidProject( center, outerRadius, endAngle * M_PI / 180 ) ); + } + else + { + outerP1 = center.project( outerRadius, startAngle ); + outerP2 = center.project( outerRadius, averageAngle ); + outerP3 = center.project( outerRadius, endAngle ); + } + wedge->addCurve( new QgsCircularString( outerP1, outerP2, outerP3 ) ); if ( !qgsDoubleNear( innerRadius, 0.0 ) && innerRadius > 0 ) { - const QgsPoint innerP1 = center.project( innerRadius, startAngle ); - const QgsPoint innerP2 = center.project( innerRadius, endAngle ); - wedge->addCurve( new QgsLineString( outerP2, innerP2 ) ); - wedge->addCurve( new QgsCircularString( QgsCircularString::fromTwoPointsAndCenter( innerP2, innerP1, center, useShortestArc ) ) ); + QgsPoint innerP1; + QgsPoint innerP2; + QgsPoint innerP3; + if ( crs.isGeographic() ) + { + innerP1 = QgsPoint( da.computeSpheroidProject( center, innerRadius, startAngle * M_PI / 180 ) ); + innerP2 = QgsPoint( da.computeSpheroidProject( center, innerRadius, averageAngle * M_PI / 180 ) ); + innerP3 = QgsPoint( da.computeSpheroidProject( center, innerRadius, endAngle * M_PI / 180 ) ); + } + else + { + innerP1 = center.project( innerRadius, startAngle ); + innerP2 = center.project( innerRadius, averageAngle ); + innerP3 = center.project( innerRadius, endAngle ); + } + wedge->addCurve( new QgsLineString( outerP3, innerP3 ) ); + wedge->addCurve( new QgsCircularString( innerP3, innerP2, innerP1 ) ); wedge->addCurve( new QgsLineString( innerP1, outerP1 ) ); } else { - wedge->addCurve( new QgsLineString( outerP2, center ) ); + wedge->addCurve( new QgsLineString( outerP3, center ) ); wedge->addCurve( new QgsLineString( center, outerP1 ) ); } diff --git a/src/core/geometry/qgsgeometry.h b/src/core/geometry/qgsgeometry.h index e9d26f20e96c..a4d06edb58eb 100644 --- a/src/core/geometry/qgsgeometry.h +++ b/src/core/geometry/qgsgeometry.h @@ -337,13 +337,15 @@ class CORE_EXPORT QgsGeometry * The outer radius of the buffer is specified via \a outerRadius, and optionally an * \a innerRadius can also be specified. * + * If the \a crs is given and is geographic, the wedge is projected along the ellipsoïd. + * * The returned geometry will be a CurvePolygon geometry containing circular strings. It may * need to be segmentized to convert to a standard Polygon geometry. * * \since QGIS 3.2 */ static QgsGeometry createWedgeBuffer( const QgsPoint ¢er, double azimuth, double angularWidth, - double outerRadius, double innerRadius = 0 ); + double outerRadius, double innerRadius = 0, const QgsCoordinateReferenceSystem &crs = QgsCoordinateReferenceSystem() ); /** * Creates a wedge shaped buffer from a \a center point. @@ -353,13 +355,15 @@ class CORE_EXPORT QgsGeometry * The outer radius of the buffer is specified via \a outerRadius, and optionally an * \a innerRadius can also be specified. * + * If the \a crs is given and is geographic, the wedge is projected along the ellipsoïd. + * * The returned geometry will be a CurvePolygon geometry containing circular strings. It may * need to be segmentized to convert to a standard Polygon geometry. * * \since QGIS 3.40 */ - static QgsGeometry createWedgeBufferV2( const QgsPoint ¢er, double startAngle, double endAngle, - double outerRadius, double innerRadius = 0 ); + static QgsGeometry createWedgeBufferFromAngles( const QgsPoint ¢er, double startAngle, double endAngle, + double outerRadius, double innerRadius = 0, const QgsCoordinateReferenceSystem &crs = QgsCoordinateReferenceSystem() ); /** * Set the geometry, feeding in the buffer containing OGC Well-Known Binary and the buffer's length. From 70eda6714fd63e7bd2c677d2d81691a7a8c1f7db Mon Sep 17 00:00:00 2001 From: Denis Rouzaud Date: Mon, 26 Aug 2024 15:42:11 +0200 Subject: [PATCH 04/26] normalize angles --- src/core/geometry/qgsgeometry.cpp | 37 +++++++++++++++++-------------- 1 file changed, 20 insertions(+), 17 deletions(-) diff --git a/src/core/geometry/qgsgeometry.cpp b/src/core/geometry/qgsgeometry.cpp index cee5ce2d418b..22a02644703e 100644 --- a/src/core/geometry/qgsgeometry.cpp +++ b/src/core/geometry/qgsgeometry.cpp @@ -409,6 +409,26 @@ QgsGeometry QgsGeometry::collectGeometry( const QVector< QgsGeometry > &geometri QgsGeometry QgsGeometry::createWedgeBuffer( const QgsPoint ¢er, const double azimuth, const double angularWidth, const double outerRadius, const double innerRadius, const QgsCoordinateReferenceSystem &crs ) { + const double startAngle = azimuth - angularWidth * 0.5; + const double endAngle = azimuth + angularWidth * 0.5; + + return createWedgeBufferFromAngles( center, startAngle, endAngle, outerRadius, innerRadius, crs ); +} + +QgsGeometry QgsGeometry::createWedgeBufferAngles( const QgsPoint ¢er, double startAngle, double endAngle, double outerRadius, double innerRadius, const QgsCoordinateReferenceSystem &crs ) +{ + std::unique_ptr< QgsCompoundCurve > wedge = std::make_unique< QgsCompoundCurve >(); + + startAngle = QgsGeometryUtils::normalizedAngle( startAngle * M_PI / 180 ) * 180 / M_PI; + endAngle = QgsGeometryUtils::normalizedAngle( endAngle * M_PI / 180 ) * 180 / M_PI; + + double angularWidth = endAngle - startAngle; + double averageAngle = QgsGeometryUtils::averageAngle( endAngle * M_PI / 180, startAngle * M_PI / 180 ) * 180 / M_PI; + + bool useShortestArc = angularWidth >= 0 && angularWidth <= 180.0 || angularWidth <= 180.0 && angularWidth >= -360.0; + if ( !useShortestArc ) + averageAngle += 180; + if ( std::abs( angularWidth ) >= 360.0 ) { std::unique_ptr< QgsCompoundCurve > outerCc = std::make_unique< QgsCompoundCurve >(); @@ -432,23 +452,6 @@ QgsGeometry QgsGeometry::createWedgeBuffer( const QgsPoint ¢er, const double return QgsGeometry( std::move( cp ) ); } - const double startAngle = azimuth - angularWidth * 0.5; - const double endAngle = azimuth + angularWidth * 0.5; - - return createWedgeBufferFromAngles( center, startAngle, endAngle, outerRadius, innerRadius, crs ); -} - -QgsGeometry QgsGeometry::createWedgeBufferAngles( const QgsPoint ¢er, double startAngle, double endAngle, double outerRadius, double innerRadius, const QgsCoordinateReferenceSystem &crs ) -{ - std::unique_ptr< QgsCompoundCurve > wedge = std::make_unique< QgsCompoundCurve >(); - - double angularWidth = endAngle - startAngle; - double averageAngle = QgsGeometryUtils::averageAngle( endAngle * M_PI / 180, startAngle * M_PI / 180 ) * 180 / M_PI; - - bool useShortestArc = angularWidth >= 0 && angularWidth <= 180.0 || angularWidth <= 0 && angularWidth >= -360.0; - if ( !useShortestArc ) - averageAngle += 180; - QgsDistanceArea da; if ( crs.isValid() && crs.isGeographic() ) { From da2d80a64748dba6daf06daf5e1ce1498c2e1ec2 Mon Sep 17 00:00:00 2001 From: Denis Rouzaud Date: Mon, 26 Aug 2024 15:46:33 +0200 Subject: [PATCH 05/26] add test --- tests/src/python/test_qgsgeometry.py | 49 +++++++++++++++++----------- 1 file changed, 30 insertions(+), 19 deletions(-) diff --git a/tests/src/python/test_qgsgeometry.py b/tests/src/python/test_qgsgeometry.py index e6e0898fc0dd..c0cd937b3d19 100644 --- a/tests/src/python/test_qgsgeometry.py +++ b/tests/src/python/test_qgsgeometry.py @@ -6198,40 +6198,51 @@ def testClipped(self): f"clipped: mismatch Expected:\n{exp}\nGot:\n{result}\n") def testCreateWedgeBuffer(self): - tests = [[QgsPoint(1, 11), 0, 45, 2, 0, + invalidCrs = QgsCoordinateReferenceSystem() + wgs84 = QgsCoordinateReferenceSystem::fromOgcWmsCrs( "EPSG:4326" ) + tests = [[QgsPoint(1, 11), 0, 45, -22.5, 22.5, 2, 0, invalidCrs, 'CurvePolygon (CompoundCurve (CircularString (0.23463313526982044 12.84775906502257392, 1 13, 1.76536686473017967 12.84775906502257392),(1.76536686473017967 12.84775906502257392, 1 11),(1 11, 0.23463313526982044 12.84775906502257392)))'], - [QgsPoint(1, 11), 90, 45, 2, 0, + [QgsPoint(1, 11), 90, 45, 67.5, 112.5, 2, 0, invalidCrs, 'CurvePolygon (CompoundCurve (CircularString (2.84775906502257348 11.76536686473017923, 3 11, 2.84775906502257348 10.23463313526982077),(2.84775906502257348 10.23463313526982077, 1 11),(1 11, 2.84775906502257348 11.76536686473017923)))'], - [QgsPoint(1, 11), 180, 90, 2, 0, + [QgsPoint(1, 11), 180, 90, 135, 225, 2, 0, invalidCrs, 'CurvePolygon (CompoundCurve (CircularString (2.41421356237309492 9.58578643762690419, 1.00000000000000022 9, -0.41421356237309492 9.58578643762690419),(-0.41421356237309492 9.58578643762690419, 1 11),(1 11, 2.41421356237309492 9.58578643762690419)))'], - [QgsPoint(1, 11), 0, 200, 2, 0, + [QgsPoint(1, 11), 0, 200, -100, 100, 2, 0, invalidCrs, 'CurvePolygon (CompoundCurve (CircularString (-0.96961550602441604 10.65270364466613984, 0.99999999999999956 13, 2.96961550602441626 10.65270364466613984),(2.96961550602441626 10.65270364466613984, 1 11),(1 11, -0.96961550602441604 10.65270364466613984)))'], - [QgsPoint(1, 11), 0, 45, 2, 1, + [QgsPoint(1, 11), 0, 45, -22.5, 22.5, 2, 1, invalidCrs, 'CurvePolygon (CompoundCurve (CircularString (0.23463313526982044 12.84775906502257392, 1 13, 1.76536686473017967 12.84775906502257392),(1.76536686473017967 12.84775906502257392, 1.38268343236508984 11.92387953251128607),CircularString (1.38268343236508984 11.92387953251128607, 0.99999999999999978 12, 0.61731656763491016 11.92387953251128607),(0.61731656763491016 11.92387953251128607, 0.23463313526982044 12.84775906502257392)))'], - [QgsPoint(1, 11), 0, 200, 2, 1, + [QgsPoint(1, 11), 0, 200, -100, 100, 2, 1, invalidCrs, 'CurvePolygon (CompoundCurve (CircularString (-0.96961550602441604 10.65270364466613984, 0.99999999999999956 13, 2.96961550602441626 10.65270364466613984),(2.96961550602441626 10.65270364466613984, 1.98480775301220813 10.82635182233306992),CircularString (1.98480775301220813 10.82635182233306992, 0.99999999999999978 12, 0.01519224698779198 10.82635182233306992),(0.01519224698779198 10.82635182233306992, -0.96961550602441604 10.65270364466613984)))'], - [QgsPoint(1, 11, 3), 0, 45, 2, 0, + [QgsPoint(1, 11, 3), 0, 45, -22.5, 22.5, 2, 0, invalidCrs, 'CurvePolygonZ (CompoundCurveZ (CircularStringZ (0.23463313526982044 12.84775906502257392 3, 1 13 3, 1.76536686473017967 12.84775906502257392 3),(1.76536686473017967 12.84775906502257392 3, 1 11 3),(1 11 3, 0.23463313526982044 12.84775906502257392 3)))'], - [QgsPoint(1, 11, m=3), 0, 45, 2, 0, + [QgsPoint(1, 11, m=3), 0, 45, -22.5, 22.5, 2, 0, invalidCrs, 'CurvePolygonM (CompoundCurveM (CircularStringM (0.23463313526982044 12.84775906502257392 3, 1 13 3, 1.76536686473017967 12.84775906502257392 3),(1.76536686473017967 12.84775906502257392 3, 1 11 3),(1 11 3, 0.23463313526982044 12.84775906502257392 3)))'], - [QgsPoint(1, 11), 0, 360, 2, 0, + [QgsPoint(1, 11), 0, 360, -180, 180, 2, 0, invalidCrs, 'CurvePolygon (CompoundCurve (CircularString (1 13, 3 11, 1 9, -1 11, 1 13)))'], - [QgsPoint(1, 11), 0, -1000, 2, 0, + [QgsPoint(1, 11), 0, -1000, 0, 360, 2, 0, invalidCrs, 'CurvePolygon (CompoundCurve (CircularString (1 13, 3 11, 1 9, -1 11, 1 13)))'], - [QgsPoint(1, 11), 0, 360, 2, 1, + [QgsPoint(1, 11), 0, 360, -180, 180, 2, 1, invalidCrs, + 'CurvePolygon (CompoundCurve (CircularString (1 13, 3 11, 1 9, -1 11, 1 13)),CompoundCurve (CircularString (1 12, 2 11, 1 10, 0 11, 1 12)))'] + [QgsPoint(1, 11), 10, 40, 350, 30, 2, 1, wgs84, 'CurvePolygon (CompoundCurve (CircularString (1 13, 3 11, 1 9, -1 11, 1 13)),CompoundCurve (CircularString (1 12, 2 11, 1 10, 0 11, 1 12)))'] ] for t in tests: - input = t[0] + point = t[0] azimuth = t[1] width = t[2] - outer = t[3] - inner = t[4] - o = QgsGeometry.createWedgeBuffer(input, azimuth, width, outer, inner) - exp = t[5] - result = o.asWkt() - self.assertTrue(compareWkt(result, exp, 0.01), - f"wedge buffer: mismatch Expected:\n{exp}\nGot:\n{result}\n") + startAngle = t[3] + endAngle = t[4] + outer = t[5] + inner = t[6] + crs = t[7] + o1 = QgsGeometry.createWedgeBuffer(point, azimuth, width, outer, inner, crs) + o2 = QgsGeometry.createWedgeBufferFromAngles(point, azimuth, width, outer, inner, crs) + exp = t[8] + result1 = o1.asWkt() + result2 = o2.asWkt() + self.assertTrue(compareWkt(result1, exp, 0.01), + f"wedge buffer from azimuth: mismatch Expected:\n{exp}\nGot:\n{result1}\n") + self.assertTrue(compareWkt(result2, exp, 0.01), + f"wedge buffer from angles: mismatch Expected:\n{exp}\nGot:\n{result2}\n") def testTaperedBuffer(self): tests = [['LineString (6 2, 9 2, 9 3, 11 5)', 1, 2, 3, From ffc3be99cdfe04b87d291bd565f7be85fea91d29 Mon Sep 17 00:00:00 2001 From: Denis Rouzaud Date: Mon, 26 Aug 2024 15:56:16 +0200 Subject: [PATCH 06/26] fix test --- tests/src/python/test_qgsgeometry.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/src/python/test_qgsgeometry.py b/tests/src/python/test_qgsgeometry.py index c0cd937b3d19..5f0711ef68d8 100644 --- a/tests/src/python/test_qgsgeometry.py +++ b/tests/src/python/test_qgsgeometry.py @@ -1,4 +1,4 @@ -"""QGIS Unit tests for QgsGeometry. + """QGIS Unit tests for QgsGeometry. .. note:: This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -6199,7 +6199,7 @@ def testClipped(self): def testCreateWedgeBuffer(self): invalidCrs = QgsCoordinateReferenceSystem() - wgs84 = QgsCoordinateReferenceSystem::fromOgcWmsCrs( "EPSG:4326" ) + wgs84 = QgsCoordinateReferenceSystem.fromOgcWmsCrs("EPSG:4326") tests = [[QgsPoint(1, 11), 0, 45, -22.5, 22.5, 2, 0, invalidCrs, 'CurvePolygon (CompoundCurve (CircularString (0.23463313526982044 12.84775906502257392, 1 13, 1.76536686473017967 12.84775906502257392),(1.76536686473017967 12.84775906502257392, 1 11),(1 11, 0.23463313526982044 12.84775906502257392)))'], [QgsPoint(1, 11), 90, 45, 67.5, 112.5, 2, 0, invalidCrs, From f935a2e54e3fdae5f1b63f9495b31e1646de5030 Mon Sep 17 00:00:00 2001 From: Denis Rouzaud Date: Mon, 26 Aug 2024 20:51:59 +0200 Subject: [PATCH 07/26] fix test --- tests/src/python/test_qgsgeometry.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/src/python/test_qgsgeometry.py b/tests/src/python/test_qgsgeometry.py index 5f0711ef68d8..d655a2a895a1 100644 --- a/tests/src/python/test_qgsgeometry.py +++ b/tests/src/python/test_qgsgeometry.py @@ -6221,7 +6221,7 @@ def testCreateWedgeBuffer(self): [QgsPoint(1, 11), 0, -1000, 0, 360, 2, 0, invalidCrs, 'CurvePolygon (CompoundCurve (CircularString (1 13, 3 11, 1 9, -1 11, 1 13)))'], [QgsPoint(1, 11), 0, 360, -180, 180, 2, 1, invalidCrs, - 'CurvePolygon (CompoundCurve (CircularString (1 13, 3 11, 1 9, -1 11, 1 13)),CompoundCurve (CircularString (1 12, 2 11, 1 10, 0 11, 1 12)))'] + 'CurvePolygon (CompoundCurve (CircularString (1 13, 3 11, 1 9, -1 11, 1 13)),CompoundCurve (CircularString (1 12, 2 11, 1 10, 0 11, 1 12)))'], [QgsPoint(1, 11), 10, 40, 350, 30, 2, 1, wgs84, 'CurvePolygon (CompoundCurve (CircularString (1 13, 3 11, 1 9, -1 11, 1 13)),CompoundCurve (CircularString (1 12, 2 11, 1 10, 0 11, 1 12)))'] ] From cf113ace3cf5b299515822ab312e0880d19d3c99 Mon Sep 17 00:00:00 2001 From: Denis Rouzaud Date: Mon, 26 Aug 2024 20:54:15 +0200 Subject: [PATCH 08/26] missing include --- src/core/geometry/qgsgeometry.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/core/geometry/qgsgeometry.h b/src/core/geometry/qgsgeometry.h index a4d06edb58eb..cf4989d5b2ad 100644 --- a/src/core/geometry/qgsgeometry.h +++ b/src/core/geometry/qgsgeometry.h @@ -30,6 +30,7 @@ email : morb at ozemail dot com dot au #include "qgis_core.h" #include "qgis_sip.h" +#include "qgscoordinatereferencesystem.h" #include "qgsabstractgeometry.h" #include "qgspointxy.h" From 7bb1cec07b6a5d16c41a989419d80e9b59e9a98a Mon Sep 17 00:00:00 2001 From: Denis Rouzaud Date: Mon, 26 Aug 2024 21:06:52 +0200 Subject: [PATCH 09/26] typo --- src/core/geometry/qgsgeometry.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/geometry/qgsgeometry.cpp b/src/core/geometry/qgsgeometry.cpp index 22a02644703e..85487417524c 100644 --- a/src/core/geometry/qgsgeometry.cpp +++ b/src/core/geometry/qgsgeometry.cpp @@ -415,7 +415,7 @@ QgsGeometry QgsGeometry::createWedgeBuffer( const QgsPoint ¢er, const double return createWedgeBufferFromAngles( center, startAngle, endAngle, outerRadius, innerRadius, crs ); } -QgsGeometry QgsGeometry::createWedgeBufferAngles( const QgsPoint ¢er, double startAngle, double endAngle, double outerRadius, double innerRadius, const QgsCoordinateReferenceSystem &crs ) +QgsGeometry QgsGeometry::createWedgeBufferFromAngles( const QgsPoint ¢er, double startAngle, double endAngle, double outerRadius, double innerRadius, const QgsCoordinateReferenceSystem &crs ) { std::unique_ptr< QgsCompoundCurve > wedge = std::make_unique< QgsCompoundCurve >(); From 7b5cdd26a0f20d7fbf65c6638e964280298b35ec Mon Sep 17 00:00:00 2001 From: Denis Rouzaud Date: Mon, 26 Aug 2024 21:13:55 +0200 Subject: [PATCH 10/26] fix indentation --- tests/src/python/test_qgsgeometry.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/src/python/test_qgsgeometry.py b/tests/src/python/test_qgsgeometry.py index d655a2a895a1..a015a70f5103 100644 --- a/tests/src/python/test_qgsgeometry.py +++ b/tests/src/python/test_qgsgeometry.py @@ -1,4 +1,4 @@ - """QGIS Unit tests for QgsGeometry. +"""QGIS Unit tests for QgsGeometry. .. note:: This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by From aebfbc9120c640941251179f00edb0747ea592fe Mon Sep 17 00:00:00 2001 From: Denis Rouzaud Date: Mon, 26 Aug 2024 21:09:48 +0200 Subject: [PATCH 11/26] sipify --- .../PyQt6/core/auto_additions/qgsgeometry.py | 1 + .../geometry/qgsgeometry.sip.in | 22 ++++++++++++++++++- python/core/auto_additions/qgsgeometry.py | 1 + .../geometry/qgsgeometry.sip.in | 22 ++++++++++++++++++- 4 files changed, 44 insertions(+), 2 deletions(-) diff --git a/python/PyQt6/core/auto_additions/qgsgeometry.py b/python/PyQt6/core/auto_additions/qgsgeometry.py index 022745384afd..cc6aaafd0f9e 100644 --- a/python/PyQt6/core/auto_additions/qgsgeometry.py +++ b/python/PyQt6/core/auto_additions/qgsgeometry.py @@ -12,6 +12,7 @@ QgsGeometry.fromBox3D = staticmethod(QgsGeometry.fromBox3D) QgsGeometry.collectGeometry = staticmethod(QgsGeometry.collectGeometry) QgsGeometry.createWedgeBuffer = staticmethod(QgsGeometry.createWedgeBuffer) +QgsGeometry.createWedgeBufferFromAngles = staticmethod(QgsGeometry.createWedgeBufferFromAngles) QgsGeometry.unaryUnion = staticmethod(QgsGeometry.unaryUnion) QgsGeometry.polygonize = staticmethod(QgsGeometry.polygonize) QgsGeometry.fromQPointF = staticmethod(QgsGeometry.fromQPointF) diff --git a/python/PyQt6/core/auto_generated/geometry/qgsgeometry.sip.in b/python/PyQt6/core/auto_generated/geometry/qgsgeometry.sip.in index e524d105f2f2..46b1a689916b 100644 --- a/python/PyQt6/core/auto_generated/geometry/qgsgeometry.sip.in +++ b/python/PyQt6/core/auto_generated/geometry/qgsgeometry.sip.in @@ -273,7 +273,7 @@ Creates a new multipart geometry from a list of QgsGeometry objects %End static QgsGeometry createWedgeBuffer( const QgsPoint ¢er, double azimuth, double angularWidth, - double outerRadius, double innerRadius = 0 ); + double outerRadius, double innerRadius = 0, const QgsCoordinateReferenceSystem &crs = QgsCoordinateReferenceSystem() ); %Docstring Creates a wedge shaped buffer from a ``center`` point. @@ -284,12 +284,32 @@ wedge will extend to half of the ``angularWidth`` either side of the ``azimuth`` The outer radius of the buffer is specified via ``outerRadius``, and optionally an ``innerRadius`` can also be specified. +If the ``crs`` is given and is geographic, the wedge is projected along the ellipsoïd. + The returned geometry will be a CurvePolygon geometry containing circular strings. It may need to be segmentized to convert to a standard Polygon geometry. .. versionadded:: 3.2 %End + static QgsGeometry createWedgeBufferFromAngles( const QgsPoint ¢er, double startAngle, double endAngle, + double outerRadius, double innerRadius = 0, const QgsCoordinateReferenceSystem &crs = QgsCoordinateReferenceSystem() ); +%Docstring +Creates a wedge shaped buffer from a ``center`` point. + +The wedges goes from the ``startAngle`` to ``endAngle`` in degrees. + +The outer radius of the buffer is specified via ``outerRadius``, and optionally an +``innerRadius`` can also be specified. + +If the ``crs`` is given and is geographic, the wedge is projected along the ellipsoïd. + +The returned geometry will be a CurvePolygon geometry containing circular strings. It may +need to be segmentized to convert to a standard Polygon geometry. + +.. versionadded:: 3.40 +%End + void fromWkb( const QByteArray &wkb ); %Docstring diff --git a/python/core/auto_additions/qgsgeometry.py b/python/core/auto_additions/qgsgeometry.py index 022745384afd..cc6aaafd0f9e 100644 --- a/python/core/auto_additions/qgsgeometry.py +++ b/python/core/auto_additions/qgsgeometry.py @@ -12,6 +12,7 @@ QgsGeometry.fromBox3D = staticmethod(QgsGeometry.fromBox3D) QgsGeometry.collectGeometry = staticmethod(QgsGeometry.collectGeometry) QgsGeometry.createWedgeBuffer = staticmethod(QgsGeometry.createWedgeBuffer) +QgsGeometry.createWedgeBufferFromAngles = staticmethod(QgsGeometry.createWedgeBufferFromAngles) QgsGeometry.unaryUnion = staticmethod(QgsGeometry.unaryUnion) QgsGeometry.polygonize = staticmethod(QgsGeometry.polygonize) QgsGeometry.fromQPointF = staticmethod(QgsGeometry.fromQPointF) diff --git a/python/core/auto_generated/geometry/qgsgeometry.sip.in b/python/core/auto_generated/geometry/qgsgeometry.sip.in index e524d105f2f2..46b1a689916b 100644 --- a/python/core/auto_generated/geometry/qgsgeometry.sip.in +++ b/python/core/auto_generated/geometry/qgsgeometry.sip.in @@ -273,7 +273,7 @@ Creates a new multipart geometry from a list of QgsGeometry objects %End static QgsGeometry createWedgeBuffer( const QgsPoint ¢er, double azimuth, double angularWidth, - double outerRadius, double innerRadius = 0 ); + double outerRadius, double innerRadius = 0, const QgsCoordinateReferenceSystem &crs = QgsCoordinateReferenceSystem() ); %Docstring Creates a wedge shaped buffer from a ``center`` point. @@ -284,12 +284,32 @@ wedge will extend to half of the ``angularWidth`` either side of the ``azimuth`` The outer radius of the buffer is specified via ``outerRadius``, and optionally an ``innerRadius`` can also be specified. +If the ``crs`` is given and is geographic, the wedge is projected along the ellipsoïd. + The returned geometry will be a CurvePolygon geometry containing circular strings. It may need to be segmentized to convert to a standard Polygon geometry. .. versionadded:: 3.2 %End + static QgsGeometry createWedgeBufferFromAngles( const QgsPoint ¢er, double startAngle, double endAngle, + double outerRadius, double innerRadius = 0, const QgsCoordinateReferenceSystem &crs = QgsCoordinateReferenceSystem() ); +%Docstring +Creates a wedge shaped buffer from a ``center`` point. + +The wedges goes from the ``startAngle`` to ``endAngle`` in degrees. + +The outer radius of the buffer is specified via ``outerRadius``, and optionally an +``innerRadius`` can also be specified. + +If the ``crs`` is given and is geographic, the wedge is projected along the ellipsoïd. + +The returned geometry will be a CurvePolygon geometry containing circular strings. It may +need to be segmentized to convert to a standard Polygon geometry. + +.. versionadded:: 3.40 +%End + void fromWkb( const QByteArray &wkb ); %Docstring From a5499a7212fbb123bba019b63ace928011b24c1d Mon Sep 17 00:00:00 2001 From: Denis Rouzaud Date: Tue, 27 Aug 2024 07:50:38 +0200 Subject: [PATCH 12/26] =?UTF-8?q?remove=20ellipso=C3=AFd=20version?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../geometry/qgsgeometry.sip.in | 8 +--- src/core/geometry/qgsgeometry.cpp | 48 ++++--------------- src/core/geometry/qgsgeometry.h | 9 +--- tests/src/python/test_qgsgeometry.py | 29 +++++------ 4 files changed, 25 insertions(+), 69 deletions(-) diff --git a/python/PyQt6/core/auto_generated/geometry/qgsgeometry.sip.in b/python/PyQt6/core/auto_generated/geometry/qgsgeometry.sip.in index 46b1a689916b..d7c72159e280 100644 --- a/python/PyQt6/core/auto_generated/geometry/qgsgeometry.sip.in +++ b/python/PyQt6/core/auto_generated/geometry/qgsgeometry.sip.in @@ -273,7 +273,7 @@ Creates a new multipart geometry from a list of QgsGeometry objects %End static QgsGeometry createWedgeBuffer( const QgsPoint ¢er, double azimuth, double angularWidth, - double outerRadius, double innerRadius = 0, const QgsCoordinateReferenceSystem &crs = QgsCoordinateReferenceSystem() ); + double outerRadius, double innerRadius = 0 ); %Docstring Creates a wedge shaped buffer from a ``center`` point. @@ -284,8 +284,6 @@ wedge will extend to half of the ``angularWidth`` either side of the ``azimuth`` The outer radius of the buffer is specified via ``outerRadius``, and optionally an ``innerRadius`` can also be specified. -If the ``crs`` is given and is geographic, the wedge is projected along the ellipsoïd. - The returned geometry will be a CurvePolygon geometry containing circular strings. It may need to be segmentized to convert to a standard Polygon geometry. @@ -293,7 +291,7 @@ need to be segmentized to convert to a standard Polygon geometry. %End static QgsGeometry createWedgeBufferFromAngles( const QgsPoint ¢er, double startAngle, double endAngle, - double outerRadius, double innerRadius = 0, const QgsCoordinateReferenceSystem &crs = QgsCoordinateReferenceSystem() ); + double outerRadius, double innerRadius = 0 ); %Docstring Creates a wedge shaped buffer from a ``center`` point. @@ -302,8 +300,6 @@ The wedges goes from the ``startAngle`` to ``endAngle`` in degrees. The outer radius of the buffer is specified via ``outerRadius``, and optionally an ``innerRadius`` can also be specified. -If the ``crs`` is given and is geographic, the wedge is projected along the ellipsoïd. - The returned geometry will be a CurvePolygon geometry containing circular strings. It may need to be segmentized to convert to a standard Polygon geometry. diff --git a/src/core/geometry/qgsgeometry.cpp b/src/core/geometry/qgsgeometry.cpp index 85487417524c..85dd6a82aac8 100644 --- a/src/core/geometry/qgsgeometry.cpp +++ b/src/core/geometry/qgsgeometry.cpp @@ -407,15 +407,15 @@ QgsGeometry QgsGeometry::collectGeometry( const QVector< QgsGeometry > &geometri return collected; } -QgsGeometry QgsGeometry::createWedgeBuffer( const QgsPoint ¢er, const double azimuth, const double angularWidth, const double outerRadius, const double innerRadius, const QgsCoordinateReferenceSystem &crs ) +QgsGeometry QgsGeometry::createWedgeBuffer( const QgsPoint ¢er, const double azimuth, const double angularWidth, const double outerRadius, const double innerRadius ) { const double startAngle = azimuth - angularWidth * 0.5; const double endAngle = azimuth + angularWidth * 0.5; - return createWedgeBufferFromAngles( center, startAngle, endAngle, outerRadius, innerRadius, crs ); + return createWedgeBufferFromAngles( center, startAngle, endAngle, outerRadius, innerRadius ); } -QgsGeometry QgsGeometry::createWedgeBufferFromAngles( const QgsPoint ¢er, double startAngle, double endAngle, double outerRadius, double innerRadius, const QgsCoordinateReferenceSystem &crs ) +QgsGeometry QgsGeometry::createWedgeBufferFromAngles( const QgsPoint ¢er, double startAngle, double endAngle, double outerRadius, double innerRadius ) { std::unique_ptr< QgsCompoundCurve > wedge = std::make_unique< QgsCompoundCurve >(); @@ -452,47 +452,17 @@ QgsGeometry QgsGeometry::createWedgeBufferFromAngles( const QgsPoint ¢er, do return QgsGeometry( std::move( cp ) ); } - QgsDistanceArea da; - if ( crs.isValid() && crs.isGeographic() ) - { - da.setSourceCrs( crs, QgsProject::instance()->transformContext() ); - da.setEllipsoid( crs.ellipsoidAcronym() ); - } + const QgsPoint outerP1 = center.project( outerRadius, startAngle ); + const QgsPoint outerP2 = center.project( outerRadius, averageAngle ); + const QgsPoint outerP3 = center.project( outerRadius, endAngle ); - QgsPoint outerP1; - QgsPoint outerP2; - QgsPoint outerP3; - if ( crs.isGeographic() ) - { - outerP1 = QgsPoint( da.computeSpheroidProject( center, outerRadius, startAngle * M_PI / 180 ) ); - outerP2 = QgsPoint( da.computeSpheroidProject( center, outerRadius, averageAngle * M_PI / 180 ) ); - outerP3 = QgsPoint( da.computeSpheroidProject( center, outerRadius, endAngle * M_PI / 180 ) ); - } - else - { - outerP1 = center.project( outerRadius, startAngle ); - outerP2 = center.project( outerRadius, averageAngle ); - outerP3 = center.project( outerRadius, endAngle ); - } wedge->addCurve( new QgsCircularString( outerP1, outerP2, outerP3 ) ); if ( !qgsDoubleNear( innerRadius, 0.0 ) && innerRadius > 0 ) { - QgsPoint innerP1; - QgsPoint innerP2; - QgsPoint innerP3; - if ( crs.isGeographic() ) - { - innerP1 = QgsPoint( da.computeSpheroidProject( center, innerRadius, startAngle * M_PI / 180 ) ); - innerP2 = QgsPoint( da.computeSpheroidProject( center, innerRadius, averageAngle * M_PI / 180 ) ); - innerP3 = QgsPoint( da.computeSpheroidProject( center, innerRadius, endAngle * M_PI / 180 ) ); - } - else - { - innerP1 = center.project( innerRadius, startAngle ); - innerP2 = center.project( innerRadius, averageAngle ); - innerP3 = center.project( innerRadius, endAngle ); - } + const QgsPoint innerP1 = center.project( innerRadius, startAngle ); + const QgsPoint innerP2 = center.project( innerRadius, averageAngle ); + const QgsPoint innerP3 = center.project( innerRadius, endAngle ); wedge->addCurve( new QgsLineString( outerP3, innerP3 ) ); wedge->addCurve( new QgsCircularString( innerP3, innerP2, innerP1 ) ); wedge->addCurve( new QgsLineString( innerP1, outerP1 ) ); diff --git a/src/core/geometry/qgsgeometry.h b/src/core/geometry/qgsgeometry.h index cf4989d5b2ad..3ec8e40cd09a 100644 --- a/src/core/geometry/qgsgeometry.h +++ b/src/core/geometry/qgsgeometry.h @@ -30,7 +30,6 @@ email : morb at ozemail dot com dot au #include "qgis_core.h" #include "qgis_sip.h" -#include "qgscoordinatereferencesystem.h" #include "qgsabstractgeometry.h" #include "qgspointxy.h" @@ -338,15 +337,13 @@ class CORE_EXPORT QgsGeometry * The outer radius of the buffer is specified via \a outerRadius, and optionally an * \a innerRadius can also be specified. * - * If the \a crs is given and is geographic, the wedge is projected along the ellipsoïd. - * * The returned geometry will be a CurvePolygon geometry containing circular strings. It may * need to be segmentized to convert to a standard Polygon geometry. * * \since QGIS 3.2 */ static QgsGeometry createWedgeBuffer( const QgsPoint ¢er, double azimuth, double angularWidth, - double outerRadius, double innerRadius = 0, const QgsCoordinateReferenceSystem &crs = QgsCoordinateReferenceSystem() ); + double outerRadius, double innerRadius = 0 ); /** * Creates a wedge shaped buffer from a \a center point. @@ -356,15 +353,13 @@ class CORE_EXPORT QgsGeometry * The outer radius of the buffer is specified via \a outerRadius, and optionally an * \a innerRadius can also be specified. * - * If the \a crs is given and is geographic, the wedge is projected along the ellipsoïd. - * * The returned geometry will be a CurvePolygon geometry containing circular strings. It may * need to be segmentized to convert to a standard Polygon geometry. * * \since QGIS 3.40 */ static QgsGeometry createWedgeBufferFromAngles( const QgsPoint ¢er, double startAngle, double endAngle, - double outerRadius, double innerRadius = 0, const QgsCoordinateReferenceSystem &crs = QgsCoordinateReferenceSystem() ); + double outerRadius, double innerRadius = 0 ); /** * Set the geometry, feeding in the buffer containing OGC Well-Known Binary and the buffer's length. diff --git a/tests/src/python/test_qgsgeometry.py b/tests/src/python/test_qgsgeometry.py index a015a70f5103..367161a7feb8 100644 --- a/tests/src/python/test_qgsgeometry.py +++ b/tests/src/python/test_qgsgeometry.py @@ -6198,32 +6198,28 @@ def testClipped(self): f"clipped: mismatch Expected:\n{exp}\nGot:\n{result}\n") def testCreateWedgeBuffer(self): - invalidCrs = QgsCoordinateReferenceSystem() - wgs84 = QgsCoordinateReferenceSystem.fromOgcWmsCrs("EPSG:4326") - tests = [[QgsPoint(1, 11), 0, 45, -22.5, 22.5, 2, 0, invalidCrs, + tests = [[QgsPoint(1, 11), 0, 45, -22.5, 22.5, 2, 0, 'CurvePolygon (CompoundCurve (CircularString (0.23463313526982044 12.84775906502257392, 1 13, 1.76536686473017967 12.84775906502257392),(1.76536686473017967 12.84775906502257392, 1 11),(1 11, 0.23463313526982044 12.84775906502257392)))'], - [QgsPoint(1, 11), 90, 45, 67.5, 112.5, 2, 0, invalidCrs, + [QgsPoint(1, 11), 90, 45, 67.5, 112.5, 2, 0, 'CurvePolygon (CompoundCurve (CircularString (2.84775906502257348 11.76536686473017923, 3 11, 2.84775906502257348 10.23463313526982077),(2.84775906502257348 10.23463313526982077, 1 11),(1 11, 2.84775906502257348 11.76536686473017923)))'], - [QgsPoint(1, 11), 180, 90, 135, 225, 2, 0, invalidCrs, + [QgsPoint(1, 11), 180, 90, 135, 225, 2, 0, 'CurvePolygon (CompoundCurve (CircularString (2.41421356237309492 9.58578643762690419, 1.00000000000000022 9, -0.41421356237309492 9.58578643762690419),(-0.41421356237309492 9.58578643762690419, 1 11),(1 11, 2.41421356237309492 9.58578643762690419)))'], - [QgsPoint(1, 11), 0, 200, -100, 100, 2, 0, invalidCrs, + [QgsPoint(1, 11), 0, 200, -100, 100, 2, 0, 'CurvePolygon (CompoundCurve (CircularString (-0.96961550602441604 10.65270364466613984, 0.99999999999999956 13, 2.96961550602441626 10.65270364466613984),(2.96961550602441626 10.65270364466613984, 1 11),(1 11, -0.96961550602441604 10.65270364466613984)))'], - [QgsPoint(1, 11), 0, 45, -22.5, 22.5, 2, 1, invalidCrs, + [QgsPoint(1, 11), 0, 45, -22.5, 22.5, 2, 1, 'CurvePolygon (CompoundCurve (CircularString (0.23463313526982044 12.84775906502257392, 1 13, 1.76536686473017967 12.84775906502257392),(1.76536686473017967 12.84775906502257392, 1.38268343236508984 11.92387953251128607),CircularString (1.38268343236508984 11.92387953251128607, 0.99999999999999978 12, 0.61731656763491016 11.92387953251128607),(0.61731656763491016 11.92387953251128607, 0.23463313526982044 12.84775906502257392)))'], - [QgsPoint(1, 11), 0, 200, -100, 100, 2, 1, invalidCrs, + [QgsPoint(1, 11), 0, 200, -100, 100, 2, 1, 'CurvePolygon (CompoundCurve (CircularString (-0.96961550602441604 10.65270364466613984, 0.99999999999999956 13, 2.96961550602441626 10.65270364466613984),(2.96961550602441626 10.65270364466613984, 1.98480775301220813 10.82635182233306992),CircularString (1.98480775301220813 10.82635182233306992, 0.99999999999999978 12, 0.01519224698779198 10.82635182233306992),(0.01519224698779198 10.82635182233306992, -0.96961550602441604 10.65270364466613984)))'], - [QgsPoint(1, 11, 3), 0, 45, -22.5, 22.5, 2, 0, invalidCrs, + [QgsPoint(1, 11, 3), 0, 45, -22.5, 22.5, 2, 0, 'CurvePolygonZ (CompoundCurveZ (CircularStringZ (0.23463313526982044 12.84775906502257392 3, 1 13 3, 1.76536686473017967 12.84775906502257392 3),(1.76536686473017967 12.84775906502257392 3, 1 11 3),(1 11 3, 0.23463313526982044 12.84775906502257392 3)))'], - [QgsPoint(1, 11, m=3), 0, 45, -22.5, 22.5, 2, 0, invalidCrs, + [QgsPoint(1, 11, m=3), 0, 45, -22.5, 22.5, 2, 0, 'CurvePolygonM (CompoundCurveM (CircularStringM (0.23463313526982044 12.84775906502257392 3, 1 13 3, 1.76536686473017967 12.84775906502257392 3),(1.76536686473017967 12.84775906502257392 3, 1 11 3),(1 11 3, 0.23463313526982044 12.84775906502257392 3)))'], - [QgsPoint(1, 11), 0, 360, -180, 180, 2, 0, invalidCrs, + [QgsPoint(1, 11), 0, 360, -180, 180, 2, 0, 'CurvePolygon (CompoundCurve (CircularString (1 13, 3 11, 1 9, -1 11, 1 13)))'], - [QgsPoint(1, 11), 0, -1000, 0, 360, 2, 0, invalidCrs, + [QgsPoint(1, 11), 0, -1000, 0, 360, 2, 0, 'CurvePolygon (CompoundCurve (CircularString (1 13, 3 11, 1 9, -1 11, 1 13)))'], - [QgsPoint(1, 11), 0, 360, -180, 180, 2, 1, invalidCrs, + [QgsPoint(1, 11), 0, 360, -180, 180, 2, 1, 'CurvePolygon (CompoundCurve (CircularString (1 13, 3 11, 1 9, -1 11, 1 13)),CompoundCurve (CircularString (1 12, 2 11, 1 10, 0 11, 1 12)))'], - [QgsPoint(1, 11), 10, 40, 350, 30, 2, 1, wgs84, - 'CurvePolygon (CompoundCurve (CircularString (1 13, 3 11, 1 9, -1 11, 1 13)),CompoundCurve (CircularString (1 12, 2 11, 1 10, 0 11, 1 12)))'] ] for t in tests: point = t[0] @@ -6233,10 +6229,9 @@ def testCreateWedgeBuffer(self): endAngle = t[4] outer = t[5] inner = t[6] - crs = t[7] o1 = QgsGeometry.createWedgeBuffer(point, azimuth, width, outer, inner, crs) o2 = QgsGeometry.createWedgeBufferFromAngles(point, azimuth, width, outer, inner, crs) - exp = t[8] + exp = t[7] result1 = o1.asWkt() result2 = o2.asWkt() self.assertTrue(compareWkt(result1, exp, 0.01), From 1683f8a1b855cb0838b5a222032df35f3d0a6376 Mon Sep 17 00:00:00 2001 From: Denis Rouzaud Date: Tue, 27 Aug 2024 07:53:22 +0200 Subject: [PATCH 13/26] sipify --- python/core/auto_generated/geometry/qgsgeometry.sip.in | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/python/core/auto_generated/geometry/qgsgeometry.sip.in b/python/core/auto_generated/geometry/qgsgeometry.sip.in index 46b1a689916b..d7c72159e280 100644 --- a/python/core/auto_generated/geometry/qgsgeometry.sip.in +++ b/python/core/auto_generated/geometry/qgsgeometry.sip.in @@ -273,7 +273,7 @@ Creates a new multipart geometry from a list of QgsGeometry objects %End static QgsGeometry createWedgeBuffer( const QgsPoint ¢er, double azimuth, double angularWidth, - double outerRadius, double innerRadius = 0, const QgsCoordinateReferenceSystem &crs = QgsCoordinateReferenceSystem() ); + double outerRadius, double innerRadius = 0 ); %Docstring Creates a wedge shaped buffer from a ``center`` point. @@ -284,8 +284,6 @@ wedge will extend to half of the ``angularWidth`` either side of the ``azimuth`` The outer radius of the buffer is specified via ``outerRadius``, and optionally an ``innerRadius`` can also be specified. -If the ``crs`` is given and is geographic, the wedge is projected along the ellipsoïd. - The returned geometry will be a CurvePolygon geometry containing circular strings. It may need to be segmentized to convert to a standard Polygon geometry. @@ -293,7 +291,7 @@ need to be segmentized to convert to a standard Polygon geometry. %End static QgsGeometry createWedgeBufferFromAngles( const QgsPoint ¢er, double startAngle, double endAngle, - double outerRadius, double innerRadius = 0, const QgsCoordinateReferenceSystem &crs = QgsCoordinateReferenceSystem() ); + double outerRadius, double innerRadius = 0 ); %Docstring Creates a wedge shaped buffer from a ``center`` point. @@ -302,8 +300,6 @@ The wedges goes from the ``startAngle`` to ``endAngle`` in degrees. The outer radius of the buffer is specified via ``outerRadius``, and optionally an ``innerRadius`` can also be specified. -If the ``crs`` is given and is geographic, the wedge is projected along the ellipsoïd. - The returned geometry will be a CurvePolygon geometry containing circular strings. It may need to be segmentized to convert to a standard Polygon geometry. From e6b0c4ed5383d23f9c3b9bd0a0214d0aaf7c172e Mon Sep 17 00:00:00 2001 From: Denis Rouzaud Date: Tue, 27 Aug 2024 11:05:24 +0200 Subject: [PATCH 14/26] fix warnings --- src/core/geometry/qgsgeometry.cpp | 6 +++--- tests/src/python/test_qgsgeometry.py | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/core/geometry/qgsgeometry.cpp b/src/core/geometry/qgsgeometry.cpp index 85dd6a82aac8..b600c50d0a6c 100644 --- a/src/core/geometry/qgsgeometry.cpp +++ b/src/core/geometry/qgsgeometry.cpp @@ -419,13 +419,13 @@ QgsGeometry QgsGeometry::createWedgeBufferFromAngles( const QgsPoint ¢er, do { std::unique_ptr< QgsCompoundCurve > wedge = std::make_unique< QgsCompoundCurve >(); - startAngle = QgsGeometryUtils::normalizedAngle( startAngle * M_PI / 180 ) * 180 / M_PI; - endAngle = QgsGeometryUtils::normalizedAngle( endAngle * M_PI / 180 ) * 180 / M_PI; + startAngle = QgsGeometryUtilsBase::normalizedAngle( startAngle * M_PI / 180 ) * 180 / M_PI; + endAngle = QgsGeometryUtilsBase::normalizedAngle( endAngle * M_PI / 180 ) * 180 / M_PI; double angularWidth = endAngle - startAngle; double averageAngle = QgsGeometryUtils::averageAngle( endAngle * M_PI / 180, startAngle * M_PI / 180 ) * 180 / M_PI; - bool useShortestArc = angularWidth >= 0 && angularWidth <= 180.0 || angularWidth <= 180.0 && angularWidth >= -360.0; + bool useShortestArc = ( angularWidth >= 0 && angularWidth <= 180.0 ) || ( angularWidth <= 180.0 && angularWidth >= -360.0 ); if ( !useShortestArc ) averageAngle += 180; diff --git a/tests/src/python/test_qgsgeometry.py b/tests/src/python/test_qgsgeometry.py index 367161a7feb8..d643a986e086 100644 --- a/tests/src/python/test_qgsgeometry.py +++ b/tests/src/python/test_qgsgeometry.py @@ -6229,8 +6229,8 @@ def testCreateWedgeBuffer(self): endAngle = t[4] outer = t[5] inner = t[6] - o1 = QgsGeometry.createWedgeBuffer(point, azimuth, width, outer, inner, crs) - o2 = QgsGeometry.createWedgeBufferFromAngles(point, azimuth, width, outer, inner, crs) + o1 = QgsGeometry.createWedgeBuffer(point, azimuth, width, outer, inner) + o2 = QgsGeometry.createWedgeBufferFromAngles(point, azimuth, width, outer, inner) exp = t[7] result1 = o1.asWkt() result2 = o2.asWkt() From 4c806e25c241d0800d227adcaf21a5bedcd4199f Mon Sep 17 00:00:00 2001 From: Denis Rouzaud Date: Wed, 28 Aug 2024 11:33:47 +0200 Subject: [PATCH 15/26] fix warning --- src/core/geometry/qgsgeometry.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/geometry/qgsgeometry.cpp b/src/core/geometry/qgsgeometry.cpp index b600c50d0a6c..634fb2f7b0dd 100644 --- a/src/core/geometry/qgsgeometry.cpp +++ b/src/core/geometry/qgsgeometry.cpp @@ -423,7 +423,7 @@ QgsGeometry QgsGeometry::createWedgeBufferFromAngles( const QgsPoint ¢er, do endAngle = QgsGeometryUtilsBase::normalizedAngle( endAngle * M_PI / 180 ) * 180 / M_PI; double angularWidth = endAngle - startAngle; - double averageAngle = QgsGeometryUtils::averageAngle( endAngle * M_PI / 180, startAngle * M_PI / 180 ) * 180 / M_PI; + double averageAngle = QgsGeometryUtilsBase::averageAngle( endAngle * M_PI / 180, startAngle * M_PI / 180 ) * 180 / M_PI; bool useShortestArc = ( angularWidth >= 0 && angularWidth <= 180.0 ) || ( angularWidth <= 180.0 && angularWidth >= -360.0 ); if ( !useShortestArc ) From 12007cc1c2c074113e25dfa526f126719342ccba Mon Sep 17 00:00:00 2001 From: Denis Rouzaud Date: Thu, 29 Aug 2024 10:04:37 +0200 Subject: [PATCH 16/26] Update qgsgeometry.cpp --- src/core/geometry/qgsgeometry.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/geometry/qgsgeometry.cpp b/src/core/geometry/qgsgeometry.cpp index 634fb2f7b0dd..9153b518ba49 100644 --- a/src/core/geometry/qgsgeometry.cpp +++ b/src/core/geometry/qgsgeometry.cpp @@ -425,7 +425,7 @@ QgsGeometry QgsGeometry::createWedgeBufferFromAngles( const QgsPoint ¢er, do double angularWidth = endAngle - startAngle; double averageAngle = QgsGeometryUtilsBase::averageAngle( endAngle * M_PI / 180, startAngle * M_PI / 180 ) * 180 / M_PI; - bool useShortestArc = ( angularWidth >= 0 && angularWidth <= 180.0 ) || ( angularWidth <= 180.0 && angularWidth >= -360.0 ); + bool useShortestArc = ( angularWidth >= 0 && angularWidth <= 180.0 ) || ( angularWidth <= -180.0 && angularWidth >= -360.0 ); if ( !useShortestArc ) averageAngle += 180; From d92ea8f0225f3c9e9cbe5efc2a45be26f1411927 Mon Sep 17 00:00:00 2001 From: Denis Rouzaud Date: Thu, 29 Aug 2024 10:36:18 +0200 Subject: [PATCH 17/26] Update src/core/geometry/qgsgeometry.cpp MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Loïc Bartoletti --- src/core/geometry/qgsgeometry.cpp | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/src/core/geometry/qgsgeometry.cpp b/src/core/geometry/qgsgeometry.cpp index 9153b518ba49..51205b66ebec 100644 --- a/src/core/geometry/qgsgeometry.cpp +++ b/src/core/geometry/qgsgeometry.cpp @@ -419,15 +419,21 @@ QgsGeometry QgsGeometry::createWedgeBufferFromAngles( const QgsPoint ¢er, do { std::unique_ptr< QgsCompoundCurve > wedge = std::make_unique< QgsCompoundCurve >(); - startAngle = QgsGeometryUtilsBase::normalizedAngle( startAngle * M_PI / 180 ) * 180 / M_PI; - endAngle = QgsGeometryUtilsBase::normalizedAngle( endAngle * M_PI / 180 ) * 180 / M_PI; + const double HALF_CIRCLE_DEGREES = 180.0; + const double FULL_CIRCLE_DEGREES = 360.0; + // maybe we have/need a method for these two: + const double DEG_TO_RAD = M_PI / HALF_CIRCLE_DEGREES; + const double RAD_TO_DEG = HALF_CIRCLE_DEGREES / M_PI; - double angularWidth = endAngle - startAngle; - double averageAngle = QgsGeometryUtilsBase::averageAngle( endAngle * M_PI / 180, startAngle * M_PI / 180 ) * 180 / M_PI; + startAngle = QgsGeometryUtilsBase::normalizedAngle(startAngle * DEG_TO_RAD) * RAD_TO_DEG; + endAngle = QgsGeometryUtilsBase::normalizedAngle(endAngle * DEG_TO_RAD) * RAD_TO_DEG; - bool useShortestArc = ( angularWidth >= 0 && angularWidth <= 180.0 ) || ( angularWidth <= -180.0 && angularWidth >= -360.0 ); - if ( !useShortestArc ) - averageAngle += 180; + const double angularWidth = endAngle - startAngle; + const bool useShortestArc = (angularWidth >= 0 && angularWidth <= HALF_CIRCLE_DEGREES) || + (angularWidth <= -HALF_CIRCLE_DEGREES && angularWidth >= -FULL_CIRCLE_DEGREES); + + const double averageAngle = QgsGeometryUtilsBase::averageAngle(endAngle * DEG_TO_RAD, startAngle * DEG_TO_RAD) * RAD_TO_DEG + + (useShortestArc ? 0 : HALF_CIRCLE_DEGREES); if ( std::abs( angularWidth ) >= 360.0 ) { From 1c34e74e27fd212cde69f2cb1153f27120214a63 Mon Sep 17 00:00:00 2001 From: Denis Rouzaud Date: Thu, 29 Aug 2024 10:37:23 +0200 Subject: [PATCH 18/26] laxout --- python/PyQt6/core/auto_generated/geometry/qgsgeometry.sip.in | 2 +- python/core/auto_generated/geometry/qgsgeometry.sip.in | 2 +- src/core/geometry/qgsgeometry.h | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/python/PyQt6/core/auto_generated/geometry/qgsgeometry.sip.in b/python/PyQt6/core/auto_generated/geometry/qgsgeometry.sip.in index d7c72159e280..c38fcaf188a2 100644 --- a/python/PyQt6/core/auto_generated/geometry/qgsgeometry.sip.in +++ b/python/PyQt6/core/auto_generated/geometry/qgsgeometry.sip.in @@ -291,7 +291,7 @@ need to be segmentized to convert to a standard Polygon geometry. %End static QgsGeometry createWedgeBufferFromAngles( const QgsPoint ¢er, double startAngle, double endAngle, - double outerRadius, double innerRadius = 0 ); + double outerRadius, double innerRadius = 0 ); %Docstring Creates a wedge shaped buffer from a ``center`` point. diff --git a/python/core/auto_generated/geometry/qgsgeometry.sip.in b/python/core/auto_generated/geometry/qgsgeometry.sip.in index d7c72159e280..c38fcaf188a2 100644 --- a/python/core/auto_generated/geometry/qgsgeometry.sip.in +++ b/python/core/auto_generated/geometry/qgsgeometry.sip.in @@ -291,7 +291,7 @@ need to be segmentized to convert to a standard Polygon geometry. %End static QgsGeometry createWedgeBufferFromAngles( const QgsPoint ¢er, double startAngle, double endAngle, - double outerRadius, double innerRadius = 0 ); + double outerRadius, double innerRadius = 0 ); %Docstring Creates a wedge shaped buffer from a ``center`` point. diff --git a/src/core/geometry/qgsgeometry.h b/src/core/geometry/qgsgeometry.h index 3ec8e40cd09a..3448a26162ba 100644 --- a/src/core/geometry/qgsgeometry.h +++ b/src/core/geometry/qgsgeometry.h @@ -359,7 +359,7 @@ class CORE_EXPORT QgsGeometry * \since QGIS 3.40 */ static QgsGeometry createWedgeBufferFromAngles( const QgsPoint ¢er, double startAngle, double endAngle, - double outerRadius, double innerRadius = 0 ); + double outerRadius, double innerRadius = 0 ); /** * Set the geometry, feeding in the buffer containing OGC Well-Known Binary and the buffer's length. From 81104b0dae73a48fc842808ee8bcccdd15e2115f Mon Sep 17 00:00:00 2001 From: Denis Rouzaud Date: Thu, 29 Aug 2024 14:40:58 +0200 Subject: [PATCH 19/26] fix --- src/core/geometry/qgsgeometry.cpp | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/src/core/geometry/qgsgeometry.cpp b/src/core/geometry/qgsgeometry.cpp index 51205b66ebec..22d9c2b13f14 100644 --- a/src/core/geometry/qgsgeometry.cpp +++ b/src/core/geometry/qgsgeometry.cpp @@ -425,15 +425,14 @@ QgsGeometry QgsGeometry::createWedgeBufferFromAngles( const QgsPoint ¢er, do const double DEG_TO_RAD = M_PI / HALF_CIRCLE_DEGREES; const double RAD_TO_DEG = HALF_CIRCLE_DEGREES / M_PI; - startAngle = QgsGeometryUtilsBase::normalizedAngle(startAngle * DEG_TO_RAD) * RAD_TO_DEG; - endAngle = QgsGeometryUtilsBase::normalizedAngle(endAngle * DEG_TO_RAD) * RAD_TO_DEG; + startAngle = QgsGeometryUtilsBase::normalizedAngle( startAngle * DEG_TO_RAD ) * RAD_TO_DEG; + endAngle = QgsGeometryUtilsBase::normalizedAngle( endAngle * DEG_TO_RAD ) * RAD_TO_DEG; - const double angularWidth = endAngle - startAngle; - const bool useShortestArc = (angularWidth >= 0 && angularWidth <= HALF_CIRCLE_DEGREES) || - (angularWidth <= -HALF_CIRCLE_DEGREES && angularWidth >= -FULL_CIRCLE_DEGREES); + const double angularWidth = QgsGeometryUtilsBase::normalizedAngle( endAngle - startAngle * DEG_TO_RAD ) * RAD_TO_DEG; + const bool useShortestArc = angularWidth <= HALF_CIRCLE_DEGREES; - const double averageAngle = QgsGeometryUtilsBase::averageAngle(endAngle * DEG_TO_RAD, startAngle * DEG_TO_RAD) * RAD_TO_DEG + - (useShortestArc ? 0 : HALF_CIRCLE_DEGREES); + const double averageAngle = QgsGeometryUtilsBase::averageAngle( endAngle * DEG_TO_RAD, startAngle * DEG_TO_RAD ) * RAD_TO_DEG + + ( useShortestArc ? 0 : HALF_CIRCLE_DEGREES ); if ( std::abs( angularWidth ) >= 360.0 ) { From 1c897081e5d6b2bbaa9728a6884616d931226402 Mon Sep 17 00:00:00 2001 From: Denis Rouzaud Date: Thu, 29 Aug 2024 16:00:15 +0200 Subject: [PATCH 20/26] Update qgsgeometry.cpp --- src/core/geometry/qgsgeometry.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/core/geometry/qgsgeometry.cpp b/src/core/geometry/qgsgeometry.cpp index 22d9c2b13f14..7007e87a8843 100644 --- a/src/core/geometry/qgsgeometry.cpp +++ b/src/core/geometry/qgsgeometry.cpp @@ -420,8 +420,6 @@ QgsGeometry QgsGeometry::createWedgeBufferFromAngles( const QgsPoint ¢er, do std::unique_ptr< QgsCompoundCurve > wedge = std::make_unique< QgsCompoundCurve >(); const double HALF_CIRCLE_DEGREES = 180.0; - const double FULL_CIRCLE_DEGREES = 360.0; - // maybe we have/need a method for these two: const double DEG_TO_RAD = M_PI / HALF_CIRCLE_DEGREES; const double RAD_TO_DEG = HALF_CIRCLE_DEGREES / M_PI; From 0108f9bc721de5898acfa26e78cedf7c552a4b45 Mon Sep 17 00:00:00 2001 From: Denis Rouzaud Date: Fri, 30 Aug 2024 07:51:44 +0200 Subject: [PATCH 21/26] revert to use QgsCircularString::fromTwoPointsAndCenter --- src/core/geometry/qgsgeometry.cpp | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/src/core/geometry/qgsgeometry.cpp b/src/core/geometry/qgsgeometry.cpp index 7007e87a8843..fa97af10a580 100644 --- a/src/core/geometry/qgsgeometry.cpp +++ b/src/core/geometry/qgsgeometry.cpp @@ -429,9 +429,6 @@ QgsGeometry QgsGeometry::createWedgeBufferFromAngles( const QgsPoint ¢er, do const double angularWidth = QgsGeometryUtilsBase::normalizedAngle( endAngle - startAngle * DEG_TO_RAD ) * RAD_TO_DEG; const bool useShortestArc = angularWidth <= HALF_CIRCLE_DEGREES; - const double averageAngle = QgsGeometryUtilsBase::averageAngle( endAngle * DEG_TO_RAD, startAngle * DEG_TO_RAD ) * RAD_TO_DEG + - ( useShortestArc ? 0 : HALF_CIRCLE_DEGREES ); - if ( std::abs( angularWidth ) >= 360.0 ) { std::unique_ptr< QgsCompoundCurve > outerCc = std::make_unique< QgsCompoundCurve >(); @@ -456,23 +453,20 @@ QgsGeometry QgsGeometry::createWedgeBufferFromAngles( const QgsPoint ¢er, do } const QgsPoint outerP1 = center.project( outerRadius, startAngle ); - const QgsPoint outerP2 = center.project( outerRadius, averageAngle ); const QgsPoint outerP3 = center.project( outerRadius, endAngle ); - wedge->addCurve( new QgsCircularString( outerP1, outerP2, outerP3 ) ); + wedge->addCurve( new QgsCircularString( QgsCircularString::fromTwoPointsAndCenter( outerP1, outerP2, center, useShortestArc ) ) ); if ( !qgsDoubleNear( innerRadius, 0.0 ) && innerRadius > 0 ) { const QgsPoint innerP1 = center.project( innerRadius, startAngle ); - const QgsPoint innerP2 = center.project( innerRadius, averageAngle ); - const QgsPoint innerP3 = center.project( innerRadius, endAngle ); - wedge->addCurve( new QgsLineString( outerP3, innerP3 ) ); - wedge->addCurve( new QgsCircularString( innerP3, innerP2, innerP1 ) ); - wedge->addCurve( new QgsLineString( innerP1, outerP1 ) ); + const QgsPoint innerP2 = center.project( innerRadius, endAngle ); + wedge->addCurve( new QgsLineString( outerP2, innerP2 ) ); + wedge->addCurve( new QgsCircularString( QgsCircularString::fromTwoPointsAndCenter( innerP2, innerP1, center, useShortestArc ) ) ); } else { - wedge->addCurve( new QgsLineString( outerP3, center ) ); + wedge->addCurve( new QgsLineString( outerP2, center ) ); wedge->addCurve( new QgsLineString( center, outerP1 ) ); } From 5083df0fc4b38daf42801d1b699dcc0178b90111 Mon Sep 17 00:00:00 2001 From: Denis Rouzaud Date: Fri, 30 Aug 2024 07:52:41 +0200 Subject: [PATCH 22/26] next --- src/core/geometry/qgsgeometry.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/geometry/qgsgeometry.cpp b/src/core/geometry/qgsgeometry.cpp index fa97af10a580..dca3631790e3 100644 --- a/src/core/geometry/qgsgeometry.cpp +++ b/src/core/geometry/qgsgeometry.cpp @@ -453,7 +453,7 @@ QgsGeometry QgsGeometry::createWedgeBufferFromAngles( const QgsPoint ¢er, do } const QgsPoint outerP1 = center.project( outerRadius, startAngle ); - const QgsPoint outerP3 = center.project( outerRadius, endAngle ); + const QgsPoint outerP2 = center.project( outerRadius, endAngle ); wedge->addCurve( new QgsCircularString( QgsCircularString::fromTwoPointsAndCenter( outerP1, outerP2, center, useShortestArc ) ) ); From 5a41c899329dadd3851418b1b23f338c61d183f5 Mon Sep 17 00:00:00 2001 From: Denis Rouzaud Date: Fri, 30 Aug 2024 07:55:06 +0200 Subject: [PATCH 23/26] simplify code --- src/core/geometry/qgsgeometry.cpp | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/core/geometry/qgsgeometry.cpp b/src/core/geometry/qgsgeometry.cpp index dca3631790e3..e339a80a03fa 100644 --- a/src/core/geometry/qgsgeometry.cpp +++ b/src/core/geometry/qgsgeometry.cpp @@ -419,15 +419,11 @@ QgsGeometry QgsGeometry::createWedgeBufferFromAngles( const QgsPoint ¢er, do { std::unique_ptr< QgsCompoundCurve > wedge = std::make_unique< QgsCompoundCurve >(); - const double HALF_CIRCLE_DEGREES = 180.0; const double DEG_TO_RAD = M_PI / HALF_CIRCLE_DEGREES; const double RAD_TO_DEG = HALF_CIRCLE_DEGREES / M_PI; - startAngle = QgsGeometryUtilsBase::normalizedAngle( startAngle * DEG_TO_RAD ) * RAD_TO_DEG; - endAngle = QgsGeometryUtilsBase::normalizedAngle( endAngle * DEG_TO_RAD ) * RAD_TO_DEG; - - const double angularWidth = QgsGeometryUtilsBase::normalizedAngle( endAngle - startAngle * DEG_TO_RAD ) * RAD_TO_DEG; - const bool useShortestArc = angularWidth <= HALF_CIRCLE_DEGREES; + const double angularWidth = endAngle - startAngle; + const bool useShortestArc = QgsGeometryUtilsBase::normalizedAngle( angularWidth * DEG_TO_RAD ) * RAD_TO_DEG <= 180.0; if ( std::abs( angularWidth ) >= 360.0 ) { From 193d97264b0b8ac748329585bb15b1d22a8d3aed Mon Sep 17 00:00:00 2001 From: Denis Rouzaud Date: Fri, 30 Aug 2024 07:56:01 +0200 Subject: [PATCH 24/26] missing bit --- src/core/geometry/qgsgeometry.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/core/geometry/qgsgeometry.cpp b/src/core/geometry/qgsgeometry.cpp index e339a80a03fa..0d108753bc26 100644 --- a/src/core/geometry/qgsgeometry.cpp +++ b/src/core/geometry/qgsgeometry.cpp @@ -459,6 +459,7 @@ QgsGeometry QgsGeometry::createWedgeBufferFromAngles( const QgsPoint ¢er, do const QgsPoint innerP2 = center.project( innerRadius, endAngle ); wedge->addCurve( new QgsLineString( outerP2, innerP2 ) ); wedge->addCurve( new QgsCircularString( QgsCircularString::fromTwoPointsAndCenter( innerP2, innerP1, center, useShortestArc ) ) ); + wedge->addCurve( new QgsLineString( innerP1, outerP1 ) ); } else { From c0baf46d8aa1620269eb8fca22613aa2e1f00c7e Mon Sep 17 00:00:00 2001 From: Denis Rouzaud Date: Fri, 30 Aug 2024 08:15:44 +0200 Subject: [PATCH 25/26] fix --- src/core/geometry/qgsgeometry.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/core/geometry/qgsgeometry.cpp b/src/core/geometry/qgsgeometry.cpp index 0d108753bc26..865bb7e6be5f 100644 --- a/src/core/geometry/qgsgeometry.cpp +++ b/src/core/geometry/qgsgeometry.cpp @@ -419,8 +419,8 @@ QgsGeometry QgsGeometry::createWedgeBufferFromAngles( const QgsPoint ¢er, do { std::unique_ptr< QgsCompoundCurve > wedge = std::make_unique< QgsCompoundCurve >(); - const double DEG_TO_RAD = M_PI / HALF_CIRCLE_DEGREES; - const double RAD_TO_DEG = HALF_CIRCLE_DEGREES / M_PI; + const double DEG_TO_RAD = M_PI / 180.0; + const double RAD_TO_DEG = 180.0 / M_PI; const double angularWidth = endAngle - startAngle; const bool useShortestArc = QgsGeometryUtilsBase::normalizedAngle( angularWidth * DEG_TO_RAD ) * RAD_TO_DEG <= 180.0; From f435996ffd7bb2b6358395d6300dd6de66ead501 Mon Sep 17 00:00:00 2001 From: Denis Rouzaud Date: Fri, 30 Aug 2024 11:45:37 +0200 Subject: [PATCH 26/26] ouch --- tests/src/python/test_qgsgeometry.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/src/python/test_qgsgeometry.py b/tests/src/python/test_qgsgeometry.py index d643a986e086..6bb93f3ebb4b 100644 --- a/tests/src/python/test_qgsgeometry.py +++ b/tests/src/python/test_qgsgeometry.py @@ -6230,7 +6230,7 @@ def testCreateWedgeBuffer(self): outer = t[5] inner = t[6] o1 = QgsGeometry.createWedgeBuffer(point, azimuth, width, outer, inner) - o2 = QgsGeometry.createWedgeBufferFromAngles(point, azimuth, width, outer, inner) + o2 = QgsGeometry.createWedgeBufferFromAngles(point, startAngle, endAngle, outer, inner) exp = t[7] result1 = o1.asWkt() result2 = o2.asWkt()