Repository.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/Repository.cpp
22 
23  \brief This class represents a repository of geometries and features.
24 */
25 
26 // TerraLib
27 #include "../common/Exception.h"
28 #include "../common/STLUtils.h"
29 #include "../core/translator/Translator.h"
30 #include "../dataaccess/dataset/ObjectId.h"
31 #include "../datatype/SimpleData.h"
32 #include "../geometry/Coord2D.h"
33 #include "../geometry/Envelope.h"
34 #include "../geometry/Geometry.h"
35 #include "../geometry/Point.h"
36 #include "../geometry/Utils.h"
37 #include "Feature.h"
38 #include "Repository.h"
39 
40 // STL
41 #include <cassert>
42 #include <memory>
43 
44 te::edit::Repository::Repository(const std::string& source)
45  : m_source(source)
46 {
47 }
48 
50 {
51  clear();
52 }
53 
55 {
56  assert(geom);
57 
59 
60  assert(!hasIdentifier(id));
61 
62  add(id, geom);
63 
64 }
65 
67 {
68  assert(id);
69  assert(geom);
70 
71  Feature* f = new Feature(id, geom);
72 
73  add(f);
74 
75 }
76 
78 {
79  assert(f);
80 
81  // Try find the given feature
82  std::size_t pos = getPosition(f->getId());
83 
84  if(pos == std::string::npos) // Not found! Insert
85  {
86  m_features.push_back(f);
87 
88  buildIndex(m_features.size() - 1, f->getGeometry());
89 
90  return;
91  }
92 
93  // Else, set the new values
94  set(pos, f);
95 }
96 
98 {
99  assert(id);
100  assert(geom);
101 
102  Feature* f = new Feature(id, geom);
103 
104  set(f);
105 }
106 
108 {
109  assert(f);
110 
111  // Try find the given feature
112  std::size_t pos = getPosition(f->getId());
113 
114  if(pos == std::string::npos)
115  throw te::common::Exception(TE_TR("Identifier not found!"));
116 
117  set(pos, f);
118 }
119 
120 void te::edit::Repository::set(const std::size_t& pos, Feature* f)
121 {
122  assert(pos != std::string::npos);
123  assert(f);
124  assert(pos < m_features.size());
125 
126  // Cleaning...
127  delete m_features[pos];
128 
129  // Set the new values
130  m_features[pos] = f;
131 
132  // Indexing...
133  buildIndex();
134 }
135 
137 {
138  assert(id);
139 
140  // Try find the given identifier
141  std::size_t pos = getPosition(id);
142 
143  if(pos == std::string::npos)
144  throw te::common::Exception(TE_TR("Identifier not found!"));
145 
146  // Cleaning...
147  delete m_features[pos];
148 
149  // Removing...
150  m_features.erase(m_features.begin() + pos);
151 
152  // Indexing...
153  buildIndex();
154 }
155 
157 {
158  assert(id);
159 
160  for(std::size_t i = 0; i < m_features.size(); ++i)
161  if(m_features[i]->isEquals(id))
162  return i;
163 
164  return std::string::npos;
165 }
166 
168 {
169  return getPosition(id) != std::string::npos;
170 }
171 
172 const std::string& te::edit::Repository::getSource() const
173 {
174  return m_source;
175 }
176 
177 const std::vector<te::edit::Feature*>& te::edit::Repository::getAllFeatures() const
178 {
179  return m_features;
180 }
181 
182 std::vector<te::edit::Feature*> te::edit::Repository::getFeatures(const te::gm::Envelope& e, int /*srid*/) const
183 {
184  assert(e.isValid());
185 
186  std::vector<te::edit::Feature*> result;
187 
188  // Search on rtree
189  std::vector<std::size_t> report;
190  m_rtree.search(e, report);
191 
192  for(std::size_t i = 0; i < report.size(); ++i)
193  {
194  std::size_t pos = report[i];
195 
196  assert(pos < m_features.size());
197 
198  result.push_back(m_features[pos]);
199  }
200 
201  return result;
202 }
203 
205 {
206  assert(id);
207 
208  for (std::size_t i = 0; i < m_features.size(); ++i)
209  if (m_features[i]->isEquals(id))
210  return m_features[i];
211 
212  return nullptr;
213 }
214 
216 {
217  std::vector<te::edit::Feature*> candidates = getFeatures(e, srid);
218 
219  if (candidates.empty())
220  return nullptr;
221 
222  // Generates a geometry from the given extent. It will be used to refine the results
223  std::unique_ptr<te::gm::Geometry> geometryFromEnvelope(te::gm::GetGeomFromEnvelope(&e, srid));
224 
225  // The restriction point. It will be used to refine the results
226  te::gm::Coord2D center = e.getCenter();
227  te::gm::Point point(center.x, center.y, srid);
228 
229  for (std::size_t i = 0; i < candidates.size(); ++i)
230  {
231  if (!candidates[i]->isEditable())
232  continue;
233 
234  te::gm::Geometry* g = candidates[i]->getGeometry();
235 
236  if (g->getSRID() != srid)
237  g->transform(srid);
238 
239  if (g->contains(&point) || g->crosses(geometryFromEnvelope.get()) || geometryFromEnvelope->contains(g)) // Geometry found!
240  return candidates[i];
241  }
242 
243  return nullptr;
244 }
245 
247 {
249  m_features.clear();
250 
251  clearIndex();
252 }
253 
255 {
256  m_rtree.clear();
257 }
258 
260 {
261  clearIndex();
262 
263  for(std::size_t i = 0; i < m_features.size(); ++i)
264  buildIndex(i, m_features[i]->getGeometry());
265 }
266 
267 void te::edit::Repository::buildIndex(const std::size_t& pos, te::gm::Geometry* geom)
268 {
269  assert(pos != std::string::npos);
270  assert(geom);
271 
272  te::gm::Envelope mbr(*geom->getMBR());
273 
274  // Indexing...
275  m_rtree.insert(mbr, pos);
276 }
void add(te::da::ObjectId *id, te::gm::Geometry *geom)
Definition: Repository.cpp:66
void set(te::da::ObjectId *id, te::gm::Geometry *geom)
Definition: Repository.cpp:97
Feature * getFeature(const te::gm::Envelope &e, int srid) const
Definition: Repository.cpp:215
double y
y-coordinate.
Definition: Coord2D.h:114
TEEDITEXPORT te::da::ObjectId * GenerateId()
const std::vector< Feature * > & getAllFeatures() const
Definition: Repository.cpp:177
te::sam::rtree::Index< std::size_t, 8 > m_rtree
Internal index used to retrieve geometries spatially.
Definition: Repository.h:113
double x
x-coordinate.
Definition: Coord2D.h:113
te::da::ObjectId * getId() const
Definition: Feature.cpp:134
te::gm::Geometry * getGeometry() const
Definition: Feature.cpp:139
An utility struct for representing 2D coordinates.
Definition: Coord2D.h:40
Repository(const std::string &source)
Definition: Repository.cpp:44
#define TE_TR(message)
It marks a string in order to get translated.
Definition: Translator.h:242
This class represents a geographic feature.
bool hasIdentifier(te::da::ObjectId *id)
Definition: Repository.cpp:167
Coord2D getCenter() const
It returns the rectangle&#39;s center coordinate.
int getSRID() const _NOEXCEPT_OP(true)
It returns the Spatial Reference System ID associated to this geometric object.
A point with x and y coordinate values.
Definition: Point.h:50
const Envelope * getMBR() const _NOEXCEPT_OP(true)
It returns the minimum bounding rectangle for the geometry in an internal representation.
An Envelope defines a 2D rectangular region.
void add(te::gm::Geometry *geom)
Definition: Repository.cpp:54
void remove(te::da::ObjectId *id)
Definition: Repository.cpp:136
This class represents an unique id for a data set element.
This class represents a repository of geometries and features.
virtual bool contains(const Geometry *const rhs) const _NOEXCEPT_OP(false)
It returns true if this geometry object spatially contains rhs geometry.
std::vector< Feature * > m_features
The repository features.
Definition: Repository.h:112
int search(const te::gm::Envelope &mbr, std::vector< DATATYPE > &report) const
Range search query.
This class is designed to declare objects to be thrown as exceptions by TerraLib. ...
Geometry is the root class of the geometries hierarchy, it follows OGC and ISO standards.
std::string m_source
The source of the features.
Definition: Repository.h:111
std::vector< Feature * > getFeatures(const te::gm::Envelope &e, int srid) const
Definition: Repository.cpp:182
void insert(const te::gm::Envelope &mbr, const DATATYPE &data)
It inserts an item into the tree.
std::size_t getPosition(te::da::ObjectId *id)
Definition: Repository.cpp:156
const std::string & getSource() const
Definition: Repository.cpp:172
virtual bool crosses(const Geometry *const rhs) const _NOEXCEPT_OP(false)
It returns true if the geometry object spatially crosses rhs geometry.
virtual void transform(int srid) _NOEXCEPT_OP(false)=0
It converts the coordinate values of the geometry to the new spatial reference system.
void FreeContents(boost::unordered_map< K, V * > &m)
This function can be applied to a map of pointers. It will delete each pointer in the map...
Definition: BoostUtils.h:55
bool isValid() const
It tells if the rectangle is valid or not.
TEGEOMEXPORT Geometry * GetGeomFromEnvelope(const Envelope *const e, int srid)
It creates a Geometry (a polygon) from the given envelope.