QGIS API Documentation  2.14.0-Essen
qgsmapoverviewcanvas.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsmapoverviewcanvas.cpp
3  Map canvas subclassed for overview
4  -------------------
5  begin : 09/14/2005
6  copyright : (C) 2005 by Martin Dobias
7  email : won.der at centrum.sk
8  ***************************************************************************/
9 
10 /***************************************************************************
11  * *
12  * This program is free software; you can redistribute it and/or modify *
13  * it under the terms of the GNU General Public License as published by *
14  * the Free Software Foundation; either version 2 of the License, or *
15  * (at your option) any later version. *
16  * *
17  ***************************************************************************/
18 
19 #include "qgsmapcanvas.h"
20 #include "qgsmaplayer.h"
21 #include "qgsmaplayerregistry.h"
22 #include "qgsmapoverviewcanvas.h"
24 #include "qgsmaptopixel.h"
25 
26 #include <QPainter>
27 #include <QPaintEvent>
28 #include <QResizeEvent>
29 #include <QMouseEvent>
30 #include "qgslogger.h"
31 #include <limits.h>
32 
33 
35  : QWidget( parent )
36  , mMapCanvas( mapCanvas )
37  , mJob( nullptr )
38 {
39  setAutoFillBackground( true );
40  setObjectName( "theOverviewCanvas" );
41  mPanningWidget = new QgsPanningWidget( this );
42 
44 
45  connect( mMapCanvas, SIGNAL( extentsChanged() ), this, SLOT( drawExtentRect() ) );
46 }
47 
49 {
50 }
51 
53 {
54  mPixmap = QPixmap();
55 
57 
59 
60  refresh();
61 
63 }
64 
66 {
67  if ( !mPixmap.isNull() )
68  {
69  QPainter paint( this );
70  paint.drawPixmap( pe->rect().topLeft(), mPixmap, pe->rect() );
71  }
72 }
73 
74 
76 {
77  if ( !mMapCanvas ) return;
78 
79  const QgsRectangle& extent = mMapCanvas->extent();
80 
81  // show only when valid extent is set
82  if ( extent.isEmpty() || mSettings.visibleExtent().isEmpty() )
83  {
84  mPanningWidget->hide();
85  return;
86  }
87 
88  const QPolygonF& vPoly = mMapCanvas->mapSettings().visiblePolygon();
89  const QgsMapToPixel& cXf = mSettings.mapToPixel();
91  pts.push_back( cXf.transform( QgsPoint( vPoly[0] ) ).toQPointF().toPoint() );
92  pts.push_back( cXf.transform( QgsPoint( vPoly[1] ) ).toQPointF().toPoint() );
93  pts.push_back( cXf.transform( QgsPoint( vPoly[2] ) ).toQPointF().toPoint() );
94  pts.push_back( cXf.transform( QgsPoint( vPoly[3] ) ).toQPointF().toPoint() );
95  mPanningWidget->setPolygon( QPolygon( pts ) );
96  mPanningWidget->show(); // show if hidden
97 }
98 
99 
101 {
102 // if (mPanningWidget->isHidden())
103 // return;
104 
105  // set offset in panning widget if inside it
106  // for better experience with panning :)
107  if ( mPanningWidget->geometry().contains( e->pos() ) )
108  {
109  mPanningCursorOffset = e->pos() - mPanningWidget->pos();
110  }
111  else
112  {
113  // use center of the panning widget if outside
114  QSize s = mPanningWidget->size();
115  mPanningCursorOffset = QPoint( s.width() / 2, s.height() / 2 );
116  }
117  updatePanningWidget( e->pos() );
118 }
119 
120 
122 {
123 // if (mPanningWidget->isHidden())
124 // return;
125 
126  if ( e->button() == Qt::LeftButton )
127  {
128  // set new extent
129  const QgsMapToPixel& cXf = mSettings.mapToPixel();
130  QRect rect = mPanningWidget->geometry();
131 
132  QgsPoint center = cXf.toMapCoordinates( rect.center() );
133  mMapCanvas->setCenter( center );
134  mMapCanvas->refresh();
135  }
136 }
137 
138 
140 {
141  // move with panning widget if tracking cursor
142  if (( e->buttons() & Qt::LeftButton ) == Qt::LeftButton )
143  {
144  updatePanningWidget( e->pos() );
145  }
146 }
147 
148 
150 {
151 // if (mPanningWidget->isHidden())
152 // return;
153  mPanningWidget->move( pos.x() - mPanningCursorOffset.x(), pos.y() - mPanningCursorOffset.y() );
154 }
155 
157 {
159 
160  if ( !mSettings.hasValidSettings() )
161  {
162  mPixmap = QPixmap();
163  update();
164  return; // makes no sense to render anything
165  }
166 
167  if ( mJob )
168  {
169  QgsDebugMsg( "oveview - cancelling old" );
170  mJob->cancel();
171  QgsDebugMsg( "oveview - deleting old" );
172  delete mJob; // get rid of previous job (if any)
173  }
174 
175  QgsDebugMsg( "oveview - starting new" );
176 
177  // TODO: setup overview mode
179  connect( mJob, SIGNAL( finished() ), this, SLOT( mapRenderingFinished() ) );
180  mJob->start();
181 
183 
184  // schedule repaint
185  update();
186 
187  // update panning widget
188  drawExtentRect();
189 }
190 
192 {
193  QgsDebugMsg( "overview - finished" );
195 
196  delete mJob;
197  mJob = nullptr;
198 
199  // schedule repaint
200  update();
201 }
202 
204 {
205  refresh();
206 }
207 
208 
210 {
211  mSettings.setBackgroundColor( color );
212 
213  // set erase color
215  palette.setColor( backgroundRole(), color );
216  setPalette( palette );
217 }
218 
220 {
221  QgsDebugMsg( "layerSet: " + layerSet.join( ", " ) );
222 
223  Q_FOREACH ( const QString& layerID, mSettings.layers() )
224  {
225  if ( QgsMapLayer* ml = QgsMapLayerRegistry::instance()->mapLayer( layerID ) )
226  disconnect( ml, SIGNAL( repaintRequested() ), this, SLOT( layerRepaintRequested() ) );
227  }
228 
229  mSettings.setLayers( layerSet );
230 
231  Q_FOREACH ( const QString& layerID, mSettings.layers() )
232  {
233  if ( QgsMapLayer* ml = QgsMapLayerRegistry::instance()->mapLayer( layerID ) )
234  connect( ml, SIGNAL( repaintRequested() ), this, SLOT( layerRepaintRequested() ) );
235  }
236 
238 }
239 
241 {
243  if ( mSettings.hasValidSettings() )
244  rect = mSettings.fullExtent();
245  else
246  rect = mMapCanvas->fullExtent();
247 
248  // expand a bit to keep features on margin
249  rect.scale( 1.1 );
250 
251  mSettings.setExtent( rect );
252  drawExtentRect();
253 }
254 
256 {
258 }
259 
261 {
263 }
264 
266 {
267  return mSettings.layers();
268 }
269 
270 
272 
273 QgsPanningWidget::QgsPanningWidget( QWidget* parent )
274  : QWidget( parent )
275 {
276  setObjectName( "panningWidget" );
277  setMinimumSize( 5, 5 );
278  setAttribute( Qt::WA_NoSystemBackground );
279 }
280 
281 void QgsPanningWidget::setPolygon( const QPolygon& p )
282 {
283  if ( p == mPoly ) return;
284  mPoly = p;
285  setGeometry( p.boundingRect() );
286  update();
287 }
288 
289 void QgsPanningWidget::paintEvent( QPaintEvent* pe )
290 {
291  Q_UNUSED( pe );
292 
293  QPainter p;
294  p.begin( this );
295  p.setPen( Qt::red );
296  QPolygonF t = mPoly.translated( -mPoly.boundingRect().left(), -mPoly.boundingRect().top() );
297  p.drawConvexPolygon( t );
298  p.end();
299 }
300 
301 
302 
QPoint mPanningCursorOffset
position of cursor inside panning widget
void setDestinationCrs(const QgsCoordinateReferenceSystem &crs)
sets destination coordinate reference system
A rectangle specified with double values.
Definition: qgsrectangle.h:35
Base class for all map layer types.
Definition: qgsmaplayer.h:49
bool isEmpty() const
test if rectangle is empty.
const QPalette & palette() const
int width() const
bool end()
void setColor(ColorGroup group, ColorRole role, const QColor &color)
QgsRectangle fullExtent() const
returns current extent of layer set
#define QgsDebugMsg(str)
Definition: qgslogger.h:33
QRect boundingRect() const
QgsMapCanvas * mMapCanvas
main map canvas - used to get/set extent
QgsMapRendererQImageJob * mJob
for rendering overview
QgsPoint transform(const QgsPoint &p) const
Transform the point from map (world) coordinates to device coordinates.
void scale(double scaleFactor, const QgsPoint *c=nullptr)
Scale the rectangle around its center point.
QPolygonF translated(qreal dx, qreal dy) const
QgsRectangle visibleExtent() const
Return the actual extent derived from requested extent that takes takes output image size into accoun...
void updatePanningWidget(QPoint pos)
called when panning to reflect mouse movement
void setAttribute(Qt::WidgetAttribute attribute, bool on)
const QgsMapSettings & mapSettings() const
Get access to properties used for map rendering.
QPixmap fromImage(const QImage &image, QFlags< Qt::ImageConversionFlag > flags)
void refresh()
Repaints the canvas map.
const QgsMapToPixel & mapToPixel() const
QString join(const QString &separator) const
Qt::MouseButtons buttons() const
void setBackgroundColor(const QColor &color)
changes background color
void setLayers(const QStringList &layers)
Set list of layer IDs for map rendering.
bool disconnect(const QObject *sender, const char *signal, const QObject *receiver, const char *method)
virtual QImage renderedImage()=0
Get a preview/resulting image.
Map canvas is a class for displaying all GIS data types on a canvas.
Definition: qgsmapcanvas.h:105
void update()
Enable drawing of labels on top of the map.
int x() const
int y() const
QgsMapLayer * mapLayer(const QString &theLayerId)
Retrieve a pointer to a loaded layer by id.
void setGeometry(int x, int y, int w, int h)
void setFlag(Flag flag, bool on=true)
Enable or disable a particular flag (other flags are not affected)
const QRect & rect() const
void setMinimumSize(const QSize &)
Perform transforms between map coordinates and device coordinates.
Definition: qgsmaptopixel.h:34
void setOutputSize(QSize size)
Set the size of the resulting map image.
QgsPanningWidget * mPanningWidget
widget for panning map in overview
bool hasValidSettings() const
Check whether the map settings are valid and can be used for rendering.
void setPen(const QColor &color)
Qt::MouseButton button() const
QgsMapSettings mSettings
map settings used for rendering of the overview map
QPalette::ColorRole backgroundRole() const
const QgsCoordinateReferenceSystem & destinationCrs() const
returns CRS of destination coordinate reference system
void drawPixmap(const QRectF &target, const QPixmap &pixmap, const QRectF &source)
void setObjectName(const QString &name)
void mouseMoveEvent(QMouseEvent *e) override
Overridden mouse move event.
QPoint pos() const
QPoint center() const
QgsMapOverviewCanvas(QWidget *parent=nullptr, QgsMapCanvas *mapCanvas=nullptr)
void refresh()
renders overview and updates panning widget
A class to represent a point.
Definition: qgspoint.h:65
QRect rect() const
const QSize & size() const
bool isNull() const
QColor backgroundColor() const
Get the background color of the map.
virtual void start()=0
Start the rendering job and immediately return.
void hasCrsTransformEnabled(bool flag)
QgsPoint toMapCoordinates(int x, int y) const
Job implementation that renders everything sequentially in one thread.
void setBackgroundColor(const QColor &color)
Set the background color of the map.
void paintEvent(QPaintEvent *pe) override
Overridden paint event.
QPixmap mPixmap
pixmap where the map is stored
static QgsMapLayerRegistry * instance()
Returns the instance pointer, creating the object on the first call.
QPoint toPoint() const
void setLayerSet(const QStringList &layerSet)
updates layer set for overview
void drawConvexPolygon(const QPointF *points, int pointCount)
QWidget(QWidget *parent, QFlags< Qt::WindowType > f)
void setExtent(const QgsRectangle &rect)
Set coordinates of the rectangle which should be rendered.
int height() const
QPoint topLeft() const
void push_back(const T &value)
void setCenter(const QgsPoint &center)
Set the center of the map canvas, in geographical coordinates.
virtual void cancel()=0
Stop the rendering job - does not return until the job has terminated.
QStringList layers() const
Get list of layer IDs for map rendering The layers are stored in the reverse order of how they are re...
void resizeEvent(QResizeEvent *e) override
Overridden resize event.
void setAutoFillBackground(bool enabled)
QgsRectangle extent() const
Returns the current zoom exent of the map canvas.
QPolygonF visiblePolygon() const
Return the visible area as a polygon (may be rotated)
const QPoint & pos() const
virtual void resizeEvent(QResizeEvent *event)
void mousePressEvent(QMouseEvent *e) override
Overridden mouse press event.
bool connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
QObject * parent() const
bool begin(QPaintDevice *device)
void mouseReleaseEvent(QMouseEvent *e) override
Overridden mouse release event.
void drawExtentRect()
used for overview canvas to reflect changed extent in main map canvas
void setCrsTransformEnabled(bool enabled)
sets whether to use projections for this layer set
QStringList layerSet() const
QgsRectangle fullExtent() const
Returns the combined exent for all layers on the map canvas.
QPointF toQPointF() const
Converts a point to a QPointF.
Definition: qgspoint.cpp:121