Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Resurrect display of interpolated z/m in identify results #7607

Merged
merged 4 commits into from
Aug 14, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/core/geometry/qgscircle.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -249,8 +249,8 @@ int QgsCircle::intersections( const QgsCircle &other, QgsPoint &intersection1, Q
if ( res == 0 )
return 0;

intersection1 = QgsPoint( int1.x(), int1.y() );
intersection2 = QgsPoint( int2.x(), int2.y() );
intersection1 = QgsPoint( int1 );
intersection2 = QgsPoint( int2 );
if ( useZ && mCenter.is3D() )
{
intersection1.addZValue( mCenter.z() );
Expand Down
4 changes: 2 additions & 2 deletions src/core/geometry/qgsgeometry.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -589,7 +589,7 @@ QgsPoint QgsGeometry::vertexAt( int atVertex ) const
double QgsGeometry::sqrDistToVertexAt( QgsPointXY &point, int atVertex ) const
{
QgsPointXY vertexPoint = vertexAt( atVertex );
return QgsGeometryUtils::sqrDistance2D( QgsPoint( vertexPoint.x(), vertexPoint.y() ), QgsPoint( point.x(), point.y() ) );
return QgsGeometryUtils::sqrDistance2D( QgsPoint( vertexPoint ), QgsPoint( point ) );
}

QgsGeometry QgsGeometry::nearestPoint( const QgsGeometry &other ) const
Expand Down Expand Up @@ -640,7 +640,7 @@ double QgsGeometry::closestSegmentWithContext( const QgsPointXY &point,
QgsPoint segmentPt;
QgsVertexId vertexAfter;

double sqrDist = d->geometry->closestSegment( QgsPoint( point.x(), point.y() ), segmentPt, vertexAfter, leftOf, epsilon );
double sqrDist = d->geometry->closestSegment( QgsPoint( point ), segmentPt, vertexAfter, leftOf, epsilon );
if ( sqrDist < 0 )
return -1;

Expand Down
2 changes: 1 addition & 1 deletion src/gui/qgsmaptool.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ QgsPointXY QgsMapTool::toMapCoordinates( QPoint point )
QgsPoint QgsMapTool::toMapCoordinates( const QgsMapLayer *layer, const QgsPoint &point )
{
QgsPointXY result = mCanvas->mapSettings().layerToMapCoordinates( layer, QgsPointXY( point.x(), point.y() ) );
return QgsPoint( result.x(), result.y() );
return QgsPoint( result );
}


Expand Down
47 changes: 34 additions & 13 deletions src/gui/qgsmaptoolidentify.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -224,7 +224,7 @@ bool QgsMapToolIdentify::identifyVectorLayer( QList<QgsMapToolIdentify::Identify

if ( !layer->isInScaleRange( mCanvas->mapSettings().scale() ) )
{
QgsDebugMsg( "Out of scale limits" );
QgsDebugMsg( QStringLiteral( "Out of scale limits" ) );
return false;
}

Expand Down Expand Up @@ -347,18 +347,18 @@ void QgsMapToolIdentify::closestVertexAttributes( const QgsAbstractGeometry &geo
QgsPoint closestPoint = geometry.vertexAt( vId );

QgsPointXY closestPointMapCoords = mCanvas->mapSettings().layerToMapCoordinates( layer, QgsPointXY( closestPoint.x(), closestPoint.y() ) );
derivedAttributes.insert( QStringLiteral( "Closest vertex X" ), formatXCoordinate( closestPointMapCoords ) );
derivedAttributes.insert( QStringLiteral( "Closest vertex Y" ), formatYCoordinate( closestPointMapCoords ) );
derivedAttributes.insert( tr( "Closest vertex X" ), formatXCoordinate( closestPointMapCoords ) );
derivedAttributes.insert( tr( "Closest vertex Y" ), formatYCoordinate( closestPointMapCoords ) );

if ( closestPoint.is3D() )
{
str = QLocale().toString( closestPoint.z(), 'g', 10 );
derivedAttributes.insert( QStringLiteral( "Closest vertex Z" ), str );
derivedAttributes.insert( tr( "Closest vertex Z" ), str );
}
if ( closestPoint.isMeasure() )
{
str = QLocale().toString( closestPoint.m(), 'g', 10 );
derivedAttributes.insert( QStringLiteral( "Closest vertex M" ), str );
derivedAttributes.insert( tr( "Closest vertex M" ), str );
}

if ( vId.type == QgsVertexId::CurveVertex )
Expand All @@ -374,6 +374,25 @@ void QgsMapToolIdentify::closestVertexAttributes( const QgsAbstractGeometry &geo
}
}

void QgsMapToolIdentify::closestPointAttributes( const QgsAbstractGeometry &geometry, const QgsPointXY &layerPoint, QMap<QString, QString> &derivedAttributes )
{
QgsPoint closestPoint = QgsGeometryUtils::closestPoint( geometry, QgsPoint( layerPoint ) );

derivedAttributes.insert( tr( "Closest X" ), formatXCoordinate( closestPoint ) );
derivedAttributes.insert( tr( "Closest Y" ), formatYCoordinate( closestPoint ) );

if ( closestPoint.is3D() )
{
const QString str = QLocale().toString( closestPoint.z(), 'g', 10 );
derivedAttributes.insert( tr( "Interpolated Z" ), str );
}
if ( closestPoint.isMeasure() )
{
const QString str = QLocale().toString( closestPoint.m(), 'g', 10 );
derivedAttributes.insert( tr( "Interpolated M" ), str );
}
}

QString QgsMapToolIdentify::formatCoordinate( const QgsPointXY &canvasPoint ) const
{
return QgsCoordinateUtils::formatCoordinateForProject( QgsProject::instance(), canvasPoint, mCanvas->mapSettings().destinationCrs(),
Expand Down Expand Up @@ -414,7 +433,7 @@ QMap< QString, QString > QgsMapToolIdentify::featureDerivedAttributes( const Qgs
geometryType = feature.geometry().type();
wkbType = feature.geometry().wkbType();
//find closest vertex to clicked point
closestPoint = QgsGeometryUtils::closestVertex( *feature.geometry().constGet(), QgsPoint( layerPoint.x(), layerPoint.y() ), vId );
closestPoint = QgsGeometryUtils::closestVertex( *feature.geometry().constGet(), QgsPoint( layerPoint ), vId );
}

if ( QgsWkbTypes::isMultiType( wkbType ) )
Expand Down Expand Up @@ -451,6 +470,7 @@ QMap< QString, QString > QgsMapToolIdentify::featureDerivedAttributes( const Qgs
derivedAttributes.insert( tr( "Vertices" ), str );
//add details of closest vertex to identify point
closestVertexAttributes( *geom, vId, layer, derivedAttributes );
closestPointAttributes( *geom, layerPoint, derivedAttributes );

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

//add details of closest vertex to identify point
closestVertexAttributes( *feature.geometry().constGet(), vId, layer, derivedAttributes );
closestPointAttributes( *feature.geometry().constGet(), layerPoint, derivedAttributes );
}
else if ( geometryType == QgsWkbTypes::PointGeometry )
{
Expand All @@ -506,19 +527,19 @@ QMap< QString, QString > QgsMapToolIdentify::featureDerivedAttributes( const Qgs
// Include the x and y coordinates of the point as a derived attribute
QgsPointXY pnt = mCanvas->mapSettings().layerToMapCoordinates( layer, feature.geometry().asPoint() );
QString str = formatXCoordinate( pnt );
derivedAttributes.insert( QStringLiteral( "X" ), str );
derivedAttributes.insert( tr( "X" ), str );
str = formatYCoordinate( pnt );
derivedAttributes.insert( QStringLiteral( "Y" ), str );
derivedAttributes.insert( tr( "Y" ), str );

if ( QgsWkbTypes::hasZ( wkbType ) )
{
str = QLocale().toString( static_cast<const QgsPoint *>( feature.geometry().constGet() )->z(), 'g', 10 );
derivedAttributes.insert( QStringLiteral( "Z" ), str );
derivedAttributes.insert( tr( "Z" ), str );
}
if ( QgsWkbTypes::hasM( wkbType ) )
{
str = QLocale().toString( static_cast<const QgsPoint *>( feature.geometry().constGet() )->m(), 'g', 10 );
derivedAttributes.insert( QStringLiteral( "M" ), str );
derivedAttributes.insert( tr( "M" ), str );
}
}
else
Expand Down Expand Up @@ -620,8 +641,8 @@ bool QgsMapToolIdentify::identifyRasterLayer( QList<IdentifyResult> *results, Qg
// are similar to source width and height used to reproject layer for drawing.
// TODO: may be very dangerous, because it may result in different resolutions
// in source CRS, and WMS server (QGIS server) calcs wrong coor using average resolution.
int width = std::round( viewExtent.width() / mapUnitsPerPixel );
int height = std::round( viewExtent.height() / mapUnitsPerPixel );
int width = static_cast< int >( std::round( viewExtent.width() / mapUnitsPerPixel ) );
int height = static_cast< int >( std::round( viewExtent.height() / mapUnitsPerPixel ) );

QgsDebugMsg( QStringLiteral( "viewExtent.width = %1 viewExtent.height = %2" ).arg( viewExtent.width() ).arg( viewExtent.height() ) );
QgsDebugMsg( QStringLiteral( "width = %1 height = %2" ).arg( width ).arg( height ) );
Expand Down Expand Up @@ -695,7 +716,7 @@ bool QgsMapToolIdentify::identifyRasterLayer( QList<IdentifyResult> *results, Qg
for ( const QgsFeatureStore &featureStore : featureStoreList )
{
const QgsFeatureList storeFeatures = featureStore.features();
for ( QgsFeature feature : storeFeatures )
for ( const QgsFeature &feature : storeFeatures )
{
attributes.clear();
// WMS sublayer and feature type, a sublayer may contain multiple feature types.
Expand Down
5 changes: 5 additions & 0 deletions src/gui/qgsmaptoolidentify.h
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,11 @@ 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, 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;
Expand Down
59 changes: 59 additions & 0 deletions tests/src/app/testqgsmaptoolidentifyaction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ class TestQgsMapToolIdentifyAction : public QObject
void identifyRasterFloat64(); // test pixel identification and decimal precision
void identifyInvalidPolygons(); // test selecting invalid polygons
void clickxy(); // test if clicked_x and clicked_y variables are propagated
void closestPoint();

private:
void doAction();
Expand Down Expand Up @@ -209,6 +210,64 @@ void TestQgsMapToolIdentifyAction::clickxy()
mIdentifyAction->canvasReleaseEvent( &mapReleases );
}

void TestQgsMapToolIdentifyAction::closestPoint()
{
QgsSettings s;
s.setValue( QStringLiteral( "/qgis/measure/keepbaseunit" ), true );

//create a temporary layer
std::unique_ptr< QgsVectorLayer> tempLayer( new QgsVectorLayer( QStringLiteral( "LineStringZM?crs=epsg:3111&field=pk:int&field=col1:double" ), QStringLiteral( "vl" ), QStringLiteral( "memory" ) ) );
QVERIFY( tempLayer->isValid() );
QgsFeature f1( tempLayer->dataProvider()->fields(), 1 );
f1.setAttribute( QStringLiteral( "pk" ), 1 );
f1.setAttribute( QStringLiteral( "col1" ), 0.0 );
QgsPolylineXY line3111;
line3111 << QgsPointXY( 2484588, 2425722 ) << QgsPointXY( 2482767, 2398853 );
QgsGeometry line3111G = QgsGeometry::fromWkt( QStringLiteral( "LineStringZM( 2484588 2425722 11 31, 2484588 2398853 15 37)" ) ) ;
f1.setGeometry( line3111G );
tempLayer->dataProvider()->addFeatures( QgsFeatureList() << f1 );

// set project CRS and ellipsoid
QgsCoordinateReferenceSystem srs( 3111, QgsCoordinateReferenceSystem::EpsgCrsId );
canvas->setDestinationCrs( srs );
canvas->setExtent( f1.geometry().boundingBox() );
QgsProject::instance()->setCrs( srs );
QgsProject::instance()->setEllipsoid( QStringLiteral( "WGS84" ) );
QgsProject::instance()->setDistanceUnits( QgsUnitTypes::DistanceMeters );

QgsPointXY mapPoint = canvas->getCoordinateTransform()->transform( 2484587, 2399800 );

std::unique_ptr< QgsMapToolIdentifyAction > action( new QgsMapToolIdentifyAction( canvas ) );

//check that closest point attributes are present
QList<QgsMapToolIdentify::IdentifyResult> result = action->identify( mapPoint.x(), mapPoint.y(), QList<QgsMapLayer *>() << tempLayer.get() );
QCOMPARE( result.length(), 1 );
QCOMPARE( result.at( 0 ).mDerivedAttributes[tr( "Closest X" )], QStringLiteral( "2484588" ) );
QCOMPARE( result.at( 0 ).mDerivedAttributes[tr( "Closest Y" )], QStringLiteral( "2399800" ) );
QCOMPARE( result.at( 0 ).mDerivedAttributes[tr( "Interpolated M" )].left( 4 ), QStringLiteral( "36.7" ) );
QCOMPARE( result.at( 0 ).mDerivedAttributes[tr( "Interpolated Z" )].left( 4 ), QStringLiteral( "14.8" ) );

// polygons
//create a temporary layer
std::unique_ptr< QgsVectorLayer> tempLayer2( new QgsVectorLayer( QStringLiteral( "PolygonZM?crs=epsg:3111&field=pk:int&field=col1:double" ), QStringLiteral( "vl" ), QStringLiteral( "memory" ) ) );
QVERIFY( tempLayer2->isValid() );
f1 = QgsFeature( tempLayer2->dataProvider()->fields(), 1 );
f1.setAttribute( QStringLiteral( "pk" ), 1 );
f1.setAttribute( QStringLiteral( "col1" ), 0.0 );

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))" ) ) );
QVERIFY( f1.hasGeometry() );
tempLayer2->dataProvider()->addFeatures( QgsFeatureList() << f1 );

mapPoint = canvas->getCoordinateTransform()->transform( 2484589, 2399800 );
result = action->identify( mapPoint.x(), mapPoint.y(), QList<QgsMapLayer *>() << tempLayer2.get() );
QCOMPARE( result.length(), 1 );
QCOMPARE( result.at( 0 ).mDerivedAttributes[tr( "Closest X" )], QStringLiteral( "2484588" ) );
QCOMPARE( result.at( 0 ).mDerivedAttributes[tr( "Closest Y" )], QStringLiteral( "2399800" ) );
QCOMPARE( result.at( 0 ).mDerivedAttributes[tr( "Interpolated M" )].left( 4 ), QStringLiteral( "11.9" ) );
QCOMPARE( result.at( 0 ).mDerivedAttributes[tr( "Interpolated Z" )].left( 4 ), QStringLiteral( "1.96" ) );
}

void TestQgsMapToolIdentifyAction::lengthCalculation()
{
QgsSettings s;
Expand Down