Skip to content

Commit

Permalink
Fix identify tool not finding points when using a single point click
Browse files Browse the repository at this point in the history
and map crs != layer crs
  • Loading branch information
nyalldawson authored and wonder-sk committed Jan 4, 2021
1 parent c69b804 commit 30084f6
Show file tree
Hide file tree
Showing 6 changed files with 36 additions and 34 deletions.
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -56,10 +56,10 @@ Ctor


~QgsPointCloudDataProvider(); ~QgsPointCloudDataProvider();


QVector<QVariantMap> identify( double maxErrorInMapCoords, const QgsGeometry &extentGeometry, const QgsDoubleRange &extentZRange = QgsDoubleRange(), int pointsLimit = 1000 ); QVector<QVariantMap> identify( double maxError, const QgsGeometry &extentGeometry, const QgsDoubleRange &extentZRange = QgsDoubleRange(), int pointsLimit = 1000 );
%Docstring %Docstring
Returns the list of points of the point cloud according to a zoom level Returns the list of points of the point cloud according to a zoom level
defined by ``maxErrorInMapCoords``, an extent ``geometry`` in the 2D plane defined by ``maxError`` (in layer coordinates), an extent ``geometry`` in the 2D plane
and a range ``extentZRange`` for z values. The function will try to limit and a range ``extentZRange`` for z values. The function will try to limit
the number of points returned to ``pointsLimit`` points the number of points returned to ``pointsLimit`` points


Expand Down
8 changes: 4 additions & 4 deletions src/core/pointcloud/qgspointclouddataprovider.cpp
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -318,7 +318,7 @@ struct MapIndexedPointCloudNode
}; };


