All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
WellKnownMarkRenderer.cpp
Go to the documentation of this file.
1 /* Copyright (C) 2008-2011 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 terralib/qt/widgets/WellKnownMarkRenderer.cpp
22 
23  \brief A concrete renderer based on Qt4 for conversion of Symbology Enconding Mark elements to an image pattern.
24 */
25 
26 // TerraLib
27 #include "../../../common/StringUtils.h"
28 #include "../../../maptools/Utils.h"
29 #include "../../../se/Mark.h"
30 #include "../Utils.h"
31 #include "WellKnownMarkRenderer.h"
32 #include "Utils.h"
33 
34 // STL
35 #include <vector>
36 
37 // MarkMap::<name -> MarkType>
38 std::map<std::string, te::qt::widgets::WellKnownMarkRenderer::MarkType> te::qt::widgets::WellKnownMarkRenderer::sm_markMap;
39 
41  : te::map::AbstractMarkRenderer()
42 {
43  m_brush.setStyle(Qt::SolidPattern);
44  m_brush.setColor(QColor(TE_SE_DEFAULT_FILL_BASIC_COLOR));
45  buildMaps();
46  buildPaths();
47 }
48 
50 {
51 }
52 
54 {
55  // Supports the mark?
56  const std::string* name = mark->getWellKnownName();
57  std::string lname = te::common::Convert2LCase(*name);
58  std::map<std::string, MarkType>::iterator it = sm_markMap.find(lname);
59  if(it == sm_markMap.end()) // Not recognize mark!
60  return 0;
61 
62  // Gets the correct mark type from mark name
63  MarkType markType = it->second;
64 
65  // Creates the image that will represent the graphical mark pattern
66  QImage* img = new QImage(size, size, QImage::Format_ARGB32_Premultiplied);
67  img->fill(Qt::transparent);
68 
69  // Configuring visual...
70  te::qt::widgets::Config(m_pen, mark->getStroke());
71  te::qt::widgets::Config(m_brush, mark->getFill());
72 
73  // Let's draw the mark!
74  switch(markType)
75  {
77  draw(img, m_squarePath);
78  break;
79 
81  draw(img, m_circlePath);
82  break;
83 
85  draw(img, m_trianglePath);
86  break;
87 
89  draw(img, m_starPath);
90  break;
91 
93  draw(img, m_crossPath);
94  break;
95 
97  draw(img, m_xPath);
98  break;
99 
101  draw(img, m_diamondPath);
102  break;
103 
105  draw(img, m_ellipsePath);
106  break;
107 
109  draw(img, m_semiCirclePath);
110  break;
111 
113  draw(img, m_pentagonPath);
114  break;
115 
117  draw(img, m_hexagonPath);
118  break;
119 
121  draw(img, m_octagonPath);
122  break;
123  }
124 
125  // Converts QImage to te::color::RGBA**
127 
128  delete img;
129 
130  return rgba;
131 }
132 
133 void te::qt::widgets::WellKnownMarkRenderer::getSupportedMarks(std::vector<std::string>& marks) const
134 {
135  std::map<std::string, MarkType>::const_iterator it;
136  for(it = sm_markMap.begin(); it != sm_markMap.end(); ++it)
137  marks.push_back(it->first);
138 }
139 
141 {
142  // MarkMap
143  sm_markMap["square" ] = te::qt::widgets::WellKnownMarkRenderer::Square;
144  sm_markMap["circle" ] = te::qt::widgets::WellKnownMarkRenderer::Circle;
145  sm_markMap["triangle" ] = te::qt::widgets::WellKnownMarkRenderer::Triangle;
146  sm_markMap["star" ] = te::qt::widgets::WellKnownMarkRenderer::Star;
147  sm_markMap["cross" ] = te::qt::widgets::WellKnownMarkRenderer::Cross;
149  sm_markMap["diamond" ] = te::qt::widgets::WellKnownMarkRenderer::Diamond;
150  sm_markMap["ellipse" ] = te::qt::widgets::WellKnownMarkRenderer::Ellipse;
151  sm_markMap["semicircle"] = te::qt::widgets::WellKnownMarkRenderer::Semicircle;
152  sm_markMap["pentagon" ] = te::qt::widgets::WellKnownMarkRenderer::Pentagon;
153  sm_markMap["hexagon" ] = te::qt::widgets::WellKnownMarkRenderer::Hexagon;
154  sm_markMap["octagon" ] = te::qt::widgets::WellKnownMarkRenderer::Octagon;
155 }
156 
158 {
159  // Local transformation matrix
160  QTransform transform;
161 
162  // Square
163  m_squarePath.addRect(-0.5, -0.5, 1.0, 1.0);
164 
165  // Circle
166  m_circlePath.addEllipse(-0.5, -0.5, 1.0, 1.0);
167 
168  // Triangle
169  m_trianglePath.moveTo(0.0, 1.25);
170  m_trianglePath.lineTo(1.0, -0.75);
171  m_trianglePath.lineTo(-1.0, -0.75);
172  m_trianglePath.closeSubpath();
173  m_trianglePath.translate(0, -0.25);
174  m_trianglePath = transform.scale(0.5, 0.5).rotate(180).map(m_trianglePath);
175 
176  // Star
177  m_starPath.moveTo(0.191, 0.0);
178  m_starPath.lineTo(0.25, 0.344);
179  m_starPath.lineTo(0.0, 0.588);
180  m_starPath.lineTo(0.346, 0.638);
181  m_starPath.lineTo(0.5, 1.0);
182  m_starPath.lineTo(0.654, 0.638);
183  m_starPath.lineTo(1.0, 0.588);
184  m_starPath.lineTo(0.75, 0.344);
185  m_starPath.lineTo(0.8, 0.0);
186  m_starPath.lineTo(0.5, 0.162);
187  m_starPath.closeSubpath();
188  m_starPath.translate(-0.5, -0.5);
189  transform.reset();
190  m_starPath = transform.rotate(180).map(m_starPath);
191 
192  // Cross
193  m_crossPath.moveTo(0.5, 0.125);
194  m_crossPath.lineTo(0.125, 0.125);
195  m_crossPath.lineTo(0.125, 0.5);
196  m_crossPath.lineTo(-0.125, 0.5);
197  m_crossPath.lineTo(-0.125, 0.125);
198  m_crossPath.lineTo(-0.5, 0.125);
199  m_crossPath.lineTo(-0.5, -0.125);
200  m_crossPath.lineTo(-0.125, -0.125);
201  m_crossPath.lineTo(-0.125, -0.5);
202  m_crossPath.lineTo(0.125, -0.5);
203  m_crossPath.lineTo(0.125, -0.125);
204  m_crossPath.lineTo(0.5, -0.125);
205  m_crossPath.closeSubpath();
206 
207  // X
208  transform.reset();
209  m_xPath = transform.rotate(-45).map(m_crossPath);
210 
211  // Diamond
212  transform.reset();
213  m_diamondPath = transform.rotate(-45).scale(0.7, 0.7).map(m_squarePath);
214 
215  // Ellipse
216  m_ellipsePath.addEllipse(-0.5, -0.3, 1.0, 0.7);
217 
218  // Semicircle
219  m_semiCirclePath.arcTo(QRectF(-0.5, -0.5, 1.0, 1.0), 0.0, 180.0);
220  m_semiCirclePath.closeSubpath();
221 
222  // Pentagon
223  transform.reset();
224  m_pentagonPath.moveTo(-0.6, -0.75);
225  m_pentagonPath.lineTo(-1.0, 0.50);
226  m_pentagonPath.lineTo(0.0, 1.25);
227  m_pentagonPath.lineTo(1.0, 0.50);
228  m_pentagonPath.lineTo(0.6, -0.75);
229  m_pentagonPath.closeSubpath();
230  m_pentagonPath.translate(0, -0.25);
231  m_pentagonPath = transform.scale(0.5, 0.5).rotate(180).map(m_pentagonPath);
232 
233  // Hexagon
234  transform.reset();
235  m_hexagonPath.moveTo(-0.5, -0.5);
236  m_hexagonPath.lineTo(-1.0, 0.4);
237  m_hexagonPath.lineTo(-0.5, 1.1);
238  m_hexagonPath.lineTo(0.5, 1.1);
239  m_hexagonPath.lineTo(1.0, 0.4);
240  m_hexagonPath.lineTo(0.5, -0.5);
241  m_hexagonPath.closeSubpath();
242  m_hexagonPath.translate(0, -0.25);
243  m_hexagonPath = transform.scale(0.5, 0.5).rotate(180).map(m_hexagonPath);
244 
245  // Octagon
246  transform.reset();
247  m_octagonPath.moveTo(-0.5, -0.75);
248  m_octagonPath.lineTo(-1.0, -0.15);
249  m_octagonPath.lineTo(-1.0, 0.75);
250  m_octagonPath.lineTo(-0.5, 1.25);
251  m_octagonPath.lineTo(0.5, 1.25);
252  m_octagonPath.lineTo(1.0, 0.75);
253  m_octagonPath.lineTo(1.0, -0.15);
254  m_octagonPath.lineTo(0.5, -0.75);
255  m_octagonPath.closeSubpath();
256  m_octagonPath.translate(0, -0.25);
257  m_octagonPath = transform.scale(0.5, 0.5).rotate(180).map(m_octagonPath);
258 }
259 
261 {
262  m_painter.begin(img);
263  m_painter.setRenderHints(QPainter::Antialiasing);
264  m_painter.setPen(m_pen);
265  m_painter.setBrush(m_brush);
266 }
267 
269 {
270  m_painter.end();
271  m_pen = QPen(QColor(TE_SE_DEFAULT_STROKE_BASIC_COLOR));
272  m_brush = QBrush(QColor(TE_SE_DEFAULT_FILL_BASIC_COLOR), Qt::SolidPattern);
273 }
274 
275 void te::qt::widgets::WellKnownMarkRenderer::draw(QImage* img, QPainterPath& path)
276 {
277  setup(img);
278 
279  // Transformation parameters
280  double s = img->width() - m_pen.width() - 1;
281  double t = img->width() * 0.5;
282 
283  QTransform transform;
284  QPainterPath transformedPath = transform.translate(t, t).scale(s, s).map(path);
285 
286  m_painter.drawPath(transformedPath);
287 
288  end();
289 }
te::color::RGBAColor ** render(const te::se::Mark *mark, std::size_t size)
It generates the image pattern from the given Symbology Enconding Mark element.
std::string Convert2LCase(const std::string &value)
It converts a string to lower case.
Definition: StringUtils.h:197
void Config(QPen &pen, const te::se::Stroke *stroke)
It configs the given pen based on Symbology Enconding Stroke element.
Definition: Utils.cpp:38
Utility functions for MapTools module.
const Fill * getFill() const
Definition: Mark.cpp:114
const std::string * getWellKnownName() const
Definition: Mark.cpp:60
static std::map< std::string, MarkType > sm_markMap
A map that associates a well-known mark name to the correct mark type.
void buildMaps()
Builds the internal auxiliary maps to map Symbology Enconding concepts to Qt.
void setup(QImage *img)
Setups the internal QPainter and associates it with the given paint device (QImage).
MarkType
This enum specifies mark types handle by this renderer.
void end()
Finalizes the internal QPainter resources.
QBrush m_brush
The pen used to draw the mark patterns.
A helper class for 32-bit RGBA (Red-Green-Blue-Alpha channel) color.
Definition: RGBAColor.h:57
#define TE_SE_DEFAULT_STROKE_BASIC_COLOR
It specifies the default color used by stroke basic (solid colors).
Definition: Config.h:86
#define TE_SE_DEFAULT_FILL_BASIC_COLOR
It specifies the default color used by basic fill (solid colors).
Definition: Config.h:79
void draw(QImage *img, QPainterPath &path)
Draw the given path on the the given image using the internal pen and brush.
const Stroke * getStroke() const
Definition: Mark.cpp:125
void buildPaths()
Builds the pre-defined marks paths.
void getSupportedMarks(std::vector< std::string > &marks) const
Method that informs the set of supported marks by a specific concrete mark renderer.
A concrete renderer based on Qt4 for conversion of Symbology Enconding Mark elements to an image patt...
TEQTWIDGETSEXPORT QImage * GetImage(te::color::RGBAColor **img, int width, int height)
It creates a QImage from an RGBA color array.
Definition: Utils.cpp:63
A Mark specifies a geometric shape and applies coloring to it.
Definition: Mark.h:84