68#include "moc_qgsmaptoolidentify.cpp"
70using namespace Qt::StringLiterals;
109 return identify( x, y, mode, QList<QgsMapLayer *>(), layerType, identifyContext );
119 return identify( geometry, mode, QList<QgsMapLayer *>(), layerType, identifyContext );
124 QList<IdentifyResult> results;
126 mLastGeometry = geometry;
127 mLastExtent =
mCanvas->extent();
128 mLastMapUnitsPerPixel =
mCanvas->mapUnitsPerPixel();
130 mCoordinatePrecision = QgsCoordinateUtils::calculateCoordinatePrecision( mLastMapUnitsPerPixel,
mCanvas->mapSettings().destinationCrs() );
141 int x = canvasPt.x(), y = canvasPt.y();
142 QList<IdentifyResult> results =
identify( x, y,
TopDownAll, layerList, layerType, identifyContext );
143 QPoint globalPos =
mCanvas->mapToGlobal( QPoint( x + 5, y + 5 ) );
146 else if ( mode ==
ActiveLayer && layerList.isEmpty() )
152 emit
identifyMessage( tr(
"No active layer. To identify features, you must choose an active layer." ) );
158 QApplication::setOverrideCursor( Qt::WaitCursor );
160 identifyLayer( &results,
layer, mLastGeometry, mLastExtent, mLastMapUnitsPerPixel, layerType, identifyContext );
164 QApplication::setOverrideCursor( Qt::WaitCursor );
166 QList<QgsMapLayer *> targetLayers;
167 if ( layerList.isEmpty() )
168 targetLayers =
mCanvas->layers(
true );
170 targetLayers = layerList;
172 const int layerCount = targetLayers.size();
173 for (
int i = 0; i < layerCount; i++ )
183 if (
identifyLayer( &results,
layer, mLastGeometry, mLastExtent, mLastMapUnitsPerPixel, layerType, identifyContext ) )
194 QApplication::restoreOverrideCursor();
201 mPropertiesOverrides.searchRadiusMapUnits = searchRadiusMapUnits;
206 mPropertiesOverrides.searchRadiusMapUnits = -1;
207 mPropertiesOverrides.skip3DLayers =
false;
212 mPropertiesOverrides = overrides;
218 mPropertiesOverrides.skip3DLayers =
false;
250 return identifyRasterLayer( results, qobject_cast<QgsRasterLayer *>(
layer ), geometry, viewExtent, mapUnitsPerPixel, identifyContext );
264 return identifyVectorTileLayer( results, qobject_cast<QgsVectorTileLayer *>(
layer ), geometry, identifyContext );
271 return identifyPointCloudLayer( results, qobject_cast<QgsPointCloudLayer *>(
layer ), geometry, identifyContext );
302 if ( mPropertiesOverrides.skip3DLayers &&
layer->renderer3D() )
307 if ( !
layer->elevationProperties()->isVisibleInZRange( identifyContext.
zRange() ) )
311 double searchRadius = mPropertiesOverrides.searchRadiusMapUnits < 0 ?
searchRadiusMU(
mCanvas ) : mPropertiesOverrides.searchRadiusMapUnits;
312 bool isTemporal = identifyContext.
isTemporal() &&
layer->temporalProperties()->isActive();
314 QList<QgsMeshDatasetIndex> datasetIndexList;
315 int activeScalarGroup =
layer->rendererSettings().activeScalarDatasetGroup();
316 int activeVectorGroup =
layer->rendererSettings().activeVectorDatasetGroup();
318 const QList<int> allGroup =
layer->enabledDatasetGroupsIndexes();
322 if ( activeScalarGroup >= 0 )
323 datasetIndexList.append(
layer->activeScalarDatasetAtTime( time ) );
324 if ( activeVectorGroup >= 0 && activeVectorGroup != activeScalarGroup )
325 datasetIndexList.append(
layer->activeVectorDatasetAtTime( time ) );
327 for (
int groupIndex : allGroup )
329 if ( groupIndex != activeScalarGroup && groupIndex != activeVectorGroup )
330 datasetIndexList.append(
layer->datasetIndexAtTime( time, groupIndex ) );
336 if ( activeScalarGroup >= 0 )
337 datasetIndexList.append(
layer->staticScalarDatasetIndex() );
338 if ( activeVectorGroup >= 0 && activeVectorGroup != activeScalarGroup )
339 datasetIndexList.append(
layer->staticVectorDatasetIndex() );
342 for (
int groupIndex : allGroup )
344 if ( groupIndex != activeScalarGroup && groupIndex != activeVectorGroup )
346 if ( !
layer->datasetGroupMetadata( groupIndex ).isTemporal() )
347 datasetIndexList.append( groupIndex );
355 if ( !index.isValid() )
359 QMap<QString, QString> derivedAttributes;
361 QMap<QString, QString> attribute;
365 const double scalar = scalarValue.
scalar();
366 attribute.insert( tr(
"Scalar Value" ), std::isnan( scalar ) ? tr(
"no data" ) : QLocale().toString( scalar ) );
372 const double vectorX = vectorValue.
x();
373 const double vectorY = vectorValue.
y();
374 if ( std::isnan( vectorX ) || std::isnan( vectorY ) )
375 attribute.insert( tr(
"Vector Value" ), tr(
"no data" ) );
378 attribute.insert( tr(
"Vector Magnitude" ), QLocale().toString( vectorValue.
scalar() ) );
379 derivedAttributes.insert( tr(
"Vector x-component" ), QLocale().toString( vectorY ) );
380 derivedAttributes.insert( tr(
"Vector y-component" ), QLocale().toString( vectorX ) );
387 derivedAttributes.insert( tr(
"Time Step" ),
layer->formatTime( meta.
time() ) );
388 derivedAttributes.insert( tr(
"Source" ), groupMeta.
uri() );
390 QString resultName = groupMeta.
name();
391 if ( isTemporal && ( index.group() == activeScalarGroup || index.group() == activeVectorGroup ) )
392 resultName.append( tr(
" (active)" ) );
396 results->append( result );
399 QMap<QString, QString> derivedGeometry;
402 const int vertexId =
layer->closestElement(
QgsMesh::Vertex, point, searchRadius, vertexPoint );
405 derivedGeometry.insert( tr(
"Snapped Vertex Index" ), QLocale().toString( vertexId ) );
406 derivedGeometry.insert( tr(
"Snapped Vertex Position X" ), QLocale().toString( vertexPoint.
x() ) );
407 derivedGeometry.insert( tr(
"Snapped Vertex Position Y" ), QLocale().toString( vertexPoint.
y() ) );
411 const int faceId =
layer->closestElement(
QgsMesh::Face, point, searchRadius, faceCentroid );
414 derivedGeometry.insert( tr(
"Face Index" ), QLocale().toString( faceId ) );
415 derivedGeometry.insert( tr(
"Face Centroid X" ), QLocale().toString( faceCentroid.
x() ) );
416 derivedGeometry.insert( tr(
"Face Centroid Y" ), QLocale().toString( faceCentroid.
y() ) );
420 const int edgeId =
layer->closestElement(
QgsMesh::Edge, point, searchRadius, pointOnEdge );
423 derivedGeometry.insert( tr(
"Edge Index" ), QLocale().toString( edgeId ) );
424 derivedGeometry.insert( tr(
"Point on Edge X" ), QLocale().toString( pointOnEdge.
x() ) );
425 derivedGeometry.insert( tr(
"Point on Edge Y" ), QLocale().toString( pointOnEdge.
y() ) );
430 results->append( result );
437 Q_UNUSED( identifyContext )
447 QgsTemporaryCursorOverride waitCursor( Qt::WaitCursor );
449 QMap<QString, QString> commonDerivedAttributes;
451 QgsGeometry selectionGeom = geometry;
452 bool isPointOrRectangle;
457 isPointOrRectangle =
true;
458 point = selectionGeom.
asPoint();
468 int featureCount = 0;
470 std::unique_ptr<QgsGeometryEngine> selectionGeomPrepared;
480 double sr = mPropertiesOverrides.searchRadiusMapUnits < 0 ?
searchRadiusMU(
mCanvas ) : mPropertiesOverrides.searchRadiusMapUnits;
487 if ( !isPointOrRectangle )
489 QgsCoordinateTransform ct(
mCanvas->mapSettings().destinationCrs(),
layer->crs(),
mCanvas->mapSettings().transformContext() );
498 const double tileScale =
layer->tileMatrixSet().calculateTileScaleForMap(
500 mCanvas->mapSettings().destinationCrs(),
501 mCanvas->mapSettings().extent(),
506 const int tileZoom =
layer->tileMatrixSet().scaleToZoomLevel( tileScale );
507 const QgsTileMatrix tileMatrix =
layer->tileMatrixSet().tileMatrix( tileZoom );
510 const QVector<QgsTileXYZ> tiles =
layer->tileMatrixSet().tilesInRange( tileRange, tileZoom );
512 for (
const QgsTileXYZ &tileID : tiles )
514 const QgsVectorTileRawData data =
layer->getRawTile( tileID );
515 if ( data.
data.isEmpty() )
518 QgsVectorTileMVTDecoder decoder(
layer->tileMatrixSet() );
519 if ( !decoder.decode( data ) )
522 QMap<QString, QgsFields> perLayerFields;
523 const QStringList layerNames = decoder.layers();
524 for (
const QString &layerName : layerNames )
526 QSet<QString> fieldNames = qgis::listToSet( decoder.layerFieldNames( layerName ) );
530 const QgsVectorTileFeatures features = decoder.layerFeatures( perLayerFields, QgsCoordinateTransform() );
531 const QStringList featuresLayerNames = features.keys();
532 for (
const QString &layerName : featuresLayerNames )
534 const QgsFields fFields = perLayerFields[layerName];
535 const QVector<QgsFeature> &layerFeatures = features[layerName];
536 for (
const QgsFeature &f : layerFeatures )
538 if ( f.geometry().intersects( r ) && ( !selectionGeomPrepared || selectionGeomPrepared->intersects( f.geometry().constGet() ) ) )
540 QMap<QString, QString> derivedAttributes = commonDerivedAttributes;
541 derivedAttributes.insert( tr(
"Feature ID" ),
FID_TO_STRING( f.id() ) );
542 derivedAttributes.insert( tr(
"Tile column" ), QString::number( tileID.column() ) );
543 derivedAttributes.insert( tr(
"Tile row" ), QString::number( tileID.row() ) );
544 derivedAttributes.insert( tr(
"Tile zoom" ), QString::number( tileID.zoomLevel() ) );
554 catch ( QgsCsException &cse )
561 return featureCount > 0;
566 if ( mPropertiesOverrides.skip3DLayers &&
layer->renderer3D() )
571 if ( !
layer->elevationProperties()->isVisibleInZRange( identifyContext.
zRange(),
layer ) )
575 QgsPointCloudRenderer *renderer =
layer->renderer();
582 const double searchRadiusMapUnits = mPropertiesOverrides.searchRadiusMapUnits < 0 ?
searchRadiusMU(
mCanvas ) : mPropertiesOverrides.searchRadiusMapUnits;
584 const QVector<QVariantMap> points = renderer->
identify(
layer, context, geometry, searchRadiusMapUnits );
593 QMap<QString, QString> derivedAttributes;
597 formatCoordinate( point, x, y );
599 derivedAttributes.insert( tr(
"(clicked coordinate X)" ), x );
600 derivedAttributes.insert( tr(
"(clicked coordinate Y)" ), y );
602 derivedAttributes.insert( tr(
"(clicked coordinate Z)" ), QLocale().toString( point.
z(),
'f' ) );
603 return derivedAttributes;
620 QString temporalFilter;
623 if ( !
layer->temporalProperties()->isVisibleInTemporalRange( identifyContext.
temporalRange() ) )
626 QgsVectorLayerTemporalContext temporalContext;
628 temporalFilter = qobject_cast<const QgsVectorLayerTemporalProperties *>(
layer->temporalProperties() )->createFilterString( temporalContext, identifyContext.
temporalRange() );
633 QApplication::setOverrideCursor( Qt::WaitCursor );
635 QMap<QString, QString> commonDerivedAttributes;
637 QgsGeometry selectionGeom = geometry;
638 bool isPointOrRectangle;
643 isPointOrRectangle =
true;
655 std::unique_ptr<QgsGeometryEngine> selectionGeomPrepared;
665 double sr = mPropertiesOverrides.searchRadiusMapUnits < 0 ?
searchRadiusMU(
mCanvas ) : mPropertiesOverrides.searchRadiusMapUnits;
672 if ( !isPointOrRectangle )
674 QgsCoordinateTransform ct(
mCanvas->mapSettings().destinationCrs(),
layer->crs(),
mCanvas->mapSettings().transformContext() );
683 QgsFeatureRequest featureRequest;
686 if ( !temporalFilter.isEmpty() )
689 QgsFeatureIterator fit =
layer->getFeatures( featureRequest );
693 if ( !selectionGeomPrepared || selectionGeomPrepared->intersects( f.
geometry().
constGet() ) )
694 featureList << QgsFeature( f );
697 catch ( QgsCsException &cse )
709 std::unique_ptr<QgsFeatureRenderer> renderer(
layer->renderer() ?
layer->renderer()->clone() :
nullptr );
718 if ( !isSingleClick )
721 const int featureCount =
identifyVectorLayer( results,
layer, featureList, filter ? renderer.get() :
nullptr, commonDerivedAttributes, [point,
layer,
this](
const QgsFeature &feature ) -> QMap<QString, QString> { return featureDerivedAttributes( feature, layer, toLayerCoordinates( layer, point ) ); }, context );
727 QApplication::restoreOverrideCursor();
728 return featureCount > 0;
733 int featureCount = 0;
734 for (
const QgsFeature &feature : std::as_const( features ) )
736 QMap<QString, QString> derivedAttributes = commonDerivedAttributes;
744 derivedAttributes.insert( deriveAttributesForFeature( feature ) );
745 derivedAttributes.insert( tr(
"Feature ID" ), fid < 0 ? tr(
"new feature" ) :
FID_TO_STRING( fid ) );
747 results->append(
IdentifyResult( qobject_cast<QgsMapLayer *>(
layer ), feature, derivedAttributes ) );
762 QString str = QLocale().toString( vId.
vertex + 1 );
763 derivedAttributes.insert( tr(
"Closest vertex number" ), str );
765 QgsPoint closestPoint = geometry.
vertexAt( vId );
766 QgsPoint closestPointMapCoords = closestPoint;
767 if ( layerToMapTransform.
isValid() )
773 catch ( QgsCsException &cse )
781 formatCoordinate( closestPointMapCoords, x, y );
782 derivedAttributes.insert( tr(
"Closest vertex X" ), x );
783 derivedAttributes.insert( tr(
"Closest vertex Y" ), y );
785 if ( closestPoint.
is3D() )
787 str = QLocale().toString( closestPoint.
z(),
'g', 10 );
790 if ( showTransformedZ && !std::isnan( closestPointMapCoords.
z() ) && !
qgsDoubleNear( closestPoint.
z(), closestPointMapCoords.
z() ) )
792 const QString str = QLocale().toString( closestPointMapCoords.
z(),
'g', 10 );
798 str = QLocale().toString( closestPointMapCoords.
m(),
'g', 10 );
799 derivedAttributes.insert( tr(
"Closest vertex M" ), str );
804 double radius, centerX, centerY;
805 QgsVertexId vIdBefore = vId;
807 QgsVertexId vIdAfter = vId;
810 derivedAttributes.insert( u
"Closest vertex radius"_s, QLocale().toString( radius ) );
817 QgsPoint closestPointMapCrs = closestPoint;
818 if ( layerToMapTransform.
isValid() )
824 catch ( QgsCsException &cse )
832 formatCoordinate( closestPoint, x, y );
833 derivedAttributes.insert( tr(
"Closest X" ), x );
834 derivedAttributes.insert( tr(
"Closest Y" ), y );
836 if ( closestPoint.
is3D() )
838 const QString str = QLocale().toString( closestPoint.
z(),
'g', 10 );
841 if ( showTransformedZ && !std::isnan( closestPointMapCrs.
z() ) && !
qgsDoubleNear( closestPoint.
z(), closestPointMapCrs.
z() ) )
843 const QString str = QLocale().toString( closestPointMapCrs.
z(),
'g', 10 );
849 const QString str = QLocale().toString( closestPoint.
m(),
'g', 10 );
850 derivedAttributes.insert( tr(
"Interpolated M" ), str );
856 QgsCoordinateUtils::formatCoordinatePartsForProject(
QgsProject::instance(), canvasPoint, mapCrs, coordinatePrecision, x, y );
859void QgsMapToolIdentify::formatCoordinate(
const QgsPointXY &canvasPoint, QString &x, QString &y )
const
861 formatCoordinate( canvasPoint, x, y,
mCanvas->mapSettings().destinationCrs(), mCoordinatePrecision );
868 QMap<QString, QString> derivedAttributes;
872 QgsDistanceArea calc;
880 QgsPoint closestPoint;
894 QString str = QLocale().toString(
static_cast<const QgsGeometryCollection *
>( feature.
geometry().
constGet() )->numGeometries() );
895 derivedAttributes.insert( tr(
"Parts" ), str );
898 str = QLocale().toString( vId.
part + 1 );
899 derivedAttributes.insert( tr(
"Part number" ), str );
904 ? displayDistanceUnits()
905 :
layer->crs().mapUnits();
908 : QgsUnitTypes::distanceToAreaUnit(
layer->crs().mapUnits() );
912 const QgsCoordinateReferenceSystem layerVertCrs =
layer->crs3D().verticalCrs().isValid() ?
layer->crs3D().verticalCrs()
917 const QgsGeometry layerCrsGeometry = feature.
geometry();
918 QgsGeometry mapCrsGeometry = layerCrsGeometry;
921 if ( layerToMapTransform.
isValid() )
926 catch ( QgsCsException &cse )
933 const QgsAbstractGeometry *layerCrsGeom = layerCrsGeometry.
constGet();
941 catch ( QgsCsException & )
944 QgsDebugError( u
"An error occurred while calculating length"_s );
950 str = formatDistance( dist );
951 derivedAttributes.insert( tr(
"Length (Ellipsoidal — %1)" ).arg( ellipsoid ), str );
959 derivedAttributes.insert( tr(
"Length (Cartesian — 2D)" ), str );
961 double totalLength3d = std::accumulate( layerCrsGeom->
const_parts_begin(), layerCrsGeom->
const_parts_end(), 0.0, [](
double total,
const QgsAbstractGeometry *part ) {
962 return total + qgsgeometry_cast<const QgsLineString *>( part )->length3D();
965 str = formatDistance( totalLength3d, cartesianDistanceUnits );
966 derivedAttributes.insert( tr(
"Length (Cartesian — 3D)" ), str );
970 derivedAttributes.insert( tr(
"Length (Cartesian)" ), str );
973 str = QLocale().toString( layerCrsGeom->
nCoordinates() );
974 derivedAttributes.insert( tr(
"Vertices" ), str );
978 closestVertexAttributes( layerToMapTransform, layerVertCrs, mapVertCrs, *layerCrsGeom, vId, showTransformedZ, derivedAttributes );
979 closestPointAttributes( layerToMapTransform, layerVertCrs, mapVertCrs, *layerCrsGeom, layerPoint, showTransformedZ, derivedAttributes );
985 QgsPointXY pnt =
mCanvas->mapSettings().layerToMapCoordinates(
layer, QgsPointXY( curve->startPoint().x(), curve->startPoint().y() ) );
988 formatCoordinate( pnt, x, y );
989 derivedAttributes.insert( tr(
"firstX",
"attributes get sorted; translation for lastX should be lexically larger than this one" ), x );
990 derivedAttributes.insert( tr(
"firstY" ), y );
991 pnt =
mCanvas->mapSettings().layerToMapCoordinates(
layer, QgsPointXY( curve->endPoint().x(), curve->endPoint().y() ) );
992 formatCoordinate( pnt, x, y );
993 derivedAttributes.insert( tr(
"lastX",
"attributes get sorted; translation for firstX should be lexically smaller than this one" ), x );
994 derivedAttributes.insert( tr(
"lastY" ), y );
1005 catch ( QgsCsException & )
1008 QgsDebugError( u
"An error occurred while calculating area"_s );
1014 str = formatArea( area );
1015 derivedAttributes.insert( tr(
"Area (Ellipsoidal — %1)" ).arg( ellipsoid ), str );
1018 derivedAttributes.insert( tr(
"Area (Cartesian)" ), str );
1022 double perimeter = 0;
1028 catch ( QgsCsException & )
1031 QgsDebugError( u
"An error occurred while calculating perimeter"_s );
1033 str = formatDistance( perimeter );
1034 derivedAttributes.insert( tr(
"Perimeter (Ellipsoidal — %1)" ).arg( ellipsoid ), str );
1037 derivedAttributes.insert( tr(
"Perimeter (Cartesian)" ), str );
1040 derivedAttributes.insert( tr(
"Vertices" ), str );
1045 closestVertexAttributes( layerToMapTransform, layerVertCrs, mapVertCrs, *layerCrsGeometry.
constGet(), vId, showTransformedZ, derivedAttributes );
1046 closestPointAttributes( layerToMapTransform, layerVertCrs, mapVertCrs, *layerCrsGeometry.
constGet(), layerPoint, showTransformedZ, derivedAttributes );
1056 formatCoordinate( QgsPointXY( mapCrsPoint->x(), mapCrsPoint->y() ), x, y );
1057 derivedAttributes.insert( tr(
"X" ), x );
1058 derivedAttributes.insert( tr(
"Y" ), y );
1061 : std::numeric_limits<double>::quiet_NaN();
1062 const double mapCrsZ = mapCrsPoint->is3D() ? mapCrsPoint->z() : std::numeric_limits<double>::quiet_NaN();
1064 if ( !std::isnan( originalZ ) )
1066 const QString str = QLocale().toString( originalZ,
'g', 10 );
1069 if ( showTransformedZ && !std::isnan( mapCrsZ ) && !
qgsDoubleNear( originalZ, mapCrsZ ) )
1071 const QString str = QLocale().toString( mapCrsZ,
'g', 10 );
1078 derivedAttributes.insert( tr(
"M" ), str );
1087 const QgsAbstractGeometry *geom = layerCrsGeometry.
constGet();
1088 closestVertexAttributes( layerToMapTransform, layerVertCrs, mapVertCrs, *geom, vId, showTransformedZ, derivedAttributes );
1098 return derivedAttributes;
1103 QgsPointXY point = geometry.
asPoint();
1113 std::unique_ptr<QgsRasterDataProvider> dprovider(
layer->dataProvider()->clone() );
1123 if ( !
layer->temporalProperties()->isVisibleInTemporalRange( identifyContext.
temporalRange() ) )
1126 dprovider->temporalCapabilities()->setRequestedTemporalRange( identifyContext.
temporalRange() );
1131 if ( !
layer->elevationProperties()->isVisibleInZRange( identifyContext.
zRange(),
layer ) )
1148 if ( !
layer->extent().contains( point ) )
1151 QMap<QString, QString> attributes, derivedAttributes;
1172 if ( dprovider->crs() !=
mCanvas->mapSettings().destinationCrs() )
1181 r.
setXMinimum( pointInCanvasCrs.
x() - mapUnitsPerPixel / 2. );
1182 r.
setXMaximum( pointInCanvasCrs.
x() + mapUnitsPerPixel / 2. );
1183 r.
setYMinimum( pointInCanvasCrs.
y() - mapUnitsPerPixel / 2. );
1184 r.
setYMaximum( pointInCanvasCrs.
y() + mapUnitsPerPixel / 2. );
1188 identifyResult = dprovider->identify( point, format, r, 1, 1 );
1204 int width =
static_cast<int>( std::round( viewExtent.
width() / mapUnitsPerPixel ) );
1205 int height =
static_cast<int>( std::round( viewExtent.
height() / mapUnitsPerPixel ) );
1208 QgsDebugMsgLevel( u
"width = %1 height = %2"_s.arg( width ).arg( height ), 2 );
1209 QgsDebugMsgLevel( u
"xRes = %1 yRes = %2 mapUnitsPerPixel = %3"_s.arg( viewExtent.
width() / width ).arg( viewExtent.
height() / height ).arg( mapUnitsPerPixel ), 2 );
1211 identifyResult = dprovider->identify( point, format, viewExtent, width, height );
1222 bool foundMatch =
false;
1223 QMap<int, QVariant> values = identifyResult.
results();
1224 QMap<int, QVariant> filteredValues;
1225 for (
auto it = values.constBegin(); it != values.constEnd(); ++it )
1231 const double value = it.value().toDouble();
1235 filteredValues.insert( it.key(), it.value() );
1259 const double xres =
layer->rasterUnitsPerPixelX();
1260 const double yres =
layer->rasterUnitsPerPixelY();
1268 const int rasterCol =
static_cast<int>( std::floor( ( point.
x() - extent.
xMinimum() ) / xres ) );
1269 const int rasterRow =
static_cast<int>( std::floor( ( extent.
yMaximum() - point.
y() ) / yres ) );
1271 derivedAttributes.insert( tr(
"Column (0-based)" ), QLocale().toString( rasterCol ) );
1272 derivedAttributes.insert( tr(
"Row (0-based)" ), QLocale().toString( rasterRow ) );
1277 if ( identifyResult.
isValid() )
1279 QMap<int, QVariant> values = identifyResult.
results();
1282 for (
auto it = values.constBegin(); it != values.constEnd(); ++it )
1284 QString valueString;
1287 valueString = tr(
"no data" );
1291 QVariant value( it.value() );
1295 if (
static_cast<QMetaType::Type
>( value.userType() ) == QMetaType::Float )
1304 attributes.insert( dprovider->generateBandName( it.key() ), valueString );
1310 const double doubleValue { it.value().toDouble( &ok ) };
1313 const QVariantList row = rat->row( doubleValue );
1314 if ( !row.isEmpty() )
1316 for (
int colIdx = 0; colIdx < std::min( rat->fields().count(), row.count() ); ++colIdx )
1327 switch ( ratField.
type )
1329 case QMetaType::Type::QChar:
1330 case QMetaType::Type::Int:
1331 case QMetaType::Type::UInt:
1332 case QMetaType::Type::LongLong:
1333 case QMetaType::Type::ULongLong:
1334 ratValue = QLocale().toString( row.at( colIdx ).toLongLong() );
1336 case QMetaType::Type::Double:
1337 ratValue = QLocale().toString( row.at( colIdx ).toDouble() );
1340 ratValue = row.at( colIdx ).toString();
1342 attributes.insert( ratField.
name, ratValue );
1349 QString label =
layer->name();
1351 if ( !pixelRect.
isNull() )
1358 results->append( result );
1362 for (
auto it = values.constBegin(); it != values.constEnd(); ++it )
1364 QVariant value = it.value();
1365 if ( value.userType() == QMetaType::Type::Bool && !value.toBool() )
1371 if ( value.userType() == QMetaType::Type::QString )
1375 QString label =
layer->subLayers().value( it.key() );
1377 attributes.insert( tr(
"Error" ), value.toString() );
1379 results->append(
IdentifyResult( qobject_cast<QgsMapLayer *>(
layer ), label, attributes, derivedAttributes ) );
1389 for (
const QgsFeature &feature : storeFeatures )
1395 QString sublayer = featureStore.params().value( u
"sublayer"_s ).toString();
1396 QString featureType = featureStore.params().value( u
"featureType"_s ).toString();
1398 featureType.remove( u
"_feature"_s );
1400 if ( sublayer.compare(
layer->name(), Qt::CaseInsensitive ) != 0 )
1404 if ( featureType.compare( sublayer, Qt::CaseInsensitive ) != 0 || labels.isEmpty() )
1406 labels << featureType;
1409 QMap<QString, QString> derAttributes = derivedAttributes;
1412 IdentifyResult identifyResult( qobject_cast<QgsMapLayer *>(
layer ), labels.join(
" / "_L1 ), featureStore.fields(), feature, derAttributes );
1414 identifyResult.
mParams.insert( u
"getFeatureInfoUrl"_s, featureStore.params().value( u
"getFeatureInfoUrl"_s ) );
1415 results->append( identifyResult );
1423 for (
auto it = values.constBegin(); it != values.constEnd(); ++it )
1425 QString value = it.value().toString();
1427 attributes.insert( QString(), value );
1429 QString label =
layer->subLayers().value( it.key() );
1430 results->append(
IdentifyResult( qobject_cast<QgsMapLayer *>(
layer ), label, attributes, derivedAttributes ) );
1438 attributes.insert( tr(
"Error" ), value );
1439 QString label = tr(
"Identify error" );
1440 results->append(
IdentifyResult( qobject_cast<QgsMapLayer *>(
layer ), label, attributes, derivedAttributes ) );
1456QString QgsMapToolIdentify::formatDistance(
double distance )
const
1458 return formatDistance( distance, displayDistanceUnits() );
1461QString QgsMapToolIdentify::formatArea(
double area )
const
1463 return formatArea( area, displayAreaUnits() );
1466QString QgsMapToolIdentify::formatDistance(
double distance,
Qgis::DistanceUnit unit )
const
1468 QgsSettings settings;
1469 bool baseUnit = settings.
value( u
"qgis/measure/keepbaseunit"_s,
true ).toBool();
1474QString QgsMapToolIdentify::formatArea(
double area,
Qgis::AreaUnit unit )
const
1476 QgsSettings settings;
1477 bool baseUnit = settings.
value( u
"qgis/measure/keepbaseunit"_s,
true ).toBool();
1484 QList<IdentifyResult> results;
1502 for (
const QVariantMap &pt : identified )
1504 QMap<QString, QString> ptStr;
1505 QString classification;
1506 for (
auto attrIt = pt.constBegin(); attrIt != pt.constEnd(); ++attrIt )
1508 if ( attrIt.key().compare(
'Z'_L1, Qt::CaseInsensitive ) == 0
1512 ptStr[tr(
"Z (original)" )] = attrIt.value().toString();
1513 ptStr[tr(
"Z (adjusted)" )] = QString::number( attrIt.value().toDouble() * elevationProps->
zScale() + elevationProps->
zOffset() );
1515 else if ( attrIt.key().compare(
"Classification"_L1, Qt::CaseInsensitive ) == 0 )
1518 ptStr[attrIt.key()] = u
"%1 (%2)"_s.arg( attrIt.value().toString(), classification );
1522 ptStr[attrIt.key()] = attrIt.value().toString();
1526 QMap<QString, QString> derivedAttributes;
1527 QgsPoint layerPoint( pt.value(
"X" ).toDouble(), pt.value(
"Y" ).toDouble(), pt.value(
"Z" ).toDouble() );
1532 if ( layerToMapTransform.
isValid() )
1547 derivedAttributes.insert( tr(
"X" ), x );
1548 derivedAttributes.insert( tr(
"Y" ), y );
1550 const double originalZ = layerPoint.
z();
1551 const double mapCrsZ = mapCrsPoint.
is3D() ? mapCrsPoint.
z() : std::numeric_limits<double>::quiet_NaN();
1553 if ( !std::isnan( originalZ ) )
1555 const QString str = QLocale().toString( originalZ,
'g', 10 );
1558 if ( showTransformedZ && !std::isnan( mapCrsZ ) && !
qgsDoubleNear( originalZ, mapCrsZ ) )
1560 const QString str = QLocale().toString( mapCrsZ,
'g', 10 );
1565 results.append( res );
1575 if ( identified.empty() )
1578 switch (
layer->type() )
1585 QHash<QgsFeatureId, QVariant> featureDistances;
1586 QHash<QgsFeatureId, QVariant> featureElevations;
1589 for (
const QVariantMap &map : identified )
1591 if ( !map.contains( u
"id"_s ) )
1593 QMap<QString, QString> attributes;
1594 if ( map.value( u
"distance"_s ).isValid() )
1595 attributes.insert( tr(
"Distance along curve" ), QString::number( map.value( u
"distance"_s ).toDouble() ) );
1596 if ( map.value( u
"elevation"_s ).isValid() )
1597 attributes.insert( tr(
"Elevation" ), QString::number( map.value( u
"elevation"_s ).toDouble() ) );
1603 const QgsFeatureId id = map.value( u
"id"_s ).toLongLong();
1604 filterIds.insert(
id );
1606 featureDistances.insert(
id, map.value( u
"distance"_s ) );
1607 featureElevations.insert(
id, map.value( u
"elevation"_s ) );
1619 identifyVectorLayer( &results, vl, features,
nullptr, QMap<QString, QString>(), [
this, vl, &featureDistances, &featureElevations](
const QgsFeature &feature ) -> QMap<QString, QString> {
1620 QMap< QString, QString > attributes = featureDerivedAttributes( feature, vl,
QgsPointXY() );
1622 if ( featureDistances.value( feature.
id() ).isValid() )
1623 attributes.insert( tr(
"Distance along curve" ), QString::number( featureDistances.value( feature.
id() ).toDouble() ) );
1624 if ( featureElevations.value( feature.
id() ).isValid() )
1625 attributes.insert( tr(
"Elevation" ), QString::number( featureElevations.value( feature.
id() ).toDouble() ) );
1627 return attributes; }, context );
1634 for (
const QVariantMap &map : identified )
1636 QMap<QString, QString> attributes;
1637 if ( map.value( u
"distance"_s ).isValid() )
1638 attributes.insert( tr(
"Distance along curve" ), QString::number( map.value( u
"distance"_s ).toDouble() ) );
1639 if ( map.value( u
"elevation"_s ).isValid() )
1640 attributes.insert( tr(
"Elevation" ), QString::number( map.value( u
"elevation"_s ).toDouble() ) );
@ FeatureSymbology
Provider is able retrieve embedded symbology associated with individual features.
@ MediumString
A medium-length string, recommended for general purpose use.
DistanceUnit
Units of distance.
@ ExactIntersect
Use exact geometry intersection (slower) instead of bounding boxes.
@ EmbeddedSymbols
Retrieve any embedded feature symbology.
@ Curve
An intermediate point on a segment defining the curvature of the segment.
QFlags< RasterInterfaceCapability > RasterInterfaceCapabilities
Raster interface capabilities.
QFlags< FeatureRequestFlag > FeatureRequestFlags
Flags for controlling feature requests.
GeometryType
The geometry types are used to group Qgis::WkbType in a coarse way.
@ Size
Original data source size (and thus resolution) is known, it is not always available,...
@ IdentifyValue
Numerical values.
@ Identify
At least one identify format supported.
@ IdentifyFeature
WMS GML -> feature.
@ Group
Composite group layer. Added in QGIS 3.24.
@ Plugin
Plugin based layer.
@ TiledScene
Tiled scene layer. Added in QGIS 3.34.
@ Annotation
Contains freeform, georeferenced annotations. Added in QGIS 3.16.
@ VectorTile
Vector tile layer. Added in QGIS 3.14.
@ Mesh
Mesh layer. Added in QGIS 3.2.
@ PointCloud
Point cloud layer. Added in QGIS 3.18.
static QString geoNone()
Constant that holds the string representation for "No ellipse/No CRS".
RasterIdentifyFormat
Raster identify formats.
@ Feature
WMS GML/JSON -> feature.
@ Value
Numerical pixel value.
WkbType
The WKB type describes the number of dimensions a geometry has.
@ Forward
Forward transform (from source to destination).
Abstract base class for all geometries.
bool isMeasure() const
Returns true if the geometry contains m values.
bool is3D() const
Returns true if the geometry is 3D and contains a z-value.
virtual double perimeter() const
Returns the planar, 2-dimensional perimeter of the geometry.
virtual int nCoordinates() const
Returns the number of nodes contained in the geometry.
virtual QgsPoint vertexAt(QgsVertexId id) const =0
Returns the point corresponding to a specified vertex id.
Qgis::WkbType wkbType() const
Returns the WKB type of the geometry.
virtual double length() const
Returns the planar, 2-dimensional length of the geometry.
const_part_iterator const_parts_end() const
Returns STL-style iterator pointing to the imaginary const part after the last part of the geometry.
const_part_iterator const_parts_begin() const
Returns STL-style iterator pointing to the const first part of the geometry.
static QCursor getThemeCursor(Cursor cursor)
Helper to get a theme cursor.
@ Identify
Identify: obtain information about the object.
Represents a coordinate reference system (CRS).
bool isValid() const
Returns whether this CRS is correctly initialized and usable.
bool hasVerticalAxis() const
Returns true if the CRS has a vertical axis.
QString userFriendlyIdentifier(Qgis::CrsIdentifierType type=Qgis::CrsIdentifierType::MediumString) const
Returns a user friendly identifier for the CRS.
QgsCoordinateReferenceSystem verticalCrs() const
Returns the vertical CRS associated with this CRS object.
Custom exception class for Coordinate Reference System related exceptions.
static QString formatDistance(double distance, int decimals, Qgis::DistanceUnit unit, bool keepBaseUnit=false)
Returns an distance formatted as a friendly string.
double measureArea(const QgsGeometry &geometry) const
Measures the area of a geometry.
double convertLengthMeasurement(double length, Qgis::DistanceUnit toUnits) const
Takes a length measurement calculated by this QgsDistanceArea object and converts it to a different d...
double measurePerimeter(const QgsGeometry &geometry) const
Measures the perimeter of a polygon geometry.
double measureLength(const QgsGeometry &geometry) const
Measures the length of a geometry.
void setSourceCrs(const QgsCoordinateReferenceSystem &crs, const QgsCoordinateTransformContext &context)
Sets source spatial reference system crs.
bool setEllipsoid(const QString &ellipsoid)
Sets the ellipsoid by its acronym.
double convertAreaMeasurement(double area, Qgis::AreaUnit toUnits) const
Takes an area measurement calculated by this QgsDistanceArea object and converts it to a different ar...
static QString formatArea(double area, int decimals, Qgis::AreaUnit unit, bool keepBaseUnit=false)
Returns an area formatted as a friendly string.
QgsRange which stores a range of double values.
bool isInfinite() const
Returns true if the range consists of all possible values.
QString message(QgsErrorMessage::Format format=QgsErrorMessage::Html) const
Full error messages description.
static QgsExpressionContextScope * layerScope(const QgsMapLayer *layer)
Creates a new scope which contains variables and functions relating to a QgsMapLayer.
void setFeature(const QgsFeature &feature)
Convenience function for setting a feature for the context.
Wrapper for iterator of features from vector data provider or vector layer.
bool nextFeature(QgsFeature &f)
Fetch next feature and stores in f, returns true on success.
Abstract base class for all 2D vector feature renderers.
@ Filter
Features may be filtered, i.e. some features may not be rendered (categorized, rule based ....
virtual bool willRenderFeature(const QgsFeature &feature, QgsRenderContext &context) const
Returns whether the renderer will render a feature or not.
Wraps a request for features to a vector layer (or directly its vector data provider).
QgsFeatureRequest & setFlags(Qgis::FeatureRequestFlags flags)
Sets flags that affect how features will be fetched.
QgsFeatureRequest & setFilterFids(const QgsFeatureIds &fids)
Sets the feature IDs that should be fetched.
QgsFeatureRequest & setFilterExpression(const QString &expression)
Set the filter expression.
QgsFeatureRequest & setFilterRect(const QgsRectangle &rectangle)
Sets the rectangle from which features will be taken.
A container for features with the same fields and crs.
The feature class encapsulates a single feature including its unique ID, geometry and a list of field...
const QgsSymbol * embeddedSymbol() const
Returns the feature's embedded symbology, or nullptr if the feature has no embedded symbol.
bool hasGeometry() const
Returns true if the feature has an associated geometry.
void setGeometry(const QgsGeometry &geometry)
Set the feature's geometry.
Container of fields for a vector layer.
static QgsPoint closestPoint(const QgsAbstractGeometry &geometry, const QgsPoint &point)
Returns the nearest point on a segment of a geometry for the specified point.
static void circleCenterRadius(const QgsPoint &pt1, const QgsPoint &pt2, const QgsPoint &pt3, double &radius, double ¢erX, double ¢erY)
Returns radius and center of the circle through pt1, pt2, pt3.
static QgsPoint closestVertex(const QgsAbstractGeometry &geom, const QgsPoint &pt, QgsVertexId &id)
Returns the closest vertex to a geometry for a specified point.
A geometry is the spatial representation of a feature.
static QgsGeometry fromRect(const QgsRectangle &rect)
Creates a new geometry from a QgsRectangle.
Qgis::GeometryOperationResult transform(const QgsCoordinateTransform &ct, Qgis::TransformDirection direction=Qgis::TransformDirection::Forward, bool transformZ=false)
Transforms this geometry as described by the coordinate transform ct.
const QgsAbstractGeometry * constGet() const
Returns a non-modifiable (const) reference to the underlying abstract geometry primitive.
QgsPointXY asPoint() const
Returns the contents of the geometry as a 2-dimensional point.
static QgsGeometry fromPointXY(const QgsPointXY &point)
Creates a new geometry from a QgsPointXY object.
double area() const
Returns the planar, 2-dimensional area of the geometry.
QgsRectangle boundingBox() const
Returns the bounding box of the geometry.
Qgis::WkbType wkbType() const
Returns type of the geometry as a WKB type (point / linestring / polygon etc.).
bool isGeosEqual(const QgsGeometry &) const
Compares the geometry with another geometry using GEOS.
static QgsGeometryEngine * createGeometryEngine(const QgsAbstractGeometry *geometry, double precision=0.0, Qgis::GeosCreationFlags flags=Qgis::GeosCreationFlag::SkipEmptyInteriorRings)
Creates and returns a new geometry engine representing the specified geometry using precision on a gr...
Identify contexts are used to encapsulate the settings to be used to perform an identify action.
bool isTemporal() const
Returns true if the temporal range setting is enabled.
const QgsDateTimeRange & temporalRange() const
Returns the datetime range to be used with the identify action.
QgsDoubleRange zRange() const
Returns the range of z-values to identify within, or an infinite range if no filtering by z should be...
double zScale() const
Returns the z scale, which is a scaling factor which should be applied to z values from the layer.
double zOffset() const
Returns the z offset, which is a fixed offset amount which should be added to z values from the layer...
Base class for all map layer types.
virtual bool isSpatial() const
Returns true if the layer is considered a spatial layer, ie it has some form of geometry associated w...
QgsAbstract3DRenderer * renderer3D() const
Returns 3D renderer associated with the layer.
bool isInScaleRange(double scale) const
Tests whether the layer should be visible at the specified scale.
@ Identifiable
If the layer is identifiable using the identify map tool and as a WMS layer.
virtual Q_INVOKABLE QgsDataProvider * dataProvider()
Returns the layer's data provider, it may be nullptr.
A mouse event which is the result of a user interaction with a QgsMapCanvas.
An index that identifies the dataset group (e.g.
Represents a single mesh dataset value.
double y() const
Returns y value.
double scalar() const
Returns magnitude of vector for vector data or scalar value for scalar data.
double x() const
Returns x value.
Represents a mesh layer supporting display of data on structured or unstructured meshes.
static void logMessage(const QString &message, const QString &tag=QString(), Qgis::MessageLevel level=Qgis::MessageLevel::Warning, bool notifyUser=true, const char *file=__builtin_FILE(), const char *function=__builtin_FUNCTION(), int line=__builtin_LINE(), Qgis::StringFormat format=Qgis::StringFormat::PlainText)
Adds a message to the log instance (and creates it if necessary).
static QMap< int, QString > translatedLasClassificationCodes()
Returns the map of LAS classification code to translated string value, corresponding to the ASPRS Sta...
Point cloud layer specific subclass of QgsMapLayerElevationProperties.
Represents a map layer supporting display of point clouds.
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...
virtual void startRender(QgsPointCloudRenderContext &context)
Must be called when a new render cycle is started.
virtual void stopRender(QgsPointCloudRenderContext &context)
Must be called when a render cycle has finished, to allow the renderer to clean up.
QString toString(int precision=-1) const
Returns a string representation of the point (x, y) with a preset precision.
bool isEmpty() const
Returns true if the geometry is empty.
Point geometry type, with support for z-dimension and m-values.
void transform(const QgsCoordinateTransform &ct, Qgis::TransformDirection d=Qgis::TransformDirection::Forward, bool transformZ=false) override
Transforms the geometry using a coordinate transform.
static QgsProject * instance()
Returns the QgsProject singleton instance.
QgsCoordinateTransformContext transformContext
QgsCoordinateReferenceSystem crs3D() const
Returns the CRS to use for the project when transforming 3D data, or when z/elevation value handling ...
bool overlaps(const QgsRange< T > &other) const
Returns true if this range overlaps another range.
The Field class represents a Raster Attribute Table field, including its name, usage and type.
Qgis::RasterAttributeTableFieldUsage usage
Represents a Raster Attribute Table (RAT).
static QList< Qgis::RasterAttributeTableFieldUsage > valueAndColorFieldUsages()
Returns the list of field usages for colors and values.
static QString printValue(double value, bool localized=false)
Print double value with all necessary significant digits.
static Qgis::RasterInterfaceCapability identifyFormatToCapability(Qgis::RasterIdentifyFormat format)
Converts a raster identify format to a capability.
static Qgis::RasterIdentifyFormat identifyFormatFromName(const QString &formatName)
Converts a string formatName to a raster identify format.
Raster identify results container.
QgsError error() const
Returns the last error.
bool isValid() const
Returns true if valid.
QMap< int, QVariant > results() const
Returns the identify results.
Raster layer specific subclass of QgsMapLayerElevationProperties.
bool isEnabled() const
Returns true if the elevation properties are enabled, i.e.
QgsDoubleRange elevationRangeForPixelValue(QgsRasterLayer *layer, int band, double pixelValue) const
Returns the elevation range corresponding to a raw pixel value from the specified band.
Represents a raster layer.
A rectangle specified with double values.
void setYMinimum(double y)
Set the minimum y value.
void setXMinimum(double x)
Set the minimum x value.
void setYMaximum(double y)
Set the maximum y value.
void setXMaximum(double x)
Set the maximum x value.
Contains information about the context of a rendering operation.
void setCoordinateTransform(const QgsCoordinateTransform &t)
Sets the current coordinate transform for the context.
QgsExpressionContext & expressionContext()
Gets the expression context.
static QgsRenderContext fromMapSettings(const QgsMapSettings &mapSettings)
create initialized QgsRenderContext instance from given QgsMapSettings
void setExpressionContext(const QgsExpressionContext &context)
Sets the expression context.
void setZRange(const QgsDoubleRange &range)
Sets the range of z-values which should be rendered.
Stores settings for use within QGIS.
QVariant value(const QString &key, const QVariant &defaultValue=QVariant(), Section section=NoSection) const
Returns the value for setting key.
T enumValue(const QString &key, const T &defaultValue, const Section section=NoSection)
Returns the setting value for a setting based on an enum.
static QString symbolTypeToString(Qgis::SymbolType type)
Returns a translated string version of the specified symbol type.
QColor color() const
Returns the symbol's color.
Qgis::SymbolType type() const
Returns the symbol's type.
QgsTileRange tileRangeFromExtent(const QgsRectangle &mExtent) const
Returns tile range that fully covers the given extent.
static Q_INVOKABLE double fromUnitToUnitFactor(Qgis::DistanceUnit fromUnit, Qgis::DistanceUnit toUnit)
Returns the conversion factor between the specified distance units.
static Q_INVOKABLE Qgis::DistanceUnitType unitType(Qgis::DistanceUnit unit)
Returns the type for a distance unit.
static Q_INVOKABLE Qgis::AreaUnit distanceToAreaUnit(Qgis::DistanceUnit distanceUnit)
Converts a distance unit to its corresponding area unit, e.g., meters to square meters.
static bool isNull(const QVariant &variant, bool silenceNullWarnings=false)
Returns true if the specified variant should be considered a NULL value.
void setLayer(QgsVectorLayer *layer)
Sets the associated layer.
Represents a vector layer which manages a vector based dataset.
QgsFeatureIterator getFeatures(const QgsFeatureRequest &request=QgsFeatureRequest()) const final
Queries the layer for features specified in request.
Implements a map layer that is dedicated to rendering of vector tiles.
QMap< QString, QByteArray > data
Raw tile data by source ID.
static QgsFields makeQgisFields(const QSet< QString > &flds)
Returns QgsFields instance based on the set of field names.
static Q_INVOKABLE bool hasZ(Qgis::WkbType type)
Tests whether a WKB type contains the z-dimension.
static Qgis::WkbType singleType(Qgis::WkbType type)
Returns the single type for a WKB type.
static Q_INVOKABLE bool hasM(Qgis::WkbType type)
Tests whether a WKB type contains m values.
static Qgis::WkbType flatType(Qgis::WkbType type)
Returns the flat type for a WKB type.
static Q_INVOKABLE bool isMultiType(Qgis::WkbType type)
Returns true if the WKB type is a multi type.
bool qgsDoubleNear(double a, double b, double epsilon=4 *std::numeric_limits< double >::epsilon())
Compare two doubles (but allow some difference).
T qgsgeometry_cast(QgsAbstractGeometry *geom)
QList< QgsFeature > QgsFeatureList
QSet< QgsFeatureId > QgsFeatureIds
#define FID_TO_STRING(fid)
qint64 QgsFeatureId
64 bit feature ids negative numbers are used for uncommitted/newly added features
QVector< QgsFeatureStore > QgsFeatureStoreList
#define QgsDebugMsgLevel(str, level)
#define QgsDebugError(str)
QgsTemporalRange< QDateTime > QgsDateTimeRange
QgsRange which stores a range of date times.
QMap< QString, QVector< QgsFeature > > QgsVectorTileFeatures
Features of a vector tile, grouped by sub-layer names (key of the map).
Utility class for identifying a unique vertex within a geometry.
bool isValid() const
Returns true if the vertex id is valid.
Qgis::VertexType type
Vertex type.