QGIS API Documentation  2.8.6-Wien
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 
34 class QgsPanningWidget : public QWidget
35 {
36  QPolygon mPoly;
37 
38  public:
39  QgsPanningWidget( QWidget* parent )
40  : QWidget( parent )
41  {
42  setObjectName( "panningWidget" );
43  setMinimumSize( 5, 5 );
44  setAttribute( Qt::WA_NoSystemBackground );
45  }
46 
47  void setPolygon( const QPolygon& p )
48  {
49  if ( p == mPoly ) return;
50  mPoly = p;
51  setGeometry( p.boundingRect() );
52  update();
53  }
54 
55 
56  void paintEvent( QPaintEvent* pe ) override
57  {
58  Q_UNUSED( pe );
59 
60  QPainter p;
61  p.begin( this );
62  p.setPen( Qt::red );
63  QPolygonF t = mPoly.translated( -mPoly.boundingRect().left(), -mPoly.boundingRect().top() );
64  p.drawConvexPolygon( t );
65  p.end();
66  }
67 
68 };
69 
70 
71 
73  : QWidget( parent )
74  , mMapCanvas( mapCanvas )
75  , mJob( 0 )
76 {
77  setAutoFillBackground( true );
78  setObjectName( "theOverviewCanvas" );
79  mPanningWidget = new QgsPanningWidget( this );
80 
82 
83  connect( mMapCanvas, SIGNAL( extentsChanged() ), this, SLOT( drawExtentRect() ) );
84 }
85 
87 {
88 }
89 
90 void QgsMapOverviewCanvas::resizeEvent( QResizeEvent* e )
91 {
92  mPixmap = QPixmap();
93 
94  mSettings.setOutputSize( e->size() );
95 
97 
98  refresh();
99 
100  QWidget::resizeEvent( e );
101 }
102 
103 void QgsMapOverviewCanvas::paintEvent( QPaintEvent* pe )
104 {
105  if ( !mPixmap.isNull() )
106  {
107  QPainter paint( this );
108  paint.drawPixmap( pe->rect().topLeft(), mPixmap, pe->rect() );
109  }
110 }
111 
112 
114 {
115  if ( !mMapCanvas ) return;
116 
117  const QgsRectangle& extent = mMapCanvas->extent();
118 
119  // show only when valid extent is set
120  if ( extent.isEmpty() || mSettings.visibleExtent().isEmpty() )
121  {
122  mPanningWidget->hide();
123  return;
124  }
125 
126  const QPolygonF& vPoly = mMapCanvas->mapSettings().visiblePolygon();
127  const QgsMapToPixel& cXf = mSettings.mapToPixel();
128  QVector< QPoint > pts;
129  pts.push_back( cXf.transform( QgsPoint( vPoly[0] ) ).toQPointF().toPoint() );
130  pts.push_back( cXf.transform( QgsPoint( vPoly[1] ) ).toQPointF().toPoint() );
131  pts.push_back( cXf.transform( QgsPoint( vPoly[2] ) ).toQPointF().toPoint() );
132  pts.push_back( cXf.transform( QgsPoint( vPoly[3] ) ).toQPointF().toPoint() );
133  mPanningWidget->setPolygon( QPolygon( pts ) );
134  mPanningWidget->show(); // show if hidden
135 }
136 
137 
139 {
140 // if (mPanningWidget->isHidden())
141 // return;
142 
143  // set offset in panning widget if inside it
144  // for better experience with panning :)
145  if ( mPanningWidget->geometry().contains( e->pos() ) )
146  {
147  mPanningCursorOffset = e->pos() - mPanningWidget->pos();
148  }
149  else
150  {
151  // use center of the panning widget if outside
152  QSize s = mPanningWidget->size();
153  mPanningCursorOffset = QPoint( s.width() / 2, s.height() / 2 );
154  }
155  updatePanningWidget( e->pos() );
156 }
157 
158 
160 {
161 // if (mPanningWidget->isHidden())
162 // return;
163 
164  if ( e->button() == Qt::LeftButton )
165  {
166  // set new extent
167  const QgsMapToPixel& cXf = mSettings.mapToPixel();
168  QRect rect = mPanningWidget->geometry();
169 
170  QgsPoint center = cXf.toMapCoordinates( rect.center() );
171  mMapCanvas->setCenter( center );
172  mMapCanvas->refresh();
173  }
174 }
175 
176 
178 {
179  // move with panning widget if tracking cursor
180  if (( e->buttons() & Qt::LeftButton ) == Qt::LeftButton )
181  {
182  updatePanningWidget( e->pos() );
183  }
184 }
185 
186 
188 {
189 // if (mPanningWidget->isHidden())
190 // return;
191  mPanningWidget->move( pos.x() - mPanningCursorOffset.x(), pos.y() - mPanningCursorOffset.y() );
192 }
193 
195 {
197 
198  if ( !mSettings.hasValidSettings() )
199  {
200  mPixmap = QPixmap();
201  update();
202  return; // makes no sense to render anything
203  }
204 
205  if ( mJob )
206  {
207  QgsDebugMsg( "oveview - cancelling old" );
208  mJob->cancel();
209  QgsDebugMsg( "oveview - deleting old" );
210  delete mJob; // get rid of previous job (if any)
211  }
212 
213  QgsDebugMsg( "oveview - starting new" );
214 
215  // TODO: setup overview mode
217  connect( mJob, SIGNAL( finished() ), this, SLOT( mapRenderingFinished() ) );
218  mJob->start();
219 
221 
222  // schedule repaint
223  update();
224 
225  // update panning widget
226  drawExtentRect();
227 }
228 
230 {
231  QgsDebugMsg( "overview - finished" );
232  mPixmap = QPixmap::fromImage( mJob->renderedImage() );
233 
234  delete mJob;
235  mJob = 0;
236 
237  // schedule repaint
238  update();
239 }
240 
242 {
243  refresh();
244 }
245 
246 
247 void QgsMapOverviewCanvas::setBackgroundColor( const QColor& color )
248 {
249  mSettings.setBackgroundColor( color );
250 
251  // set erase color
252  QPalette palette;
253  palette.setColor( backgroundRole(), color );
254  setPalette( palette );
255 }
256 
257 void QgsMapOverviewCanvas::setLayerSet( const QStringList& layerSet )
258 {
259  QgsDebugMsg( "layerSet: " + layerSet.join( ", " ) );
260 
261  foreach ( const QString& layerID, mSettings.layers() )
262  {
263  if ( QgsMapLayer* ml = QgsMapLayerRegistry::instance()->mapLayer( layerID ) )
264  disconnect( ml, SIGNAL( repaintRequested() ), this, SLOT( layerRepaintRequested() ) );
265  }
266 
267  mSettings.setLayers( layerSet );
268 
269  foreach ( const QString& layerID, mSettings.layers() )
270  {
271  if ( QgsMapLayer* ml = QgsMapLayerRegistry::instance()->mapLayer( layerID ) )
272  connect( ml, SIGNAL( repaintRequested() ), this, SLOT( layerRepaintRequested() ) );
273  }
274 
276 }
277 
279 {
280  QgsRectangle rect;
281  if ( mSettings.hasValidSettings() )
282  rect = mSettings.fullExtent();
283  else
284  rect = mMapCanvas->fullExtent();
285 
286  // expand a bit to keep features on margin
287  rect.scale( 1.1 );
288 
289  mSettings.setExtent( rect );
290  drawExtentRect();
291 }
292 
294 {
296 }
297 
299 {
301 }
302 
304 {
305  return mSettings.layers();
306 }
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.
QgsRectangle fullExtent() const
returns current extent of layer set
#define QgsDebugMsg(str)
Definition: qgslogger.h:33
QgsMapCanvas * mMapCanvas
main map canvas - used to get/set extent
QgsMapRendererQImageJob * mJob
for rendering overview
QgsPoint transform(const QgsPoint &p) const
static QgsMapLayerRegistry * instance()
Definition: qgssingleton.h:23
QgsRectangle visibleExtent() const
Return the actual extent derived from requested extent that takes takes output image size into accoun...
const QgsMapSettings & mapSettings() const
Get access to properties used for map rendering.
void refresh()
Repaints the canvas map.
const QgsMapToPixel & mapToPixel() const
void setBackgroundColor(const QColor &color)
changes background color
widget that serves as rectangle showing current extent in overview
void setLayers(const QStringList &layers)
Set list of layer IDs for map rendering.
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
Enable drawing of labels on top of the map.
void setFlag(Flag flag, bool on=true)
Enable or disable a particular flag (other flags are not affected)
Perform transforms between map coordinates and device coordinates.
Definition: qgsmaptopixel.h:34
QgsPanningWidget * mPanningWidget
widget for panning map in overview
bool hasValidSettings() const
Check whether the map settings are valid and can be used for rendering.
QgsMapSettings mSettings
map settings used for rendering of the overview map
const QgsCoordinateReferenceSystem & destinationCrs() const
returns CRS of destination coordinate reference system
QgsPanningWidget(QWidget *parent)
void mouseMoveEvent(QMouseEvent *e) override
Overridden mouse move event.
void refresh()
renders overview and updates panning widget
A class to represent a point.
Definition: qgspoint.h:63
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
void setLayerSet(const QStringList &layerSet)
updates layer set for overview
void setOutputSize(const QSize &size)
Set the size of the resulting map image.
void setPolygon(const QPolygon &p)
void setExtent(const QgsRectangle &rect)
Set coordinates of the rectangle which should be rendered.
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.
QgsMapLayer * mapLayer(QString theLayerId)
Retrieve a pointer to a loaded layer by id.
void paintEvent(QPaintEvent *pe) override
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)
void mousePressEvent(QMouseEvent *e) override
Overridden mouse press event.
QgsMapOverviewCanvas(QWidget *parent=0, QgsMapCanvas *mapCanvas=NULL)
void mouseReleaseEvent(QMouseEvent *e) override
Overridden mouse release event.
void updatePanningWidget(const QPoint &pos)
called when panning to reflect mouse movement
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
void scale(double scaleFactor, const QgsPoint *c=0)
Scale the rectangle around its center point.