Skip to content

Commit

Permalink
[FEATURE] Identification map tool for 3D views
Browse files Browse the repository at this point in the history
Currently identification only works on terrain and does not highlight in 3D
  • Loading branch information
wonder-sk committed Sep 10, 2018
1 parent 7679863 commit c5d8843
Show file tree
Hide file tree
Showing 12 changed files with 193 additions and 3 deletions.
11 changes: 11 additions & 0 deletions src/app/3d/qgs3dmapcanvas.cpp
Expand Up @@ -112,18 +112,29 @@ void Qgs3DMapCanvas::saveAsImage( const QString fileName, const QString fileForm

void Qgs3DMapCanvas::setMapTool( Qgs3DMapTool *tool )
{
if ( tool == mMapTool )
return;

if ( mMapTool && !tool )
{
mEngine->window()->removeEventFilter( this );
mScene->cameraController()->setEnabled( true );
mEngine->window()->setCursor( Qt::OpenHandCursor );
}
else if ( !mMapTool && tool )
{
mEngine->window()->installEventFilter( this );
mScene->cameraController()->setEnabled( false );
mEngine->window()->setCursor( Qt::CrossCursor );
}

if ( mMapTool )
mMapTool->deactivate();

mMapTool = tool;

if ( mMapTool )
mMapTool->activate();
}

bool Qgs3DMapCanvas::eventFilter( QObject *watched, QEvent *event )
Expand Down
16 changes: 16 additions & 0 deletions src/app/3d/qgs3dmapcanvasdockwidget.cpp
Expand Up @@ -25,6 +25,7 @@
#include "qgs3danimationsettings.h"
#include "qgs3danimationwidget.h"
#include "qgs3dmapsettings.h"
#include "qgs3dmaptoolidentify.h"
#include "qgs3dutils.h"

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

QAction *actionIdentify = toolBar->addAction( QIcon( QgsApplication::iconPath( "mActionIdentify.svg" ) ),
tr( "Identify" ), this, &Qgs3DMapCanvasDockWidget::identify );
actionIdentify->setCheckable( true );

mCanvas = new Qgs3DMapCanvas( contentsWidget );
mCanvas->setMinimumSize( QSize( 200, 200 ) );
mCanvas->setSizePolicy( QSizePolicy::Expanding, QSizePolicy::Expanding );
Expand All @@ -62,6 +67,8 @@ Qgs3DMapCanvasDockWidget::Qgs3DMapCanvasDockWidget( QWidget *parent )
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 ) ) );
} );

mMapToolIdentify = new Qgs3DMapToolIdentify( mCanvas );

mLabelPendingJobs = new QLabel( this );
mProgressPendingJobs = new QProgressBar( this );
mProgressPendingJobs->setRange( 0, 0 );
Expand Down Expand Up @@ -117,6 +124,15 @@ void Qgs3DMapCanvasDockWidget::toggleAnimations()
}
}

void Qgs3DMapCanvasDockWidget::identify()
{
QAction *action = qobject_cast<QAction *>( sender() );
if ( !action )
return;

mCanvas->setMapTool( action->isChecked() ? mMapToolIdentify : nullptr );
}

void Qgs3DMapCanvasDockWidget::setMapSettings( Qgs3DMapSettings *map )
{
mCanvas->setMap( map );
Expand Down
3 changes: 3 additions & 0 deletions src/app/3d/qgs3dmapcanvasdockwidget.h
Expand Up @@ -24,6 +24,7 @@ class QProgressBar;
class Qgs3DAnimationWidget;
class Qgs3DMapCanvas;
class Qgs3DMapSettings;
class Qgs3DMapToolIdentify;
class QgsMapCanvas;


Expand All @@ -46,6 +47,7 @@ class Qgs3DMapCanvasDockWidget : public QgsDockWidget
void configure();
void saveAsImage();
void toggleAnimations();
void identify();

void onMainCanvasLayersChanged();
void onMainCanvasColorChanged();
Expand All @@ -57,6 +59,7 @@ class Qgs3DMapCanvasDockWidget : public QgsDockWidget
QgsMapCanvas *mMainCanvas = nullptr;
QProgressBar *mProgressPendingJobs = nullptr;
QLabel *mLabelPendingJobs = nullptr;
Qgs3DMapToolIdentify *mMapToolIdentify = nullptr;
};

#endif // QGS3DMAPCANVASDOCKWIDGET_H
13 changes: 12 additions & 1 deletion src/app/3d/qgs3dmaptool.cpp
Expand Up @@ -15,8 +15,11 @@

#include "qgs3dmaptool.h"

#include "qgs3dmapcanvas.h"

