QGIS API Documentation  2.8.2-Wien
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
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  setObjectName( "theOverviewCanvas" );
78  mPanningWidget = new QgsPanningWidget( this );
79 
81 
82  connect( mMapCanvas, SIGNAL( extentsChanged() ), this, SLOT( drawExtentRect() ) );
83 }
84 
86 {
87 }
88 
89 void QgsMapOverviewCanvas::resizeEvent( QResizeEvent* e )
90 {
91  mPixmap = QPixmap();
92 
93  mSettings.setOutputSize( e->size() );
94 
96 
97  refresh();
98 
100 }
101 
102 void QgsMapOverviewCanvas::paintEvent( QPaintEvent* pe )
103 {
104  if ( !mPixmap.isNull() )
105  {
106  QPainter paint( this );
107  paint.drawPixmap( pe->rect().topLeft(), mPixmap, pe->rect() );
108  }
109 }
110 
111 
113 {
114  if ( !mMapCanvas ) return;
115 
116  const QgsRectangle& extent = mMapCanvas->extent();
117 
118  // show only when valid extent is set
119  if ( extent.isEmpty() || mSettings.visibleExtent().isEmpty() )
120  {
121  mPanningWidget->hide();
122  return;
123  }
124 
125  const QPolygonF& vPoly = mMapCanvas->mapSettings().visiblePolygon();
126  const QgsMapToPixel& cXf = mSettings.mapToPixel();
127  QVector< QPoint > pts;
128  pts.push_back( cXf.transform( QgsPoint( vPoly[0] ) ).toQPointF().toPoint() );
129  pts.push_back( cXf.transform( QgsPoint( vPoly[1] ) ).toQPointF().toPoint() );
130  pts.push_back( cXf.transform( QgsPoint( vPoly[2] ) ).toQPointF().toPoint() );
131  pts.push_back( cXf.transform( QgsPoint( vPoly[3] ) ).toQPointF().toPoint() );
132  mPanningWidget->setPolygon( QPolygon( pts ) );
133  mPanningWidget->show(); // show if hidden
134 }
135 
136 
138 {
139 // if (mPanningWidget->isHidden())
140 // return;
141 
142  // set offset in panning widget if inside it
143  // for better experience with panning :)
144  if ( mPanningWidget->geometry().contains( e->pos() ) )
145  {
146  mPanningCursorOffset = e->pos() - mPanningWidget->pos();
147  }
148  else
149  {
150  // use center of the panning widget if outside
151  QSize s = mPanningWidget->size();
152  mPanningCursorOffset = QPoint( s.width() / 2, s.height() / 2 );
153  }
154  updatePanningWidget( e->pos() );
155 }
156 
157 
159 {
160 // if (mPanningWidget->isHidden())
161 // return;
162 
163  if ( e->button() == Qt::LeftButton )
164  {
165  // set new extent
166  const QgsMapToPixel& cXf = mSettings.mapToPixel();
167  QRect rect = mPanningWidget->geometry();
168 
169  QgsPoint center = cXf.toMapCoordinates( rect.center() );
170  mMapCanvas->setCenter( center );
171  mMapCanvas->refresh();
172  }
173 }
174 
175 
177 {
178  // move with panning widget if tracking cursor
179  if (( e->buttons() & Qt::LeftButton ) == Qt::LeftButton )
180  {
181  updatePanningWidget( e->pos() );
182  }
183 }
184 
185 
187 {
188 // if (mPanningWidget->isHidden())
189 // return;
190  mPanningWidget->move( pos.x() - mPanningCursorOffset.x(), pos.y() - mPanningCursorOffset.y() );
191 }
192 
194 {
196 
197  if ( !mSettings.hasValidSettings() )
198  {
199  mPixmap = QPixmap();
200  update();
201  return; // makes no sense to render anything
202  }
203 
204  if ( mJob )
205  {
206  QgsDebugMsg( "oveview - cancelling old" );
207  mJob->cancel();
208  QgsDebugMsg( "oveview - deleting old" );
209  delete mJob; // get rid of previous job (if any)
210  }
211 
212  QgsDebugMsg( "oveview - starting new" );
213 
214  // TODO: setup overview mode
216  connect( mJob, SIGNAL( finished() ), this, SLOT( mapRenderingFinished() ) );
217  mJob->start();
218 
220 
221  // schedule repaint
222  update();
223 
224  // update panning widget
225  drawExtentRect();
226 }
227 
229 {
230  QgsDebugMsg( "overview - finished" );
231  mPixmap = QPixmap::fromImage( mJob->renderedImage() );
232 
233  delete mJob;
234  mJob = 0;
235 
236  // schedule repaint
237  update();
238 }
239 
241 {
242  refresh();
243 }
244 
245 
246 void QgsMapOverviewCanvas::setBackgroundColor( const QColor& color )
247 {
248  mSettings.setBackgroundColor( color );
249 
250  // set erase color
251  QPalette palette;
252  palette.setColor( backgroundRole(), color );
253  setPalette( palette );
254 }
255 
256 void QgsMapOverviewCanvas::setLayerSet( const QStringList& layerSet )
257 {
258  QgsDebugMsg( "layerSet: " + layerSet.join( ", " ) );
259 
260  foreach ( const QString& layerID, mSettings.layers() )
261  {
262  if ( QgsMapLayer* ml = QgsMapLayerRegistry::instance()->mapLayer( layerID ) )
263  disconnect( ml, SIGNAL( repaintRequested() ), this, SLOT( layerRepaintRequested() ) );
264  }
265 
266  mSettings.setLayers( layerSet );
267 
268  foreach ( const QString& layerID, mSettings.layers() )
269  {
270  if ( QgsMapLayer* ml = QgsMapLayerRegistry::instance()->mapLayer( layerID ) )
271  connect( ml, SIGNAL( repaintRequested() ), this, SLOT( layerRepaintRequested() ) );
272  }
273 
275 }
276 
278 {
279  QgsRectangle rect;
280  if ( mSettings.hasValidSettings() )
281  rect = mSettings.fullExtent();
282  else
283  rect = mMapCanvas->fullExtent();
284 
285  // expand a bit to keep features on margin
286  rect.scale( 1.1 );
287 
288  mSettings.setExtent( rect );
289  drawExtentRect();
290 }
291 
293 {
295 }
296 
298 {
300 }
301 
303 {
304  return mSettings.layers();
305 }