QGIS API Documentation  3.16.0-Hannover (43b64b13f3)
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 "qgsdistancearea.h"
18 #include "qgsfeature.h"
19 #include "qgsfeatureiterator.h"
20 #include "qgsfeaturestore.h"
21 #include "qgsfields.h"
22 #include "qgsgeometry.h"
23 #include "qgsgeometryengine.h"
24 #include "qgsidentifymenu.h"
25 #include "qgslogger.h"
26 #include "qgsmapcanvas.h"
27 #include "qgsmaptoolidentify.h"
28 #include "qgsmaptopixel.h"
29 #include "qgsmessageviewer.h"
30 #include "qgsmeshlayer.h"
32 #include "qgsmaplayer.h"
33 #include "qgsrasterdataprovider.h"
34 #include "qgsrasterlayer.h"
37 #include "qgsvectordataprovider.h"
38 #include "qgsvectorlayer.h"
39 #include "qgsvectortilelayer.h"
41 #include "qgsvectortileutils.h"
42 #include "qgsproject.h"
43 #include "qgsrenderer.h"
44 #include "qgstiles.h"
45 #include "qgsgeometryutils.h"
46 #include "qgsgeometrycollection.h"
47 #include "qgscurve.h"
48 #include "qgscoordinateutils.h"
49 #include "qgsexception.h"
50 #include "qgssettings.h"
52 
53 #include <QMouseEvent>
54 #include <QCursor>
55 #include <QPixmap>
56 #include <QStatusBar>
57 #include <QVariant>
58 #include <QMenu>
59 
61  : QgsMapTool( canvas )
62  , mIdentifyMenu( new QgsIdentifyMenu( mCanvas ) )
63  , mLastMapUnitsPerPixel( -1.0 )
64  , mCoordinatePrecision( 6 )
65 {
66  setCursor( QgsApplication::getThemeCursor( QgsApplication::Cursor::Identify ) );
67 }
68 
70 {
71  delete mIdentifyMenu;
72 }
73 
75 {
76  Q_UNUSED( e )
77 }
78 
80 {
81  Q_UNUSED( e )
82 }
83 
85 {
86  Q_UNUSED( e )
87 }
88 
89 QList<QgsMapToolIdentify::IdentifyResult> QgsMapToolIdentify::identify( int x, int y, const QList<QgsMapLayer *> &layerList, IdentifyMode mode )
90 {
91  return identify( x, y, mode, layerList, AllLayers );
92 }
93 
94 QList<QgsMapToolIdentify::IdentifyResult> QgsMapToolIdentify::identify( int x, int y, IdentifyMode mode, LayerType layerType )
95 {
96  return identify( x, y, mode, QList<QgsMapLayer *>(), layerType );
97 }
98 
99 QList<QgsMapToolIdentify::IdentifyResult> QgsMapToolIdentify::identify( int x, int y, IdentifyMode mode, const QList<QgsMapLayer *> &layerList, LayerType layerType )
100 {
101  return identify( QgsGeometry::fromPointXY( toMapCoordinates( QPoint( x, y ) ) ), mode, layerList, layerType );
102 }
103 
104 QList<QgsMapToolIdentify::IdentifyResult> QgsMapToolIdentify::identify( const QgsGeometry &geometry, IdentifyMode mode, LayerType layerType )
105 {
106  return identify( geometry, mode, QList<QgsMapLayer *>(), layerType );
107 }
108 
109 QList<QgsMapToolIdentify::IdentifyResult> QgsMapToolIdentify::identify( const QgsGeometry &geometry, IdentifyMode mode, const QList<QgsMapLayer *> &layerList, LayerType layerType )
110 {
111  QList<IdentifyResult> results;
112 
113  mLastGeometry = geometry;
114  mLastExtent = mCanvas->extent();
115  mLastMapUnitsPerPixel = mCanvas->mapUnitsPerPixel();
116 
117  mCoordinatePrecision = QgsCoordinateUtils::calculateCoordinatePrecision( mLastMapUnitsPerPixel, mCanvas->mapSettings().destinationCrs() );
118 
119  if ( mode == DefaultQgsSetting )
120  {
121  QgsSettings settings;
122  mode = settings.enumValue( QStringLiteral( "Map/identifyMode" ), ActiveLayer );
123  }
124 
125  if ( mode == LayerSelection )
126  {
127  QPoint canvasPt = toCanvasCoordinates( geometry.asPoint() );
128  int x = canvasPt.x(), y = canvasPt.y();
129  QList<IdentifyResult> results = identify( x, y, TopDownAll, layerList, layerType );
130  QPoint globalPos = mCanvas->mapToGlobal( QPoint( x + 5, y + 5 ) );
131  return mIdentifyMenu->exec( results, globalPos );
132  }
133  else if ( mode == ActiveLayer && layerList.isEmpty() )
134  {
135  QgsMapLayer *layer = mCanvas->currentLayer();
136 
137  if ( !layer )
138  {
139  emit identifyMessage( tr( "No active layer. To identify features, you must choose an active layer." ) );
140  return results;
141  }
142 
143  QApplication::setOverrideCursor( Qt::WaitCursor );
144 
145  identifyLayer( &results, layer, mLastGeometry, mLastExtent, mLastMapUnitsPerPixel, layerType );
146  }
147  else
148  {
149  QApplication::setOverrideCursor( Qt::WaitCursor );
150 
151  int layerCount;
152  if ( layerList.isEmpty() )
153  layerCount = mCanvas->layerCount();
154  else
155  layerCount = layerList.count();
156 
157 
158  for ( int i = 0; i < layerCount; i++ )
159  {
160 
161  QgsMapLayer *layer = nullptr;
162  if ( layerList.isEmpty() )
163  layer = mCanvas->layer( i );
164  else
165  layer = layerList.value( i );
166 
167  emit identifyProgress( i, mCanvas->layerCount() );
168  emit identifyMessage( tr( "Identifying on %1…" ).arg( layer->name() ) );
169 
170  if ( !layer->flags().testFlag( QgsMapLayer::Identifiable ) )
171  continue;
172 
173  if ( identifyLayer( &results, layer, mLastGeometry, mLastExtent, mLastMapUnitsPerPixel, layerType ) )
174  {
175  if ( mode == TopDownStopAtFirst )
176  break;
177  }
178  }
179 
181  emit identifyMessage( tr( "Identifying done." ) );
182  }
183 
184  QApplication::restoreOverrideCursor();
185 
186  return results;
187 }
188 
189 void QgsMapToolIdentify::setCanvasPropertiesOverrides( double searchRadiusMapUnits )
190 {
191  mOverrideCanvasSearchRadius = searchRadiusMapUnits;
192 }
193 
195 {
196  mOverrideCanvasSearchRadius = -1;
197 }
198 
200 {
202 }
203 
205 {
207 }
208 
209 bool QgsMapToolIdentify::identifyLayer( QList<IdentifyResult> *results, QgsMapLayer *layer, const QgsPointXY &point, const QgsRectangle &viewExtent, double mapUnitsPerPixel, QgsMapToolIdentify::LayerType layerType )
210 {
211  return identifyLayer( results, layer, QgsGeometry::fromPointXY( point ), viewExtent, mapUnitsPerPixel, layerType );
212 }
213 
214 bool QgsMapToolIdentify::identifyLayer( QList<IdentifyResult> *results, QgsMapLayer *layer, const QgsGeometry &geometry, const QgsRectangle &viewExtent, double mapUnitsPerPixel, QgsMapToolIdentify::LayerType layerType )
215 {
216  if ( layer->type() == QgsMapLayerType::RasterLayer && layerType.testFlag( RasterLayer ) )
217  {
218  return identifyRasterLayer( results, qobject_cast<QgsRasterLayer *>( layer ), geometry, viewExtent, mapUnitsPerPixel );
219  }
220  else if ( layer->type() == QgsMapLayerType::VectorLayer && layerType.testFlag( VectorLayer ) )
221  {
222  return identifyVectorLayer( results, qobject_cast<QgsVectorLayer *>( layer ), geometry );
223  }
224  else if ( layer->type() == QgsMapLayerType::MeshLayer && layerType.testFlag( MeshLayer ) )
225  {
226  return identifyMeshLayer( results, qobject_cast<QgsMeshLayer *>( layer ), geometry );
227  }
228  else if ( layer->type() == QgsMapLayerType::VectorTileLayer && layerType.testFlag( VectorTileLayer ) )
229  {
230  return identifyVectorTileLayer( results, qobject_cast<QgsVectorTileLayer *>( layer ), geometry );
231  }
232  else
233  {
234  return false;
235  }
236 }
237 
238 bool QgsMapToolIdentify::identifyVectorLayer( QList<QgsMapToolIdentify::IdentifyResult> *results, QgsVectorLayer *layer, const QgsPointXY &point )
239 {
240  return identifyVectorLayer( results, layer, QgsGeometry::fromPointXY( point ) );
241 }
242 
243 bool QgsMapToolIdentify::identifyMeshLayer( QList<QgsMapToolIdentify::IdentifyResult> *results, QgsMeshLayer *layer, const QgsGeometry &geometry )
244 {
245  const QgsPointXY point = geometry.asPoint(); // mesh layers currently only support identification by point
246  return identifyMeshLayer( results, layer, point );
247 }
248 
249 bool QgsMapToolIdentify::identifyMeshLayer( QList<QgsMapToolIdentify::IdentifyResult> *results, QgsMeshLayer *layer, const QgsPointXY &point )
250 {
251  QgsDebugMsgLevel( "point = " + point.toString(), 4 );
252  if ( !layer )
253  return false;
254 
255  double searchRadius = mOverrideCanvasSearchRadius < 0 ? searchRadiusMU( mCanvas ) : mOverrideCanvasSearchRadius;
256  bool isTemporal = mCanvas->mapSettings().isTemporal() && layer->temporalProperties()->isActive();
257 
258  QList<QgsMeshDatasetIndex> datasetIndexList;
259  int activeScalarGroup = layer->rendererSettings().activeScalarDatasetGroup();
260  int activeVectorGroup = layer->rendererSettings().activeVectorDatasetGroup();
261 
262  if ( isTemporal ) //non active dataset group value are only accesible if temporal is active
263  {
264  const QgsDateTimeRange &time = mCanvas->mapSettings().temporalRange();
265  if ( activeScalarGroup >= 0 )
266  datasetIndexList.append( layer->activeScalarDatasetAtTime( time ) );
267  if ( activeVectorGroup >= 0 && activeVectorGroup != activeScalarGroup )
268  datasetIndexList.append( layer->activeVectorDatasetAtTime( time ) );
269 
270  const QList<int> allGroup = layer->datasetGroupsIndexes();
271  for ( int groupIndex : allGroup )
272  {
273  if ( groupIndex != activeScalarGroup && groupIndex != activeVectorGroup )
274  datasetIndexList.append( layer->datasetIndexAtTime( time, groupIndex ) );
275  }
276  }
277  else
278  {
279  if ( activeScalarGroup >= 0 )
280  datasetIndexList.append( layer->staticScalarDatasetIndex() );
281  if ( activeVectorGroup >= 0 && activeVectorGroup != activeScalarGroup )
282  datasetIndexList.append( layer->staticVectorDatasetIndex() );
283  }
284 
285  //create results
286  for ( const QgsMeshDatasetIndex &index : datasetIndexList )
287  {
288  if ( !index.isValid() )
289  continue;
290 
291  const QgsMeshDatasetGroupMetadata &groupMeta = layer->datasetGroupMetadata( index );
292  QMap< QString, QString > derivedAttributes;
293 
294  QMap<QString, QString> attribute;
295  if ( groupMeta.isScalar() )
296  {
297  const QgsMeshDatasetValue scalarValue = layer->datasetValue( index, point, searchRadius );
298  const double scalar = scalarValue.scalar();
299  attribute.insert( tr( "Scalar Value" ), std::isnan( scalar ) ? tr( "no data" ) : QString::number( scalar ) );
300  }
301 
302  if ( groupMeta.isVector() )
303  {
304  const QgsMeshDatasetValue vectorValue = layer->datasetValue( index, point, searchRadius );
305  const double vectorX = vectorValue.x();
306  const double vectorY = vectorValue.y();
307  if ( std::isnan( vectorX ) || std::isnan( vectorY ) )
308  attribute.insert( tr( "Vector Value" ), tr( "no data" ) );
309  else
310  {
311  attribute.insert( tr( "Vector Magnitude" ), QString::number( vectorValue.scalar() ) );
312  derivedAttributes.insert( tr( "Vector x-component" ), QString::number( vectorY ) );
313  derivedAttributes.insert( tr( "Vector y-component" ), QString::number( vectorX ) );
314  }
315  }
316 
317  const QgsMeshDatasetMetadata &meta = layer->datasetMetadata( index );
318 
319  if ( groupMeta.isTemporal() )
320  derivedAttributes.insert( tr( "Time Step" ), layer->formatTime( meta.time() ) );
321  derivedAttributes.insert( tr( "Source" ), groupMeta.uri() );
322 
323  QString resultName = groupMeta.name();
324  if ( isTemporal && ( index.group() == activeScalarGroup || index.group() == activeVectorGroup ) )
325  resultName.append( tr( " (active)" ) );
326 
327  const IdentifyResult result( qobject_cast<QgsMapLayer *>( layer ),
328  resultName,
329  attribute,
330  derivedAttributes );
331 
332  results->append( result );
333  }
334 
335  QMap<QString, QString> derivedGeometry;
336 
337  QgsPointXY vertexPoint = layer->snapOnElement( QgsMesh::Vertex, point, searchRadius );
338  if ( !vertexPoint.isEmpty() )
339  {
340  derivedGeometry.insert( tr( "Snapped Vertex Position X" ), QString::number( vertexPoint.x() ) );
341  derivedGeometry.insert( tr( "Snapped Vertex Position Y" ), QString::number( vertexPoint.y() ) );
342  }
343 
344  QgsPointXY faceCentroid = layer->snapOnElement( QgsMesh::Face, point, searchRadius );
345  if ( !faceCentroid.isEmpty() )
346  {
347  derivedGeometry.insert( tr( "Face Centroid X" ), QString::number( faceCentroid.x() ) );
348  derivedGeometry.insert( tr( "Face Centroid Y" ), QString::number( faceCentroid.y() ) );
349  }
350 
351  QgsPointXY pointOnEdge = layer->snapOnElement( QgsMesh::Edge, point, searchRadius );
352  if ( !pointOnEdge.isEmpty() )
353  {
354  derivedGeometry.insert( tr( "Point on Edge X" ), QString::number( pointOnEdge.x() ) );
355  derivedGeometry.insert( tr( "Point on Edge Y" ), QString::number( pointOnEdge.y() ) );
356  }
357 
358  const IdentifyResult result( qobject_cast<QgsMapLayer *>( layer ),
359  tr( "Geometry" ),
361  derivedGeometry );
362 
363  results->append( result );
364 
365  return true;
366 }
367 
368 bool QgsMapToolIdentify::identifyVectorTileLayer( QList<QgsMapToolIdentify::IdentifyResult> *results, QgsVectorTileLayer *layer, const QgsGeometry &geometry )
369 {
370  if ( !layer || !layer->isSpatial() )
371  return false;
372 
373  if ( !layer->isInScaleRange( mCanvas->mapSettings().scale() ) )
374  {
375  QgsDebugMsgLevel( QStringLiteral( "Out of scale limits" ), 2 );
376  return false;
377  }
378 
379  QgsTemporaryCursorOverride waitCursor( Qt::WaitCursor );
380 
381  QMap< QString, QString > commonDerivedAttributes;
382 
383  QgsGeometry selectionGeom = geometry;
384  bool isPointOrRectangle;
385  QgsPointXY point;
386  bool isSingleClick = selectionGeom.type() == QgsWkbTypes::PointGeometry;
387  if ( isSingleClick )
388  {
389  isPointOrRectangle = true;
390  point = selectionGeom.asPoint();
391 
392  commonDerivedAttributes = derivedAttributesForPoint( QgsPoint( point ) );
393  }
394  else
395  {
396  // we have a polygon - maybe it is a rectangle - in such case we can avoid costly insterestion tests later
397  isPointOrRectangle = QgsGeometry::fromRect( selectionGeom.boundingBox() ).isGeosEqual( selectionGeom );
398  }
399 
400  int featureCount = 0;
401 
402  QgsFeatureList featureList;
403  std::unique_ptr<QgsGeometryEngine> selectionGeomPrepared;
404 
405  // toLayerCoordinates will throw an exception for an 'invalid' point.
406  // For example, if you project a world map onto a globe using EPSG 2163
407  // and then click somewhere off the globe, an exception will be thrown.
408  try
409  {
410  QgsRectangle r;
411  if ( isSingleClick )
412  {
413  double sr = mOverrideCanvasSearchRadius < 0 ? searchRadiusMU( mCanvas ) : mOverrideCanvasSearchRadius;
414  r = toLayerCoordinates( layer, QgsRectangle( point.x() - sr, point.y() - sr, point.x() + sr, point.y() + sr ) );
415  }
416  else
417  {
418  r = toLayerCoordinates( layer, selectionGeom.boundingBox() );
419 
420  if ( !isPointOrRectangle )
421  {
423  if ( ct.isValid() )
424  selectionGeom.transform( ct );
425 
426  // use prepared geometry for faster intersection test
427  selectionGeomPrepared.reset( QgsGeometry::createGeometryEngine( selectionGeom.constGet() ) );
428  }
429  }
430 
431  int tileZoom = QgsVectorTileUtils::scaleToZoomLevel( mCanvas->scale(), layer->sourceMinZoom(), layer->sourceMaxZoom() );
432  QgsTileMatrix tileMatrix = QgsTileMatrix::fromWebMercator( tileZoom );
433  QgsTileRange tileRange = tileMatrix.tileRangeFromExtent( r );
434 
435  for ( int row = tileRange.startRow(); row <= tileRange.endRow(); ++row )
436  {
437  for ( int col = tileRange.startColumn(); col <= tileRange.endColumn(); ++col )
438  {
439  QgsTileXYZ tileID( col, row, tileZoom );
440  QByteArray data = layer->getRawTile( tileID );
441  if ( data.isEmpty() )
442  continue; // failed to get data
443 
444  QgsVectorTileMVTDecoder decoder;
445  if ( !decoder.decode( tileID, data ) )
446  continue; // failed to decode
447 
448  QMap<QString, QgsFields> perLayerFields;
449  const QStringList layerNames = decoder.layers();
450  for ( const QString &layerName : layerNames )
451  {
452  QSet<QString> fieldNames = qgis::listToSet( decoder.layerFieldNames( layerName ) );
453  perLayerFields[layerName] = QgsVectorTileUtils::makeQgisFields( fieldNames );
454  }
455 
456  const QgsVectorTileFeatures features = decoder.layerFeatures( perLayerFields, QgsCoordinateTransform() );
457  const QStringList featuresLayerNames = features.keys();
458  for ( const QString &layerName : featuresLayerNames )
459  {
460  const QgsFields fFields = perLayerFields[layerName];
461  const QVector<QgsFeature> &layerFeatures = features[layerName];
462  for ( const QgsFeature &f : layerFeatures )
463  {
464  if ( f.geometry().intersects( r ) && ( !selectionGeomPrepared || selectionGeomPrepared->intersects( f.geometry().constGet() ) ) )
465  {
466  QMap< QString, QString > derivedAttributes = commonDerivedAttributes;
467  derivedAttributes.insert( tr( "Feature ID" ), FID_TO_STRING( f.id() ) );
468 
469  results->append( IdentifyResult( qobject_cast<QgsMapLayer *>( layer ), layerName, fFields, f, derivedAttributes ) );
470 
471  featureCount++;
472  }
473  }
474  }
475  }
476  }
477 
478  }
479  catch ( QgsCsException &cse )
480  {
481  Q_UNUSED( cse )
482  // catch exception for 'invalid' point and proceed with no features found
483  QgsDebugMsg( QStringLiteral( "Caught CRS exception %1" ).arg( cse.what() ) );
484  }
485 
486  return featureCount > 0;
487 }
488 
489 QMap<QString, QString> QgsMapToolIdentify::derivedAttributesForPoint( const QgsPoint &point )
490 {
491  QMap< QString, QString > derivedAttributes;
492  derivedAttributes.insert( tr( "(clicked coordinate X)" ), formatXCoordinate( point ) );
493  derivedAttributes.insert( tr( "(clicked coordinate Y)" ), formatYCoordinate( point ) );
494  if ( point.is3D() )
495  derivedAttributes.insert( tr( "(clicked coordinate Z)" ), QString::number( point.z(), 'f' ) );
496  return derivedAttributes;
497 }
498 
499 bool QgsMapToolIdentify::identifyVectorLayer( QList<QgsMapToolIdentify::IdentifyResult> *results, QgsVectorLayer *layer, const QgsGeometry &geometry )
500 {
501  if ( !layer || !layer->isSpatial() )
502  return false;
503 
504  if ( !layer->isInScaleRange( mCanvas->mapSettings().scale() ) )
505  {
506  QgsDebugMsg( QStringLiteral( "Out of scale limits" ) );
507  return false;
508  }
509 
510  QApplication::setOverrideCursor( Qt::WaitCursor );
511 
512  QMap< QString, QString > commonDerivedAttributes;
513 
514  QgsGeometry selectionGeom = geometry;
515  bool isPointOrRectangle;
516  QgsPointXY point;
517  bool isSingleClick = selectionGeom.type() == QgsWkbTypes::PointGeometry;
518  if ( isSingleClick )
519  {
520  isPointOrRectangle = true;
521  point = selectionGeom.asPoint();
522 
523  commonDerivedAttributes = derivedAttributesForPoint( QgsPoint( point ) );
524  }
525  else
526  {
527  // we have a polygon - maybe it is a rectangle - in such case we can avoid costly insterestion tests later
528  isPointOrRectangle = QgsGeometry::fromRect( selectionGeom.boundingBox() ).isGeosEqual( selectionGeom );
529  }
530 
531  int featureCount = 0;
532 
533  QgsFeatureList featureList;
534  std::unique_ptr<QgsGeometryEngine> selectionGeomPrepared;
535 
536  // toLayerCoordinates will throw an exception for an 'invalid' point.
537  // For example, if you project a world map onto a globe using EPSG 2163
538  // and then click somewhere off the globe, an exception will be thrown.
539  try
540  {
541  QgsRectangle r;
542  if ( isSingleClick )
543  {
544  double sr = mOverrideCanvasSearchRadius < 0 ? searchRadiusMU( mCanvas ) : mOverrideCanvasSearchRadius;
545  r = toLayerCoordinates( layer, QgsRectangle( point.x() - sr, point.y() - sr, point.x() + sr, point.y() + sr ) );
546  }
547  else
548  {
549  r = toLayerCoordinates( layer, selectionGeom.boundingBox() );
550 
551  if ( !isPointOrRectangle )
552  {
554  if ( ct.isValid() )
555  selectionGeom.transform( ct );
556 
557  // use prepared geometry for faster intersection test
558  selectionGeomPrepared.reset( QgsGeometry::createGeometryEngine( selectionGeom.constGet() ) );
559  }
560  }
561 
562  QgsFeatureIterator fit = layer->getFeatures( QgsFeatureRequest().setFilterRect( r ).setFlags( QgsFeatureRequest::ExactIntersect ) );
563  QgsFeature f;
564  while ( fit.nextFeature( f ) )
565  {
566  if ( !selectionGeomPrepared || selectionGeomPrepared->intersects( f.geometry().constGet() ) )
567  featureList << QgsFeature( f );
568  }
569  }
570  catch ( QgsCsException &cse )
571  {
572  Q_UNUSED( cse )
573  // catch exception for 'invalid' point and proceed with no features found
574  QgsDebugMsg( QStringLiteral( "Caught CRS exception %1" ).arg( cse.what() ) );
575  }
576 
577  bool filter = false;
578 
580  context.expressionContext() << QgsExpressionContextUtils::layerScope( layer );
581  std::unique_ptr< QgsFeatureRenderer > renderer( layer->renderer() ? layer->renderer()->clone() : nullptr );
582  if ( renderer )
583  {
584  // setup scale for scale dependent visibility (rule based)
585  renderer->startRender( context, layer->fields() );
586  filter = renderer->capabilities() & QgsFeatureRenderer::Filter;
587  }
588 
589  for ( const QgsFeature &feature : qgis::as_const( featureList ) )
590  {
591  QMap< QString, QString > derivedAttributes = commonDerivedAttributes;
592 
593  QgsFeatureId fid = feature.id();
594  context.expressionContext().setFeature( feature );
595 
596  if ( filter && !renderer->willRenderFeature( feature, context ) )
597  continue;
598 
599  featureCount++;
600 
601  if ( isSingleClick )
602  derivedAttributes.unite( featureDerivedAttributes( feature, layer, toLayerCoordinates( layer, point ) ) );
603 
604  derivedAttributes.insert( tr( "Feature ID" ), fid < 0 ? tr( "new feature" ) : FID_TO_STRING( fid ) );
605 
606  results->append( IdentifyResult( qobject_cast<QgsMapLayer *>( layer ), feature, derivedAttributes ) );
607  }
608 
609  if ( renderer )
610  {
611  renderer->stopRender( context );
612  }
613 
614  QgsDebugMsgLevel( "Feature count on identify: " + QString::number( featureCount ), 2 );
615 
616  QApplication::restoreOverrideCursor();
617  return featureCount > 0;
618 }
619 
620 void QgsMapToolIdentify::closestVertexAttributes( const QgsAbstractGeometry &geometry, QgsVertexId vId, QgsMapLayer *layer, QMap< QString, QString > &derivedAttributes )
621 {
622  if ( ! vId.isValid( ) )
623  {
624  // We should not get here ...
625  QgsDebugMsg( "Invalid vertex id!" );
626  return;
627  }
628 
629  QString str = QLocale().toString( vId.vertex + 1 );
630  derivedAttributes.insert( tr( "Closest vertex number" ), str );
631 
632  QgsPoint closestPoint = geometry.vertexAt( vId );
633 
634  QgsPointXY closestPointMapCoords = mCanvas->mapSettings().layerToMapCoordinates( layer, QgsPointXY( closestPoint.x(), closestPoint.y() ) );
635  derivedAttributes.insert( tr( "Closest vertex X" ), formatXCoordinate( closestPointMapCoords ) );
636  derivedAttributes.insert( tr( "Closest vertex Y" ), formatYCoordinate( closestPointMapCoords ) );
637 
638  if ( closestPoint.is3D() )
639  {
640  str = QLocale().toString( closestPoint.z(), 'g', 10 );
641  derivedAttributes.insert( tr( "Closest vertex Z" ), str );
642  }
643  if ( closestPoint.isMeasure() )
644  {
645  str = QLocale().toString( closestPoint.m(), 'g', 10 );
646  derivedAttributes.insert( tr( "Closest vertex M" ), str );
647  }
648 
649  if ( vId.type == QgsVertexId::CurveVertex )
650  {
651  double radius, centerX, centerY;
652  QgsVertexId vIdBefore = vId;
653  --vIdBefore.vertex;
654  QgsVertexId vIdAfter = vId;
655  ++vIdAfter.vertex;
656  QgsGeometryUtils::circleCenterRadius( geometry.vertexAt( vIdBefore ), geometry.vertexAt( vId ),
657  geometry.vertexAt( vIdAfter ), radius, centerX, centerY );
658  derivedAttributes.insert( QStringLiteral( "Closest vertex radius" ), QLocale().toString( radius ) );
659  }
660 }
661 
662 void QgsMapToolIdentify::closestPointAttributes( const QgsAbstractGeometry &geometry, const QgsPointXY &layerPoint, QMap<QString, QString> &derivedAttributes )
663 {
664  QgsPoint closestPoint = QgsGeometryUtils::closestPoint( geometry, QgsPoint( layerPoint ) );
665 
666  derivedAttributes.insert( tr( "Closest X" ), formatXCoordinate( closestPoint ) );
667  derivedAttributes.insert( tr( "Closest Y" ), formatYCoordinate( closestPoint ) );
668 
669  if ( closestPoint.is3D() )
670  {
671  const QString str = QLocale().toString( closestPoint.z(), 'g', 10 );
672  derivedAttributes.insert( tr( "Interpolated Z" ), str );
673  }
674  if ( closestPoint.isMeasure() )
675  {
676  const QString str = QLocale().toString( closestPoint.m(), 'g', 10 );
677  derivedAttributes.insert( tr( "Interpolated M" ), str );
678  }
679 }
680 
681 QString QgsMapToolIdentify::formatCoordinate( const QgsPointXY &canvasPoint ) const
682 {
683  return QgsCoordinateUtils::formatCoordinateForProject( QgsProject::instance(), canvasPoint, mCanvas->mapSettings().destinationCrs(),
684  mCoordinatePrecision );
685 }
686 
687 QString QgsMapToolIdentify::formatXCoordinate( const QgsPointXY &canvasPoint ) const
688 {
689  QString coordinate = formatCoordinate( canvasPoint );
690  return coordinate.split( ',' ).at( 0 );
691 }
692 
693 QString QgsMapToolIdentify::formatYCoordinate( const QgsPointXY &canvasPoint ) const
694 {
695  QString coordinate = formatCoordinate( canvasPoint );
696  return coordinate.split( ',' ).at( 1 );
697 }
698 
699 QMap< QString, QString > QgsMapToolIdentify::featureDerivedAttributes( const QgsFeature &feature, QgsMapLayer *layer, const QgsPointXY &layerPoint )
700 {
701  // Calculate derived attributes and insert:
702  // measure distance or area depending on geometry type
703  QMap< QString, QString > derivedAttributes;
704 
705  // init distance/area calculator
706  QString ellipsoid = QgsProject::instance()->ellipsoid();
707  QgsDistanceArea calc;
708  calc.setEllipsoid( ellipsoid );
709  calc.setSourceCrs( layer->crs(), QgsProject::instance()->transformContext() );
710 
713 
714  QgsVertexId vId;
715  QgsPoint closestPoint;
716  if ( feature.hasGeometry() )
717  {
718  geometryType = feature.geometry().type();
719  wkbType = feature.geometry().wkbType();
720  //find closest vertex to clicked point
721  closestPoint = QgsGeometryUtils::closestVertex( *feature.geometry().constGet(), QgsPoint( layerPoint ), vId );
722  }
723 
724 
725 
726  if ( QgsWkbTypes::isMultiType( wkbType ) )
727  {
728  QString str = QLocale().toString( static_cast<const QgsGeometryCollection *>( feature.geometry().constGet() )->numGeometries() );
729  derivedAttributes.insert( tr( "Parts" ), str );
730  str = QLocale().toString( vId.part + 1 );
731  derivedAttributes.insert( tr( "Part number" ), str );
732  }
733 
734  QgsUnitTypes::DistanceUnit cartesianDistanceUnits = QgsUnitTypes::unitType( layer->crs().mapUnits() ) == QgsUnitTypes::unitType( displayDistanceUnits() )
735  ? displayDistanceUnits() : layer->crs().mapUnits();
736  QgsUnitTypes::AreaUnit cartesianAreaUnits = QgsUnitTypes::unitType( QgsUnitTypes::distanceToAreaUnit( layer->crs().mapUnits() ) ) == QgsUnitTypes::unitType( displayAreaUnits() )
737  ? displayAreaUnits() : QgsUnitTypes::distanceToAreaUnit( layer->crs().mapUnits() );
738 
739  if ( geometryType == QgsWkbTypes::LineGeometry )
740  {
741  double dist = calc.measureLength( feature.geometry() );
742  dist = calc.convertLengthMeasurement( dist, displayDistanceUnits() );
743  QString str;
744  if ( ellipsoid != geoNone() )
745  {
746  str = formatDistance( dist );
747  derivedAttributes.insert( tr( "Length (Ellipsoidal — %1)" ).arg( ellipsoid ), str );
748  }
749  str = formatDistance( feature.geometry().constGet()->length()
750  * QgsUnitTypes::fromUnitToUnitFactor( layer->crs().mapUnits(), cartesianDistanceUnits ), cartesianDistanceUnits );
751  if ( !QgsWkbTypes::hasZ( feature.geometry().wkbType() ) )
752  derivedAttributes.insert( tr( "Length (Cartesian)" ), str );
753  else
754  derivedAttributes.insert( tr( "Length (Cartesian — 2D)" ), str );
756  {
757  str = formatDistance( qgsgeometry_cast< const QgsLineString * >( feature.geometry().constGet() )->length3D()
758  * QgsUnitTypes::fromUnitToUnitFactor( layer->crs().mapUnits(), cartesianDistanceUnits ), cartesianDistanceUnits );
759  derivedAttributes.insert( tr( "Length (Cartesian — 3D)" ), str );
760  }
761 
762  const QgsAbstractGeometry *geom = feature.geometry().constGet();
763  if ( geom )
764  {
765  str = QLocale().toString( geom->nCoordinates() );
766  derivedAttributes.insert( tr( "Vertices" ), str );
767  //add details of closest vertex to identify point
768  closestVertexAttributes( *geom, vId, layer, derivedAttributes );
769  closestPointAttributes( *geom, layerPoint, derivedAttributes );
770 
771  if ( const QgsCurve *curve = qgsgeometry_cast< const QgsCurve * >( geom ) )
772  {
773  // Add the start and end points in as derived attributes
774  QgsPointXY pnt = mCanvas->mapSettings().layerToMapCoordinates( layer, QgsPointXY( curve->startPoint().x(), curve->startPoint().y() ) );
775  str = formatXCoordinate( pnt );
776  derivedAttributes.insert( tr( "firstX", "attributes get sorted; translation for lastX should be lexically larger than this one" ), str );
777  str = formatYCoordinate( pnt );
778  derivedAttributes.insert( tr( "firstY" ), str );
779  pnt = mCanvas->mapSettings().layerToMapCoordinates( layer, QgsPointXY( curve->endPoint().x(), curve->endPoint().y() ) );
780  str = formatXCoordinate( pnt );
781  derivedAttributes.insert( tr( "lastX", "attributes get sorted; translation for firstX should be lexically smaller than this one" ), str );
782  str = formatYCoordinate( pnt );
783  derivedAttributes.insert( tr( "lastY" ), str );
784  }
785  }
786  }
787  else if ( geometryType == QgsWkbTypes::PolygonGeometry )
788  {
789  double area = calc.measureArea( feature.geometry() );
790  area = calc.convertAreaMeasurement( area, displayAreaUnits() );
791  QString str;
792  if ( ellipsoid != geoNone() )
793  {
794  str = formatArea( area );
795  derivedAttributes.insert( tr( "Area (Ellipsoidal — %1)" ).arg( ellipsoid ), str );
796  }
797  str = formatArea( feature.geometry().area()
798  * QgsUnitTypes::fromUnitToUnitFactor( QgsUnitTypes::distanceToAreaUnit( layer->crs().mapUnits() ), cartesianAreaUnits ), cartesianAreaUnits );
799  derivedAttributes.insert( tr( "Area (Cartesian)" ), str );
800 
801  if ( ellipsoid != geoNone() )
802  {
803  double perimeter = calc.measurePerimeter( feature.geometry() );
804  perimeter = calc.convertLengthMeasurement( perimeter, displayDistanceUnits() );
805  str = formatDistance( perimeter );
806  derivedAttributes.insert( tr( "Perimeter (Ellipsoidal — %1)" ).arg( ellipsoid ), str );
807  }
808  str = formatDistance( feature.geometry().constGet()->perimeter()
809  * QgsUnitTypes::fromUnitToUnitFactor( layer->crs().mapUnits(), cartesianDistanceUnits ), cartesianDistanceUnits );
810  derivedAttributes.insert( tr( "Perimeter (Cartesian)" ), str );
811 
812  str = QLocale().toString( feature.geometry().constGet()->nCoordinates() );
813  derivedAttributes.insert( tr( "Vertices" ), str );
814 
815  //add details of closest vertex to identify point
816  closestVertexAttributes( *feature.geometry().constGet(), vId, layer, derivedAttributes );
817  closestPointAttributes( *feature.geometry().constGet(), layerPoint, derivedAttributes );
818  }
819  else if ( geometryType == QgsWkbTypes::PointGeometry )
820  {
821  if ( QgsWkbTypes::flatType( wkbType ) == QgsWkbTypes::Point )
822  {
823  // Include the x and y coordinates of the point as a derived attribute
824  QgsPointXY pnt = mCanvas->mapSettings().layerToMapCoordinates( layer, feature.geometry().asPoint() );
825  QString str = formatXCoordinate( pnt );
826  derivedAttributes.insert( tr( "X" ), str );
827  str = formatYCoordinate( pnt );
828  derivedAttributes.insert( tr( "Y" ), str );
829 
830  if ( QgsWkbTypes::hasZ( wkbType ) )
831  {
832  str = QLocale().toString( static_cast<const QgsPoint *>( feature.geometry().constGet() )->z(), 'g', 10 );
833  derivedAttributes.insert( tr( "Z" ), str );
834  }
835  if ( QgsWkbTypes::hasM( wkbType ) )
836  {
837  str = QLocale().toString( static_cast<const QgsPoint *>( feature.geometry().constGet() )->m(), 'g', 10 );
838  derivedAttributes.insert( tr( "M" ), str );
839  }
840  }
841  else
842  {
843  //multipart
844 
845  //add details of closest vertex to identify point
846  const QgsAbstractGeometry *geom = feature.geometry().constGet();
847  {
848  closestVertexAttributes( *geom, vId, layer, derivedAttributes );
849  }
850  }
851  }
852 
853  return derivedAttributes;
854 }
855 
856 bool QgsMapToolIdentify::identifyRasterLayer( QList<IdentifyResult> *results, QgsRasterLayer *layer, const QgsGeometry &geometry, const QgsRectangle &viewExtent, double mapUnitsPerPixel )
857 {
858  QgsPointXY point = geometry.asPoint(); // raster layers currently only support identification by point
859  return identifyRasterLayer( results, layer, point, viewExtent, mapUnitsPerPixel );
860 }
861 
862 bool QgsMapToolIdentify::identifyRasterLayer( QList<IdentifyResult> *results, QgsRasterLayer *layer, QgsPointXY point, const QgsRectangle &viewExtent, double mapUnitsPerPixel )
863 {
864  QgsDebugMsg( "point = " + point.toString() );
865  if ( !layer )
866  return false;
867 
868  QgsRasterDataProvider *dprovider = layer->dataProvider();
869  if ( !dprovider )
870  return false;
871 
872  int capabilities = dprovider->capabilities();
873  if ( !( capabilities & QgsRasterDataProvider::Identify ) )
874  return false;
875 
876  QgsPointXY pointInCanvasCrs = point;
877  try
878  {
879  point = toLayerCoordinates( layer, point );
880  }
881  catch ( QgsCsException &cse )
882  {
883  Q_UNUSED( cse )
884  QgsDebugMsg( QStringLiteral( "coordinate not reprojectable: %1" ).arg( cse.what() ) );
885  return false;
886  }
887  QgsDebugMsg( QStringLiteral( "point = %1 %2" ).arg( point.x() ).arg( point.y() ) );
888 
889  if ( !layer->extent().contains( point ) )
890  return false;
891 
892  QMap< QString, QString > attributes, derivedAttributes;
893 
894  QgsRaster::IdentifyFormat format = QgsRasterDataProvider::identifyFormatFromName( layer->customProperty( QStringLiteral( "identify/format" ) ).toString() );
895 
896  // check if the format is really supported otherwise use first supported format
897  if ( !( QgsRasterDataProvider::identifyFormatToCapability( format ) & capabilities ) )
898  {
900  else if ( capabilities & QgsRasterInterface::IdentifyValue ) format = QgsRaster::IdentifyFormatValue;
901  else if ( capabilities & QgsRasterInterface::IdentifyHtml ) format = QgsRaster::IdentifyFormatHtml;
902  else if ( capabilities & QgsRasterInterface::IdentifyText ) format = QgsRaster::IdentifyFormatText;
903  else return false;
904  }
905 
906  QgsRasterIdentifyResult identifyResult;
907  // We can only use current map canvas context (extent, width, height) if layer is not reprojected,
908  if ( dprovider->crs() != mCanvas->mapSettings().destinationCrs() )
909  {
910  // To get some reasonable response for point/line WMS vector layers we must
911  // use a context with approximately a resolution in layer CRS units
912  // corresponding to current map canvas resolution (for examplei UMN Mapserver
913  // in msWMSFeatureInfo() -> msQueryByRect() is using requested pixel
914  // + TOLERANCE (layer param) for feature selection)
915  //
916  QgsRectangle r;
917  r.setXMinimum( pointInCanvasCrs.x() - mapUnitsPerPixel / 2. );
918  r.setXMaximum( pointInCanvasCrs.x() + mapUnitsPerPixel / 2. );
919  r.setYMinimum( pointInCanvasCrs.y() - mapUnitsPerPixel / 2. );
920  r.setYMaximum( pointInCanvasCrs.y() + mapUnitsPerPixel / 2. );
921  r = toLayerCoordinates( layer, r ); // will be a bit larger
922  // Mapserver (6.0.3, for example) does not work with 1x1 pixel box
923  // but that is fixed (the rect is enlarged) in the WMS provider
924  identifyResult = dprovider->identify( point, format, r, 1, 1 );
925  }
926  else
927  {
928  // It would be nice to use the same extent and size which was used for drawing,
929  // so that WCS can use cache from last draw, unfortunately QgsRasterLayer::draw()
930  // is doing some tricks with extent and size to align raster to output which
931  // would be difficult to replicate here.
932  // Note: cutting the extent may result in slightly different x and y resolutions
933  // and thus shifted point calculated back in QGIS WMS (using average resolution)
934  //viewExtent = dprovider->extent().intersect( &viewExtent );
935 
936  // Width and height are calculated from not projected extent and we hope that
937  // are similar to source width and height used to reproject layer for drawing.
938  // TODO: may be very dangerous, because it may result in different resolutions
939  // in source CRS, and WMS server (QGIS server) calcs wrong coor using average resolution.
940  int width = static_cast< int >( std::round( viewExtent.width() / mapUnitsPerPixel ) );
941  int height = static_cast< int >( std::round( viewExtent.height() / mapUnitsPerPixel ) );
942 
943  QgsDebugMsg( QStringLiteral( "viewExtent.width = %1 viewExtent.height = %2" ).arg( viewExtent.width() ).arg( viewExtent.height() ) );
944  QgsDebugMsg( QStringLiteral( "width = %1 height = %2" ).arg( width ).arg( height ) );
945  QgsDebugMsg( QStringLiteral( "xRes = %1 yRes = %2 mapUnitsPerPixel = %3" ).arg( viewExtent.width() / width ).arg( viewExtent.height() / height ).arg( mapUnitsPerPixel ) );
946 
947  identifyResult = dprovider->identify( point, format, viewExtent, width, height );
948  }
949 
950  derivedAttributes.unite( derivedAttributesForPoint( QgsPoint( pointInCanvasCrs ) ) );
951 
952  if ( identifyResult.isValid() )
953  {
954  QMap<int, QVariant> values = identifyResult.results();
955  QgsGeometry geometry;
956  if ( format == QgsRaster::IdentifyFormatValue )
957  {
958  for ( auto it = values.constBegin(); it != values.constEnd(); ++it )
959  {
960  QString valueString;
961  if ( it.value().isNull() )
962  {
963  valueString = tr( "no data" );
964  }
965  else
966  {
967  QVariant value( it.value() );
968  // The cast is legit. Quoting QT doc :
969  // "Although this function is declared as returning QVariant::Type,
970  // the return value should be interpreted as QMetaType::Type"
971  if ( static_cast<QMetaType::Type>( value.type() ) == QMetaType::Float )
972  {
973  valueString = QgsRasterBlock::printValue( value.toFloat() );
974  }
975  else
976  {
977  valueString = QgsRasterBlock::printValue( value.toDouble() );
978  }
979  }
980  attributes.insert( dprovider->generateBandName( it.key() ), valueString );
981  }
982  QString label = layer->name();
983  results->append( IdentifyResult( qobject_cast<QgsMapLayer *>( layer ), label, attributes, derivedAttributes ) );
984  }
985  else if ( format == QgsRaster::IdentifyFormatFeature )
986  {
987  for ( auto it = values.constBegin(); it != values.constEnd(); ++it )
988  {
989  QVariant value = it.value();
990  if ( value.type() == QVariant::Bool && !value.toBool() )
991  {
992  // sublayer not visible or not queryable
993  continue;
994  }
995 
996  if ( value.type() == QVariant::String )
997  {
998  // error
999  // TODO: better error reporting
1000  QString label = layer->subLayers().value( it.key() );
1001  attributes.clear();
1002  attributes.insert( tr( "Error" ), value.toString() );
1003 
1004  results->append( IdentifyResult( qobject_cast<QgsMapLayer *>( layer ), label, attributes, derivedAttributes ) );
1005  continue;
1006  }
1007 
1008  // list of feature stores for a single sublayer
1009  const QgsFeatureStoreList featureStoreList = it.value().value<QgsFeatureStoreList>();
1010 
1011  for ( const QgsFeatureStore &featureStore : featureStoreList )
1012  {
1013  const QgsFeatureList storeFeatures = featureStore.features();
1014  for ( const QgsFeature &feature : storeFeatures )
1015  {
1016  attributes.clear();
1017  // WMS sublayer and feature type, a sublayer may contain multiple feature types.
1018  // Sublayer name may be the same as layer name and feature type name
1019  // may be the same as sublayer. We try to avoid duplicities in label.
1020  QString sublayer = featureStore.params().value( QStringLiteral( "sublayer" ) ).toString();
1021  QString featureType = featureStore.params().value( QStringLiteral( "featureType" ) ).toString();
1022  // Strip UMN MapServer '_feature'
1023  featureType.remove( QStringLiteral( "_feature" ) );
1024  QStringList labels;
1025  if ( sublayer.compare( layer->name(), Qt::CaseInsensitive ) != 0 )
1026  {
1027  labels << sublayer;
1028  }
1029  if ( featureType.compare( sublayer, Qt::CaseInsensitive ) != 0 || labels.isEmpty() )
1030  {
1031  labels << featureType;
1032  }
1033 
1034  QMap< QString, QString > derAttributes = derivedAttributes;
1035  derAttributes.unite( featureDerivedAttributes( feature, layer, toLayerCoordinates( layer, point ) ) );
1036 
1037  IdentifyResult identifyResult( qobject_cast<QgsMapLayer *>( layer ), labels.join( QLatin1String( " / " ) ), featureStore.fields(), feature, derAttributes );
1038 
1039  identifyResult.mParams.insert( QStringLiteral( "getFeatureInfoUrl" ), featureStore.params().value( QStringLiteral( "getFeatureInfoUrl" ) ) );
1040  results->append( identifyResult );
1041  }
1042  }
1043  }
1044  }
1045  else // text or html
1046  {
1047  QgsDebugMsg( QStringLiteral( "%1 HTML or text values" ).arg( values.size() ) );
1048  for ( auto it = values.constBegin(); it != values.constEnd(); ++it )
1049  {
1050  QString value = it.value().toString();
1051  attributes.clear();
1052  attributes.insert( QString(), value );
1053 
1054  QString label = layer->subLayers().value( it.key() );
1055  results->append( IdentifyResult( qobject_cast<QgsMapLayer *>( layer ), label, attributes, derivedAttributes ) );
1056  }
1057  }
1058  }
1059  else
1060  {
1061  attributes.clear();
1062  QString value = identifyResult.error().message( QgsErrorMessage::Text );
1063  attributes.insert( tr( "Error" ), value );
1064  QString label = tr( "Identify error" );
1065  results->append( IdentifyResult( qobject_cast<QgsMapLayer *>( layer ), label, attributes, derivedAttributes ) );
1066  }
1067 
1068  return true;
1069 }
1070 
1071 QgsUnitTypes::DistanceUnit QgsMapToolIdentify::displayDistanceUnits() const
1072 {
1073  return mCanvas->mapUnits();
1074 }
1075 
1076 QgsUnitTypes::AreaUnit QgsMapToolIdentify::displayAreaUnits() const
1077 {
1079 }
1080 
1081 QString QgsMapToolIdentify::formatDistance( double distance ) const
1082 {
1083  return formatDistance( distance, displayDistanceUnits() );
1084 }
1085 
1086 QString QgsMapToolIdentify::formatArea( double area ) const
1087 {
1088  return formatArea( area, displayAreaUnits() );
1089 }
1090 
1091 QString QgsMapToolIdentify::formatDistance( double distance, QgsUnitTypes::DistanceUnit unit ) const
1092 {
1093  QgsSettings settings;
1094  bool baseUnit = settings.value( QStringLiteral( "qgis/measure/keepbaseunit" ), true ).toBool();
1095 
1096  return QgsDistanceArea::formatDistance( distance, 3, unit, baseUnit );
1097 }
1098 
1099 QString QgsMapToolIdentify::formatArea( double area, QgsUnitTypes::AreaUnit unit ) const
1100 {
1101  QgsSettings settings;
1102  bool baseUnit = settings.value( QStringLiteral( "qgis/measure/keepbaseunit" ), true ).toBool();
1103 
1104  return QgsDistanceArea::formatArea( area, 3, unit, baseUnit );
1105 }
1106 
1108 {
1109  QList<IdentifyResult> results;
1110  if ( identifyRasterLayer( &results, layer, mLastGeometry, mLastExtent, mLastMapUnitsPerPixel ) )
1111  {
1112  emit changedRasterResults( results );
1113  }
1114 }
1115 
QgsMeshLayer::datasetGroupsIndexes
QList< int > datasetGroupsIndexes() const
Returns the list of indexes of dataset groups count handled by the layer.
Definition: qgsmeshlayer.cpp:337
QgsCurve
Abstract base class for curved geometry type.
Definition: qgscurve.h:36
QgsMapToolIdentify::deactivate
void deactivate() override
called when map tool is being deactivated
Definition: qgsmaptoolidentify.cpp:204
QgsMapTool::mCanvas
QgsMapCanvas * mCanvas
pointer to map canvas
Definition: qgsmaptool.h:264
QgsVertexId::part
int part
Part number.
Definition: qgsabstractgeometry.h:1131
QgsVectorLayer::getFeatures
QgsFeatureIterator getFeatures(const QgsFeatureRequest &request=QgsFeatureRequest()) const FINAL
Queries the layer for features specified in request.
Definition: qgsvectorlayer.cpp:993
QgsMapLayer::crs
QgsCoordinateReferenceSystem crs
Definition: qgsmaplayer.h:89
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:256
QgsRasterBlock::printValue
static QString printValue(double value)
Print double value with all necessary significant digits.
Definition: qgsrasterblock.cpp:626
QgsMapToolIdentify::activate
void activate() override
called when set as currently active map tool
Definition: qgsmaptoolidentify.cpp:199
QgsMapToolIdentify::identify
QList< QgsMapToolIdentify::IdentifyResult > identify(int x, int y, const QList< QgsMapLayer * > &layerList=QList< QgsMapLayer * >(), IdentifyMode mode=DefaultQgsSetting)
Performs the identification.
Definition: qgsmaptoolidentify.cpp:89
QgsRectangle::height
double height() const SIP_HOLDGIL
Returns the height of the rectangle.
Definition: qgsrectangle.h:209
QgsVertexId::vertex
int vertex
Vertex number.
Definition: qgsabstractgeometry.h:1137
QgsRasterInterface::generateBandName
virtual QString generateBandName(int bandNumber) const
helper function to create zero padded band names
Definition: qgsrasterinterface.h:245
QgsPointXY::y
double y
Definition: qgspointxy.h:48
QgsDistanceArea::measureLength
double measureLength(const QgsGeometry &geometry) const
Measures the length of a geometry.
Definition: qgsdistancearea.cpp:192
QgsMapToolIdentify::LayerSelection
@ LayerSelection
Definition: qgsmaptoolidentify.h:60
QgsGeometry::transform
OperationResult transform(const QgsCoordinateTransform &ct, QgsCoordinateTransform::TransformDirection direction=QgsCoordinateTransform::ForwardTransform, bool transformZ=false) SIP_THROW(QgsCsException)
Transforms this geometry as described by the coordinate transform ct.
Definition: qgsgeometry.cpp:2813
QgsMapCanvas::extent
QgsRectangle extent() const
Returns the current zoom extent of the map canvas.
Definition: qgsmapcanvas.cpp:1056
QgsVectorTileLayer
Implements a map layer that is dedicated to rendering of vector tiles.
Definition: qgsvectortilelayer.h:84
qgsrasterlayer.h
QgsCoordinateReferenceSystem::mapUnits
Q_GADGET QgsUnitTypes::DistanceUnit mapUnits
Definition: qgscoordinatereferencesystem.h:209
QgsMapToolIdentify::AllLayers
@ AllLayers
Definition: qgsmaptoolidentify.h:70
QgsWkbTypes::Point
@ Point
Definition: qgswkbtypes.h:72
QgsRasterInterface::IdentifyHtml
@ IdentifyHtml
Definition: qgsrasterinterface.h:193
QgsSettings::value
QVariant value(const QString &key, const QVariant &defaultValue=QVariant(), Section section=NoSection) const
Returns the value for setting key.
Definition: qgssettings.cpp:174
QgsMapLayerType::MeshLayer
@ MeshLayer
Added in 3.2.
QgsTileXYZ
Stores coordinates of a tile in a tile matrix set.
Definition: qgstiles.h:33
QgsFeatureRequest::ExactIntersect
@ ExactIntersect
Use exact geometry intersection (slower) instead of bounding boxes.
Definition: qgsfeaturerequest.h:83
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:197
QgsMapLayerType::VectorLayer
@ VectorLayer
QgsPoint
Point geometry type, with support for z-dimension and m-values.
Definition: qgspoint.h:38
QgsVectorTileUtils::makeQgisFields
static QgsFields makeQgisFields(QSet< QString > flds)
Returns QgsFields instance based on the set of field names.
Definition: qgsvectortileutils.cpp:51
QgsTileRange
Range of tiles in a tile matrix to be rendered.
Definition: qgstiles.h:66
QgsDebugMsgLevel
#define QgsDebugMsgLevel(str, level)
Definition: qgslogger.h:39
qgscoordinateutils.h
qgsrasteridentifyresult.h
QgsMapToolIdentify::ActiveLayer
@ ActiveLayer
Definition: qgsmaptoolidentify.h:57
QgsMapToolIdentify::VectorLayer
@ VectorLayer
Definition: qgsmaptoolidentify.h:66
qgsmaptopixel.h
QgsMapCanvas::mapSettings
const QgsMapSettings & mapSettings() const
Gets access to properties used for map rendering.
Definition: qgsmapcanvas.cpp:391
QgsTemporalRangeObject::isTemporal
bool isTemporal() const
Returns true if the object's temporal range is enabled, and the object will be filtered when renderin...
Definition: qgstemporalrangeobject.cpp:30
QgsMesh::Face
@ Face
Definition: qgsmeshdataprovider.h:68
QgsPointXY::x
Q_GADGET double x
Definition: qgspointxy.h:47
crs
const QgsCoordinateReferenceSystem & crs
Definition: qgswfsgetfeature.cpp:51
QgsMapToolIdentify::MeshLayer
@ MeshLayer
Definition: qgsmaptoolidentify.h:68
QgsApplication::getThemeCursor
static QCursor getThemeCursor(Cursor cursor)
Helper to get a theme cursor.
Definition: qgsapplication.cpp:656
QgsRaster::IdentifyFormatText
@ IdentifyFormatText
Definition: qgsraster.h:61
QgsWkbTypes::flatType
static Type flatType(Type type) SIP_HOLDGIL
Returns the flat type for a WKB type.
Definition: qgswkbtypes.h:702
QgsMeshDatasetValue
QgsMeshDatasetValue represents single dataset value.
Definition: qgsmeshdataset.h:78
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:60
QgsWkbTypes::LineString
@ LineString
Definition: qgswkbtypes.h:73
qgsfeatureiterator.h
QgsFields
Container of fields for a vector layer.
Definition: qgsfields.h:45
QgsFeatureStore
A container for features with the same fields and crs.
Definition: qgsfeaturestore.h:33
QgsMapTool::setCursor
virtual void setCursor(const QCursor &cursor)
Sets a user defined cursor.
Definition: qgsmaptool.cpp:146
QgsGeometry::fromPointXY
static QgsGeometry fromPointXY(const QgsPointXY &point) SIP_HOLDGIL
Creates a new geometry from a QgsPointXY object.
Definition: qgsgeometry.cpp:164
QgsExpressionContextUtils::layerScope
static QgsExpressionContextScope * layerScope(const QgsMapLayer *layer)
Creates a new scope which contains variables and functions relating to a QgsMapLayer.
Definition: qgsexpressioncontextutils.cpp:265
QgsMapCanvas
Map canvas is a class for displaying all GIS data types on a canvas.
Definition: qgsmapcanvas.h:85
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:96
qgsfeature.h
QgsRaster::IdentifyFormatHtml
@ IdentifyFormatHtml
Definition: qgsraster.h:62
QgsFeature::geometry
QgsGeometry geometry
Definition: qgsfeature.h:67
QgsProject::transformContext
QgsCoordinateTransformContext transformContext
Definition: qgsproject.h:101
QgsTemporalRangeObject::temporalRange
const QgsDateTimeRange & temporalRange() const
Returns the datetime range for the object.
Definition: qgstemporalrangeobject.cpp:43
QgsPoint::z
double z
Definition: qgspoint.h:43
QgsRenderContext
Contains information about the context of a rendering operation.
Definition: qgsrendercontext.h:58
QgsDistanceArea::measureArea
double measureArea(const QgsGeometry &geometry) const
Measures the area of a geometry.
Definition: qgsdistancearea.cpp:183
QgsProject::instance
static QgsProject * instance()
Returns the QgsProject singleton instance.
Definition: qgsproject.cpp:468
QgsMapToolIdentify::identifyLayer
bool identifyLayer(QList< QgsMapToolIdentify::IdentifyResult > *results, QgsMapLayer *layer, const QgsPointXY &point, const QgsRectangle &viewExtent, double mapUnitsPerPixel, QgsMapToolIdentify::LayerType layerType=AllLayers)
Call the right method depending on layer type.
Definition: qgsmaptoolidentify.cpp:209
QgsAbstractGeometry::length
virtual double length() const
Returns the planar, 2-dimensional length of the geometry.
Definition: qgsabstractgeometry.cpp:132
QgsMapCanvas::scale
double scale() const
Returns the last reported scale of the canvas.
Definition: qgsmapcanvas.cpp:323
QgsVectorLayer::isSpatial
bool isSpatial() const FINAL
Returns true if this is a geometry layer and false in case of NoGeometry (table only) or UnknownGeome...
Definition: qgsvectorlayer.cpp:3599
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:62
QgsWkbTypes::Type
Type
The WKB type describes the number of dimensions a geometry has.
Definition: qgswkbtypes.h:70
QgsPointXY::isEmpty
bool isEmpty() const SIP_HOLDGIL
Returns true if the geometry is empty.
Definition: qgspointxy.h:234
QgsRasterInterface::IdentifyFeature
@ IdentifyFeature
Definition: qgsrasterinterface.h:194
QgsRasterIdentifyResult::isValid
bool isValid() const
Returns true if valid.
Definition: qgsrasteridentifyresult.h:55
QgsMapCanvas::mapUnits
QgsUnitTypes::DistanceUnit mapUnits() const
Convenience function for returning the current canvas map units.
Definition: qgsmapcanvas.cpp:2165
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:68
FID_TO_STRING
#define FID_TO_STRING(fid)
Definition: qgsfeatureid.h:33
QgsRasterInterface::Identify
@ Identify
Definition: qgsrasterinterface.h:190
QgsIdentifyMenu::exec
QList< QgsMapToolIdentify::IdentifyResult > exec(const QList< QgsMapToolIdentify::IdentifyResult > &idResults, QPoint pos)
exec
Definition: qgsidentifymenu.cpp:70
QgsMeshLayer::datasetValue
QgsMeshDatasetValue datasetValue(const QgsMeshDatasetIndex &index, int valueIndex) const
Returns vector/scalar value associated with the index from the dataset To read multiple continuous va...
Definition: qgsmeshlayer.cpp:357
qgsidentifymenu.h
QgsRectangle
A rectangle specified with double values.
Definition: qgsrectangle.h:42
QgsVectorTileMVTDecoder
This class is responsible for decoding raw tile data written with Mapbox Vector Tiles encoding.
Definition: qgsvectortilemvtdecoder.h:37
QgsMeshDatasetMetadata
QgsMeshDatasetMetadata is a collection of mesh dataset metadata such as whether the data is valid or ...
Definition: qgsmeshdataset.h:476
QgsMeshDatasetMetadata::time
double time() const
Returns the time value for this dataset.
Definition: qgsmeshdataset.cpp:215
QgsWkbTypes::PolygonGeometry
@ PolygonGeometry
Definition: qgswkbtypes.h:144
QgsMapToolIdentify::TopDownStopAtFirst
@ TopDownStopAtFirst
Definition: qgsmaptoolidentify.h:58
QgsGeometryCollection::numGeometries
int numGeometries() const SIP_HOLDGIL
Returns the number of geometries within the collection.
Definition: qgsgeometrycollection.h:57
QgsRasterDataProvider::identifyFormatFromName
static QgsRaster::IdentifyFormat identifyFormatFromName(const QString &formatName)
Definition: qgsrasterdataprovider.cpp:495
QgsMapToolIdentify::TopDownAll
@ TopDownAll
Definition: qgsmaptoolidentify.h:59
QgsMeshLayer::datasetMetadata
QgsMeshDatasetMetadata datasetMetadata(const QgsMeshDatasetIndex &index) const
Returns the dataset metadata.
Definition: qgsmeshlayer.cpp:352
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:673
QgsAbstractGeometry::vertexAt
virtual QgsPoint vertexAt(QgsVertexId id) const =0
Returns the point corresponding to a specified vertex id.
QgsMapTool::toLayerCoordinates
QgsPointXY toLayerCoordinates(const QgsMapLayer *layer, QPoint point)
transformation from screen coordinates to layer's coordinates
Definition: qgsmaptool.cpp:51
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:1156
qgsapplication.h
QgsMapToolIdentify::DefaultQgsSetting
@ DefaultQgsSetting
Definition: qgsmaptoolidentify.h:56
QgsAbstractGeometry::isMeasure
bool isMeasure() const SIP_HOLDGIL
Returns true if the geometry contains m values.
Definition: qgsabstractgeometry.h:215
QgsMapTool
Abstract base class for all map tools.
Definition: qgsmaptool.h:64
QgsVectorTileMVTDecoder::layerFeatures
QgsVectorTileFeatures layerFeatures(const QMap< QString, QgsFields > &perLayerFields, const QgsCoordinateTransform &ct, const QSet< QString > *layerSubset=nullptr) const
Returns decoded features grouped by sub-layers.
Definition: qgsvectortilemvtdecoder.cpp:80
QgsGeometry::isGeosEqual
bool isGeosEqual(const QgsGeometry &) const
Compares the geometry with another geometry using GEOS.
Definition: qgsgeometry.cpp:2731
QgsMeshLayer::rendererSettings
QgsMeshRendererSettings rendererSettings() const
Returns renderer settings.
Definition: qgsmeshlayer.cpp:287
qgsvectortilelayer.h
QgsMapToolIdentify::IdentifyMode
IdentifyMode
Definition: qgsmaptoolidentify.h:55
QgsVectorLayer::fields
QgsFields fields() const FINAL
Returns the list of fields of this layer.
Definition: qgsvectorlayer.cpp:3283
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
QgsPoint::y
double y
Definition: qgspoint.h:42
QgsDistanceArea::setEllipsoid
bool setEllipsoid(const QString &ellipsoid)
Sets the ellipsoid by its acronym.
Definition: qgsdistancearea.cpp:66
QgsMapLayer::isInScaleRange
bool isInScaleRange(double scale) const
Tests whether the layer should be visible at the specified scale.
Definition: qgsmaplayer.cpp:671
QgsTileRange::endRow
int endRow() const
Returns index of the last row in the range.
Definition: qgstiles.h:82
QgsMapTool::toCanvasCoordinates
QPoint toCanvasCoordinates(const QgsPointXY &point) const
transformation from map coordinates to screen coordinates
Definition: qgsmaptool.cpp:72
QgsFeatureRequest
This class wraps a request for features to a vector layer (or directly its vector data provider).
Definition: qgsfeaturerequest.h:76
QgsMeshLayer::staticVectorDatasetIndex
QgsMeshDatasetIndex staticVectorDatasetIndex() const
Returns the static vector dataset index that is rendered if the temporal properties is not active.
Definition: qgsmeshlayer.cpp:709
QgsMapLayer::flags
QgsMapLayer::LayerFlags flags() const
Returns the flags for this layer.
Definition: qgsmaplayer.cpp:134
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:489
QgsRasterLayer::subLayers
QStringList subLayers() const override
Returns the sublayers of this layer.
Definition: qgsrasterlayer.cpp:1687
QgsTileMatrix
Defines a matrix of tiles for a single zoom level: it is defined by its size (width * height) and map...
Definition: qgstiles.h:103
qgsgeometryengine.h
QgsMeshLayer::datasetIndexAtTime
QgsMeshDatasetIndex datasetIndexAtTime(const QgsDateTimeRange &timeRange, int datasetGroupIndex) const
Returns dataset index from datasets group depending on the time range.
Definition: qgsmeshlayer.cpp:517
QgsCsException
Custom exception class for Coordinate Reference System related exceptions.
Definition: qgsexception.h:66
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:79
QgsMapToolIdentify::identifyProgress
void identifyProgress(int, int)
QgsMeshRendererSettings::activeScalarDatasetGroup
int activeScalarDatasetGroup() const
Returns the active scalar dataset group.
Definition: qgsmeshrenderersettings.cpp:509
QgsRaster::IdentifyFormatValue
@ IdentifyFormatValue
Definition: qgsraster.h:60
QgsVectorTileMVTDecoder::layerFieldNames
QStringList layerFieldNames(const QString &layerName) const
Returns a list of all field names in a tile. It can only be called after a successful decode()
Definition: qgsvectortilemvtdecoder.cpp:65
QgsMapSettings::transformContext
QgsCoordinateTransformContext transformContext() const
Returns the coordinate transform context, which stores various information regarding which datum tran...
Definition: qgsmapsettings.cpp:401
QgsMapCanvas::layerCount
int layerCount() const
Returns number of layers on the map.
Definition: qgsmapcanvas.cpp:2133
QgsRasterInterface::IdentifyValue
@ IdentifyValue
Definition: qgsrasterinterface.h:191
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:66
geoNone
CONSTLATIN1STRING geoNone()
Constant that holds the string representation for "No ellips/No CRS".
Definition: qgis.h:715
QgsMapToolIdentify::setCanvasPropertiesOverrides
void setCanvasPropertiesOverrides(double searchRadiusMapUnits)
Overrides some map canvas properties inside the map tool for the upcoming identify requests.
Definition: qgsmaptoolidentify.cpp:189
QgsRasterIdentifyResult
Raster identify results container.
Definition: qgsrasteridentifyresult.h:31
QgsMapToolIdentify::canvasReleaseEvent
void canvasReleaseEvent(QgsMapMouseEvent *e) override
Mouse release event for overriding. Default implementation does nothing.
Definition: qgsmaptoolidentify.cpp:84
qgsvectortilemvtdecoder.h
QgsRectangle::contains
bool contains(const QgsRectangle &rect) const
Returns true when rectangle contains other rectangle.
Definition: qgsrectangle.h:342
QgsMeshLayer::formatTime
QString formatTime(double hours)
Returns (date) time in hours formatted to human readable form.
Definition: qgsmeshlayer.cpp:319
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.
Definition: qgsmeshdataset.h:47
QgsMeshRendererSettings::activeVectorDatasetGroup
int activeVectorDatasetGroup() const
Returns the active vector dataset group.
Definition: qgsmeshrenderersettings.cpp:519
QgsMapCanvas::layer
QgsMapLayer * layer(int index)
Returns the map layer at position index in the layer stack.
Definition: qgsmapcanvas.cpp:305
QgsFeatureRenderer::clone
virtual QgsFeatureRenderer * clone() const =0
Create a deep copy of this renderer.
QgsRasterIdentifyResult::error
QgsError error() const
Returns the last error.
Definition: qgsrasteridentifyresult.h:75
QgsMapLayer::extent
virtual QgsRectangle extent() const
Returns the extent of the layer.
Definition: qgsmaplayer.cpp:197
QgsMeshLayer
Represents a mesh layer supporting display of data on structured or unstructured meshes.
Definition: qgsmeshlayer.h:95
QgsException::what
QString what() const
Definition: qgsexception.h:48
qgsmaplayer.h
QgsMapLayerType::RasterLayer
@ RasterLayer
qgsmessageviewer.h
QgsMapToolIdentify::identifyRasterLayer
bool identifyRasterLayer(QList< QgsMapToolIdentify::IdentifyResult > *results, QgsRasterLayer *layer, QgsPointXY point, const QgsRectangle &viewExtent, double mapUnitsPerPixel)
Definition: qgsmaptoolidentify.cpp:862
QgsMeshDatasetValue::x
double x() const
Returns x value.
Definition: qgsmeshdataset.cpp:93
qgsvectordataprovider.h
QgsFeatureList
QList< QgsFeature > QgsFeatureList
Definition: qgsfeature.h:583
QgsRasterDataProvider::identify
virtual QgsRasterIdentifyResult identify(const QgsPointXY &point, QgsRaster::IdentifyFormat format, const QgsRectangle &boundingBox=QgsRectangle(), int width=0, int height=0, int dpi=96)
Identify raster value(s) found on the point position.
Definition: qgsrasterdataprovider.cpp:265
QgsMesh::Edge
@ Edge
Definition: qgsmeshdataprovider.h:67
QgsWkbTypes::hasM
static bool hasM(Type type) SIP_HOLDGIL
Tests whether a WKB type contains m values.
Definition: qgswkbtypes.h:1093
QgsRectangle::setXMinimum
void setXMinimum(double x) SIP_HOLDGIL
Set the minimum x value.
Definition: qgsrectangle.h:130
QgsUnitTypes
Helper functions for various unit types.
Definition: qgsunittypes.h:39
QgsPoint::x
Q_GADGET double x
Definition: qgspoint.h:41
QgsRasterLayer::dataProvider
QgsRasterDataProvider * dataProvider() override
Returns the source data provider.
Definition: qgsrasterlayer.cpp:234
QgsPoint::m
double m
Definition: qgspoint.h:44
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:1132
QgsUnitTypes::AreaUnit
AreaUnit
Units of area.
Definition: qgsunittypes.h:94
QgsAbstractGeometry::nCoordinates
virtual int nCoordinates() const
Returns the number of nodes contained in the geometry.
Definition: qgsabstractgeometry.cpp:116
QgsMapSettings::scale
double scale() const
Returns the calculated map scale.
Definition: qgsmapsettings.cpp:396
QgsFeatureStoreList
QVector< QgsFeatureStore > QgsFeatureStoreList
Definition: qgsfeaturestore.h:119
QgsMeshLayer::activeVectorDatasetAtTime
QgsMeshDatasetIndex activeVectorDatasetAtTime(const QgsDateTimeRange &timeRange) const
Returns dataset index from active vector group depending on the time range If the temporal properties...
Definition: qgsmeshlayer.cpp:638
qgsrenderer.h
QgsTileRange::endColumn
int endColumn() const
Returns index of the last column in the range.
Definition: qgstiles.h:78
QgsDistanceArea::setSourceCrs
void setSourceCrs(const QgsCoordinateReferenceSystem &crs, const QgsCoordinateTransformContext &context)
Sets source spatial reference system crs.
Definition: qgsdistancearea.cpp:60
QgsRasterLayer
Represents a raster layer.
Definition: qgsrasterlayer.h:71
QgsGeometry::constGet
const QgsAbstractGeometry * constGet() const SIP_HOLDGIL
Returns a non-modifiable (const) reference to the underlying abstract geometry primitive.
Definition: qgsgeometry.cpp:128
QgsMapToolIdentify::RasterLayer
@ RasterLayer
Definition: qgsmaptoolidentify.h:67
QgsMapTool::activate
virtual void activate()
called when set as currently active map tool
Definition: qgsmaptool.cpp:80
QgsMapToolIdentify::identifyMeshLayer
bool identifyMeshLayer(QList< QgsMapToolIdentify::IdentifyResult > *results, QgsMeshLayer *layer, const QgsPointXY &point)
Identifies data from active scalar and vector dataset from the mesh layer.
Definition: qgsmaptoolidentify.cpp:249
QgsRectangle::setXMaximum
void setXMaximum(double x) SIP_HOLDGIL
Set the maximum x value.
Definition: qgsrectangle.h:135
QgsMeshDatasetGroupMetadata::name
QString name() const
Returns name of the dataset group.
Definition: qgsmeshdataset.cpp:166
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:63
QgsAbstractGeometry
Abstract base class for all geometries.
Definition: qgsabstractgeometry.h:74
QgsVectorTileUtils::scaleToZoomLevel
static int scaleToZoomLevel(double mapScale, int sourceMinZoom, int sourceMaxZoom)
Finds best fitting zoom level (assuming GoogleCRS84Quad tile matrix set) given map scale denominator ...
Definition: qgsvectortileutils.cpp:71
QgsVertexId::type
VertexType type
Vertex type.
Definition: qgsabstractgeometry.h:1140
qgsgeometryutils.h
QgsAbstractGeometry::is3D
bool is3D() const SIP_HOLDGIL
Returns true if the geometry is 3D and contains a z-value.
Definition: qgsabstractgeometry.h:206
qgsmeshlayer.h
qgsvectorlayer.h
QgsPointXY
A class to represent a 2D point.
Definition: qgspointxy.h:44
QgsMapSettings::destinationCrs
QgsCoordinateReferenceSystem destinationCrs() const
returns CRS of destination coordinate reference system
Definition: qgsmapsettings.cpp:318
QgsRectangle::setYMaximum
void setYMaximum(double y) SIP_HOLDGIL
Set the maximum y value.
Definition: qgsrectangle.h:145
QgsMapToolIdentify::formatChanged
void formatChanged(QgsRasterLayer *layer)
Definition: qgsmaptoolidentify.cpp:1107
QgsGeometry::asPoint
QgsPointXY asPoint() const
Returns the contents of the geometry as a 2-dimensional point.
Definition: qgsgeometry.cpp:1544
QgsVectorTileLayer::sourceMaxZoom
int sourceMaxZoom() const
Returns maximum zoom level at which source has any valid tiles (negative = unconstrained)
Definition: qgsvectortilelayer.h:140
QgsRasterDataProvider::identifyFormatToCapability
static Capability identifyFormatToCapability(QgsRaster::IdentifyFormat format)
Definition: qgsrasterdataprovider.cpp:504
QgsMeshDatasetGroupMetadata::isTemporal
bool isTemporal() const
Returns whether the dataset group is temporal (contains time-related dataset)
Definition: qgsmeshdataset.cpp:161
QgsVertexId::isValid
bool isValid() const SIP_HOLDGIL
Returns true if the vertex id is valid.
Definition: qgsabstractgeometry.h:1083
QgsTileRange::startRow
int startRow() const
Returns index of the first row in the range.
Definition: qgstiles.h:80
QgsGeometry::createGeometryEngine
static QgsGeometryEngine * createGeometryEngine(const QgsAbstractGeometry *geometry)
Creates and returns a new geometry engine.
Definition: qgsgeometry.cpp:3636
QgsMapMouseEvent
A QgsMapMouseEvent is the result of a user interaction with the mouse on a QgsMapCanvas.
Definition: qgsmapmouseevent.h:36
QgsMapLayer::Identifiable
@ Identifiable
If the layer is identifiable using the identify map tool and as a WMS layer.
Definition: qgsmaplayer.h:148
QgsWkbTypes::LineGeometry
@ LineGeometry
Definition: qgswkbtypes.h:143
QgsMapToolIdentify::VectorTileLayer
@ VectorTileLayer
Definition: qgsmaptoolidentify.h:69
QgsMeshDatasetGroupMetadata
QgsMeshDatasetGroupMetadata is a collection of dataset group metadata such as whether the data is vec...
Definition: qgsmeshdataset.h:350
QgsWkbTypes::PointGeometry
@ PointGeometry
Definition: qgswkbtypes.h:142
QgsMeshDatasetGroupMetadata::isScalar
bool isScalar() const
Returns whether dataset group has scalar data.
Definition: qgsmeshdataset.cpp:156
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:1723
qgsgeometry.h
QgsWkbTypes::GeometryType
GeometryType
The geometry types are used to group QgsWkbTypes::Type in a coarse way.
Definition: qgswkbtypes.h:141
qgstiles.h
QgsFeatureIterator::nextFeature
bool nextFeature(QgsFeature &f)
Definition: qgsfeatureiterator.h:374
QgsRectangle::setYMinimum
void setYMinimum(double y) SIP_HOLDGIL
Set the minimum y value.
Definition: qgsrectangle.h:140
QgsDistanceArea::measurePerimeter
double measurePerimeter(const QgsGeometry &geometry) const
Measures the perimeter of a polygon geometry.
Definition: qgsdistancearea.cpp:201
qgscurve.h
QgsGeometry
A geometry is the spatial representation of a feature.
Definition: qgsgeometry.h:124
QgsVectorLayer
Represents a vector layer which manages a vector based data sets.
Definition: qgsvectorlayer.h:387
QgsFeature::hasGeometry
bool hasGeometry() const
Returns true if the feature has an associated geometry.
Definition: qgsfeature.cpp:199
QgsRectangle::width
double width() const SIP_HOLDGIL
Returns the width of the rectangle.
Definition: qgsrectangle.h:202
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:1142
QgsMapLayer
Base class for all map layer types.
Definition: qgsmaplayer.h:83
QgsRasterInterface::IdentifyText
@ IdentifyText
Definition: qgsrasterinterface.h:192
QgsGeometry::fromRect
static QgsGeometry fromRect(const QgsRectangle &rect) SIP_HOLDGIL
Creates a new geometry from a QgsRectangle.
Definition: qgsgeometry.cpp:229
QgsVertexId
Utility class for identifying a unique vertex within a geometry.
Definition: qgsabstractgeometry.h:1059
QgsMeshDatasetValue::y
double y() const
Returns y value.
Definition: qgsmeshdataset.cpp:98
qgssettings.h
QgsErrorMessage::Text
@ Text
Definition: qgserror.h:38
QgsMapLayerType::VectorTileLayer
@ VectorTileLayer
Added in 3.14.
QgsMeshLayer::staticScalarDatasetIndex
QgsMeshDatasetIndex staticScalarDatasetIndex() const
Returns the static scalar dataset index that is rendered if the temporal properties is not active.
Definition: qgsmeshlayer.cpp:909
QgsAbstractGeometry::perimeter
virtual double perimeter() const
Returns the planar, 2-dimensional perimeter of the geometry.
Definition: qgsabstractgeometry.cpp:137
QgsMapLayer::name
QString name
Definition: qgsmaplayer.h:86
QgsMapToolIdentify::identifyMessage
void identifyMessage(const QString &)
QgsVectorTileLayer::getRawTile
QByteArray getRawTile(QgsTileXYZ tileID)
Fetches raw tile data for the give tile coordinates.
Definition: qgsvectortilelayer.cpp:596
QgsMapTool::searchRadiusMU
static double searchRadiusMU(const QgsRenderContext &context)
Gets search radius in map units for given context.
Definition: qgsmaptool.cpp:212
QgsMeshLayer::datasetGroupMetadata
QgsMeshDatasetGroupMetadata datasetGroupMetadata(const QgsMeshDatasetIndex &index) const
Returns the dataset groups metadata.
Definition: qgsmeshlayer.cpp:342
QgsGeometry::boundingBox
QgsRectangle boundingBox() const
Returns the bounding box of the geometry.
Definition: qgsgeometry.cpp:996
QgsWkbTypes::hasZ
static bool hasZ(Type type) SIP_HOLDGIL
Tests whether a WKB type contains the z-dimension.
Definition: qgswkbtypes.h:1043
QgsDistanceArea
A general purpose distance and area calculator, capable of performing ellipsoid based calculations.
Definition: qgsdistancearea.h:50
QgsTileMatrix::fromWebMercator
static QgsTileMatrix fromWebMercator(int mZoomLevel)
Returns a tile matrix for the usual web mercator.
Definition: qgstiles.cpp:20
QgsMapToolIdentify::restoreCanvasPropertiesOverrides
void restoreCanvasPropertiesOverrides()
Clears canvas properties overrides previously set with setCanvasPropertiesOverrides()
Definition: qgsmaptoolidentify.cpp:194
qgsgeometrycollection.h
QgsMapToolIdentify::identifyVectorLayer
bool identifyVectorLayer(QList< QgsMapToolIdentify::IdentifyResult > *results, QgsVectorLayer *layer, const QgsPointXY &point)
Definition: qgsmaptoolidentify.cpp:238
qgsexception.h
QgsMapToolIdentify::~QgsMapToolIdentify
~QgsMapToolIdentify() override
Definition: qgsmaptoolidentify.cpp:69
qgsdistancearea.h
QgsFeature
The feature class encapsulates a single feature including its id, geometry and a list of field/values...
Definition: qgsfeature.h:56
QgsVectorTileLayer::sourceMinZoom
int sourceMinZoom() const
Returns minimum zoom level at which source has any valid tiles (negative = unconstrained)
Definition: qgsvectortilelayer.h:138
QgsMapCanvas::currentLayer
QgsMapLayer * currentLayer()
returns current layer (set by legend widget)
Definition: qgsmapcanvas.cpp:512
QgsMeshDatasetGroupMetadata::uri
QString uri() const
Returns the uri of the source.
Definition: qgsmeshdataset.cpp:196
QgsMapToolIdentify::mIdentifyMenu
QgsIdentifyMenu * mIdentifyMenu
Definition: qgsmaptoolidentify.h:167
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:1137
QgsVectorTileFeatures
QMap< QString, QVector< QgsFeature > > QgsVectorTileFeatures
Features of a vector tile, grouped by sub-layer names (key of the map)
Definition: qgsvectortilerenderer.h:25
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:252
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:1745
QgsMapToolIdentify::IdentifyResult::mParams
QMap< QString, QVariant > mParams
Definition: qgsmaptoolidentify.h:95
QgsMeshLayer::temporalProperties
QgsMapLayerTemporalProperties * temporalProperties() override
Returns the layer's temporal properties.
Definition: qgsmeshlayer.cpp:1407
qgslogger.h
QgsMeshDatasetGroupMetadata::isVector
bool isVector() const
Returns whether dataset group has vector data.
Definition: qgsmeshdataset.cpp:151
qgsvectortileutils.h
qgsfeaturestore.h
QgsIdentifyMenu
The QgsIdentifyMenu class builds a menu to be used with identify results (.
Definition: qgsidentifymenu.h:49
QgsMapCanvas::mapUnitsPerPixel
double mapUnitsPerPixel() const
Returns the mapUnitsPerPixel (map units per pixel) for the canvas.
Definition: qgsmapcanvas.cpp:2160
QgsVertexId::CurveVertex
@ CurveVertex
An intermediate point on a segment defining the curvature of the segment.
Definition: qgsabstractgeometry.h:1067
QgsWkbTypes::isMultiType
static bool isMultiType(Type type) SIP_HOLDGIL
Returns true if the WKB type is a multi type.
Definition: qgswkbtypes.h:832
QgsCoordinateTransform
Class for doing transforms between two map coordinate systems.
Definition: qgscoordinatetransform.h:53
QgsMeshDatasetValue::scalar
double scalar() const
Returns magnitude of vector for vector data or scalar value for scalar data.
Definition: qgsmeshdataset.cpp:62
QgsGeometry::type
QgsWkbTypes::GeometryType type
Definition: qgsgeometry.h:127
QgsVectorTileMVTDecoder::decode
bool decode(QgsTileXYZ tileID, const QByteArray &rawTileData)
Tries to decode raw tile data, returns true on success.
Definition: qgsvectortilemvtdecoder.cpp:36
QgsFeatureIterator
Wrapper for iterator of features from vector data provider or vector layer.
Definition: qgsfeatureiterator.h:265
QgsMapSettings::layerToMapCoordinates
QgsPointXY layerToMapCoordinates(const QgsMapLayer *layer, QgsPointXY point) const
transform point coordinates from layer's CRS to output CRS
Definition: qgsmapsettings.cpp:483
QgsGeometry::area
double area() const
Returns the planar, 2-dimensional area of the geometry.
Definition: qgsgeometry.cpp:1760
QgsRaster::IdentifyFormat
IdentifyFormat
Definition: qgsraster.h:58
QgsProject::ellipsoid
QString ellipsoid
Definition: qgsproject.h:102
qgscoordinatereferencesystem.h
QgsRasterInterface::capabilities
virtual int capabilities() const
Returns a bitmask containing the supported capabilities.
Definition: qgsrasterinterface.h:206
QgsVectorTileMVTDecoder::layers
QStringList layers() const
Returns a list of sub-layer names in a tile. It can only be called after a successful decode()
Definition: qgsvectortilemvtdecoder.cpp:53
QgsTileMatrix::tileRangeFromExtent
QgsTileRange tileRangeFromExtent(const QgsRectangle &mExtent)
Returns tile range that fully covers the given extent.
Definition: qgstiles.cpp:54
QgsRasterDataProvider
Base class for raster data providers.
Definition: qgsrasterdataprovider.h:89
qgsproject.h
QgsMapToolIdentify::canvasMoveEvent
void canvasMoveEvent(QgsMapMouseEvent *e) override
Mouse move event for overriding. Default implementation does nothing.
Definition: qgsmaptoolidentify.cpp:74
QgsMeshLayer::activeScalarDatasetAtTime
QgsMeshDatasetIndex activeScalarDatasetAtTime(const QgsDateTimeRange &timeRange) const
Returns dataset index from active scalar group depending on the time range.
Definition: qgsmeshlayer.cpp:630
QgsMeshLayer::snapOnElement
QgsPointXY snapOnElement(QgsMesh::ElementType elementType, const QgsPointXY &point, double searchRadius)
Returns the position of the snapped point on the mesh element closest to point intersecting with the ...
Definition: qgsmeshlayer.cpp:895
QgsTemporaryCursorOverride
Temporarily sets a cursor override for the QApplication for the lifetime of the object.
Definition: qgsguiutils.h:222
QgsGeometry::wkbType
QgsWkbTypes::Type wkbType() const SIP_HOLDGIL
Returns type of the geometry as a WKB type (point / linestring / polygon etc.)
Definition: qgsgeometry.cpp:345
qgsmeshlayertemporalproperties.h
QgsMapTool::toMapCoordinates
QgsPointXY toMapCoordinates(QPoint point)
transformation from screen coordinates to map coordinates
Definition: qgsmaptool.cpp:41
QgsTileRange::startColumn
int startColumn() const
Returns index of the first column in the range.
Definition: qgstiles.h:76
qgsrasterdataprovider.h
QgsFeatureId
qint64 QgsFeatureId
64 bit feature ids negative numbers are used for uncommitted/newly added features
Definition: qgsfeatureid.h:28
QgsDataProvider::crs
virtual QgsCoordinateReferenceSystem crs() const =0
Returns the coordinate system for the data source.
QgsMapToolIdentify::IdentifyResult
Definition: qgsmaptoolidentify.h:76
QgsVectorLayer::renderer
QgsFeatureRenderer * renderer()
Returns renderer.
Definition: qgsvectorlayer.h:892
QgsMesh::Vertex
@ Vertex
Definition: qgsmeshdataprovider.h:66
QgsMapLayer::type
QgsMapLayerType type
Definition: qgsmaplayer.h:90