Qgs3DMapTool::Qgs3DMapTool( Qgs3DMapCanvas *canvas )
: mCanvas( canvas )
: QObject( canvas )
, mCanvas( canvas )
{
}

Expand All @@ -34,3 +37,11 @@ void Qgs3DMapTool::mouseMoveEvent( QMouseEvent *event )
{
Q_UNUSED( event );
}

void Qgs3DMapTool::activate()
{
}

void Qgs3DMapTool::deactivate()
{
}
6 changes: 6 additions & 0 deletions src/app/3d/qgs3dmaptool.h
Expand Up @@ -35,6 +35,12 @@ class Qgs3DMapTool : public QObject
virtual void mouseReleaseEvent( QMouseEvent *event );
virtual void mouseMoveEvent( QMouseEvent *event );

//! Called when set as currently active map tool
virtual void activate();

//! Called when map tool is being deactivated
virtual void deactivate();

protected:
Qgs3DMapCanvas *mCanvas = nullptr;
};
Expand Down
72 changes: 72 additions & 0 deletions src/app/3d/qgs3dmaptoolidentify.cpp
@@ -0,0 +1,72 @@
/***************************************************************************
qgs3dmaptoolidentify.cpp
--------------------------------------
Date : Sep 2018
Copyright : (C) 2018 by Martin Dobias
Email : wonder dot sk at gmail dot com
***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/

#include "qgs3dmaptoolidentify.h"

#include "qgs3dmapcanvas.h"
#include "qgs3dmapscene.h"
#include "qgs3dutils.h"
#include "qgsterrainentity_p.h"

#include "qgisapp.h"
#include "qgsmaptoolidentifyaction.h"

#include <Qt3DRender/QObjectPicker>
#include <Qt3DRender/QPickEvent>

Qgs3DMapToolIdentify::Qgs3DMapToolIdentify( Qgs3DMapCanvas *canvas )
: Qgs3DMapTool( canvas )
{
connect( mCanvas->scene(), &Qgs3DMapScene::terrainEntityChanged, this, &Qgs3DMapToolIdentify::onTerrainEntityChanged );
}

void Qgs3DMapToolIdentify::mousePressEvent( QMouseEvent *event )
{
Q_UNUSED( event );

QgsMapToolIdentifyAction *identifyTool2D = QgisApp::instance()->identifyMapTool();
identifyTool2D->clearResults();
}

void Qgs3DMapToolIdentify::activate()
{
Qt3DRender::QObjectPicker *picker = mCanvas->scene()->terrainEntity()->terrainPicker();
connect( picker, &Qt3DRender::QObjectPicker::pressed, this, &Qgs3DMapToolIdentify::onTerrainPicked );
}

void Qgs3DMapToolIdentify::deactivate()
{
Qt3DRender::QObjectPicker *picker = mCanvas->scene()->terrainEntity()->terrainPicker();
disconnect( picker, &Qt3DRender::QObjectPicker::pressed, this, &Qgs3DMapToolIdentify::onTerrainPicked );
}

void Qgs3DMapToolIdentify::onTerrainPicked( Qt3DRender::QPickEvent *event )
{
QgsVector3D mapCoords = Qgs3DUtils::worldToMapCoordinates( event->worldIntersection(), mCanvas->map()->origin() );

QgsGeometry geom = QgsGeometry::fromPointXY( QgsPointXY( mapCoords.x(), mapCoords.y() ) );

QgsMapToolIdentifyAction *identifyTool2D = QgisApp::instance()->identifyMapTool();

identifyTool2D->identifyAndShowResults( geom );
}

void Qgs3DMapToolIdentify::onTerrainEntityChanged()
{
// no need to disconnect from the previous entity: it has been destroyed
// start listening to the new terrain entity
Qt3DRender::QObjectPicker *picker = mCanvas->scene()->terrainEntity()->terrainPicker();
connect( picker, &Qt3DRender::QObjectPicker::pressed, this, &Qgs3DMapToolIdentify::onTerrainPicked );
}
51 changes: 51 additions & 0 deletions src/app/3d/qgs3dmaptoolidentify.h
@@ -0,0 +1,51 @@
/***************************************************************************
qgs3dmaptoolidentify.h
--------------------------------------
Date : Sep 2018
Copyright : (C) 2018 by Martin Dobias
Email : wonder dot sk at gmail dot com
***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/

#ifndef QGS3DMAPTOOLIDENTIFY_H
#define QGS3DMAPTOOLIDENTIFY_H

#include "qgs3dmaptool.h"

namespace Qt3DRender
{
class QPickEvent;
}

//class QgsMapToolIdentifyAction;


class Qgs3DMapToolIdentify : public Qgs3DMapTool
{
Q_OBJECT

public:
Qgs3DMapToolIdentify( Qgs3DMapCanvas *canvas );

void mousePressEvent( QMouseEvent *event ) override;
void mouseReleaseEvent( QMouseEvent *event ) override { Q_UNUSED( event );}
void mouseMoveEvent( QMouseEvent *event ) override {Q_UNUSED( event );}

void activate() override;
void deactivate() override;

private slots:
void onTerrainPicked( Qt3DRender::QPickEvent *event );
void onTerrainEntityChanged();

private:
//QgsMapToolIdentifyAction *mIdentifyTool2D = nullptr;
};

#endif // QGS3DMAPTOOLIDENTIFY_H
2 changes: 2 additions & 0 deletions src/app/CMakeLists.txt
Expand Up @@ -446,6 +446,7 @@ IF (WITH_3D)
3d/qgs3dmapcanvasdockwidget.cpp
3d/qgs3dmapconfigwidget.cpp
3d/qgs3dmaptool.cpp
3d/qgs3dmaptoolidentify.cpp
3d/qgsline3dsymbolwidget.cpp
3d/qgspoint3dsymbolwidget.cpp
3d/qgspolygon3dsymbolwidget.cpp
Expand All @@ -461,6 +462,7 @@ IF (WITH_3D)
3d/qgs3dmapcanvasdockwidget.h
3d/qgs3dmapconfigwidget.h
3d/qgs3dmaptool.h
3d/qgs3dmaptoolidentify.h
3d/qgsline3dsymbolwidget.h
3d/qgspoint3dsymbolwidget.h
3d/qgspolygon3dsymbolwidget.h
Expand Down
3 changes: 3 additions & 0 deletions src/app/qgisapp.h
Expand Up @@ -695,6 +695,9 @@ class APP_EXPORT QgisApp : public QMainWindow, private Ui::MainWindow
//! Zoom to a bookmark
void zoomToBookmarkIndex( const QModelIndex & );

//! Returns pointer to the identify map tool - used by identify tool in 3D view
QgsMapToolIdentifyAction *identifyMapTool() const { return mMapTools.mIdentify; }

public slots:
//! save current vector layer
void saveAsFile( QgsMapLayer *layer = nullptr, bool onlySelected = false );
Expand Down
10 changes: 10 additions & 0 deletions src/app/qgsmaptoolidentifyaction.cpp
Expand Up @@ -212,6 +212,16 @@ void QgsMapToolIdentifyAction::deactivate()
QgsMapToolIdentify::deactivate();
}

void QgsMapToolIdentifyAction::identifyAndShowResults( const QgsGeometry &geom )
{
mSelectionHandler->setSelectedGeometry( geom );
}

void QgsMapToolIdentifyAction::clearResults()
{
resultsDialog()->clear();
}

QgsUnitTypes::DistanceUnit QgsMapToolIdentifyAction::displayDistanceUnits() const
{
return QgsProject::instance()->distanceUnits();
Expand Down
5 changes: 5 additions & 0 deletions src/app/qgsmaptoolidentifyaction.h
Expand Up @@ -61,6 +61,11 @@ class APP_EXPORT QgsMapToolIdentifyAction : public QgsMapToolIdentify

void deactivate() override;

//! Triggers map identification of at the given location and outputs results in GUI
void identifyAndShowResults( const QgsGeometry &geom );
//! Clears any previous results from the GUI
void clearResults();

public slots:
void handleCopyToClipboard( QgsFeatureStore & );
void handleChangedRasterResults( QList<QgsMapToolIdentify::IdentifyResult> &results );
Expand Down
4 changes: 2 additions & 2 deletions src/app/qgsmaptoolselectionhandler.h
Expand Up @@ -124,6 +124,8 @@ class QgsMapToolSelectionHandler : public QObject
//! Handles escape press event - returns true if the even has been processed
bool keyReleaseEvent( QKeyEvent *e );

void setSelectedGeometry( const QgsGeometry &geometry, Qt::KeyboardModifiers modifiers = Qt::NoModifier );

signals:
//! emitted when a new geometry has been picked (selectedGeometry())
void geometryChanged( Qt::KeyboardModifiers modifiers = Qt::NoModifier );
Expand Down Expand Up @@ -165,8 +167,6 @@ class QgsMapToolSelectionHandler : public QObject

void updateRadiusFromEdge( QgsPointXY &radiusEdge );

void setSelectedGeometry( const QgsGeometry &geometry, Qt::KeyboardModifiers modifiers = Qt::NoModifier );

private:

QgsMapCanvas *mCanvas = nullptr;
Expand Down

0 comments on commit c5d8843

Please sign in to comment.