QGIS API Documentation  3.26.3-Buenos Aires (65e4edfdad)
qgsmaptoolidentify.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsmaptoolidentify.cpp - map tool for identifying features
3  ---------------------
4  begin : January 2006
5  copyright : (C) 2006 by Martin Dobias
6  email : wonder.sk at gmail dot com
7  ***************************************************************************
8  * *
9  * This program is free software; you can redistribute it and/or modify *
10  * it under the terms of the GNU General Public License as published by *
11  * the Free Software Foundation; either version 2 of the License, or *
12  * (at your option) any later version. *
13  * *
14  ***************************************************************************/
15 
16 #include "qgsapplication.h"
17 #include "qgscoordinateformatter.h"
18 #include "qgsdistancearea.h"
19 #include "qgsfeature.h"
20 #include "qgsfeatureiterator.h"
21 #include "qgsfeaturestore.h"
22 #include "qgsfields.h"
23 #include "qgsgeometry.h"
24 #include "qgsgeometryengine.h"
25 #include "qgsidentifymenu.h"
26 #include "qgslogger.h"
27 #include "qgsmapcanvas.h"
28 #include "qgsmaptoolidentify.h"
29 #include "qgsmaptopixel.h"
30 #include "qgsmessageviewer.h"
31 #include "qgsmeshlayer.h"
33 #include "qgsmaplayer.h"
34 #include "qgsrasterdataprovider.h"
35 #include "qgsrasterlayer.h"
38 #include "qgsvectordataprovider.h"
39 #include "qgsvectorlayer.h"
41 #include "qgsvectortilelayer.h"
43 #include "qgsvectortileutils.h"
44 #include "qgsproject.h"
45 #include "qgsrenderer.h"
46 #include "qgstiles.h"
47 #include "qgsgeometryutils.h"
48 #include "qgsgeometrycollection.h"
49 #include "qgscurve.h"
50 #include "qgscoordinateutils.h"
51 #include "qgsexception.h"
52 #include "qgssettings.h"
54 #include "qgspointcloudlayer.h"
55 #include "qgspointcloudrenderer.h"
58 #include "qgssymbol.h"
59 #include "qgsmultilinestring.h"
60 
61 #include <QMouseEvent>
62 #include <QCursor>
63 #include <QPixmap>
64 #include <QStatusBar>
65 #include <QVariant>
66 
68  : QgsMapTool( canvas )
69  , mIdentifyMenu( new QgsIdentifyMenu( mCanvas ) )
70  , mLastMapUnitsPerPixel( -1.0 )
71  , mCoordinatePrecision( 6 )
72 {
73  setCursor( QgsApplication::getThemeCursor( QgsApplication::Cursor::Identify ) );
74 }
75 
77 {
78  delete mIdentifyMenu;
79 }
80 
82 {
83  Q_UNUSED( e )
84 }
85 
87 {
88  Q_UNUSED( e )
89 }
90 
92 {
93  Q_UNUSED( e )
94 }
95 
96 QList<QgsMapToolIdentify::IdentifyResult> QgsMapToolIdentify::identify( int x, int y, const QList<QgsMapLayer *> &layerList, IdentifyMode mode, const QgsIdentifyContext &identifyContext )
97 {
98  return identify( x, y, mode, layerList, AllLayers, identifyContext );
99 }
100 
101 QList<QgsMapToolIdentify::IdentifyResult> QgsMapToolIdentify::identify( int x, int y, IdentifyMode mode, LayerType layerType, const QgsIdentifyContext &identifyContext )
102 {
103  return identify( x, y, mode, QList<QgsMapLayer *>(), layerType, identifyContext );
104 }
105 
106 QList<QgsMapToolIdentify::IdentifyResult> QgsMapToolIdentify::identify( int x, int y, IdentifyMode mode, const QList<QgsMapLayer *> &layerList, LayerType layerType, const QgsIdentifyContext &identifyContext )
107 {
108  return identify( QgsGeometry::fromPointXY( toMapCoordinates( QPoint( x, y ) ) ), mode, layerList, layerType, identifyContext );
109 }
110 
111 QList<QgsMapToolIdentify::IdentifyResult> QgsMapToolIdentify::identify( const QgsGeometry &geometry, IdentifyMode mode, LayerType layerType, const QgsIdentifyContext &identifyContext )
112 {
113  return identify( geometry, mode, QList<QgsMapLayer *>(), layerType, identifyContext );
114 }
115 
116 QList<QgsMapToolIdentify::IdentifyResult> QgsMapToolIdentify::identify( const QgsGeometry &geometry, IdentifyMode mode, const QList<QgsMapLayer *> &layerList, LayerType layerType, const QgsIdentifyContext &identifyContext )
117 {
118  QList<IdentifyResult> results;
119 
120  mLastGeometry = geometry;
121  mLastExtent = mCanvas->extent();
122  mLastMapUnitsPerPixel = mCanvas->mapUnitsPerPixel();
123 
124  mCoordinatePrecision = QgsCoordinateUtils::calculateCoordinatePrecision( mLastMapUnitsPerPixel, mCanvas->mapSettings().destinationCrs() );
125 
126  if ( mode == DefaultQgsSetting )
127  {
128  QgsSettings settings;
129  mode = settings.enumValue( QStringLiteral( "Map/identifyMode" ), ActiveLayer );
130  }
131 
132  if ( mode == LayerSelection )
133  {
134  QPoint canvasPt = toCanvasCoordinates( geometry.asPoint() );
135  int x = canvasPt.x(), y = canvasPt.y();
136  QList<IdentifyResult> results = identify( x, y, TopDownAll, layerList, layerType, identifyContext );
137  QPoint globalPos = mCanvas->mapToGlobal( QPoint( x + 5, y + 5 ) );
138  return mIdentifyMenu->exec( results, globalPos );
139  }
140  else if ( mode == ActiveLayer && layerList.isEmpty() )
141  {
142  QgsMapLayer *layer = mCanvas->currentLayer();
143 
144  if ( !layer )
145  {
146  emit identifyMessage( tr( "No active layer. To identify features, you must choose an active layer." ) );
147  return results;
148  }
149  if ( !layer->flags().testFlag( QgsMapLayer::Identifiable ) )
150  return results;
151 
152  QApplication::setOverrideCursor( Qt::WaitCursor );
153 
154  identifyLayer( &results, layer, mLastGeometry, mLastExtent, mLastMapUnitsPerPixel, layerType, identifyContext );
155  }
156  else
157  {
158  QApplication::setOverrideCursor( Qt::WaitCursor );
159 
160  QList< QgsMapLayer * > targetLayers;
161  if ( layerList.isEmpty() )
162  targetLayers = mCanvas->layers( true );
163  else
164  targetLayers = layerList;
165 
166  const int layerCount = targetLayers.size();
167  for ( int i = 0; i < layerCount; i++ )
168  {
169  QgsMapLayer *layer = targetLayers.value( i );
170 
171  emit identifyProgress( i, layerCount );
172  emit identifyMessage( tr( "Identifying on %1…" ).arg( layer->name() ) );
173 
174  if ( !layer->flags().testFlag( QgsMapLayer::Identifiable ) )
175  continue;
176 
177  if ( identifyLayer( &results, layer, mLastGeometry, mLastExtent, mLastMapUnitsPerPixel, layerType, identifyContext ) )
178  {
179  if ( mode == TopDownStopAtFirst )
180  break;
181  }
182  }
183 
184  emit identifyProgress( layerCount, layerCount );
185  emit identifyMessage( tr( "Identifying done." ) );
186  }
187 
188  QApplication::restoreOverrideCursor();
189 
190  return results;
191 }
192 
193 void QgsMapToolIdentify::setCanvasPropertiesOverrides( double searchRadiusMapUnits )
194 {
195  mOverrideCanvasSearchRadius = searchRadiusMapUnits;
196 }
197 
199 {
200  mOverrideCanvasSearchRadius = -1;
201 }
202 
204 {
206 }
207 
209 {
211 }
212 
213 bool QgsMapToolIdentify::identifyLayer( QList<IdentifyResult> *results, QgsMapLayer *layer, const QgsPointXY &point, const QgsRectangle &viewExtent, double mapUnitsPerPixel, QgsMapToolIdentify::LayerType layerType, const QgsIdentifyContext &identifyContext )
214 {
215  return identifyLayer( results, layer, QgsGeometry::fromPointXY( point ), viewExtent, mapUnitsPerPixel, layerType, identifyContext );
216 }
217 
218 bool QgsMapToolIdentify::identifyLayer( QList<IdentifyResult> *results, QgsMapLayer *layer, const QgsGeometry &geometry, const QgsRectangle &viewExtent, double mapUnitsPerPixel, QgsMapToolIdentify::LayerType layerType, const QgsIdentifyContext &identifyContext )
219 {
220  if ( layer->type() == QgsMapLayerType::RasterLayer && layerType.testFlag( RasterLayer ) )
221  {
222  return identifyRasterLayer( results, qobject_cast<QgsRasterLayer *>( layer ), geometry, viewExtent, mapUnitsPerPixel, identifyContext );
223  }
224  else if ( layer->type() == QgsMapLayerType::VectorLayer && layerType.testFlag( VectorLayer ) )
225  {
226  return identifyVectorLayer( results, qobject_cast<QgsVectorLayer *>( layer ), geometry, identifyContext );
227  }
228  else if ( layer->type() == QgsMapLayerType::MeshLayer && layerType.testFlag( MeshLayer ) )
229  {
230  return identifyMeshLayer( results, qobject_cast<QgsMeshLayer *>( layer ), geometry, identifyContext );
231  }
232  else if ( layer->type() == QgsMapLayerType::VectorTileLayer && layerType.testFlag( VectorTileLayer ) )
233  {
234  return identifyVectorTileLayer( results, qobject_cast<QgsVectorTileLayer *>( layer ), geometry, identifyContext );
235  }
236  else if ( layer->type() == QgsMapLayerType::PointCloudLayer && layerType.testFlag( PointCloudLayer ) )
237  {
238  return identifyPointCloudLayer( results, qobject_cast<QgsPointCloudLayer *>( layer ), geometry, identifyContext );
239  }
240  else
241  {
242  return false;
243  }
244 }
245 
246 bool QgsMapToolIdentify::identifyVectorLayer( QList<QgsMapToolIdentify::IdentifyResult> *results, QgsVectorLayer *layer, const QgsPointXY &point, const QgsIdentifyContext &identifyContext )
247 {
248  return identifyVectorLayer( results, layer, QgsGeometry::fromPointXY( point ), identifyContext );
249 }
250 
251 bool QgsMapToolIdentify::identifyMeshLayer( QList<QgsMapToolIdentify::IdentifyResult> *results, QgsMeshLayer *layer, const QgsGeometry &geometry, const QgsIdentifyContext &identifyContext )
252 {
253  const QgsPointXY point = geometry.asPoint(); // mesh layers currently only support identification by point
254  return identifyMeshLayer( results, layer, point, identifyContext );
255 }
256 
257 bool QgsMapToolIdentify::identifyMeshLayer( QList<QgsMapToolIdentify::IdentifyResult> *results, QgsMeshLayer *layer, const QgsPointXY &point, const QgsIdentifyContext &identifyContext )
258 {
259  QgsDebugMsgLevel( "point = " + point.toString(), 4 );
260  if ( !layer )
261  return false;
262 
263  double searchRadius = mOverrideCanvasSearchRadius < 0 ? searchRadiusMU( mCanvas ) : mOverrideCanvasSearchRadius;
264  bool isTemporal = identifyContext.isTemporal() && layer->temporalProperties()->isActive();
265 
266  QList<QgsMeshDatasetIndex> datasetIndexList;
267  int activeScalarGroup = layer->rendererSettings().activeScalarDatasetGroup();
268  int activeVectorGroup = layer->rendererSettings().activeVectorDatasetGroup();
269 
270  const QList<int> allGroup = layer->enabledDatasetGroupsIndexes();
271  if ( isTemporal ) //non active dataset group value are only accesible if temporal is active
272  {
273  const QgsDateTimeRange &time = identifyContext.temporalRange();
274  if ( activeScalarGroup >= 0 )
275  datasetIndexList.append( layer->activeScalarDatasetAtTime( time ) );
276  if ( activeVectorGroup >= 0 && activeVectorGroup != activeScalarGroup )
277  datasetIndexList.append( layer->activeVectorDatasetAtTime( time ) );
278 
279  for ( int groupIndex : allGroup )
280  {
281  if ( groupIndex != activeScalarGroup && groupIndex != activeVectorGroup )
282  datasetIndexList.append( layer->datasetIndexAtTime( time, groupIndex ) );
283  }
284  }
285  else
286  {
287  // only active dataset group
288  if ( activeScalarGroup >= 0 )
289  datasetIndexList.append( layer->staticScalarDatasetIndex() );
290  if ( activeVectorGroup >= 0 && activeVectorGroup != activeScalarGroup )
291  datasetIndexList.append( layer->staticVectorDatasetIndex() );
292 
293  // ...and static dataset group
294  for ( int groupIndex : allGroup )
295  {
296  if ( groupIndex != activeScalarGroup && groupIndex != activeVectorGroup )
297  {
298  if ( !layer->datasetGroupMetadata( groupIndex ).isTemporal() )
299  datasetIndexList.append( groupIndex );
300  }
301  }
302  }
303 
304  //create results
305  for ( const QgsMeshDatasetIndex &index : datasetIndexList )
306  {
307  if ( !index.isValid() )
308  continue;
309 
310  const QgsMeshDatasetGroupMetadata &groupMeta = layer->datasetGroupMetadata( index );
311  QMap< QString, QString > derivedAttributes;
312 
313  QMap<QString, QString> attribute;
314  if ( groupMeta.isScalar() )
315  {
316  const QgsMeshDatasetValue scalarValue = layer->datasetValue( index, point, searchRadius );
317  const double scalar = scalarValue.scalar();
318  attribute.insert( tr( "Scalar Value" ), std::isnan( scalar ) ? tr( "no data" ) : QLocale().toString( scalar ) );
319  }
320 
321  if ( groupMeta.isVector() )
322  {
323  const QgsMeshDatasetValue vectorValue = layer->datasetValue( index, point, searchRadius );
324  const double vectorX = vectorValue.x();
325  const double vectorY = vectorValue.y();
326  if ( std::isnan( vectorX ) || std::isnan( vectorY ) )
327  attribute.insert( tr( "Vector Value" ), tr( "no data" ) );
328  else
329  {
330  attribute.insert( tr( "Vector Magnitude" ), QLocale().toString( vectorValue.scalar() ) );
331  derivedAttributes.insert( tr( "Vector x-component" ), QLocale().toString( vectorY ) );
332  derivedAttributes.insert( tr( "Vector y-component" ), QLocale().toString( vectorX ) );
333  }
334  }
335 
336  const QgsMeshDatasetMetadata &meta = layer->datasetMetadata( index );
337 
338  if ( groupMeta.isTemporal() )
339  derivedAttributes.insert( tr( "Time Step" ), layer->formatTime( meta.time() ) );
340  derivedAttributes.insert( tr( "Source" ), groupMeta.uri() );
341 
342  QString resultName = groupMeta.name();
343  if ( isTemporal && ( index.group() == activeScalarGroup || index.group() == activeVectorGroup ) )
344  resultName.append( tr( " (active)" ) );
345 
346  const IdentifyResult result( layer,
347  resultName,
348  attribute,
349  derivedAttributes );
350 
351  results->append( result );
352  }
353 
354  QMap<QString, QString> derivedGeometry;
355 
356  QgsPointXY vertexPoint = layer->snapOnElement( QgsMesh::Vertex, point, searchRadius );
357  if ( !vertexPoint.isEmpty() )
358  {
359  derivedGeometry.insert( tr( "Snapped Vertex Position X" ), QLocale().toString( vertexPoint.x() ) );
360  derivedGeometry.insert( tr( "Snapped Vertex Position Y" ), QLocale().toString( vertexPoint.y() ) );
361  }
362 
363  QgsPointXY faceCentroid = layer->snapOnElement( QgsMesh::Face, point, searchRadius );
364  if ( !faceCentroid.isEmpty() )
365  {
366  derivedGeometry.insert( tr( "Face Centroid X" ), QLocale().toString( faceCentroid.x() ) );
367  derivedGeometry.insert( tr( "Face Centroid Y" ), QLocale().toString( faceCentroid.y() ) );
368  }
369 
370  QgsPointXY pointOnEdge = layer->snapOnElement( QgsMesh::Edge, point, searchRadius );
371  if ( !pointOnEdge.isEmpty() )
372  {
373  derivedGeometry.insert( tr( "Point on Edge X" ), QLocale().toString( pointOnEdge.x() ) );
374  derivedGeometry.insert( tr( "Point on Edge Y" ), QLocale().toString( pointOnEdge.y() ) );
375  }
376 
377  const IdentifyResult result( layer,
378  tr( "Geometry" ),
380  derivedGeometry );
381 
382  results->append( result );
383 
384  return true;
385 }
386 
387 bool QgsMapToolIdentify::identifyVectorTileLayer( QList<QgsMapToolIdentify::IdentifyResult> *results, QgsVectorTileLayer *layer, const QgsGeometry &geometry, const QgsIdentifyContext &identifyContext )
388 {
389  Q_UNUSED( identifyContext )
390  if ( !layer || !layer->isSpatial() )
391  return false;
392 
393  if ( !layer->isInScaleRange( mCanvas->mapSettings().scale() ) )
394  {
395  QgsDebugMsgLevel( QStringLiteral( "Out of scale limits" ), 2 );
396  return false;
397  }
398 
399  QgsTemporaryCursorOverride waitCursor( Qt::WaitCursor );
400 
401  QMap< QString, QString > commonDerivedAttributes;
402 
403  QgsGeometry selectionGeom = geometry;
404  bool isPointOrRectangle;
405  QgsPointXY point;
406  bool isSingleClick = selectionGeom.type() == QgsWkbTypes::PointGeometry;
407  if ( isSingleClick )
408  {
409  isPointOrRectangle = true;
410  point = selectionGeom.asPoint();
411 
412  commonDerivedAttributes = derivedAttributesForPoint( QgsPoint( point ) );
413  }
414  else
415  {
416  // we have a polygon - maybe it is a rectangle - in such case we can avoid costly insterestion tests later
417  isPointOrRectangle = QgsGeometry::fromRect( selectionGeom.boundingBox() ).isGeosEqual( selectionGeom );
418  }
419 
420  int featureCount = 0;
421 
422  std::unique_ptr<QgsGeometryEngine> selectionGeomPrepared;
423 
424  // toLayerCoordinates will throw an exception for an 'invalid' point.
425  // For example, if you project a world map onto a globe using EPSG 2163
426  // and then click somewhere off the globe, an exception will be thrown.
427  try
428  {
429  QgsRectangle r;
430  if ( isSingleClick )
431  {
432  double sr = mOverrideCanvasSearchRadius < 0 ? searchRadiusMU( mCanvas ) : mOverrideCanvasSearchRadius;
433  r = toLayerCoordinates( layer, QgsRectangle( point.x() - sr, point.y() - sr, point.x() + sr, point.y() + sr ) );
434  }
435  else
436  {
437  r = toLayerCoordinates( layer, selectionGeom.boundingBox() );
438 
439  if ( !isPointOrRectangle )
440  {
441  QgsCoordinateTransform ct( mCanvas->mapSettings().destinationCrs(), layer->crs(), mCanvas->mapSettings().transformContext() );
442  if ( ct.isValid() )
443  selectionGeom.transform( ct );
444 
445  // use prepared geometry for faster intersection test
446  selectionGeomPrepared.reset( QgsGeometry::createGeometryEngine( selectionGeom.constGet() ) );
447  }
448  }
449 
450  const int tileZoom = layer->tileMatrixSet().scaleToZoomLevel( mCanvas->scale() );
451  const QgsTileMatrix tileMatrix = layer->tileMatrixSet().tileMatrix( tileZoom );
452  const QgsTileRange tileRange = tileMatrix.tileRangeFromExtent( r );
453 
454  for ( int row = tileRange.startRow(); row <= tileRange.endRow(); ++row )
455  {
456  for ( int col = tileRange.startColumn(); col <= tileRange.endColumn(); ++col )
457  {
458  QgsTileXYZ tileID( col, row, tileZoom );
459  QByteArray data = layer->getRawTile( tileID );
460  if ( data.isEmpty() )
461  continue; // failed to get data
462 
463  QgsVectorTileMVTDecoder decoder( layer->tileMatrixSet() );
464  if ( !decoder.decode( tileID, data ) )
465  continue; // failed to decode
466 
467  QMap<QString, QgsFields> perLayerFields;
468  const QStringList layerNames = decoder.layers();
469  for ( const QString &layerName : layerNames )
470  {
471  QSet<QString> fieldNames = qgis::listToSet( decoder.layerFieldNames( layerName ) );
472  perLayerFields[layerName] = QgsVectorTileUtils::makeQgisFields( fieldNames );
473  }
474 
475  const QgsVectorTileFeatures features = decoder.layerFeatures( perLayerFields, QgsCoordinateTransform() );
476  const QStringList featuresLayerNames = features.keys();
477  for ( const QString &layerName : featuresLayerNames )
478  {
479  const QgsFields fFields = perLayerFields[layerName];
480  const QVector<QgsFeature> &layerFeatures = features[layerName];
481  for ( const QgsFeature &f : layerFeatures )
482  {
483  if ( f.geometry().intersects( r ) && ( !selectionGeomPrepared || selectionGeomPrepared->intersects( f.geometry().constGet() ) ) )
484  {
485  QMap< QString, QString > derivedAttributes = commonDerivedAttributes;
486  derivedAttributes.insert( tr( "Feature ID" ), FID_TO_STRING( f.id() ) );
487 
488  results->append( IdentifyResult( layer, layerName, fFields, f, derivedAttributes ) );
489 
490  featureCount++;
491  }
492  }
493  }
494  }
495  }
496 
497  }
498  catch ( QgsCsException &cse )
499  {
500  Q_UNUSED( cse )
501  // catch exception for 'invalid' point and proceed with no features found
502  QgsDebugMsg( QStringLiteral( "Caught CRS exception %1" ).arg( cse.what() ) );
503  }
504 
505  return featureCount > 0;
506 }
507 
508 bool QgsMapToolIdentify::identifyPointCloudLayer( QList<QgsMapToolIdentify::IdentifyResult> *results, QgsPointCloudLayer *layer, const QgsGeometry &geometry, const QgsIdentifyContext &identifyContext )
509 {
510  Q_UNUSED( identifyContext )
511  QgsPointCloudRenderer *renderer = layer->renderer();
512 
513  QgsRenderContext context = QgsRenderContext::fromMapSettings( mCanvas->mapSettings() );
514  context.setCoordinateTransform( QgsCoordinateTransform( layer->crs(), mCanvas->mapSettings().destinationCrs(), mCanvas->mapSettings().transformContext() ) );
515 
516  const double searchRadiusMapUnits = mOverrideCanvasSearchRadius < 0 ? searchRadiusMU( mCanvas ) : mOverrideCanvasSearchRadius;
517 
518  const QVector<QVariantMap> points = renderer->identify( layer, context, geometry, searchRadiusMapUnits );
519 
521 
522  return true;
523 }
524 
525 QMap<QString, QString> QgsMapToolIdentify::derivedAttributesForPoint( const QgsPoint &point )
526 {
527  QMap< QString, QString > derivedAttributes;
528  derivedAttributes.insert( tr( "(clicked coordinate X)" ), formatXCoordinate( point ) );
529  derivedAttributes.insert( tr( "(clicked coordinate Y)" ), formatYCoordinate( point ) );
530  if ( point.is3D() )
531  derivedAttributes.insert( tr( "(clicked coordinate Z)" ), QLocale().toString( point.z(), 'f' ) );
532  return derivedAttributes;
533 }
534 
535 bool QgsMapToolIdentify::identifyVectorLayer( QList<QgsMapToolIdentify::IdentifyResult> *results, QgsVectorLayer *layer, const QgsGeometry &geometry, const QgsIdentifyContext &identifyContext )
536 {
537  if ( !layer || !layer->isSpatial() || !layer->dataProvider() )
538  return false;
539 
540  if ( !layer->isInScaleRange( mCanvas->mapSettings().scale() ) )
541  {
542  QgsDebugMsg( QStringLiteral( "Out of scale limits" ) );
543  return false;
544  }
545 
546  QString temporalFilter;
547  if ( identifyContext.isTemporal() )
548  {
549  if ( !layer->temporalProperties()->isVisibleInTemporalRange( identifyContext.temporalRange() ) )
550  return false;
551 
552  QgsVectorLayerTemporalContext temporalContext;
553  temporalContext.setLayer( layer );
554  temporalFilter = qobject_cast< const QgsVectorLayerTemporalProperties * >( layer->temporalProperties() )->createFilterString( temporalContext, identifyContext.temporalRange() );
555  }
556 
557  const bool fetchFeatureSymbols = layer->dataProvider()->capabilities() & QgsVectorDataProvider::FeatureSymbology;
558 
559  QApplication::setOverrideCursor( Qt::WaitCursor );
560 
561  QMap< QString, QString > commonDerivedAttributes;
562 
563  QgsGeometry selectionGeom = geometry;
564  bool isPointOrRectangle;
565  QgsPoint point;
566  bool isSingleClick = selectionGeom.type() == QgsWkbTypes::PointGeometry;
567  if ( isSingleClick )
568  {
569  isPointOrRectangle = true;
570  point = *qgsgeometry_cast< const QgsPoint *>( selectionGeom.constGet() );
571 
572  commonDerivedAttributes = derivedAttributesForPoint( point );
573  }
574  else
575  {
576  // we have a polygon - maybe it is a rectangle - in such case we can avoid costly insterestion tests later
577  isPointOrRectangle = QgsGeometry::fromRect( selectionGeom.boundingBox() ).isGeosEqual( selectionGeom );
578  }
579 
580  QgsFeatureList featureList;
581  std::unique_ptr<QgsGeometryEngine> selectionGeomPrepared;
582 
583  // toLayerCoordinates will throw an exception for an 'invalid' point.
584  // For example, if you project a world map onto a globe using EPSG 2163
585  // and then click somewhere off the globe, an exception will be thrown.
586  try
587  {
588  QgsRectangle r;
589  if ( isSingleClick )
590  {
591  double sr = mOverrideCanvasSearchRadius < 0 ? searchRadiusMU( mCanvas ) : mOverrideCanvasSearchRadius;
592  r = toLayerCoordinates( layer, QgsRectangle( point.x() - sr, point.y() - sr, point.x() + sr, point.y() + sr ) );
593  }
594  else
595  {
596  r = toLayerCoordinates( layer, selectionGeom.boundingBox() );
597 
598  if ( !isPointOrRectangle )
599  {
600  QgsCoordinateTransform ct( mCanvas->mapSettings().destinationCrs(), layer->crs(), mCanvas->mapSettings().transformContext() );
601  if ( ct.isValid() )
602  selectionGeom.transform( ct );
603 
604  // use prepared geometry for faster intersection test
605  selectionGeomPrepared.reset( QgsGeometry::createGeometryEngine( selectionGeom.constGet() ) );
606  }
607  }
608 
609  QgsFeatureRequest featureRequest;
610  featureRequest.setFilterRect( r );
611  featureRequest.setFlags( QgsFeatureRequest::ExactIntersect | ( fetchFeatureSymbols ? QgsFeatureRequest::EmbeddedSymbols : QgsFeatureRequest::Flags() ) );
612  if ( !temporalFilter.isEmpty() )
613  featureRequest.setFilterExpression( temporalFilter );
614 
615  QgsFeatureIterator fit = layer->getFeatures( featureRequest );
616  QgsFeature f;
617  while ( fit.nextFeature( f ) )
618  {
619  if ( !selectionGeomPrepared || selectionGeomPrepared->intersects( f.geometry().constGet() ) )
620  featureList << QgsFeature( f );
621  }
622  }
623  catch ( QgsCsException &cse )
624  {
625  Q_UNUSED( cse )
626  // catch exception for 'invalid' point and proceed with no features found
627  QgsDebugMsg( QStringLiteral( "Caught CRS exception %1" ).arg( cse.what() ) );
628  }
629 
630  bool filter = false;
631 
632  QgsRenderContext context( QgsRenderContext::fromMapSettings( mCanvas->mapSettings() ) );
633  context.setExpressionContext( mCanvas->createExpressionContext() );
635  std::unique_ptr< QgsFeatureRenderer > renderer( layer->renderer() ? layer->renderer()->clone() : nullptr );
636  if ( renderer )
637  {
638  // setup scale for scale dependent visibility (rule based)
639  renderer->startRender( context, layer->fields() );
640  filter = renderer->capabilities() & QgsFeatureRenderer::Filter;
641  }
642 
643  // When not single click identify, pass an empty point so some derived attributes may still be computed
644  if ( !isSingleClick )
645  point = QgsPoint();
646 
647  const int featureCount = identifyVectorLayer( results, layer, featureList, filter ? renderer.get() : nullptr, commonDerivedAttributes,
648  [point, layer, this]( const QgsFeature & feature )->QMap< QString, QString >
649  {
650  return featureDerivedAttributes( feature, layer, toLayerCoordinates( layer, point ) );
651  }, context );
652 
653  if ( renderer )
654  {
655  renderer->stopRender( context );
656  }
657  QApplication::restoreOverrideCursor();
658  return featureCount > 0;
659 }
660 
661 int QgsMapToolIdentify::identifyVectorLayer( QList<IdentifyResult> *results, QgsVectorLayer *layer, const QgsFeatureList &features, QgsFeatureRenderer *renderer, const QMap< QString, QString > &commonDerivedAttributes, const std::function< QMap< QString, QString > ( const QgsFeature & ) > &deriveAttributesForFeature, QgsRenderContext &context )
662 {
663  int featureCount = 0;
664  for ( const QgsFeature &feature : std::as_const( features ) )
665  {
666  QMap< QString, QString > derivedAttributes = commonDerivedAttributes;
667 
668  QgsFeatureId fid = feature.id();
669  context.expressionContext().setFeature( feature );
670 
671  if ( renderer && !renderer->willRenderFeature( feature, context ) )
672  continue;
673 
674  derivedAttributes.unite( deriveAttributesForFeature( feature ) );
675 
676  derivedAttributes.insert( tr( "Feature ID" ), fid < 0 ? tr( "new feature" ) : FID_TO_STRING( fid ) );
677 
678  results->append( IdentifyResult( qobject_cast<QgsMapLayer *>( layer ), feature, derivedAttributes ) );
679  featureCount++;
680  }
681  return featureCount;
682 }
683 
684 void QgsMapToolIdentify::closestVertexAttributes( const QgsAbstractGeometry &geometry, QgsVertexId vId, QgsMapLayer *layer, QMap< QString, QString > &derivedAttributes )
685 {
686  if ( ! vId.isValid( ) )
687  {
688  // We should not get here ...
689  QgsDebugMsg( "Invalid vertex id!" );
690  return;
691  }
692 
693  QString str = QLocale().toString( vId.vertex + 1 );
694  derivedAttributes.insert( tr( "Closest vertex number" ), str );
695 
696  QgsPoint closestPoint = geometry.vertexAt( vId );
697 
698  QgsPoint closestPointMapCoords = mCanvas->mapSettings().layerToMapCoordinates( layer, closestPoint );
699  derivedAttributes.insert( tr( "Closest vertex X" ), formatXCoordinate( closestPointMapCoords ) );
700  derivedAttributes.insert( tr( "Closest vertex Y" ), formatYCoordinate( closestPointMapCoords ) );
701 
702  if ( closestPoint.is3D() )
703  {
704  str = QLocale().toString( closestPointMapCoords.z(), 'g', 10 );
705  derivedAttributes.insert( tr( "Closest vertex Z" ), str );
706  }
707  if ( closestPoint.isMeasure() )
708  {
709  str = QLocale().toString( closestPointMapCoords.m(), 'g', 10 );
710  derivedAttributes.insert( tr( "Closest vertex M" ), str );
711  }
712 
713  if ( vId.type == Qgis::VertexType::Curve )
714  {
715  double radius, centerX, centerY;
716  QgsVertexId vIdBefore = vId;
717  --vIdBefore.vertex;
718  QgsVertexId vIdAfter = vId;
719  ++vIdAfter.vertex;
720  QgsGeometryUtils::circleCenterRadius( geometry.vertexAt( vIdBefore ), geometry.vertexAt( vId ),
721  geometry.vertexAt( vIdAfter ), radius, centerX, centerY );
722  derivedAttributes.insert( QStringLiteral( "Closest vertex radius" ), QLocale().toString( radius ) );
723  }
724 }
725 
726 void QgsMapToolIdentify::closestPointAttributes( const QgsAbstractGeometry &geometry, const QgsPointXY &layerPoint, QMap<QString, QString> &derivedAttributes )
727 {
728  QgsPoint closestPoint = QgsGeometryUtils::closestPoint( geometry, QgsPoint( layerPoint ) );
729 
730  derivedAttributes.insert( tr( "Closest X" ), formatXCoordinate( closestPoint ) );
731  derivedAttributes.insert( tr( "Closest Y" ), formatYCoordinate( closestPoint ) );
732 
733  if ( closestPoint.is3D() )
734  {
735  const QString str = QLocale().toString( closestPoint.z(), 'g', 10 );
736  derivedAttributes.insert( tr( "Interpolated Z" ), str );
737  }
738  if ( closestPoint.isMeasure() )
739  {
740  const QString str = QLocale().toString( closestPoint.m(), 'g', 10 );
741  derivedAttributes.insert( tr( "Interpolated M" ), str );
742  }
743 }
744 
745 QString QgsMapToolIdentify::formatCoordinate( const QgsPointXY &canvasPoint ) const
746 {
747  return QgsCoordinateUtils::formatCoordinateForProject( QgsProject::instance(), canvasPoint, mCanvas->mapSettings().destinationCrs(),
748  mCoordinatePrecision );
749 }
750 
751 QString QgsMapToolIdentify::formatXCoordinate( const QgsPointXY &canvasPoint ) const
752 {
753  QString coordinate = formatCoordinate( canvasPoint );
754  return coordinate.split( QgsCoordinateFormatter::separator() ).at( 0 );
755 }
756 
757 QString QgsMapToolIdentify::formatYCoordinate( const QgsPointXY &canvasPoint ) const
758 {
759  QString coordinate = formatCoordinate( canvasPoint );
760  return coordinate.split( QgsCoordinateFormatter::separator() ).at( 1 );
761 }
762 
763 QMap< QString, QString > QgsMapToolIdentify::featureDerivedAttributes( const QgsFeature &feature, QgsMapLayer *layer, const QgsPointXY &layerPoint )
764 {
765  // Calculate derived attributes and insert:
766  // measure distance or area depending on geometry type
767  QMap< QString, QString > derivedAttributes;
768 
769  // init distance/area calculator
770  QString ellipsoid = QgsProject::instance()->ellipsoid();
771  QgsDistanceArea calc;
772  calc.setEllipsoid( ellipsoid );
774 
777 
778  QgsVertexId vId;
779  QgsPoint closestPoint;
780  if ( feature.hasGeometry() )
781  {
782  geometryType = feature.geometry().type();
783  wkbType = feature.geometry().wkbType();
784  if ( !layerPoint.isEmpty() )
785  {
786  //find closest vertex to clicked point
787  closestPoint = QgsGeometryUtils::closestVertex( *feature.geometry().constGet(), QgsPoint( layerPoint ), vId );
788  }
789  }
790 
791 
792 
793  if ( QgsWkbTypes::isMultiType( wkbType ) )
794  {
795  QString str = QLocale().toString( static_cast<const QgsGeometryCollection *>( feature.geometry().constGet() )->numGeometries() );
796  derivedAttributes.insert( tr( "Parts" ), str );
797  if ( !layerPoint.isEmpty() )
798  {
799  str = QLocale().toString( vId.part + 1 );
800  derivedAttributes.insert( tr( "Part number" ), str );
801  }
802  }
803 
804  QgsUnitTypes::DistanceUnit cartesianDistanceUnits = QgsUnitTypes::unitType( layer->crs().mapUnits() ) == QgsUnitTypes::unitType( displayDistanceUnits() )
805  ? displayDistanceUnits() : layer->crs().mapUnits();
807  ? displayAreaUnits() : QgsUnitTypes::distanceToAreaUnit( layer->crs().mapUnits() );
808 
809  if ( geometryType == QgsWkbTypes::LineGeometry )
810  {
811  const QgsAbstractGeometry *geom = feature.geometry().constGet();
812 
813  double dist = calc.measureLength( feature.geometry() );
814  dist = calc.convertLengthMeasurement( dist, displayDistanceUnits() );
815  QString str;
816  if ( ellipsoid != geoNone() )
817  {
818  str = formatDistance( dist );
819  derivedAttributes.insert( tr( "Length (Ellipsoidal — %1)" ).arg( ellipsoid ), str );
820  }
821 
822  str = formatDistance( geom->length()
823  * QgsUnitTypes::fromUnitToUnitFactor( layer->crs().mapUnits(), cartesianDistanceUnits ), cartesianDistanceUnits );
824  if ( QgsWkbTypes::hasZ( geom->wkbType() )
826  {
827  // 3d linestring (or multiline)
828  derivedAttributes.insert( tr( "Length (Cartesian — 2D)" ), str );
829 
830  double totalLength3d = std::accumulate( geom->const_parts_begin(), geom->const_parts_end(), 0.0, []( double total, const QgsAbstractGeometry * part )
831  {
832  return total + qgsgeometry_cast< const QgsLineString * >( part )->length3D();
833  } );
834 
835  str = formatDistance( totalLength3d, cartesianDistanceUnits );
836  derivedAttributes.insert( tr( "Length (Cartesian — 3D)" ), str );
837  }
838  else
839  {
840  derivedAttributes.insert( tr( "Length (Cartesian)" ), str );
841  }
842 
843  str = QLocale().toString( geom->nCoordinates() );
844  derivedAttributes.insert( tr( "Vertices" ), str );
845  if ( !layerPoint.isEmpty() )
846  {
847  //add details of closest vertex to identify point
848  closestVertexAttributes( *geom, vId, layer, derivedAttributes );
849  closestPointAttributes( *geom, layerPoint, derivedAttributes );
850  }
851 
852  if ( const QgsCurve *curve = qgsgeometry_cast< const QgsCurve * >( geom ) )
853  {
854  // Add the start and end points in as derived attributes
855  QgsPointXY pnt = mCanvas->mapSettings().layerToMapCoordinates( layer, QgsPointXY( curve->startPoint().x(), curve->startPoint().y() ) );
856  str = formatXCoordinate( pnt );
857  derivedAttributes.insert( tr( "firstX", "attributes get sorted; translation for lastX should be lexically larger than this one" ), str );
858  str = formatYCoordinate( pnt );
859  derivedAttributes.insert( tr( "firstY" ), str );
860  pnt = mCanvas->mapSettings().layerToMapCoordinates( layer, QgsPointXY( curve->endPoint().x(), curve->endPoint().y() ) );
861  str = formatXCoordinate( pnt );
862  derivedAttributes.insert( tr( "lastX", "attributes get sorted; translation for firstX should be lexically smaller than this one" ), str );
863  str = formatYCoordinate( pnt );
864  derivedAttributes.insert( tr( "lastY" ), str );
865  }
866  }
867  else if ( geometryType == QgsWkbTypes::PolygonGeometry )
868  {
869  double area = calc.measureArea( feature.geometry() );
870  area = calc.convertAreaMeasurement( area, displayAreaUnits() );
871  QString str;
872  if ( ellipsoid != geoNone() )
873  {
874  str = formatArea( area );
875  derivedAttributes.insert( tr( "Area (Ellipsoidal — %1)" ).arg( ellipsoid ), str );
876  }
877  str = formatArea( feature.geometry().area()
878  * QgsUnitTypes::fromUnitToUnitFactor( QgsUnitTypes::distanceToAreaUnit( layer->crs().mapUnits() ), cartesianAreaUnits ), cartesianAreaUnits );
879  derivedAttributes.insert( tr( "Area (Cartesian)" ), str );
880 
881  if ( ellipsoid != geoNone() )
882  {
883  double perimeter = calc.measurePerimeter( feature.geometry() );
884  perimeter = calc.convertLengthMeasurement( perimeter, displayDistanceUnits() );
885  str = formatDistance( perimeter );
886  derivedAttributes.insert( tr( "Perimeter (Ellipsoidal — %1)" ).arg( ellipsoid ), str );
887  }
888  str = formatDistance( feature.geometry().constGet()->perimeter()
889  * QgsUnitTypes::fromUnitToUnitFactor( layer->crs().mapUnits(), cartesianDistanceUnits ), cartesianDistanceUnits );
890  derivedAttributes.insert( tr( "Perimeter (Cartesian)" ), str );
891 
892  str = QLocale().toString( feature.geometry().constGet()->nCoordinates() );
893  derivedAttributes.insert( tr( "Vertices" ), str );
894 
895  if ( !layerPoint.isEmpty() )
896  {
897  //add details of closest vertex to identify point
898  closestVertexAttributes( *feature.geometry().constGet(), vId, layer, derivedAttributes );
899  closestPointAttributes( *feature.geometry().constGet(), layerPoint, derivedAttributes );
900  }
901  }
902  else if ( geometryType == QgsWkbTypes::PointGeometry )
903  {
904  if ( QgsWkbTypes::flatType( wkbType ) == QgsWkbTypes::Point )
905  {
906  // Include the x and y coordinates of the point as a derived attribute
907  QgsPointXY pnt = mCanvas->mapSettings().layerToMapCoordinates( layer, feature.geometry().asPoint() );
908  QString str = formatXCoordinate( pnt );
909  derivedAttributes.insert( tr( "X" ), str );
910  str = formatYCoordinate( pnt );
911  derivedAttributes.insert( tr( "Y" ), str );
912 
913  if ( QgsWkbTypes::hasZ( wkbType ) )
914  {
915  str = QLocale().toString( static_cast<const QgsPoint *>( feature.geometry().constGet() )->z(), 'g', 10 );
916  derivedAttributes.insert( tr( "Z" ), str );
917  }
918  if ( QgsWkbTypes::hasM( wkbType ) )
919  {
920  str = QLocale().toString( static_cast<const QgsPoint *>( feature.geometry().constGet() )->m(), 'g', 10 );
921  derivedAttributes.insert( tr( "M" ), str );
922  }
923  }
924  else
925  {
926  //multipart
927 
928  if ( !layerPoint.isEmpty() )
929  {
930  //add details of closest vertex to identify point
931  const QgsAbstractGeometry *geom = feature.geometry().constGet();
932  closestVertexAttributes( *geom, vId, layer, derivedAttributes );
933  }
934  }
935  }
936 
937  if ( feature.embeddedSymbol() )
938  {
939  derivedAttributes.insert( tr( "Embedded Symbol" ), tr( "%1 (%2)" ).arg( QgsSymbol::symbolTypeToString( feature.embeddedSymbol()->type() ), feature.embeddedSymbol()->color().name() ) );
940  }
941 
942  return derivedAttributes;
943 }
944 
945 bool QgsMapToolIdentify::identifyRasterLayer( QList<IdentifyResult> *results, QgsRasterLayer *layer, const QgsGeometry &geometry, const QgsRectangle &viewExtent, double mapUnitsPerPixel, const QgsIdentifyContext &identifyContext )
946 {
947  QgsPointXY point = geometry.asPoint(); // raster layers currently only support identification by point
948  return identifyRasterLayer( results, layer, point, viewExtent, mapUnitsPerPixel, identifyContext );
949 }
950 
951 bool QgsMapToolIdentify::identifyRasterLayer( QList<IdentifyResult> *results, QgsRasterLayer *layer, QgsPointXY point, const QgsRectangle &viewExtent, double mapUnitsPerPixel, const QgsIdentifyContext &identifyContext )
952 {
953  QgsDebugMsg( "point = " + point.toString() );
954  if ( !layer )
955  return false;
956 
957  std::unique_ptr< QgsRasterDataProvider > dprovider( layer->dataProvider()->clone() );
958  if ( !dprovider )
959  return false;
960 
961  int capabilities = dprovider->capabilities();
962  if ( !( capabilities & QgsRasterDataProvider::Identify ) )
963  return false;
964 
965  if ( identifyContext.isTemporal() )
966  {
967  if ( !layer->temporalProperties()->isVisibleInTemporalRange( identifyContext.temporalRange() ) )
968  return false;
969 
970  dprovider->temporalCapabilities()->setRequestedTemporalRange( identifyContext.temporalRange() );
971  }
972 
973  QgsPointXY pointInCanvasCrs = point;
974  try
975  {
976  point = toLayerCoordinates( layer, point );
977  }
978  catch ( QgsCsException &cse )
979  {
980  Q_UNUSED( cse )
981  QgsDebugMsg( QStringLiteral( "coordinate not reprojectable: %1" ).arg( cse.what() ) );
982  return false;
983  }
984  QgsDebugMsg( QStringLiteral( "point = %1 %2" ).arg( point.x() ).arg( point.y() ) );
985 
986  if ( !layer->extent().contains( point ) )
987  return false;
988 
989  QMap< QString, QString > attributes, derivedAttributes;
990 
991  QgsRaster::IdentifyFormat format = QgsRasterDataProvider::identifyFormatFromName( layer->customProperty( QStringLiteral( "identify/format" ) ).toString() );
992 
993  // check if the format is really supported otherwise use first supported format
994  if ( !( QgsRasterDataProvider::identifyFormatToCapability( format ) & capabilities ) )
995  {
997  else if ( capabilities & QgsRasterInterface::IdentifyValue ) format = QgsRaster::IdentifyFormatValue;
998  else if ( capabilities & QgsRasterInterface::IdentifyHtml ) format = QgsRaster::IdentifyFormatHtml;
999  else if ( capabilities & QgsRasterInterface::IdentifyText ) format = QgsRaster::IdentifyFormatText;
1000  else return false;
1001  }
1002 
1003  QgsRasterIdentifyResult identifyResult;
1004  // We can only use current map canvas context (extent, width, height) if layer is not reprojected,
1005  if ( dprovider->crs() != mCanvas->mapSettings().destinationCrs() )
1006  {
1007  // To get some reasonable response for point/line WMS vector layers we must
1008  // use a context with approximately a resolution in layer CRS units
1009  // corresponding to current map canvas resolution (for examplei UMN Mapserver
1010  // in msWMSFeatureInfo() -> msQueryByRect() is using requested pixel
1011  // + TOLERANCE (layer param) for feature selection)
1012  //
1013  QgsRectangle r;
1014  r.setXMinimum( pointInCanvasCrs.x() - mapUnitsPerPixel / 2. );
1015  r.setXMaximum( pointInCanvasCrs.x() + mapUnitsPerPixel / 2. );
1016  r.setYMinimum( pointInCanvasCrs.y() - mapUnitsPerPixel / 2. );
1017  r.setYMaximum( pointInCanvasCrs.y() + mapUnitsPerPixel / 2. );
1018  r = toLayerCoordinates( layer, r ); // will be a bit larger
1019  // Mapserver (6.0.3, for example) does not work with 1x1 pixel box
1020  // but that is fixed (the rect is enlarged) in the WMS provider
1021  identifyResult = dprovider->identify( point, format, r, 1, 1 );
1022  }
1023  else
1024  {
1025  // It would be nice to use the same extent and size which was used for drawing,
1026  // so that WCS can use cache from last draw, unfortunately QgsRasterLayer::draw()
1027  // is doing some tricks with extent and size to align raster to output which
1028  // would be difficult to replicate here.
1029  // Note: cutting the extent may result in slightly different x and y resolutions
1030  // and thus shifted point calculated back in QGIS WMS (using average resolution)
1031  //viewExtent = dprovider->extent().intersect( &viewExtent );
1032 
1033  // Width and height are calculated from not projected extent and we hope that
1034  // are similar to source width and height used to reproject layer for drawing.
1035  // TODO: may be very dangerous, because it may result in different resolutions
1036  // in source CRS, and WMS server (QGIS server) calcs wrong coor using average resolution.
1037  int width = static_cast< int >( std::round( viewExtent.width() / mapUnitsPerPixel ) );
1038  int height = static_cast< int >( std::round( viewExtent.height() / mapUnitsPerPixel ) );
1039 
1040  QgsDebugMsg( QStringLiteral( "viewExtent.width = %1 viewExtent.height = %2" ).arg( viewExtent.width() ).arg( viewExtent.height() ) );
1041  QgsDebugMsg( QStringLiteral( "width = %1 height = %2" ).arg( width ).arg( height ) );
1042  QgsDebugMsg( QStringLiteral( "xRes = %1 yRes = %2 mapUnitsPerPixel = %3" ).arg( viewExtent.width() / width ).arg( viewExtent.height() / height ).arg( mapUnitsPerPixel ) );
1043 
1044  identifyResult = dprovider->identify( point, format, viewExtent, width, height );
1045  }
1046 
1047  derivedAttributes.unite( derivedAttributesForPoint( QgsPoint( pointInCanvasCrs ) ) );
1048 
1049  if ( identifyResult.isValid() )
1050  {
1051  QMap<int, QVariant> values = identifyResult.results();
1052  QgsGeometry geometry;
1053  if ( format == QgsRaster::IdentifyFormatValue )
1054  {
1055  for ( auto it = values.constBegin(); it != values.constEnd(); ++it )
1056  {
1057  QString valueString;
1058  if ( it.value().isNull() )
1059  {
1060  valueString = tr( "no data" );
1061  }
1062  else
1063  {
1064  QVariant value( it.value() );
1065  // The cast is legit. Quoting QT doc :
1066  // "Although this function is declared as returning QVariant::Type,
1067  // the return value should be interpreted as QMetaType::Type"
1068  if ( static_cast<QMetaType::Type>( value.type() ) == QMetaType::Float )
1069  {
1070  valueString = QgsRasterBlock::printValue( value.toFloat() );
1071  }
1072  else
1073  {
1074  valueString = QgsRasterBlock::printValue( value.toDouble() );
1075  }
1076  }
1077  attributes.insert( dprovider->generateBandName( it.key() ), valueString );
1078  }
1079  QString label = layer->name();
1080  results->append( IdentifyResult( qobject_cast<QgsMapLayer *>( layer ), label, attributes, derivedAttributes ) );
1081  }
1082  else if ( format == QgsRaster::IdentifyFormatFeature )
1083  {
1084  for ( auto it = values.constBegin(); it != values.constEnd(); ++it )
1085  {
1086  QVariant value = it.value();
1087  if ( value.type() == QVariant::Bool && !value.toBool() )
1088  {
1089  // sublayer not visible or not queryable
1090  continue;
1091  }
1092 
1093  if ( value.type() == QVariant::String )
1094  {
1095  // error
1096  // TODO: better error reporting
1097  QString label = layer->subLayers().value( it.key() );
1098  attributes.clear();
1099  attributes.insert( tr( "Error" ), value.toString() );
1100 
1101  results->append( IdentifyResult( qobject_cast<QgsMapLayer *>( layer ), label, attributes, derivedAttributes ) );
1102  continue;
1103  }
1104 
1105  // list of feature stores for a single sublayer
1106  const QgsFeatureStoreList featureStoreList = value.value<QgsFeatureStoreList>();
1107 
1108  for ( const QgsFeatureStore &featureStore : featureStoreList )
1109  {
1110  const QgsFeatureList storeFeatures = featureStore.features();
1111  for ( const QgsFeature &feature : storeFeatures )
1112  {
1113  attributes.clear();
1114  // WMS sublayer and feature type, a sublayer may contain multiple feature types.
1115  // Sublayer name may be the same as layer name and feature type name
1116  // may be the same as sublayer. We try to avoid duplicities in label.
1117  QString sublayer = featureStore.params().value( QStringLiteral( "sublayer" ) ).toString();
1118  QString featureType = featureStore.params().value( QStringLiteral( "featureType" ) ).toString();
1119  // Strip UMN MapServer '_feature'
1120  featureType.remove( QStringLiteral( "_feature" ) );
1121  QStringList labels;
1122  if ( sublayer.compare( layer->name(), Qt::CaseInsensitive ) != 0 )
1123  {
1124  labels << sublayer;
1125  }
1126  if ( featureType.compare( sublayer, Qt::CaseInsensitive ) != 0 || labels.isEmpty() )
1127  {
1128  labels << featureType;
1129  }
1130 
1131  QMap< QString, QString > derAttributes = derivedAttributes;
1132  derAttributes.unite( featureDerivedAttributes( feature, layer, toLayerCoordinates( layer, point ) ) );
1133 
1134  IdentifyResult identifyResult( qobject_cast<QgsMapLayer *>( layer ), labels.join( QLatin1String( " / " ) ), featureStore.fields(), feature, derAttributes );
1135 
1136  identifyResult.mParams.insert( QStringLiteral( "getFeatureInfoUrl" ), featureStore.params().value( QStringLiteral( "getFeatureInfoUrl" ) ) );
1137  results->append( identifyResult );
1138  }
1139  }
1140  }
1141  }
1142  else // text or html
1143  {
1144  QgsDebugMsg( QStringLiteral( "%1 HTML or text values" ).arg( values.size() ) );
1145  for ( auto it = values.constBegin(); it != values.constEnd(); ++it )
1146  {
1147  QString value = it.value().toString();
1148  attributes.clear();
1149  attributes.insert( QString(), value );
1150 
1151  QString label = layer->subLayers().value( it.key() );
1152  results->append( IdentifyResult( qobject_cast<QgsMapLayer *>( layer ), label, attributes, derivedAttributes ) );
1153  }
1154  }
1155  }
1156  else
1157  {
1158  attributes.clear();
1159  QString value = identifyResult.error().message( QgsErrorMessage::Text );
1160  attributes.insert( tr( "Error" ), value );
1161  QString label = tr( "Identify error" );
1162  results->append( IdentifyResult( qobject_cast<QgsMapLayer *>( layer ), label, attributes, derivedAttributes ) );
1163  }
1164 
1165  return true;
1166 }
1167 
1168 QgsUnitTypes::DistanceUnit QgsMapToolIdentify::displayDistanceUnits() const
1169 {
1170  return mCanvas->mapUnits();
1171 }
1172 
1173 QgsUnitTypes::AreaUnit QgsMapToolIdentify::displayAreaUnits() const
1174 {
1175  return QgsUnitTypes::distanceToAreaUnit( mCanvas->mapUnits() );
1176 }
1177 
1178 QString QgsMapToolIdentify::formatDistance( double distance ) const
1179 {
1180  return formatDistance( distance, displayDistanceUnits() );
1181 }
1182 
1183 QString QgsMapToolIdentify::formatArea( double area ) const
1184 {
1185  return formatArea( area, displayAreaUnits() );
1186 }
1187 
1188 QString QgsMapToolIdentify::formatDistance( double distance, QgsUnitTypes::DistanceUnit unit ) const
1189 {
1190  QgsSettings settings;
1191  bool baseUnit = settings.value( QStringLiteral( "qgis/measure/keepbaseunit" ), true ).toBool();
1192 
1193  return QgsDistanceArea::formatDistance( distance, mCoordinatePrecision, unit, baseUnit );
1194 }
1195 
1196 QString QgsMapToolIdentify::formatArea( double area, QgsUnitTypes::AreaUnit unit ) const
1197 {
1198  QgsSettings settings;
1199  bool baseUnit = settings.value( QStringLiteral( "qgis/measure/keepbaseunit" ), true ).toBool();
1200 
1201  return QgsDistanceArea::formatArea( area, mCoordinatePrecision, unit, baseUnit );
1202 }
1203 
1205 {
1206  QList<IdentifyResult> results;
1207  if ( identifyRasterLayer( &results, layer, mLastGeometry, mLastExtent, mLastMapUnitsPerPixel ) )
1208  {
1209  emit changedRasterResults( results );
1210  }
1211 }
1212 
1213 void QgsMapToolIdentify::fromPointCloudIdentificationToIdentifyResults( QgsPointCloudLayer *layer, const QVector<QVariantMap> &identified, QList<QgsMapToolIdentify::IdentifyResult> &results )
1214 {
1215  int id = 1;
1216  const QgsPointCloudLayerElevationProperties *elevationProps = qobject_cast< const QgsPointCloudLayerElevationProperties *>( layer->elevationProperties() );
1217  for ( const QVariantMap &pt : identified )
1218  {
1219  QMap<QString, QString> ptStr;
1220  QString classification;
1221  for ( auto attrIt = pt.constBegin(); attrIt != pt.constEnd(); ++attrIt )
1222  {
1223  if ( attrIt.key().compare( QLatin1String( "Z" ), Qt::CaseInsensitive ) == 0
1224  && ( !qgsDoubleNear( elevationProps->zScale(), 1 ) || !qgsDoubleNear( elevationProps->zOffset(), 0 ) ) )
1225  {
1226  // Apply elevation properties
1227  ptStr[ tr( "Z (original)" ) ] = attrIt.value().toString();
1228  ptStr[ tr( "Z (adjusted)" ) ] = QString::number( attrIt.value().toDouble() * elevationProps->zScale() + elevationProps->zOffset() );
1229  }
1230  else if ( attrIt.key().compare( QLatin1String( "Classification" ), Qt::CaseInsensitive ) == 0 )
1231  {
1232  classification = QgsPointCloudDataProvider::translatedLasClassificationCodes().value( attrIt.value().toInt() );
1233  ptStr[ attrIt.key() ] = QStringLiteral( "%1 (%2)" ).arg( attrIt.value().toString(), classification );
1234  }
1235  else
1236  {
1237  ptStr[attrIt.key()] = attrIt.value().toString();
1238  }
1239  }
1240  QgsMapToolIdentify::IdentifyResult res( layer, classification.isEmpty() ? QString::number( id ) : QStringLiteral( "%1 (%2)" ).arg( id ).arg( classification ), ptStr, QMap<QString, QString>() );
1241  results.append( res );
1242  ++id;
1243  }
1244 }
1245 
1246 void QgsMapToolIdentify::fromElevationProfileLayerIdentificationToIdentifyResults( QgsMapLayer *layer, const QVector<QVariantMap> &identified, QList<IdentifyResult> &results )
1247 {
1248  if ( !layer )
1249  return;
1250 
1251  if ( identified.empty() )
1252  return;
1253 
1254  switch ( layer->type() )
1255  {
1257  {
1258  QgsVectorLayer *vl = qobject_cast< QgsVectorLayer * >( layer );
1259 
1260  QgsFeatureList features;
1261  QHash< QgsFeatureId, QVariant > featureDistances;
1262  QHash< QgsFeatureId, QVariant > featureElevations;
1263 
1264  QgsFeatureIds filterIds;
1265  for ( const QVariantMap &map : identified )
1266  {
1267  if ( !map.contains( QStringLiteral( "id" ) ) )
1268  {
1269  QMap< QString, QString > attributes;
1270  if ( map.value( QStringLiteral( "distance" ) ).isValid() )
1271  attributes.insert( tr( "Distance along curve" ), QString::number( map.value( QStringLiteral( "distance" ) ).toDouble() ) );
1272  if ( map.value( QStringLiteral( "elevation" ) ).isValid() )
1273  attributes.insert( tr( "Elevation" ), QString::number( map.value( QStringLiteral( "elevation" ) ).toDouble() ) );
1274 
1275  results.append( IdentifyResult( layer, layer->name(), {}, attributes ) );
1276  }
1277  else
1278  {
1279  const QgsFeatureId id = map.value( QStringLiteral( "id" ) ).toLongLong();
1280  filterIds.insert( id );
1281 
1282  featureDistances.insert( id, map.value( QStringLiteral( "distance" ) ) );
1283  featureElevations.insert( id, map.value( QStringLiteral( "elevation" ) ) );
1284  }
1285  }
1286 
1287  QgsFeatureRequest request;
1288  request.setFilterFids( filterIds );
1289  QgsFeatureIterator it = vl->getFeatures( request );
1290  QgsFeature f;
1291  while ( it.nextFeature( f ) )
1292  features << f;
1293 
1294  QgsRenderContext context;
1295  identifyVectorLayer( &results, vl, features, nullptr, QMap< QString, QString >(), [this, vl, &featureDistances, &featureElevations]( const QgsFeature & feature )->QMap< QString, QString >
1296  {
1297  QMap< QString, QString > attributes = featureDerivedAttributes( feature, vl, QgsPointXY() );
1298 
1299  if ( featureDistances.value( feature.id() ).isValid() )
1300  attributes.insert( tr( "Distance along curve" ), QString::number( featureDistances.value( feature.id() ).toDouble() ) );
1301  if ( featureElevations.value( feature.id() ).isValid() )
1302  attributes.insert( tr( "Elevation" ), QString::number( featureElevations.value( feature.id() ).toDouble() ) );
1303 
1304  return attributes;
1305  }, context );
1306  break;
1307  }
1308 
1311  {
1312  for ( const QVariantMap &map : identified )
1313  {
1314  QMap< QString, QString > attributes;
1315  if ( map.value( QStringLiteral( "distance" ) ).isValid() )
1316  attributes.insert( tr( "Distance along curve" ), QString::number( map.value( QStringLiteral( "distance" ) ).toDouble() ) );
1317  if ( map.value( QStringLiteral( "elevation" ) ).isValid() )
1318  attributes.insert( tr( "Elevation" ), QString::number( map.value( QStringLiteral( "elevation" ) ).toDouble() ) );
1319 
1320  results.append( IdentifyResult( layer, layer->name(), {}, attributes ) );
1321  }
1322 
1323  break;
1324  }
1325 
1327  {
1328  QgsPointCloudLayer *pcLayer = qobject_cast< QgsPointCloudLayer * >( layer );
1329  fromPointCloudIdentificationToIdentifyResults( pcLayer, identified, results );
1330  break;
1331  }
1332 
1337  break;
1338  }
1339 }
QgsCurve
Abstract base class for curved geometry type.
Definition: qgscurve.h:35
QgsMapToolIdentify::deactivate
void deactivate() override
called when map tool is being deactivated
Definition: qgsmaptoolidentify.cpp:208
QgsVertexId::part
int part
Part number.
Definition: qgsvertexid.h:89
QgsVectorLayer::getFeatures
QgsFeatureIterator getFeatures(const QgsFeatureRequest &request=QgsFeatureRequest()) const FINAL
Queries the layer for features specified in request.
Definition: qgsvectorlayer.cpp:1052
QgsMapLayer::crs
QgsCoordinateReferenceSystem crs
Definition: qgsmaplayer.h:79
qgsmaptoolidentify.h
qgsfields.h
qgsexpressioncontextutils.h
QgsFeatureRenderer::Filter
@ Filter
Features may be filtered, i.e. some features may not be rendered (categorized, rule based ....
Definition: qgsrenderer.h:265
QgsRasterBlock::printValue
static QString printValue(double value)
Print double value with all necessary significant digits.
Definition: qgsrasterblock.cpp:618
QgsMapToolIdentify::activate
void activate() override
called when set as currently active map tool
Definition: qgsmaptoolidentify.cpp:203
QgsSymbol::color
QColor color() const
Returns the symbol's color.
Definition: qgssymbol.cpp:877
QgsRectangle::height
double height() const SIP_HOLDGIL
Returns the height of the rectangle.
Definition: qgsrectangle.h:230
QgsVertexId::vertex
int vertex
Vertex number.
Definition: qgsvertexid.h:95
QgsSymbol::symbolTypeToString
static QString symbolTypeToString(Qgis::SymbolType type)
Returns a translated string version of the specified symbol type.
Definition: qgssymbol.cpp:533
QgsPointXY::y
double y
Definition: qgspointxy.h:63
QgsMapTool::toLayerCoordinates
QgsPoint toLayerCoordinates(const QgsMapLayer *layer, const QgsPoint &point)
Transforms a point from map coordinates to layer coordinates.
Definition: qgsmaptool.cpp:62
QgsDistanceArea::measureLength
double measureLength(const QgsGeometry &geometry) const
Measures the length of a geometry.
Definition: qgsdistancearea.cpp:217
QgsMapToolIdentify::LayerSelection
@ LayerSelection
Definition: qgsmaptoolidentify.h:65
QgsVectorTileLayer
Implements a map layer that is dedicated to rendering of vector tiles. Vector tiles compared to "ordi...
Definition: qgsvectortilelayer.h:84
qgsrasterlayer.h
QgsPointCloudRenderer::identify
QVector< QVariantMap > identify(QgsPointCloudLayer *layer, const QgsRenderContext &context, const QgsGeometry &geometry, double toleranceForPointIdentification=0)
Returns the list of visible points of the point cloud layer layer and an extent defined by a geometry...
Definition: qgspointcloudrenderer.cpp:217
QgsMapToolIdentify::AllLayers
@ AllLayers
Definition: qgsmaptoolidentify.h:76
QgsWkbTypes::Point
@ Point
Definition: qgswkbtypes.h:72
QgsRasterInterface::IdentifyHtml
@ IdentifyHtml
WMS HTML.
Definition: qgsrasterinterface.h:212
QgsRenderContext::expressionContext
QgsExpressionContext & expressionContext()
Gets the expression context.
Definition: qgsrendercontext.h:625
QgsSettings::value
QVariant value(const QString &key, const QVariant &defaultValue=QVariant(), Section section=NoSection) const
Returns the value for setting key.
Definition: qgssettings.cpp:161
QgsIdentifyContext::isTemporal
bool isTemporal() const
Returns true if the temporal range setting is enabled.
Definition: qgsidentifycontext.cpp:29
QgsMapLayerType::MeshLayer
@ MeshLayer
Mesh layer. Added in QGIS 3.2.
QgsTileXYZ
Stores coordinates of a tile in a tile matrix set. Tile matrix is identified by the zoomLevel(),...
Definition: qgstiles.h:37
QgsFeatureRequest::ExactIntersect
@ ExactIntersect
Use exact geometry intersection (slower) instead of bounding boxes.
Definition: qgsfeaturerequest.h:117
QgsMapToolIdentify::identifyMeshLayer
bool identifyMeshLayer(QList< QgsMapToolIdentify::IdentifyResult > *results, QgsMeshLayer *layer, const QgsPointXY &point, const QgsIdentifyContext &identifyContext=QgsIdentifyContext())
Identifies data from active scalar and vector dataset from the mesh layer.
Definition: qgsmaptoolidentify.cpp:257
qgsmapcanvas.h
QgsWkbTypes::NullGeometry
@ NullGeometry
Definition: qgswkbtypes.h:146
QgsRenderContext::fromMapSettings
static QgsRenderContext fromMapSettings(const QgsMapSettings &mapSettings)
create initialized QgsRenderContext instance from given QgsMapSettings
Definition: qgsrendercontext.cpp:234
QgsMapLayerType::VectorLayer
@ VectorLayer
Vector layer.
QgsPoint
Point geometry type, with support for z-dimension and m-values.
Definition: qgspoint.h:48
QgsTileRange
Range of tiles in a tile matrix to be rendered. The selection is rectangular, given by start/end row ...
Definition: qgstiles.h:70
QgsDebugMsgLevel
#define QgsDebugMsgLevel(str, level)
Definition: qgslogger.h:39
QgsGeometry::transform
Qgis::GeometryOperationResult transform(const QgsCoordinateTransform &ct, Qgis::TransformDirection direction=Qgis::TransformDirection::Forward, bool transformZ=false) SIP_THROW(QgsCsException)
Transforms this geometry as described by the coordinate transform ct.
Definition: qgsgeometry.cpp:3128
qgscoordinateutils.h
qgsrasteridentifyresult.h
QgsMapToolIdentify::ActiveLayer
@ ActiveLayer
Definition: qgsmaptoolidentify.h:62
QgsMapLayer::clone
virtual QgsMapLayer * clone() const =0
Returns a new instance equivalent to this one except for the id which is still unique.
QgsMapToolIdentify::VectorLayer
@ VectorLayer
Definition: qgsmaptoolidentify.h:71
QgsPointCloudLayerElevationProperties
Point cloud layer specific subclass of QgsMapLayerElevationProperties.
Definition: qgspointcloudlayerelevationproperties.h:33
qgsmaptopixel.h
QgsPointCloudLayer
Represents a map layer supporting display of point clouds.
Definition: qgspointcloudlayer.h:45
QgsIdentifyContext::temporalRange
const QgsDateTimeRange & temporalRange() const
Returns the datetime range to be used with the identify action.
Definition: qgsidentifycontext.cpp:24
QgsMesh::Face
@ Face
Definition: qgsmeshdataprovider.h:69
crs
const QgsCoordinateReferenceSystem & crs
Definition: qgswfsgetfeature.cpp:105
QgsMapToolIdentify::MeshLayer
@ MeshLayer
Definition: qgsmaptoolidentify.h:73
QgsApplication::getThemeCursor
static QCursor getThemeCursor(Cursor cursor)
Helper to get a theme cursor.
Definition: qgsapplication.cpp:762
QgsRaster::IdentifyFormatText
@ IdentifyFormatText
Definition: qgsraster.h:74
QgsWkbTypes::flatType
static Type flatType(Type type) SIP_HOLDGIL
Returns the flat type for a WKB type.
Definition: qgswkbtypes.h:732
QgsMapLayerType::AnnotationLayer
@ AnnotationLayer
Contains freeform, georeferenced annotations. Added in QGIS 3.16.
QgsMapLayer::subLayers
virtual QStringList subLayers() const
Returns the sublayers of this layer.
Definition: qgsmaplayer.cpp:909
QgsMeshDatasetValue
QgsMeshDatasetValue represents single dataset value.
Definition: qgsmeshdataset.h:79
QgsUnitTypes::unitType
static Q_INVOKABLE QgsUnitTypes::DistanceUnitType unitType(QgsUnitTypes::DistanceUnit unit)
Returns the type for a distance unit.
Definition: qgsunittypes.cpp:73
QgsMapToolIdentify::QgsMapToolIdentify
QgsMapToolIdentify(QgsMapCanvas *canvas)
constructor
Definition: qgsmaptoolidentify.cpp:67
QgsWkbTypes::LineString
@ LineString
Definition: qgswkbtypes.h:73
qgsfeatureiterator.h
QgsFields
Container of fields for a vector layer.
Definition: qgsfields.h:44
QgsFeatureStore
A container for features with the same fields and crs.
Definition: qgsfeaturestore.h:32
QgsMapTool::setCursor
virtual void setCursor(const QCursor &cursor)
Sets a user defined cursor.
Definition: qgsmaptool.cpp:160
QgsGeometry::fromPointXY
static QgsGeometry fromPointXY(const QgsPointXY &point) SIP_HOLDGIL
Creates a new geometry from a QgsPointXY object.
Definition: qgsgeometry.cpp:176
QgsExpressionContextUtils::layerScope
static QgsExpressionContextScope * layerScope(const QgsMapLayer *layer)
Creates a new scope which contains variables and functions relating to a QgsMapLayer.
Definition: qgsexpressioncontextutils.cpp:334
QgsMapCanvas
Map canvas is a class for displaying all GIS data types on a canvas.
Definition: qgsmapcanvas.h:89
QgsUnitTypes::distanceToAreaUnit
static Q_INVOKABLE QgsUnitTypes::AreaUnit distanceToAreaUnit(QgsUnitTypes::DistanceUnit distanceUnit)
Converts a distance unit to its corresponding area unit, e.g., meters to square meters.
Definition: qgsunittypes.cpp:1176
QgsMapTool::deactivate
virtual void deactivate()
called when map tool is being deactivated
Definition: qgsmaptool.cpp:110
QgsMapToolIdentify::identifyLayer
bool identifyLayer(QList< QgsMapToolIdentify::IdentifyResult > *results, QgsMapLayer *layer, const QgsPointXY &point, const QgsRectangle &viewExtent, double mapUnitsPerPixel, QgsMapToolIdentify::LayerType layerType=AllLayers, const QgsIdentifyContext &identifyContext=QgsIdentifyContext())
Call the right method depending on layer type.
Definition: qgsmaptoolidentify.cpp:213
qgsfeature.h
QgsRaster::IdentifyFormatHtml
@ IdentifyFormatHtml
Definition: qgsraster.h:75
QgsFeature::geometry
QgsGeometry geometry
Definition: qgsfeature.h:71
QgsProject::transformContext
QgsCoordinateTransformContext transformContext
Definition: qgsproject.h:110
QgsPoint::z
double z
Definition: qgspoint.h:71
QgsRenderContext
Contains information about the context of a rendering operation.
Definition: qgsrendercontext.h:59
QgsDistanceArea::measureArea
double measureArea(const QgsGeometry &geometry) const
Measures the area of a geometry.
Definition: qgsdistancearea.cpp:208
QgsProject::instance
static QgsProject * instance()
Returns the QgsProject singleton instance.
Definition: qgsproject.cpp:480
QgsAbstractGeometry::length
virtual double length() const
Returns the planar, 2-dimensional length of the geometry.
Definition: qgsabstractgeometry.cpp:166
QgsGeometryUtils::closestPoint
static QgsPoint closestPoint(const QgsAbstractGeometry &geometry, const QgsPoint &point)
Returns the nearest point on a segment of a geometry for the specified point.
Definition: qgsgeometryutils.cpp:101
QgsSettings
This class is a composition of two QSettings instances:
Definition: qgssettings.h:61
QgsWkbTypes::Type
Type
The WKB type describes the number of dimensions a geometry has.
Definition: qgswkbtypes.h:69
QgsPointXY::isEmpty
bool isEmpty() const SIP_HOLDGIL
Returns true if the geometry is empty.
Definition: qgspointxy.h:249
QgsRasterInterface::IdentifyFeature
@ IdentifyFeature
WMS GML -> feature.
Definition: qgsrasterinterface.h:213
QgsRasterIdentifyResult::isValid
bool isValid() const
Returns true if valid.
Definition: qgsrasteridentifyresult.h:68
QgsDebugMsg
#define QgsDebugMsg(str)
Definition: qgslogger.h:38
QgsFields::append
bool append(const QgsField &field, FieldOrigin origin=OriginProvider, int originIndex=-1)
Appends a field. The field must have unique name, otherwise it is rejected (returns false)
Definition: qgsfields.cpp:59
QgsUnitTypes::DistanceUnit
DistanceUnit
Units of distance.
Definition: qgsunittypes.h:67
QgsMapTool::mCanvas
QPointer< QgsMapCanvas > mCanvas
The pointer to the map canvas.
Definition: qgsmaptool.h:336
FID_TO_STRING
#define FID_TO_STRING(fid)
Definition: qgsfeatureid.h:33
QgsRasterInterface::Identify
@ Identify
At least one identify format supported.
Definition: qgsrasterinterface.h:209
QgsIdentifyMenu::exec
QList< QgsMapToolIdentify::IdentifyResult > exec(const QList< QgsMapToolIdentify::IdentifyResult > &idResults, QPoint pos)
exec
Definition: qgsidentifymenu.cpp:127
qgsidentifymenu.h
QgsRectangle
A rectangle specified with double values.
Definition: qgsrectangle.h:41
QgsVectorTileMVTDecoder
This class is responsible for decoding raw tile data written with Mapbox Vector Tiles encoding.
Definition: qgsvectortilemvtdecoder.h:38
QgsMeshDatasetMetadata
QgsMeshDatasetMetadata is a collection of mesh dataset metadata such as whether the data is valid or ...
Definition: qgsmeshdataset.h:478
QgsMeshDatasetMetadata::time
double time() const
Returns the time value for this dataset.
Definition: qgsmeshdataset.cpp:216
QgsPointCloudRenderer::startRender
virtual void startRender(QgsPointCloudRenderContext &context)
Must be called when a new render cycle is started.
Definition: qgspointcloudrenderer.cpp:88
QgsWkbTypes::PolygonGeometry
@ PolygonGeometry
Definition: qgswkbtypes.h:144
QgsVectorDataProvider::FeatureSymbology
@ FeatureSymbology
Provider is able retrieve embedded symbology associated with individual features. Since QGIS 3....
Definition: qgsvectordataprovider.h:98
QgsMapToolIdentify::TopDownStopAtFirst
@ TopDownStopAtFirst
Definition: qgsmaptoolidentify.h:63
QgsGeometryCollection::numGeometries
int numGeometries() const SIP_HOLDGIL
Returns the number of geometries within the collection.
Definition: qgsgeometrycollection.h:58
QgsRasterDataProvider::identifyFormatFromName
static QgsRaster::IdentifyFormat identifyFormatFromName(const QString &formatName)
Definition: qgsrasterdataprovider.cpp:480
QgsMapToolIdentify::TopDownAll
@ TopDownAll
Definition: qgsmaptoolidentify.h:64
QgsFeatureRenderer::willRenderFeature
virtual bool willRenderFeature(const QgsFeature &feature, QgsRenderContext &context) const
Returns whether the renderer will render a feature or not.
Definition: qgsrenderer.cpp:388
QgsFeatureRequest::setFilterExpression
QgsFeatureRequest & setFilterExpression(const QString &expression)
Set the filter expression.
Definition: qgsfeaturerequest.cpp:167
QgsGeometryUtils::circleCenterRadius
static void circleCenterRadius(const QgsPoint &pt1, const QgsPoint &pt2, const QgsPoint &pt3, double &radius, double &centerX, double &centerY) SIP_HOLDGIL
Returns radius and center of the circle through pt1, pt2, pt3.
Definition: qgsgeometryutils.cpp:706
QgsMapToolIdentify::PointCloudLayer
@ PointCloudLayer
Definition: qgsmaptoolidentify.h:75
QgsAbstractGeometry::vertexAt
virtual QgsPoint vertexAt(QgsVertexId id) const =0
Returns the point corresponding to a specified vertex id.
QgsDistanceArea::convertAreaMeasurement
double convertAreaMeasurement(double area, QgsUnitTypes::AreaUnit toUnits) const
Takes an area measurement calculated by this QgsDistanceArea object and converts it to a different ar...
Definition: qgsdistancearea.cpp:992
qgsapplication.h
QgsMapToolIdentify::DefaultQgsSetting
@ DefaultQgsSetting
Definition: qgsmaptoolidentify.h:61
QgsAbstractGeometry::isMeasure
bool isMeasure() const SIP_HOLDGIL
Returns true if the geometry contains m values.
Definition: qgsabstractgeometry.h:228
QgsMapTool
Abstract base class for all map tools. Map tools are user interactive tools for manipulating the map ...
Definition: qgsmaptool.h:70
QgsFeature::embeddedSymbol
const QgsSymbol * embeddedSymbol() const
Returns the feature's embedded symbology, or nullptr if the feature has no embedded symbol.
Definition: qgsfeature.cpp:313
QgsFeatureRequest::setFilterRect
QgsFeatureRequest & setFilterRect(const QgsRectangle &rectangle)
Sets the rectangle from which features will be taken.
Definition: qgsfeaturerequest.cpp:101
QgsGeometry::isGeosEqual
bool isGeosEqual(const QgsGeometry &) const
Compares the geometry with another geometry using GEOS.
Definition: qgsgeometry.cpp:3048
qgsvectortilelayer.h
QgsMapToolIdentify::IdentifyMode
IdentifyMode
Definition: qgsmaptoolidentify.h:59
QgsUnitTypes::fromUnitToUnitFactor
static Q_INVOKABLE double fromUnitToUnitFactor(QgsUnitTypes::DistanceUnit fromUnit, QgsUnitTypes::DistanceUnit toUnit)
Returns the conversion factor between the specified distance units.
Definition: qgsunittypes.cpp:352
QgsFeature::id
QgsFeatureId id
Definition: qgsfeature.h:68
QgsPoint::y
double y
Definition: qgspoint.h:70
QgsDistanceArea::setEllipsoid
bool setEllipsoid(const QString &ellipsoid)
Sets the ellipsoid by its acronym.
Definition: qgsdistancearea.cpp:89
QgsMapLayer::isInScaleRange
bool isInScaleRange(double scale) const
Tests whether the layer should be visible at the specified scale.
Definition: qgsmaplayer.cpp:832
QgsTileRange::endRow
int endRow() const
Returns index of the last row in the range.
Definition: qgstiles.h:87
QgsMapTool::toCanvasCoordinates
QPoint toCanvasCoordinates(const QgsPointXY &point) const
Transforms a point from map coordinates to screen coordinates.
Definition: qgsmaptool.cpp:77
QgsMapTool::layer
QgsMapLayer * layer(const QString &id)
Returns the map layer with the matching ID, or nullptr if no layers could be found.
Definition: qgsmaptool.cpp:84
QgsCoordinateFormatter::separator
static QChar separator()
Returns the character used as X/Y separator, this is a , on locales that do not use ,...
Definition: qgscoordinateformatter.cpp:96
QgsFeatureRequest
This class wraps a request for features to a vector layer (or directly its vector data provider).
Definition: qgsfeaturerequest.h:83
QgsMapLayer::flags
QgsMapLayer::LayerFlags flags() const
Returns the flags for this layer.
Definition: qgsmaplayer.cpp:150
QgsGeometryCollection
Geometry collection.
Definition: qgsgeometrycollection.h:36
QgsMapToolIdentify::derivedAttributesForPoint
QMap< QString, QString > derivedAttributesForPoint(const QgsPoint &point)
Returns derived attributes map for a clicked point in map coordinates. May be 2D or 3D point.
Definition: qgsmaptoolidentify.cpp:525
qgsvectorlayertemporalproperties.h
QgsTileMatrix
Defines a matrix of tiles for a single zoom level: it is defined by its size (width *.
Definition: qgstiles.h:107
QgsMapToolIdentify::identify
QList< QgsMapToolIdentify::IdentifyResult > identify(int x, int y, const QList< QgsMapLayer * > &layerList=QList< QgsMapLayer * >(), IdentifyMode mode=DefaultQgsSetting, const QgsIdentifyContext &identifyContext=QgsIdentifyContext())
Performs the identification.
Definition: qgsmaptoolidentify.cpp:96
qgsgeometryengine.h
QgsVertexId::type
Qgis::VertexType type
Vertex type.
Definition: qgsvertexid.h:98
QgsCsException
Custom exception class for Coordinate Reference System related exceptions.
Definition: qgsexception.h:65
QgsError::message
QString message(QgsErrorMessage::Format format=QgsErrorMessage::Html) const
Full error messages description.
Definition: qgserror.cpp:49
QgsMapToolIdentify::canvasPressEvent
void canvasPressEvent(QgsMapMouseEvent *e) override
Mouse press event for overriding. Default implementation does nothing.
Definition: qgsmaptoolidentify.cpp:86
QgsMapToolIdentify::identifyProgress
void identifyProgress(int, int)
QgsMapLayer::dataProvider
virtual Q_INVOKABLE QgsDataProvider * dataProvider()
Returns the layer's data provider, it may be nullptr.
Definition: qgsmaplayer.cpp:190
QgsRaster::IdentifyFormatValue
@ IdentifyFormatValue
Definition: qgsraster.h:73
QgsAbstractGeometry::wkbType
QgsWkbTypes::Type wkbType() const SIP_HOLDGIL
Returns the WKB type of the geometry.
Definition: qgsabstractgeometry.h:206
qgspointcloudlayer.h
QgsRasterInterface::IdentifyValue
@ IdentifyValue
Numerical values.
Definition: qgsrasterinterface.h:210
QgsMapToolIdentify::changedRasterResults
void changedRasterResults(QList< QgsMapToolIdentify::IdentifyResult > &)
QgsTemporalProperty::isActive
bool isActive() const
Returns true if the temporal property is active.
Definition: qgstemporalproperty.cpp:36
QgsRasterIdentifyResult::results
QMap< int, QVariant > results() const
Returns the identify results.
Definition: qgsrasteridentifyresult.h:80
QgsMapLayerElevationProperties::zScale
double zScale() const
Returns the z scale, which is a scaling factor which should be applied to z values from the layer.
Definition: qgsmaplayerelevationproperties.h:203
geoNone
CONSTLATIN1STRING geoNone()
Constant that holds the string representation for "No ellips/No CRS".
Definition: qgis.h:2738
QgsSymbol::type
Qgis::SymbolType type() const
Returns the symbol's type.
Definition: qgssymbol.h:152
QgsMapLayerType::GroupLayer
@ GroupLayer
Composite group layer. Added in QGIS 3.24.
QgsMapToolIdentify::setCanvasPropertiesOverrides
void setCanvasPropertiesOverrides(double searchRadiusMapUnits)
Overrides some map canvas properties inside the map tool for the upcoming identify requests.
Definition: qgsmaptoolidentify.cpp:193
QgsRasterIdentifyResult
Raster identify results container.
Definition: qgsrasteridentifyresult.h:30
QgsMapToolIdentify::canvasReleaseEvent
void canvasReleaseEvent(QgsMapMouseEvent *e) override
Mouse release event for overriding. Default implementation does nothing.
Definition: qgsmaptoolidentify.cpp:91
qgsvectortilemvtdecoder.h
QgsPointXY::toString
QString toString(int precision=-1) const
Returns a string representation of the point (x, y) with a preset precision.
Definition: qgspointxy.cpp:51
QgsMeshDatasetIndex
QgsMeshDatasetIndex is index that identifies the dataset group (e.g. wind speed) and a dataset in thi...
Definition: qgsmeshdataset.h:48
qgsDoubleNear
bool qgsDoubleNear(double a, double b, double epsilon=4 *std::numeric_limits< double >::epsilon())
Compare two doubles (but allow some difference)
Definition: qgis.h:2265
QgsRenderContext::setCoordinateTransform
void setCoordinateTransform(const QgsCoordinateTransform &t)
Sets the current coordinate transform for the context.
Definition: qgsrendercontext.cpp:320
QgsRasterIdentifyResult::error
QgsError error() const
Returns the last error.
Definition: qgsrasteridentifyresult.h:89
QgsMapLayer::extent
virtual QgsRectangle extent() const
Returns the extent of the layer.
Definition: qgsmaplayer.cpp:305
QgsMeshLayer
Represents a mesh layer supporting display of data on structured or unstructured meshes.
Definition: qgsmeshlayer.h:98
QgsTileMatrix::tileRangeFromExtent
QgsTileRange tileRangeFromExtent(const QgsRectangle &mExtent) const
Returns tile range that fully covers the given extent.
Definition: qgstiles.cpp:97
QgsException::what
QString what() const
Definition: qgsexception.h:48
qgsmaplayer.h
QgsMapLayerType::RasterLayer
@ RasterLayer
Raster layer.
qgsmessageviewer.h
QgsRectangle::contains
bool contains(const QgsRectangle &rect) const SIP_HOLDGIL
Returns true when rectangle contains other rectangle.
Definition: qgsrectangle.h:363
QgsMapToolIdentify::fromPointCloudIdentificationToIdentifyResults
static void fromPointCloudIdentificationToIdentifyResults(QgsPointCloudLayer *layer, const QVector< QVariantMap > &identified, QList< QgsMapToolIdentify::IdentifyResult > &results)
Converts point cloud identification results from variant maps to QgsMapToolIdentify::IdentifyResult a...
Definition: qgsmaptoolidentify.cpp:1213
QgsIdentifyContext
Identify contexts are used to encapsulate the settings to be used to perform an identify action.
Definition: qgsidentifycontext.h:31
QgsVectorLayerTemporalContext::setLayer
void setLayer(QgsVectorLayer *layer)
Sets the associated layer.
Definition: qgsvectorlayertemporalproperties.cpp:704
QgsMapToolIdentify::fromElevationProfileLayerIdentificationToIdentifyResults
void fromElevationProfileLayerIdentificationToIdentifyResults(QgsMapLayer *layer, const QVector< QVariantMap > &identified, QList< QgsMapToolIdentify::IdentifyResult > &results)
Converts elevation profile identification results from variant maps to QgsMapToolIdentify::IdentifyRe...
Definition: qgsmaptoolidentify.cpp:1246
QgsMapLayer::temporalProperties
virtual QgsMapLayerTemporalProperties * temporalProperties()
Returns the layer's temporal properties.
Definition: qgsmaplayer.h:1502
QgsMeshDatasetValue::x
double x() const
Returns x value.
Definition: qgsmeshdataset.cpp:94
QgsMapLayerTemporalProperties::isVisibleInTemporalRange
virtual bool isVisibleInTemporalRange(const QgsDateTimeRange &range) const
Returns true if the layer should be visible and rendered for the specified time range.
Definition: qgsmaplayertemporalproperties.cpp:25
qgsvectordataprovider.h
QgsFeatureList
QList< QgsFeature > QgsFeatureList
Definition: qgsfeature.h:882
QgsMesh::Edge
@ Edge
Definition: qgsmeshdataprovider.h:68
QgsWkbTypes::hasM
static bool hasM(Type type) SIP_HOLDGIL
Tests whether a WKB type contains m values.
Definition: qgswkbtypes.h:1130
QgsRectangle::setXMinimum
void setXMinimum(double x) SIP_HOLDGIL
Set the minimum x value.
Definition: qgsrectangle.h:151
QgsUnitTypes
Helper functions for various unit types.
Definition: qgsunittypes.h:38
QgsMapToolIdentify::identifyVectorLayer
bool identifyVectorLayer(QList< QgsMapToolIdentify::IdentifyResult > *results, QgsVectorLayer *layer, const QgsPointXY &point, const QgsIdentifyContext &identifyContext=QgsIdentifyContext())
Performs the identification against a given vector layer.
Definition: qgsmaptoolidentify.cpp:246
QgsPoint::m
double m
Definition: qgspoint.h:72
QgsDistanceArea::formatDistance
static QString formatDistance(double distance, int decimals, QgsUnitTypes::DistanceUnit unit, bool keepBaseUnit=false)
Returns an distance formatted as a friendly string.
Definition: qgsdistancearea.cpp:968
QgsFeatureRequest::setFilterFids
QgsFeatureRequest & setFilterFids(const QgsFeatureIds &fids)
Sets the feature IDs that should be fetched.
Definition: qgsfeaturerequest.cpp:148
QgsUnitTypes::AreaUnit
AreaUnit
Units of area.
Definition: qgsunittypes.h:93
QgsAbstractGeometry::nCoordinates
virtual int nCoordinates() const
Returns the number of nodes contained in the geometry.
Definition: qgsabstractgeometry.cpp:150
QgsVectorLayerTemporalContext
Encapsulates the context in which a QgsVectorLayer's temporal capabilities will be applied.
Definition: qgsvectorlayertemporalproperties.h:40
QgsFeatureStoreList
QVector< QgsFeatureStore > QgsFeatureStoreList
Definition: qgsfeaturestore.h:119
QgsAbstractGeometry::const_parts_end
const_part_iterator const_parts_end() const
Returns STL-style iterator pointing to the imaginary const part after the last part of the geometry.
Definition: qgsabstractgeometry.cpp:318
qgsrenderer.h
QgsTileRange::endColumn
int endColumn() const
Returns index of the last column in the range.
Definition: qgstiles.h:83
QgsDistanceArea::setSourceCrs
void setSourceCrs(const QgsCoordinateReferenceSystem &crs, const QgsCoordinateTransformContext &context)
Sets source spatial reference system crs.
Definition: qgsdistancearea.cpp:83
QgsRasterLayer
Represents a raster layer.
Definition: qgsrasterlayer.h:76
QgsPointCloudRenderer::stopRender
virtual void stopRender(QgsPointCloudRenderContext &context)
Must be called when a render cycle has finished, to allow the renderer to clean up.
Definition: qgspointcloudrenderer.cpp:115
QgsGeometry::constGet
const QgsAbstractGeometry * constGet() const SIP_HOLDGIL
Returns a non-modifiable (const) reference to the underlying abstract geometry primitive.
Definition: qgsgeometry.cpp:136
QgsFeatureIds
QSet< QgsFeatureId > QgsFeatureIds
Definition: qgsfeatureid.h:37
QgsMapToolIdentify::RasterLayer
@ RasterLayer
Definition: qgsmaptoolidentify.h:72
QgsMapTool::activate
virtual void activate()
called when set as currently active map tool
Definition: qgsmaptool.cpp:94
QgsRectangle::setXMaximum
void setXMaximum(double x) SIP_HOLDGIL
Set the maximum x value.
Definition: qgsrectangle.h:156
QgsMeshDatasetGroupMetadata::name
QString name() const
Returns name of the dataset group.
Definition: qgsmeshdataset.cpp:167
QgsGeometryUtils::closestVertex
static QgsPoint closestVertex(const QgsAbstractGeometry &geom, const QgsPoint &pt, QgsVertexId &id)
Returns the closest vertex to a geometry for a specified point.
Definition: qgsgeometryutils.cpp:67
QgsRaster::IdentifyFormatFeature
@ IdentifyFormatFeature
Definition: qgsraster.h:76
QgsAbstractGeometry
Abstract base class for all geometries.
Definition: qgsabstractgeometry.h:79
qgsgeometryutils.h
QgsAbstractGeometry::is3D
bool is3D() const SIP_HOLDGIL
Returns true if the geometry is 3D and contains a z-value.
Definition: qgsabstractgeometry.h:219
qgsmeshlayer.h
qgsvectorlayer.h
QgsPointXY
A class to represent a 2D point.
Definition: qgspointxy.h:58
QgsRectangle::setYMaximum
void setYMaximum(double y) SIP_HOLDGIL
Set the maximum y value.
Definition: qgsrectangle.h:166
QgsMapToolIdentify::formatChanged
void formatChanged(QgsRasterLayer *layer)
Definition: qgsmaptoolidentify.cpp:1204
QgsGeometry::asPoint
QgsPointXY asPoint() const
Returns the contents of the geometry as a 2-dimensional point.
Definition: qgsgeometry.cpp:1662
QgsRasterDataProvider::identifyFormatToCapability
static Capability identifyFormatToCapability(QgsRaster::IdentifyFormat format)
Definition: qgsrasterdataprovider.cpp:489
QgsMeshDatasetGroupMetadata::isTemporal
bool isTemporal() const
Returns whether the dataset group is temporal (contains time-related dataset)
Definition: qgsmeshdataset.cpp:162
QgsVertexId::isValid
bool isValid() const SIP_HOLDGIL
Returns true if the vertex id is valid.
Definition: qgsvertexid.h:46
QgsTileRange::startRow
int startRow() const
Returns index of the first row in the range.
Definition: qgstiles.h:85
QgsGeometry::createGeometryEngine
static QgsGeometryEngine * createGeometryEngine(const QgsAbstractGeometry *geometry)
Creates and returns a new geometry engine representing the specified geometry.
Definition: qgsgeometry.cpp:3972
QgsMapMouseEvent
A QgsMapMouseEvent is the result of a user interaction with the mouse on a QgsMapCanvas....
Definition: qgsmapmouseevent.h:35
QgsMapLayer::Identifiable
@ Identifiable
If the layer is identifiable using the identify map tool and as a WMS layer.
Definition: qgsmaplayer.h:145
QgsWkbTypes::LineGeometry
@ LineGeometry
Definition: qgswkbtypes.h:143
QgsMapToolIdentify::VectorTileLayer
@ VectorTileLayer
Definition: qgsmaptoolidentify.h:74
QgsMeshDatasetGroupMetadata
QgsMeshDatasetGroupMetadata is a collection of dataset group metadata such as whether the data is vec...
Definition: qgsmeshdataset.h:351
QgsWkbTypes::PointGeometry
@ PointGeometry
Definition: qgswkbtypes.h:142
QgsMeshDatasetGroupMetadata::isScalar
bool isScalar() const
Returns whether dataset group has scalar data.
Definition: qgsmeshdataset.cpp:157
QgsCoordinateReferenceSystem::mapUnits
QgsUnitTypes::DistanceUnit mapUnits
Definition: qgscoordinatereferencesystem.h:215
QgsWkbTypes::NoGeometry
@ NoGeometry
Definition: qgswkbtypes.h:85
QgsMapLayer::customProperty
Q_INVOKABLE QVariant customProperty(const QString &value, const QVariant &defaultValue=QVariant()) const
Read a custom property from layer.
Definition: qgsmaplayer.cpp:1999
qgsgeometry.h
QgsFeatureRenderer
Definition: qgsrenderer.h:101
QgsWkbTypes::GeometryType
GeometryType
The geometry types are used to group QgsWkbTypes::Type in a coarse way.
Definition: qgswkbtypes.h:140
qgstiles.h
QgsFeatureIterator::nextFeature
bool nextFeature(QgsFeature &f)
Definition: qgsfeatureiterator.h:399
QgsRectangle::setYMinimum
void setYMinimum(double y) SIP_HOLDGIL
Set the minimum y value.
Definition: qgsrectangle.h:161
QgsDistanceArea::measurePerimeter
double measurePerimeter(const QgsGeometry &geometry) const
Measures the perimeter of a polygon geometry.
Definition: qgsdistancearea.cpp:226
qgscurve.h
QgsGeometry
A geometry is the spatial representation of a feature.
Definition: qgsgeometry.h:124
str
#define str(x)
Definition: qgis.cpp:37
QgsVectorLayer
Represents a vector layer which manages a vector based data sets.
Definition: qgsvectorlayer.h:391
QgsFeature::hasGeometry
bool hasGeometry() const
Returns true if the feature has an associated geometry.
Definition: qgsfeature.cpp:230
QgsRectangle::width
double width() const SIP_HOLDGIL
Returns the width of the rectangle.
Definition: qgsrectangle.h:223
QgsDistanceArea::convertLengthMeasurement
double convertLengthMeasurement(double length, QgsUnitTypes::DistanceUnit toUnits) const
Takes a length measurement calculated by this QgsDistanceArea object and converts it to a different d...
Definition: qgsdistancearea.cpp:978
QgsMapLayer
Base class for all map layer types. This is the base class for all map layer types (vector,...
Definition: qgsmaplayer.h:72
QgsRasterInterface::IdentifyText
@ IdentifyText
WMS text.
Definition: qgsrasterinterface.h:211
QgsPointXY::x
double x
Definition: qgspointxy.h:62
QgsGeometry::fromRect
static QgsGeometry fromRect(const QgsRectangle &rect) SIP_HOLDGIL
Creates a new geometry from a QgsRectangle.
Definition: qgsgeometry.cpp:241
QgsVertexId
Utility class for identifying a unique vertex within a geometry.
Definition: qgsvertexid.h:30
QgsMeshDatasetValue::y
double y() const
Returns y value.
Definition: qgsmeshdataset.cpp:99
qgssettings.h
QgsErrorMessage::Text
@ Text
Definition: qgserror.h:38
QgsPointCloudRenderer
Abstract base class for 2d point cloud renderers.
Definition: qgspointcloudrenderer.h:296
QgsMapLayerType::VectorTileLayer
@ VectorTileLayer
Vector tile layer. Added in QGIS 3.14.
QgsAbstractGeometry::perimeter
virtual double perimeter() const
Returns the planar, 2-dimensional perimeter of the geometry.
Definition: qgsabstractgeometry.cpp:171
QgsMapLayer::name
QString name
Definition: qgsmaplayer.h:76
QgsMapToolIdentify::identifyMessage
void identifyMessage(const QString &)
QgsVectorTileUtils::makeQgisFields
static QgsFields makeQgisFields(const QSet< QString > &flds)
Returns QgsFields instance based on the set of field names.
Definition: qgsvectortileutils.cpp:51
QgsMapTool::searchRadiusMU
static double searchRadiusMU(const QgsRenderContext &context)
Gets search radius in map units for given context.
Definition: qgsmaptool.cpp:232
QgsRenderContext::setExpressionContext
void setExpressionContext(const QgsExpressionContext &context)
Sets the expression context.
Definition: qgsrendercontext.h:617
QgsGeometry::boundingBox
QgsRectangle boundingBox() const
Returns the bounding box of the geometry.
Definition: qgsgeometry.cpp:1080
QgsWkbTypes::hasZ
static bool hasZ(Type type) SIP_HOLDGIL
Tests whether a WKB type contains the z-dimension.
Definition: qgswkbtypes.h:1080
QgsDistanceArea
A general purpose distance and area calculator, capable of performing ellipsoid based calculations.
Definition: qgsdistancearea.h:52
QgsMapToolIdentify::restoreCanvasPropertiesOverrides
void restoreCanvasPropertiesOverrides()
Clears canvas properties overrides previously set with setCanvasPropertiesOverrides()
Definition: qgsmaptoolidentify.cpp:198
qgsgeometrycollection.h
QgsMapToolIdentify::identifyRasterLayer
bool identifyRasterLayer(QList< QgsMapToolIdentify::IdentifyResult > *results, QgsRasterLayer *layer, QgsPointXY point, const QgsRectangle &viewExtent, double mapUnitsPerPixel, const QgsIdentifyContext &identifyContext=QgsIdentifyContext())
Performs the identification against a given raster layer.
Definition: qgsmaptoolidentify.cpp:951
qgsexception.h
QgsMapToolIdentify::~QgsMapToolIdentify
~QgsMapToolIdentify() override
Definition: qgsmaptoolidentify.cpp:76
QgsMapLayerElevationProperties::zOffset
double zOffset() const
Returns the z offset, which is a fixed offset amount which should be added to z values from the layer...
Definition: qgsmaplayerelevationproperties.h:180
qgsdistancearea.h
QgsFeature
The feature class encapsulates a single feature including its unique ID, geometry and a list of field...
Definition: qgsfeature.h:55
qgspointcloudlayerelevationproperties.h
QgsMeshDatasetGroupMetadata::uri
QString uri() const
Returns the uri of the source.
Definition: qgsmeshdataset.cpp:197
QgsFeatureRequest::EmbeddedSymbols
@ EmbeddedSymbols
Retrieve any embedded feature symbology (since QGIS 3.20)
Definition: qgsfeaturerequest.h:119
QgsMapToolIdentify::mIdentifyMenu
QgsIdentifyMenu * mIdentifyMenu
Definition: qgsmaptoolidentify.h:191
QgsDistanceArea::formatArea
static QString formatArea(double area, int decimals, QgsUnitTypes::AreaUnit unit, bool keepBaseUnit=false)
Returns an area formatted as a friendly string.
Definition: qgsdistancearea.cpp:973
QgsVectorTileFeatures
QMap< QString, QVector< QgsFeature > > QgsVectorTileFeatures
Features of a vector tile, grouped by sub-layer names (key of the map)
Definition: qgsvectortilerenderer.h:27
QgsSettings::enumValue
T enumValue(const QString &key, const T &defaultValue, const Section section=NoSection)
Returns the setting value for a setting based on an enum.
Definition: qgssettings.h:282
QgsMapLayer::isSpatial
virtual bool isSpatial() const
Returns true if the layer is considered a spatial layer, ie it has some form of geometry associated w...
Definition: qgsmaplayer.cpp:2031
QgsMapToolIdentify::IdentifyResult::mParams
QMap< QString, QVariant > mParams
Definition: qgsmaptoolidentify.h:101
qgslogger.h
QgsAbstractGeometry::const_parts_begin
const_part_iterator const_parts_begin() const
Returns STL-style iterator pointing to the const first part of the geometry.
Definition: qgsabstractgeometry.h:904
QgsMeshDatasetGroupMetadata::isVector
bool isVector() const
Returns whether dataset group has vector data.
Definition: qgsmeshdataset.cpp:152
qgsvectortileutils.h
qgspointcloudlayerrenderer.h
qgsfeaturestore.h
QgsIdentifyMenu
The QgsIdentifyMenu class builds a menu to be used with identify results (.
Definition: qgsidentifymenu.h:49
qgscoordinateformatter.h
QgsWkbTypes::isMultiType
static bool isMultiType(Type type) SIP_HOLDGIL
Returns true if the WKB type is a multi type.
Definition: qgswkbtypes.h:862
QgsCoordinateTransform
Class for doing transforms between two map coordinate systems.
Definition: qgscoordinatetransform.h:57
QgsMeshDatasetValue::scalar
double scalar() const
Returns magnitude of vector for vector data or scalar value for scalar data.
Definition: qgsmeshdataset.cpp:63
QgsGeometry::type
QgsWkbTypes::GeometryType type
Definition: qgsgeometry.h:128
QgsFeatureIterator
Wrapper for iterator of features from vector data provider or vector layer.
Definition: qgsfeatureiterator.h:289
QgsMapLayerType::PointCloudLayer
@ PointCloudLayer
Point cloud layer. Added in QGIS 3.18.
QgsPointCloudDataProvider::translatedLasClassificationCodes
static QMap< int, QString > translatedLasClassificationCodes()
Returns the map of LAS classification code to translated string value, corresponding to the ASPRS Sta...
Definition: qgspointclouddataprovider.cpp:105
qgspointcloudrenderer.h
QgsWkbTypes::singleType
static Type singleType(Type type) SIP_HOLDGIL
Returns the single type for a WKB type.
Definition: qgswkbtypes.h:157
QgsGeometry::area
double area() const
Returns the planar, 2-dimensional area of the geometry.
Definition: qgsgeometry.cpp:1880
QgsRaster::IdentifyFormat
IdentifyFormat
Definition: qgsraster.h:70
QgsProject::ellipsoid
QString ellipsoid
Definition: qgsproject.h:111
qgscoordinatereferencesystem.h
QgsFeatureRequest::setFlags
QgsFeatureRequest & setFlags(QgsFeatureRequest::Flags flags)
Sets flags that affect how features will be fetched.
Definition: qgsfeaturerequest.cpp:222
qgssymbol.h
QgsPoint::x
double x
Definition: qgspoint.h:69
qgsproject.h
QgsMapToolIdentify::canvasMoveEvent
void canvasMoveEvent(QgsMapMouseEvent *e) override
Mouse move event for overriding. Default implementation does nothing.
Definition: qgsmaptoolidentify.cpp:81
QgsMapLayerType::PluginLayer
@ PluginLayer
Plugin based layer.
QgsMapLayer::elevationProperties
virtual QgsMapLayerElevationProperties * elevationProperties()
Returns the layer's elevation properties.
Definition: qgsmaplayer.h:1509
QgsTemporaryCursorOverride
Temporarily sets a cursor override for the QApplication for the lifetime of the object.
Definition: qgsguiutils.h:220
QgsGeometry::wkbType
QgsWkbTypes::Type wkbType() const SIP_HOLDGIL
Returns type of the geometry as a WKB type (point / linestring / polygon etc.)
Definition: qgsgeometry.cpp:357
qgsmeshlayertemporalproperties.h
QgsMapTool::toMapCoordinates
QgsPointXY toMapCoordinates(QPoint point)
Transforms a point from screen coordinates to map coordinates.
Definition: qgsmaptool.cpp:41
qgsmultilinestring.h
QgsTileRange::startColumn
int startColumn() const
Returns index of the first column in the range.
Definition: qgstiles.h:81
qgsrasterdataprovider.h
QgsFeatureId
qint64 QgsFeatureId
64 bit feature ids negative numbers are used for uncommitted/newly added features
Definition: qgsfeatureid.h:28
QgsExpressionContext::setFeature
void setFeature(const QgsFeature &feature)
Convenience function for setting a feature for the context.
Definition: qgsexpressioncontext.cpp:525
QgsMapToolIdentify::IdentifyResult
Definition: qgsmaptoolidentify.h:81
QgsMesh::Vertex
@ Vertex
Definition: qgsmeshdataprovider.h:67
QgsMapLayer::type
QgsMapLayerType type
Definition: qgsmaplayer.h:80