Skip to content

Commit 5c6e794

Browse files
committedJun 22, 2017
nearest point measure in identify tool
1 parent 7cd517c commit 5c6e794

File tree

5 files changed

+56
-0
lines changed

5 files changed

+56
-0
lines changed
 

‎python/core/geometry/qgsgeometryutils.sip

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,12 @@ class QgsGeometryUtils
3737
:rtype: QgsPoint
3838
%End
3939

40+
static double closestPointMeasure( const QgsAbstractGeometry &geom, const QgsPoint &pt );
41+
%Docstring
42+
Returns measure of nearest point on a geometry for a specified point or NaN if geometry does not have measures
43+
:rtype: float
44+
%End
45+
4046
static double distanceToVertex( const QgsAbstractGeometry &geom, QgsVertexId id );
4147
%Docstring
4248
Returns the distance along a geometry from its first vertex to the specified vertex.

‎src/core/geometry/qgsgeometryutils.cpp

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,35 @@ QgsPoint QgsGeometryUtils::closestVertex( const QgsAbstractGeometry &geom, const
9393
return minDistPoint;
9494
}
9595

96+
double QgsGeometryUtils::closestPointMeasure( const QgsAbstractGeometry &geom, const QgsPoint &pt )
97+
{
98+
if ( QgsWkbTypes::hasM( geom.wkbType() ) )
99+
{
100+
QgsPoint closestPoint;
101+
QgsVertexId vertexAfter;
102+
bool leftOf;
103+
geom.closestSegment( pt, closestPoint, vertexAfter, &leftOf, DEFAULT_SEGMENT_EPSILON );
104+
if ( vertexAfter.isValid() )
105+
{
106+
QgsPoint pointAfter = geom.vertexAt( vertexAfter );
107+
if ( vertexAfter.vertex > 0 )
108+
{
109+
QgsVertexId vertexBefore = vertexAfter;
110+
vertexBefore.vertex--;
111+
QgsPoint pointBefore = geom.vertexAt( vertexBefore );
112+
double length = pointBefore.distance( pointAfter );
113+
double distance = pointBefore.distance( closestPoint );
114+
return pointBefore.m() + ( pointAfter.m() - pointBefore.m() ) * distance / length;
115+
}
116+
else
117+
{
118+
return pointAfter.m();
119+
}
120+
}
121+
}
122+
return std::numeric_limits<double>::quiet_NaN();
123+
}
124+
96125
double QgsGeometryUtils::distanceToVertex( const QgsAbstractGeometry &geom, QgsVertexId id )
97126
{
98127
double currentDist = 0;

‎src/core/geometry/qgsgeometryutils.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,10 @@ class CORE_EXPORT QgsGeometryUtils
4444
*/
4545
static QgsPoint closestVertex( const QgsAbstractGeometry &geom, const QgsPoint &pt, QgsVertexId &id SIP_OUT );
4646

47+
/** Returns measure of nearest point on a geometry for a specified point or NaN if geometry does not have measures
48+
*/
49+
static double closestPointMeasure( const QgsAbstractGeometry &geom, const QgsPoint &pt );
50+
4751
/** Returns the distance along a geometry from its first vertex to the specified vertex.
4852
* \param geom geometry
4953
* \param id vertex id to find distance to

‎src/gui/qgsmaptoolidentify.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -326,6 +326,18 @@ void QgsMapToolIdentify::closestVertexAttributes( const QgsAbstractGeometry &geo
326326
}
327327
}
328328

329+
void QgsMapToolIdentify::closestPointAttributes( const QgsAbstractGeometry &geometry, QgsMapLayer *layer, const QgsPointXY &layerPoint, QMap< QString, QString > &derivedAttributes )
330+
{
331+
Q_UNUSED( layer );
332+
// measure
333+
if ( QgsWkbTypes::hasM( geometry.wkbType() ) )
334+
{
335+
double measure = QgsGeometryUtils::closestPointMeasure( geometry, QgsPoint( layerPoint.x(), layerPoint.y() ) );
336+
QString str = QLocale::system().toString( measure, 'g', 10 );
337+
derivedAttributes.insert( QStringLiteral( "Closest point M" ), str );
338+
}
339+
}
340+
329341
QString QgsMapToolIdentify::formatCoordinate( const QgsPointXY &canvasPoint ) const
330342
{
331343
return QgsCoordinateUtils::formatCoordinateForProject( canvasPoint, mCanvas->mapSettings().destinationCrs(),
@@ -392,6 +404,7 @@ QMap< QString, QString > QgsMapToolIdentify::featureDerivedAttributes( QgsFeatur
392404

393405
//add details of closest vertex to identify point
394406
closestVertexAttributes( *curve, vId, layer, derivedAttributes );
407+
closestPointAttributes( *curve, layer, layerPoint, derivedAttributes );
395408

396409
// Add the start and end points in as derived attributes
397410
QgsPointXY pnt = mCanvas->mapSettings().layerToMapCoordinates( layer, QgsPointXY( curve->startPoint().x(), curve->startPoint().y() ) );

‎src/gui/qgsmaptoolidentify.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,10 @@ class GUI_EXPORT QgsMapToolIdentify : public QgsMapTool
183183
*/
184184
void closestVertexAttributes( const QgsAbstractGeometry &geometry, QgsVertexId vId, QgsMapLayer *layer, QMap< QString, QString > &derivedAttributes );
185185

186+
/** Adds details of the closest point to derived attributes
187+
*/
188+
void closestPointAttributes( const QgsAbstractGeometry &geometry, QgsMapLayer *layer, const QgsPointXY &layerPoint, QMap< QString, QString > &derivedAttributes );
189+
186190
QString formatCoordinate( const QgsPointXY &canvasPoint ) const;
187191
QString formatXCoordinate( const QgsPointXY &canvasPoint ) const;
188192
QString formatYCoordinate( const QgsPointXY &canvasPoint ) const;

0 commit comments

Comments
 (0)