{{ message }}

# qgis / QGIS Public

nearest point measure in identify tool
blazek committed Jun 22, 2017
@@ -37,6 +37,12 @@ class QgsGeometryUtils
:rtype: QgsPoint
%End

static double closestPointMeasure( const QgsAbstractGeometry &geom, const QgsPoint &pt );

#### 3nids Jun 22, 2017

Member

I guess it would make a lot of sense to create its sibling for Z, no?

#### blazek Jun 22, 2017

Author Member

Yes. In such case, it would be probably better to return QgsPoint with Z / M set, according to input geometry.

#### 3nids Jun 22, 2017

Member

Makes sense. Would you do it?

Author Member

No.

#### m-kuhn Jun 23, 2017

Member

Doesn't `QgsGeometryUtils::closestVertex` do this in a generic way (and this new method is redundant)?

#### blazek Jun 23, 2017

Author Member

QgsGeometryUtils::closestVertex returns nearest vertex, not nearest point on segment.

#### m-kuhn Jun 23, 2017

Member

Ah right, I missed that. Nice!
Can you elaborate on this interpolation behavior in the docs?
Also a unit test and a plan of action concerning the z discussed above would be great.
Thanks a lot.

#### blazek Jun 23, 2017

Author Member

Would be great, but no free resources here.

%Docstring
Returns measure of nearest point on a geometry for a specified point or NaN if geometry does not have measures
:rtype: float
%End

static double distanceToVertex( const QgsAbstractGeometry &geom, QgsVertexId id );
%Docstring
Returns the distance along a geometry from its first vertex to the specified vertex.
 @@ -93,6 +93,35 @@ QgsPoint QgsGeometryUtils::closestVertex( const QgsAbstractGeometry &geom, const return minDistPoint; } double QgsGeometryUtils::closestPointMeasure( const QgsAbstractGeometry &geom, const QgsPoint &pt ) { if ( QgsWkbTypes::hasM( geom.wkbType() ) ) { QgsPoint closestPoint; QgsVertexId vertexAfter; bool leftOf; geom.closestSegment( pt, closestPoint, vertexAfter, &leftOf, DEFAULT_SEGMENT_EPSILON ); if ( vertexAfter.isValid() ) { QgsPoint pointAfter = geom.vertexAt( vertexAfter ); if ( vertexAfter.vertex > 0 ) { QgsVertexId vertexBefore = vertexAfter; vertexBefore.vertex--; QgsPoint pointBefore = geom.vertexAt( vertexBefore ); double length = pointBefore.distance( pointAfter ); double distance = pointBefore.distance( closestPoint ); return pointBefore.m() + ( pointAfter.m() - pointBefore.m() ) * distance / length; } else { return pointAfter.m(); } } } return std::numeric_limits::quiet_NaN(); } double QgsGeometryUtils::distanceToVertex( const QgsAbstractGeometry &geom, QgsVertexId id ) { double currentDist = 0;
 @@ -44,6 +44,10 @@ class CORE_EXPORT QgsGeometryUtils */ static QgsPoint closestVertex( const QgsAbstractGeometry &geom, const QgsPoint &pt, QgsVertexId &id SIP_OUT ); /** Returns measure of nearest point on a geometry for a specified point or NaN if geometry does not have measures */ static double closestPointMeasure( const QgsAbstractGeometry &geom, const QgsPoint &pt ); /** Returns the distance along a geometry from its first vertex to the specified vertex. * \param geom geometry * \param id vertex id to find distance to
 @@ -326,6 +326,18 @@ void QgsMapToolIdentify::closestVertexAttributes( const QgsAbstractGeometry &geo } } void QgsMapToolIdentify::closestPointAttributes( const QgsAbstractGeometry &geometry, QgsMapLayer *layer, const QgsPointXY &layerPoint, QMap< QString, QString > &derivedAttributes ) { Q_UNUSED( layer ); // measure if ( QgsWkbTypes::hasM( geometry.wkbType() ) ) { double measure = QgsGeometryUtils::closestPointMeasure( geometry, QgsPoint( layerPoint.x(), layerPoint.y() ) ); QString str = QLocale::system().toString( measure, 'g', 10 ); derivedAttributes.insert( QStringLiteral( "Closest point M" ), str ); } } QString QgsMapToolIdentify::formatCoordinate( const QgsPointXY &canvasPoint ) const { return QgsCoordinateUtils::formatCoordinateForProject( canvasPoint, mCanvas->mapSettings().destinationCrs(), @@ -392,6 +404,7 @@ QMap< QString, QString > QgsMapToolIdentify::featureDerivedAttributes( QgsFeatur //add details of closest vertex to identify point closestVertexAttributes( *curve, vId, layer, derivedAttributes ); closestPointAttributes( *curve, layer, layerPoint, derivedAttributes ); // Add the start and end points in as derived attributes QgsPointXY pnt = mCanvas->mapSettings().layerToMapCoordinates( layer, QgsPointXY( curve->startPoint().x(), curve->startPoint().y() ) );
 @@ -183,6 +183,10 @@ class GUI_EXPORT QgsMapToolIdentify : public QgsMapTool */ void closestVertexAttributes( const QgsAbstractGeometry &geometry, QgsVertexId vId, QgsMapLayer *layer, QMap< QString, QString > &derivedAttributes ); /** Adds details of the closest point to derived attributes */ void closestPointAttributes( const QgsAbstractGeometry &geometry, QgsMapLayer *layer, const QgsPointXY &layerPoint, QMap< QString, QString > &derivedAttributes ); QString formatCoordinate( const QgsPointXY &canvasPoint ) const; QString formatXCoordinate( const QgsPointXY &canvasPoint ) const; QString formatYCoordinate( const QgsPointXY &canvasPoint ) const;