Skip to content

Commit 407a5cb

Browse files
committed
[FEATURE] Identification map tool for 3D views
Currently identification only works on terrain and does not highlight in 3D
1 parent 7c905eb commit 407a5cb

12 files changed

+193
-3
lines changed

src/app/3d/qgs3dmapcanvas.cpp

+11
Original file line numberDiff line numberDiff line change
@@ -112,18 +112,29 @@ void Qgs3DMapCanvas::saveAsImage( const QString fileName, const QString fileForm
112112

113113
void Qgs3DMapCanvas::setMapTool( Qgs3DMapTool *tool )
114114
{
115+
if ( tool == mMapTool )
116+
return;
117+
115118
if ( mMapTool && !tool )
116119
{
117120
mEngine->window()->removeEventFilter( this );
118121
mScene->cameraController()->setEnabled( true );
122+
mEngine->window()->setCursor( Qt::OpenHandCursor );
119123
}
120124
else if ( !mMapTool && tool )
121125
{
122126
mEngine->window()->installEventFilter( this );
123127
mScene->cameraController()->setEnabled( false );
128+
mEngine->window()->setCursor( Qt::CrossCursor );
124129
}
125130

131+
if ( mMapTool )
132+
mMapTool->deactivate();
133+
126134
mMapTool = tool;
135+
136+
if ( mMapTool )
137+
mMapTool->activate();
127138
}
128139

129140
bool Qgs3DMapCanvas::eventFilter( QObject *watched, QEvent *event )

src/app/3d/qgs3dmapcanvasdockwidget.cpp

+16
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
#include "qgs3danimationsettings.h"
2626
#include "qgs3danimationwidget.h"
2727
#include "qgs3dmapsettings.h"
28+
#include "qgs3dmaptoolidentify.h"
2829
#include "qgs3dutils.h"
2930

3031
#include <QBoxLayout>
@@ -53,6 +54,10 @@ Qgs3DMapCanvasDockWidget::Qgs3DMapCanvasDockWidget( QWidget *parent )
5354
tr( "Animations" ), this, &Qgs3DMapCanvasDockWidget::toggleAnimations );
5455
actionAnim->setCheckable( true );
5556

57+
QAction *actionIdentify = toolBar->addAction( QIcon( QgsApplication::iconPath( "mActionIdentify.svg" ) ),
58+
tr( "Identify" ), this, &Qgs3DMapCanvasDockWidget::identify );
59+
actionIdentify->setCheckable( true );
60+
5661
mCanvas = new Qgs3DMapCanvas( contentsWidget );
5762
mCanvas->setMinimumSize( QSize( 200, 200 ) );
5863
mCanvas->setSizePolicy( QSizePolicy::Expanding, QSizePolicy::Expanding );
@@ -62,6 +67,8 @@ Qgs3DMapCanvasDockWidget::Qgs3DMapCanvasDockWidget( QWidget *parent )
6267
QgisApp::instance()->messageBar()->pushSuccess( tr( "Save as Image" ), tr( "Successfully saved the 3D map to <a href=\"%1\">%2</a>" ).arg( QUrl::fromLocalFile( fileName ).toString(), QDir::toNativeSeparators( fileName ) ) );
6368
} );
6469

70+
mMapToolIdentify = new Qgs3DMapToolIdentify( mCanvas );
71+
6572
mLabelPendingJobs = new QLabel( this );
6673
mProgressPendingJobs = new QProgressBar( this );
6774
mProgressPendingJobs->setRange( 0, 0 );
@@ -117,6 +124,15 @@ void Qgs3DMapCanvasDockWidget::toggleAnimations()
117124
}
118125
}
119126

