Skip to content

Commit b58849f

Browse files
committedAug 16, 2018
Resurrect display of interpolated z/m in identify results, and
add closest point x/y (closest point on geometry) Add tests Fixes #19403 (cherry-picked from 3f9ea77)
1 parent cef3b16 commit b58849f

File tree

3 files changed

+85
-0
lines changed

3 files changed

+85
-0
lines changed
 

‎src/gui/qgsmaptoolidentify.cpp

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -374,6 +374,25 @@ void QgsMapToolIdentify::closestVertexAttributes( const QgsAbstractGeometry &geo
374374
}
375375
}
376376

377+
void QgsMapToolIdentify::closestPointAttributes( const QgsAbstractGeometry &geometry, const QgsPointXY &layerPoint, QMap<QString, QString> &derivedAttributes )
378+
{
379+
QgsPoint closestPoint = QgsGeometryUtils::closestPoint( geometry, QgsPoint( layerPoint.x(), layerPoint.y() ) );
380+
381+
derivedAttributes.insert( tr( "Closest X" ), formatXCoordinate( closestPoint ) );
382+
derivedAttributes.insert( tr( "Closest Y" ), formatYCoordinate( closestPoint ) );
383+
384+
if ( closestPoint.is3D() )
385+
{
386+
const QString str = QLocale().toString( closestPoint.z(), 'g', 10 );
387+
derivedAttributes.insert( tr( "Interpolated Z" ), str );
388+
}
389+
if ( closestPoint.isMeasure() )
390+
{
391+
const QString str = QLocale().toString( closestPoint.m(), 'g', 10 );
392+
derivedAttributes.insert( tr( "Interpolated M" ), str );
393+
}
394+
}
395+
377396
QString QgsMapToolIdentify::formatCoordinate( const QgsPointXY &canvasPoint ) const
378397
{
379398
return QgsCoordinateUtils::formatCoordinateForProject( QgsProject::instance(), canvasPoint, mCanvas->mapSettings().destinationCrs(),
@@ -451,6 +470,7 @@ QMap< QString, QString > QgsMapToolIdentify::featureDerivedAttributes( const Qgs
451470
derivedAttributes.insert( tr( "Vertices" ), str );
452471
//add details of closest vertex to identify point
453472
closestVertexAttributes( *geom, vId, layer, derivedAttributes );
473+
closestPointAttributes( *geom, layerPoint, derivedAttributes );
454474

455475
if ( const QgsCurve *curve = qgsgeometry_cast< const QgsCurve * >( geom ) )
456476
{
@@ -498,6 +518,7 @@ QMap< QString, QString > QgsMapToolIdentify::featureDerivedAttributes( const Qgs
498518

499519
//add details of closest vertex to identify point
500520
closestVertexAttributes( *feature.geometry().constGet(), vId, layer, derivedAttributes );
521+
closestPointAttributes( *feature.geometry().constGet(), layerPoint, derivedAttributes );
501522
}
502523
else if ( geometryType == QgsWkbTypes::PointGeometry )
503524
{

‎src/gui/qgsmaptoolidentify.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -218,6 +218,11 @@ class GUI_EXPORT QgsMapToolIdentify : public QgsMapTool
218218
*/
219219
void closestVertexAttributes( const QgsAbstractGeometry &geometry, QgsVertexId vId, QgsMapLayer *layer, QMap< QString, QString > &derivedAttributes );
220220

221+
/**
222+
* Adds details of the closest point to derived attributes
223+
*/
224+
void closestPointAttributes( const QgsAbstractGeometry &geometry, const QgsPointXY &layerPoint, QMap< QString, QString > &derivedAttributes );
225+
221226
QString formatCoordinate( const QgsPointXY &canvasPoint ) const;
222227
QString formatXCoordinate( const QgsPointXY &canvasPoint ) const;
223228
QString formatYCoordinate( const QgsPointXY &canvasPoint ) const;

‎tests/src/app/testqgsmaptoolidentifyaction.cpp

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ class TestQgsMapToolIdentifyAction : public QObject
5555
void identifyRasterFloat64(); // test pixel identification and decimal precision
5656
void identifyInvalidPolygons(); // test selecting invalid polygons
5757
void clickxy(); // test if clicked_x and clicked_y variables are propagated
58+
void closestPoint();
5859

5960
private:
6061
void doAction();
@@ -209,6 +210,64 @@ void TestQgsMapToolIdentifyAction::clickxy()
209210
mIdentifyAction->canvasReleaseEvent( &mapReleases );
210211
}
211212

213+
void TestQgsMapToolIdentifyAction::closestPoint()
214+
{
215+
QgsSettings s;
216+
s.setValue( QStringLiteral( "/qgis/measure/keepbaseunit" ), true );
217+
218+
//create a temporary layer
219+
std::unique_ptr< QgsVectorLayer> tempLayer( new QgsVectorLayer( QStringLiteral( "LineStringZM?crs=epsg:3111&field=pk:int&field=col1:double" ), QStringLiteral( "vl" ), QStringLiteral( "memory" ) ) );
220+
QVERIFY( tempLayer->isValid() );
221+
QgsFeature f1( tempLayer->dataProvider()->fields(), 1 );
222+
f1.setAttribute( QStringLiteral( "pk" ), 1 );
223+
f1.setAttribute( QStringLiteral( "col1" ), 0.0 );
224+
QgsPolylineXY line3111;
225+
line3111 << QgsPointXY( 2484588, 2425722 ) << QgsPointXY( 2482767, 2398853 );
226+
QgsGeometry line3111G = QgsGeometry::fromWkt( QStringLiteral( "LineStringZM( 2484588 2425722 11 31, 2484588 2398853 15 37)" ) ) ;
227+
f1.setGeometry( line3111G );
228+
tempLayer->dataProvider()->addFeatures( QgsFeatureList() << f1 );
229+
230+
// set project CRS and ellipsoid
231+
QgsCoordinateReferenceSystem srs( 3111, QgsCoordinateReferenceSystem::EpsgCrsId );
232+
canvas->setDestinationCrs( srs );
233+
canvas->setExtent( f1.geometry().boundingBox() );
234+
QgsProject::instance()->setCrs( srs );
235+
QgsProject::instance()->setEllipsoid( QStringLiteral( "WGS84" ) );
236+
QgsProject::instance()->setDistanceUnits( QgsUnitTypes::DistanceMeters );
237+
238+
QgsPointXY mapPoint = canvas->getCoordinateTransform()->transform( 2484587, 2399800 );
239+
240+
std::unique_ptr< QgsMapToolIdentifyAction > action( new QgsMapToolIdentifyAction( canvas ) );
241+
242+
//check that closest point attributes are present
243+
QList<QgsMapToolIdentify::IdentifyResult> result = action->identify( mapPoint.x(), mapPoint.y(), QList<QgsMapLayer *>() << tempLayer.get() );
244+
QCOMPARE( result.length(), 1 );
245+
QCOMPARE( result.at( 0 ).mDerivedAttributes[tr( "Closest X" )], QStringLiteral( "2484588" ) );
246+
QCOMPARE( result.at( 0 ).mDerivedAttributes[tr( "Closest Y" )], QStringLiteral( "2399800" ) );
247+
QCOMPARE( result.at( 0 ).mDerivedAttributes[tr( "Interpolated M" )].left( 4 ), QStringLiteral( "36.7" ) );
248+
QCOMPARE( result.at( 0 ).mDerivedAttributes[tr( "Interpolated Z" )].left( 4 ), QStringLiteral( "14.8" ) );
249+
250+
// polygons
251+
//create a temporary layer
252+
std::unique_ptr< QgsVectorLayer> tempLayer2( new QgsVectorLayer( QStringLiteral( "PolygonZM?crs=epsg:3111&field=pk:int&field=col1:double" ), QStringLiteral( "vl" ), QStringLiteral( "memory" ) ) );
253+
QVERIFY( tempLayer2->isValid() );
254+
f1 = QgsFeature( tempLayer2->dataProvider()->fields(), 1 );
255+
f1.setAttribute( QStringLiteral( "pk" ), 1 );
256+
f1.setAttribute( QStringLiteral( "col1" ), 0.0 );
257+
258+
f1.setGeometry( QgsGeometry::fromWkt( QStringLiteral( "PolygonZM((2484588 2425722 1 11, 2484588 2398853 2 12, 2520109 2397715 3 13, 2520792 2425494 4 14, 2484588 2425722 1 11))" ) ) );
259+
QVERIFY( f1.hasGeometry() );
260+
tempLayer2->dataProvider()->addFeatures( QgsFeatureList() << f1 );
261+
262+
mapPoint = canvas->getCoordinateTransform()->transform( 2484589, 2399800 );
263+
result = action->identify( mapPoint.x(), mapPoint.y(), QList<QgsMapLayer *>() << tempLayer2.get() );
264+
QCOMPARE( result.length(), 1 );
265+
QCOMPARE( result.at( 0 ).mDerivedAttributes[tr( "Closest X" )], QStringLiteral( "2484588" ) );
266+
QCOMPARE( result.at( 0 ).mDerivedAttributes[tr( "Closest Y" )], QStringLiteral( "2399800" ) );
267+
QCOMPARE( result.at( 0 ).mDerivedAttributes[tr( "Interpolated M" )].left( 4 ), QStringLiteral( "11.9" ) );
268+
QCOMPARE( result.at( 0 ).mDerivedAttributes[tr( "Interpolated Z" )].left( 4 ), QStringLiteral( "1.96" ) );
269+
}
270+
212271
void TestQgsMapToolIdentifyAction::lengthCalculation()
213272
{
214273
QgsSettings s;

0 commit comments

Comments
 (0)
Please sign in to comment.