All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
LegendItem.cpp
Go to the documentation of this file.
1 /* Copyright (C) 2008 National Institute For Space Research (INPE) - Brazil.
2 
3  This file is part of the TerraLib - a Framework for building GIS enabled applications.
4 
5  TerraLib is free software: you can redistribute it and/or modify
6  it under the terms of the GNU Lesser General Public License as published by
7  the Free Software Foundation, either version 3 of the License,
8  or (at your option) any later version.
9 
10  TerraLib is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  GNU Lesser General Public License for more details.
14 
15  You should have received a copy of the GNU Lesser General Public License
16  along with TerraLib. See COPYING. If not, write to
17  TerraLib Team at <terralib-team@terralib.org>.
18  */
19 
20 /*!
21  \file LegendItem.cpp
22 
23  \brief
24 
25  \ingroup layout
26 */
27 
28 // TerraLib
29 #include "LegendItem.h"
30 #include "../../core/pattern/singleton/Context.h"
31 #include "../../core/pattern/mvc/ItemController.h"
32 #include "../core/Scene.h"
33 #include "../../core/pattern/mvc/Observable.h"
34 #include "../../../color/RGBAColor.h"
35 #include "../../../qt/widgets/Utils.h"
36 #include "../../../geometry/Envelope.h"
37 #include "../../../geometry/Geometry.h"
38 #include "../../../geometry/Polygon.h"
39 #include "../../../geometry/LinearRing.h"
40 #include "../../../common/STLUtils.h"
41 #include "../../item/LegendModel.h"
42 #include "../../../maptools/AbstractLayer.h"
43 #include "../../../maptools/GroupingItem.h"
44 #include "../../../maptools/Canvas.h"
45 #include "../../../maptools/CanvasConfigurer.h"
46 #include "../../../qt/widgets/canvas/Canvas.h"
47 #include "../../../se/Symbolizer.h"
48 #include "../../../se/PolygonSymbolizer.h"
49 #include "../../../se/Fill.h"
50 #include "../../../se/Utils.h"
51 #include "../../../color/RGBAColor.h"
52 
53 
54 // Qt
55 #include <QPixmap>
56 #include <QStyle>
57 #include <QStyleOption>
58 #include <QFont>
59 #include <QPaintDevice>
60 #include <QColor>
61 #include <QMatrix>
62 
64  ObjectItem(controller, o, true),
65  m_move(false)
66 {
67  this->setFlags(QGraphicsItem::ItemIsMovable
68  | QGraphicsItem::ItemIsSelectable
69  | QGraphicsItem::ItemSendsGeometryChanges
70  | QGraphicsItem::ItemIsFocusable);
71 
72  m_nameClass = std::string(this->metaObject()->className());
73 }
74 
76 {
77 
78 }
79 
81 {
82  if(!m_model)
83  return;
84 
85  Utils* utils = context.getUtils();
86 
87  if(!utils)
88  return;
89 
90  te::gm::Envelope box = m_model->getBox();
91 
92  if(!box.isValid())
93  return;
94 
95  double widthInPixels = utils->mm2pixel(box.getWidth());
96  double heightInPixels = utils->mm2pixel(box.getHeight());
97 
98  this->setRect(QRectF(0, 0, widthInPixels, heightInPixels));
99 
100  update();
101 }
102 
103 void te::layout::LegendItem::paint( QPainter * painter, const QStyleOptionGraphicsItem * option, QWidget * widget /*= 0 */ )
104 {
105  LegendModel* legendModel = dynamic_cast<LegendModel*> (m_model);
106 
109 
110  if (legendModel == 0)
111  {
112  return;
113  }
114 
115  drawBackground(painter);
116 
117  drawBorder(painter);
118 
119  te::map::AbstractLayerPtr layer = legendModel->getLayer();
120 
121  if (!layer)
122  {
123  //Draw Selection
124  if (option->state & QStyle::State_Selected)
125  {
126  drawSelection(painter);
127  }
128 
129  return;
130  }
131 
132  std::string title = layer->getTitle();
133 
134  QString qTitle (title.c_str());
135 
136  QRectF boundRect = this->boundingRect();
137  QMatrix matrix = painter->matrix();
138 
139  te::layout::Font font = legendModel->getFont();
140  te::color::RGBAColor fontColor = legendModel->getFontColor();
141 
142  QFont qfont (QString(font.getFamily().c_str()), font.getPointSize());
143  QColor qFontColor (fontColor.getRed(), fontColor.getGreen(), fontColor.getBlue(), fontColor.getAlpha());
144 
145 
146  int borderDisplacementInPixels = utils->mm2pixel(legendModel->getBorderDisplacement());
147  int dispBetweenSymbolAndTextInPixels = utils->mm2pixel(legendModel->getDisplacementBetweenSymbolAndText());
148  int dispBetweenSymbolsInPixels = utils->mm2pixel(legendModel->getDisplacementBetweenSymbols());
149  int dispBetweenTitleAndSymbolsInPixels = utils->mm2pixel(legendModel->getDisplacementBetweenTitleAndSymbols());
150  int symbolSizeInPixels = utils->mm2pixel(legendModel->getSymbolSize());
151 
152  double x1 = boundRect.x() + borderDisplacementInPixels;
153  double y1 = boundRect.y() + borderDisplacementInPixels;
154 
155  canvas->setTextPointSize(font.getPointSize());
156  canvas->setTextUnderline(font.isUnderline());
157  canvas->setTextStrikeOut(font.isStrikeout());
158  canvas->setTextColor(legendModel->getFontColor());
159 
160  double wtxtInPixels = 0.;
161  double htxtInPixels = 0.;
162 
163  utils->textBoundingBox(wtxtInPixels, htxtInPixels, title);
164 
165  wtxtInPixels = utils->mm2pixel(wtxtInPixels);
166  htxtInPixels = utils->mm2pixel(htxtInPixels);
167 
168  QRectF rectTitle (x1, y1, wtxtInPixels, htxtInPixels);
169 
170  painter->setFont(qfont);
171  painter->setBrush(qFontColor);
172  painter->drawText(rectTitle, qTitle);
173 
174 
175  y1 += htxtInPixels + dispBetweenTitleAndSymbolsInPixels;
176 
177  te::map::Grouping* grouping = layer->getGrouping();
178 
179  if (grouping != 0 && grouping->isVisible() == true)
180  {
181  std::string propertyName = grouping->getPropertyName();
182 
183  std::vector<te::map::GroupingItem*> items = grouping->getGroupingItems();
184 
185  te::map::GroupingType type = grouping->getType();
186 
187  double labelX1 = x1 + symbolSizeInPixels + dispBetweenSymbolAndTextInPixels;
188 
189  for (unsigned int i = 0; i < items.size(); ++i)
190  {
191  std::string label = propertyName;
192  label += ": ";
193 
194  te::map::GroupingItem* item = items[i];
195 
196  if (type == te::map::UNIQUE_VALUE)
197  {
198  label += item->getValue();
199  }
200  else
201  {
202  std::string upperLimit = item->getUpperLimit();
203  std::string lowerLimit = item->getLowerLimit();
204 
205  label += lowerLimit;
206  label += " ~ ";
207  label += upperLimit;
208  }
209  painter->save();
210  QRectF labelRect (labelX1, y1, boundRect.width(), boundRect.height());
211  QString qLabel (label.c_str());
212  painter->setFont(qfont);
213  painter->setBrush(qFontColor);
214  painter->drawText(labelRect, qLabel);
215  painter->restore();
216 
217  const std::vector<te::se::Symbolizer*>& symbolizers = item->getSymbolizers();
218 
219  te::qt::widgets::Canvas geomCanvas (painter->device());
220  geomCanvas.setMatrix(matrix);
221 
222  foreach (te::se::Symbolizer* symbol, symbolizers)
223  {
224  double offset = 2.0;
225  QRectF geomRect (x1, y1, symbolSizeInPixels, symbolSizeInPixels);
226 
227  te::gm::Geometry* geom = 0;
228  if (symbol->getType() == "PolygonSymbolizer")
229  {
232  ring->setPoint(0, x1 + offset, y1 + offset);
233  ring->setPoint(1, x1 + geomRect.width() - offset, y1 + offset);
234  ring->setPoint(2, x1 + geomRect.width() - offset, y1 + geomRect.height() - offset);
235  ring->setPoint(3, x1 + offset, y1 + geomRect.height() - offset);
236  ring->setPoint(4, x1 + offset, y1 + offset);
237  polygon->setRingN(0, ring);
238  geom = polygon;
239  }
240  else if (symbol->getType() == "LineSymbolizer")
241  {
243  line->setPoint(0, x1 + offset, y1 + geomRect.height() * 0.5);
244  line->setPoint(1, x1 + geomRect.width() - offset, y1 + geomRect.height() * 0.5);
245  geom = line;
246  }
247  else if (symbol->getType() == "PointSymbolizer")
248  {
249  geom = new te::gm::Point( x1 +geomRect.width() * 0.5, y1 +geomRect.height() * 0.5);
250  }
251 
252  // Configuring...
253  te::map::CanvasConfigurer cc(&geomCanvas);
254  cc.config(symbol);
255 
256  // Let's draw!
257  geomCanvas.draw(geom);
258 
259  }
260 
261  y1 += htxtInPixels + dispBetweenSymbolsInPixels;
262  }
263  }
264 
265  //Draw Selection
266  if (option->state & QStyle::State_Selected)
267  {
268  drawSelection(painter);
269  }
270 
271  update();
272 }
273 
274 QVariant te::layout::LegendItem::itemChange( GraphicsItemChange change, const QVariant & value )
275 {
276  if(change == QGraphicsItem::ItemPositionChange && !m_move)
277  {
278  // value is the new position.
279  QPointF newPos = value.toPointF();
280  double h = 0;
281 
282  newPos.setX(newPos.x() - transform().dx());
283  newPos.setY(newPos.y() - transform().dy() + h);
284  return newPos;
285  }
286  else if(change == QGraphicsItem::ItemPositionHasChanged)
287  {
288  refresh();
289  m_move = false;
290  }
291 
292  return QGraphicsItem::itemChange(change, value);
293 }
294 
295 void te::layout::LegendItem::mouseMoveEvent( QGraphicsSceneMouseEvent * event )
296 {
297  m_move = true;
298 
299  QGraphicsItem::mouseMoveEvent(event);
300 }
301 
virtual double getDisplacementBetweenTitleAndSymbols()
Abstract class to represent an observable. "Model" part of MVC component.
Definition: Observable.h:56
Class responsible for maintaining the drawing context of a MVC component. It is always used by the "M...
Definition: ContextItem.h:49
Class specifies a font.
Definition: Font.h:46
Class that represents a "Model" part of Legend MVC component. Its coordinate system is the same of sc...
Definition: LegendModel.h:62
bool isStrikeout()
Returns true if font use strikeout, false otherwise.
Definition: Font.cpp:111
int getRed() const
It returns the red component color value (a value from 0 to 255).
Definition: RGBAColor.h:295
virtual double getSymbolSize()
virtual void textBoundingBox(double &w, double &h, std::string txt)
A method that calculates the height and width of a text.
Definition: Utils.cpp:271
const std::string & getValue() const
It gets the value of the legend item.
A Symbolizer describes how a feature is to appear on a map.
Definition: Symbolizer.h:80
virtual void updateObserver(ContextItem context)
Reimplemented from ObjectItem.
Definition: LegendItem.cpp:80
std::string getPropertyName() const
It gets the property name whose values will be grouped.
Definition: Grouping.cpp:68
int getPointSize()
Returns point size of the font.
Definition: Font.cpp:71
virtual te::map::AbstractLayerPtr getLayer()
int getBlue() const
It returns the blue component color value (a value from 0 to 255).
Definition: RGBAColor.h:305
virtual te::color::RGBAColor getFontColor()
int getGreen() const
It returns the green component color value (a value from 0 to 255).
Definition: RGBAColor.h:300
double getWidth() const
It returns the envelope width.
Definition: Envelope.h:443
Abstract class to represent a controller. "Controller" part of MVC component. All classes representin...
virtual ~LegendItem()
Destructor.
Definition: LegendItem.cpp:75
virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget=0)
Mandatory implementation from QGraphicsObject.
Definition: LegendItem.cpp:103
virtual Font getFont()
This class contains the parameters needed for grouping the values of a Property.
Definition: Grouping.h:59
A LinearRing is a LineString that is both closed and simple.
Definition: LinearRing.h:53
virtual void setTextUnderline(bool b)=0
It sets the text underline flag.
virtual int mm2pixel(double mm)
Millimeter to pixel.
Definition: Utils.cpp:131
LineString is a curve with linear interpolation between points.
Definition: LineString.h:62
Abstract class that represents a graphic item. This object is of type QGraphicsObject.
Definition: ObjectItem.h:61
static Context & getInstance()
It returns a reference to the singleton instance.
A point with x and y coordinate values.
Definition: Point.h:50
void setPoint(std::size_t i, const double &x, const double &y)
It sets the value of the specified point.
Definition: LineString.cpp:353
An Envelope defines a 2D rectangular region.
Definition: Envelope.h:51
A GroupingItem contains information about a grouping item associated to a layer.
Definition: GroupingItem.h:48
virtual Utils * getUtils()
void setMatrix(const QMatrix &matrix)
Definition: Canvas.cpp:2222
virtual double getDisplacementBetweenSymbols()
virtual void setTextColor(const te::color::RGBAColor &color)=0
It sets the text drawing color.
Utils * getUtils()
Returns pointer with functions to manipulate the canvas and conversion between projections.
Definition: Context.cpp:153
int getAlpha() const
It returns the alpha component color value (a value from 0 to 255).
Definition: RGBAColor.h:310
std::string m_nameClass
Class name.
Definition: ItemObserver.h:201
bool isUnderline()
Returns true if font use underline, false otherwise.
Definition: Font.cpp:101
Geometry is the root class of the geometries hierarchy, it follows OGC and ISO standards.
Definition: Geometry.h:73
LegendItem(ItemController *controller, Observable *o)
Constructor.
Definition: LegendItem.cpp:63
A canvas built on top of Qt.
Definition: Canvas.h:54
virtual void setTextStrikeOut(bool b)=0
It sets the text strike out flag.
A canvas is an abstraction of a drawing area.
Definition: Canvas.h:91
bool isVisible() const
It gets the grouping visibility.
Definition: Grouping.cpp:142
const std::vector< te::map::GroupingItem * > & getGroupingItems() const
It gets the vector of grouping items.
Definition: Grouping.cpp:130
Polygon is a subclass of CurvePolygon whose rings are defined by linear rings.
Definition: Polygon.h:50
GroupingType
The grouping type associated to the layer.
Definition: Enums.h:150
const std::string & getUpperLimit() const
It gets the upper limit value of the legend item.
virtual double getBorderDisplacement()
virtual void mouseMoveEvent(QGraphicsSceneMouseEvent *event)
Reimplemented from QGraphicsItem.
Definition: LegendItem.cpp:295
virtual QVariant itemChange(GraphicsItemChange change, const QVariant &value)
Reimplemented from QGraphicsItem.
Definition: LegendItem.cpp:274
A helper class for 32-bit RGBA (Red-Green-Blue-Alpha channel) color.
Definition: RGBAColor.h:57
const GroupingType getType() const
It gets the grouping type.
Definition: Grouping.cpp:90
std::string getFamily()
Sets font family name.
Definition: Font.cpp:61
void config(const te::se::Symbolizer *symbolizer)
It configs the canvas based on given symbolizer.
const std::string & getLowerLimit() const
It gets the lower limit value of the legend item.
const std::vector< te::se::Symbolizer * > & getSymbolizers() const
It gets the symbolizer of the legend item.
virtual const std::string & getType() const =0
It returns the symbolizer type.
Utility class with functions to manipulate the canvas and conversion between projections.
Definition: Utils.h:61
boost::intrusive_ptr< AbstractLayer > AbstractLayerPtr
double getHeight() const
It returns the envelope height.
Definition: Envelope.h:448
bool isValid() const
It tells if the rectangle is valid or not.
Definition: Envelope.h:438
virtual double getDisplacementBetweenSymbolAndText()
te::map::Canvas * getCanvas()
Returns abstraction of a drawing area.
Definition: Context.cpp:143
void setRingN(std::size_t i, Curve *r)
It sets the informed position ring to the new one.
virtual void setTextPointSize(double size)=0
It sets the text point Size.
A Symbology Enconding visitor that configures a given canvas based on symbolizers elements...