QGIS API Documentation  3.4.15-Madeira (e83d02e274)
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 
27 QgsMapCanvasMap::QgsMapCanvasMap( QgsMapCanvas *canvas )
28  : QgsMapCanvasItem( canvas )
29 {
30  setZValue( -10 );
31 }
32 
33 void 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 
47 void QgsMapCanvasMap::addPreviewImage( const QImage &image, const QgsRectangle &rect )
48 {
49  mPreviewImages.append( qMakePair( image, rect ) );
50  update();
51 }
52 
53 QRectF QgsMapCanvasMap::boundingRect() const
54 {
55  double width = mItemSize.width();
56  double height = mItemSize.height();
57 
58  return QRectF( -width, -height, 3 * width, 3 * height );
59 }
60 
61 void QgsMapCanvasMap::paint( QPainter *painter )
62 {
63  // setRect() makes the size +2 :-(
64  int w = std::round( mItemSize.width() ) - 2;
65  int h = std::round( mItemSize.height() ) - 2;
66 
67  bool scale = false;
68 #if QT_VERSION >= 0x050600
69  if ( mImage.size() != QSize( w, h ) * mImage.devicePixelRatioF() )
70 #else
71  if ( mImage.size() != QSize( w, h ) * mImage.devicePixelRatio() )
72 #endif
73  {
74 #if QT_VERSION >= 0x050600
75  QgsDebugMsg( QStringLiteral( "map paint DIFFERENT SIZE: img %1,%2 item %3,%4" )
76  .arg( mImage.width() / mImage.devicePixelRatioF() )
77  .arg( mImage.height() / mImage.devicePixelRatioF() )
78  .arg( w ).arg( h ) );
79 #else
80  QgsDebugMsg( QStringLiteral( "map paint DIFFERENT SIZE: img %1,%2 item %3,%4" )
81  .arg( mImage.width() / mImage.devicePixelRatio() )
82  .arg( mImage.height() / mImage.devicePixelRatio() )
83  .arg( w ).arg( h ) );
84 #endif
85  // This happens on zoom events when ::paint is called before
86  // the renderer has completed
87  scale = true;
88  }
89 
90  /*Offset between 0/0 and mRect.xMinimum/mRect.yMinimum.
91  We need to consider the offset, because mRect is not updated yet and there might be an offset*/
92  QgsPointXY pt = toMapCoordinates( QPoint( 0, 0 ) );
93  double offsetX = pt.x() - mRect.xMinimum();
94  double offsetY = pt.y() - mRect.yMaximum();
95 
96  //draw preview images first
97  QList< QPair< QImage, QgsRectangle > >::const_iterator imIt = mPreviewImages.constBegin();
98  for ( ; imIt != mPreviewImages.constEnd(); ++imIt )
99  {
100  QPointF ul = toCanvasCoordinates( QgsPoint( imIt->second.xMinimum() + offsetX, imIt->second.yMaximum() + offsetY ) );
101  QPointF lr = toCanvasCoordinates( QgsPoint( imIt->second.xMaximum() + offsetX, imIt->second.yMinimum() + offsetY ) );
102  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() ) );
103  }
104 
105  if ( scale )
106  painter->drawImage( QRect( 0, 0, w, h ), mImage );
107  else
108  painter->drawImage( 0, 0, mImage );
109 
110  // For debugging:
111 #if 0
112  QRectF br = boundingRect();
113  QPointF c = br.center();
114  double rad = std::max( br.width(), br.height() ) / 10;
115  painter->drawRoundedRect( br, rad, rad );
116  painter->drawLine( QLineF( 0, 0, br.width(), br.height() ) );
117  painter->drawLine( QLineF( br.width(), 0, 0, br.height() ) );
118 
119  double nw = br.width() * 0.5;
120  double nh = br.height() * 0.5;
121  br = QRectF( c - QPointF( nw / 2, nh / 2 ), QSize( nw, nh ) );
122  painter->drawRoundedRect( br, rad, rad );
123 
124  nw = br.width() * 0.5;
125  nh = br.height() * 0.5;
126  br = QRectF( c - QPointF( nw / 2, nh / 2 ), QSize( nw, nh ) );
127  painter->drawRoundedRect( br, rad, rad );
128 #endif
129 }
130 
A rectangle specified with double values.
Definition: qgsrectangle.h:40
double yMaximum() const
Returns the y maximum value (top side of rectangle).
Definition: qgsrectangle.h:171
#define QgsDebugMsg(str)
Definition: qgslogger.h:38
double y
Definition: qgspointxy.h:48
A class to represent a 2D point.
Definition: qgspointxy.h:43
An abstract class for items that can be placed on the map canvas.
QgsRectangle rect() const
returns canvas item rectangle in map units
Map canvas is a class for displaying all GIS data types on a canvas.
Definition: qgsmapcanvas.h:74
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
QSizeF mItemSize
cached size of the item (to return in boundingRect())
QRectF boundingRect() const override
void setRect(const QgsRectangle &r, bool resetRotation=true)
sets canvas item rectangle in map units
QgsRectangle mRect
cached canvas item rectangle in map coordinates encodes position (xmin,ymax) and size (width/height) ...
Point geometry type, with support for z-dimension and m-values.
Definition: qgspoint.h:37
double x
Definition: qgspointxy.h:47
QgsPointXY toMapCoordinates(QPoint point) const
transformation from screen coordinates to map coordinates
QgsMapCanvas * mMapCanvas
pointer to map canvas
QPointF toCanvasCoordinates(const QgsPointXY &point) const
transformation from map coordinates to screen coordinates
double xMinimum() const
Returns the x minimum value (left side of rectangle).
Definition: qgsrectangle.h:166