127+
void Qgs3DMapCanvasDockWidget::identify()
128+
{
129+
QAction *action = qobject_cast<QAction *>( sender() );
130+
if ( !action )
131+
return;
132+
133+
mCanvas->setMapTool( action->isChecked() ? mMapToolIdentify : nullptr );
134+
}
135+
120136
void Qgs3DMapCanvasDockWidget::setMapSettings( Qgs3DMapSettings *map )
121137
{
122138
mCanvas->setMap( map );

src/app/3d/qgs3dmapcanvasdockwidget.h

+3
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ class QProgressBar;
2424
class Qgs3DAnimationWidget;
2525
class Qgs3DMapCanvas;
2626
class Qgs3DMapSettings;
27+
class Qgs3DMapToolIdentify;
2728
class QgsMapCanvas;
2829

2930

@@ -46,6 +47,7 @@ class Qgs3DMapCanvasDockWidget : public QgsDockWidget
4647
void configure();
4748
void saveAsImage();
4849
void toggleAnimations();
50+
void identify();
4951

5052
void onMainCanvasLayersChanged();
5153
void onMainCanvasColorChanged();
@@ -57,6 +59,7 @@ class Qgs3DMapCanvasDockWidget : public QgsDockWidget
5759
QgsMapCanvas *mMainCanvas = nullptr;
5860
QProgressBar *mProgressPendingJobs = nullptr;
5961
QLabel *mLabelPendingJobs = nullptr;
62+
Qgs3DMapToolIdentify *mMapToolIdentify = nullptr;
6063
};
6164

6265
#endif // QGS3DMAPCANVASDOCKWIDGET_H

src/app/3d/qgs3dmaptool.cpp

+12-1
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,11 @@
1515

1616
#include "qgs3dmaptool.h"
1717

18+
#include "qgs3dmapcanvas.h"
19+
1820
Qgs3DMapTool::Qgs3DMapTool( Qgs3DMapCanvas *canvas )
19-
: mCanvas( canvas )
21+
: QObject( canvas )
22+
, mCanvas( canvas )
2023
{
2124
}
2225

@@ -34,3 +37,11 @@ void Qgs3DMapTool::mouseMoveEvent( QMouseEvent *event )
3437
{
3538
Q_UNUSED( event );
3639
}
40+
41+
void Qgs3DMapTool::activate()
42+
{
43+
}
44+
45+
void Qgs3DMapTool::deactivate()
46+
{
47+
}

src/app/3d/qgs3dmaptool.h

+6
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,12 @@ class Qgs3DMapTool : public QObject
3535
virtual void mouseReleaseEvent( QMouseEvent *event );
3636
virtual void mouseMoveEvent( QMouseEvent *event );
3737

38+
//! Called when set as currently active map tool
39+
virtual void activate();
40+
41+
//! Called when map tool is being deactivated
42+
virtual void deactivate();
43+
3844
protected:
3945
Qgs3DMapCanvas *mCanvas = nullptr;
4046
};

src/app/3d/qgs3dmaptoolidentify.cpp

