From 8e2fb49718a3bd00d930e2c9ba01237fcaae04d2 Mon Sep 17 00:00:00 2001 From: Nyall Dawson Date: Tue, 8 Jun 2021 10:24:16 +1000 Subject: [PATCH] Add method to retrieve all labels from QgsLabelingResults, instead of just labels within a rect --- .../labeling/qgslabelingresults.sip.in | 7 +++++++ .../labeling/qgslabelsearchtree.sip.in | 7 +++++++ src/core/labeling/qgslabelingresults.cpp | 6 ++++++ src/core/labeling/qgslabelingresults.h | 7 +++++++ src/core/labeling/qgslabelsearchtree.cpp | 11 +++++++++++ src/core/labeling/qgslabelsearchtree.h | 7 +++++++ tests/src/core/testqgslabelingengine.cpp | 12 +++++++++++- 7 files changed, 56 insertions(+), 1 deletion(-) diff --git a/python/core/auto_generated/labeling/qgslabelingresults.sip.in b/python/core/auto_generated/labeling/qgslabelingresults.sip.in index 3d5c3884463..b694f66fe14 100644 --- a/python/core/auto_generated/labeling/qgslabelingresults.sip.in +++ b/python/core/auto_generated/labeling/qgslabelingresults.sip.in @@ -25,6 +25,13 @@ Class that stores computed placement from labeling engine. ~QgsLabelingResults(); + QList< QgsLabelPosition > allLabels() const; +%Docstring +Returns a list of all labels generated by the labeling run. + +.. versionadded:: 3.20 +%End + QList labelsAtPosition( const QgsPointXY &p ) const; %Docstring Returns the details of any labels placed at the specified point (in map coordinates). diff --git a/python/core/auto_generated/labeling/qgslabelsearchtree.sip.in b/python/core/auto_generated/labeling/qgslabelsearchtree.sip.in index 5cb72a697b7..94e1b2f7cc7 100644 --- a/python/core/auto_generated/labeling/qgslabelsearchtree.sip.in +++ b/python/core/auto_generated/labeling/qgslabelsearchtree.sip.in @@ -41,6 +41,13 @@ Removes and deletes all the entries. + QList< QgsLabelPosition > allLabels() const; +%Docstring +Returns a list of all labels generated by the labeling run. + +.. versionadded:: 3.20 +%End + diff --git a/src/core/labeling/qgslabelingresults.cpp b/src/core/labeling/qgslabelingresults.cpp index c84dda710d8..e54c9b29868 100644 --- a/src/core/labeling/qgslabelingresults.cpp +++ b/src/core/labeling/qgslabelingresults.cpp @@ -23,6 +23,12 @@ QgsLabelingResults::QgsLabelingResults() QgsLabelingResults::~QgsLabelingResults() = default; + +QList QgsLabelingResults::allLabels() const +{ + return mLabelSearchTree ? mLabelSearchTree->allLabels() : QList(); +} + QList QgsLabelingResults::labelsAtPosition( const QgsPointXY &p ) const { QList positions; diff --git a/src/core/labeling/qgslabelingresults.h b/src/core/labeling/qgslabelingresults.h index 8919648ebe3..418f9362e16 100644 --- a/src/core/labeling/qgslabelingresults.h +++ b/src/core/labeling/qgslabelingresults.h @@ -40,6 +40,13 @@ class CORE_EXPORT QgsLabelingResults //! QgsLabelingResults cannot be copied. QgsLabelingResults &operator=( const QgsLabelingResults &rh ) = delete; + /** + * Returns a list of all labels generated by the labeling run. + * + * \since QGIS 3.20 + */ + QList< QgsLabelPosition > allLabels() const; + /** * Returns the details of any labels placed at the specified point (in map coordinates). */ diff --git a/src/core/labeling/qgslabelsearchtree.cpp b/src/core/labeling/qgslabelsearchtree.cpp index a1575bfb49c..3ca4e10a78e 100644 --- a/src/core/labeling/qgslabelsearchtree.cpp +++ b/src/core/labeling/qgslabelsearchtree.cpp @@ -42,6 +42,17 @@ void QgsLabelSearchTree::label( const QgsPointXY &point, QList QgsLabelSearchTree::allLabels() const +{ + QList res; + res.reserve( mOwnedPositions.size() ); + for ( const std::unique_ptr< QgsLabelPosition > &pos : mOwnedPositions ) + { + res.append( * pos ); + } + return res; +} + void QgsLabelSearchTree::labelsInRect( const QgsRectangle &r, QList &posList ) const { QList searchResults; diff --git a/src/core/labeling/qgslabelsearchtree.h b/src/core/labeling/qgslabelsearchtree.h index e54b2452628..a1cef1a06f9 100644 --- a/src/core/labeling/qgslabelsearchtree.h +++ b/src/core/labeling/qgslabelsearchtree.h @@ -74,6 +74,13 @@ class CORE_EXPORT QgsLabelSearchTree //TODO: why does this break bindings with QList? + /** + * Returns a list of all labels generated by the labeling run. + * + * \since QGIS 3.20 + */ + QList< QgsLabelPosition > allLabels() const; + /** * Returns label position(s) in given rectangle. QgsLabelSearchTree keeps ownership, don't delete the LabelPositions * \note not available in Python bindings diff --git a/tests/src/core/testqgslabelingengine.cpp b/tests/src/core/testqgslabelingengine.cpp index d7223a1e119..f82de4d1a62 100644 --- a/tests/src/core/testqgslabelingengine.cpp +++ b/tests/src/core/testqgslabelingengine.cpp @@ -1961,7 +1961,17 @@ void TestQgsLabelingEngine::labelingResults() QVERIFY( results ); // retrieve some labels - QList labels = results->labelsAtPosition( QgsPointXY( -654732, 7003282 ) ); + QList labels = results->allLabels(); + QCOMPARE( labels.count(), 3 ); + std::sort( labels.begin(), labels.end(), []( const QgsLabelPosition & a, const QgsLabelPosition & b ) + { + return a.labelText.compare( b.labelText ); + } ); + QCOMPARE( labels.at( 0 ).labelText, QStringLiteral( "1" ) ); + QCOMPARE( labels.at( 1 ).labelText, QStringLiteral( "8888" ) ); + QCOMPARE( labels.at( 2 ).labelText, QStringLiteral( "33333" ) ); + + labels = results->labelsAtPosition( QgsPointXY( -654732, 7003282 ) ); QCOMPARE( labels.count(), 1 ); QCOMPARE( labels.at( 0 ).featureId, 1 ); QCOMPARE( labels.at( 0 ).labelText, QStringLiteral( "1" ) );