70#include "moc_qgsmaptoolidentify.cpp"
72using namespace Qt::StringLiterals;
114 return identify( x, y, mode, QList<QgsMapLayer *>(), layerType, identifyContext );
124 return identify( geometry, mode, QList<QgsMapLayer *>(), layerType, identifyContext );
131 QList<IdentifyResult> results;
133 mLastGeometry = geometry;
134 mLastExtent =
mCanvas->extent();
135 mLastMapUnitsPerPixel =
mCanvas->mapUnitsPerPixel();
137 mCoordinatePrecision = QgsCoordinateUtils::calculateCoordinatePrecision( mLastMapUnitsPerPixel,
mCanvas->mapSettings().destinationCrs() );
147 int x = canvasPt.x(), y = canvasPt.y();
148 QList<IdentifyResult> results =
identify( x, y,
TopDownAll, layerList, layerType, identifyContext );
149 QPoint globalPos =
mCanvas->mapToGlobal( QPoint( x + 5, y + 5 ) );
152 else if ( mode ==
ActiveLayer && layerList.isEmpty() )
158 emit
identifyMessage( tr(
"No active layer. To identify features, you must choose an active layer." ) );
164 QApplication::setOverrideCursor( Qt::WaitCursor );
166 identifyLayer( &results,
layer, mLastGeometry, mLastExtent, mLastMapUnitsPerPixel, layerType, identifyContext );
170 QApplication::setOverrideCursor( Qt::WaitCursor );
172 QList<QgsMapLayer *> targetLayers;
173 if ( layerList.isEmpty() )
174 targetLayers =
mCanvas->layers(
true );
176 targetLayers = layerList;
178 const int layerCount = targetLayers.size();
179 for (
int i = 0; i < layerCount; i++ )
189 if (
identifyLayer( &results,
layer, mLastGeometry, mLastExtent, mLastMapUnitsPerPixel, layerType, identifyContext ) )
200 QApplication::restoreOverrideCursor();
207 mPropertiesOverrides.searchRadiusMapUnits = searchRadiusMapUnits;
212 mPropertiesOverrides.searchRadiusMapUnits = -1;
213 mPropertiesOverrides.skip3DLayers =
false;
218 mPropertiesOverrides = overrides;
224 mPropertiesOverrides.skip3DLayers =
false;
245 QList<IdentifyResult> *results,
249 double mapUnitsPerPixel,
266 return identifyRasterLayer( results, qobject_cast<QgsRasterLayer *>(
layer ), geometry, viewExtent, mapUnitsPerPixel, identifyContext );
280 return identifyVectorTileLayer( results, qobject_cast<QgsVectorTileLayer *>(
layer ), geometry, identifyContext );
287 return identifyPointCloudLayer( results, qobject_cast<QgsPointCloudLayer *>(
layer ), geometry, identifyContext );
318 if ( mPropertiesOverrides.skip3DLayers &&
layer->renderer3D() )
323 if ( !
layer->elevationProperties()->isVisibleInZRange( identifyContext.
zRange() ) )
327 double searchRadius = mPropertiesOverrides.searchRadiusMapUnits < 0 ?
searchRadiusMU(
mCanvas ) : mPropertiesOverrides.searchRadiusMapUnits;
328 bool isTemporal = identifyContext.
isTemporal() &&
layer->temporalProperties()->isActive();
330 QList<QgsMeshDatasetIndex> datasetIndexList;
331 int activeScalarGroup =
layer->rendererSettings().activeScalarDatasetGroup();
332 int activeVectorGroup =
layer->rendererSettings().activeVectorDatasetGroup();
334 const QList<int> allGroup =
layer->enabledDatasetGroupsIndexes();
338 if ( activeScalarGroup >= 0 )
339 datasetIndexList.append(
layer->activeScalarDatasetAtTime( time ) );
340 if ( activeVectorGroup >= 0 && activeVectorGroup != activeScalarGroup )
341 datasetIndexList.append(
layer->activeVectorDatasetAtTime( time ) );
343 for (
int groupIndex : allGroup )
345 if ( groupIndex != activeScalarGroup && groupIndex != activeVectorGroup )
346 datasetIndexList.append(
layer->datasetIndexAtTime( time, groupIndex ) );
352 if ( activeScalarGroup >= 0 )
353 datasetIndexList.append(
layer->staticScalarDatasetIndex() );
354 if ( activeVectorGroup >= 0 && activeVectorGroup != activeScalarGroup )
355 datasetIndexList.append(
layer->staticVectorDatasetIndex() );
358 for (
int groupIndex : allGroup )
360 if ( groupIndex != activeScalarGroup && groupIndex != activeVectorGroup )
362 if ( !
layer->datasetGroupMetadata( groupIndex ).isTemporal() )
363 datasetIndexList.append( groupIndex );
371 if ( !index.isValid() )
375 QMap<QString, QString> derivedAttributes;
377 QMap<QString, QString> attribute;
381 const double scalar = scalarValue.
scalar();
382 attribute.insert( tr(
"Scalar Value" ), std::isnan( scalar ) ? tr(
"no data" ) : QLocale().toString( scalar ) );
388 const double vectorX = vectorValue.
x();
389 const double vectorY = vectorValue.
y();
390 if ( std::isnan( vectorX ) || std::isnan( vectorY ) )
391 attribute.insert( tr(
"Vector Value" ), tr(
"no data" ) );
394 attribute.insert( tr(
"Vector Magnitude" ), QLocale().toString( vectorValue.
scalar() ) );
395 derivedAttributes.insert( tr(
"Vector x-component" ), QLocale().toString( vectorY ) );
396 derivedAttributes.insert( tr(
"Vector y-component" ), QLocale().toString( vectorX ) );
403 derivedAttributes.insert( tr(
"Time Step" ),
layer->formatTime( meta.
time() ) );
404 derivedAttributes.insert( tr(
"Source" ), groupMeta.
uri() );
406 QString resultName = groupMeta.
name();
407 if ( isTemporal && ( index.group() == activeScalarGroup || index.group() == activeVectorGroup ) )
408 resultName.append( tr(
" (active)" ) );
412 results->append( result );
415 QMap<QString, QString> derivedGeometry;
418 const int vertexId =
layer->closestElement(
QgsMesh::Vertex, point, searchRadius, vertexPoint );
421 derivedGeometry.insert( tr(
"Snapped Vertex Index" ), QLocale().toString( vertexId ) );
422 derivedGeometry.insert( tr(
"Snapped Vertex Position X" ), QLocale().toString( vertexPoint.
x() ) );
423 derivedGeometry.insert( tr(
"Snapped Vertex Position Y" ), QLocale().toString( vertexPoint.
y() ) );
427 const int faceId =
layer->closestElement(
QgsMesh::Face, point, searchRadius, faceCentroid );
430 derivedGeometry.insert( tr(
"Face Index" ), QLocale().toString( faceId ) );
431 derivedGeometry.insert( tr(
"Face Centroid X" ), QLocale().toString( faceCentroid.
x() ) );
432 derivedGeometry.insert( tr(
"Face Centroid Y" ), QLocale().toString( faceCentroid.
y() ) );
436 const int edgeId =
layer->closestElement(
QgsMesh::Edge, point, searchRadius, pointOnEdge );
439 derivedGeometry.insert( tr(
"Edge Index" ), QLocale().toString( edgeId ) );
440 derivedGeometry.insert( tr(
"Point on Edge X" ), QLocale().toString( pointOnEdge.
x() ) );
441 derivedGeometry.insert( tr(
"Point on Edge Y" ), QLocale().toString( pointOnEdge.
y() ) );
446 results->append( result );
453 Q_UNUSED( identifyContext )
463 QgsTemporaryCursorOverride waitCursor( Qt::WaitCursor );
465 QMap<QString, QString> commonDerivedAttributes;
467 QgsGeometry selectionGeom = geometry;
468 bool isPointOrRectangle;
473 isPointOrRectangle =
true;
474 point = selectionGeom.
asPoint();
484 int featureCount = 0;
486 std::unique_ptr<QgsGeometryEngine> selectionGeomPrepared;
496 double sr = mPropertiesOverrides.searchRadiusMapUnits < 0 ?
searchRadiusMU(
mCanvas ) : mPropertiesOverrides.searchRadiusMapUnits;
503 if ( !isPointOrRectangle )
505 QgsCoordinateTransform ct(
mCanvas->mapSettings().destinationCrs(),
layer->crs(),
mCanvas->mapSettings().transformContext() );
514 const double tileScale
517 const int tileZoom =
layer->tileMatrixSet().scaleToZoomLevel( tileScale );
518 const QgsTileMatrix tileMatrix =
layer->tileMatrixSet().tileMatrix( tileZoom );
521 const QVector<QgsTileXYZ> tiles =
layer->tileMatrixSet().tilesInRange( tileRange, tileZoom );
523 for (
const QgsTileXYZ &tileID : tiles )
525 const QgsVectorTileRawData data =
layer->getRawTile( tileID );
526 if ( data.
data.isEmpty() )
529 QgsVectorTileMVTDecoder decoder(
layer->tileMatrixSet() );
530 if ( !decoder.decode( data ) )
533 QMap<QString, QgsFields> perLayerFields;
534 const QStringList layerNames = decoder.layers();
535 for (
const QString &layerName : layerNames )
537 QSet<QString> fieldNames = qgis::listToSet( decoder.layerFieldNames( layerName ) );
541 const QgsVectorTileFeatures features = decoder.layerFeatures( perLayerFields, QgsCoordinateTransform() );
542 const QStringList featuresLayerNames = features.keys();
543 for (
const QString &layerName : featuresLayerNames )
545 const QgsFields fFields = perLayerFields[layerName];
546 const QVector<QgsFeature> &layerFeatures = features[layerName];
547 for (
const QgsFeature &f : layerFeatures )
549 if ( f.geometry().intersects( r ) && ( !selectionGeomPrepared || selectionGeomPrepared->intersects( f.geometry().constGet() ) ) )
551 QMap<QString, QString> derivedAttributes = commonDerivedAttributes;
552 derivedAttributes.insert( tr(
"Feature ID" ),
FID_TO_STRING( f.id() ) );
553 derivedAttributes.insert( tr(
"Tile column" ), QString::number( tileID.column() ) );
554 derivedAttributes.insert( tr(
"Tile row" ), QString::number( tileID.row() ) );
555 derivedAttributes.insert( tr(
"Tile zoom" ), QString::number( tileID.zoomLevel() ) );
565 catch ( QgsCsException &cse )
572 return featureCount > 0;
577 if ( mPropertiesOverrides.skip3DLayers &&
layer->renderer3D() )
582 if ( !
layer->elevationProperties()->isVisibleInZRange( identifyContext.
zRange(),
layer ) )
586 QgsPointCloudRenderer *renderer =
layer->renderer();
593 const double searchRadiusMapUnits = mPropertiesOverrides.searchRadiusMapUnits < 0 ?
searchRadiusMU(
mCanvas ) : mPropertiesOverrides.searchRadiusMapUnits;
595 const QVector<QVariantMap> points = renderer->
identify(
layer, context, geometry, searchRadiusMapUnits );
604 QMap<QString, QString> derivedAttributes;
608 formatCoordinate( point, x, y );
610 derivedAttributes.insert( tr(
"(clicked coordinate X)" ), x );
611 derivedAttributes.insert( tr(
"(clicked coordinate Y)" ), y );
613 derivedAttributes.insert( tr(
"(clicked coordinate Z)" ), QLocale().toString( point.
z(),
'f' ) );
614 return derivedAttributes;
631 QString temporalFilter;
634 if ( !
layer->temporalProperties()->isVisibleInTemporalRange( identifyContext.
temporalRange() ) )
637 QgsVectorLayerTemporalContext temporalContext;
639 temporalFilter = qobject_cast<const QgsVectorLayerTemporalProperties *>(
layer->temporalProperties() )->createFilterString( temporalContext, identifyContext.
temporalRange() );
644 QApplication::setOverrideCursor( Qt::WaitCursor );
646 QMap<QString, QString> commonDerivedAttributes;
648 QgsGeometry selectionGeom = geometry;
649 bool isPointOrRectangle;
654 isPointOrRectangle =
true;
666 std::unique_ptr<QgsGeometryEngine> selectionGeomPrepared;
676 double sr = mPropertiesOverrides.searchRadiusMapUnits < 0 ?
searchRadiusMU(
mCanvas ) : mPropertiesOverrides.searchRadiusMapUnits;
683 if ( !isPointOrRectangle )
685 QgsCoordinateTransform ct(
mCanvas->mapSettings().destinationCrs(),
layer->crs(),
mCanvas->mapSettings().transformContext() );
694 QgsFeatureRequest featureRequest;
697 if ( !temporalFilter.isEmpty() )
700 QgsFeatureIterator fit =
layer->getFeatures( featureRequest );
704 if ( !selectionGeomPrepared || selectionGeomPrepared->intersects( f.
geometry().
constGet() ) )
705 featureList << QgsFeature( f );
708 catch ( QgsCsException &cse )
720 std::unique_ptr<QgsFeatureRenderer> renderer(
layer->renderer() ?
layer->renderer()->clone() :
nullptr );
729 if ( !isSingleClick )
736 filter ? renderer.get() :
nullptr,
737 commonDerivedAttributes,
738 [point,
layer,
this](
const QgsFeature &feature ) -> QMap<QString, QString> { return featureDerivedAttributes( feature, layer, toLayerCoordinates( layer, point ) ); },
746 QApplication::restoreOverrideCursor();
747 return featureCount > 0;
751 QList<IdentifyResult> *results,
755 const QMap<QString, QString> &commonDerivedAttributes,
756 const std::function<QMap<QString, QString>(
const QgsFeature & )> &deriveAttributesForFeature,
760 int featureCount = 0;
761 for (
const QgsFeature &feature : std::as_const( features ) )
763 QMap<QString, QString> derivedAttributes = commonDerivedAttributes;
771 derivedAttributes.insert( deriveAttributesForFeature( feature ) );
772 derivedAttributes.insert( tr(
"Feature ID" ), fid < 0 ? tr(
"new feature" ) :
FID_TO_STRING( fid ) );
774 results->append(
IdentifyResult( qobject_cast<QgsMapLayer *>(
layer ), feature, derivedAttributes ) );
780void QgsMapToolIdentify::closestVertexAttributes(
786 bool showTransformedZ,
787 QMap<QString, QString> &derivedAttributes
797 QString str = QLocale().toString( vId.
vertex + 1 );
798 derivedAttributes.insert( tr(
"Closest vertex number" ), str );
800 QgsPoint closestPoint = geometry.
vertexAt( vId );
801 QgsPoint closestPointMapCoords = closestPoint;
802 if ( layerToMapTransform.
isValid() )
808 catch ( QgsCsException &cse )
816 formatCoordinate( closestPointMapCoords, x, y );
817 derivedAttributes.insert( tr(
"Closest vertex X" ), x );
818 derivedAttributes.insert( tr(
"Closest vertex Y" ), y );
820 if ( closestPoint.
is3D() )
822 str = QLocale().toString( closestPoint.
z(),
'g', 10 );
825 if ( showTransformedZ && !std::isnan( closestPointMapCoords.
z() ) && !
qgsDoubleNear( closestPoint.
z(), closestPointMapCoords.
z() ) )
827 const QString str = QLocale().toString( closestPointMapCoords.
z(),
'g', 10 );
833 str = QLocale().toString( closestPointMapCoords.
m(),
'g', 10 );
834 derivedAttributes.insert( tr(
"Closest vertex M" ), str );
839 double radius, centerX, centerY;
840 QgsVertexId vIdBefore = vId;
842 QgsVertexId vIdAfter = vId;
845 derivedAttributes.insert( u
"Closest vertex radius"_s, QLocale().toString( radius ) );
849void QgsMapToolIdentify::closestPointAttributes(
855 bool showTransformedZ,
856 QMap<QString, QString> &derivedAttributes
860 QgsPoint closestPointMapCrs = closestPoint;
861 if ( layerToMapTransform.
isValid() )
867 catch ( QgsCsException &cse )
875 formatCoordinate( closestPoint, x, y );
876 derivedAttributes.insert( tr(
"Closest X" ), x );
877 derivedAttributes.insert( tr(
"Closest Y" ), y );
879 if ( closestPoint.
is3D() )
881 const QString str = QLocale().toString( closestPoint.
z(),
'g', 10 );
884 if ( showTransformedZ && !std::isnan( closestPointMapCrs.
z() ) && !
qgsDoubleNear( closestPoint.
z(), closestPointMapCrs.
z() ) )
886 const QString str = QLocale().toString( closestPointMapCrs.
z(),
'g', 10 );
892 const QString str = QLocale().toString( closestPoint.
m(),
'g', 10 );
893 derivedAttributes.insert( tr(
"Interpolated M" ), str );
899 QgsCoordinateUtils::formatCoordinatePartsForProject(
QgsProject::instance(), canvasPoint, mapCrs, coordinatePrecision, x, y );
902void QgsMapToolIdentify::formatCoordinate(
const QgsPointXY &canvasPoint, QString &x, QString &y )
const
904 formatCoordinate( canvasPoint, x, y,
mCanvas->mapSettings().destinationCrs(), mCoordinatePrecision );
911 QMap<QString, QString> derivedAttributes;
915 QgsDistanceArea calc;
923 QgsPoint closestPoint;
937 QString str = QLocale().toString(
static_cast<const QgsGeometryCollection *
>( feature.
geometry().
constGet() )->numGeometries() );
938 derivedAttributes.insert( tr(
"Parts" ), str );
941 str = QLocale().toString( vId.
part + 1 );
942 derivedAttributes.insert( tr(
"Part number" ), str );
949 : QgsUnitTypes::distanceToAreaUnit(
layer->crs().mapUnits() );
952 const QgsCoordinateReferenceSystem layerVertCrs =
layer->crs3D().verticalCrs().isValid() ?
layer->crs3D().verticalCrs() :
layer->crs3D();
956 const QgsGeometry layerCrsGeometry = feature.
geometry();
957 QgsGeometry mapCrsGeometry = layerCrsGeometry;
960 if ( layerToMapTransform.
isValid() )
965 catch ( QgsCsException &cse )
972 const QgsAbstractGeometry *layerCrsGeom = layerCrsGeometry.
constGet();
980 catch ( QgsCsException & )
983 QgsDebugError( u
"An error occurred while calculating length"_s );
989 str = formatDistance( dist );
990 derivedAttributes.insert( tr(
"Length (Ellipsoidal — %1)" ).arg( ellipsoid ), str );
997 derivedAttributes.insert( tr(
"Length (Cartesian — 2D)" ), str );
999 double totalLength3d = std::accumulate( layerCrsGeom->
const_parts_begin(), layerCrsGeom->
const_parts_end(), 0.0, [](
double total,
const QgsAbstractGeometry *part ) {
1000 return total + qgsgeometry_cast<const QgsLineString *>( part )->length3D();
1003 str = formatDistance( totalLength3d, cartesianDistanceUnits );
1004 derivedAttributes.insert( tr(
"Length (Cartesian — 3D)" ), str );
1008 derivedAttributes.insert( tr(
"Length (Cartesian)" ), str );
1011 str = QLocale().toString( layerCrsGeom->
nCoordinates() );
1012 derivedAttributes.insert( tr(
"Vertices" ), str );
1016 closestVertexAttributes( layerToMapTransform, layerVertCrs, mapVertCrs, *layerCrsGeom, vId, showTransformedZ, derivedAttributes );
1017 closestPointAttributes( layerToMapTransform, layerVertCrs, mapVertCrs, *layerCrsGeom, layerPoint, showTransformedZ, derivedAttributes );
1023 QgsPointXY pnt =
mCanvas->mapSettings().layerToMapCoordinates(
layer, QgsPointXY( curve->startPoint().x(), curve->startPoint().y() ) );
1026 formatCoordinate( pnt, x, y );
1027 derivedAttributes.insert( tr(
"firstX",
"attributes get sorted; translation for lastX should be lexically larger than this one" ), x );
1028 derivedAttributes.insert( tr(
"firstY" ), y );
1029 pnt =
mCanvas->mapSettings().layerToMapCoordinates(
layer, QgsPointXY( curve->endPoint().x(), curve->endPoint().y() ) );
1030 formatCoordinate( pnt, x, y );
1031 derivedAttributes.insert( tr(
"lastX",
"attributes get sorted; translation for firstX should be lexically smaller than this one" ), x );
1032 derivedAttributes.insert( tr(
"lastY" ), y );
1043 catch ( QgsCsException & )
1046 QgsDebugError( u
"An error occurred while calculating area"_s );
1052 str = formatArea( area );
1053 derivedAttributes.insert( tr(
"Area (Ellipsoidal — %1)" ).arg( ellipsoid ), str );
1056 derivedAttributes.insert( tr(
"Area (Cartesian)" ), str );
1060 double perimeter = 0;
1066 catch ( QgsCsException & )
1069 QgsDebugError( u
"An error occurred while calculating perimeter"_s );
1071 str = formatDistance( perimeter );
1072 derivedAttributes.insert( tr(
"Perimeter (Ellipsoidal — %1)" ).arg( ellipsoid ), str );
1075 derivedAttributes.insert( tr(
"Perimeter (Cartesian)" ), str );
1078 derivedAttributes.insert( tr(
"Vertices" ), str );
1083 closestVertexAttributes( layerToMapTransform, layerVertCrs, mapVertCrs, *layerCrsGeometry.
constGet(), vId, showTransformedZ, derivedAttributes );
1084 closestPointAttributes( layerToMapTransform, layerVertCrs, mapVertCrs, *layerCrsGeometry.
constGet(), layerPoint, showTransformedZ, derivedAttributes );
1094 formatCoordinate( QgsPointXY( mapCrsPoint->x(), mapCrsPoint->y() ), x, y );
1095 derivedAttributes.insert( tr(
"X" ), x );
1096 derivedAttributes.insert( tr(
"Y" ), y );
1099 const double mapCrsZ = mapCrsPoint->is3D() ? mapCrsPoint->z() : std::numeric_limits<double>::quiet_NaN();
1101 if ( !std::isnan( originalZ ) )
1103 const QString str = QLocale().toString( originalZ,
'g', 10 );
1106 if ( showTransformedZ && !std::isnan( mapCrsZ ) && !
qgsDoubleNear( originalZ, mapCrsZ ) )
1108 const QString str = QLocale().toString( mapCrsZ,
'g', 10 );
1115 derivedAttributes.insert( tr(
"M" ), str );
1124 const QgsAbstractGeometry *geom = layerCrsGeometry.
constGet();
1125 closestVertexAttributes( layerToMapTransform, layerVertCrs, mapVertCrs, *geom, vId, showTransformedZ, derivedAttributes );
1135 return derivedAttributes;
1142 QgsPointXY point = geometry.
asPoint();
1154 std::unique_ptr<QgsRasterDataProvider> dprovider(
layer->dataProvider()->clone() );
1164 if ( !
layer->temporalProperties()->isVisibleInTemporalRange( identifyContext.
temporalRange() ) )
1167 dprovider->temporalCapabilities()->setRequestedTemporalRange( identifyContext.
temporalRange() );
1172 if ( !
layer->elevationProperties()->isVisibleInZRange( identifyContext.
zRange(),
layer ) )
1189 if ( !
layer->extent().contains( point ) )
1192 QMap<QString, QString> attributes, derivedAttributes;
1213 if ( dprovider->crs() !=
mCanvas->mapSettings().destinationCrs() )
1222 r.
setXMinimum( pointInCanvasCrs.
x() - mapUnitsPerPixel / 2. );
1223 r.
setXMaximum( pointInCanvasCrs.
x() + mapUnitsPerPixel / 2. );
1224 r.
setYMinimum( pointInCanvasCrs.
y() - mapUnitsPerPixel / 2. );
1225 r.
setYMaximum( pointInCanvasCrs.
y() + mapUnitsPerPixel / 2. );
1229 identifyResult = dprovider->identify( point, format, r, 1, 1 );
1245 int width =
static_cast<int>( std::round( viewExtent.
width() / mapUnitsPerPixel ) );
1246 int height =
static_cast<int>( std::round( viewExtent.
height() / mapUnitsPerPixel ) );
1249 QgsDebugMsgLevel( u
"width = %1 height = %2"_s.arg( width ).arg( height ), 2 );
1250 QgsDebugMsgLevel( u
"xRes = %1 yRes = %2 mapUnitsPerPixel = %3"_s.arg( viewExtent.
width() / width ).arg( viewExtent.
height() / height ).arg( mapUnitsPerPixel ), 2 );
1252 identifyResult = dprovider->identify( point, format, viewExtent, width, height );
1263 bool foundMatch =
false;
1264 QMap<int, QVariant> values = identifyResult.
results();
1265 QMap<int, QVariant> filteredValues;
1266 for (
auto it = values.constBegin(); it != values.constEnd(); ++it )
1272 const double value = it.value().toDouble();
1276 filteredValues.insert( it.key(), it.value() );
1300 const double xres =
layer->rasterUnitsPerPixelX();
1301 const double yres =
layer->rasterUnitsPerPixelY();
1309 const int rasterCol =
static_cast<int>( std::floor( ( point.
x() - extent.
xMinimum() ) / xres ) );
1310 const int rasterRow =
static_cast<int>( std::floor( ( extent.
yMaximum() - point.
y() ) / yres ) );
1312 derivedAttributes.insert( tr(
"Column (0-based)" ), QLocale().toString( rasterCol ) );
1313 derivedAttributes.insert( tr(
"Row (0-based)" ), QLocale().toString( rasterRow ) );
1318 if ( identifyResult.
isValid() )
1320 QMap<int, QVariant> values = identifyResult.
results();
1323 for (
auto it = values.constBegin(); it != values.constEnd(); ++it )
1325 QString valueString;
1328 valueString = tr(
"no data" );
1332 QVariant value( it.value() );
1336 if (
static_cast<QMetaType::Type
>( value.userType() ) == QMetaType::Float )
1345 attributes.insert( dprovider->generateBandName( it.key() ), valueString );
1351 const double doubleValue { it.value().toDouble( &ok ) };
1354 const QVariantList row = rat->row( doubleValue );
1355 if ( !row.isEmpty() )
1357 for (
int colIdx = 0; colIdx < std::min( rat->fields().count(), row.count() ); ++colIdx )
1368 switch ( ratField.
type )
1370 case QMetaType::Type::QChar:
1371 case QMetaType::Type::Int:
1372 case QMetaType::Type::UInt:
1373 case QMetaType::Type::LongLong:
1374 case QMetaType::Type::ULongLong:
1375 ratValue = QLocale().toString( row.at( colIdx ).toLongLong() );
1377 case QMetaType::Type::Double:
1378 ratValue = QLocale().toString( row.at( colIdx ).toDouble() );
1381 ratValue = row.at( colIdx ).toString();
1383 attributes.insert( ratField.
name, ratValue );
1390 QString label =
layer->name();
1392 if ( !pixelRect.
isNull() )
1399 results->append( result );
1403 for (
auto it = values.constBegin(); it != values.constEnd(); ++it )
1405 QVariant value = it.value();
1406 if ( value.userType() == QMetaType::Type::Bool && !value.toBool() )
1412 if ( value.userType() == QMetaType::Type::QString )
1416 QString label =
layer->subLayers().value( it.key() );
1418 attributes.insert( tr(
"Error" ), value.toString() );
1420 results->append(
IdentifyResult( qobject_cast<QgsMapLayer *>(
layer ), label, attributes, derivedAttributes ) );
1430 for (
const QgsFeature &feature : storeFeatures )
1436 QString sublayer = featureStore.params().value( u
"sublayer"_s ).toString();
1437 QString featureType = featureStore.params().value( u
"featureType"_s ).toString();
1439 featureType.remove( u
"_feature"_s );
1441 if ( sublayer.compare(
layer->name(), Qt::CaseInsensitive ) != 0 )
1445 if ( featureType.compare( sublayer, Qt::CaseInsensitive ) != 0 || labels.isEmpty() )
1447 labels << featureType;
1450 QMap<QString, QString> derAttributes = derivedAttributes;
1453 IdentifyResult identifyResult( qobject_cast<QgsMapLayer *>(
layer ), labels.join(
" / "_L1 ), featureStore.fields(), feature, derAttributes );
1455 identifyResult.
mParams.insert( u
"getFeatureInfoUrl"_s, featureStore.params().value( u
"getFeatureInfoUrl"_s ) );
1456 results->append( identifyResult );
1464 for (
auto it = values.constBegin(); it != values.constEnd(); ++it )
1466 QString value = it.value().toString();
1468 attributes.insert( QString(), value );
1470 QString label =
layer->subLayers().value( it.key() );
1471 results->append(
IdentifyResult( qobject_cast<QgsMapLayer *>(
layer ), label, attributes, derivedAttributes ) );
1479 attributes.insert( tr(
"Error" ), value );
1480 QString label = tr(
"Identify error" );
1481 results->append(
IdentifyResult( qobject_cast<QgsMapLayer *>(
layer ), label, attributes, derivedAttributes ) );
1497QString QgsMapToolIdentify::formatDistance(
double distance )
const
1499 return formatDistance( distance, displayDistanceUnits() );
1502QString QgsMapToolIdentify::formatArea(
double area )
const
1504 return formatArea( area, displayAreaUnits() );
1507QString QgsMapToolIdentify::formatDistance(
double distance,
Qgis::DistanceUnit unit )
const
1509 QgsSettings settings;
1515QString QgsMapToolIdentify::formatArea(
double area,
Qgis::AreaUnit unit )
const
1517 QgsSettings settings;
1525 QList<IdentifyResult> results;
1541 for (
const QVariantMap &pt : identified )
1543 QMap<QString, QString> ptStr;
1544 QString classification;
1545 for (
auto attrIt = pt.constBegin(); attrIt != pt.constEnd(); ++attrIt )
1550 ptStr[tr(
"Z (original)" )] = attrIt.value().toString();
1551 ptStr[tr(
"Z (adjusted)" )] = QString::number( attrIt.value().toDouble() * elevationProps->
zScale() + elevationProps->
zOffset() );
1553 else if ( attrIt.key().compare(
"Classification"_L1, Qt::CaseInsensitive ) == 0 )
1556 ptStr[attrIt.key()] = u
"%1 (%2)"_s.arg( attrIt.value().toString(), classification );
1560 ptStr[attrIt.key()] = attrIt.value().toString();
1564 QMap<QString, QString> derivedAttributes;
1565 QgsPoint layerPoint( pt.value(
"X" ).toDouble(), pt.value(
"Y" ).toDouble(), pt.value(
"Z" ).toDouble() );
1570 if ( layerToMapTransform.
isValid() )
1585 derivedAttributes.insert( tr(
"X" ), x );
1586 derivedAttributes.insert( tr(
"Y" ), y );
1588 const double originalZ = layerPoint.
z();
1589 const double mapCrsZ = mapCrsPoint.
is3D() ? mapCrsPoint.
z() : std::numeric_limits<double>::quiet_NaN();
1591 if ( !std::isnan( originalZ ) )
1593 const QString str = QLocale().toString( originalZ,
'g', 10 );
1596 if ( showTransformedZ && !std::isnan( mapCrsZ ) && !
qgsDoubleNear( originalZ, mapCrsZ ) )
1598 const QString str = QLocale().toString( mapCrsZ,
'g', 10 );
1603 results.append( res );
1613 if ( identified.empty() )
1616 switch (
layer->type() )
1623 QHash<QgsFeatureId, QVariant> featureDistances;
1624 QHash<QgsFeatureId, QVariant> featureElevations;
1627 for (
const QVariantMap &map : identified )
1629 if ( !map.contains( u
"id"_s ) )
1631 QMap<QString, QString> attributes;
1632 if ( map.value( u
"distance"_s ).isValid() )
1633 attributes.insert( tr(
"Distance along curve" ), QString::number( map.value( u
"distance"_s ).toDouble() ) );
1634 if ( map.value( u
"elevation"_s ).isValid() )
1635 attributes.insert( tr(
"Elevation" ), QString::number( map.value( u
"elevation"_s ).toDouble() ) );
1641 const QgsFeatureId id = map.value( u
"id"_s ).toLongLong();
1642 filterIds.insert(
id );
1644 featureDistances.insert(
id, map.value( u
"distance"_s ) );
1645 featureElevations.insert(
id, map.value( u
"elevation"_s ) );
1662 QMap<QString, QString>(),
1663 [
this, vl, &featureDistances, &featureElevations](
const QgsFeature &feature ) -> QMap<QString, QString> {
1664 QMap< QString, QString > attributes = featureDerivedAttributes( feature, vl,
QgsPointXY() );
1666 if ( featureDistances.value( feature.
id() ).isValid() )
1667 attributes.insert( tr(
"Distance along curve" ), QString::number( featureDistances.value( feature.
id() ).toDouble() ) );
1668 if ( featureElevations.value( feature.
id() ).isValid() )
1669 attributes.insert( tr(
"Elevation" ), QString::number( featureElevations.value( feature.
id() ).toDouble() ) );
1681 for (
const QVariantMap &map : identified )
1683 QMap<QString, QString> attributes;
1684 if ( map.value( u
"distance"_s ).isValid() )
1685 attributes.insert( tr(
"Distance along curve" ), QString::number( map.value( u
"distance"_s ).toDouble() ) );
1686 if ( map.value( u
"elevation"_s ).isValid() )
1687 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.
bool isTopologicallyEqual(const QgsGeometry &geometry, Qgis::GeometryBackend backend=Qgis::GeometryBackend::GEOS) const
Compares the geometry with another geometry using the specified backend.
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.).
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.
T value(const QString &dynamicKeyPart=QString()) const
Returns settings value.
A template class for enum and flag settings entry.
static const QgsSettingsEntryBool * settingsMeasureKeepBaseUnit
Settings entry for whether to keep base measurement units.
static QgsSettingsTreeNode * sTreeMap
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.