Skip to content
Permalink
Browse files

Fix identify tool not finding points when using a single point click

and map crs != layer crs
  • Loading branch information
nyalldawson authored and wonder-sk committed Jan 4, 2021
1 parent c69b804 commit 30084f61a8bd5f9220573fc711728ec971959b26
@@ -56,10 +56,10 @@ Ctor

~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
Returns the list of points of the point cloud according to a zoom level
defined by ``maxErrorInMapCoords``, an extent ``geometry`` in the 2D plane
Returns the list of points of the point cloud according to a zoom level
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
the number of points returned to ``pointsLimit`` points

@@ -318,7 +318,7 @@ struct MapIndexedPointCloudNode
};

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

QgsRectangle rootNodeExtentMapCoords = index->nodeMapExtent( root );
const double rootErrorInMapCoordinates = rootNodeExtentMapCoords.width() / index->span();
QgsRectangle rootNodeExtent = index->nodeMapExtent( root );
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();
QgsPointCloudRequest request;
@@ -75,8 +75,8 @@ class CORE_EXPORT QgsPointCloudDataProvider: public QgsDataProvider
~QgsPointCloudDataProvider() override;

/**
* 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
* Returns the list of points of the point cloud according to a zoom level
* 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
* the number of points returned to \a pointsLimit points
*
@@ -85,7 +85,7 @@ class CORE_EXPORT QgsPointCloudDataProvider: public QgsDataProvider
* \note this function does not handle elevation properties and you need to
* 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.
@@ -204,17 +204,20 @@ QVector<QVariantMap> QgsPointCloudRenderer::identify( QgsPointCloudLayer *layer,

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

QgsRectangle rootNodeExtentMapCoords = index->nodeMapExtent( root );
const QgsRectangle rootNodeExtentLayerCoords = index->nodeMapExtent( root );
QgsRectangle rootNodeExtentMapCoords;
try
{
rootNodeExtentMapCoords = renderContext.coordinateTransform().transformBoundingBox( index->nodeMapExtent( root ) );
rootNodeExtentMapCoords = renderContext.coordinateTransform().transformBoundingBox( rootNodeExtentLayerCoords );
}
catch ( QgsCsException & )
{
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();
if ( ( rootErrorInMapCoordinates < 0.0 ) || ( mapUnitsPerPixel < 0.0 ) || ( maxErrorPixels < 0.0 ) )
@@ -223,7 +226,8 @@ QVector<QVariantMap> QgsPointCloudRenderer::identify( QgsPointCloudLayer *layer,
return selectedPoints;
}

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

QgsGeometry selectionGeometry = geometry;
if ( geometry.type() == QgsWkbTypes::PointGeometry )
@@ -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() );

return selectedPoints;
}


@@ -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
* 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
@@ -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 )
{
Q_UNUSED( identifyContext )
QgsCoordinateTransform ct( mCanvas->mapSettings().destinationCrs(), layer->crs(), mCanvas->mapSettings().transformContext() );
QgsPointCloudRenderer *renderer = layer->renderer();

QgsGeometry transformedGeometry = geometry;

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

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;
const QgsPointCloudLayerElevationProperties *elevationProps = qobject_cast< const QgsPointCloudLayerElevationProperties *>( layer->elevationProperties() );
for ( const QVariantMap &pt : points )

0 comments on commit 30084f6

Please sign in to comment.
You can’t perform that action at this time.