Fix Identify tool on virtual point cloud

(fix #54729)
This commit is contained in:
David Koňařík 2024-10-14 12:20:18 +02:00 committed by Martin Dobias
parent 373a2b6310
commit 71b2591c62
5 changed files with 35 additions and 22 deletions

View File

@ -301,6 +301,7 @@ Emitted when point cloud generation state is changed
protected:
};
/************************************************************************

View File

@ -301,6 +301,7 @@ Emitted when point cloud generation state is changed
protected:
};
/************************************************************************

View File

@ -311,13 +311,36 @@ QVector<QVariantMap> QgsPointCloudDataProvider::identify(
double maxError,
const QgsGeometry &extentGeometry,
const QgsDoubleRange &extentZRange, int pointsLimit )
{
QVector<QVariantMap> acceptedPoints;
// Try sub-indexes first
for ( QgsPointCloudSubIndex &subidx : subIndexes() )
{
// Check if the sub-index is relevant and if it is loaded. We shouldn't
// need to identify points in unloaded indices.
if ( !subidx.index()
|| ( !subidx.zRange().overlaps( extentZRange ) )
|| !subidx.polygonBounds().intersects( extentGeometry ) )
continue;
acceptedPoints.append( identify( subidx.index(), maxError, extentGeometry, extentZRange, pointsLimit ) );
}
// Then look at main index
acceptedPoints.append( identify( index(), maxError, extentGeometry, extentZRange, pointsLimit ) );
return acceptedPoints;
}
QVector<QVariantMap> QgsPointCloudDataProvider::identify(
QgsPointCloudIndex *index, double maxError,
const QgsGeometry &extentGeometry,
const QgsDoubleRange &extentZRange, int pointsLimit )
{
QGIS_PROTECT_QOBJECT_THREAD_ACCESS
QVector<QVariantMap> acceptedPoints;
QgsPointCloudIndex *index = this->index();
if ( !index || !index->isValid() )
return acceptedPoints;

View File

@ -385,6 +385,9 @@ class CORE_EXPORT QgsPointCloudDataProvider: public QgsDataProvider
//! String used to define a subset of the layer
QString mSubsetString;
//! Identify in a specific index (used for sub-indexes)
QVector<QVariantMap> identify( QgsPointCloudIndex *index, double maxError, const QgsGeometry &extentGeometry, const QgsDoubleRange &extentZRange, int pointsLimit ) SIP_SKIP ;
private:
QVector<IndexedPointCloudNode> traverseTree( const QgsPointCloudIndex *pc, IndexedPointCloudNode n, double maxError, double nodeError, const QgsGeometry &extentGeometry, const QgsDoubleRange &extentZRange );

View File

@ -265,48 +265,33 @@ QVector<QVariantMap> QgsPointCloudRenderer::identify( QgsPointCloudLayer *layer,
{
QVector<QVariantMap> selectedPoints;
QgsPointCloudIndex *index = layer->dataProvider()->index();
if ( !index || !index->isValid() )
return selectedPoints;
const IndexedPointCloudNode root = index->root();
const double maxErrorPixels = renderContext.convertToPainterUnits( maximumScreenError(), maximumScreenErrorUnit() );// in pixels
const QgsRectangle rootNodeExtentLayerCoords = index->nodeMapExtent( root );
QgsRectangle rootNodeExtentMapCoords;
const QgsRectangle layerExtentLayerCoords = layer->dataProvider()->extent();
QgsRectangle layerExtentMapCoords = layerExtentLayerCoords;
if ( !renderContext.coordinateTransform().isShortCircuited() )
{
try
{
QgsCoordinateTransform extentTransform = renderContext.coordinateTransform();
extentTransform.setBallparkTransformsAreAppropriate( true );
rootNodeExtentMapCoords = extentTransform.transformBoundingBox( rootNodeExtentLayerCoords );
layerExtentMapCoords = extentTransform.transformBoundingBox( layerExtentLayerCoords );
}
catch ( QgsCsException & )
{
QgsDebugError( QStringLiteral( "Could not transform node extent to map CRS" ) );
rootNodeExtentMapCoords = rootNodeExtentLayerCoords;
}
}
else
{
rootNodeExtentMapCoords = rootNodeExtentLayerCoords;
}
const double rootErrorInMapCoordinates = rootNodeExtentMapCoords.width() / index->span();
const double rootErrorInLayerCoordinates = rootNodeExtentLayerCoords.width() / index->span();
const double mapUnitsPerPixel = renderContext.mapToPixel().mapUnitsPerPixel();
if ( ( rootErrorInMapCoordinates < 0.0 ) || ( mapUnitsPerPixel < 0.0 ) || ( maxErrorPixels < 0.0 ) )
if ( ( mapUnitsPerPixel < 0.0 ) || ( maxErrorPixels < 0.0 ) )
{
QgsDebugError( QStringLiteral( "invalid screen error" ) );
return selectedPoints;
}
const double maxErrorInMapCoordinates = maxErrorPixels * mapUnitsPerPixel;
const double maxErrorInLayerCoordinates = maxErrorInMapCoordinates * rootErrorInLayerCoordinates / rootErrorInMapCoordinates;
const double maxErrorInLayerCoordinates = maxErrorInMapCoordinates * layerExtentLayerCoords.width() / layerExtentMapCoords.width();
QgsGeometry selectionGeometry = geometry;
if ( geometry.type() == Qgis::GeometryType::Point )