QGIS API Documentation  3.22.4-Białowieża (ce8e65e95e)
qgsannotationlayer.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsannotationlayer.cpp
3  ------------------
4  copyright : (C) 2019 by Sandro Mani
5  email : smani at sourcepole dot ch
6  ***************************************************************************/
7 
8 /***************************************************************************
9  * *
10  * This program is free software; you can redistribute it and/or modify *
11  * it under the terms of the GNU General Public License as published by *
12  * the Free Software Foundation; either version 2 of the License, or *
13  * (at your option) any later version. *
14  * *
15  ***************************************************************************/
16 
17 #include "qgsannotationlayer.h"
19 #include "qgsannotationitem.h"
21 #include "qgsapplication.h"
22 #include "qgslogger.h"
23 #include "qgspainting.h"
24 #include "qgsmaplayerfactory.h"
25 #include "qgsfeedback.h"
27 #include "qgspainteffect.h"
28 #include "qgseffectstack.h"
29 #include "qgspainteffectregistry.h"
30 #include <QUuid>
31 #include "RTree.h"
32 
34 class QgsAnnotationLayerSpatialIndex : public RTree<QString, float, 2, float>
35 {
36  public:
37 
38  void insert( const QString &uuid, const QgsRectangle &bounds )
39  {
40  std::array< float, 4 > scaledBounds = scaleBounds( bounds );
41  this->Insert(
42  {
43  scaledBounds[0], scaledBounds[ 1]
44  },
45  {
46  scaledBounds[2], scaledBounds[3]
47  },
48  uuid );
49  }
50 
57  void remove( const QString &uuid, const QgsRectangle &bounds )
58  {
59  std::array< float, 4 > scaledBounds = scaleBounds( bounds );
60  this->Remove(
61  {
62  scaledBounds[0], scaledBounds[ 1]
63  },
64  {
65  scaledBounds[2], scaledBounds[3]
66  },
67  uuid );
68  }
69 
75  bool intersects( const QgsRectangle &bounds, const std::function< bool( const QString &uuid )> &callback ) const
76  {
77  std::array< float, 4 > scaledBounds = scaleBounds( bounds );
78  this->Search(
79  {
80  scaledBounds[0], scaledBounds[ 1]
81  },
82  {
83  scaledBounds[2], scaledBounds[3]
84  },
85  callback );
86  return true;
87  }
88 
89  private:
90  std::array<float, 4> scaleBounds( const QgsRectangle &bounds ) const
91  {
92  return
93  {
94  static_cast< float >( bounds.xMinimum() ),
95  static_cast< float >( bounds.yMinimum() ),
96  static_cast< float >( bounds.xMaximum() ),
97  static_cast< float >( bounds.yMaximum() )
98  };
99  }
100 };
102 
103 QgsAnnotationLayer::QgsAnnotationLayer( const QString &name, const LayerOptions &options )
105  , mTransformContext( options.transformContext )
106  , mSpatialIndex( std::make_unique< QgsAnnotationLayerSpatialIndex >() )
107 {
108  mShouldValidateCrs = false;
109  mValid = true;
110 
111  QgsDataProvider::ProviderOptions providerOptions;
112  providerOptions.transformContext = options.transformContext;
113  mDataProvider = new QgsAnnotationLayerDataProvider( providerOptions, QgsDataProvider::ReadFlags() );
114 
115  mPaintEffect.reset( QgsPaintEffectRegistry::defaultStack() );
116  mPaintEffect->setEnabled( false );
117 }
118 
120 {
121  emit willBeDeleted();
122  qDeleteAll( mItems );
123  delete mDataProvider;
124 }
125 
127 {
128  setOpacity( 1.0 );
131  clear();
132 }
133 
135 {
136  const QString uuid = QUuid::createUuid().toString();
137  mItems.insert( uuid, item );
139  mNonIndexedItems.insert( uuid );
140  else
141  mSpatialIndex->insert( uuid, item->boundingBox() );
142 
143  triggerRepaint();
144 
145  return uuid;
146 }
147 
148 void QgsAnnotationLayer::replaceItem( const QString &id, QgsAnnotationItem *item )
149 {
150  std::unique_ptr< QgsAnnotationItem> prevItem( mItems.take( id ) );
151 
152  if ( prevItem )
153  {
154  auto it = mNonIndexedItems.find( id );
155  if ( it == mNonIndexedItems.end() )
156  {
157  mSpatialIndex->remove( id, prevItem->boundingBox() );
158  }
159  else
160  {
161  mNonIndexedItems.erase( it );
162  }
163  }
164 
165  mItems.insert( id, item );
167  mNonIndexedItems.insert( id );
168  else
169  mSpatialIndex->insert( id, item->boundingBox() );
170 
171  triggerRepaint();
172 }
173 
174 bool QgsAnnotationLayer::removeItem( const QString &id )
175 {
176  if ( !mItems.contains( id ) )
177  return false;
178 
179  std::unique_ptr< QgsAnnotationItem> item( mItems.take( id ) );
180 
181  auto it = mNonIndexedItems.find( id );
182  if ( it == mNonIndexedItems.end() )
183  {
184  mSpatialIndex->remove( id, item->boundingBox() );
185  }
186  else
187  {
188  mNonIndexedItems.erase( it );
189  }
190 
191  item.reset();
192 
193  triggerRepaint();
194 
195  return true;
196 }
197 
199 {
200  qDeleteAll( mItems );
201  mItems.clear();
202  mSpatialIndex = std::make_unique< QgsAnnotationLayerSpatialIndex >();
203  mNonIndexedItems.clear();
204 
205  triggerRepaint();
206 }
207 
209 {
210  return mItems.empty();
211 }
212 
214 {
215  return mItems.value( id );
216 }
217 
218 
219 QStringList QgsAnnotationLayer::queryIndex( const QgsRectangle &bounds, QgsFeedback *feedback ) const
220 {
221  QStringList res;
222 
223  mSpatialIndex->intersects( bounds, [&res, feedback]( const QString & uuid )->bool
224  {
225  res << uuid;
226  return !feedback || !feedback->isCanceled();
227  } );
228  return res;
229 }
230 
231 QStringList QgsAnnotationLayer::itemsInBounds( const QgsRectangle &bounds, QgsRenderContext &context, QgsFeedback *feedback ) const
232 {
233  QStringList res = queryIndex( bounds, feedback );
234  // we also have to search through any non-indexed items
235  for ( const QString &uuid : mNonIndexedItems )
236  {
237  if ( mItems.value( uuid )->boundingBox( context ).intersects( bounds ) )
238  res << uuid;
239  }
240 
241  return res;
242 }
243 
245 {
247  if ( QgsAnnotationItem *targetItem = item( operation->itemId() ) )
248  {
249  // remove item from index if present
250  auto it = mNonIndexedItems.find( operation->itemId() );
251  if ( it == mNonIndexedItems.end() )
252  {
253  mSpatialIndex->remove( operation->itemId(), targetItem->boundingBox() );
254  }
255  res = targetItem->applyEdit( operation );
256 
257  switch ( res )
258  {
261  // re-add to index if possible
262  if ( !( targetItem->flags() & Qgis::AnnotationItemFlag::ScaleDependentBoundingBox ) )
263  mSpatialIndex->insert( operation->itemId(), targetItem->boundingBox() );
264  break;
265 
267  // item needs removing from layer
268  delete mItems.take( operation->itemId() );
269  mNonIndexedItems.remove( operation->itemId() );
270  break;
271  }
272  }
273 
275  triggerRepaint();
276 
277  return res;
278 }
279 
280 Qgis::MapLayerProperties QgsAnnotationLayer::properties() const
281 {
282  // annotation layers are always editable
284 }
285 
287 {
288  const QgsAnnotationLayer::LayerOptions options( mTransformContext );
289  std::unique_ptr< QgsAnnotationLayer > layer = std::make_unique< QgsAnnotationLayer >( name(), options );
290  QgsMapLayer::clone( layer.get() );
291 
292  for ( auto it = mItems.constBegin(); it != mItems.constEnd(); ++it )
293  {
294  layer->mItems.insert( it.key(), ( *it )->clone() );
296  layer->mNonIndexedItems.insert( it.key() );
297  else
298  layer->mSpatialIndex->insert( it.key(), ( *it )->boundingBox() );
299  }
300 
301  if ( mPaintEffect )
302  layer->setPaintEffect( mPaintEffect->clone() );
303 
304  return layer.release();
305 }
306 
308 {
309  return new QgsAnnotationLayerRenderer( this, rendererContext );
310 }
311 
313 {
314  QgsRectangle rect;
315  for ( auto it = mItems.constBegin(); it != mItems.constEnd(); ++it )
316  {
317  if ( rect.isNull() )
318  {
319  rect = it.value()->boundingBox();
320  }
321  else
322  {
323  rect.combineExtentWith( it.value()->boundingBox() );
324  }
325  }
326  return rect;
327 }
328 
330 {
331  if ( mDataProvider )
332  mDataProvider->setTransformContext( context );
333 
334  mTransformContext = context;
336 }
337 
338 bool QgsAnnotationLayer::readXml( const QDomNode &layerNode, QgsReadWriteContext &context )
339 {
341  {
342  return false;
343  }
344 
345  qDeleteAll( mItems );
346  mItems.clear();
347  mSpatialIndex = std::make_unique< QgsAnnotationLayerSpatialIndex >();
348  mNonIndexedItems.clear();
349 
350  const QDomNodeList itemsElements = layerNode.toElement().elementsByTagName( QStringLiteral( "items" ) );
351  if ( itemsElements.size() == 0 )
352  return false;
353 
354  const QDomNodeList items = itemsElements.at( 0 ).childNodes();
355  for ( int i = 0; i < items.size(); ++i )
356  {
357  const QDomElement itemElement = items.at( i ).toElement();
358  const QString id = itemElement.attribute( QStringLiteral( "id" ) );
359  const QString type = itemElement.attribute( QStringLiteral( "type" ) );
360  std::unique_ptr< QgsAnnotationItem > item( QgsApplication::annotationItemRegistry()->createItem( type ) );
361  if ( item )
362  {
363  item->readXml( itemElement, context );
365  mNonIndexedItems.insert( id );
366  else
367  mSpatialIndex->insert( id, item->boundingBox() );
368  mItems.insert( id, item.release() );
369  }
370  }
371 
372  QString errorMsg;
373  readSymbology( layerNode, errorMsg, context );
374 
375  triggerRepaint();
376 
377  return mValid;
378 }
379 
380 bool QgsAnnotationLayer::writeXml( QDomNode &layer_node, QDomDocument &doc, const QgsReadWriteContext &context ) const
381 {
382  // first get the layer element so that we can append the type attribute
383  QDomElement mapLayerNode = layer_node.toElement();
384 
385  if ( mapLayerNode.isNull() )
386  {
387  QgsDebugMsgLevel( QStringLiteral( "can't find maplayer node" ), 2 );
388  return false;
389  }
390 
391  mapLayerNode.setAttribute( QStringLiteral( "type" ), QgsMapLayerFactory::typeToString( QgsMapLayerType::AnnotationLayer ) );
392 
393  QDomElement itemsElement = doc.createElement( QStringLiteral( "items" ) );
394  for ( auto it = mItems.constBegin(); it != mItems.constEnd(); ++it )
395  {
396  QDomElement itemElement = doc.createElement( QStringLiteral( "item" ) );
397  itemElement.setAttribute( QStringLiteral( "type" ), ( *it )->type() );
398  itemElement.setAttribute( QStringLiteral( "id" ), it.key() );
399  ( *it )->writeXml( itemElement, doc, context );
400  itemsElement.appendChild( itemElement );
401  }
402  mapLayerNode.appendChild( itemsElement );
403 
404  // renderer specific settings
405  QString errorMsg;
406  return writeSymbology( layer_node, doc, errorMsg, context );
407 }
408 
409 bool QgsAnnotationLayer::writeSymbology( QDomNode &node, QDomDocument &doc, QString &, const QgsReadWriteContext &, QgsMapLayer::StyleCategories categories ) const
410 {
411  // add the layer opacity
412  if ( categories.testFlag( Rendering ) )
413  {
414  QDomElement layerOpacityElem = doc.createElement( QStringLiteral( "layerOpacity" ) );
415  const QDomText layerOpacityText = doc.createTextNode( QString::number( opacity() ) );
416  layerOpacityElem.appendChild( layerOpacityText );
417  node.appendChild( layerOpacityElem );
418  }
419 
420  if ( categories.testFlag( Symbology ) )
421  {
422  // add the blend mode field
423  QDomElement blendModeElem = doc.createElement( QStringLiteral( "blendMode" ) );
424  const QDomText blendModeText = doc.createTextNode( QString::number( QgsPainting::getBlendModeEnum( blendMode() ) ) );
425  blendModeElem.appendChild( blendModeText );
426  node.appendChild( blendModeElem );
427 
428  QDomElement paintEffectElem = doc.createElement( QStringLiteral( "paintEffect" ) );
429  if ( mPaintEffect && !QgsPaintEffectRegistry::isDefaultStack( mPaintEffect.get() ) )
430  mPaintEffect->saveProperties( doc, paintEffectElem );
431  node.appendChild( paintEffectElem );
432  }
433 
434  return true;
435 }
436 
437 bool QgsAnnotationLayer::readSymbology( const QDomNode &node, QString &, QgsReadWriteContext &, QgsMapLayer::StyleCategories categories )
438 {
439  if ( categories.testFlag( Rendering ) )
440  {
441  const QDomNode layerOpacityNode = node.namedItem( QStringLiteral( "layerOpacity" ) );
442  if ( !layerOpacityNode.isNull() )
443  {
444  const QDomElement e = layerOpacityNode.toElement();
445  setOpacity( e.text().toDouble() );
446  }
447  }
448 
449  if ( categories.testFlag( Symbology ) )
450  {
451  // get and set the blend mode if it exists
452  const QDomNode blendModeNode = node.namedItem( QStringLiteral( "blendMode" ) );
453  if ( !blendModeNode.isNull() )
454  {
455  const QDomElement e = blendModeNode.toElement();
456  setBlendMode( QgsPainting::getCompositionMode( static_cast< QgsPainting::BlendMode >( e.text().toInt() ) ) );
457  }
458 
459  //restore layer effect
460  const QDomNode paintEffectNode = node.namedItem( QStringLiteral( "paintEffect" ) );
461  if ( !paintEffectNode.isNull() )
462  {
463  const QDomElement effectElem = paintEffectNode.firstChildElement( QStringLiteral( "effect" ) );
464  if ( !effectElem.isNull() )
465  {
466  setPaintEffect( QgsApplication::paintEffectRegistry()->createEffect( effectElem ) );
467  }
468  }
469  }
470 
471  return true;
472 }
473 
475 {
476  // annotation layers are always editable
477  return true;
478 }
479 
481 {
482  return true;
483 }
484 
486 {
487  return mDataProvider;
488 }
489 
491 {
492  return mDataProvider;
493 }
494 
496 {
497  QString metadata = QStringLiteral( "<html>\n<body>\n<h1>" ) + tr( "General" ) + QStringLiteral( "</h1>\n<hr>\n" ) + QStringLiteral( "<table class=\"list-view\">\n" );
498 
499  metadata += QStringLiteral( "<tr><td class=\"highlight\">" ) + tr( "Name" ) + QStringLiteral( "</td><td>" ) + name() + QStringLiteral( "</td></tr>\n" );
500 
501  // Extent
502  metadata += QStringLiteral( "<tr><td class=\"highlight\">" ) + tr( "Extent" ) + QStringLiteral( "</td><td>" ) + extent().toString() + QStringLiteral( "</td></tr>\n" );
503 
504  // item count
505  QLocale locale = QLocale();
506  locale.setNumberOptions( locale.numberOptions() &= ~QLocale::NumberOption::OmitGroupSeparator );
507  const int itemCount = mItems.size();
508  metadata += QStringLiteral( "<tr><td class=\"highlight\">" )
509  + tr( "Item count" ) + QStringLiteral( "</td><td>" )
510  + locale.toString( static_cast<qlonglong>( itemCount ) )
511  + QStringLiteral( "</td></tr>\n" );
512  metadata += QLatin1String( "</table>\n<br><br>" );
513 
514  // CRS
516 
517  // items section
518  metadata += QStringLiteral( "<h1>" ) + tr( "Items" ) + QStringLiteral( "</h1>\n<hr>\n" );
519 
520  metadata += QLatin1String( "<table width=\"100%\" class=\"tabular-view\">\n" );
521  metadata += QLatin1String( "<tr><th>" ) + tr( "Type" ) + QLatin1String( "</th><th>" ) + tr( "Count" ) + QLatin1String( "</th></tr>\n" );
522 
523  QMap< QString, int > itemCounts;
524  for ( auto it = mItems.constBegin(); it != mItems.constEnd(); ++it )
525  {
526  itemCounts[ it.value()->type() ]++;
527  }
528 
529  const QMap<QString, QString> itemTypes = QgsApplication::annotationItemRegistry()->itemTypes();
530  int i = 0;
531  for ( auto it = itemTypes.begin(); it != itemTypes.end(); ++it )
532  {
533  QString rowClass;
534  if ( i % 2 )
535  rowClass = QStringLiteral( "class=\"odd-row\"" );
536  metadata += QLatin1String( "<tr " ) + rowClass + QLatin1String( "><td>" ) + it.value() + QLatin1String( "</td><td>" ) + locale.toString( static_cast<qlonglong>( itemCounts.value( it.key() ) ) ) + QLatin1String( "</td></tr>\n" );
537  i++;
538  }
539 
540  metadata += QLatin1String( "</table>\n<br><br>" );
541 
542  metadata += QLatin1String( "\n</body>\n</html>\n" );
543  return metadata;
544 }
545 
547 {
548  return mPaintEffect.get();
549 }
550 
552 {
553  mPaintEffect.reset( effect );
554 }
555 
556 
557 //
558 // QgsAnnotationLayerDataProvider
559 //
561 QgsAnnotationLayerDataProvider::QgsAnnotationLayerDataProvider(
562  const ProviderOptions &options,
563  QgsDataProvider::ReadFlags flags )
564  : QgsDataProvider( QString(), options, flags )
565 {}
566 
568 {
570 }
571 
572 QString QgsAnnotationLayerDataProvider::name() const
573 {
574  return QStringLiteral( "annotation" );
575 }
576 
577 QString QgsAnnotationLayerDataProvider::description() const
578 {
579  return QString();
580 }
581 
582 QgsRectangle QgsAnnotationLayerDataProvider::extent() const
583 {
584  return QgsRectangle();
585 }
586 
587 bool QgsAnnotationLayerDataProvider::isValid() const
588 {
589  return true;
590 }
@ UsersCannotToggleEditing
Indicates that users are not allowed to toggle editing for this layer. Note that this does not imply ...
@ ScaleDependentBoundingBox
Item's bounding box will vary depending on map scale.
AnnotationItemEditOperationResult
Results from an edit operation on an annotation item.
Definition: qgis.h:814
@ Invalid
Operation has invalid parameters for the item, no change occurred.
@ Success
Item was modified successfully.
@ ItemCleared
The operation results in the item being cleared, and the item should be removed from the layer as a r...
Abstract base class for annotation item edit operations.
QString itemId() const
Returns the associated item ID.
QMap< QString, QString > itemTypes() const
Returns a map of available item types to translated name.
Abstract base class for annotation items which are drawn with QgsAnnotationLayers.
virtual QgsRectangle boundingBox() const =0
Returns the bounding box of the item's geographic location, in the parent layer's coordinate referenc...
virtual bool readXml(const QDomElement &element, const QgsReadWriteContext &context)=0
Reads the item's state from the given DOM element.
virtual Qgis::AnnotationItemFlags flags() const
Returns item flags.
Represents a map layer containing a set of georeferenced annotations, e.g.
QgsRectangle extent() const override
Returns the extent of the layer.
bool writeSymbology(QDomNode &node, QDomDocument &doc, QString &errorMessage, const QgsReadWriteContext &, StyleCategories categories=AllStyleCategories) const override
Write the style for the layer into the document provided.
bool readSymbology(const QDomNode &node, QString &errorMessage, QgsReadWriteContext &context, StyleCategories categories=AllStyleCategories) override
Read the symbology for the current layer from the DOM node supplied.
void clear()
Removes all items from the layer.
QgsDataProvider * dataProvider() override
Returns the layer's data provider, it may be nullptr.
QgsAnnotationItem * item(const QString &id)
Returns the item with the specified id, or nullptr if no matching item was found.
QgsMapLayerRenderer * createMapRenderer(QgsRenderContext &rendererContext) override
Returns new instance of QgsMapLayerRenderer that will be used for rendering of given context.
QMap< QString, QgsAnnotationItem * > items() const
Returns a map of items contained in the layer, by unique item ID.
bool isEditable() const override
Returns true if the layer can be edited.
bool removeItem(const QString &id)
Removes (and deletes) the item with matching id.
QStringList itemsInBounds(const QgsRectangle &bounds, QgsRenderContext &context, QgsFeedback *feedback=nullptr) const
Returns a list of the IDs of all annotation items within the specified bounds (in layer CRS),...
void setTransformContext(const QgsCoordinateTransformContext &context) override
Sets the coordinate transform context to transformContext.
Qgis::AnnotationItemEditOperationResult applyEdit(QgsAbstractAnnotationItemEditOperation *operation)
Applies an edit operation to the layer.
void setPaintEffect(QgsPaintEffect *effect)
Sets the current paint effect for the layer.
QgsPaintEffect * paintEffect() const
Returns the current paint effect for the layer.
void replaceItem(const QString &id, QgsAnnotationItem *item)
Replaces the existing item with matching id with a new item.
QgsAnnotationLayer * clone() const override
Returns a new instance equivalent to this one except for the id which is still unique.
friend class QgsAnnotationLayerRenderer
bool supportsEditing() const override
Returns whether the layer supports editing or not.
void reset()
Resets the annotation layer to a default state, and clears all items from it.
QString addItem(QgsAnnotationItem *item)
Adds an item to the layer.
QString htmlMetadata() const override
Obtain a formatted HTML string containing assorted metadata for this layer.
Qgis::MapLayerProperties properties() const override
Returns the map layer properties of this layer.
bool isEmpty() const
Returns true if the annotation layer is empty and contains no annotations.
bool writeXml(QDomNode &layer_node, QDomDocument &doc, const QgsReadWriteContext &context) const override
Called by writeLayerXML(), used by children to write state specific to them to project files.
bool readXml(const QDomNode &layerNode, QgsReadWriteContext &context) override
Called by readLayerXML(), used by children to read state specific to them from project files.
QgsAnnotationLayer(const QString &name, const QgsAnnotationLayer::LayerOptions &options)
Constructor for a new QgsAnnotationLayer with the specified layer name.
static QgsAnnotationItemRegistry * annotationItemRegistry()
Returns the application's annotation item registry, used for annotation item types.
static QgsPaintEffectRegistry * paintEffectRegistry()
Returns the application's paint effect registry, used for managing paint effects.
This class represents a coordinate reference system (CRS).
Contains information about the context in which a coordinate transform is executed.
Abstract base class for spatial data provider implementations.
virtual void setTransformContext(const QgsCoordinateTransformContext &transformContext)
Sets data coordinate transform context to transformContext.
Base class for feedback objects to be used for cancellation of something running in a worker thread.
Definition: qgsfeedback.h:45
bool isCanceled() const SIP_HOLDGIL
Tells whether the operation has been canceled already.
Definition: qgsfeedback.h:54
static QString typeToString(QgsMapLayerType type)
Converts a map layer type to a string value.
Base class for utility classes that encapsulate information necessary for rendering of map layers.
Base class for all map layer types.
Definition: qgsmaplayer.h:73
QString name
Definition: qgsmaplayer.h:76
void setBlendMode(QPainter::CompositionMode blendMode)
Set the blending mode used for rendering a layer.
QgsMapLayerType type
Definition: qgsmaplayer.h:80
void triggerRepaint(bool deferredUpdate=false)
Will advise the map canvas (and any other interested party) that this layer requires to be repainted.
QString crsHtmlMetadata() const
Returns a HTML fragment containing the layer's CRS metadata, for use in the htmlMetadata() method.
QgsLayerMetadata metadata
Definition: qgsmaplayer.h:78
QPainter::CompositionMode blendMode() const
Returns the current blending mode for a layer.
virtual void setOpacity(double opacity)
Sets the opacity for the layer, where opacity is a value between 0 (totally transparent) and 1....
virtual QgsMapLayer * clone() const =0
Returns a new instance equivalent to this one except for the id which is still unique.
void willBeDeleted()
Emitted in the destructor when the layer is about to be deleted, but it is still in a perfectly valid...
@ FlagDontResolveLayers
Don't resolve layer paths or create data providers for layers.
Definition: qgsmaplayer.h:637
QgsMapLayer::ReadFlags mReadFlags
Read flags. It's up to the subclass to respect these when restoring state from XML.
Definition: qgsmaplayer.h:1971
double opacity
Definition: qgsmaplayer.h:82
bool mValid
Indicates if the layer is valid and can be drawn.
Definition: qgsmaplayer.h:1922
@ Symbology
Symbology.
Definition: qgsmaplayer.h:158
@ Rendering
Rendering: scale visibility, simplify method, opacity.
Definition: qgsmaplayer.h:167
void invalidateWgs84Extent()
Invalidates the WGS84 extent.
bool mShouldValidateCrs
true if the layer's CRS should be validated and invalid CRSes are not permitted.
Definition: qgsmaplayer.h:1978
void setCrs(const QgsCoordinateReferenceSystem &srs, bool emitSignal=true)
Sets layer's spatial reference system.
static QgsPaintEffect * defaultStack()
Returns a new effect stack consisting of a sensible selection of default effects.
static bool isDefaultStack(QgsPaintEffect *effect)
Tests whether a paint effect matches the default effects stack.
Base class for visual effects which can be applied to QPicture drawings.
static QgsPainting::BlendMode getBlendModeEnum(QPainter::CompositionMode blendMode)
Returns a BlendMode corresponding to a QPainter::CompositionMode.
Definition: qgspainting.cpp:80
static QPainter::CompositionMode getCompositionMode(QgsPainting::BlendMode blendMode)
Returns a QPainter::CompositionMode corresponding to a BlendMode.
Definition: qgspainting.cpp:20
BlendMode
Blending modes enum defining the available composition modes that can be used when rendering a layer.
Definition: qgspainting.h:37
The class is used as a container of context for various read/write operations on other objects.
A rectangle specified with double values.
Definition: qgsrectangle.h:42
QString toString(int precision=16) const
Returns a string representation of form xmin,ymin : xmax,ymax Coordinates will be truncated to the sp...
double yMaximum() const SIP_HOLDGIL
Returns the y maximum value (top side of rectangle).
Definition: qgsrectangle.h:193
double xMaximum() const SIP_HOLDGIL
Returns the x maximum value (right side of rectangle).
Definition: qgsrectangle.h:183
double xMinimum() const SIP_HOLDGIL
Returns the x minimum value (left side of rectangle).
Definition: qgsrectangle.h:188
double yMinimum() const SIP_HOLDGIL
Returns the y minimum value (bottom side of rectangle).
Definition: qgsrectangle.h:198
bool isNull() const
Test if the rectangle is null (all coordinates zero or after call to setMinimal()).
Definition: qgsrectangle.h:479
void combineExtentWith(const QgsRectangle &rect)
Expands the rectangle so that it covers both the original rectangle and the given rectangle.
Definition: qgsrectangle.h:391
Contains information about the context of a rendering operation.
QgsMapLayerType
Types of layers that can be added to a map.
Definition: qgis.h:47
@ AnnotationLayer
Contains freeform, georeferenced annotations. Added in QGIS 3.16.
#define QgsDebugMsgLevel(str, level)
Definition: qgslogger.h:39
const QgsCoordinateReferenceSystem & crs
Setting options for loading annotation layers.
QgsCoordinateTransformContext transformContext
Coordinate transform context.
Setting options for creating vector data providers.
QgsCoordinateTransformContext transformContext
Coordinate transform context.