+72
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
/***************************************************************************
2+
qgs3dmaptoolidentify.cpp
3+
--------------------------------------
4+
Date : Sep 2018
5+
Copyright : (C) 2018 by Martin Dobias
6+
Email : wonder dot sk at gmail dot com
7+
***************************************************************************
8+
* *
9+
* This program is free software; you can redistribute it and/or modify *
10+
* it under the terms of the GNU General Public License as published by *
11+
* the Free Software Foundation; either version 2 of the License, or *
12+
* (at your option) any later version. *
13+
* *
14+
***************************************************************************/
15+
16+
#include "qgs3dmaptoolidentify.h"
17+
18+
#include "qgs3dmapcanvas.h"
19+
#include "qgs3dmapscene.h"
20+
#include "qgs3dutils.h"
21+
#include "qgsterrainentity_p.h"
22+
23+
#include "qgisapp.h"
24+
#include "qgsmaptoolidentifyaction.h"
25+
26+
#include <Qt3DRender/QObjectPicker>
27+
#include <Qt3DRender/QPickEvent>
28+
29+
Qgs3DMapToolIdentify::Qgs3DMapToolIdentify( Qgs3DMapCanvas *canvas )
30+
: Qgs3DMapTool( canvas )
31+
{
32+
connect( mCanvas->scene(), &Qgs3DMapScene::terrainEntityChanged, this, &Qgs3DMapToolIdentify::onTerrainEntityChanged );
33+
}
34+
35+
void Qgs3DMapToolIdentify::mousePressEvent( QMouseEvent *event )
36+
{
37+
Q_UNUSED( event );
38+
39+
QgsMapToolIdentifyAction *identifyTool2D = QgisApp::instance()->identifyMapTool();
40+
identifyTool2D->clearResults();
41+
}
42+
43+
void Qgs3DMapToolIdentify::activate()
44+
{
45+
Qt3DRender::QObjectPicker *picker = mCanvas->scene()->terrainEntity()->terrainPicker();
46+
connect( picker, &Qt3DRender::QObjectPicker::pressed, this, &Qgs3DMapToolIdentify::onTerrainPicked );
47+
}
48+
49+
void Qgs3DMapToolIdentify::deactivate()
50+
{
51+
Qt3DRender::QObjectPicker *picker = mCanvas->scene()->terrainEntity()->terrainPicker();
52+
disconnect( picker, &Qt3DRender::QObjectPicker::pressed, this, &Qgs3DMapToolIdentify::onTerrainPicked );
53+
}
54+
55+
void Qgs3DMapToolIdentify::onTerrainPicked( Qt3DRender::QPickEvent *event )
56+
{
57+
QgsVector3D mapCoords = Qgs3DUtils::worldToMapCoordinates( event->worldIntersection(), mCanvas->map()->origin() );
58+
59+
QgsGeometry geom = QgsGeometry::fromPointXY( QgsPointXY( mapCoords.x(), mapCoords.y() ) );
60+
61+
QgsMapToolIdentifyAction *identifyTool2D = QgisApp::instance()->identifyMapTool();
62+
63+
identifyTool2D->identifyAndShowResults( geom );
64+
}
65+
66+
void Qgs3DMapToolIdentify::onTerrainEntityChanged()
67+
{
68+
// no need to disconnect from the previous entity: it has been destroyed
69+
// start listening to the new terrain entity
70+
Qt3DRender::QObjectPicker *picker = mCanvas->scene()->terrainEntity()->terrainPicker();
71+
connect( picker, &Qt3DRender::QObjectPicker::pressed, this, &Qgs3DMapToolIdentify::onTerrainPicked );
72+
}

src/app/3d/qgs3dmaptoolidentify.h

+51
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
/***************************************************************************
2+
qgs3dmaptoolidentify.h
3+
--------------------------------------
4+
Date : Sep 2018
5+
Copyright : (C) 2018 by Martin Dobias
6+
Email : wonder dot sk at gmail dot com
7+
***************************************************************************
8+
* *
9+
* This program is free software; you can redistribute it and/or modify *
10+
* it under the terms of the GNU General Public License as published by *
11+
* the Free Software Foundation; either version 2 of the License, or *
12+
* (at your option) any later version. *
13+
* *
14+
***************************************************************************/
15+
16+
#ifndef QGS3DMAPTOOLIDENTIFY_H
17+
#define QGS3DMAPTOOLIDENTIFY_H
18+
19+
#include "qgs3dmaptool.h"
20+
21+
namespace Qt3DRender
22+
{
23+
class QPickEvent;
24+
}
25+
26+
//class QgsMapToolIdentifyAction;
27+
28+
29+
class Qgs3DMapToolIdentify : public Qgs3DMapTool
30+
{
31+
Q_OBJECT
32+
33+
public:
34+
Qgs3DMapToolIdentify( Qgs3DMapCanvas *canvas );
35+
36+
void mousePressEvent( QMouseEvent *event ) override;
37+
void mouseReleaseEvent( QMouseEvent *event ) override { Q_UNUSED( event );}
38+
void mouseMoveEvent( QMouseEvent *event ) override {Q_UNUSED( event );}
39+
40+
void activate() override;
41+
void deactivate() override;
42+
43+
private slots:
44+
void onTerrainPicked( Qt3DRender::QPickEvent *event );
45+
void onTerrainEntityChanged();
46+
47+
private:
48+
//QgsMapToolIdentifyAction *mIdentifyTool2D = nullptr;
49+
};
50+
51+
#endif // QGS3DMAPTOOLIDENTIFY_H

src/app/CMakeLists.txt

