19#include "moc_qgsmeshlayerelevationproperties.cpp" 
   33  setDefaultProfileLineSymbol( color );
 
   34  setDefaultProfileFillSymbol( color );
 
 
   46  QDomElement element = document.createElement( QStringLiteral( 
"elevation" ) );
 
   48  element.setAttribute( QStringLiteral( 
"symbology" ), 
qgsEnumValueToKey( mSymbology ) );
 
   49  if ( !std::isnan( mElevationLimit ) )
 
   50    element.setAttribute( QStringLiteral( 
"elevationLimit" ), 
qgsDoubleToString( mElevationLimit ) );
 
   59      element.setAttribute( QStringLiteral( 
"includeLower" ), mFixedRange.
includeLower() ? 
"1" : 
"0" );
 
   60      element.setAttribute( QStringLiteral( 
"includeUpper" ), mFixedRange.
includeUpper() ? 
"1" : 
"0" );
 
   65      QDomElement ranges = document.createElement( QStringLiteral( 
"ranges" ) );
 
   66      for ( 
auto it = mRangePerGroup.constBegin(); it != mRangePerGroup.constEnd(); ++it )
 
   68        QDomElement range = document.createElement( QStringLiteral( 
"range" ) );
 
   69        range.setAttribute( QStringLiteral( 
"group" ), it.key() );
 
   70        range.setAttribute( QStringLiteral( 
"lower" ), 
qgsDoubleToString( it.value().lower() ) );
 
   71        range.setAttribute( QStringLiteral( 
"upper" ), 
qgsDoubleToString( it.value().upper() ) );
 
   72        range.setAttribute( QStringLiteral( 
"includeLower" ), it.value().includeLower() ? 
"1" : 
"0" );
 
   73        range.setAttribute( QStringLiteral( 
"includeUpper" ), it.value().includeUpper() ? 
"1" : 
"0" );
 
   74        ranges.appendChild( range );
 
   76      element.appendChild( ranges );
 
   84  QDomElement profileLineSymbolElement = document.createElement( QStringLiteral( 
"profileLineSymbol" ) );
 
   86  element.appendChild( profileLineSymbolElement );
 
   88  QDomElement profileFillSymbolElement = document.createElement( QStringLiteral( 
"profileFillSymbol" ) );
 
   90  element.appendChild( profileFillSymbolElement );
 
   92  parentElement.appendChild( element );
 
 
   98  const QDomElement elevationElement = element.firstChildElement( QStringLiteral( 
"elevation" ) ).toElement();
 
  101  if ( elevationElement.hasAttribute( QStringLiteral( 
"elevationLimit" ) ) )
 
  102    mElevationLimit = elevationElement.attribute( QStringLiteral( 
"elevationLimit" ) ).toDouble();
 
  104    mElevationLimit = std::numeric_limits< double >::quiet_NaN();
 
  112      const double lower = elevationElement.attribute( QStringLiteral( 
"lower" ) ).toDouble();
 
  113      const double upper = elevationElement.attribute( QStringLiteral( 
"upper" ) ).toDouble();
 
  114      const bool includeLower = elevationElement.attribute( QStringLiteral( 
"includeLower" ) ).toInt();
 
  115      const bool includeUpper = elevationElement.attribute( QStringLiteral( 
"includeUpper" ) ).toInt();
 
  116      mFixedRange = 
QgsDoubleRange( lower, upper, includeLower, includeUpper );
 
  122      mRangePerGroup.clear();
 
  124      const QDomNodeList ranges = elevationElement.firstChildElement( QStringLiteral( 
"ranges" ) ).childNodes();
 
  125      for ( 
int i = 0; i < ranges.size(); ++i )
 
  127        const QDomElement rangeElement = ranges.at( i ).toElement();
 
  128        const int group = rangeElement.attribute( QStringLiteral( 
"group" ) ).toInt();
 
  129        const double lower = rangeElement.attribute( QStringLiteral( 
"lower" ) ).toDouble();
 
  130        const double upper = rangeElement.attribute( QStringLiteral( 
"upper" ) ).toDouble();
 
  131        const bool includeLower = rangeElement.attribute( QStringLiteral( 
"includeLower" ) ).toInt();
 
  132        const bool includeUpper = rangeElement.attribute( QStringLiteral( 
"includeUpper" ) ).toInt();
 
  133        mRangePerGroup.insert( group, 
QgsDoubleRange( lower, upper, includeLower, includeUpper ) );
 
  144  const QDomElement profileLineSymbolElement = elevationElement.firstChildElement( QStringLiteral( 
"profileLineSymbol" ) ).firstChildElement( QStringLiteral( 
"symbol" ) );
 
  145  mProfileLineSymbol = QgsSymbolLayerUtils::loadSymbol< QgsLineSymbol >( profileLineSymbolElement, context );
 
  146  if ( !mProfileLineSymbol )
 
  147    setDefaultProfileLineSymbol( defaultColor );
 
  149  const QDomElement profileFillSymbolElement = elevationElement.firstChildElement( QStringLiteral( 
"profileFillSymbol" ) ).firstChildElement( QStringLiteral( 
"symbol" ) );
 
  150  mProfileFillSymbol = QgsSymbolLayerUtils::loadSymbol< QgsFillSymbol >( profileFillSymbolElement, context );
 
  151  if ( !mProfileFillSymbol )
 
  152    setDefaultProfileFillSymbol( defaultColor );
 
 
  159  QStringList properties;
 
  163      properties << tr( 
"Elevation range: %1 to %2" ).arg( mFixedRange.
lower() ).arg( mFixedRange.
upper() );
 
  168      for ( 
auto it = mRangePerGroup.constBegin(); it != mRangePerGroup.constEnd(); ++it )
 
  170        properties << tr( 
"Elevation for group %1: %2 to %3" ).arg( it.key() ).arg( it.value().lower() ).arg( it.value().upper() );
 
  176      properties << tr( 
"Scale: %1" ).arg( 
mZScale );
 
  177      properties << tr( 
"Offset: %1" ).arg( 
mZOffset );
 
  180  return QStringLiteral( 
"<li>%1</li>" ).arg( properties.join( QLatin1String( 
"</li><li>" ) ) );
 
 
  185  auto res = std::make_unique< QgsMeshLayerElevationProperties >( 
nullptr );
 
  186  res->setMode( mMode );
 
  187  res->setProfileLineSymbol( mProfileLineSymbol->clone() );
 
  188  res->setProfileFillSymbol( mProfileFillSymbol->clone() );
 
  189  res->setProfileSymbology( mSymbology );
 
  190  res->setElevationLimit( mElevationLimit );
 
  191  res->setFixedRange( mFixedRange );
 
  192  res->setFixedRangePerGroup( mRangePerGroup );
 
  193  res->copyCommonProperties( 
this );
 
  194  return res.release();
 
 
  202      return mFixedRange.
