All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
CreatePolygonTool.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 terralib/edit/qt/tools/CreatePolygonTool.cpp
22 
23  \brief This class implements a concrete tool to create polygons.
24 */
25 
26 // TerraLib
27 #include "../../../geometry/Envelope.h"
28 #include "../../../geometry/Geometry.h"
29 #include "../../../geometry/LinearRing.h"
30 #include "../../../geometry/LineString.h"
31 #include "../../../geometry/Point.h"
32 #include "../../../geometry/Polygon.h"
33 #include "../../../qt/widgets/canvas/MapDisplay.h"
34 #include "../../../qt/widgets/Utils.h"
35 #include "../../RepositoryManager.h"
36 #include "../../Utils.h"
37 #include "../Renderer.h"
38 #include "../Utils.h"
39 #include "CreatePolygonTool.h"
40 
41 // Qt
42 #include <QMouseEvent>
43 #include <QPainter>
44 #include <QPixmap>
45 
46 // STL
47 #include <cassert>
48 #include <memory>
49 
50 te::edit::CreatePolygonTool::CreatePolygonTool(te::qt::widgets::MapDisplay* display, const te::map::AbstractLayerPtr& layer, const QCursor& cursor, QObject* parent)
51  : AbstractTool(display, parent),
52  m_layer(layer),
53  m_continuousMode(false),
54  m_isFinished(false)
55 {
56  setCursor(cursor);
57 
58  // Signals & slots
59  connect(m_display, SIGNAL(extentChanged()), SLOT(onExtentChanged()));
60 
61  draw();
62 }
63 
65 {
66  QPixmap* draft = m_display->getDraftPixmap();
67  draft->fill(Qt::transparent);
68 }
69 
71 {
72  if(e->button() != Qt::LeftButton)
73  return false;
74 
75  if(m_isFinished) // Is Finished?! So, start again...
76  {
77  clear();
78  m_isFinished = false;
79  }
80 
81  QPointF pw = m_display->transform(GetPosition(e));
82 
83  te::gm::Coord2D coord = te::gm::Coord2D(pw.x(), pw.y());
84 
85  TrySnap(coord, m_display->getSRID());
86 
87  m_coords.push_back(coord);
88 
89  return true;
90 }
91 
93 {
94  if(m_coords.size() < 1 || m_isFinished)
95  return false;
96 
97  QPointF pos = GetPosition(e);
98  pos += QPointF(0.0001, 0.0001); // To avoid collinear points on polygon
99 
100  QPointF pw = m_display->transform(pos);
101 
102  te::gm::Coord2D coord = te::gm::Coord2D(pw.x(), pw.y());
103 
104  TrySnap(coord, m_display->getSRID());
105 
106  m_coords.push_back(coord);
107 
108  m_lastPos = te::gm::Coord2D(coord.x, coord.y);
109 
110  Qt::KeyboardModifiers keys = e->modifiers();
111 
112  if(keys == Qt::NoModifier)
113  m_continuousMode = false;
114  else if(keys == Qt::ShiftModifier)
115  m_continuousMode = true;
116 
117  draw();
118 
119  return false;
120 }
121 
123 {
124  return false;
125 }
126 
128 {
129  if(e->button() != Qt::LeftButton)
130  return false;
131 
132  if(m_coords.size() < 3) // Can not stop yet...
133  return false;
134 
135  m_isFinished = true;
136 
137  storeNewGeometry();
138 
139  return true;
140 }
141 
143 {
144  const te::gm::Envelope& env = m_display->getExtent();
145  if(!env.isValid())
146  return;
147 
148  // Clear!
149  QPixmap* draft = m_display->getDraftPixmap();
150  draft->fill(Qt::transparent);
151 
152  // Initialize the renderer
153  Renderer& renderer = Renderer::getInstance();
154  renderer.begin(draft, env, m_display->getSRID());
155 
156  // Draw the layer edited geometries
157  renderer.drawRepository(m_layer->getId(), env, m_display->getSRID());
158 
159  if(!m_coords.empty())
160  {
161  // Draw the geometry being created
162  if(m_coords.size() < 3)
163  drawLine();
164  else
165  drawPolygon();
166 
167  if(m_continuousMode == false)
168  m_coords.pop_back();
169  }
170 
171  renderer.end();
172 
173  m_display->repaint();
174 }
175 
177 {
178  // Build the geometry
179  te::gm::Geometry* polygon = buildPolygon();
180 
181  // Draw the current geometry and the vertexes
182  Renderer& renderer = Renderer::getInstance();
183  renderer.draw(polygon, true);
184 
185  delete polygon;
186 }
187 
189 {
190  // Build the geometry
191  te::gm::Geometry* line = buildLine();
192 
193  // Draw the current geometry and the vertexes
194  Renderer& renderer = Renderer::getInstance();
195  renderer.draw(line, true);
196 
197  delete line;
198 }
199 
201 {
202  m_coords.clear();
203 }
204 
206 {
207  // Build the geometry
208  te::gm::LinearRing* ring = new te::gm::LinearRing(m_coords.size() + 1, te::gm::LineStringType);
209  for(std::size_t i = 0; i < m_coords.size(); ++i)
210  ring->setPoint(i, m_coords[i].x, m_coords[i].y);
211  ring->setPoint(m_coords.size(), m_coords[0].x, m_coords[0].y); // Closing...
212 
214  polygon->setRingN(0, ring);
215 
216  polygon->setSRID(m_display->getSRID());
217 
218  if(polygon->getSRID() == m_layer->getSRID())
219  return polygon;
220 
221  // else, need conversion...
222  polygon->transform(m_layer->getSRID());
223 
224  return polygon;
225 }
226 
228 {
229  te::gm::LineString* line = new te::gm::LineString(m_coords.size(), te::gm::LineStringType);
230  for(std::size_t i = 0; i < m_coords.size(); ++i)
231  line->setPoint(i, m_coords[i].x, m_coords[i].y);
232 
233  line->setSRID(m_display->getSRID());
234 
235  if(line->getSRID() == m_layer->getSRID())
236  return line;
237 
238  // else, need conversion...
239  line->transform(m_layer->getSRID());
240 
241  return line;
242 }
243 
245 {
246  RepositoryManager::getInstance().addGeometry(m_layer->getId(), buildPolygon());
247 }
248 
250 {
251  if(m_coords.empty())
252  return;
253 
254  m_coords.push_back(m_lastPos);
255 
256  draw();
257 }
int getSRID() const
It returns the Spatial Reference System ID associated to this geometric object.
Definition: Geometry.h:189
This class implements a concrete tool to create polygons.
void addGeometry(const std::string &source, te::gm::Geometry *geom)
double y
y-coordinate.
Definition: Coord2D.h:114
void transform(int srid)
It converts the coordinate values of the geometry to the new spatial reference system.
void setSRID(int srid)
It sets the Spatial Reference System ID of the geometry and all its parts if it is a GeometryCollecti...
double x
x-coordinate.
Definition: Coord2D.h:113
bool mouseReleaseEvent(QMouseEvent *e)
This event handler can be reimplemented in a concrete tool class to receive mouse release events for ...
A widget to control the display of a set of layers.
Definition: MapDisplay.h:66
An utility struct for representing 2D coordinates.
Definition: Coord2D.h:40
A LinearRing is a LineString that is both closed and simple.
Definition: LinearRing.h:53
bool mouseDoubleClickEvent(QMouseEvent *e)
This event handler can be reimplemented in a concrete tool class to receive mouse double click events...
LineString is a curve with linear interpolation between points.
Definition: LineString.h:62
static Renderer & getInstance()
It returns a reference to the singleton instance.
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
CreatePolygonTool(te::qt::widgets::MapDisplay *display, const te::map::AbstractLayerPtr &layer, const QCursor &cursor, QObject *parent=0)
It constructs a create polygon tool associated with the given map display.
TEEDITQTEXPORT QPointF GetPosition(QMouseEvent *e)
Definition: Utils.cpp:42
virtual void setCursor(const QCursor &cursor)
It sets the tool cursor.
void draw(te::gm::Geometry *geom, bool showVertexes=false)
Definition: Renderer.cpp:141
te::gm::Geometry * buildPolygon()
te::gm::Geometry * buildLine()
Geometry is the root class of the geometries hierarchy, it follows OGC and ISO standards.
Definition: Geometry.h:73
This is a singleton for rendering geometries and features.
Definition: Renderer.h:67
Polygon is a subclass of CurvePolygon whose rings are defined by linear rings.
Definition: Polygon.h:50
TEEDITEXPORT void TrySnap(te::gm::Coord2D &coord, int srid)
Definition: Utils.cpp:343
void begin(QPaintDevice *device, const te::gm::Envelope &e, int srid)
Definition: Renderer.cpp:55
void drawRepository(const std::string &source, const te::gm::Envelope &e, int srid)
Definition: Renderer.cpp:73
void setSRID(int srid)
It sets the Spatial Reference System ID of the linestring.
Definition: LineString.cpp:176
MapDisplay * m_display
The map display associated with the tool.
Definition: AbstractTool.h:160
bool mouseMoveEvent(QMouseEvent *e)
This event handler can be reimplemented in a concrete tool class to receive mouse move events for the...
bool mousePressEvent(QMouseEvent *e)
This event handler can be reimplemented in a concrete tool class to receive mouse press events for th...
boost::intrusive_ptr< AbstractLayer > AbstractLayerPtr
bool isValid() const
It tells if the rectangle is valid or not.
Definition: Envelope.h:438
void transform(int srid)
It converts the coordinate values of the linestring to the new spatial reference system.
Definition: LineString.cpp:181
void setRingN(std::size_t i, Curve *r)
It sets the informed position ring to the new one.