QGIS API Documentation 4.1.0-Master (0cdd3ae6384)
Loading...
Searching...
No Matches
qgssunlightsettings.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgssunlightsettings.cpp
3 --------------------------------------
4 Date : April 2026
5 Copyright : (C) 2026 by Nyall Dawson
6 Email : nyall dot dawson 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 "qgssunlightsettings.h"
17
18#include "qgs3dmapsettings.h"
19#include "qgscolorutils.h"
21#include "qgssymbollayerutils.h"
22
23#include <QDomDocument>
24#include <QString>
25#include <Qt3DCore/QEntity>
26#include <Qt3DRender/QDirectionalLight>
27
28using namespace Qt::StringLiterals;
29
34
36{
37 auto res = std::make_unique< QgsSunLightSettings >( *this );
38 res->mId = mId;
39 return res.release();
40}
41
43{
44 QgsSunPositionResult sunResult;
45 try
46 {
47 sunResult = QgsSunPositionCalculator::calculate( map.extent().center(), map.crs(), map.transformContext(), mSunTime, mReferenceElevation, mAtmosphericPressure, mTemperature );
48 }
49 catch ( const QgsException & )
50 {
51 // fallback to straight down (noon) if CRS transformation or math fails
52 sunResult.azimuth = 0.0;
53 sunResult.apparentElevation = 90.0;
54 }
55
56 const float azimuthRad = M_PI * sunResult.azimuth / 180.0;
57 const float elevationRad = M_PI * sunResult.apparentElevation / 180.0;
58 // convert to vector in z-up world
59 const float x = std::cos( elevationRad ) * std::sin( azimuthRad );
60 const float y = std::cos( elevationRad ) * std::cos( azimuthRad );
61 const float z = std::sin( elevationRad );
62 const QVector3D sunVector( x, y, z );
63 return -sunVector.normalized();
64}
65
66Qt3DCore::QEntity *QgsSunLightSettings::createEntity( const Qgs3DMapSettings &map, Qt3DCore::QEntity *parent ) const
67{
68 Qt3DCore::QEntity *lightEntity = new Qt3DCore::QEntity( parent );
69
70 Qt3DRender::QDirectionalLight *light = new Qt3DRender::QDirectionalLight;
71 light->setColor( color() );
72 light->setIntensity( static_cast< float >( intensity() ) );
73 light->setWorldDirection( direction( map ).toVector3D() );
74
75 lightEntity->addComponent( light );
76
77 return lightEntity;
78}
79
80QDomElement QgsSunLightSettings::writeXml( QDomDocument &doc, const QgsReadWriteContext & ) const
81{
82 QDomElement elemLight = doc.createElement( u"sun-light"_s );
83 elemLight.setAttribute( u"id"_s, mId );
84 elemLight.setAttribute( u"color"_s, QgsColorUtils::colorToString( mColor ) );
85 elemLight.setAttribute( u"intensity"_s, mIntensity );
86 elemLight.setAttribute( u"sun-time"_s, mSunTime.toString( Qt::ISODate ) );
87 elemLight.setAttribute( u"reference-elevation"_s, mReferenceElevation );
88 elemLight.setAttribute( u"atmospheric-pressure"_s, mAtmosphericPressure );
89 elemLight.setAttribute( u"temperature"_s, mTemperature );
90
91 return elemLight;
92}
93
94void QgsSunLightSettings::readXml( const QDomElement &elem, const QgsReadWriteContext & )
95{
96 if ( elem.hasAttribute( u"id"_s ) )
97 mId = elem.attribute( u"id"_s );
98 mColor = QgsColorUtils::colorFromString( elem.attribute( u"color"_s ) );
99 mIntensity = elem.attribute( u"intensity"_s ).toDouble();
100 mSunTime = QDateTime::fromString( elem.attribute( u"sun-time"_s ), Qt::ISODate );
101 if ( !mSunTime.isValid() )
102 {
103 mSunTime = QDateTime::currentDateTimeUtc();
104 }
105 mReferenceElevation = elem.attribute( u"reference-elevation"_s, u"0.0"_s ).toDouble();
106 mAtmosphericPressure = elem.attribute( u"atmospheric-pressure"_s, u"1013.25"_s ).toDouble();
107 mTemperature = elem.attribute( u"temperature"_s, u"15.0"_s ).toDouble();
108}
109
111{
112 return mId == other.mId
113 && mSunTime == other.mSunTime
114 && mColor == other.mColor
115 && mIntensity == other.mIntensity
116 && qgsDoubleNear( mAtmosphericPressure, other.mAtmosphericPressure )
117 && qgsDoubleNear( mTemperature, other.mTemperature )
118 && qgsDoubleNear( mReferenceElevation, other.mReferenceElevation );
119}
LightSourceType
Light source types for 3D scenes.
Definition qgis.h:4437
@ Sun
Sun based light source.
Definition qgis.h:4440
Definition of the world.
QgsRectangle extent() const
Returns the 3D scene's 2D extent in the 3D scene's CRS.
QgsCoordinateReferenceSystem crs() const
Returns coordinate reference system used in the 3D scene.
QgsCoordinateTransformContext transformContext() const
Returns the coordinate transform context, which stores various information regarding which datum tran...
static QColor colorFromString(const QString &string)
Decodes a string into a color value.
static QString colorToString(const QColor &color)
Encodes a color into a string value.
Defines a QGIS exception class.
QString mId
Unique light ID.
A container for the context for various read/write operations on objects.
QgsPointXY center
bool operator==(const QgsSunLightSettings &other) const
QDomElement writeXml(QDomDocument &doc, const QgsReadWriteContext &context=QgsReadWriteContext()) const override
Writes the light source's configuration to a new DOM element and returns it.
double intensity() const
Returns the base intensity of the sunlight.
QgsSunLightSettings()=default
QgsSunLightSettings * clone() const override
Returns a copy of the light source.
QColor color() const
Returns the base color of the sunlight.
void readXml(const QDomElement &elem, const QgsReadWriteContext &context=QgsReadWriteContext()) override
Reads configuration from a DOM element previously written using writeXml().
QgsVector3D direction(const Qgs3DMapSettings &map) const
Returns the calculated direction of the light.
Qt3DCore::QEntity * createEntity(const Qgs3DMapSettings &map, Qt3DCore::QEntity *parent) const override
Creates an entity representing the light source.
Qgis::LightSourceType type() const override
Returns the light source type.
static QgsSunPositionResult calculate(const QgsPointXY &point, const QgsCoordinateReferenceSystem &crs, const QgsCoordinateTransformContext &context, const QDateTime &dateTime, double elevationMeters=0.0, double pressure=1013.25, double temperature=15.0)
Calculates the solar position and events for a given point and time.
A 3D vector (similar to QVector3D) with the difference that it uses double precision instead of singl...
Definition qgsvector3d.h:33
bool qgsDoubleNear(double a, double b, double epsilon=4 *std::numeric_limits< double >::epsilon())
Compare two doubles (but allow some difference).
Definition qgis.h:7340
Contains the results of a solar position calculation.
double azimuth
Azimuth angle in degrees clockwise from North.
double apparentElevation
Apparent topocentric elevation angle in degrees (corrected for atmospheric refraction).