67#include "moc_qgsmaptoolidentify.cpp"
69using namespace Qt::StringLiterals;
108 return identify( x, y, mode, QList<QgsMapLayer *>(), layerType, identifyContext );
118 return identify( geometry, mode, QList<QgsMapLayer *>(), layerType, identifyContext );
123 QList<IdentifyResult> results;
125 mLastGeometry = geometry;
126 mLastExtent =
mCanvas->extent();
127 mLastMapUnitsPerPixel =
mCanvas->mapUnitsPerPixel();
129 mCoordinatePrecision = QgsCoordinateUtils::calculateCoordinatePrecision( mLastMapUnitsPerPixel,
mCanvas->mapSettings().destinationCrs() );
140 int x = canvasPt.x(), y = canvasPt.y();
141 QList<IdentifyResult> results =
identify( x, y,
TopDownAll, layerList, layerType, identifyContext );
142 QPoint globalPos =
mCanvas->mapToGlobal( QPoint( x + 5, y + 5 ) );
145 else if ( mode ==
ActiveLayer && layerList.isEmpty() )
151 emit
identifyMessage( tr(
"No active layer. To identify features, you must choose an active layer." ) );
157 QApplication::setOverrideCursor( Qt::WaitCursor );
159 identifyLayer( &results,
layer, mLastGeometry, mLastExtent, mLastMapUnitsPerPixel, layerType, identifyContext );
163 QApplication::setOverrideCursor( Qt::WaitCursor );
165 QList<QgsMapLayer *> targetLayers;
166 if ( layerList.isEmpty() )
167 targetLayers =
mCanvas->layers(
true );
169 targetLayers = layerList;
171 const int layerCount = targetLayers.size();
172 for (
int i = 0; i < layerCount; i++ )
182 if (
identifyLayer( &results,
layer, mLastGeometry, mLastExtent, mLastMapUnitsPerPixel, layerType, identifyContext ) )
193 QApplication::restoreOverrideCursor();
200 mPropertiesOverrides.searchRadiusMapUnits = searchRadiusMapUnits;
205 mPropertiesOverrides.searchRadiusMapUnits = -1;
206 mPropertiesOverrides.skip3DLayers =
false;
211 mPropertiesOverrides = overrides;
217 mPropertiesOverrides.skip3DLayers =
false;
249 return identifyRasterLayer( results, qobject_cast<QgsRasterLayer *>(
layer ), geometry, viewExtent, mapUnitsPerPixel, identifyContext );
263 return identifyVectorTileLayer( results, qobject_cast<QgsVectorTileLayer *>(
layer ), geometry, identifyContext );
270 return identifyPointCloudLayer( results, qobject_cast<QgsPointCloudLayer *>(
layer ), geometry, identifyContext );
301 if ( mPropertiesOverrides.skip3DLayers &&
layer->renderer3D() )
306 if ( !
layer->elevationProperties()->isVisibleInZRange( identifyContext.
zRange() ) )
310 double searchRadius = mPropertiesOverrides.searchRadiusMapUnits < 0 ?
searchRadiusMU(
mCanvas ) : mPropertiesOverrides.searchRadiusMapUnits;
311 bool isTemporal = identifyContext.
isTemporal() &&
layer->temporalProperties()->isActive();
313 QList<QgsMeshDatasetIndex> datasetIndexList;
314 int activeScalarGroup =
layer->rendererSettings().activeScalarDatasetGroup();
315 int activeVectorGroup =
layer->rendererSettings().activeVectorDatasetGroup();
317 const QList<int> allGroup =
layer->enabledDatasetGroupsIndexes();
321 if ( activeScalarGroup >= 0 )
322 datasetIndexList.append(
layer->activeScalarDatasetAtTime( time ) );
323 if ( activeVectorGroup >= 0 && activeVectorGroup != activeScalarGroup )
324 datasetIndexList.append(
layer->activeVectorDatasetAtTime( time ) );
326 for (
int groupIndex : allGroup )
328 if ( groupIndex != activeScalarGroup && groupIndex != activeVectorGroup )
329 datasetIndexList.append(
layer->datasetIndexAtTime( time, groupIndex ) );
335 if ( activeScalarGroup >= 0 )
336 datasetIndexList.append(
layer->staticScalarDatasetIndex() );
337 if ( activeVectorGroup >= 0 && activeVectorGroup != activeScalarGroup )
338 datasetIndexList.append(
layer->staticVectorDatasetIndex() );
341 for (
int groupIndex : allGroup )
343 if ( groupIndex != activeScalarGroup && groupIndex != activeVectorGroup )
345 if ( !
layer->datasetGroupMetadata( groupIndex ).isTemporal() )
346 datasetIndexList.append( groupIndex );
354 if ( !index.isValid() )
358 QMap<QString, QString> derivedAttributes;
360 QMap<QString, QString> attribute;
364 const double scalar = scalarValue.
scalar();
365 attribute.insert( tr(
"Scalar Value" ), std::isnan( scalar ) ? tr(
"no data" ) : QLocale().toString( scalar ) );
371 const double vectorX = vectorValue.
x();
372 const double vectorY = vectorValue.
y();
373 if ( std::isnan( vectorX ) || std::isnan( vectorY ) )
374 attribute.insert( tr(
"Vector Value" ), tr(
"no data" ) );
377 attribute.insert( tr(
"Vector Magnitude" ), QLocale().toString( vectorValue.
scalar() ) );
378 derivedAttributes.insert( tr(
"Vector x-component" ), QLocale().toString( vectorY ) );
379 derivedAttributes.insert( tr(
"Vector y-component" ), QLocale().toString( vectorX ) );
386 derivedAttributes.insert( tr(
"Time Step" ),
layer->formatTime( meta.
time() ) );
387 derivedAttributes.insert( tr(
"Source" ), groupMeta.
uri() );
389 QString resultName = groupMeta.
name();
390 if ( isTemporal && ( index.group() == activeScalarGroup || index.group() == activeVectorGroup ) )
391 resultName.append( tr(
" (active)" ) );
395 results->append( result );
398 QMap<QString, QString> derivedGeometry;
401 const int vertexId =
layer->closestElement(
QgsMesh::Vertex, point, searchRadius, vertexPoint );
404 derivedGeometry.insert( tr(
"Snapped Vertex Index" ), QLocale().toString( vertexId ) );
405 derivedGeometry.insert( tr(
"Snapped Vertex Position X" ), QLocale().toString( vertexPoint.
x() ) );
406 derivedGeometry.insert( tr(
"Snapped Vertex Position Y" ), QLocale().toString( vertexPoint.
y() ) );
410 const int faceId =
layer->closestElement(
QgsMesh::Face, point, searchRadius, faceCentroid );
413 derivedGeometry.insert( tr(
"Face Index" ), QLocale().toString( faceId ) );
414 derivedGeometry.insert( tr(
"Face Centroid X" ), QLocale().toString( faceCentroid.
x() ) );
415 derivedGeometry.insert( tr(
"Face Centroid Y" ), QLocale().toString( faceCentroid.
y() ) );
419 const int edgeId =
layer->closestElement(
QgsMesh::Edge, point, searchRadius, pointOnEdge );
422 derivedGeometry.insert( tr(
"Edge Index" ), QLocale().toString( edgeId ) );
423 derivedGeometry.insert( tr(
"Point on Edge X" ), QLocale().toString( pointOnEdge.
x() ) );
424 derivedGeometry.insert( tr(
"Point on Edge Y" ), QLocale().toString( pointOnEdge.
y() ) );
429 results->append( result );
436 Q_UNUSED( identifyContext )
446 QgsTemporaryCursorOverride waitCursor( Qt::WaitCursor );
448 QMap<QString, QString> commonDerivedAttributes;
450 QgsGeometry selectionGeom = geometry;
451 bool isPointOrRectangle;
456 isPointOrRectangle =
true;
457 point = selectionGeom.
asPoint();
467 int featureCount = 0;
469 std::unique_ptr<QgsGeometryEngine> selectionGeomPrepared;
479 double sr = mPropertiesOverrides.searchRadiusMapUnits < 0 ?
searchRadiusMU(
mCanvas ) : mPropertiesOverrides.searchRadiusMapUnits;
486 if ( !isPointOrRectangle )
488 QgsCoordinateTransform ct(
mCanvas->mapSettings().destinationCrs(),
layer->crs(),
mCanvas->mapSettings().transformContext() );
497 const double tileScale =
layer->tileMatrixSet().calculateTileScaleForMap(
499 mCanvas->mapSettings().destinationCrs(),
500 mCanvas->mapSettings().extent(),
505 const int tileZoom =
layer->tileMatrixSet().scaleToZoomLevel( tileScale );
506 const QgsTileMatrix tileMatrix =
layer->tileMatrixSet().tileMatrix( tileZoom );
509 const QVector<QgsTileXYZ> tiles =
layer->tileMatrixSet().tilesInRange( tileRange, tileZoom );
511 for (
const QgsTileXYZ &tileID : tiles )
513 const QgsVectorTileRawData data =
layer->getRawTile( tileID );
514 if ( data.
data.isEmpty() )
517 QgsVectorTileMVTDecoder decoder(
layer->tileMatrixSet() );
518 if ( !decoder.decode( data ) )
521 QMap<QString, QgsFields> perLayerFields;
522 const QStringList layerNames = decoder.layers();
523 for (
const QString &layerName : layerNames )
525 QSet<QString> fieldNames = qgis::listToSet( decoder.layerFieldNames( layerName ) );
529 const QgsVectorTileFeatures features = decoder.layerFeatures( perLayerFields, QgsCoordinateTransform() );
530 const QStringList featuresLayerNames = features.keys();
531 for (
const QString &layerName : featuresLayerNames )
533 const QgsFields fFields = perLayerFields[layerName];
534 const QVector<QgsFeature> &layerFeatures = features[layerName];
535 for (
const QgsFeature &f : layerFeatures )
537 if ( f.geometry().intersects( r ) && ( !selectionGeomPrepared || selectionGeomPrepared->intersects( f.geometry().constGet() ) ) )
539 QMap<QString, QString> derivedAttributes = commonDerivedAttributes;
540 derivedAttributes.insert( tr(
"Feature ID" ),
FID_TO_STRING( f.id() ) );
541 derivedAttributes.insert( tr(
"Tile column" ), QString::number( tileID.column() ) );
542 derivedAttributes.insert( tr(
"Tile row" ), QString::number( tileID.row() ) );
543 derivedAttributes.insert( tr(
"Tile zoom" ), QString::number( tileID.zoomLevel() ) );
553 catch ( QgsCsException &cse )
560 return featureCount > 0;
565 if ( mPropertiesOverrides.skip3DLayers &&
layer->renderer3D() )
570 if ( !
layer->elevationProperties()->isVisibleInZRange( identifyContext.
zRange(),
layer ) )
574 QgsPointCloudRenderer *renderer =
layer->renderer();
581 const double searchRadiusMapUnits = mPropertiesOverrides.searchRadiusMapUnits < 0 ?
searchRadiusMU(
mCanvas ) : mPropertiesOverrides.searchRadiusMapUnits;
583 const QVector<QVariantMap> points = renderer->
identify(
layer, context, geometry, searchRadiusMapUnits );
592 QMap<QString, QString> derivedAttributes;
596 formatCoordinate( point, x, y );
598 derivedAttributes.insert( tr(
"(clicked coordinate X)" ), x );
599 derivedAttributes.insert( tr(
"(clicked coordinate Y)" ), y );
601 derivedAttributes.insert( tr(
"(clicked coordinate Z)" ), QLocale().toString( point.
z(),
'f' ) );
602 return derivedAttributes;
619 QString temporalFilter;
622 if ( !
layer->temporalProperties()->isVisibleInTemporalRange( identifyContext.
temporalRange() ) )
625 QgsVectorLayerTemporalContext temporalContext;
627 temporalFilter = qobject_cast<const QgsVectorLayerTemporalProperties *>(
layer->temporalProperties() )->createFilterString( temporalContext, identifyContext.
temporalRange() );
632 QApplication::setOverrideCursor( Qt::WaitCursor );
634 QMap<QString, QString> commonDerivedAttributes;
636 QgsGeometry selectionGeom = geometry;
637 bool isPointOrRectangle;
642 isPointOrRectangle =
true;
654 std::unique_ptr<QgsGeometryEngine> selectionGeomPrepared;
664 double sr = mPropertiesOverrides.searchRadiusMapUnits < 0 ?
searchRadiusMU(
mCanvas ) : mPropertiesOverrides.searchRadiusMapUnits;
671 if ( !isPointOrRectangle )
673 QgsCoordinateTransform ct(
mCanvas->mapSettings().destinationCrs(),
layer->crs(),
mCanvas->mapSettings().transformContext() );
682 QgsFeatureRequest featureRequest;
685 if ( !temporalFilter.isEmpty() )
688 QgsFeatureIterator fit =
layer->getFeatures( featureRequest );
692 if ( !selectionGeomPrepared || selectionGeomPrepared->intersects( f.
geometry().
constGet() ) )
693 featureList << QgsFeature( f );
696 catch ( QgsCsException &cse )
708 std::unique_ptr<QgsFeatureRenderer> renderer(
layer->renderer() ?
layer->renderer()->clone() :
nullptr );
717 if ( !isSingleClick )
720 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 );
726 QApplication::restoreOverrideCursor();
727 return featureCount > 0;
732 int featureCount = 0;
733 for (
const QgsFeature &feature : std::as_const( features ) )
735 QMap<QString, QString> derivedAttributes = commonDerivedAttributes;
743 derivedAttributes.insert( deriveAttributesForFeature( feature ) );
744 derivedAttributes.insert( tr(
"Feature ID" ), fid < 0 ? tr(
"new feature" ) :
FID_TO_STRING( fid ) );
746 results->append(
IdentifyResult( qobject_cast<QgsMapLayer *>(
layer ), feature, derivedAttributes ) );
761 QString str = QLocale().toString( vId.
vertex + 1 );
762 derivedAttributes.insert( tr(
"Closest vertex number" ), str );
764 QgsPoint closestPoint = geometry.
vertexAt( vId );
765 QgsPoint closestPointMapCoords = closestPoint;
766 if ( layerToMapTransform.
isValid() )
772 catch ( QgsCsException &cse )
780 formatCoordinate( closestPointMapCoords, x, y );
781 derivedAttributes.insert( tr(
"Closest vertex X" ), x );
782 derivedAttributes.insert( tr(
"Closest vertex Y" ), y );
784 if ( closestPoint.
is3D() )
786 str = QLocale().toString( closestPoint.
z(),
'g', 10 );
789 if ( showTransformedZ && !std::isnan( closestPointMapCoords.
z() ) && !
qgsDoubleNear( closestPoint.
z(), closestPointMapCoords.
z() ) )
791 const QString str = QLocale().toString( closestPointMapCoords.
z(),
'g', 10 );
797 str = QLocale().toString( closestPointMapCoords.
m(),
'g', 10 );
798 derivedAttributes.insert( tr(
"Closest vertex M" ), str );
803 double radius, centerX, centerY;
804 QgsVertexId vIdBefore = vId;
806 QgsVertexId vIdAfter = vId;
809 derivedAttributes.insert( u
"Closest vertex radius"_s, QLocale().toString( radius ) );
816 QgsPoint closestPointMapCrs = closestPoint;
817 if ( layerToMapTransform.
isValid() )
823 catch ( QgsCsException &cse )
831 formatCoordinate( closestPoint, x, y );
832 derivedAttributes.insert( tr(
"Closest X" ), x );
833 derivedAttributes.insert( tr(
"Closest Y" ), y );
835 if ( closestPoint.
is3D() )
837 const QString str = QLocale().toString( closestPoint.
z(),
'g', 10 );
840 if ( showTransformedZ && !std::isnan( closestPointMapCrs.
z() ) && !
qgsDoubleNear( closestPoint.
z(), closestPointMapCrs.
z() ) )
842 const QString str = QLocale().toString( closestPointMapCrs.
z(),
'g', 10 );
848 const QString str = QLocale().toString( closestPoint.
m(),
'g', 10 );
849 derivedAttributes.insert( tr(
"Interpolated M" ), str );
855 QgsCoordinateUtils::formatCoordinatePartsForProject(
QgsProject::instance(), canvasPoint, mapCrs, coordinatePrecision, x, y );
858void QgsMapToolIdentify::formatCoordinate(
const QgsPointXY &canvasPoint, QString &x, QString &y )
const
860 formatCoordinate( canvasPoint, x, y,
mCanvas->mapSettings().destinationCrs(), mCoordinatePrecision );
867 QMap<QString, QString> derivedAttributes;
871 QgsDistanceArea calc;
879 QgsPoint closestPoint;
893 QString str = QLocale().toString(
static_cast<const QgsGeometryCollection *
>( feature.
geometry().
constGet() )->numGeometries() );
894 derivedAttributes.insert( tr(
"Parts" ), str );
897 str = QLocale().toString( vId.
part + 1 );
898 derivedAttributes.insert( tr(
"Part number" ), str );
903 ? displayDistanceUnits()
904 :
layer->crs().mapUnits();
907 : QgsUnitTypes::distanceToAreaUnit(
layer->crs().mapUnits() );
911 const QgsCoordinateReferenceSystem layerVertCrs =
layer->crs3D().verticalCrs().isValid() ?
layer->crs3D().verticalCrs()
916 const QgsGeometry layerCrsGeometry = feature.
geometry();
917 QgsGeometry mapCrsGeometry = layerCrsGeometry;
920 if ( layerToMapTransform.
isValid() )
925 catch ( QgsCsException &cse )
932 const QgsAbstractGeometry *layerCrsGeom = layerCrsGeometry.
constGet();
940 catch ( QgsCsException & )
943 QgsDebugError( u
"An error occurred while calculating length"_s );
949 str = formatDistance( dist );
950 derivedAttributes.insert( tr(
"Length (Ellipsoidal — %1)" ).arg( ellipsoid ), str );
958 derivedAttributes.insert( tr(
"Length (Cartesian — 2D)" ), str );
960 double totalLength3d = std::accumulate( layerCrsGeom->
const_parts_begin(), layerCrsGeom->
const_parts_end(), 0.0, [](
double total,
const QgsAbstractGeometry *part ) {
961 return total + qgsgeometry_cast<const QgsLineString *>( part )->length3D();
964 str = formatDistance( totalLength3d, cartesianDistanceUnits );
965 derivedAttributes.insert( tr(
"Length (Cartesian — 3D)" ), str );
969 derivedAttributes.insert( tr(
"Length (Cartesian)" ), str );
972 str = QLocale().toString( layerCrsGeom->
nCoordinates() );
973 derivedAttributes.insert( tr(
"Vertices" ), str );
977 closestVertexAttributes( layerToMapTransform, layerVertCrs, mapVertCrs, *layerCrsGeom, vId, showTransformedZ, derivedAttributes );
978 closestPointAttributes( layerToMapTransform, layerVertCrs, mapVertCrs, *layerCrsGeom, layerPoint, showTransformedZ, derivedAttributes );
984 QgsPointXY pnt =
mCanvas->mapSettings().layerToMapCoordinates(
layer, QgsPointXY( curve->startPoint().x(), curve->startPoint().y() ) );
987 formatCoordinate( pnt, x, y );
988 derivedAttributes.insert( tr(
"firstX",
"attributes get sorted; translation for lastX should be lexically larger than this one" ), x );
989 derivedAttributes.insert( tr(
"firstY" ), y );
990 pnt =
mCanvas->mapSettings().layerToMapCoordinates(
layer, QgsPointXY( curve->endPoint().x(), curve->endPoint().y() ) );
991 formatCoordinate( pnt, x, y );
992 derivedAttributes.insert( tr(
"lastX",
"attributes get sorted; translation for firstX should be lexically smaller than this one" ), x );
993 derivedAttributes.insert( tr(
"lastY" ), y );
1004 catch ( QgsCsException & )
1007 QgsDebugError( u
"An error occurred while calculating area"_s );
1013 str = formatArea( area );
1014 derivedAttributes.insert( tr(
"Area (Ellipsoidal — %1)" ).arg( ellipsoid ), str );
1017 derivedAttributes.insert( tr(
"Area (Cartesian)" ), str );
1021 double perimeter = 0;
1027 catch ( QgsCsException & )
1030 QgsDebugError( u
"An error occurred while calculating perimeter"_s );
1032 str = formatDistance( perimeter );
1033 derivedAttributes.insert( tr(
"Perimeter (Ellipsoidal — %1)" ).arg( ellipsoid ), str );
1036 derivedAttributes.insert( tr(
"Perimeter (Cartesian)" ), str );
1039 derivedAttributes.insert( tr(
"Vertices" ), str );
1044 closestVertexAttributes( layerToMapTransform, layerVertCrs, mapVertCrs, *layerCrsGeometry.
constGet(), vId, showTransformedZ, derivedAttributes );
1045 closestPointAttributes( layerToMapTransform, layerVertCrs, mapVertCrs, *layerCrsGeometry.
constGet(), layerPoint, showTransformedZ, derivedAttributes );
1055 formatCoordinate( QgsPointXY( mapCrsPoint->x(), mapCrsPoint->y() ), x, y );
1056 derivedAttributes.insert( tr(
"X" ), x );
1057 derivedAttributes.insert( tr(
"Y" ), y );
1060 : std::numeric_limits<double>::quiet_NaN();
1061 const double mapCrsZ = mapCrsPoint->is3D() ? mapCrsPoint->z() : std::numeric_limits<double>::quiet_NaN();
1063 if ( !std::isnan( originalZ ) )
1065 const QString str = QLocale().toString( originalZ,
'g', 10 );
1068 if ( showTransformedZ && !std::isnan( mapCrsZ ) && !
qgsDoubleNear( originalZ, mapCrsZ ) )
1070 const QString str = QLocale().toString( mapCrsZ,
'g', 10 );
1077 derivedAttributes.insert( tr(
"M" ), str );
1086 const QgsAbstractGeometry *geom = layerCrsGeometry.
constGet();
1087 closestVertexAttributes( layerToMapTransform, layerVertCrs, mapVertCrs, *geom, vId, showTransformedZ, derivedAttributes );
1097 return derivedAttributes;
1102 QgsPointXY point = geometry.
asPoint();
1112 std::unique_ptr<QgsRasterDataProvider> dprovider(
layer->dataProvider()->clone() );
1122 if ( !
layer->temporalProperties()->isVisibleInTemporalRange( identifyContext.
temporalRange() ) )
1125 dprovider->temporalCapabilities()->setRequestedTemporalRange( identifyContext.
temporalRange() );
1130 if ( !
layer->elevationProperties()->isVisibleInZRange( identifyContext.
zRange(),
layer ) )
1147 if ( !
layer->extent().contains( point ) )
1150 QMap<QString, QString> attributes, derivedAttributes;
1171 if ( dprovider->crs() !=
mCanvas->mapSettings().destinationCrs() )
1180 r.
setXMinimum( pointInCanvasCrs.
x() - mapUnitsPerPixel / 2. );
1181 r.
setXMaximum( pointInCanvasCrs.
x() + mapUnitsPerPixel / 2. );
1182 r.
setYMinimum( pointInCanvasCrs.
y() - mapUnitsPerPixel / 2. );
1183 r.
setYMaximum( pointInCanvasCrs.
y() + mapUnitsPerPixel / 2. );
1187 identifyResult = dprovider->identify( point, format, r, 1, 1 );
1203 int width =
static_cast<int>( std::round( viewExtent.
width() / mapUnitsPerPixel ) );
1204 int height =
static_cast<int>( std::round( viewExtent.
height() / mapUnitsPerPixel ) );
1207 QgsDebugMsgLevel( u
"width = %1 height = %2"_s.arg( width ).arg( height ), 2 );
1208 QgsDebugMsgLevel( u
"xRes = %1 yRes = %2 mapUnitsPerPixel = %3"_s.arg( viewExtent.
width() / width ).arg( viewExtent.
height() / height ).arg( mapUnitsPerPixel ), 2 );
1210 identifyResult = dprovider->identify( point, format, viewExtent, width, height );
1221 bool foundMatch =
false;
1222 QMap<int, QVariant> values = identifyResult.
results();
1223 QMap<int, QVariant> filteredValues;
1224 for (
auto it = values.constBegin(); it != values.constEnd(); ++it )
1230 const double value = it.value().toDouble();
1234 filteredValues.insert( it.key(), it.value() );
1258 const double xres =
layer->rasterUnitsPerPixelX();
1259 const double yres =
layer->rasterUnitsPerPixelY();
1267 const int rasterCol =
static_cast<int>( std::floor( ( point.
x() - extent.
xMinimum() ) / xres ) );
1268 const int rasterRow =
static_cast<int>( std::floor( ( extent.
yMaximum() - point.
y() ) / yres ) );
1270 derivedAttributes.insert( tr(
"Column (0-based)" ), QLocale().toString( rasterCol ) );
1271 derivedAttributes.insert( tr(
"Row (0-based)" ), QLocale().toString( rasterRow ) );
1276 if ( identifyResult.
isValid() )
1278 QMap<int, QVariant> values = identifyResult.
results();
1281 for (
auto it = values.constBegin(); it != values.constEnd(); ++it )
1283 QString valueString;
1286 valueString = tr(
"no data" );
1290 QVariant value( it.value() );
1294 if (
static_cast<QMetaType::Type
>( value.userType() ) == QMetaType::Float )
1303 attributes.insert( dprovider->generateBandName( it.key() ), valueString );
1309 const double doubleValue { it.value().toDouble( &ok ) };
1312 const QVariantList row = rat->row( doubleValue );
1313 if ( !row.isEmpty() )
1315 for (
int colIdx = 0; colIdx < std::min( rat->fields().count(), row.count() ); ++colIdx )
1326 switch ( ratField.
type )
1328 case QMetaType::Type::QChar:
1329 case QMetaType::Type::Int:
1330 case QMetaType::Type::UInt:
1331 case QMetaType::Type::LongLong:
1332 case QMetaType::Type::ULongLong:
1333 ratValue = QLocale().toString( row.at( colIdx ).toLongLong() );
1335 case QMetaType::Type::Double:
1336 ratValue = QLocale().toString( row.at( colIdx ).toDouble() );
1339 ratValue = row.at( colIdx ).toString();
1341 attributes.insert( ratField.
name, ratValue );
1348 QString label =
layer->name();
1350 if ( !pixelRect.
isNull() )
1357 results->append( result );
1361 for (
auto it = values.constBegin(); it != values.constEnd(); ++it )
1363 QVariant value = it.value();
1364 if ( value.userType() == QMetaType::Type::Bool && !value.toBool() )
1370 if ( value.userType() == QMetaType::Type::QString )
1374 QString label =
layer->subLayers().value( it.key() );
1376 attributes.insert( tr(
"Error" ), value.toString() );
1378 results->append(
IdentifyResult( qobject_cast<QgsMapLayer *>(
layer ), label, attributes, derivedAttributes ) );
1388 for (
const QgsFeature &feature : storeFeatures )
1394 QString sublayer = featureStore.params().value( u
"sublayer"_s ).toString();
1395 QString featureType = featureStore.params().value( u
"featureType"_s ).toString();
1397 featureType.remove( u
"_feature"_s );
1399 if ( sublayer.compare(
layer->name(), Qt::CaseInsensitive ) != 0 )
1403 if ( featureType.compare( sublayer, Qt::CaseInsensitive ) != 0 || labels.isEmpty() )
1405 labels << featureType;
1408 QMap<QString, QString> derAttributes = derivedAttributes;
1411 IdentifyResult identifyResult( qobject_cast<QgsMapLayer *>(
layer ), labels.join(
" / "_L1 ), featureStore.fields(), feature, derAttributes );
1413 identifyResult.
mParams.insert( u
"getFeatureInfoUrl"_s, featureStore.params().value( u
"getFeatureInfoUrl"_s ) );
1414 results->append( identifyResult );
1422 for (
auto it = values.constBegin(); it != values.constEnd(); ++it )
1424 QString value = it.value().toString();
1426 attributes.insert( QString(), value );
1428 QString label =
layer->subLayers().value( it.key() );
1429 results->append(
IdentifyResult( qobject_cast<QgsMapLayer *>(
layer ), label, attributes, derivedAttributes ) );
1437 attributes.insert( tr(
"Error" ), value );
1438 QString label = tr(
"Identify error" );
1439 results->append(
IdentifyResult( qobject_cast<QgsMapLayer *>(
layer ), label, attributes, derivedAttributes ) );
1455QString QgsMapToolIdentify::formatDistance(
double distance )
const
1457 return formatDistance( distance, displayDistanceUnits() );
1460QString QgsMapToolIdentify::formatArea(
double area )
const
1462 return formatArea( area, displayAreaUnits() );
1465QString QgsMapToolIdentify::formatDistance(
double distance,
Qgis::DistanceUnit unit )
const
1467 QgsSettings settings;
1468 bool baseUnit = settings.
value( u
"qgis/measure/keepbaseunit"_s,
true ).toBool();
1473QString QgsMapToolIdentify::formatArea(
double area,
Qgis::AreaUnit unit )
const
1475 QgsSettings settings;
1476 bool baseUnit = settings.
value( u
"qgis/measure/keepbaseunit"_s,
true ).toBool();
1483 QList<IdentifyResult> results;
1501 for (
const QVariantMap &pt : identified )
1503 QMap<QString, QString> ptStr;
1504 QString classification;
1505 for (
auto attrIt = pt.constBegin(); attrIt != pt.constEnd(); ++attrIt )
1507 if ( attrIt.key().compare(
'Z'_L1, Qt::CaseInsensitive ) == 0
1511 ptStr[tr(
"Z (original)" )] = attrIt.value().toString();
1512 ptStr[tr(
"Z (adjusted)" )] = QString::number( attrIt.value().toDouble() * elevationProps->
zScale() + elevationProps->
zOffset() );
1514 else if ( attrIt.key().compare(
"Classification"_L1, Qt::CaseInsensitive ) == 0 )
1517 ptStr[attrIt.key()] = u
"%1 (%2)"_s.arg( attrIt.value().toString(), classification );
1521 ptStr[attrIt.key()] = attrIt.value().toString();
1525 QMap<QString, QString> derivedAttributes;
1526 QgsPoint layerPoint( pt.value(
"X" ).toDouble(), pt.value(
"Y" ).toDouble(), pt.value(
"Z" ).toDouble() );
1531 if ( layerToMapTransform.
isValid() )
1546 derivedAttributes.insert( tr(
"X" ), x );
1547 derivedAttributes.insert( tr(
"Y" ), y );
1549 const double originalZ = layerPoint.
z();
1550 const double mapCrsZ = mapCrsPoint.
is3D() ? mapCrsPoint.
z() : std::numeric_limits<double>::quiet_NaN();
1552 if ( !std::isnan( originalZ ) )
1554 const QString str = QLocale().toString( originalZ,
'g', 10 );
1557 if ( showTransformedZ && !std::isnan( mapCrsZ ) && !
qgsDoubleNear( originalZ, mapCrsZ ) )
1559 const QString str = QLocale().toString( mapCrsZ,
'g', 10 );
1564 results.append( res );
1574 if ( identified.empty() )
1577 switch (
layer->type() )
1584 QHash<QgsFeatureId, QVariant> featureDistances;
1585 QHash<QgsFeatureId, QVariant> featureElevations;
1588 for (
const QVariantMap &map : identified )
1590 if ( !map.contains( u
"id"_s ) )
1592 QMap<QString, QString> attributes;
1593 if ( map.value( u
"distance"_s ).isValid() )
1594 attributes.insert( tr(
"Distance along curve" ), QString::number( map.value( u
"distance"_s ).toDouble() ) );
1595 if ( map.value( u
"elevation"_s ).isValid() )
1596 attributes.insert( tr(
"Elevation" ), QString::number( map.value( u
"elevation"_s ).toDouble() ) );
1602 const QgsFeatureId id = map.value( u
"id"_s ).toLongLong();
1603 filterIds.insert(
id );
1605 featureDistances.insert(
id, map.value( u
"distance"_s ) );
1606 featureElevations.insert(
id, map.value( u
"elevation"_s ) );
1618 identifyVectorLayer( &results, vl, features,
nullptr, QMap<QString, QString>(), [
this, vl, &featureDistances, &featureElevations](
const QgsFeature &feature ) -> QMap<QString, QString> {
1619 QMap< QString, QString > attributes = featureDerivedAttributes( feature, vl,
QgsPointXY() );
1621 if ( featureDistances.value( feature.
id() ).isValid() )
1622 attributes.insert( tr(
"Distance along curve" ), QString::number( featureDistances.value( feature.
id() ).toDouble() ) );
1623 if ( featureElevations.value( feature.
id() ).isValid() )
1624 attributes.insert( tr(
"Elevation" ), QString::number( featureElevations.value( feature.
id() ).toDouble() ) );
1626 return attributes; }, context );
1633 for (
const QVariantMap &map : identified )
1635 QMap<QString, QString> attributes;
1636 if ( map.value( u
"distance"_s ).isValid() )
1637 attributes.insert( tr(
"Distance along curve" ), QString::number( map.value( u
"distance"_s ).toDouble() ) );
1638 if ( map.value( u
"elevation"_s ).isValid() )
1639 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())
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.