QGIS API Documentation 3.29.0-Master (53715c36dc)
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
18#include "qgsscalecalculator.h"
19#include "qgsmaprendererjob.h"
20#include "qgsmaptopixel.h"
21#include "qgslogger.h"
22
23#include "qgsmessagelog.h"
24#include "qgsmaplayer.h"
26#include "qgsproject.h"
27#include "qgsxmlutils.h"
28#include "qgsexception.h"
29#include "qgsgeometry.h"
30#include "qgsgrouplayer.h"
31
32Q_GUI_EXPORT extern int qt_defaultDpiX();
33
34
36 : mDpi( qt_defaultDpiX() ) // DPI that will be used by default for QImage instances
37 , mSize( QSize( 0, 0 ) )
38 , mBackgroundColor( Qt::white )
39 , mSelectionColor( Qt::yellow )
40 , mFlags( Qgis::MapSettingsFlag::Antialiasing | Qgis::MapSettingsFlag::UseAdvancedEffects | Qgis::MapSettingsFlag::DrawLabeling | Qgis::MapSettingsFlag::DrawSelection )
41 , mSegmentationTolerance( M_PI_2 / 90 )
42{
45
47}
48
49void QgsMapSettings::setMagnificationFactor( double factor, const QgsPointXY *center )
50{
51 const double ratio = mMagnificationFactor / factor;
52
53 mMagnificationFactor = factor;
54
55 const double rot = rotation();
56 setRotation( 0.0 );
57
59 ext.scale( ratio, center );
60
61 mRotation = rot;
62 mExtent = ext;
63 mDpi = mDpi / ratio;
64
65 QgsDebugMsgLevel( QStringLiteral( "Magnification factor: %1 dpi: %2 ratio: %3" ).arg( factor ).arg( mDpi ).arg( ratio ), 3 );
66
68}
69
71{
73}
74
76{
77 return mExtent;
78}
79
80void QgsMapSettings::setExtent( const QgsRectangle &extent, bool magnified )
81{
82 QgsRectangle magnifiedExtent = extent;
83
84 if ( !magnified )
85 magnifiedExtent.scale( 1 / mMagnificationFactor );
86
87 mExtent = magnifiedExtent;
88
90}
91
93{
94 return mExtentBuffer;
95}
96
97void QgsMapSettings::setExtentBuffer( const double buffer )
98{
99 mExtentBuffer = buffer;
100}
101
103{
104 return mRotation;
105}
106
107void QgsMapSettings::setRotation( double degrees )
108{
109 if ( qgsDoubleNear( mRotation, degrees ) )
110 return;
111
112 mRotation = degrees;
113
114 // TODO: update extent while keeping scale ?
116}
117
118
120{
122
123 if ( extent.isEmpty() || !extent.isFinite() )
124 {
125 mValid = false;
126 return;
127 }
128
129 // Don't allow zooms where the current extent is so small that it
130 // can't be accurately represented using a double (which is what
131 // currentExtent uses). Excluding 0 avoids a divide by zero and an
132 // infinite loop when rendering to a new canvas. Excluding extents
133 // greater than 1 avoids doing unnecessary calculations.
134
135 // The scheme is to compare the width against the mean x coordinate
136 // (and height against mean y coordinate) and only allow zooms where
137 // the ratio indicates that there is more than about 12 significant
138 // figures (there are about 16 significant figures in a double).
139
140 if ( extent.width() > 0 &&
141 extent.height() > 0 &&
142 extent.width() < 1 &&
143 extent.height() < 1 )
144 {
145 // Use abs() on the extent to avoid the case where the extent is
146 // symmetrical about 0.
147 const double xMean = ( std::fabs( extent.xMinimum() ) + std::fabs( extent.xMaximum() ) ) * 0.5;
148 const double yMean = ( std::fabs( extent.yMinimum() ) + std::fabs( extent.yMaximum() ) ) * 0.5;
149
150 const double xRange = extent.width() / xMean;
151 const double yRange = extent.height() / yMean;
152
153 static const double MIN_PROPORTION = 1e-12;
154 if ( xRange < MIN_PROPORTION || yRange < MIN_PROPORTION )
155 {
156 mValid = false;
157 return;
158 }
159 }
160
161 const double myHeight = mSize.height();
162 const double myWidth = mSize.width();
163
164 if ( !myWidth || !myHeight )
165 {
166 mValid = false;
167 return;
168 }
169
170 // calculate the translation and scaling parameters
171 const double mapUnitsPerPixelY = mExtent.height() / myHeight;
172 const double mapUnitsPerPixelX = mExtent.width() / myWidth;
173 mMapUnitsPerPixel = mapUnitsPerPixelY > mapUnitsPerPixelX ? mapUnitsPerPixelY : mapUnitsPerPixelX;
174
175 // calculate the actual extent of the mapCanvas
176 double dxmin = mExtent.xMinimum(), dxmax = mExtent.xMaximum(),
177 dymin = mExtent.yMinimum(), dymax = mExtent.yMaximum(), whitespace;
178
179 if ( mapUnitsPerPixelY > mapUnitsPerPixelX )
180 {
181 whitespace = ( ( myWidth * mMapUnitsPerPixel ) - mExtent.width() ) * 0.5;
182 dxmin -= whitespace;
183 dxmax += whitespace;
184 }
185 else
186 {
187 whitespace = ( ( myHeight * mMapUnitsPerPixel ) - mExtent.height() ) * 0.5;
188 dymin -= whitespace;
189 dymax += whitespace;
190 }
191
192 mVisibleExtent.set( dxmin, dymin, dxmax, dymax );
193
194 // update the scale
197
198 bool ok = true;
201 visibleExtent().center().x(),
202 visibleExtent().center().y(),
203 outputSize().width(),
204 outputSize().height(),
205 mRotation, &ok );
206
207 mValid = ok;
208
209#if 1 // set visible extent taking rotation in consideration
210 if ( mRotation )
211 {
212 const QgsPointXY p1 = mMapToPixel.toMapCoordinates( QPoint( 0, 0 ) );
213 const QgsPointXY p2 = mMapToPixel.toMapCoordinates( QPoint( 0, myHeight ) );
214 const QgsPointXY p3 = mMapToPixel.toMapCoordinates( QPoint( myWidth, 0 ) );
215 const QgsPointXY p4 = mMapToPixel.toMapCoordinates( QPoint( myWidth, myHeight ) );
216 dxmin = std::min( p1.x(), std::min( p2.x(), std::min( p3.x(), p4.x() ) ) );
217 dymin = std::min( p1.y(), std::min( p2.y(), std::min( p3.y(), p4.y() ) ) );
218 dxmax = std::max( p1.x(), std::max( p2.x(), std::max( p3.x(), p4.x() ) ) );
219 dymax = std::max( p1.y(), std::max( p2.y(), std::max( p3.y(), p4.y() ) ) );
220 mVisibleExtent.set( dxmin, dymin, dxmax, dymax );
221 }
222#endif
223
224 QgsDebugMsgLevel( QStringLiteral( "Map units per pixel (x,y) : %1, %2" ).arg( qgsDoubleToString( mapUnitsPerPixelX ), qgsDoubleToString( mapUnitsPerPixelY ) ), 5 );
225 QgsDebugMsgLevel( QStringLiteral( "Pixmap dimensions (x,y) : %1, %2" ).arg( qgsDoubleToString( mSize.width() ), qgsDoubleToString( mSize.height() ) ), 5 );
226 QgsDebugMsgLevel( QStringLiteral( "Extent dimensions (x,y) : %1, %2" ).arg( qgsDoubleToString( mExtent.width() ), qgsDoubleToString( mExtent.height() ) ), 5 );
228 QgsDebugMsgLevel( QStringLiteral( "Adjusted map units per pixel (x,y) : %1, %2" ).arg( qgsDoubleToString( mVisibleExtent.width() / myWidth ), qgsDoubleToString( mVisibleExtent.height() / myHeight ) ), 5 );
229 QgsDebugMsgLevel( QStringLiteral( "Recalced pixmap dimensions (x,y) : %1, %2" ).arg( qgsDoubleToString( mVisibleExtent.width() / mMapUnitsPerPixel ), qgsDoubleToString( mVisibleExtent.height() / mMapUnitsPerPixel ) ), 5 );
230 QgsDebugMsgLevel( QStringLiteral( "Scale (assuming meters as map units) = 1:%1" ).arg( qgsDoubleToString( mScale ) ), 5 );
231 QgsDebugMsgLevel( QStringLiteral( "Rotation: %1 degrees" ).arg( mRotation ), 5 );
232 QgsDebugMsgLevel( QStringLiteral( "Extent: %1" ).arg( mExtent.asWktCoordinates() ), 5 );
233 QgsDebugMsgLevel( QStringLiteral( "Visible Extent: %1" ).arg( mVisibleExtent.asWktCoordinates() ), 5 );
234 QgsDebugMsgLevel( QStringLiteral( "Magnification factor: %1" ).arg( mMagnificationFactor ), 5 );
235
236}
237
238
240{
241 return mSize;
242}
243
245{
246 mSize = size;
247
249}
250
252{
253 return mDevicePixelRatio;
254}
255
257{
258 mDevicePixelRatio = dpr;
260}
261
263{
264 return outputSize() * mDevicePixelRatio;
265}
266
268{
269 return mDpi;
270}
271
273{
274 mDpi = dpi;
275
277}
278
280{
281 return mDpiTarget;
282}
283
285{
286 mDpiTarget = dpi;
287}
288
289QStringList QgsMapSettings::layerIds( bool expandGroupLayers ) const
290{
291 const QList<QgsMapLayer * > mapLayers = layers( expandGroupLayers );
292 QStringList res;
293 res.reserve( mapLayers.size() );
294 for ( const QgsMapLayer *layer : mapLayers )
295 res << layer->id();
296 return res;
297}
298
299QList<QgsMapLayer *> QgsMapSettings::layers( bool expandGroupLayers ) const
300{
301 const QList<QgsMapLayer *> actualLayers = _qgis_listQPointerToRaw( mLayers );
302 if ( !expandGroupLayers )
303 return actualLayers;
304
305 QList< QgsMapLayer * > result;
306
307 std::function< void( const QList< QgsMapLayer * >& layers ) > expandLayers;
308 expandLayers = [&result, &expandLayers]( const QList< QgsMapLayer * > &layers )
309 {
310 for ( QgsMapLayer *layer : layers )
311 {
312 if ( QgsGroupLayer *groupLayer = qobject_cast< QgsGroupLayer * >( layer ) )
313 {
314 expandLayers( groupLayer->childLayers() );
315 }
316 else
317 {
318 result << layer;
319 }
320 }
321 };
322
323 expandLayers( actualLayers );
324 return result;
325}
326
327void QgsMapSettings::setLayers( const QList<QgsMapLayer *> &layers )
328{
329 // filter list, removing null layers and non-spatial layers
330 auto filteredList = layers;
331 filteredList.erase( std::remove_if( filteredList.begin(), filteredList.end(),
332 []( QgsMapLayer * layer )
333 {
334 return !layer || !layer->isSpatial();
335 } ), filteredList.end() );
336
337 mLayers = _qgis_listRawToQPointer( filteredList );
338}
339
340QMap<QString, QString> QgsMapSettings::layerStyleOverrides() const
341{
343}
344
345void QgsMapSettings::setLayerStyleOverrides( const QMap<QString, QString> &overrides )
346{
347 mLayerStyleOverrides = overrides;
348}
349
351{
352 mDestCRS = crs;
354 // Since the map units have changed, force a recalculation of the scale.
356}
357
359{
360 return mDestCRS;
361}
362
363bool QgsMapSettings::setEllipsoid( const QString &ellipsoid )
364{
366 if ( !params.valid )
367 {
368 return false;
369 }
370 else
371 {
373 return true;
374 }
375}
376
377void QgsMapSettings::setFlags( Qgis::MapSettingsFlags flags )
378{
379 mFlags = flags;
380}
381
383{
384 if ( on )
385 mFlags |= flag;
386 else
387 mFlags &= ~( static_cast< int >( flag ) );
388}
389
390Qgis::MapSettingsFlags QgsMapSettings::flags() const
391{
392 return mFlags;
393}
394
396{
397 return mFlags.testFlag( flag );
398}
399
401{
402 return mScaleCalculator.mapUnits();
403}
404
405
407{
408 return mValid;
409}
410
412{
413 return mVisibleExtent;
414}
415
417{
418 QPolygonF poly;
419
420 const QSize &sz = outputSize();
421 const QgsMapToPixel &m2p = mapToPixel();
422
423 poly << m2p.toMapCoordinates( 0.0, 0.0 ).toQPointF();
424 poly << m2p.toMapCoordinates( static_cast<double>( sz.width() ), 0.0 ).toQPointF();
425 poly << m2p.toMapCoordinates( static_cast<double>( sz.width() ), static_cast<double>( sz.height() ) ).toQPointF();
426 poly << m2p.toMapCoordinates( 0.0, static_cast<double>( sz.height() ) ).toQPointF();
427
428 return poly;
429}
430
432{
433 QPolygonF poly;
434
435 const QSize &sz = outputSize();
436 const QgsMapToPixel &m2p = mapToPixel();
437
438 // Transform tilebuffer in pixel.
439 // Original tilebuffer is in pixel and transformed only according
440 // extent width (see QgsWmsRenderContext::mapTileBuffer)
441
442 const double mapUnitsPerPixel = mExtent.width() / sz.width();
443 const double buffer = mExtentBuffer / mapUnitsPerPixel;
444
445 poly << m2p.toMapCoordinates( -buffer, -buffer ).toQPointF();
446 poly << m2p.toMapCoordinates( static_cast<double>( sz.width() + buffer ), -buffer ).toQPointF();
447 poly << m2p.toMapCoordinates( static_cast<double>( sz.width() + buffer ), static_cast<double>( sz.height() + buffer ) ).toQPointF();
448 poly << m2p.toMapCoordinates( -buffer, static_cast<double>( sz.height() + buffer ) ).toQPointF();
449
450 return poly;
451}
452
454{
455 return mMapUnitsPerPixel;
456}
457
459{
460 return mScale;
461}
462
464{
465#ifdef QGISDEBUG
466 if ( !mHasTransformContext )
467 QgsDebugMsgLevel( QStringLiteral( "No QgsCoordinateTransformContext context set for transform" ), 4 );
468#endif
469
470 return mTransformContext;
471}
472
474{
475 mTransformContext = context;
476#ifdef QGISDEBUG
477 mHasTransformContext = true;
478#endif
479}
480
482{
483 if ( !layer )
484 return QgsCoordinateTransform();
485
487}
488
490{
491 // Output width in inches
492 const double outputWidthInInches = outputSize().width() / outputDpi();
493
494 // Desired visible width (honouring scale)
495 const double scaledWidthInInches = outputWidthInInches * scale;
496
498 {
499 // Start with some fraction of the current extent around the center
500 const double delta = mExtent.width() / 100.;
501 QgsRectangle ext( center.x() - delta, center.y() - delta, center.x() + delta, center.y() + delta );
502 // Get scale at extent, and then scale extent to the desired scale
503 const double testScale = mScaleCalculator.calculate( ext, outputSize().width() );
504 ext.scale( scale / testScale );
505 return ext;
506 }
507 else
508 {
509 // Conversion from inches to mapUnits - this is safe to use, because we know here that the map units AREN'T in degrees
510 const double conversionFactor = QgsUnitTypes::fromUnitToUnitFactor( QgsUnitTypes::DistanceFeet, mapUnits() ) / 12;
511
512 const double delta = 0.5 * scaledWidthInInches * conversionFactor;
513 return QgsRectangle( center.x() - delta, center.y() - delta, center.x() + delta, center.y() + delta );
514 }
515}
516
518{
519 return mScaleCalculator.calculate( extent, outputSize().width() );
520}
521
522double QgsMapSettings::layerToMapUnits( const QgsMapLayer *layer, const QgsRectangle &referenceExtent ) const
523{
524 return layerTransform( layer ).scaleFactor( referenceExtent );
525}
526
527
529{
530 try
531 {
533 if ( ct.isValid() )
534 {
535 QgsDebugMsgLevel( QStringLiteral( "sourceCrs = %1" ).arg( ct.sourceCrs().authid() ), 3 );
536 QgsDebugMsgLevel( QStringLiteral( "destCRS = %1" ).arg( ct.destinationCrs().authid() ), 3 );
537 QgsDebugMsgLevel( QStringLiteral( "extent %1" ).arg( extent.toString() ), 3 );
540 }
541 }
542 catch ( QgsCsException &cse )
543 {
544 QgsMessageLog::logMessage( QObject::tr( "Transform error caught: %1" ).arg( cse.what() ), QObject::tr( "CRS" ) );
545 }
546
547 QgsDebugMsgLevel( QStringLiteral( "proj extent = %1 " ).arg( extent.toString() ), 3 );
548
549 return extent;
550}
551
552
554{
555 try
556 {
559 if ( ct.isValid() )
560 {
561 QgsDebugMsgLevel( QStringLiteral( "sourceCrs = %1" ).arg( ct.sourceCrs().authid() ), 3 );
562 QgsDebugMsgLevel( QStringLiteral( "destCRS = %1" ).arg( ct.destinationCrs().authid() ), 3 );
563 QgsDebugMsgLevel( QStringLiteral( "extent = %1" ).arg( extent.toString() ), 3 );
564 extent = ct.transformBoundingBox( extent, Qgis::TransformDirection::Reverse );
565 }
566 }
567 catch ( QgsCsException &cse )
568 {
569 QgsMessageLog::logMessage( QObject::tr( "Transform error caught: %1" ).arg( cse.what() ), QObject::tr( "CRS" ) );
570 }
571
572 QgsDebugMsgLevel( QStringLiteral( "proj extent = %1" ).arg( extent.toString() ), 3 );
573
574 return extent;
575}
576
577
579{
580 try
581 {
582 const QgsCoordinateTransform ct = layerTransform( layer );
583 if ( ct.isValid() )
584 point = ct.transform( point, Qgis::TransformDirection::Forward );
585 }
586 catch ( QgsCsException &cse )
587 {
588 QgsMessageLog::logMessage( QObject::tr( "Transform error caught: %1" ).arg( cse.what() ), QObject::tr( "CRS" ) );
589 }
590
591 return point;
592}
593
595{
596 double x = point.x();
597 double y = point.y();
598 double z = point.z();
599 const double m = point.m();
600
601 try
602 {
603 const QgsCoordinateTransform ct = layerTransform( layer );
604 if ( ct.isValid() )
605 ct.transformInPlace( x, y, z, Qgis::TransformDirection::Forward );
606 }
607 catch ( QgsCsException &cse )
608 {
609 QgsMessageLog::logMessage( QObject::tr( "Transform error caught: %1" ).arg( cse.what() ), QObject::tr( "CRS" ) );
610 }
611
612 return QgsPoint( x, y, z, m );
613}
614
615
617{
618 try
619 {
620 const QgsCoordinateTransform ct = layerTransform( layer );
621 if ( ct.isValid() )
622 rect = ct.transform( rect, Qgis::TransformDirection::Forward );
623 }
624 catch ( QgsCsException &cse )
625 {
626 QgsMessageLog::logMessage( QObject::tr( "Transform error caught: %1" ).arg( cse.what() ), QObject::tr( "CRS" ) );
627 }
628
629 return rect;
630}
631
632
634{
635 try
636 {
637 const QgsCoordinateTransform ct = layerTransform( layer );
638 if ( ct.isValid() )
639 point = ct.transform( point, Qgis::TransformDirection::Reverse );
640 }
641 catch ( QgsCsException &cse )
642 {
643 QgsMessageLog::logMessage( QObject::tr( "Transform error caught: %1" ).arg( cse.what() ), QObject::tr( "CRS" ) );
644 }
645
646 return point;
647}
648
650{
651 double x = point.x();
652 double y = point.y();
653 double z = point.z();
654 const double m = point.m();
655
656 try
657 {
658 const QgsCoordinateTransform ct = layerTransform( layer );
659 if ( ct.isValid() )
660 ct.transformInPlace( x, y, z, Qgis::TransformDirection::Reverse );
661 }
662 catch ( QgsCsException &cse )
663 {
664 QgsMessageLog::logMessage( QObject::tr( "Transform error caught: %1" ).arg( cse.what() ), QObject::tr( "CRS" ) );
665 }
666
667 return QgsPoint( x, y, z, m );
668}
669
670
672{
673 try
674 {
675 const QgsCoordinateTransform ct = layerTransform( layer );
676 if ( ct.isValid() )
677 rect = ct.transform( rect, Qgis::TransformDirection::Reverse );
678 }
679 catch ( QgsCsException &cse )
680 {
681 QgsMessageLog::logMessage( QObject::tr( "Transform error caught: %1" ).arg( cse.what() ), QObject::tr( "CRS" ) );
682 }
683
684 return rect;
685}
686
687
688
690{
691 // reset the map canvas extent since the extent may now be smaller
692 // We can't use a constructor since QgsRectangle normalizes the rectangle upon construction
695
696 // iterate through the map layers and test each layers extent
697 // against the current min and max values
698 QgsDebugMsgLevel( QStringLiteral( "Layer count: %1" ).arg( mLayers.count() ), 5 );
699 const auto constMLayers = mLayers;
700 for ( const QgsWeakMapLayerPointer &layerPtr : constMLayers )
701 {
702 if ( QgsMapLayer *lyr = layerPtr.data() )
703 {
704 QgsDebugMsgLevel( "Updating extent using " + lyr->name(), 5 );
705 QgsDebugMsgLevel( "Input extent: " + lyr->extent().toString(), 5 );
706
707 if ( lyr->extent().isNull() )
708 continue;
709
710 // Layer extents are stored in the coordinate system (CS) of the
711 // layer. The extent must be projected to the canvas CS
712 const QgsRectangle extent = layerExtentToOutputExtent( lyr, lyr->extent() );
713
714 QgsDebugMsgLevel( "Output extent: " + extent.toString(), 5 );
716 }
717 }
718
719 if ( fullExtent.width() == 0.0 || fullExtent.height() == 0.0 )
720 {
721 // If all of the features are at the one point, buffer the
722 // rectangle a bit. If they are all at zero, do something a bit
723 // more crude.
724
725 if ( fullExtent.xMinimum() == 0.0 && fullExtent.xMaximum() == 0.0 &&
726 fullExtent.yMinimum() == 0.0 && fullExtent.yMaximum() == 0.0 )
727 {
728 fullExtent.set( -1.0, -1.0, 1.0, 1.0 );
729 }
730 else
731 {
732 const double padFactor = 1e-8;
733 const double widthPad = fullExtent.xMinimum() * padFactor;
734 const double heightPad = fullExtent.yMinimum() * padFactor;
735 const double xmin = fullExtent.xMinimum() - widthPad;
736 const double xmax = fullExtent.xMaximum() + widthPad;
737 const double ymin = fullExtent.yMinimum() - heightPad;
738 const double ymax = fullExtent.yMaximum() + heightPad;
739 fullExtent.set( xmin, ymin, xmax, ymax );
740 }
741 }
742
743 QgsDebugMsgLevel( "Full extent: " + fullExtent.toString(), 5 );
744 return fullExtent;
745}
746
747
748void QgsMapSettings::readXml( QDomNode &node )
749{
750 // set destination CRS
752 const QDomNode srsNode = node.namedItem( QStringLiteral( "destinationsrs" ) );
753 if ( !srsNode.isNull() )
754 {
755 srs.readXml( srsNode );
756 }
757 setDestinationCrs( srs );
758
759 // set extent
760 const QDomNode extentNode = node.namedItem( QStringLiteral( "extent" ) );
761 const QgsRectangle aoi = QgsXmlUtils::readRectangle( extentNode.toElement() );
762 setExtent( aoi );
763
764 // set rotation
765 const QDomNode rotationNode = node.namedItem( QStringLiteral( "rotation" ) );
766 const QString rotationVal = rotationNode.toElement().text();
767 if ( ! rotationVal.isEmpty() )
768 {
769 const double rot = rotationVal.toDouble();
770 setRotation( rot );
771 }
772
773 //render map tile
774 const QDomElement renderMapTileElem = node.firstChildElement( QStringLiteral( "rendermaptile" ) );
775 if ( !renderMapTileElem.isNull() )
776 {
777 setFlag( Qgis::MapSettingsFlag::RenderMapTile, renderMapTileElem.text() == QLatin1String( "1" ) );
778 }
779}
780
781
782
783void QgsMapSettings::writeXml( QDomNode &node, QDomDocument &doc )
784{
785 // units
786 node.appendChild( QgsXmlUtils::writeMapUnits( mapUnits(), doc ) );
787
788 // Write current view extents
789 node.appendChild( QgsXmlUtils::writeRectangle( extent(), doc ) );
790
791 // Write current view rotation
792 QDomElement rotNode = doc.createElement( QStringLiteral( "rotation" ) );
793 rotNode.appendChild(
794 doc.createTextNode( qgsDoubleToString( rotation() ) )
795 );
796 node.appendChild( rotNode );
797
798 // destination CRS
799 if ( mDestCRS.isValid() )
800 {
801 QDomElement srsNode = doc.createElement( QStringLiteral( "destinationsrs" ) );
802 node.appendChild( srsNode );
803 mDestCRS.writeXml( srsNode, doc );
804 }
805
806 //render map tile
807 QDomElement renderMapTileElem = doc.createElement( QStringLiteral( "rendermaptile" ) );
808 const QDomText renderMapTileText = doc.createTextNode( testFlag( Qgis::MapSettingsFlag::RenderMapTile ) ? "1" : "0" );
809 renderMapTileElem.appendChild( renderMapTileText );
810 node.appendChild( renderMapTileElem );
811}
812
814{
816}
817
819{
820 mLabelBoundaryGeometry = boundary;
821}
822
824{
825 mClippingRegions.append( region );
826}
827
828void QgsMapSettings::setClippingRegions( const QList<QgsMapClippingRegion> &regions )
829{
830 mClippingRegions = regions;
831}
832
833QList<QgsMapClippingRegion> QgsMapSettings::clippingRegions() const
834{
835 return mClippingRegions;
836}
837
839{
840 mRenderedFeatureHandlers.append( handler );
841}
842
843QList<QgsRenderedFeatureHandlerInterface *> QgsMapSettings::renderedFeatureHandlers() const
844{
845 return mRenderedFeatureHandlers;
846}
847
849{
850 return mZRange;
851}
852
854{
855 mZRange = zRange;
856}
857
859{
860 return mRendererUsage;
861}
862
864{
866}
867
869{
870 return mFrameRate;
871}
872
874{
875 mFrameRate = rate;
876}
877
879{
880 return mCurrentFrame;
881}
882
883void QgsMapSettings::setCurrentFrame( long long frame )
884{
885 mCurrentFrame = frame;
886}
The Qgis class provides global constants for use throughout the application.
Definition: qgis.h:72
RendererUsage
Usage of the renderer.
Definition: qgis.h:2022
MapSettingsFlag
Coordinate transformation flags.
Definition: qgis.h:1493
@ RenderMapTile
Draw map such that there are no problems between adjacent tiles.
This class represents a coordinate reference system (CRS).
bool isValid() const
Returns whether this CRS is correctly initialized and usable.
bool readXml(const QDomNode &node)
Restores state from the given DOM node.
bool writeXml(QDomNode &node, QDomDocument &doc) const
Stores state to the given Dom node in the given document.
Q_GADGET QgsUnitTypes::DistanceUnit mapUnits
Contains information about the context in which a coordinate transform is executed.
Class for doing transforms between two map 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:
bool isValid() const
Returns true if the coordinate transform is valid, ie both the source and destination CRS have been s...
void transformInPlace(double &x, double &y, double &z, Qgis::TransformDirection direction=Qgis::TransformDirection::Forward) const SIP_THROW(QgsCsException)
Transforms an array of x, y and z double coordinates in place, from the source CRS to the destination...
QgsCoordinateReferenceSystem destinationCrs() const
Returns the destination coordinate reference system, which the transform will transform coordinates t...
QgsRectangle transformBoundingBox(const QgsRectangle &rectangle, Qgis::TransformDirection direction=Qgis::TransformDirection::Forward, bool handle180Crossover=false) const SIP_THROW(QgsCsException)
Transforms a rectangle from the source CRS to the destination CRS.
QgsPointXY transform(const QgsPointXY &point, Qgis::TransformDirection direction=Qgis::TransformDirection::Forward) const SIP_THROW(QgsCsException)
Transform the point from the source CRS to the destination CRS.
Custom exception class for Coordinate Reference System related exceptions.
Definition: qgsexception.h:66
QgsRange which stores a range of double values.
Definition: qgsrange.h:203
static EllipsoidParameters ellipsoidParameters(const QString &ellipsoid)
Returns the parameters for the specified ellipsoid.
QString what() const
Definition: qgsexception.h:48
A geometry is the spatial representation of a feature.
Definition: qgsgeometry.h:164
A map layer which consists of a set of child layers, where all component layers are rendered as a sin...
Definition: qgsgrouplayer.h:42
A map clipping region (in map coordinates and CRS).
Base class for all map layer types.
Definition: qgsmaplayer.h:73
QgsCoordinateReferenceSystem crs
Definition: qgsmaplayer.h:79
QSize deviceOutputSize() const
Returns the device output size of the map render.
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)
QgsPointXY layerToMapCoordinates(const QgsMapLayer *layer, QgsPointXY point) const
transform point coordinates from layer's CRS to output CRS
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 setDpiTarget(double dpi)
Sets the target dpi (dots per inch) to be taken into consideration when rendering.
double magnificationFactor() const
Returns the magnification factor.
double mMapUnitsPerPixel
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.
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.
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 ...
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: layerUnits * layerToMapUnits = m...
double extentBuffer() const
Returns the buffer in map units to use around the visible extent for rendering symbols whose correspo...
QgsScaleCalculator mScaleCalculator
Qgis::MapSettingsFlags flags() const
Returns combination of flags used for rendering.
QgsUnitTypes::DistanceUnit mapUnits() const
Returns the units of the map's geographical coordinates - used for scale calculation.
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.
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...
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.
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)
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.
Definition: qgsmaptopixel.h:39
QgsPointXY toMapCoordinates(int x, int y) const
Transforms device coordinates to map (world) coordinates.
void setParameters(double mapUnitsPerPixel, double centerX, double centerY, int widthPixels, int heightPixels, double rotation)
Sets parameters for use in transforming coordinates.
static void logMessage(const QString &message, const QString &tag=QString(), Qgis::MessageLevel level=Qgis::MessageLevel::Warning, bool notifyUser=true)
Adds a message to the log instance (and creates it if necessary).
A class to represent a 2D point.
Definition: qgspointxy.h:59
double y
Definition: qgspointxy.h:63
Q_GADGET double x
Definition: qgspointxy.h:62
QPointF toQPointF() const
Converts a point to a QPointF.
Definition: qgspointxy.h:169
Point geometry type, with support for z-dimension and m-values.
Definition: qgspoint.h:49
Q_GADGET double x
Definition: qgspoint.h:52
double z
Definition: qgspoint.h:54
double m
Definition: qgspoint.h:55
double y
Definition: qgspoint.h:53
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...
void scale(double scaleFactor, const QgsPointXY *c=nullptr)
Scale the rectangle around its center point.
Definition: qgsrectangle.h:256
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
QString asWktCoordinates() const
Returns a string representation of the rectangle in WKT format.
double height() const SIP_HOLDGIL
Returns the height of the rectangle.
Definition: qgsrectangle.h:230
void set(const QgsPointXY &p1, const QgsPointXY &p2, bool normalize=true)
Sets the rectangle from two QgsPoints.
Definition: qgsrectangle.h:122
void setMinimal() SIP_HOLDGIL
Set a rectangle so that min corner is at max and max corner is at min.
Definition: qgsrectangle.h:172
double width() const SIP_HOLDGIL
Returns the width of the rectangle.
Definition: qgsrectangle.h:223
void combineExtentWith(const QgsRectangle &rect)
Expands the rectangle so that it covers both the original rectangle and the given rectangle.
Definition: qgsrectangle.h:391
bool isEmpty() const
Returns true if the rectangle is empty.
Definition: qgsrectangle.h:469
bool isFinite() const
Returns true if the rectangle has finite boundaries.
Definition: qgsrectangle.h:559
QgsPointXY center() const SIP_HOLDGIL
Returns the center point of the rectangle.
Definition: qgsrectangle.h:251
An interface for classes which provider custom handlers for features rendered as part of a map render...
double calculate(const QgsRectangle &mapExtent, double canvasWidth) const
Calculate the scale denominator.
void setDpi(double dpi)
Sets the dpi (dots per inch) for the output resolution, to be used in scale calculations.
void setMapUnits(QgsUnitTypes::DistanceUnit mapUnits)
Set the map units.
QgsUnitTypes::DistanceUnit mapUnits() const
Returns current map units.
DistanceUnit
Units of distance.
Definition: qgsunittypes.h:68
@ DistanceDegrees
Degrees, for planar geographic CRS distance measurements.
Definition: qgsunittypes.h:75
@ DistanceUnknownUnit
Unknown distance unit.
Definition: qgsunittypes.h:78
@ DistanceFeet
Imperial feet.
Definition: qgsunittypes.h:71
static Q_INVOKABLE double fromUnitToUnitFactor(QgsUnitTypes::DistanceUnit fromUnit, QgsUnitTypes::DistanceUnit toUnit)
Returns the conversion factor between the specified distance units.
void setSimplifyHints(SimplifyHints simplifyHints)
Sets the simplification hints of the vector layer managed.
@ NoSimplification
No simplification can be applied.
static QDomElement writeRectangle(const QgsRectangle &rect, QDomDocument &doc, const QString &elementName=QStringLiteral("extent"))
Encodes a rectangle to a DOM element.
Definition: qgsxmlutils.cpp:81
static QDomElement writeMapUnits(QgsUnitTypes::DistanceUnit units, QDomDocument &doc)
Encodes a distance unit to a DOM element.
Definition: qgsxmlutils.cpp:69
static QgsRectangle readRectangle(const QDomElement &element)
Definition: qgsxmlutils.cpp:39
QString qgsDoubleToString(double a, int precision=17)
Returns a string representation of a double.
Definition: qgis.h:2719
bool qgsDoubleNear(double a, double b, double epsilon=4 *std::numeric_limits< double >::epsilon())
Compare two doubles (but allow some difference)
Definition: qgis.h:2780
#define QgsDebugMsgLevel(str, level)
Definition: qgslogger.h:39
QPointer< QgsMapLayer > QgsWeakMapLayerPointer
Weak pointer for QgsMapLayer.
Definition: qgsmaplayer.h:2180
Q_GUI_EXPORT int qt_defaultDpiX()
const QgsCoordinateReferenceSystem & crs
Contains parameters for an ellipsoid.
bool valid
Whether ellipsoid parameters are valid.