29#include "moc_qgsmeshlayerelevationproperties.cpp"
35 setDefaultProfileLineSymbol( color );
36 setDefaultProfileFillSymbol( color );
48 QDomElement element = document.createElement( QStringLiteral(
"elevation" ) );
50 element.setAttribute( QStringLiteral(
"symbology" ),
qgsEnumValueToKey( mSymbology ) );
51 if ( !std::isnan( mElevationLimit ) )
52 element.setAttribute( QStringLiteral(
"elevationLimit" ),
qgsDoubleToString( mElevationLimit ) );
59 element.setAttribute( QStringLiteral(
"lower" ),
qgsDoubleToString( mFixedRange.lower() ) );
60 element.setAttribute( QStringLiteral(
"upper" ),
qgsDoubleToString( mFixedRange.upper() ) );
61 element.setAttribute( QStringLiteral(
"includeLower" ), mFixedRange.includeLower() ?
"1" :
"0" );
62 element.setAttribute( QStringLiteral(
"includeUpper" ), mFixedRange.includeUpper() ?
"1" :
"0" );
67 QDomElement ranges = document.createElement( QStringLiteral(
"ranges" ) );
68 for (
auto it = mRangePerGroup.constBegin(); it != mRangePerGroup.constEnd(); ++it )
70 QDomElement range = document.createElement( QStringLiteral(
"range" ) );
71 range.setAttribute( QStringLiteral(
"group" ), it.key() );
72 range.setAttribute( QStringLiteral(
"lower" ),
qgsDoubleToString( it.value().lower() ) );
73 range.setAttribute( QStringLiteral(
"upper" ),
qgsDoubleToString( it.value().upper() ) );
74 range.setAttribute( QStringLiteral(
"includeLower" ), it.value().includeLower() ?
"1" :
"0" );
75 range.setAttribute( QStringLiteral(
"includeUpper" ), it.value().includeUpper() ?
"1" :
"0" );
76 ranges.appendChild( range );
78 element.appendChild( ranges );
86 QDomElement profileLineSymbolElement = document.createElement( QStringLiteral(
"profileLineSymbol" ) );
88 element.appendChild( profileLineSymbolElement );
90 QDomElement profileFillSymbolElement = document.createElement( QStringLiteral(
"profileFillSymbol" ) );
92 element.appendChild( profileFillSymbolElement );
94 parentElement.appendChild( element );
100 const QDomElement elevationElement = element.firstChildElement( QStringLiteral(
"elevation" ) ).toElement();
103 if ( elevationElement.hasAttribute( QStringLiteral(
"elevationLimit" ) ) )
104 mElevationLimit = elevationElement.attribute( QStringLiteral(
"elevationLimit" ) ).toDouble();
106 mElevationLimit = std::numeric_limits< double >::quiet_NaN();
114 const double lower = elevationElement.attribute( QStringLiteral(
"lower" ) ).toDouble();
115 const double upper = elevationElement.attribute( QStringLiteral(
"upper" ) ).toDouble();
116 const bool includeLower = elevationElement.attribute( QStringLiteral(
"includeLower" ) ).toInt();
117 const bool includeUpper = elevationElement.attribute( QStringLiteral(
"includeUpper" ) ).toInt();
118 mFixedRange =
QgsDoubleRange( lower, upper, includeLower, includeUpper );
124 mRangePerGroup.clear();
126 const QDomNodeList ranges = elevationElement.firstChildElement( QStringLiteral(
"ranges" ) ).childNodes();
127 for (
int i = 0; i < ranges.size(); ++i )
129 const QDomElement rangeElement = ranges.at( i ).toElement();
130 const int group = rangeElement.attribute( QStringLiteral(
"group" ) ).toInt();
131 const double lower = rangeElement.attribute( QStringLiteral(
"lower" ) ).toDouble();
132 const double upper = rangeElement.attribute( QStringLiteral(
"upper" ) ).toDouble();
133 const bool includeLower = rangeElement.attribute( QStringLiteral(
"includeLower" ) ).toInt();
134 const bool includeUpper = rangeElement.attribute( QStringLiteral(
"includeUpper" ) ).toInt();
135 mRangePerGroup.insert( group,
QgsDoubleRange( lower, upper, includeLower, includeUpper ) );
146 const QDomElement profileLineSymbolElement = elevationElement.firstChildElement( QStringLiteral(
"profileLineSymbol" ) ).firstChildElement( QStringLiteral(
"symbol" ) );
148 if ( !mProfileLineSymbol )
149 setDefaultProfileLineSymbol( defaultColor );
151 const QDomElement profileFillSymbolElement = elevationElement.firstChildElement( QStringLiteral(
"profileFillSymbol" ) ).firstChildElement( QStringLiteral(
"symbol" ) );
153 if ( !mProfileFillSymbol )
154 setDefaultProfileFillSymbol( defaultColor );
161 QStringList properties;
165 properties << tr(
"Elevation range: %1 to %2" ).arg( mFixedRange.lower() ).arg( mFixedRange.upper() );
170 for (
auto it = mRangePerGroup.constBegin(); it != mRangePerGroup.constEnd(); ++it )
172 properties << tr(
"Elevation for group %1: %2 to %3" ).arg( it.key() ).arg( it.value().lower() ).arg( it.value().upper() );
178 properties << tr(
"Scale: %1" ).arg(
mZScale );
179 properties << tr(
"Offset: %1" ).arg(
mZOffset );
182 return QStringLiteral(
"<li>%1</li>" ).arg( properties.join( QLatin1String(
"</li><li>" ) ) );
187 auto res = std::make_unique< QgsMeshLayerElevationProperties >(
nullptr );
188 res->setMode( mMode );
189 res->setProfileLineSymbol( mProfileLineSymbol->clone() );
190 res->setProfileFillSymbol( mProfileFillSymbol->clone() );
191 res->setProfileSymbology( mSymbology );
192 res->setElevationLimit( mElevationLimit );
193 res->setFixedRange( mFixedRange );
194 res->setFixedRangePerGroup( mRangePerGroup );
195 res->copyCommonProperties(
this );
196 return res.release();
204 return mFixedRange.overlaps( range );
208 for (
auto it = mRangePerGroup.constBegin(); it != mRangePerGroup.constEnd(); ++it )
210 if ( it.value().overlaps( range ) )
232 double lower = std::numeric_limits< double >::max();
233 double upper = std::numeric_limits< double >::min();
234 bool includeLower =
true;
235 bool includeUpper =
true;
236 for (
auto it = mRangePerGroup.constBegin(); it != mRangePerGroup.constEnd(); ++it )
238 if ( it.value().lower() < lower )
240 lower = it.value().lower();
241 includeLower = it.value().includeLower();
243 else if ( !includeLower && it.value().lower() == lower && it.value().includeLower() )
247 if ( it.value().upper() > upper )
249 upper = it.value().upper();
250 includeUpper = it.value().includeUpper();
252 else if ( !includeUpper && it.value().upper() == upper && it.value().includeUpper() )
257 return QgsDoubleRange( lower, upper, includeLower, includeUpper );
273 if ( !mFixedRange.isInfinite() && mFixedRange.lower() != mFixedRange.upper() )
274 return { mFixedRange.lower(), mFixedRange.upper() };
275 else if ( !mFixedRange.isInfinite() )
276 return { mFixedRange.lower() };
284 for (
auto it = mRangePerGroup.constBegin(); it != mRangePerGroup.constEnd(); ++it )
286 if ( it.value().isInfinite() )
289 if ( !res.contains( it.value().lower( ) ) )
290 res.append( it.value().lower() );
291 if ( !res.contains( it.value().upper( ) ) )
292 res.append( it.value().upper() );
294 std::sort( res.begin(), res.end() );
344 if ( range == mFixedRange )
353 return mRangePerGroup;
358 if ( ranges == mRangePerGroup )
361 mRangePerGroup = ranges;
367 return mProfileLineSymbol.get();
372 mProfileLineSymbol.reset( symbol );
379 return mProfileFillSymbol.get();
384 mProfileFillSymbol.reset( symbol );
391 if ( mSymbology == symbology )
394 mSymbology = symbology;
401 return mElevationLimit;
409 mElevationLimit = limit;
414void QgsMeshLayerElevationProperties::setDefaultProfileLineSymbol(
const QColor &color )
416 auto profileLineLayer = std::make_unique< QgsSimpleLineSymbolLayer >( color, 0.6 );
417 mProfileLineSymbol = std::make_unique< QgsLineSymbol>(
QgsSymbolLayerList( { profileLineLayer.release() } ) );
420void QgsMeshLayerElevationProperties::setDefaultProfileFillSymbol(
const QColor &color )
422 auto profileFillLayer = std::make_unique< QgsSimpleFillSymbolLayer >( color );
423 profileFillLayer->setStrokeStyle( Qt::NoPen );
424 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