QGIS API Documentation 3.28.0-Firenze (ed3ad0430f)
qgsmapcanvasmap.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgsmapcanvasmap.cpp - draws the map in map canvas
3 ----------------------
4 begin : February 2006
5 copyright : (C) 2006 by Martin Dobias
6 email : wonder.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 "qgslogger.h"
17#include "qgsmapcanvas.h"
18#include "qgsmapcanvasmap.h"
19#include "qgsmaprendererjob.h"
20#include "qgsmapsettings.h"
21#include "qgsmaplayer.h"
22
23#include <QPainter>
24
26
27QgsMapCanvasMap::QgsMapCanvasMap( QgsMapCanvas *canvas )
28 : QgsMapCanvasItem( canvas )
29{
30 setZValue( -10 );
31}
32
33void QgsMapCanvasMap::setContent( const QImage &image, const QgsRectangle &rect )
34{
35 mPreviewImages.clear();
36
37 mImage = image;
38
39 // For true retro fans: this is approximately how the graphics looked like in 1990
40 if ( mMapCanvas->property( "retro" ).toBool() )
41 mImage = mImage.scaled( mImage.width() / 3, mImage.height() / 3 )
42 .convertToFormat( QImage::Format_Indexed8, Qt::OrderedDither | Qt::OrderedAlphaDither );
43
44 setRect( rect );
45}
46
47void QgsMapCanvasMap::addPreviewImage( const QImage &image, const QgsRectangle &rect )
48{
49 mPreviewImages.append( qMakePair( image, rect ) );
50 update();
51}
52
53QRectF QgsMapCanvasMap::boundingRect() const
54{
55 const double width = mItemSize.width();
56 const double height = mItemSize.height();
57
58 return QRectF( -width, -height, 3 * width, 3 * height );
59}
60
61void QgsMapCanvasMap::paint( QPainter *painter )
62{
63 // setRect() makes the size +2 :-(
64 const int w = std::round( mItemSize.width() ) - 2;
65 const int h = std::round( mItemSize.height() ) - 2;
66
67 bool scale = false;
68 if ( mImage.size() != QSize( w, h ) * mImage.devicePixelRatioF() )
69 {
70 QgsDebugMsgLevel( QStringLiteral( "map paint DIFFERENT SIZE: img %1,%2 item %3,%4" )
71 .arg( mImage.width() / mImage.devicePixelRatioF() )
72 .arg( mImage.height() / mImage.devicePixelRatioF() )
73 .arg( w ).arg( h ), 2 );
74 // This happens on zoom events when ::paint is called before
75 // the renderer has completed
76 scale = true;
77 }
78
79 /*Offset between 0/0 and mRect.xMinimum/mRect.yMinimum.
80 We need to consider the offset, because mRect is not updated yet and there might be an offset*/
81 const QgsPointXY pt = toMapCoordinates( QPoint( 0, 0 ) );
82 const double offsetX = pt.x() - mRect.xMinimum();
83 const double offsetY = pt.y() - mRect.yMaximum();
84
85 //draw preview images first
86 QList< QPair< QImage, QgsRectangle > >::const_iterator imIt = mPreviewImages.constBegin();
87 for ( ; imIt != mPreviewImages.constEnd(); ++imIt )
88 {
89 const QPointF ul = toCanvasCoordinates( QgsPoint( imIt->second.xMinimum() + offsetX, imIt->second.yMaximum() + offsetY ) );
90 const QPointF lr = toCanvasCoordinates( QgsPoint( imIt->second.xMaximum() + offsetX, imIt->second.yMinimum() + offsetY ) );
91 painter->drawImage( QRectF( ul.x(), ul.y(), lr.x() - ul.x(), lr.y() - ul.y() ), imIt->first, QRect( 0, 0, imIt->first.width(), imIt->first.height() ) );
92 }
93
94 if ( scale )
95 painter->drawImage( QRect( 0, 0, w, h ), mImage );
96 else
97 painter->drawImage( 0, 0, mImage );
98
99 // For debugging:
100#if 0
101 QRectF br = boundingRect();
102 QPointF c = br.center();
103 double rad = std::max( br.width(), br.height() ) / 10;
104 painter->drawRoundedRect( br, rad, rad );
105 painter->drawLine( QLineF( 0, 0, br.width(), br.height() ) );
106 painter->drawLine( QLineF( br.width(), 0, 0, br.height() ) );
107
108 double nw = br.width() * 0.5;
109 double nh = br.height() * 0.5;
110 br = QRectF( c - QPointF( nw / 2, nh / 2 ), QSize( nw, nh ) );
111 painter->drawRoundedRect( br, rad, rad );
112
113 nw = br.width() * 0.5;
114 nh = br.height() * 0.5;
115 br = QRectF( c - QPointF( nw / 2, nh / 2 ), QSize( nw, nh ) );
116 painter->drawRoundedRect( br, rad, rad );
117#endif
118}
119
An abstract class for items that can be placed on the map canvas.
Map canvas is a class for displaying all GIS data types on a canvas.
Definition: qgsmapcanvas.h:90
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
Point geometry type, with support for z-dimension and m-values.
Definition: qgspoint.h:49
A rectangle specified with double values.
Definition: qgsrectangle.h:42
As part of the API refactoring and improvements which landed in the Processing API was substantially reworked from the x version This was done in order to allow much of the underlying Processing framework to be ported into c
#define QgsDebugMsgLevel(str, level)
Definition: qgslogger.h:39