26using namespace Qt::StringLiterals;
29class QgsRenderedItemResultsSpatialIndex :
public RTree<const QgsRenderedItemDetails *, float, 2, float>
32 explicit QgsRenderedItemResultsSpatialIndex(
const QgsRectangle &maxBounds )
33 : mXMin( maxBounds.xMinimum() )
34 , mYMin( maxBounds.yMinimum() )
35 , mXRes( ( std::numeric_limits< float >::max() - 1 ) / ( maxBounds.xMaximum() - maxBounds.xMinimum() ) )
36 , mYRes( ( std::numeric_limits< float >::max() - 1 ) / ( maxBounds.yMaximum() - maxBounds.yMinimum() ) )
37 , mMaxBounds( maxBounds )
38 , mUseScale( !maxBounds.isNull() )
41 void insert(
const QgsRenderedItemDetails *details,
const QgsRectangle &bounds )
43 std::array< float, 4 > scaledBounds = scaleBounds( bounds );
44 const float aMin[2] { scaledBounds[0], scaledBounds[1] };
45 const float aMax[2] { scaledBounds[2], scaledBounds[3] };
46 this->Insert( aMin, aMax, details );
54 bool intersects(
const QgsRectangle &bounds,
const std::function<
bool(
const QgsRenderedItemDetails *details )> &callback )
const
56 std::array< float, 4 > scaledBounds = scaleBounds( bounds );
57 const float aMin[2] { scaledBounds[0], scaledBounds[1] };
58 const float aMax[2] { scaledBounds[2], scaledBounds[3] };
59 this->Search( aMin, aMax, callback );
68 QgsRectangle mMaxBounds;
69 bool mUseScale =
false;
71 std::array<float, 4> scaleBounds(
const QgsRectangle &bounds )
const
75 static_cast< float >( ( std::max( bounds.
xMinimum(), mMaxBounds.
xMinimum() ) - mXMin ) / mXRes ),
76 static_cast< float >( ( std::max( bounds.
yMinimum(), mMaxBounds.
yMinimum() ) - mYMin ) / mYRes ),
77 static_cast< float >( ( std::min( bounds.
xMaximum(), mMaxBounds.
xMaximum() ) - mXMin ) / mXRes ),
78 static_cast< float >( ( std::min( bounds.
yMaximum(), mMaxBounds.
yMaximum() ) - mYMin ) / mYRes )
81 return {
static_cast< float >( bounds.
xMinimum() ),
static_cast< float >( bounds.
yMinimum() ),
static_cast< float >( bounds.
xMaximum() ),
static_cast< float >( bounds.
yMaximum() ) };
87 : mExtent( extent.buffered( std::max( extent.width(), extent.height() ) * 1000 ) )
88 , mAnnotationItemsIndex( std::make_unique< QgsRenderedItemResultsSpatialIndex >( mExtent ) )
95 QList< QgsRenderedItemDetails * > res;
96 for (
const auto &it : mDetails )
98 std::transform( it.second.begin(), it.second.end(), std::back_inserter( res ), [](
const auto &detail ) { return detail.get(); } );
105 QList<const QgsRenderedAnnotationItemDetails *> res;
108 res << qgis::down_cast< const QgsRenderedAnnotationItemDetails * >( details );
123 details->setBoundingBox( transformedBounds );
127 QgsDebugError( u
"Could not transform rendered item's bounds to map CRS"_s );
131 mAnnotationItemsIndex->insert( annotationDetails, annotationDetails->boundingBox() );
134 mDetails[details->layerId()].emplace_back( std::unique_ptr< QgsRenderedItemDetails >( details ) );
140 for (
const QString &layerId : layerIds )
142 auto otherLayerIt = other->mDetails.find( layerId );
143 if ( otherLayerIt == other->mDetails.end() )
146 std::vector< std::unique_ptr< QgsRenderedItemDetails > > &source = otherLayerIt->second;
148 for ( std::unique_ptr< QgsRenderedItemDetails > &details : source )
151 mAnnotationItemsIndex->insert( annotationDetails, annotationDetails->boundingBox() );
153 mDetails[layerId].emplace_back( std::move( details ) );
156 other->mDetails.erase( otherLayerIt );
162 for (
auto layerIt = other->mDetails.begin(); layerIt != other->mDetails.end(); ++layerIt )
164 std::vector< std::unique_ptr< QgsRenderedItemDetails > > &dest = mDetails[layerIt->first];
165 dest.reserve( layerIt->second.size() );
166 for (
auto it = layerIt->second.begin(); it != layerIt->second.end(); ++it )
169 mAnnotationItemsIndex->insert( annotationDetails, annotationDetails->boundingBox() );
171 dest.emplace_back( std::move( *it ) );
174 other->mDetails.clear();
179 for (
const QString &layerId : layerIds )
181 auto it = mDetails.find( layerId );
182 if ( it != mDetails.end() )
183 mDetails.erase( it );
Custom exception class for Coordinate Reference System related exceptions.
A rectangle specified with double values.
Contains information about the context of a rendering operation.
QgsCoordinateTransform coordinateTransform() const
Returns the current coordinate transform for the context.
Contains information about a rendered annotation item.
Base class for detailed information about a rendered item.
void transferResults(QgsRenderedItemResults *other, const QStringList &layerIds)
Transfers all results from an other QgsRenderedItemResults object where the items have layer IDs matc...
QList< const QgsRenderedAnnotationItemDetails * > renderedAnnotationItemsInBounds(const QgsRectangle &bounds) const
Returns a list with details of the rendered annotation items within the specified bounds.
QgsRenderedItemResults(const QgsRectangle &extent=QgsRectangle())
Constructor for QgsRenderedItemResults.
QList< QgsRenderedItemDetails * > renderedItems() const
Returns a list of all rendered items.
~QgsRenderedItemResults()
void eraseResultsFromLayers(const QStringList &layerIds)
Erases results from layers matching those in the specified list of layers IDs.
void appendResults(const QList< QgsRenderedItemDetails * > &results, const QgsRenderContext &context)
Appends rendered item details to the results object.
#define QgsDebugError(str)