Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Ensure labeling map tools only try to affect labels from vector layers
Labels from other layer types (eg vector tiles) are unsupported,
which results in a crash.

Fixes #44486
  • Loading branch information
nyalldawson committed Oct 5, 2021
1 parent 1abf47f commit 335c01a
Showing 1 changed file with 53 additions and 0 deletions.
53 changes: 53 additions & 0 deletions src/app/labeling/qgsmaptoollabel.cpp
Expand Up @@ -68,6 +68,33 @@ bool QgsMapToolLabel::labelAtPosition( QMouseEvent *e, QgsLabelPosition &p )
return false;

QList<QgsLabelPosition> labelPosList = labelingResults->labelsAtPosition( pt );
labelPosList.erase( std::remove_if( labelPosList.begin(), labelPosList.end(), []( const QgsLabelPosition & position )
{
if ( position.layerID.isEmpty() )
return true;

if ( QgsMapLayer *layer = QgsProject::instance()->mapLayer( position.layerID ) )
{
// strip out any labels from non vector layers (e.g. those from vector tile layers). Only vector layer labels
// are supported by the map tools.
switch ( layer->type() )
{
case QgsMapLayerType::VectorLayer:
return false;

case QgsMapLayerType::RasterLayer:
case QgsMapLayerType::PluginLayer:
case QgsMapLayerType::MeshLayer:
case QgsMapLayerType::VectorTileLayer:
case QgsMapLayerType::AnnotationLayer:
case QgsMapLayerType::PointCloudLayer:
return true;
}
}

return true;
} ), labelPosList.end() );

if ( labelPosList.empty() )
return false;

Expand Down Expand Up @@ -131,6 +158,32 @@ bool QgsMapToolLabel::calloutAtPosition( QMouseEvent *e, QgsCalloutPosition &p,
const double tol = QgsTolerance::vertexSearchRadius( canvas()->mapSettings() );

QList<QgsCalloutPosition> calloutPosList = labelingResults->calloutsWithinRectangle( QgsRectangle::fromCenterAndSize( pt, tol * 2, tol * 2 ) );
calloutPosList.erase( std::remove_if( calloutPosList.begin(), calloutPosList.end(), []( const QgsCalloutPosition & position )
{
if ( position.layerID.isEmpty() )
return true;

if ( QgsMapLayer *layer = QgsProject::instance()->mapLayer( position.layerID ) )
{
// strip out any callouts from non vector layers (e.g. those from vector tile layers). Only vector layer callouts
// are supported by the map tools.
switch ( layer->type() )
{
case QgsMapLayerType::VectorLayer:
return false;

case QgsMapLayerType::RasterLayer:
case QgsMapLayerType::PluginLayer:
case QgsMapLayerType::MeshLayer:
case QgsMapLayerType::VectorTileLayer:
case QgsMapLayerType::AnnotationLayer:
case QgsMapLayerType::PointCloudLayer:
return true;
}
}

return true;
} ), calloutPosList.end() );
if ( calloutPosList.empty() )
return false;

Expand Down

0 comments on commit 335c01a

Please sign in to comment.