mirror of
https://github.com/qgis/QGIS.git
synced 2025-10-04 00:04:03 -04:00
Fix saving/loading 3D map view viewpoint
Previously the point was saved in origin-relative coordinates. Now since we pick the origin automatically, it can be changed by various initialisation routines, so the coordinates will be interpreted relative to the wrong origin. This commit changes the format to use map coordinates instead, and saves the "original" origin from the XML for interpreting older projects.
This commit is contained in:
parent
429500187c
commit
19ded7be74
@ -153,7 +153,7 @@ pointing towards north. The angle should range from 0 to 360.
|
||||
%Docstring
|
||||
Writes camera configuration to the given DOM element
|
||||
%End
|
||||
void readXml( const QDomElement &elem );
|
||||
void readXml( const QDomElement &elem, QgsVector3D savedOrigin );
|
||||
%Docstring
|
||||
Reads camera configuration from the given DOM element
|
||||
%End
|
||||
|
@ -153,7 +153,7 @@ pointing towards north. The angle should range from 0 to 360.
|
||||
%Docstring
|
||||
Writes camera configuration to the given DOM element
|
||||
%End
|
||||
void readXml( const QDomElement &elem );
|
||||
void readXml( const QDomElement &elem, QgsVector3D savedOrigin );
|
||||
%Docstring
|
||||
Reads camera configuration from the given DOM element
|
||||
%End
|
||||
|
@ -264,38 +264,41 @@ void QgsCameraController::setCameraPose( const QgsCameraPose &camPose, bool forc
|
||||
QDomElement QgsCameraController::writeXml( QDomDocument &doc ) const
|
||||
{
|
||||
QDomElement elemCamera = doc.createElement( QStringLiteral( "camera" ) );
|
||||
QgsVector3D centerPoint;
|
||||
switch ( mScene->mapSettings()->sceneMode() )
|
||||
{
|
||||
case Qgis::SceneMode::Local:
|
||||
centerPoint = mCameraPose.centerPoint();
|
||||
break;
|
||||
case Qgis::SceneMode::Globe:
|
||||
// Save center point in map coordinates, since our world origin won't be
|
||||
// the same on loading
|
||||
centerPoint = mCameraPose.centerPoint() + mOrigin;
|
||||
break;
|
||||
}
|
||||
elemCamera.setAttribute( QStringLiteral( "x" ), centerPoint.x() );
|
||||
elemCamera.setAttribute( QStringLiteral( "y" ), centerPoint.z() );
|
||||
elemCamera.setAttribute( QStringLiteral( "elev" ), centerPoint.y() );
|
||||
// Save center point in map coordinates, since our world origin won't be
|
||||
// the same on loading
|
||||
QgsVector3D centerPoint = mCameraPose.centerPoint() + mOrigin;
|
||||
elemCamera.setAttribute( QStringLiteral( "xMap" ), centerPoint.x() );
|
||||
elemCamera.setAttribute( QStringLiteral( "yMap" ), centerPoint.z() );
|
||||
elemCamera.setAttribute( QStringLiteral( "elevMap" ), centerPoint.y() );
|
||||
elemCamera.setAttribute( QStringLiteral( "dist" ), mCameraPose.distanceFromCenterPoint() );
|
||||
elemCamera.setAttribute( QStringLiteral( "pitch" ), mCameraPose.pitchAngle() );
|
||||
elemCamera.setAttribute( QStringLiteral( "yaw" ), mCameraPose.headingAngle() );
|
||||
return elemCamera;
|
||||
}
|
||||
|
||||
void QgsCameraController::readXml( const QDomElement &elem )
|
||||
void QgsCameraController::readXml( const QDomElement &elem, QgsVector3D savedOrigin )
|
||||
{
|
||||
const float x = elem.attribute( QStringLiteral( "x" ) ).toFloat();
|
||||
const float y = elem.attribute( QStringLiteral( "y" ) ).toFloat();
|
||||
const float elev = elem.attribute( QStringLiteral( "elev" ) ).toFloat();
|
||||
const float dist = elem.attribute( QStringLiteral( "dist" ) ).toFloat();
|
||||
const float pitch = elem.attribute( QStringLiteral( "pitch" ) ).toFloat();
|
||||
const float yaw = elem.attribute( QStringLiteral( "yaw" ) ).toFloat();
|
||||
QgsVector3D centerPoint( x, elev, y );
|
||||
if ( mScene->mapSettings()->sceneMode() == Qgis::SceneMode::Globe )
|
||||
centerPoint = centerPoint - mOrigin;
|
||||
|
||||
QgsVector3D centerPoint;
|
||||
if ( elem.hasAttribute( "xMap" ) )
|
||||
{
|
||||
// Prefer newer point saved in map coordinates ...
|
||||
const float x = elem.attribute( QStringLiteral( "xMap" ) ).toFloat();
|
||||
const float y = elem.attribute( QStringLiteral( "yMap" ) ).toFloat();
|
||||
const float elev = elem.attribute( QStringLiteral( "elevMap" ) ).toFloat();
|
||||
centerPoint = QgsVector3D( x, elev, y ) - mOrigin;
|
||||
}
|
||||
else
|
||||
{
|
||||
// ... but allow use of older origin-relative coordinates.
|
||||
const float x = elem.attribute( QStringLiteral( "x" ) ).toFloat();
|
||||
const float y = elem.attribute( QStringLiteral( "y" ) ).toFloat();
|
||||
const float elev = elem.attribute( QStringLiteral( "elev" ) ).toFloat();
|
||||
centerPoint = QgsVector3D( x, elev, y ) - savedOrigin + mOrigin;
|
||||
}
|
||||
setLookingAtPoint( centerPoint, dist, pitch, yaw );
|
||||
}
|
||||
|
||||
|
@ -174,7 +174,7 @@ class _3D_EXPORT QgsCameraController : public QObject
|
||||
//! Writes camera configuration to the given DOM element
|
||||
QDomElement writeXml( QDomDocument &doc ) const;
|
||||
//! Reads camera configuration from the given DOM element
|
||||
void readXml( const QDomElement &elem );
|
||||
void readXml( const QDomElement &elem, QgsVector3D savedOrigin );
|
||||
|
||||
//! Zoom the map by \a factor
|
||||
void zoom( float factor );
|
||||
|
@ -9145,7 +9145,10 @@ Qgs3DMapCanvasWidget *QgisApp::duplicate3DMapView( const QString &existingViewNa
|
||||
Qgs3DMapSettings *map = new Qgs3DMapSettings( *widget->mapCanvas3D()->mapSettings() );
|
||||
newCanvasWidget->setMapSettings( map );
|
||||
|
||||
newCanvasWidget->mapCanvas3D()->cameraController()->readXml( widget->mapCanvas3D()->cameraController()->writeXml( doc ) );
|
||||
newCanvasWidget->mapCanvas3D()->cameraController()->readXml(
|
||||
widget->mapCanvas3D()->cameraController()->writeXml( doc ),
|
||||
widget->mapCanvas3D()->mapSettings()->origin()
|
||||
);
|
||||
newCanvasWidget->animationWidget()->setAnimation( widget->animationWidget()->animation() );
|
||||
|
||||
connect( QgsProject::instance(), &QgsProject::transformContextChanged, map, [map] {
|
||||
@ -16237,12 +16240,14 @@ void QgisApp::read3DMapViewSettings( Qgs3DMapCanvasWidget *widget, QDomElement &
|
||||
map->setBackgroundColor( mMapCanvas->canvasColor() );
|
||||
map->setOutputDpi( QGuiApplication::primaryScreen()->logicalDotsPerInch() );
|
||||
|
||||
QgsVector3D savedOrigin = map->origin();
|
||||
|
||||
widget->setMapSettings( map );
|
||||
|
||||
QDomElement elemCamera = elem3DMap.firstChildElement( QStringLiteral( "camera" ) );
|
||||
if ( !elemCamera.isNull() )
|
||||
{
|
||||
widget->mapCanvas3D()->cameraController()->readXml( elemCamera );
|
||||
widget->mapCanvas3D()->cameraController()->readXml( elemCamera, savedOrigin );
|
||||
}
|
||||
// not nice hack to ensure camera navigation mode is correctly setup to previous mode
|
||||
widget->mapCanvas3D()->mapSettings()->emit cameraNavigationModeChanged();
|
||||
|
@ -139,12 +139,14 @@ void initCanvas3D( Qgs3DMapCanvas *canvas, bool isGlobe, QString viewIdxStr )
|
||||
map->setMapThemeCollection( QgsProject::instance()->mapThemeCollection() );
|
||||
map->setOutputDpi( QGuiApplication::primaryScreen()->logicalDotsPerInch() );
|
||||
|
||||
QgsVector3D savedOrigin = map->origin();
|
||||
|
||||
canvas->setMapSettings( map );
|
||||
|
||||
QDomElement elemCamera = viewXml.firstChildElement( QStringLiteral( "camera" ) );
|
||||
if ( !elemCamera.isNull() )
|
||||
{
|
||||
canvas->cameraController()->readXml( elemCamera );
|
||||
canvas->cameraController()->readXml( elemCamera, savedOrigin );
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user