overlaps( range );
 
  206      for ( 
auto it = mRangePerGroup.constBegin(); it != mRangePerGroup.constEnd(); ++it )
 
  208        if ( it.value().overlaps( range ) )
 
 
  230      double lower = std::numeric_limits< double >::max();
 
  231      double upper = std::numeric_limits< double >::min();
 
  232      bool includeLower = 
true;
 
  233      bool includeUpper = 
true;
 
  234      for ( 
auto it = mRangePerGroup.constBegin(); it != mRangePerGroup.constEnd(); ++it )
 
  236        if ( it.value().lower() < lower )
 
  238          lower = it.value().lower();
 
  239          includeLower = it.value().includeLower();
 
  241        else if ( !includeLower && it.value().lower() == lower && it.value().includeLower() )
 
  245        if ( it.value().upper() > upper )
 
  247          upper = it.value().upper();
 
  248          includeUpper = it.value().includeUpper();
 
  250        else if ( !includeUpper && it.value().upper() == upper && it.value().includeUpper() )
 
  255      return QgsDoubleRange( lower, upper, includeLower, includeUpper );
 
 
  272        return { mFixedRange.
lower(), mFixedRange.
upper() };
 
  274        return { mFixedRange.
lower() };
 
  282      for ( 
auto it = mRangePerGroup.constBegin(); it != mRangePerGroup.constEnd(); ++it )
 
  284        if ( it.value().isInfinite() )
 
  287        if ( !res.contains( it.value().lower( ) ) )
 
  288          res.append( it.value().lower() );
 
  289        if ( !res.contains( it.value().upper( ) ) )
 
  290          res.append( it.value().upper() );
 
  292      std::sort( res.begin(), res.end() );
 
 
  342  if ( range == mFixedRange )
 
 
  351  return mRangePerGroup;
 
 
  356  if ( ranges == mRangePerGroup )
 
  359  mRangePerGroup = ranges;
 
 
  365  return mProfileLineSymbol.get();
 
 
  370  mProfileLineSymbol.reset( symbol );
 
 
  377  return mProfileFillSymbol.get();
 
 
  382  mProfileFillSymbol.reset( symbol );
 
 
  389  if ( mSymbology == symbology )
 
  392  mSymbology = symbology;
 
 
  399  return mElevationLimit;
 
 
  407  mElevationLimit = limit;
 
 
  412void QgsMeshLayerElevationProperties::setDefaultProfileLineSymbol( 
const QColor &color )
 
  414  auto profileLineLayer = std::make_unique< QgsSimpleLineSymbolLayer >( color, 0.6 );
 
  415  mProfileLineSymbol = std::make_unique< QgsLineSymbol>( 
QgsSymbolLayerList( { profileLineLayer.release() } ) );
 
  418void QgsMeshLayerElevationProperties::setDefaultProfileFillSymbol( 
const QColor &color )
 
  420  auto profileFillLayer = std::make_unique< QgsSimpleFillSymbolLayer >( color );
 
  421  profileFillLayer->setStrokeStyle( Qt::NoPen );
 
  422  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.
bool isInfinite() const
Returns true if the range consists of all possible values.
A fill symbol type, for rendering Polygon and MultiPolygon geometries.
A line symbol type, for rendering LineString and MultiLineString geometries.
Base class for storage of map layer elevation properties.
void writeCommonProperties(QDomElement &element, QDomDocument &doc, const QgsReadWriteContext &context)
Writes common class properties to a DOM element, to be used later with readXml().
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.
Mesh layer specific subclass of QgsMapLayerElevationProperties.
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...
bool includeUpper() const
Returns true if the upper bound is inclusive, or false if the upper bound is exclusive.
bool overlaps(const QgsRange< T > &other) const
Returns true if this range overlaps another range.
T lower() const
Returns the lower bound of the range.
bool includeLower() const
Returns true if the lower bound is inclusive, or false if the lower bound is exclusive.
T upper() const
Returns the upper bound of the range.
A container for the context for various read/write operations on objects.
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