31#include "moc_qgsmeshlayerelevationproperties.cpp"
33using namespace Qt::StringLiterals;
39 setDefaultProfileLineSymbol( color );
40 setDefaultProfileFillSymbol( color );
52 QDomElement element = document.createElement( u
"elevation"_s );
55 if ( !std::isnan( mElevationLimit ) )
56 element.setAttribute( u
"elevationLimit"_s,
qgsDoubleToString( mElevationLimit ) );
65 element.setAttribute( u
"includeLower"_s, mFixedRange.includeLower() ?
"1" :
"0" );
66 element.setAttribute( u
"includeUpper"_s, mFixedRange.includeUpper() ?
"1" :
"0" );
71 QDomElement ranges = document.createElement( u
"ranges"_s );
72 for (
auto it = mRangePerGroup.constBegin(); it != mRangePerGroup.constEnd(); ++it )
74 QDomElement range = document.createElement( u
"range"_s );
75 range.setAttribute( u
"group"_s, it.key() );
78 range.setAttribute( u
"includeLower"_s, it.value().includeLower() ?
"1" :
"0" );
79 range.setAttribute( u
"includeUpper"_s, it.value().includeUpper() ?
"1" :
"0" );
80 ranges.appendChild( range );
82 element.appendChild( ranges );
90 QDomElement profileLineSymbolElement = document.createElement( u
"profileLineSymbol"_s );
92 element.appendChild( profileLineSymbolElement );
94 QDomElement profileFillSymbolElement = document.createElement( u
"profileFillSymbol"_s );
96 element.appendChild( profileFillSymbolElement );
98 parentElement.appendChild( element );
104 const QDomElement elevationElement = element.firstChildElement( u
"elevation"_s ).toElement();
107 if ( elevationElement.hasAttribute( u
"elevationLimit"_s ) )
108 mElevationLimit = elevationElement.attribute( u
"elevationLimit"_s ).toDouble();
110 mElevationLimit = std::numeric_limits< double >::quiet_NaN();
118 const double lower = elevationElement.attribute( u
"lower"_s ).toDouble();
119 const double upper = elevationElement.attribute( u
"upper"_s ).toDouble();
120 const bool includeLower = elevationElement.attribute( u
"includeLower"_s ).toInt();
121 const bool includeUpper = elevationElement.attribute( u
"includeUpper"_s ).toInt();
122 mFixedRange =
QgsDoubleRange( lower, upper, includeLower, includeUpper );
128 mRangePerGroup.clear();
130 const QDomNodeList ranges = elevationElement.firstChildElement( u
"ranges"_s ).childNodes();
131 for (
int i = 0; i < ranges.size(); ++i )
133 const QDomElement rangeElement = ranges.at( i ).toElement();
134 const int group = rangeElement.attribute( u
"group"_s ).toInt();
135 const double lower = rangeElement.attribute( u
"lower"_s ).toDouble();
136 const double upper = rangeElement.attribute( u
"upper"_s ).toDouble();
137 const bool includeLower = rangeElement.attribute( u
"includeLower"_s ).toInt();
138 const bool includeUpper = rangeElement.attribute( u
"includeUpper"_s ).toInt();
139 mRangePerGroup.insert( group,
QgsDoubleRange( lower, upper, includeLower, includeUpper ) );
150 const QDomElement profileLineSymbolElement = elevationElement.firstChildElement( u
"profileLineSymbol"_s ).firstChildElement( u
"symbol"_s );
152 if ( !mProfileLineSymbol )
153 setDefaultProfileLineSymbol( defaultColor );
155 const QDomElement profileFillSymbolElement = elevationElement.firstChildElement( u
"profileFillSymbol"_s ).firstChildElement( u
"symbol"_s );
157 if ( !mProfileFillSymbol )
158 setDefaultProfileFillSymbol( defaultColor );
165 QStringList properties;
169 properties << tr(
"Elevation range: %1 to %2" ).arg( mFixedRange.lower() ).arg( mFixedRange.upper() );
174 for (
auto it = mRangePerGroup.constBegin(); it != mRangePerGroup.constEnd(); ++it )
176 properties << tr(
"Elevation for group %1: %2 to %3" ).arg( it.key() ).arg( it.value().lower() ).arg( it.value().upper() );
182 properties << tr(
"Scale: %1" ).arg(
mZScale );
183 properties << tr(
"Offset: %1" ).arg(
mZOffset );
186 return u
"<li>%1</li>"_s.arg( properties.join(
"</li><li>"_L1 ) );
191 auto res = std::make_unique< QgsMeshLayerElevationProperties >(
nullptr );
192 res->setMode( mMode );
193 res->setProfileLineSymbol( mProfileLineSymbol->clone() );
194 res->setProfileFillSymbol( mProfileFillSymbol->clone() );
195 res->setProfileSymbology( mSymbology );
196 res->setElevationLimit( mElevationLimit );
197 res->setFixedRange( mFixedRange );
198 res->setFixedRangePerGroup( mRangePerGroup );
199 res->copyCommonProperties(
this );
200 return res.release();
208 return mFixedRange.overlaps( range );
212 for (
auto it = mRangePerGroup.constBegin(); it != mRangePerGroup.constEnd(); ++it )
214 if ( it.value().overlaps( range ) )
236 double lower = std::numeric_limits< double >::max();
237 double upper = std::numeric_limits< double >::min();
238 bool includeLower =
true;
239 bool includeUpper =
true;
240 for (
auto it = mRangePerGroup.constBegin(); it != mRangePerGroup.constEnd(); ++it )
242 if ( it.value().lower() < lower )
244 lower = it.value().lower();
245 includeLower = it.value().includeLower();
247 else if ( !includeLower && it.value().lower() == lower && it.value().includeLower() )
251 if ( it.value().upper() > upper )
253 upper = it.value().upper();
254 includeUpper = it.value().includeUpper();
256 else if ( !includeUpper && it.value().upper() == upper && it.value().includeUpper() )
261 return QgsDoubleRange( lower, upper, includeLower, includeUpper );
277 if ( !mFixedRange.isInfinite() && mFixedRange.lower() != mFixedRange.upper() )
278 return { mFixedRange.lower(), mFixedRange.upper() };
279 else if ( !mFixedRange.isInfinite() )
280 return { mFixedRange.lower() };
288 for (
auto it = mRangePerGroup.constBegin(); it != mRangePerGroup.constEnd(); ++it )
290 if ( it.value().isInfinite() )
293 if ( !res.contains( it.value().lower( ) ) )
294 res.append( it.value().lower() );
295 if ( !res.contains( it.value().upper( ) ) )
296 res.append( it.value().upper() );
298 std::sort( res.begin(), res.end() );
348 if ( range == mFixedRange )
357 return mRangePerGroup;
362 if ( ranges == mRangePerGroup )
365 mRangePerGroup = ranges;
371 return mProfileLineSymbol.get();
376 mProfileLineSymbol.reset( symbol );
383 return mProfileFillSymbol.get();
388 mProfileFillSymbol.reset( symbol );
395 if ( mSymbology == symbology )
398 mSymbology = symbology;
405 return mElevationLimit;
413 mElevationLimit = limit;
418void QgsMeshLayerElevationProperties::setDefaultProfileLineSymbol(
const QColor &color )
420 auto profileLineLayer = std::make_unique< QgsSimpleLineSymbolLayer >( color, 0.6 );
421 mProfileLineSymbol = std::make_unique< QgsLineSymbol>(
QgsSymbolLayerList( { profileLineLayer.release() } ) );
424void QgsMeshLayerElevationProperties::setDefaultProfileFillSymbol(
const QColor &color )
426 auto profileFillLayer = std::make_unique< QgsSimpleFillSymbolLayer >( color );
427 profileFillLayer->setStrokeStyle( Qt::NoPen );
428 mProfileFillSymbol = std::make_unique< QgsFillSymbol>(
QgsSymbolLayerList( { profileFillLayer.release() } ) );
MeshElevationMode
Mesh layer elevation modes.
@ FromVertices
Elevation should be taken from mesh vertices.
@ FixedRangePerGroup
Layer has a fixed (manually specified) elevation range per group.
@ FixedElevationRange
Layer has a fixed elevation range.
ProfileSurfaceSymbology
Surface symbology type for elevation profile plots.
@ Line
The elevation surface will be rendered using a line symbol.
static QgsColorSchemeRegistry * colorSchemeRegistry()
Returns the application's color scheme registry, used for managing color schemes.
QColor fetchRandomStyleColor() const
Returns a random color for use with a new symbol style (e.g.
QgsRange which stores a range of double values.
A fill symbol type, for rendering Polygon and MultiPolygon geometries.
A line symbol type, for rendering LineString and MultiLineString geometries.
void writeCommonProperties(QDomElement &element, QDomDocument &doc, const QgsReadWriteContext &context)
Writes common class properties to a DOM element, to be used later with readXml().
QgsMapLayerElevationProperties(QObject *parent)
Constructor for QgsMapLayerElevationProperties, with the specified parent object.
void readCommonProperties(const QDomElement &element, const QgsReadWriteContext &context)
Reads common class properties from a DOM element previously written by writeXml().
void changed()
Emitted when any of the elevation properties have changed.
void profileRenderingPropertyChanged()
Emitted when any of the elevation properties which relate solely to presentation of elevation results...
@ FlagDontInvalidateCachedRendersWhenRangeChanges
Any cached rendering will not be invalidated when z range context is modified.
Base class for all map layer types.
QDomElement writeXml(QDomElement &element, QDomDocument &doc, const QgsReadWriteContext &context) override
Writes the properties to a DOM element, to be used later with readXml().
QgsLineSymbol * profileLineSymbol() const
Returns the line symbol used to render the mesh profile in elevation profile plots.
QgsDoubleRange fixedRange() const
Returns the fixed elevation range for the mesh.
bool hasElevation() const override
Returns true if the layer has an elevation or z component.
bool isVisibleInZRange(const QgsDoubleRange &range, QgsMapLayer *layer=nullptr) const override
Returns true if the layer should be visible and rendered for the specified z range.
Qgis::MeshElevationMode mode() const
Returns the elevation mode.
void setFixedRangePerGroup(const QMap< int, QgsDoubleRange > &ranges)
Sets the fixed elevation range for each group.
QgsMeshLayerElevationProperties * clone() const override
Creates a clone of the properties.
void setElevationLimit(double limit)
Sets the elevation limit, which is used when profileSymbology() is Qgis::ProfileSurfaceSymbology::Fil...
QList< double > significantZValues(QgsMapLayer *layer) const override
Returns a list of significant elevation/z-values for the specified layer, using the settings defined ...
QgsFillSymbol * profileFillSymbol() const
Returns the fill symbol used to render the mesh profile in elevation profile plots.
void setProfileSymbology(Qgis::ProfileSurfaceSymbology symbology)
Sets the symbology option used to render the mesh profile in elevation profile plots.
void setProfileFillSymbol(QgsFillSymbol *symbol)
Sets the fill symbol used to render the mesh profile in elevation profile plots.
void setProfileLineSymbol(QgsLineSymbol *symbol)
Sets the line symbol used to render the mesh profile in elevation profile plots.
~QgsMeshLayerElevationProperties() override
QgsMeshLayerElevationProperties(QObject *parent)
Constructor for QgsMeshLayerElevationProperties, with the specified parent object.
void setMode(Qgis::MeshElevationMode mode)
Sets the elevation mode.
QMap< int, QgsDoubleRange > fixedRangePerGroup() const
Returns the fixed elevation range for each group.
QString htmlSummary() const override
Returns a HTML formatted summary of the properties.
QgsMapLayerElevationProperties::Flags flags() const override
Returns flags associated to the elevation properties.
void setFixedRange(const QgsDoubleRange &range)
Sets the fixed elevation range for the mesh.
bool showByDefaultInElevationProfilePlots() const override
Returns true if the layer should be visible by default in newly created elevation profile plots.
bool readXml(const QDomElement &element, const QgsReadWriteContext &context) override
Reads the elevation properties from a DOM element previously written by writeXml().
double elevationLimit() const
Returns the elevation limit, which is used when profileSymbology() is Qgis::ProfileSurfaceSymbology::...
QgsDoubleRange calculateZRange(QgsMapLayer *layer) const override
Attempts to calculate the overall elevation or z range for the specified layer, using the settings de...
A container for the context for various read/write operations on objects.
static std::unique_ptr< QgsSymbol > loadSymbol(const QDomElement &element, const QgsReadWriteContext &context)
Attempts to load a symbol from a DOM element.
static QDomElement saveSymbol(const QString &symbolName, const QgsSymbol *symbol, QDomDocument &doc, const QgsReadWriteContext &context)
Writes a symbol definition to XML.
T qgsEnumKeyToValue(const QString &key, const T &defaultValue, bool tryValueAsKey=true, bool *returnOk=nullptr)
Returns the value corresponding to the given key of an enum.
QString qgsDoubleToString(double a, int precision=17)
Returns a string representation of a double.
QString qgsEnumValueToKey(const T &value, bool *returnOk=nullptr)
Returns the value for the given key of an enum.
#define BUILTIN_UNREACHABLE
bool qgsDoubleNear(double a, double b, double epsilon=4 *std::numeric_limits< double >::epsilon())
Compare two doubles (but allow some difference).
QList< QgsSymbolLayer * > QgsSymbolLayerList