Skip to content

Commit

Permalink
Save state of 3D map views in projects + restore them on project load
Browse files Browse the repository at this point in the history
  • Loading branch information
wonder-sk committed Oct 19, 2017
1 parent 2aaff6a commit 79bc5d4
Show file tree
Hide file tree
Showing 5 changed files with 137 additions and 17 deletions.
3 changes: 3 additions & 0 deletions src/app/3d/qgs3dmapcanvas.cpp
Expand Up @@ -49,6 +49,9 @@ void Qgs3DMapCanvas::resizeEvent( QResizeEvent *ev )
{
QWidget::resizeEvent( ev );

if ( !mScene )
return;

QRect viewportRect( QPoint( 0, 0 ), size() );
mScene->cameraController()->setViewport( viewportRect );
}
Expand Down
2 changes: 1 addition & 1 deletion src/app/3d/qgs3dmapcanvasdockwidget.cpp
Expand Up @@ -52,7 +52,7 @@ Qgs3DMapCanvasDockWidget::Qgs3DMapCanvasDockWidget( QWidget *parent )
setWidget( contentsWidget );
}

void Qgs3DMapCanvasDockWidget::setMap( Qgs3DMapSettings *map )
void Qgs3DMapCanvasDockWidget::setMapSettings( Qgs3DMapSettings *map )
{
mCanvas->setMap( map );
}
Expand Down
4 changes: 3 additions & 1 deletion src/app/3d/qgs3dmapcanvasdockwidget.h
Expand Up @@ -31,10 +31,12 @@ class Qgs3DMapCanvasDockWidget : public QgsDockWidget
Qgs3DMapCanvasDockWidget( QWidget *parent = nullptr );

//! takes ownership
void setMap( Qgs3DMapSettings *map );
void setMapSettings( Qgs3DMapSettings *map );

void setMainCanvas( QgsMapCanvas *canvas );

Qgs3DMapCanvas *mapCanvas3D() { return mCanvas; }

private slots:
void resetView();
void configure();
Expand Down
137 changes: 122 additions & 15 deletions src/app/qgisapp.cpp
Expand Up @@ -85,6 +85,7 @@
#include "qgsabstract3drenderer.h"
#include "qgs3dmapcanvasdockwidget.h"
#include "qgs3drendererregistry.h"
#include "qgs3dmapcanvas.h"
#include "qgs3dmapsettings.h"
#include "qgsflatterraingenerator.h"
#include "qgsvectorlayer3drenderer.h"
Expand Down Expand Up @@ -3358,6 +3359,17 @@ void QgisApp::closeAdditionalMapCanvases()
freezeCanvases( false );
}

void QgisApp::closeAdditional3DMapCanvases()
{
#ifdef HAVE_3D
for ( Qgs3DMapCanvasDockWidget *w : findChildren< Qgs3DMapCanvasDockWidget * >() )
{
w->close();
delete w;
}
#endif
}

void QgisApp::freezeCanvases( bool frozen )
{
Q_FOREACH ( QgsMapCanvas *canvas, mapCanvases() )
Expand Down Expand Up @@ -9957,26 +9969,68 @@ void QgisApp::new3DMapCanvas()
return;
}

Qgs3DMapSettings *map = new Qgs3DMapSettings;
map->setCrs( prj->crs() );
map->setOrigin( fullExtent.center().x(), fullExtent.center().y(), 0 );
map->setSelectionColor( mMapCanvas->selectionColor() );
map->setBackgroundColor( mMapCanvas->canvasColor() );
map->setLayers( mMapCanvas->layers() );
int i = 1;

bool existing = true;
const QList< Qgs3DMapCanvas * > existingCanvases = findChildren< Qgs3DMapCanvas * >();
QString name;
while ( existing )
{
name = tr( "3D Map %1" ).arg( i++ );
existing = false;
for ( Qgs3DMapCanvas *canvas : existingCanvases )
{
if ( canvas->objectName() == name )
{
existing = true;
break;
}
}
}

Qgs3DMapCanvasDockWidget *dock = createNew3DMapCanvasDock( name );
if ( dock )
{
setupDockWidget( dock, true );

Qgs3DMapSettings *map = new Qgs3DMapSettings;
map->setCrs( prj->crs() );
map->setOrigin( fullExtent.center().x(), fullExtent.center().y(), 0 );
map->setSelectionColor( mMapCanvas->selectionColor() );
map->setBackgroundColor( mMapCanvas->canvasColor() );
map->setLayers( mMapCanvas->layers() );

QgsFlatTerrainGenerator *flatTerrain = new QgsFlatTerrainGenerator;
flatTerrain->setCrs( map->crs() );
flatTerrain->setExtent( fullExtent );
map->setTerrainGenerator( flatTerrain );

dock->setMapSettings( map );
}
#endif
}

