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 "../common/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 #include "Utils.h"
40 
41 // STL
42 #include <cassert>
43 #include <memory>
44 
45 te::edit::Repository::Repository(const std::string& source)
46  : m_source(source)
47 {
48 }
49 
51 {
52  clear();
53 }
54 
56 {
57  assert(geom);
58 
60 
61  assert(!hasIdentifier(id));
62 
63  add(id, geom);
64 }
65 
67 {
68  assert(id);
69  assert(geom);
70 
71  Feature* f = new Feature(id, geom);
72 
73  add(f);
74 }
75 
77 {
78  assert(f);
79 
80  // Try find the given feature
81  std::size_t pos = getPosition(f->getId());
82 
83  if(pos == std::string::npos) // Not found! Insert
84  {
85  m_features.push_back(f);
86 
87  buildIndex(m_features.size() - 1, f->getGeometry());
88 
89  return;
90  }
91 
92  // Else, set the new values
93  set(pos, f);
94 }
95 
97 {
98  assert(id);
99  assert(geom);
100 
101  Feature* f = new Feature(id, geom);
102 
103  set(f);
104 }
105 
107 {
108  assert(f);
109 
110  // Try find the given feature
111  std::size_t pos = getPosition(f->getId());
112 
113  if(pos == std::string::npos)
114  throw te::common::Exception(TE_TR("Identifier not found!"));
115 
116  set(pos, f);
117 }
118 
120 {
121  assert(id);
122 
123  // Try find the given identifier
124  std::size_t pos = getPosition(id);
125 
126  if(pos == std::string::npos)
127  throw te::common::Exception(TE_TR("Identifier not found!"));
128 
129  // Cleaning...
130  delete m_features[pos];
131 
132  // Removing...
133  m_features.erase(m_features.begin() + pos);
134 
135  // Indexing...
136  buildIndex();
137 }
138 
140 {
141  assert(id);
142 
143  for(std::size_t i = 0; i < m_features.size(); ++i)
144  if(m_features[i]->isEquals(id))
145  return i;
146 
147  return std::string::npos;
148 }
149 
151 {
152  return getPosition(id) != std::string::npos;
153 }
154 
155 const std::string& te::edit::Repository::getSource() const
156 {
157  return m_source;
158 }
159 
160 const std::vector<te::edit::Feature*>& te::edit::Repository::getAllFeatures() const
161 {
162  return m_features;
163 }
164 
165 std::vector<te::edit::Feature*> te::edit::Repository::getNewFeatures() const
166 {
167  std::vector<te::edit::Feature*> result;
168 
169  for(std::size_t i = 0; i < m_features.size(); ++i)
170  {
171  Feature* f = m_features[i];
172  assert(f);
173  assert(f->getId());
174 
175  if(f->getId()->getValueAsString().find(NEW_FEATURE_ID_SUFFIX) != std::string::npos)
176  result.push_back(f);
177  }
178 
179  return result;
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  std::vector<te::edit::Feature*> candidates = getFeatures(e, srid);
207 
208  if(candidates.empty())
209  return 0;
210 
211  // Generates a geometry from the given extent. It will be used to refine the results
212  std::auto_ptr<te::gm::Geometry> geometryFromEnvelope(te::gm::GetGeomFromEnvelope(&e, srid));
213 
214  // The restriction point. It will be used to refine the results
215  te::gm::Coord2D center = e.getCenter();
216  te::gm::Point point(center.x, center.y, srid);
217 
218  for(std::size_t i = 0; i < candidates.size(); ++i)
219  {
220  te::gm::Geometry* g = candidates[i]->getGeometry();
221 
222  if(g->contains(&point) || g->crosses(geometryFromEnvelope.get()) || geometryFromEnvelope->contains(g)) // Geometry found!
223  return candidates[i];
224  }
225 
226  return 0;
227 }
228 
230 {
231  te::common::FreeContents(m_features);
232  m_features.clear();
233 
234  clearIndex();
235 }
236 
237 void te::edit::Repository::set(const std::size_t& pos, Feature* f)
238 {
239  assert(pos != std::string::npos);
240  assert(f);
241  assert(pos < m_features.size());
242 
243  // Cleaning...
244  delete m_features[pos];
245 
246  // Set the new values
247  m_features[pos] = f;
248 
249  // Indexing...
250  buildIndex();
251 }
252 
254 {
255  m_rtree.clear();
256 }
257 
259 {
260  clearIndex();
261 
262  for(std::size_t i = 0; i < m_features.size(); ++i)
263  buildIndex(i, m_features[i]->getGeometry());
264 }
265 
266 void te::edit::Repository::buildIndex(const std::size_t& pos, te::gm::Geometry* geom)
267 {
268  assert(pos != std::string::npos);
269  assert(geom);
270 
271  te::gm::Envelope mbr(*geom->getMBR());
272 
273  // Indexing...
274  m_rtree.insert(mbr, pos);
275 }
void set(te::da::ObjectId *id, te::gm::Geometry *geom)
Definition: Repository.cpp:96
Feature * getFeature(const te::gm::Envelope &e, int srid) const
Definition: Repository.cpp:204
double y
y-coordinate.
Definition: Coord2D.h:114
TEEDITEXPORT te::da::ObjectId * GenerateId()
Definition: Utils.cpp:361
const std::vector< Feature * > & getAllFeatures() const
Definition: Repository.cpp:160
std::vector< Feature * > getNewFeatures() const
Definition: Repository.cpp:165
double x
x-coordinate.
Definition: Coord2D.h:113
te::da::ObjectId * getId() const
Definition: Feature.cpp:93
#define NEW_FEATURE_ID_SUFFIX
Definition: Config.h:31
te::gm::Geometry * getGeometry() const
Definition: Feature.cpp:98
An utility struct for representing 2D coordinates.
Definition: Coord2D.h:40
virtual bool contains(const Geometry *const rhs) const
It returns true if this geometry object spatially contains rhs geometry.
Definition: Geometry.cpp:330
Repository(const std::string &source)
Definition: Repository.cpp:45
#define TE_TR(message)
It marks a string in order to get translated.
Definition: Translator.h:346
This class represents a geographic feature.
bool hasIdentifier(te::da::ObjectId *id)
Definition: Repository.cpp:150
virtual bool crosses(const Geometry *const rhs) const
It returns true if the geometry object spatially crosses rhs geometry.
Definition: Geometry.cpp:292
Coord2D getCenter() const
It returns the rectangle's center coordinate.
Definition: Envelope.cpp:51
A point with x and y coordinate values.
Definition: Point.h:50
An Envelope defines a 2D rectangular region.
Definition: Envelope.h:51
void add(te::gm::Geometry *geom)
Definition: Repository.cpp:55
void remove(te::da::ObjectId *id)
Definition: Repository.cpp:119
This class represents an unique id for a data set element.
Definition: ObjectId.h:47
This class represents a repository of geometries and features.
std::string getValueAsString() const
It gets the properties values used to uniquely identify a data set element as string.
Definition: ObjectId.cpp:51
This class is designed to declare objects to be thrown as exceptions by TerraLib. ...
Definition: Exception.h:58
Geometry is the root class of the geometries hierarchy, it follows OGC and ISO standards.
Definition: Geometry.h:73
std::vector< Feature * > getFeatures(const te::gm::Envelope &e, int srid) const
Definition: Repository.cpp:182
std::size_t getPosition(te::da::ObjectId *id)
Definition: Repository.cpp:139
Utility functions for TerraLib Edit module.
const std::string & getSource() const
Definition: Repository.cpp:155
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
const Envelope * getMBR() const
It returns the minimum bounding rectangle for the geometry in an internal representation.
Definition: Geometry.cpp:104
bool isValid() const
It tells if the rectangle is valid or not.
Definition: Envelope.h:438
TEGEOMEXPORT Geometry * GetGeomFromEnvelope(const Envelope *const e, int srid)
It creates a Geometry (a polygon) from the given envelope.
Definition: Utils.cpp:38