QGIS API Documentation 4.1.0-Master (ca2ac17535b)
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 <Qt3DExtras/QPhongMaterial>
27#include <Qt3DExtras/QSphereMesh>
28#include <Qt3DRender/QDirectionalLight>
29
30using namespace Qt::StringLiterals;
31
36
38{
39 auto res = std::make_unique< QgsSunLightSettings >( *this );
40 res->mId = mId;
41 return res.release();
42}
43
45{
46 QgsSunPositionResult sunResult;
47 try
48 {
49 sunResult = QgsSunPositionCalculator::calculate( map.extent().center(), map.crs(), map.transformContext(), mSunTime, mReferenceElevation, mAtmosphericPressure, mTemperature );
50 }
51 catch ( const QgsException & )
52 {
53 // fallback to straight down (noon) if CRS transformation or math fails
54 sunResult.azimuth = 0.0;
55 sunResult.apparentElevation = 90.0;
56 }
57
58 const float azimuthRad = M_PI * sunResult.azimuth / 180.0;
59 const float elevationRad = M_PI * sunResult.apparentElevation / 180.0;
60 // convert to vector in z-up world
61 const float x = std::cos( elevationRad ) * std::sin( azimuthRad );
62 const float y = std::cos( elevationRad ) * std::cos( azimuthRad );
63 const float z = std::sin( elevationRad );
64 const QVector3D sunVector( x, y, z );
65 return -sunVector.normalized();
66}
67
68Qt3DCore::QEntity *QgsSunLightSettings::createEntity( const Qgs3DMapSettings &map, Qt3DCore::QEntity *parent ) const
69{
70 Qt3DCore::QEntity *lightEntity = new Qt3DCore::QEntity( parent );
71
72 Qt3DRender::QDirectionalLight *light = new Qt3DRender::QDirectionalLight;
73 light->setColor( color() );
74 light->setIntensity( static_cast< float >( intensity() ) );
75 light->setWorldDirection( direction( map ).toVector3D() );
76
77 lightEntity->addComponent( light );
78
79 return lightEntity;
80}
81
82QDomElement QgsSunLightSettings::writeXml( QDomDocument &doc, const QgsReadWriteContext & ) const
83{
84 QDomElement elemLight = doc.createElement( u"sun-light"_s );
85 elemLight.setAttribute( u"id"_s, mId );
86 elemLight.setAttribute( u"color"_s, QgsColorUtils::colorToString( mColor ) );
87 elemLight.setAttribute( u"intensity"_s, mIntensity );
88 elemLight.setAttribute( u"sun-time"_s, mSunTime.toString( Qt::ISODate ) );
89 elemLight.setAttribute( u"reference-elevation"_s, mReferenceElevation );
90 elemLight.setAttribute( u"atmospheric-pressure"_s, mAtmosphericPressure );
91 elemLight.setAttribute( u"temperature"_s, mTemperature );
92
93 return elemLight;
94}
95
96void QgsSunLightSettings::readXml( const QDomElement &elem, const QgsReadWriteContext & )
97{
98 if ( elem.hasAttribute( u"id"_s ) )
99 mId = elem.attribute( u"id"_s );
100 mColor = QgsColorUtils::colorFromString( elem.attribute( u"color"_s ) );
101 mIntensity = elem.attribute( u"intensity"_s ).toDouble();
102 mSunTime = QDateTime::fromString( elem.attribute( u"sun-time"_s ), Qt::ISODate );
103 if ( !mSunTime.isValid() )
104 {
105 mSunTime = QDateTime::currentDateTimeUtc();
106 }
107 mReferenceElevation = elem.attribute( u"reference-elevation"_s, u"0.0"_s ).toDouble();
108 mAtmosphericPressure = elem.attribute( u"atmospheric-pressure"_s, u"1013.25"_s ).toDouble();
109 mTemperature = elem.attribute( u"temperature"_s, u"15.0"_s ).toDouble();
110}
111
113{
114 return mId == other.mId
115 && mSunTime == other.mSunTime
116 && mColor == other.mColor
117 && mIntensity == other.mIntensity
118 && qgsDoubleNear( mAtmosphericPressure, other.mAtmosphericPressure )
119 && qgsDoubleNear( mTemperature, other.mTemperature )
120 && qgsDoubleNear( mReferenceElevation, other.mReferenceElevation );
121}
LightSourceType
Light source types for 3D scenes.
Definition qgis.h:4404
@ Sun
Sun based light source.
Definition qgis.h:4407
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:7236
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).