QGIS API Documentation 3.99.0-Master (21b3aa880ba)
Loading...
Searching...
No Matches
qgsmapsettings.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgsmapsettings.cpp
3 --------------------------------------
4 Date : December 2013
5 Copyright : (C) 2013 by Martin Dobias
6 Email : wonder dot sk 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 "qgsmapsettings.h"
17
19#include "qgsellipsoidutils.h"
20#include "qgsexception.h"
21#include "qgsgeometry.h"
22#include "qgsgrouplayer.h"
23#include "qgslogger.h"
24#include "qgsmaplayer.h"
26#include "qgsmaptopixel.h"
27#include "qgsmessagelog.h"
28#include "qgspainting.h"
29#include "qgsscalecalculator.h"
30#include "qgsunittypes.h"
31#include "qgsxmlutils.h"
32
34 : mDpi( QgsPainting::qtDefaultDpiX() ) // DPI that will be used by default for QImage instances
35 , mSize( QSize( 0, 0 ) )
36 , mBackgroundColor( Qt::white )
37 , mSelectionColor( Qt::yellow )
38 , mFlags( Qgis::MapSettingsFlag::Antialiasing | Qgis::MapSettingsFlag::UseAdvancedEffects | Qgis::MapSettingsFlag::DrawLabeling | Qgis::MapSettingsFlag::DrawSelection )
39 , mSegmentationTolerance( M_PI_2 / 90 )
40{
43
45}
46
47void QgsMapSettings::setMagnificationFactor( double factor, const QgsPointXY *center )
48{
49 const double ratio = mMagnificationFactor / factor;
50
51 mMagnificationFactor = factor;
52
53 const double rot = rotation();
54 setRotation( 0.0 );
55
57 ext.scale( ratio, center );
58
59 mRotation = rot;
60 mExtent = ext;
61 mDpi = mDpi / ratio;
62
63 QgsDebugMsgLevel( QStringLiteral( "Magnification factor: %1 dpi: %2 ratio: %3" ).arg( factor ).arg( mDpi ).arg( ratio ), 3 );
64
66}
67
72
74{
75 return mExtent;
76}
77
78void QgsMapSettings::setExtent( const QgsRectangle &extent, bool magnified )
79{
80 QgsRectangle magnifiedExtent = extent;
81
82 if ( !magnified )
83 magnifiedExtent.scale( 1 / mMagnificationFactor );
84
85 mExtent = magnifiedExtent;
86
88}
89
91{
92 return mExtentBuffer;
93}
94
95void QgsMapSettings::setExtentBuffer( const double buffer )
96{
97 mExtentBuffer = buffer;
98}
99
101{
102 return mRotation;
103}
104
105void QgsMapSettings::setRotation( double degrees )
106{
107 if ( qgsDoubleNear( mRotation, degrees ) )
108 return;
109
110 mRotation = degrees;
111
112 // TODO: update extent while keeping scale ?
114}
115
116
118{
120
121 if ( extent.isEmpty() || !extent.isFinite() )
122 {
123 mValid = false;
124 return;
125 }
126
127 // Don't allow zooms where the current extent is so small that it
128 // can't be accurately represented using a double (which is what
129 // currentExtent uses). Excluding 0 avoids a divide by zero and an
130 // infinite loop when rendering to a new canvas. Excluding extents
131 // greater than 1 avoids doing unnecessary calculations.
132
133 // The scheme is to compare the width against the mean x coordinate
134 // (and height against mean y coordinate) and only allow zooms where
135 // the ratio indicates that there is more than about 12 significant
136 // figures (there are about 16 significant figures in a double).
137
138 if ( extent.width() > 0 &&
139 extent.height() > 0 &&
140 extent.width() < 1 &&
141 extent.height() < 1 )
142 {
143 // Use abs() on the extent to avoid the case where the extent is
144 // symmetrical about 0.
145 const double xMean = ( std::fabs( extent.xMinimum() ) + std::fabs( extent.xMaximum() ) ) * 0.5;
146 const double yMean = ( std::fabs( extent.yMinimum() ) + std::fabs( extent.yMaximum() ) ) * 0.5;
147
148 const double xRange = extent.width() / xMean;
149 const double yRange = extent.height() / yMean;
150
151 static const double MIN_PROPORTION = 1e-12;
152 if ( xRange < MIN_PROPORTION || yRange < MIN_PROPORTION )
153 {
154 mValid = false;
155 return;
156 }
157 }
158
159 const double myHeight = mSize.height();
160 const double myWidth = mSize.width();
161
162 if ( !myWidth || !myHeight )
163 {
164 mValid = false;
165 return;
166 }
167
168 // calculate the translation and scaling parameters
169 const double mapUnitsPerPixelY = mExtent.height() / myHeight;
170 const double mapUnitsPerPixelX = mExtent.width() / myWidth;
171 mMapUnitsPerPixel = mapUnitsPerPixelY > mapUnitsPerPixelX ? mapUnitsPerPixelY : mapUnitsPerPixelX;
172
173 // calculate the actual extent of the mapCanvas
174 double dxmin = mExtent.xMinimum(), dxmax = mExtent.xMaximum(),
175 dymin = mExtent.yMinimum(), dymax = mExtent.yMaximum(), whitespace;
176
177 if ( mapUnitsPerPixelY > mapUnitsPerPixelX )
178 {
179 whitespace = ( ( myWidth * mMapUnitsPerPixel ) - mExtent.width() ) * 0.5;
180 dxmin -= whitespace;
181 dxmax += whitespace;
182 }
183 else
184 {
185 whitespace = ( ( myHeight * mMapUnitsPerPixel ) - mExtent.height() ) * 0.5;
186 dymin -= whitespace;
187 dymax += whitespace;
188 }
189
190 mVisibleExtent.set( dxmin, dymin, dxmax, dymax );
191
192 // update the scale
193 mScaleCalculator.setDpi( mDpi );
194 mScale = mScaleCalculator.calculate( mVisibleExtent, mSize.width() );
195
196 bool ok = true;
197 mMapToPixel.setParameters(
199 visibleExtent().center().x(),
200 visibleExtent().center().y(),
201 outputSize().width(),
202 outputSize().height(),
203 mRotation, &ok );
204
205 mValid = ok;
206
207#if 1 // set visible extent taking rotation in consideration
208 if ( mRotation )
209 {
210 const QgsPointXY p1 = mMapToPixel.toMapCoordinates( QPoint( 0, 0 ) );
211 const QgsPointXY p2 = mMapToPixel.toMapCoordinates( QPoint( 0, myHeight ) );
212 const QgsPointXY p3 = mMapToPixel.toMapCoordinates( QPoint( myWidth, 0 ) );
213 const QgsPointXY p4 = mMapToPixel.toMapCoordinates( QPoint( myWidth, myHeight ) );
214 dxmin = std::min( p1.x(), std::min( p2.x(), std::min( p3.x(), p4.x() ) ) );
215 dymin = std::min( p1.y(), std::min( p2.y(), std::min( p3.y(), p4.y() ) ) );
216 dxmax = std::max( p1.x(), std::max( p2.x(), std::max( p3.x(), p4.x() ) ) );
217 dymax = std::max( p1.y(), std::max( p2.y(), std::max( p3.y(), p4.y() ) ) );
218 mVisibleExtent.set( dxmin, dymin, dxmax, dymax );
219 }
220#endif
221
222 QgsDebugMsgLevel( QStringLiteral( "Map units per pixel (x,y) : %1, %2" ).arg( qgsDoubleToString( mapUnitsPerPixelX ), qgsDoubleToString( mapUnitsPerPixelY ) ), 5 );
223 QgsDebugMsgLevel( QStringLiteral( "Pixmap dimensions (x,y) : %1, %2" ).arg( qgsDoubleToString( mSize.width() ), qgsDoubleToString( mSize.height() ) ), 5 );
224 QgsDebugMsgLevel( QStringLiteral( "Extent dimensions (x,y) : %1, %2" ).arg( qgsDoubleToString( mExtent.width() ), qgsDoubleToString( mExtent.height() ) ), 5 );
225 QgsDebugMsgLevel( mExtent.toString(), 5 );
226 QgsDebugMsgLevel( QStringLiteral( "Adjusted map units per pixel (x,y) : %1, %2" ).arg( qgsDoubleToString( mVisibleExtent.width() / myWidth ), qgsDoubleToString( mVisibleExtent.height() / myHeight ) ), 5 );
227 QgsDebugMsgLevel( QStringLiteral( "Recalced pixmap dimensions (x,y) : %1, %2" ).arg( qgsDoubleToString( mVisibleExtent.width() / mMapUnitsPerPixel ), qgsDoubleToString( mVisibleExtent.height() / mMapUnitsPerPixel ) ), 5 );
228 QgsDebugMsgLevel( QStringLiteral( "Scale (assuming meters as map units) = 1:%1" ).arg( qgsDoubleToString( mScale ) ), 5 );
229 QgsDebugMsgLevel( QStringLiteral( "Rotation: %1 degrees" ).arg( mRotation ), 5 );
230 QgsDebugMsgLevel( QStringLiteral( "Extent: %1" ).arg( mExtent.asWktCoordinates() ), 5 );
231 QgsDebugMsgLevel( QStringLiteral( "Visible Extent: %1" ).arg( mVisibleExtent.asWktCoordinates() ), 5 );
232 QgsDebugMsgLevel( QStringLiteral( "Magnification factor: %1" ).arg( mMagnificationFactor ), 5 );
233
234}
235
236void QgsMapSettings::matchRasterizedRenderingPolicyToFlags()
237{
247}
248
250{
251 return mSize;
252}
253
255{
256 mSize = size;
257
259}
260
262{
263 return mDevicePixelRatio;
264}
265
267{
268 mDevicePixelRatio = dpr;
270}
271
273{
274 return outputSize() * mDevicePixelRatio;
275}
276
278{
279 return mDpi;
280}
281
283{
284 mDpi = dpi;
285
287}
288
290{
291 return mDpiTarget;
292}
293
295{
296 mDpiTarget = dpi;
297}
298
299QStringList QgsMapSettings::layerIds( bool expandGroupLayers ) const
300{
301 if ( !expandGroupLayers || !mHasGroupLayers )
302 {
303 return mLayerIds;
304 }
305 else
306 {
307 const QList<QgsMapLayer * > mapLayers = layers( expandGroupLayers );
308 QStringList res;
309 res.reserve( mapLayers.size() );
310 for ( const QgsMapLayer *layer : mapLayers )
311 res << layer->id();
312 return res;
313 }
314}
315
316QList<QgsMapLayer *> QgsMapSettings::layers( bool expandGroupLayers ) const
317{
318 const QList<QgsMapLayer *> actualLayers = _qgis_listQPointerToRaw( mLayers );
319 if ( !expandGroupLayers )
320 return actualLayers;
321
322 QList< QgsMapLayer * > result;
323
324 std::function< void( const QList< QgsMapLayer * >& layers ) > expandLayers;
325 expandLayers = [&result, &expandLayers]( const QList< QgsMapLayer * > &layers )
326 {
327 for ( QgsMapLayer *layer : layers )
328 {
329 if ( QgsGroupLayer *groupLayer = qobject_cast< QgsGroupLayer * >( layer ) )
330 {
331 expandLayers( groupLayer->childLayers() );
332 }
333 else
334 {
335 result << layer;
336 }
337 }
338 };
339
340 expandLayers( actualLayers );
341 return result;
342}
343
344template<typename T>
345QVector<T> QgsMapSettings::layers() const
346{
347 const QList<QgsMapLayer *> actualLayers = _qgis_listQPointerToRaw( mLayers );
348
349 QVector<T> layers;
350 for ( QgsMapLayer *layer : actualLayers )
351 {
352 T tLayer = qobject_cast<T>( layer );
353 if ( tLayer )
354 {
355 layers << tLayer;
356 }
357 }
358 return layers;
359}
360
361void QgsMapSettings::setLayers( const QList<QgsMapLayer *> &layers )
362{
363 // filter list, removing null layers and non-spatial layers
364 auto filteredList = layers;
365 filteredList.erase( std::remove_if( filteredList.begin(), filteredList.end(),
366 []( QgsMapLayer * layer )
367 {
368 return !layer || !layer->isSpatial();
369 } ), filteredList.end() );
370
371 mLayers = _qgis_listRawToQPointer( filteredList );
372
373 // pre-generate and store layer IDs, so that we can safely access them from other threads
374 // without needing to touch the actual map layer object
375 mLayerIds.clear();
376 mHasGroupLayers = false;
377 mLayerIds.reserve( mLayers.size() );
378 for ( const QgsMapLayer *layer : std::as_const( mLayers ) )
379 {
380 mLayerIds << layer->id();
381 if ( layer->type() == Qgis::LayerType::Group )
382 mHasGroupLayers = true;
383 }
384}
385
386QMap<QString, QString> QgsMapSettings::layerStyleOverrides() const
387{
389}
390
391void QgsMapSettings::setLayerStyleOverrides( const QMap<QString, QString> &overrides )
392{
393 mLayerStyleOverrides = overrides;
394}
395
397{
398 mDestCRS = crs;
399 mScaleCalculator.setMapUnits( crs.mapUnits() );
400 // Since the map units have changed, force a recalculation of the scale.
402}
403
408
410{
412 if ( !params.valid )
413 {
414 return false;
415 }
416 else
417 {
419 return true;
420 }
421}
422
424{
425 mFlags = flags;
426 matchRasterizedRenderingPolicyToFlags();
427}
428
430{
431 if ( on )
432 mFlags |= flag;
433 else
434 mFlags &= ~( static_cast< int >( flag ) );
435 matchRasterizedRenderingPolicyToFlags();
436}
437
442
444{
445 return mFlags.testFlag( flag );
446}
447
449{
450 return mScaleCalculator.mapUnits();
451}
452
457
459{
460 mScaleCalculator.setMethod( method );
462}
463
465{
466 return mValid;
467}
468
473
475{
476 QPolygonF poly;
477
478 const QSize &sz = outputSize();
479 const QgsMapToPixel &m2p = mapToPixel();
480
481 poly << m2p.toMapCoordinates( 0.0, 0.0 ).toQPointF();
482 poly << m2p.toMapCoordinates( static_cast<double>( sz.width() ), 0.0 ).toQPointF();
483 poly << m2p.toMapCoordinates( static_cast<double>( sz.width() ), static_cast<double>( sz.height() ) ).toQPointF();
484 poly << m2p.toMapCoordinates( 0.0, static_cast<double>( sz.height() ) ).toQPointF();
485
486 return poly;
487}
488
490{
491 QPolygonF poly;
492
493 const QSize &sz = outputSize();
494 const QgsMapToPixel &m2p = mapToPixel();
495
496 // Transform tilebuffer in pixel.
497 // Original tilebuffer is in pixel and transformed only according
498 // extent width (see QgsWmsRenderContext::mapTileBuffer)
499
500 const double mapUnitsPerPixel = mExtent.width() / sz.width();
501 const double buffer = mExtentBuffer / mapUnitsPerPixel;
502
503 poly << m2p.toMapCoordinates( -buffer, -buffer ).toQPointF();
504 poly << m2p.toMapCoordinates( static_cast<double>( sz.width() + buffer ), -buffer ).toQPointF();
505 poly << m2p.toMapCoordinates( static_cast<double>( sz.width() + buffer ), static_cast<double>( sz.height() + buffer ) ).toQPointF();
506 poly << m2p.toMapCoordinates( -buffer, static_cast<double>( sz.height() + buffer ) ).toQPointF();
507
508 return poly;
509}
510
512{
513 return mMapUnitsPerPixel;
514}
515
517{
518 return mScale;
519}
520
522{
523#ifdef QGISDEBUG
524 if ( !mHasTransformContext )
525 QgsDebugMsgLevel( QStringLiteral( "No QgsCoordinateTransformContext context set for transform" ), 4 );
526#endif
527
528 return mTransformContext;
529}
530
532{
533 mTransformContext = context;
534#ifdef QGISDEBUG
535 mHasTransformContext = true;
536#endif
537}
538
540{
541 if ( !layer )
542 return QgsCoordinateTransform();
543
545}
546
548{
549 // Output width in inches
550 const double outputWidthInInches = outputSize().width() / outputDpi();
551
552 // Desired visible width (honouring scale)
553 const double scaledWidthInInches = outputWidthInInches * scale;
554
556 {
557 // Start with some fraction of the current extent around the center
558 const double delta = mExtent.width() / 100.;
559 QgsRectangle ext( center.x() - delta, center.y() - delta, center.x() + delta, center.y() + delta );
560 // Get scale at extent, and then scale extent to the desired scale
561 const double testScale = mScaleCalculator.calculate( ext, outputSize().width() );
562 ext.scale( scale / testScale );
563 return ext;
564 }
565 else
566 {
567 // Conversion from inches to mapUnits - this is safe to use, because we know here that the map units AREN'T in degrees
568 const double conversionFactor = QgsUnitTypes::fromUnitToUnitFactor( Qgis::DistanceUnit::Feet, mapUnits() ) / 12;
569
570 const double delta = 0.5 * scaledWidthInInches * conversionFactor;
571 return QgsRectangle( center.x() - delta, center.y() - delta, center.x() + delta, center.y() + delta );
572 }
573}
574
576{
577 return mScaleCalculator.calculate( extent, outputSize().width() );
578}
579
580double QgsMapSettings::layerToMapUnits( const QgsMapLayer *layer, const QgsRectangle &referenceExtent ) const
581{
582 return layerTransform( layer ).scaleFactor( referenceExtent );
583}
584
585
587{
588 try
589 {
591 if ( ct.isValid() )
592 {
593 QgsDebugMsgLevel( QStringLiteral( "sourceCrs = %1" ).arg( ct.sourceCrs().authid() ), 3 );
594 QgsDebugMsgLevel( QStringLiteral( "destCRS = %1" ).arg( ct.destinationCrs().authid() ), 3 );
595 QgsDebugMsgLevel( QStringLiteral( "extent %1" ).arg( extent.toString() ), 3 );
598 }
599 }
600 catch ( QgsCsException &cse )
601 {
602 QgsMessageLog::logMessage( QObject::tr( "Transform error caught: %1" ).arg( cse.what() ), QObject::tr( "CRS" ) );
603 }
604
605 QgsDebugMsgLevel( QStringLiteral( "proj extent = %1 " ).arg( extent.toString() ), 3 );
606
607 return extent;
608}
609
610
612{
613 try
614 {
617 if ( ct.isValid() )
618 {
619 QgsDebugMsgLevel( QStringLiteral( "sourceCrs = %1" ).arg( ct.sourceCrs().authid() ), 3 );
620 QgsDebugMsgLevel( QStringLiteral( "destCRS = %1" ).arg( ct.destinationCrs().authid() ), 3 );
621 QgsDebugMsgLevel( QStringLiteral( "extent = %1" ).arg( extent.toString() ), 3 );
623 }
624 }
625 catch ( QgsCsException &cse )
626 {
627 QgsMessageLog::logMessage( QObject::tr( "Transform error caught: %1" ).arg( cse.what() ), QObject::tr( "CRS" ) );
628 }
629
630 QgsDebugMsgLevel( QStringLiteral( "proj extent = %1" ).arg( extent.toString() ), 3 );
631
632 return extent;
633}
634
635
637{
638 try
639 {
640 const QgsCoordinateTransform ct = layerTransform( layer );
641 if ( ct.isValid() )
642 point = ct.transform( point, Qgis::TransformDirection::Forward );
643 }
644 catch ( QgsCsException &cse )
645 {
646 QgsMessageLog::logMessage( QObject::tr( "Transform error caught: %1" ).arg( cse.what() ), QObject::tr( "CRS" ) );
647 }
648
649 return point;
650}
651
653{
654 double x = point.x();
655 double y = point.y();
656 double z = point.z();
657 const double m = point.m();
658
659 try
660 {
661 const QgsCoordinateTransform ct = layerTransform( layer );
662 if ( ct.isValid() )
664 }
665 catch ( QgsCsException &cse )
666 {
667 QgsMessageLog::logMessage( QObject::tr( "Transform error caught: %1" ).arg( cse.what() ), QObject::tr( "CRS" ) );
668 }
669
670 return QgsPoint( x, y, z, m );
671}
672
673
675{
676 try
677 {
678 const QgsCoordinateTransform ct = layerTransform( layer );
679 if ( ct.isValid() )
681 }
682 catch ( QgsCsException &cse )
683 {
684 QgsMessageLog::logMessage( QObject::tr( "Transform error caught: %1" ).arg( cse.what() ), QObject::tr( "CRS" ) );
685 }
686
687 return rect;
688}
689
690
692{
693 try
694 {
695 const QgsCoordinateTransform ct = layerTransform( layer );
696 if ( ct.isValid() )
697 point = ct.transform( point, Qgis::TransformDirection::Reverse );
698 }
699 catch ( QgsCsException &cse )
700 {
701 QgsMessageLog::logMessage( QObject::tr( "Transform error caught: %1" ).arg( cse.what() ), QObject::tr( "CRS" ) );
702 }
703
704 return point;
705}
706
708{
709 double x = point.x();
710 double y = point.y();
711 double z = point.z();
712 const double m = point.m();
713
714 try
715 {
716 const QgsCoordinateTransform ct = layerTransform( layer );
717 if ( ct.isValid() )
719 }
720 catch ( QgsCsException &cse )
721 {
722 QgsMessageLog::logMessage( QObject::tr( "Transform error caught: %1" ).arg( cse.what() ), QObject::tr( "CRS" ) );
723 }
724
725 return QgsPoint( x, y, z, m );
726}
727
728
730{
731 try
732 {
733 const QgsCoordinateTransform ct = layerTransform( layer );
734 if ( ct.isValid() )
736 }
737 catch ( QgsCsException &cse )
738 {
739 QgsMessageLog::logMessage( QObject::tr( "Transform error caught: %1" ).arg( cse.what() ), QObject::tr( "CRS" ) );
740 }
741
742 return rect;
743}
744
745
746
748{
749 // reset the map canvas extent since the extent may now be smaller
750 // We can't use a constructor since QgsRectangle normalizes the rectangle upon construction
752 fullExtent.setNull();
753
754 // iterate through the map layers and test each layers extent
755 // against the current min and max values
756 QgsDebugMsgLevel( QStringLiteral( "Layer count: %1" ).arg( mLayers.count() ), 5 );
757 const auto constMLayers = mLayers;
758 for ( const QgsWeakMapLayerPointer &layerPtr : constMLayers )
759 {
760 if ( QgsMapLayer *lyr = layerPtr.data() )
761 {
762 QgsDebugMsgLevel( "Updating extent using " + lyr->name(), 5 );
763 QgsDebugMsgLevel( "Input extent: " + lyr->extent().toString(), 5 );
764
765 if ( lyr->extent().isNull() )
766 continue;
767
768 // Layer extents are stored in the coordinate system (CS) of the
769 // layer. The extent must be projected to the canvas CS
770 const QgsRectangle extent = layerExtentToOutputExtent( lyr, lyr->extent() );
771
772 QgsDebugMsgLevel( "Output extent: " + extent.toString(), 5 );
773 fullExtent.combineExtentWith( extent );
774 }
775 }
776
777 if ( fullExtent.width() == 0.0 || fullExtent.height() == 0.0 )
778 {
779 // If all of the features are at the one point, buffer the
780 // rectangle a bit. If they are all at zero, do something a bit
781 // more crude.
782
783 if ( fullExtent.xMinimum() == 0.0 && fullExtent.xMaximum() == 0.0 &&
784 fullExtent.yMinimum() == 0.0 && fullExtent.yMaximum() == 0.0 )
785 {
786 fullExtent.set( -1.0, -1.0, 1.0, 1.0 );
787 }
788 else
789 {
790 const double padFactor = 1e-8;
791 const double widthPad = fullExtent.xMinimum() * padFactor;
792 const double heightPad = fullExtent.yMinimum() * padFactor;
793 const double xmin = fullExtent.xMinimum() - widthPad;
794 const double xmax = fullExtent.xMaximum() + widthPad;
795 const double ymin = fullExtent.yMinimum() - heightPad;
796 const double ymax = fullExtent.yMaximum() + heightPad;
797 fullExtent.set( xmin, ymin, xmax, ymax );
798 }
799 }
800
801 QgsDebugMsgLevel( "Full extent: " + fullExtent.toString(), 5 );
802 return fullExtent;
803}
804
805
806void QgsMapSettings::readXml( QDomNode &node )
807{
808 // set destination CRS
810 const QDomNode srsNode = node.namedItem( QStringLiteral( "destinationsrs" ) );
811 if ( !srsNode.isNull() )
812 {
813 srs.readXml( srsNode );
814 }
815 setDestinationCrs( srs );
816
817 // set extent
818 const QDomNode extentNode = node.namedItem( QStringLiteral( "extent" ) );
819 const QgsRectangle aoi = QgsXmlUtils::readRectangle( extentNode.toElement() );
820 setExtent( aoi );
821
822 // set rotation
823 const QDomNode rotationNode = node.namedItem( QStringLiteral( "rotation" ) );
824 const QString rotationVal = rotationNode.toElement().text();
825 if ( ! rotationVal.isEmpty() )
826 {
827 const double rot = rotationVal.toDouble();
828 setRotation( rot );
829 }
830
831 //render map tile
832 const QDomElement renderMapTileElem = node.firstChildElement( QStringLiteral( "rendermaptile" ) );
833 if ( !renderMapTileElem.isNull() )
834 {
835 setFlag( Qgis::MapSettingsFlag::RenderMapTile, renderMapTileElem.text() == QLatin1String( "1" ) );
836 }
837}
838
839
840
841void QgsMapSettings::writeXml( QDomNode &node, QDomDocument &doc )
842{
843 // units
844 node.appendChild( QgsXmlUtils::writeMapUnits( mapUnits(), doc ) );
845
846 // Write current view extents
847 node.appendChild( QgsXmlUtils::writeRectangle( extent(), doc ) );
848
849 // Write current view rotation
850 QDomElement rotNode = doc.createElement( QStringLiteral( "rotation" ) );
851 rotNode.appendChild(
852 doc.createTextNode( qgsDoubleToString( rotation() ) )
853 );
854 node.appendChild( rotNode );
855
856 // destination CRS
857 if ( mDestCRS.isValid() )
858 {
859 QDomElement srsNode = doc.createElement( QStringLiteral( "destinationsrs" ) );
860 node.appendChild( srsNode );
861 mDestCRS.writeXml( srsNode, doc );
862 }
863
864 //render map tile
865 QDomElement renderMapTileElem = doc.createElement( QStringLiteral( "rendermaptile" ) );
866 const QDomText renderMapTileText = doc.createTextNode( testFlag( Qgis::MapSettingsFlag::RenderMapTile ) ? "1" : "0" );
867 renderMapTileElem.appendChild( renderMapTileText );
868 node.appendChild( renderMapTileElem );
869}
870
875
877{
878 mLabelBoundaryGeometry = boundary;
879}
880
882{
883 mClippingRegions.append( region );
884}
885
886void QgsMapSettings::setClippingRegions( const QList<QgsMapClippingRegion> &regions )
887{
888 mClippingRegions = regions;
889}
890
891QList<QgsMapClippingRegion> QgsMapSettings::clippingRegions() const
892{
893 return mClippingRegions;
894}
895
897{
898 mMaskRenderSettings = settings;
899}
900
902{
903 mRenderedFeatureHandlers.append( handler );
904}
905
906QList<QgsRenderedFeatureHandlerInterface *> QgsMapSettings::renderedFeatureHandlers() const
907{
908 return mRenderedFeatureHandlers;
909}
910
912{
913 return mZRange;
914}
915
917{
918 mZRange = zRange;
919}
920
925
930
932{
933 return mFrameRate;
934}
935
937{
938 mFrameRate = rate;
939}
940
942{
943 return mCurrentFrame;
944}
945
946void QgsMapSettings::setCurrentFrame( long long frame )
947{
948 mCurrentFrame = frame;
949}
950
955
960
965
985
Provides global constants and enumerations for use throughout the application.
Definition qgis.h:56
RasterizedRenderingPolicy
Policies controlling when rasterisation of content during renders is permitted.
Definition qgis.h:2703
@ Default
Allow raster-based rendering in situations where it is required for correct rendering or where it wil...
Definition qgis.h:2704
@ PreferVector
Prefer vector-based rendering, when the result will still be visually near-identical to a raster-base...
Definition qgis.h:2705
@ ForceVector
Always force vector-based rendering, even when the result will be visually different to a raster-base...
Definition qgis.h:2706
QFlags< MapSettingsFlag > MapSettingsFlags
Map settings flags.
Definition qgis.h:2738
@ NoSimplification
No simplification can be applied.
Definition qgis.h:3030
DistanceUnit
Units of distance.
Definition qgis.h:5013
@ Feet
Imperial feet.
Definition qgis.h:5016
@ Unknown
Unknown distance unit.
Definition qgis.h:5063
@ Degrees
Degrees, for planar geographic CRS distance measurements.
Definition qgis.h:5020
@ Group
Composite group layer. Added in QGIS 3.24.
Definition qgis.h:198
ScaleCalculationMethod
Scale calculation logic.
Definition qgis.h:5285
RendererUsage
Usage of the renderer.
Definition qgis.h:3445
@ Forward
Forward transform (from source to destination).
Definition qgis.h:2672
@ Reverse
Reverse/inverse transform (from destination to source).
Definition qgis.h:2673
MapSettingsFlag
Flags which adjust the way maps are rendered.
Definition qgis.h:2716
@ RenderMapTile
Draw map such that there are no problems between adjacent tiles.
Definition qgis.h:2725
@ ForceVectorOutput
Vector graphics should not be cached and drawn as raster images.
Definition qgis.h:2719
@ UseAdvancedEffects
Enable layer opacity and blending effects.
Definition qgis.h:2720
Represents a coordinate reference system (CRS).
bool readXml(const QDomNode &node)
Restores state from the given DOM node.
Contains information about the context in which a coordinate transform is executed.
Handles coordinate transforms between two coordinate systems.
QgsCoordinateReferenceSystem sourceCrs() const
Returns the source coordinate reference system, which the transform will transform coordinates from.
void setBallparkTransformsAreAppropriate(bool appropriate)
Sets whether approximate "ballpark" results are appropriate for this coordinate transform.
double scaleFactor(const QgsRectangle &referenceExtent) const
Computes an estimated conversion factor between source and destination units:
QgsPointXY transform(const QgsPointXY &point, Qgis::TransformDirection direction=Qgis::TransformDirection::Forward) const
Transform the point from the source CRS to the destination CRS.
void transformInPlace(double &x, double &y, double &z, Qgis::TransformDirection direction=Qgis::TransformDirection::Forward) const
Transforms an array of x, y and z double coordinates in place, from the source CRS to the destination...
QgsRectangle transformBoundingBox(const QgsRectangle &rectangle, Qgis::TransformDirection direction=Qgis::TransformDirection::Forward, bool handle180Crossover=false) const
Transforms a rectangle from the source CRS to the destination CRS.
bool isValid() const
Returns true if the coordinate transform is valid, ie both the source and destination CRS have been s...
QgsCoordinateReferenceSystem destinationCrs() const
Returns the destination coordinate reference system, which the transform will transform coordinates t...
Custom exception class for Coordinate Reference System related exceptions.
QgsRange which stores a range of double values.
Definition qgsrange.h:233
Renders elevation shading on an image with different methods (eye dome lighting, hillshading,...
static EllipsoidParameters ellipsoidParameters(const QString &ellipsoid)
Returns the parameters for the specified ellipsoid.
QString what() const
A geometry is the spatial representation of a feature.
A map layer which consists of a set of child layers, where all component layers are rendered as a sin...
A map clipping region (in map coordinates and CRS).
Base class for all map layer types.
Definition qgsmaplayer.h:80
QgsCoordinateReferenceSystem crs
Definition qgsmaplayer.h:87
QString id
Definition qgsmaplayer.h:83
Qgis::LayerType type
Definition qgsmaplayer.h:90
void setElevationShadingRenderer(const QgsElevationShadingRenderer &renderer)
Sets the shading renderer used to render shading on the entire map.
QSize deviceOutputSize() const
Returns the device output size of the map render.
Qgis::DistanceUnit mapUnits() const
Returns the units of the map's geographical coordinates - used for scale calculation.
Qgis::RendererUsage rendererUsage() const
Returns the rendering usage.
QgsVectorSimplifyMethod mSimplifyMethod
void addClippingRegion(const QgsMapClippingRegion &region)
Adds a new clipping region to the map settings.
void writeXml(QDomNode &node, QDomDocument &doc)
Writes the map settings to an XML node.
QgsPointXY layerToMapCoordinates(const QgsMapLayer *layer, QgsPointXY point) const
transform point coordinates from layer's CRS to output CRS
QgsMaskRenderSettings mMaskRenderSettings
QList< QgsMapLayer * > layers(bool expandGroupLayers=false) const
Returns the list of layers which will be rendered in the map.
Qgis::RendererUsage mRendererUsage
QgsRectangle mVisibleExtent
Extent with some additional white space that matches the output aspect ratio.
QPolygonF visiblePolygon() const
Returns the visible area as a polygon (may be rotated).
void addRenderedFeatureHandler(QgsRenderedFeatureHandlerInterface *handler)
Adds a rendered feature handler to use while rendering the map settings.
void setLayers(const QList< QgsMapLayer * > &layers)
Sets the list of layers to render in the map.
double scale() const
Returns the calculated map scale.
void setFrameRate(double rate)
Sets the frame rate of the map (in frames per second), for maps which are part of an animation.
void setFlags(Qgis::MapSettingsFlags flags)
Sets combination of flags that will be used for rendering.
Qgis::MapSettingsFlags mFlags
QgsCoordinateTransform layerTransform(const QgsMapLayer *layer) const
Returns the coordinate transform from layer's CRS to destination CRS.
QgsRectangle layerExtentToOutputExtent(const QgsMapLayer *layer, QgsRectangle extent) const
transform bounding box from layer's CRS to output CRS
QgsDoubleRange zRange() const
Returns the range of z-values which will be visible in the map.
bool setEllipsoid(const QString &ellipsoid)
Sets the ellipsoid by its acronym.
void setScaleMethod(Qgis::ScaleCalculationMethod method)
Sets the method to use for scale calculations for the map.
void setDpiTarget(double dpi)
Sets the target dpi (dots per inch) to be taken into consideration when rendering.
double magnificationFactor() const
Returns the magnification factor.
QStringList mLayerIds
QgsGeometry labelBoundaryGeometry() const
Returns the label boundary geometry, which restricts where in the rendered map labels are permitted t...
QList< QgsRenderedFeatureHandlerInterface * > renderedFeatureHandlers() const
Returns the list of rendered feature handlers to use while rendering the map settings.
QStringList layerIds(bool expandGroupLayers=false) const
Returns the list of layer IDs which will be rendered in the map.
void setDevicePixelRatio(float dpr)
Sets the device pixel ratio.
QString mEllipsoid
ellipsoid acronym (from table tbl_ellipsoids)
void setZRange(const QgsDoubleRange &range)
Sets the range of z-values which will be visible in the map.
double dpiTarget() const
Returns the target DPI (dots per inch) to be taken into consideration when rendering.
long long currentFrame() const
Returns the current frame number of the map, for maps which are part of an animation.
bool mValid
Whether the actual settings are valid (set in updateDerived()).
void setOutputDpi(double dpi)
Sets the dpi (dots per inch) used for conversion between real world units (e.g.
const QgsMapToPixel & mapToPixel() const
double mapUnitsPerPixel() const
Returns the distance in geographical coordinates that equals to one pixel in the map.
void setRendererUsage(Qgis::RendererUsage rendererUsage)
Sets the rendering usage.
float devicePixelRatio() const
Returns the device pixel ratio.
void setRasterizedRenderingPolicy(Qgis::RasterizedRenderingPolicy policy)
Sets the policy controlling when rasterisation of content during renders is permitted.
QgsRectangle mExtent
QSize outputSize() const
Returns the size of the resulting map image, in pixels.
QgsRectangle extent() const
Returns geographical coordinates of the rectangle that should be rendered.
void setMaskSettings(const QgsMaskRenderSettings &settings)
Sets the mask render settings, which control how masks are drawn and behave during the map render.
QMap< QString, QString > mLayerStyleOverrides
QgsGeometry mLabelBoundaryGeometry
void setLayerStyleOverrides(const QMap< QString, QString > &overrides)
Sets the map of map layer style overrides (key: layer ID, value: style name) where a different style ...
QgsElevationShadingRenderer mShadingRenderer
QgsCoordinateTransformContext mTransformContext
void setExtent(const QgsRectangle &rect, bool magnified=true)
Sets the coordinates of the rectangle which should be rendered.
void setClippingRegions(const QList< QgsMapClippingRegion > &regions)
Sets the list of clipping regions to apply to the map.
double layerToMapUnits(const QgsMapLayer *layer, const QgsRectangle &referenceExtent=QgsRectangle()) const
Computes an estimated conversion factor between layer and map units, where layerUnits × layerToMapUni...
double extentBuffer() const
Returns the buffer in map units to use around the visible extent for rendering symbols whose correspo...
QVector< T > layers() const
Returns a list of registered map layers with a specified layer type.
QgsScaleCalculator mScaleCalculator
Qgis::MapSettingsFlags flags() const
Returns combination of flags used for rendering.
Qgis::ScaleCalculationMethod scaleMethod() const
Returns the method to use for scale calculations for the map.
double frameRate() const
Returns the frame rate of the map (in frames per second), for maps which are part of an animation.
void setExtentBuffer(double buffer)
Sets the buffer in map units to use around the visible extent for rendering symbols whose correspondi...
QgsRectangle visibleExtent() const
Returns the actual extent derived from requested extent that takes output image size into account.
QgsRectangle outputExtentToLayerExtent(const QgsMapLayer *layer, QgsRectangle extent) const
transform bounding box from output CRS to layer's CRS
QgsRectangle fullExtent() const
returns current extent of layer set
void setTransformContext(const QgsCoordinateTransformContext &context)
Sets the coordinate transform context, which stores various information regarding which datum transfo...
void setRotation(double rotation)
Sets the rotation of the resulting map image, in degrees clockwise.
double computeScaleForExtent(const QgsRectangle &extent) const
Compute the scale that corresponds to the specified extent.
QString ellipsoid() const
Returns ellipsoid's acronym.
double mMagnificationFactor
void setCurrentFrame(long long frame)
Sets the current frame of the map, for maps which are part of an animation.
const QgsElevationShadingRenderer & elevationShadingRenderer() const
Returns the shading renderer used to render shading on the entire map.
QgsCoordinateReferenceSystem mDestCRS
double outputDpi() const
Returns the DPI (dots per inch) used for conversion between real world units (e.g.
void setLabelBoundaryGeometry(const QgsGeometry &boundary)
Sets the label boundary geometry, which restricts where in the rendered map labels are permitted to b...
Qgis::RasterizedRenderingPolicy mRasterizedRenderingPolicy
QgsMapToPixel mMapToPixel
bool testFlag(Qgis::MapSettingsFlag flag) const
Check whether a particular flag is enabled.
QMap< QString, QString > layerStyleOverrides() const
Returns the map of map layer style overrides (key: layer ID, value: style name) where a different sty...
double rotation() const
Returns the rotation of the resulting map image, in degrees clockwise.
QList< QgsMapClippingRegion > clippingRegions() const
Returns the list of clipping regions to apply to the map.
bool hasValidSettings() const
Check whether the map settings are valid and can be used for rendering.
QgsWeakMapLayerPointerList mLayers
list of layers to be rendered (stored as weak pointers)
void setOutputSize(QSize size)
Sets the size of the resulting map image, in pixels.
Qgis::RasterizedRenderingPolicy rasterizedRenderingPolicy() const
Returns the policy controlling when rasterisation of content during renders is permitted.
QgsPointXY mapToLayerCoordinates(const QgsMapLayer *layer, QgsPointXY point) const
transform point coordinates from output CRS to layer's CRS
long long mCurrentFrame
QgsCoordinateReferenceSystem destinationCrs() const
Returns the destination coordinate reference system for the map render.
QPolygonF visiblePolygonWithBuffer() const
Returns the visible area as a polygon (may be rotated) with extent buffer included.
void setFlag(Qgis::MapSettingsFlag flag, bool on=true)
Enable or disable a particular flag (other flags are not affected).
void setDestinationCrs(const QgsCoordinateReferenceSystem &crs)
Sets the destination crs (coordinate reference system) for the map render.
void readXml(QDomNode &node)
Restore the map settings from a XML node.
double mSegmentationTolerance
QgsRectangle computeExtentForScale(const QgsPointXY &center, double scale) const
Compute the extent such that its center is at the specified position (mapped to the destinatonCrs) an...
void setMagnificationFactor(double factor, const QgsPointXY *center=nullptr)
Set the magnification factor.
QgsCoordinateTransformContext transformContext() const
Returns the coordinate transform context, which stores various information regarding which datum tran...
Perform transforms between map coordinates and device coordinates.
QgsPointXY toMapCoordinates(int x, int y) const
Transforms device coordinates to map (world) coordinates.
Contains settings regarding how masks are calculated and handled during a map render.
static void logMessage(const QString &message, const QString &tag=QString(), Qgis::MessageLevel level=Qgis::MessageLevel::Warning, bool notifyUser=true, const char *file=__builtin_FILE(), const char *function=__builtin_FUNCTION(), int line=__builtin_LINE())
Adds a message to the log instance (and creates it if necessary).
Contains miscellaneous painting utility functions.
Definition qgspainting.h:32
Represents a 2D point.
Definition qgspointxy.h:60
double y
Definition qgspointxy.h:64
double x
Definition qgspointxy.h:63
QPointF toQPointF() const
Converts a point to a QPointF.
Definition qgspointxy.h:165
Point geometry type, with support for z-dimension and m-values.
Definition qgspoint.h:49
double z
Definition qgspoint.h:54
double x
Definition qgspoint.h:52
double m
Definition qgspoint.h:55
double y
Definition qgspoint.h:53
A rectangle specified with double values.
void scale(double scaleFactor, const QgsPointXY *c=nullptr)
Scale the rectangle around its center point.
An interface for classes which provide custom handlers for features rendered as part of a map render ...
static Q_INVOKABLE double fromUnitToUnitFactor(Qgis::DistanceUnit fromUnit, Qgis::DistanceUnit toUnit)
Returns the conversion factor between the specified distance units.
static QDomElement writeRectangle(const QgsRectangle &rect, QDomDocument &doc, const QString &elementName=QStringLiteral("extent"))
Encodes a rectangle to a DOM element.
static QgsRectangle readRectangle(const QDomElement &element)
static QDomElement writeMapUnits(Qgis::DistanceUnit units, QDomDocument &doc)
Encodes a distance unit to a DOM element.
QString qgsDoubleToString(double a, int precision=17)
Returns a string representation of a double.
Definition qgis.h:6524
bool qgsDoubleNear(double a, double b, double epsilon=4 *std::numeric_limits< double >::epsilon())
Compare two doubles (but allow some difference).
Definition qgis.h:6607
#define QgsDebugMsgLevel(str, level)
Definition qgslogger.h:61
QPointer< QgsMapLayer > QgsWeakMapLayerPointer
Weak pointer for QgsMapLayer.
Contains parameters for an ellipsoid.
bool valid
Whether ellipsoid parameters are valid.