+2
Original file line numberDiff line numberDiff line change
@@ -446,6 +446,7 @@ IF (WITH_3D)
446446
3d/qgs3dmapcanvasdockwidget.cpp
447447
3d/qgs3dmapconfigwidget.cpp
448448
3d/qgs3dmaptool.cpp
449+
3d/qgs3dmaptoolidentify.cpp
449450
3d/qgsline3dsymbolwidget.cpp
450451
3d/qgspoint3dsymbolwidget.cpp
451452
3d/qgspolygon3dsymbolwidget.cpp
@@ -461,6 +462,7 @@ IF (WITH_3D)
461462
3d/qgs3dmapcanvasdockwidget.h
462463
3d/qgs3dmapconfigwidget.h
463464
3d/qgs3dmaptool.h
465+
3d/qgs3dmaptoolidentify.h
464466
3d/qgsline3dsymbolwidget.h
465467
3d/qgspoint3dsymbolwidget.h
466468
3d/qgspolygon3dsymbolwidget.h

src/app/qgisapp.h

+3
Original file line numberDiff line numberDiff line change
@@ -695,6 +695,9 @@ class APP_EXPORT QgisApp : public QMainWindow, private Ui::MainWindow
695695
//! Zoom to a bookmark
696696
void zoomToBookmarkIndex( const QModelIndex & );
697697

698+
//! Returns pointer to the identify map tool - used by identify tool in 3D view
699+
QgsMapToolIdentifyAction *identifyMapTool() const { return mMapTools.mIdentify; }
700+
698701
public slots:
699702
//! save current vector layer
700703
void saveAsFile( QgsMapLayer *layer = nullptr, bool onlySelected = false );

src/app/qgsmaptoolidentifyaction.cpp

+10
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,16 @@ void QgsMapToolIdentifyAction::deactivate()
212212
QgsMapToolIdentify::deactivate();
213213
}
214214

215+
void QgsMapToolIdentifyAction::identifyAndShowResults( const QgsGeometry &geom )
216+
{
217+
mSelectionHandler->setSelectedGeometry( geom );
218+
}
219+
220+
void QgsMapToolIdentifyAction::clearResults()
221+
{
222+
resultsDialog()->clear();
223+
}
224+
215225
QgsUnitTypes::DistanceUnit QgsMapToolIdentifyAction::displayDistanceUnits() const
216226
{
217227
return QgsProject::instance()->distanceUnits();

src/app/qgsmaptoolidentifyaction.h

+5
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,11 @@ class APP_EXPORT QgsMapToolIdentifyAction : public QgsMapToolIdentify
6161

6262
void deactivate() override;
6363

64+
//! Triggers map identification of at the given location and outputs results in GUI
65+
void identifyAndShowResults( const QgsGeometry &geom );
66+
//! Clears any previous results from the GUI
67+
void clearResults();
68+
6469
public slots:
6570
void handleCopyToClipboard( QgsFeatureStore & );
6671
void handleChangedRasterResults( QList<QgsMapToolIdentify::IdentifyResult> &results );

src/app/qgsmaptoolselectionhandler.h

+2-2
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,8 @@ class QgsMapToolSelectionHandler : public QObject
124124
//! Handles escape press event - returns true if the even has been processed
125125
bool keyReleaseEvent( QKeyEvent *e );
126126

127+
void setSelectedGeometry( const QgsGeometry &geometry, Qt::KeyboardModifiers modifiers = Qt::NoModifier );
128+
127129
signals:
128130
//! emitted when a new geometry has been picked (selectedGeometry())
129131
void geometryChanged( Qt::KeyboardModifiers modifiers = Qt::NoModifier );
@@ -165,8 +167,6 @@ class QgsMapToolSelectionHandler : public QObject
165167

166168
void updateRadiusFromEdge( QgsPointXY &radiusEdge );
167169

168-
void setSelectedGeometry( const QgsGeometry &geometry, Qt::KeyboardModifiers modifiers = Qt::NoModifier );
169-
170170
private:
171171

172172
QgsMapCanvas *mCanvas = nullptr;

0 commit comments

Comments
 (0)