mirror of
https://github.com/qgis/QGIS.git
synced 2025-02-25 00:58:06 -05:00
[3d] missing piece of the jigsaw: save 3d canvas as image (#5927)
This commit is contained in:
parent
909a0fc21c
commit
1ddcac501c
@ -17,6 +17,7 @@
|
||||
|
||||
#include <QBoxLayout>
|
||||
#include <Qt3DExtras/Qt3DWindow>
|
||||
#include <Qt3DRender/QRenderCapture>
|
||||
|
||||
#include "qgscameracontroller.h"
|
||||
#include "qgs3dmapsettings.h"
|
||||
@ -27,6 +28,11 @@ Qgs3DMapCanvas::Qgs3DMapCanvas( QWidget *parent )
|
||||
: QWidget( parent )
|
||||
{
|
||||
mWindow3D = new Qt3DExtras::Qt3DWindow;
|
||||
|
||||
mCapture = new Qt3DRender::QRenderCapture;
|
||||
mWindow3D->activeFrameGraph()->setParent( mCapture );
|
||||
mWindow3D->setActiveFrameGraph( mCapture );
|
||||
|
||||
mContainer = QWidget::createWindowContainer( mWindow3D );
|
||||
|
||||
QHBoxLayout *hLayout = new QHBoxLayout( this );
|
||||
@ -89,3 +95,19 @@ void Qgs3DMapCanvas::setViewFromTop( const QgsPointXY ¢er, float distance, f
|
||||
float worldY = center.y() - mMap->origin().y();
|
||||
mScene->cameraController()->setViewFromTop( worldX, -worldY, distance, rotation );
|
||||
}
|
||||
|
||||
void Qgs3DMapCanvas::saveAsImage( const QString fileName, const QString fileFormat )
|
||||
{
|
||||
if ( !fileName.isEmpty() )
|
||||
{
|
||||
Qt3DRender::QRenderCaptureReply *captureReply;
|
||||
captureReply = mCapture->requestCapture();
|
||||
connect( captureReply, &Qt3DRender::QRenderCaptureReply::completed, this, [ = ]
|
||||
{
|
||||
captureReply->image().save( fileName, fileFormat.toLocal8Bit().data() );
|
||||
emit savedAsImage( fileName );
|
||||
|
||||
captureReply->deleteLater();
|
||||
} );
|
||||
}
|
||||
}
|
||||
|
@ -17,6 +17,7 @@
|
||||
#define QGS3DMAPCANVAS_H
|
||||
|
||||
#include <QWidget>
|
||||
#include <Qt3DRender/QRenderCapture>
|
||||
|
||||
namespace Qt3DExtras
|
||||
{
|
||||
@ -54,12 +55,22 @@ class Qgs3DMapCanvas : public QWidget
|
||||
//! Sets camera position to look down at the given point (in map coordinates) in given distance from plane with zero elevation
|
||||
void setViewFromTop( const QgsPointXY ¢er, float distance, float rotation = 0 );
|
||||
|
||||
//! Saves the current scene as an image
|
||||
void saveAsImage( const QString fileName, const QString fileFormat );
|
||||
|
||||
signals:
|
||||
//! Emitted when the 3D map canvas was successfully saved as image
|
||||
void savedAsImage( const QString fileName );
|
||||
|
||||
protected:
|
||||
void resizeEvent( QResizeEvent *ev ) override;
|
||||
|
||||
private:
|
||||
//! 3D window with all the 3D magic inside
|
||||
Qt3DExtras::Qt3DWindow *mWindow3D = nullptr;
|
||||
//! Frame graph node for render capture
|
||||
Qt3DRender::QRenderCapture *mCapture = nullptr;
|
||||
|
||||
//! Container QWidget that encapsulates mWindow3D so we can use it embedded in ordinary widgets app
|
||||
QWidget *mContainer = nullptr;
|
||||
//! Description of the 3D scene
|
||||
|
@ -30,6 +30,7 @@
|
||||
#include <QDialogButtonBox>
|
||||
#include <QProgressBar>
|
||||
#include <QToolBar>
|
||||
#include <QUrl>
|
||||
|
||||
Qgs3DMapCanvasDockWidget::Qgs3DMapCanvasDockWidget( QWidget *parent )
|
||||
: QgsDockWidget( parent )
|
||||
@ -42,6 +43,8 @@ Qgs3DMapCanvasDockWidget::Qgs3DMapCanvasDockWidget( QWidget *parent )
|
||||
toolBar->setIconSize( QgisApp::instance()->iconSize( true ) );
|
||||
toolBar->addAction( QgsApplication::getThemeIcon( QStringLiteral( "mActionZoomFullExtent.svg" ) ),
|
||||
tr( "Zoom Full" ), this, &Qgs3DMapCanvasDockWidget::resetView );
|
||||
toolBar->addAction( QgsApplication::getThemeIcon( QStringLiteral( "mActionSaveMapAsImage.svg" ) ),
|
||||
tr( "Save as image..." ), this, &Qgs3DMapCanvasDockWidget::saveAsImage );
|
||||
toolBar->addAction( QgsApplication::getThemeIcon( QStringLiteral( "mIconProperties.svg" ) ),
|
||||
tr( "Configure" ), this, &Qgs3DMapCanvasDockWidget::configure );
|
||||
|
||||
@ -49,6 +52,11 @@ Qgs3DMapCanvasDockWidget::Qgs3DMapCanvasDockWidget( QWidget *parent )
|
||||
mCanvas->setMinimumSize( QSize( 200, 200 ) );
|
||||
mCanvas->setSizePolicy( QSizePolicy::Expanding, QSizePolicy::Expanding );
|
||||
|
||||
connect( mCanvas, &Qgs3DMapCanvas::savedAsImage, this, [ = ]( const QString fileName )
|
||||
{
|
||||
QgisApp::instance()->messageBar()->pushSuccess( tr( "Save as Image" ), tr( "Successfully saved the 3D map to <a href=\"%1\">%2</a>" ).arg( QUrl::fromLocalFile( QFileInfo( fileName ).path() ).toString(), fileName ) );
|
||||
} );
|
||||
|
||||
mLabelPendingJobs = new QLabel( this );
|
||||
mProgressPendingJobs = new QProgressBar( this );
|
||||
mProgressPendingJobs->setRange( 0, 0 );
|
||||
@ -74,6 +82,15 @@ Qgs3DMapCanvasDockWidget::Qgs3DMapCanvasDockWidget( QWidget *parent )
|
||||
onTerrainPendingJobsCountChanged();
|
||||
}
|
||||
|
||||
void Qgs3DMapCanvasDockWidget::saveAsImage()
|
||||
{
|
||||
QPair< QString, QString> fileNameAndFilter = QgsGuiUtils::getSaveAsImageName( this, tr( "Choose a file name to save the 3D map canvas to an image" ) );
|
||||
if ( !fileNameAndFilter.first.isEmpty() )
|
||||
{
|
||||
mCanvas->saveAsImage( fileNameAndFilter.first, fileNameAndFilter.second );
|
||||
}
|
||||
}
|
||||
|
||||
void Qgs3DMapCanvasDockWidget::setMapSettings( Qgs3DMapSettings *map )
|
||||
{
|
||||
mCanvas->setMap( map );
|
||||
|
@ -42,6 +42,7 @@ class Qgs3DMapCanvasDockWidget : public QgsDockWidget
|
||||
private slots:
|
||||
void resetView();
|
||||
void configure();
|
||||
void saveAsImage();
|
||||
|
||||
void onMainCanvasLayersChanged();
|
||||
void onMainCanvasColorChanged();
|
||||
|
Loading…
x
Reference in New Issue
Block a user