QGIS API Documentation  2.0.1-Dufour
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
qgshighlight.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgshighlight.cpp - widget to highlight features on the map
3  --------------------------------------
4  Date : 02-03-2011
5  Copyright : (C) 2011 by Juergen E. Fischer, norBIT GmbH
6  Email : jef at norbit dot de
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 "qgshighlight.h"
17 #include "qgsgeometry.h"
18 #include "qgsmapcanvas.h"
19 #include "qgsmaprenderer.h"
20 #include "qgscoordinatetransform.h"
21 #include "qgsvectorlayer.h"
22 
29  : QgsMapCanvasItem( mapCanvas )
30  , mLayer( layer )
31 {
32  mGeometry = geom ? new QgsGeometry( *geom ) : 0;
33  if ( mapCanvas->mapRenderer()->hasCrsTransformEnabled() )
34  {
35  QgsCoordinateTransform transform( mLayer->crs(), mapCanvas->mapRenderer()->destinationCrs() );
36  mGeometry->transform( transform );
37  }
38  updateRect();
39  update();
40  setColor( QColor( Qt::lightGray ) );
41 }
42 
44 {
45  delete mGeometry;
46 }
47 
51 void QgsHighlight::setColor( const QColor & color )
52 {
53  mPen.setColor( color );
54  QColor fillColor( color.red(), color.green(), color.blue(), 63 );
55  mBrush.setColor( fillColor );
56  mBrush.setStyle( Qt::SolidPattern );
57 }
58 
62 void QgsHighlight::setWidth( int width )
63 {
64  mPen.setWidth( width );
65 }
66 
67 void QgsHighlight::paintPoint( QPainter *p, QgsPoint point )
68 {
69  QPolygonF r( 5 );
70 
71  double d = mMapCanvas->extent().width() * 0.005;
72  r[0] = toCanvasCoordinates( point + QgsVector( -d, -d ) ) - pos();
73  r[1] = toCanvasCoordinates( point + QgsVector( d, -d ) ) - pos();
74  r[2] = toCanvasCoordinates( point + QgsVector( d, d ) ) - pos();
75  r[3] = toCanvasCoordinates( point + QgsVector( -d, d ) ) - pos();
76  r[4] = r[0];
77 
78  p->drawPolygon( r );
79 }
80 
81 void QgsHighlight::paintLine( QPainter *p, QgsPolyline line )
82 {
83  QPolygonF polygon( line.size() );
84 
85  for ( int i = 0; i < line.size(); i++ )
86  {
87  polygon[i] = toCanvasCoordinates( line[i] ) - pos();
88  }
89 
90  p->drawPolyline( polygon );
91 }
92 
93 void QgsHighlight::paintPolygon( QPainter *p, QgsPolygon polygon )
94 {
95  // OddEven fill rule by default
96  QPainterPath path;
97 
98  p->setPen( mPen );
99  p->setBrush( mBrush );
100 
101  for ( int i = 0; i < polygon.size(); i++ )
102  {
103  if ( polygon[i].empty() ) continue;
104 
105  QPolygonF ring;
106  ring.reserve( polygon[i].size() + 1 );
107 
108  for ( int j = 0; j < polygon[i].size(); j++ )
109  {
110  //adding point only if it is more than a pixel appart from the previous one
111  const QPointF cur = toCanvasCoordinates( polygon[i][j] ) - pos();
112  if ( 0 == j || std::abs( ring.back().x() - cur.x() ) > 1 || std::abs( ring.back().y() - cur.y() ) > 1 )
113  {
114  ring.push_back( cur );
115  }
116  }
117 
118  ring.push_back( ring[ 0 ] );
119 
120  path.addPolygon( ring );
121  }
122 
123  p->drawPath( path );
124 }
125 
129 void QgsHighlight::paint( QPainter* p )
130 {
131  if ( !mGeometry )
132  {
133  return;
134  }
135 
136  p->setPen( mPen );
137  p->setBrush( mBrush );
138 
139  switch ( mGeometry->wkbType() )
140  {
141  case QGis::WKBPoint:
142  case QGis::WKBPoint25D:
143  {
144  paintPoint( p, mGeometry->asPoint() );
145  }
146  break;
147 
148  case QGis::WKBMultiPoint:
150  {
152  for ( int i = 0; i < m.size(); i++ )
153  {
154  paintPoint( p, m[i] );
155  }
156  }
157  break;
158 
159  case QGis::WKBLineString:
161  {
162  paintLine( p, mGeometry->asPolyline() );
163  }
164  break;
165 
168  {
170 
171  for ( int i = 0; i < m.size(); i++ )
172  {
173  paintLine( p, m[i] );
174  }
175  }
176  break;
177 
178  case QGis::WKBPolygon:
179  case QGis::WKBPolygon25D:
180  {
182  }
183  break;
184 
187  {
189  for ( int i = 0; i < m.size(); i++ )
190  {
191  paintPolygon( p, m[i] );
192  }
193  }
194  break;
195 
196  case QGis::WKBUnknown:
197  default:
198  return;
199  }
200 }
201 
203 {
204  if ( mGeometry )
205  {
207 
208  if ( r.isEmpty() )
209  {
210  double d = mMapCanvas->extent().width() * 0.005;
211  r.setXMinimum( r.xMinimum() - d );
212  r.setYMinimum( r.yMinimum() - d );
213  r.setXMaximum( r.xMaximum() + d );
214  r.setYMaximum( r.yMaximum() + d );
215  }
216 
217  setRect( r );
218  setVisible( mGeometry );
219  }
220  else
221  {
222  setRect( QgsRectangle() );
223  }
224 }