QVector<QVariantMap> QgsPointCloudDataProvider::identify( QVector<QVariantMap> QgsPointCloudDataProvider::identify(
double maxErrorInMapCoords, double maxError,
const QgsGeometry &extentGeometry, const QgsGeometry &extentGeometry,
const QgsDoubleRange &extentZRange, int pointsLimit ) const QgsDoubleRange &extentZRange, int pointsLimit )
{ {
Expand All @@ -327,10 +327,10 @@ QVector<QVariantMap> QgsPointCloudDataProvider::identify(
QgsPointCloudIndex *index = this->index(); QgsPointCloudIndex *index = this->index();
const IndexedPointCloudNode root = index->root(); const IndexedPointCloudNode root = index->root();


QgsRectangle rootNodeExtentMapCoords = index->nodeMapExtent( root ); QgsRectangle rootNodeExtent = index->nodeMapExtent( root );
const double rootErrorInMapCoordinates = rootNodeExtentMapCoords.width() / index->span(); const double rootError = rootNodeExtent.width() / index->span();


QVector<IndexedPointCloudNode> nodes = traverseTree( index, root, maxErrorInMapCoords, rootErrorInMapCoordinates, extentGeometry, extentZRange ); QVector<IndexedPointCloudNode> nodes = traverseTree( index, root, maxError, rootError, extentGeometry, extentZRange );


QgsPointCloudAttributeCollection attributeCollection = index->attributes(); QgsPointCloudAttributeCollection attributeCollection = index->attributes();
QgsPointCloudRequest request; QgsPointCloudRequest request;
Expand Down
6 changes: 3 additions & 3 deletions src/core/pointcloud/qgspointclouddataprovider.h
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -75,8 +75,8 @@ class CORE_EXPORT QgsPointCloudDataProvider: public QgsDataProvider
~QgsPointCloudDataProvider() override; ~QgsPointCloudDataProvider() override;


/** /**
* Returns the list of points of the point cloud according to a zoom level * Returns the list of points of the point cloud according to a zoom level
* defined by \a maxErrorInMapCoords, an extent \a geometry in the 2D plane * defined by \a maxError (in layer coordinates), an extent \a geometry in the 2D plane
* and a range \a extentZRange for z values. The function will try to limit * and a range \a extentZRange for z values. The function will try to limit
* the number of points returned to \a pointsLimit points * the number of points returned to \a pointsLimit points
* *
Expand All @@ -85,7 +85,7 @@ class CORE_EXPORT QgsPointCloudDataProvider: public QgsDataProvider
* \note this function does not handle elevation properties and you need to * \note this function does not handle elevation properties and you need to
* change elevation coordinates yourself after returning from the function * change elevation coordinates yourself after returning from the function
*/ */
QVector<QVariantMap> identify( double maxErrorInMapCoords, const QgsGeometry &extentGeometry, const QgsDoubleRange &extentZRange = QgsDoubleRange(), int pointsLimit = 1000 ); QVector<QVariantMap> identify( double maxError, const QgsGeometry &extentGeometry, const QgsDoubleRange &extentZRange = QgsDoubleRange(), int pointsLimit = 1000 );


/** /**
* Returns flags containing the supported capabilities for the data provider. * Returns flags containing the supported capabilities for the data provider.
Expand Down
27 changes: 20 additions & 7 deletions src/core/pointcloud/qgspointcloudrenderer.cpp
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -204,17 +204,20 @@ QVector<QVariantMap> QgsPointCloudRenderer::identify( QgsPointCloudLayer *layer,


const double maxErrorPixels = renderContext.convertToPainterUnits( maximumScreenError(), maximumScreenErrorUnit() );// in pixels const double maxErrorPixels = renderContext.convertToPainterUnits( maximumScreenError(), maximumScreenErrorUnit() );// in pixels


QgsRectangle rootNodeExtentMapCoords = index->nodeMapExtent( root ); const QgsRectangle rootNodeExtentLayerCoords = index->nodeMapExtent( root );
QgsRectangle rootNodeExtentMapCoords;
try try
{ {
rootNodeExtentMapCoords = renderContext.coordinateTransform().transformBoundingBox( index->nodeMapExtent( root ) ); rootNodeExtentMapCoords = renderContext.coordinateTransform().transformBoundingBox( rootNodeExtentLayerCoords );
} }
catch ( QgsCsException & ) catch ( QgsCsException & )
{ {
QgsDebugMsg( QStringLiteral( "Could not transform node extent to map CRS" ) ); QgsDebugMsg( QStringLiteral( "Could not transform node extent to map CRS" ) );
rootNodeExtentMapCoords = rootNodeExtentLayerCoords;
} }


const double rootErrorInMapCoordinates = rootNodeExtentMapCoords.width() / index->span(); // in map coords const double rootErrorInMapCoordinates = rootNodeExtentMapCoords.width() / index->span();
const double rootErrorInLayerCoordinates = rootNodeExtentLayerCoords.width() / index->span();


double mapUnitsPerPixel = renderContext.mapToPixel().mapUnitsPerPixel(); double mapUnitsPerPixel = renderContext.mapToPixel().mapUnitsPerPixel();
if ( ( rootErrorInMapCoordinates < 0.0 ) || ( mapUnitsPerPixel < 0.0 ) || ( maxErrorPixels < 0.0 ) ) if ( ( rootErrorInMapCoordinates < 0.0 ) || ( mapUnitsPerPixel < 0.0 ) || ( maxErrorPixels < 0.0 ) )
Expand All @@ -223,7 +226,8 @@ QVector<QVariantMap> QgsPointCloudRenderer::identify( QgsPointCloudLayer *layer,
return selectedPoints; return selectedPoints;
} }


double maxErrorInMapCoordinates = maxErrorPixels * mapUnitsPerPixel; const double maxErrorInMapCoordinates = maxErrorPixels * mapUnitsPerPixel;
const double maxErrorInLayerCoordinates = maxErrorInMapCoordinates * rootErrorInLayerCoordinates / rootErrorInMapCoordinates;


QgsGeometry selectionGeometry = geometry; QgsGeometry selectionGeometry = geometry;
if ( geometry.type() == QgsWkbTypes::PointGeometry ) if ( geometry.type() == QgsWkbTypes::PointGeometry )
Expand Down Expand Up @@ -260,11 +264,20 @@ QVector<QVariantMap> QgsPointCloudRenderer::identify( QgsPointCloudLayer *layer,
} }
} }


selectedPoints = layer->dataProvider()->identify( maxErrorInMapCoordinates, selectionGeometry, renderContext.zRange() ); // selection geometry must be in layer CRS for QgsPointCloudDataProvider::identify
try
{
selectionGeometry.transform( renderContext.coordinateTransform(), QgsCoordinateTransform::ReverseTransform );
}
catch ( QgsCsException & )
{
QgsDebugMsg( QStringLiteral( "Could not transform geometry to layer CRS" ) );
return selectedPoints;
}

selectedPoints = layer->dataProvider()->identify( maxErrorInLayerCoordinates, selectionGeometry, renderContext.zRange() );


selectedPoints.erase( std::remove_if( selectedPoints.begin(), selectedPoints.end(), [this]( const QMap<QString, QVariant> &point ) { return !this->willRenderPoint( point ); } ), selectedPoints.end() ); selectedPoints.erase( std::remove_if( selectedPoints.begin(), selectedPoints.end(), [this]( const QMap<QString, QVariant> &point ) { return !this->willRenderPoint( point ); } ), selectedPoints.end() );


return selectedPoints; return selectedPoints;
} }


4 changes: 3 additions & 1 deletion src/core/pointcloud/qgspointcloudrenderer.h
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -284,8 +284,10 @@ class CORE_EXPORT QgsPointCloudRenderer
/** /**
* Returns the list of visible points of the point cloud layer \a layer and an extent defined by * Returns the list of visible points of the point cloud layer \a layer and an extent defined by
* a geometry in the 2D plane \a geometry. * a geometry in the 2D plane \a geometry.
*
* \warning The \a geometry value must be specified in the render context's destination CRS, not the layer's native CRS!
*/ */
QVector<QVariantMap> identify( QgsPointCloudLayer *layer, const QgsRenderContext &context, const QgsGeometry &geometry ) SIP_SKIP; QVector<QVariantMap> identify( QgsPointCloudLayer *layer, const QgsRenderContext &context, const QgsGeometry &geometry ) SIP_SKIP;


/** /**
* Checks whether the point holding \a pointAttributes attributes will be rendered * Checks whether the point holding \a pointAttributes attributes will be rendered
Expand Down
19 changes: 3 additions & 16 deletions src/gui/qgsmaptoolidentify.cpp
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -508,25 +508,12 @@ bool QgsMapToolIdentify::identifyVectorTileLayer( QList<QgsMapToolIdentify::Iden
bool QgsMapToolIdentify::identifyPointCloudLayer( QList<QgsMapToolIdentify::IdentifyResult> *results, QgsPointCloudLayer *layer, const QgsGeometry &geometry, const QgsIdentifyContext &identifyContext ) bool QgsMapToolIdentify::identifyPointCloudLayer( QList<QgsMapToolIdentify::IdentifyResult> *results, QgsPointCloudLayer *layer, const QgsGeometry &geometry, const QgsIdentifyContext &identifyContext )
{ {
Q_UNUSED( identifyContext ) Q_UNUSED( identifyContext )
QgsCoordinateTransform ct( mCanvas->mapSettings().destinationCrs(), layer->crs(), mCanvas->mapSettings().transformContext() );
QgsPointCloudRenderer *renderer = layer->renderer(); QgsPointCloudRenderer *renderer = layer->renderer();


QgsGeometry transformedGeometry = geometry;

if ( ct.isValid() )
{
try
{
transformedGeometry.transform( ct );
}
catch ( QgsCsException & )
{
return false;
}
}

QgsRenderContext context = QgsRenderContext::fromMapSettings( mCanvas->mapSettings() ); QgsRenderContext context = QgsRenderContext::fromMapSettings( mCanvas->mapSettings() );
const QVector<QVariantMap> points = renderer->identify( layer, context, transformedGeometry ); context.setCoordinateTransform( QgsCoordinateTransform( layer->crs(), mCanvas->mapSettings().destinationCrs(), mCanvas->mapSettings().transformContext() ) );

const QVector<QVariantMap> points = renderer->identify( layer, context, geometry );
int id = 0; int id = 0;
const QgsPointCloudLayerElevationProperties *elevationProps = qobject_cast< const QgsPointCloudLayerElevationProperties *>( layer->elevationProperties() ); const QgsPointCloudLayerElevationProperties *elevationProps = qobject_cast< const QgsPointCloudLayerElevationProperties *>( layer->elevationProperties() );
for ( const QVariantMap &pt : points ) for ( const QVariantMap &pt : points )
Expand Down

0 comments on commit 30084f6

Please sign in to comment.