QgsFlatTerrainGenerator *flatTerrain = new QgsFlatTerrainGenerator;
flatTerrain->setCrs( map->crs() );
flatTerrain->setExtent( fullExtent );
map->setTerrainGenerator( flatTerrain );
Qgs3DMapCanvasDockWidget *QgisApp::createNew3DMapCanvasDock( const QString &name )
{
#ifdef HAVE_3D
const QList<Qgs3DMapCanvas *> mapCanvases = findChildren<Qgs3DMapCanvas *>();
for ( Qgs3DMapCanvas *canvas : mapCanvases )
{
if ( canvas->objectName() == name )
{
QgsDebugMsg( tr( "A map canvas with name '%1' already exists!" ).arg( name ) );
return nullptr;
}
}

// TODO: combine with code in createNewMapCanvasDock()
Qgs3DMapCanvasDockWidget *map3DWidget = new Qgs3DMapCanvasDockWidget( this );
map3DWidget->setWindowTitle( "3D Map" );
map3DWidget->setAllowedAreas( Qt::AllDockWidgetAreas );
map3DWidget->setGeometry( QRect( rect().width() * 0.75, rect().height() * 0.5, 400, 400 ) );
map3DWidget->setMap( map );
map3DWidget->setWindowTitle( name );
map3DWidget->mapCanvas3D()->setObjectName( name );
map3DWidget->setMainCanvas( mMapCanvas );
addDockWidget( Qt::BottomDockWidgetArea, map3DWidget );
return map3DWidget;
#else
Q_UNUSED( name );
#endif
}

Expand Down Expand Up @@ -10100,6 +10154,7 @@ void QgisApp::closeProject()
mActionFilterLegend->setChecked( false );

closeAdditionalMapCanvases();
closeAdditional3DMapCanvases();

deletePrintComposers();
removeAnnotationItems();
Expand Down Expand Up @@ -12007,6 +12062,22 @@ void QgisApp::writeProject( QDomDocument &doc )
}
qgisNode.appendChild( mapViewNode );

#ifdef HAVE_3D
QgsReadWriteContext readWriteContext;
readWriteContext.setPathResolver( QgsProject::instance()->pathResolver() );
QDomElement elem3DMaps = doc.createElement( QStringLiteral( "mapViewDocks3D" ) );
for ( Qgs3DMapCanvasDockWidget *w : findChildren<Qgs3DMapCanvasDockWidget *>() )
{
QDomElement elem3DMap = doc.createElement( QStringLiteral( "view" ) );
elem3DMap.setAttribute( QStringLiteral( "name" ), w->mapCanvas3D()->objectName() );
QDomElement elem3DMapSettings = w->mapCanvas3D()->map()->writeXml( doc, readWriteContext );
elem3DMap.appendChild( elem3DMapSettings );
writeDockWidgetSettings( w, elem3DMap );
elem3DMaps.appendChild( elem3DMap );
}
qgisNode.appendChild( elem3DMaps );
#endif

projectChanged( doc );
}

Expand Down Expand Up @@ -12076,6 +12147,42 @@ void QgisApp::readProject( const QDomDocument &doc )
views << mapCanvas;
}
}

#ifdef HAVE_3D
QgsReadWriteContext readWriteContext;
readWriteContext.setPathResolver( QgsProject::instance()->pathResolver() );
QDomElement elem3DMaps = doc.documentElement().firstChildElement( QStringLiteral( "mapViewDocks3D" ) );
if ( !elem3DMaps.isNull() )
{
QDomElement elem3DMap = elem3DMaps.firstChildElement( QStringLiteral( "view" ) );
while ( !elem3DMap.isNull() )
{
QString mapName = elem3DMap.attribute( QStringLiteral( "name" ) );

Qgs3DMapCanvasDockWidget *mapCanvasDock3D = createNew3DMapCanvasDock( mapName );
readDockWidgetSettings( mapCanvasDock3D, elem3DMap );

QDomElement elem3D = elem3DMap.firstChildElement( QStringLiteral( "qgis3d" ) );
Qgs3DMapSettings *map = new Qgs3DMapSettings;
map->readXml( elem3D, readWriteContext );
map->resolveReferences( *QgsProject::instance() );

// these things are not saved in project
map->setSelectionColor( mMapCanvas->selectionColor() );
map->setBackgroundColor( mMapCanvas->canvasColor() );
if ( map->terrainGenerator()->type() == QgsTerrainGenerator::Flat )
{
QgsFlatTerrainGenerator *flatTerrainGen = static_cast<QgsFlatTerrainGenerator *>( map->terrainGenerator() );
flatTerrainGen->setExtent( mMapCanvas->fullExtent() );
}

mapCanvasDock3D->setMapSettings( map );

elem3DMap = elem3DMap.nextSiblingElement( QStringLiteral( "view" ) );
}
}
#endif

// unfreeze all new views at once. We don't do this as they are created since additional
// views which may exist in project could rearrange the docks and cause the canvases to resize
// resulting in multiple redraws
Expand Down
8 changes: 8 additions & 0 deletions src/app/qgisapp.h
Expand Up @@ -99,6 +99,8 @@ class QgsStatusBar;

class QgsUserProfileManagerWidgetFactory;

class Qgs3DMapCanvasDockWidget;

class QDomDocument;
class QNetworkReply;
class QNetworkProxy;
Expand Down Expand Up @@ -1749,6 +1751,12 @@ class APP_EXPORT QgisApp : public QMainWindow, private Ui::MainWindow
void init3D();
void initNativeProcessing();

//! Creates a new 3D map dock without initializing its position or contents
Qgs3DMapCanvasDockWidget *createNew3DMapCanvasDock( const QString &name );

//! Closes any existing 3D map docks
void closeAdditional3DMapCanvases();

/**
* Refresh the user profile menu.
*/
Expand Down

0 comments on commit 79bc5d4

Please sign in to comment.