TileIndexer.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/raster/TileIndexer.cpp
22 
23  \brief Polygon tile indexing class for optmized geometrical relational tests.
24 */
25 
26 // TerraLib
27 #include "TileIndexer.h"
28 #include "Exception.h"
29 #include "../geometry.h"
30 #include "../common/STLUtils.h"
31 #include "../core/translator/Translator.h"
32 
33 // STL
34 #include <iostream>
35 #include <memory>
36 
38  unsigned int& firstTile, unsigned int& lastTile) const
39 {
40 // Invalid tile indexer Y resolution
41  assert(m_dy > 0);
42 
43  double lowerY = ((p1.getY() < p2.getY())? p1.getY(): p2.getY());
44  double upperY = ((p1.getY() > p2.getY())? p1.getY(): p2.getY());
45 
46  if( ( upperY < m_referencePolygon.getMBR()->getLowerLeftY() ) ||
47  ( lowerY > m_referencePolygon.getMBR()->getUpperRightY() ) )
48  {
49  return false;
50  }
51  else
52  {
53  firstTile = (unsigned int)((lowerY - m_referencePolygon.getMBR()->getLowerLeftY()) / m_dy);
54  lastTile = (unsigned int)((upperY - m_referencePolygon.getMBR()->getLowerLeftY()) / m_dy);
55  return true;
56  }
57 }
58 
59 bool te::rst::TileIndexer::getTileIndex(const double& y, unsigned int& tileIndex) const
60 {
61  assert(m_dy > 0);
62 
63  if( ( y < m_referencePolygon.getMBR()->getLowerLeftY() ) ||
65  {
66  return false;
67  }
68  else
69  {
70  tileIndex = (unsigned int)( (y - m_referencePolygon.getMBR()->getLowerLeftY() ) / m_dy );
71  return true;
72  }
73 }
74 
76 {
77  m_dy = 0;
78 }
79 
81 {
82  return new TileIndexer( *this );
83 }
84 
87 {
88  const std::size_t tileIndexSize = rhs.m_tileIndex.size();
89 
90  for( std::size_t tileIndexIdx = 0 ; tileIndexIdx < tileIndexSize ; ++tileIndexIdx )
91  {
92  m_tileIndex.push_back( new TileSegIndex() );
93  m_tileIndex.back()->operator=( *rhs.m_tileIndex[ tileIndexIdx ] );
94  }
95 }
96 
98  : m_referencePolygon(pol)
99 {
100  assert(dy > 0);
101 
102  init();
103  m_dy = dy;
104 
105 // Building new index
107  {
108  unsigned int total_tiles_number = 1 +
109  ((unsigned int) floor(m_referencePolygon.getMBR()->getHeight() / m_dy));
110 
111  for(unsigned int i = 0; i < total_tiles_number; i++)
112  m_tileIndex.push_back(new TileSegIndex);
113 
114 // for each polygon ring, we need to index its segments
115  for(unsigned int i = 0; i < m_referencePolygon.getNumRings(); i++)
116  {
117  if( ! addRing(i) )
118  {
119  throw Exception(TE_TR("Error adding ring") );
120  }
121  }
122  }
123 }
124 
126 {
128  m_tileIndex.clear();
129  init();
130 }
131 
133 {
134  clear();
135 }
136 
137 bool te::rst::TileIndexer::addRing(const unsigned int& ri)
138 {
139  if( ri >= m_referencePolygon.getNumRings() )
140  {
141  return false;
142  }
143 
144  unsigned int num_points = static_cast<unsigned int>(m_referencePolygon[ri]->getNPoints());
145  if (num_points < 2)
146  {
147  return false;
148  }
149 
150  unsigned int numSegments = num_points - 1;
151 
152  for(unsigned int j = 0; j < numSegments; j++)
153  {
154 // creates a pointer to the segment
155  std::pair<unsigned int, unsigned int> segPointer(ri, j);
156 
157 // finds the tiles that this segment intersects
158  unsigned int firstTileIndex = 0;
159  unsigned int lastTileIndex = 0;
160 
161  std::unique_ptr<te::gm::Point> cj(
162  (static_cast<te::gm::LinearRing*> (m_referencePolygon[ri]))->getPointN(j) );
163  std::unique_ptr<te::gm::Point> cjp1(
164  (static_cast<te::gm::LinearRing*> (m_referencePolygon[ri]))->getPointN(j + 1) );
165 
166  if( getTileIndex(*cj, *cjp1, firstTileIndex, lastTileIndex) )
167  {
168  // associates the pointer segment to the tiles
169  for(unsigned int k = firstTileIndex; k <= lastTileIndex; k++)
170  m_tileIndex[k]->push_back(segPointer);
171  }
172  else
173  {
174  return false;
175  }
176  }
177 
178  return true;
179 }
180 
181 bool te::rst::TileIndexer::getTile(const double& y, TileSegIndex** index) const
182 {
183  unsigned int tidx;
184  if( getTileIndex(y, tidx) )
185  {
186  assert( tidx < m_tileIndex.size() );
187 
188  (*index) = m_tileIndex[tidx];
189  return true;
190  }
191  else
192  {
193  return false;
194  }
195 }
196 
197 bool te::rst::TileIndexer::within(const te::gm::Point& geometry) const
198 {
199  m_withinTileY = geometry.getY();
200 
202  {
203  assert( m_withinTileIndexPtr );
204 
205  m_withinTileX = geometry.getX();
206  m_withinIsInside = false;
207 
208  for( unsigned int i = 0 ; i < m_withinTileIndexPtr->size() ; ++i )
209  {
210  assert( ( ( *m_withinTileIndexPtr )[ i ].first < m_referencePolygon.getNumRings() ) );
211  assert( dynamic_cast< te::gm::LinearRing const* >( m_referencePolygon[
212  ( *m_withinTileIndexPtr )[ i ].first ] ) );
214 
215  assert( ( *m_withinTileIndexPtr )[ i ].second < m_withinRingPtr->getNPoints() );
216  m_withinVtx0.x = m_withinRingPtr->getX( ( *m_withinTileIndexPtr )[ i ].second );
217  m_withinVtx0.y = m_withinRingPtr->getY( ( *m_withinTileIndexPtr )[ i ].second );
218  m_withinVtx1.x = m_withinRingPtr->getX( ( *m_withinTileIndexPtr )[ i ].second + 1 );
219  m_withinVtx1.y = m_withinRingPtr->getY( ( *m_withinTileIndexPtr )[ i ].second + 1 );
220 
222 
224 
226  {
227  /* TODO - Check Boundary case */
228 
231  {
233  }
234  }
235  }
236 
237  return m_withinIsInside;
238  }
239  else
240  {
241  return false;
242  }
243 }
244 
246 {
247  m_withinTileY = geometry.getY();
248 
250  {
251  assert( m_withinTileIndexPtr );
252 
253  m_withinTileX = geometry.getX();
254  m_withinIsInside = false;
255 
256  for( unsigned int i = 0 ; i < m_withinTileIndexPtr->size() ; ++i )
257  {
258  assert( ( ( *m_withinTileIndexPtr )[ i ].first < m_referencePolygon.getNumRings() ) );
259  assert( dynamic_cast< te::gm::LinearRing const* >( m_referencePolygon[
260  ( *m_withinTileIndexPtr )[ i ].first ] ) );
262 
263  assert( ( *m_withinTileIndexPtr )[ i ].second < m_withinRingPtr->getNPoints() );
264  m_withinVtx0.x = m_withinRingPtr->getX( ( *m_withinTileIndexPtr )[ i ].second );
265  m_withinVtx0.y = m_withinRingPtr->getY( ( *m_withinTileIndexPtr )[ i ].second );
266  m_withinVtx1.x = m_withinRingPtr->getX( ( *m_withinTileIndexPtr )[ i ].second + 1 );
267  m_withinVtx1.y = m_withinRingPtr->getY( ( *m_withinTileIndexPtr )[ i ].second + 1 );
268 
272 
273  double m_within_coef1 = (m_withinVtx1.y - m_withinTileY) * (m_withinVtx0.x - m_withinVtx1.x);
274  double m_within_coef2 = (m_withinVtx1.x - m_withinTileX) * (m_withinVtx0.y - m_withinVtx1.y);
275 
277  {
278  if (m_within_coef1 - m_within_coef2 == 0)
279  {
280  return true;
281  }
282  else if ((m_within_coef1 >= m_within_coef2) == m_withinYFlag1) {
284  }
285  }
286  else if (m_withinYEquals)
287  {
289  return true;
290  }
291  }
292  }
293 
294  return m_withinIsInside;
295  }
296  else
297  {
298  return false;
299  }
300 }
301 
std::size_t getNumRings() const
It returns the number of rings in this CurvePolygon.
Definition: CurvePolygon.h:153
bool getTile(const double &y, TileSegIndex **index) const
Gets tile index.
An exception class for the Raster module.
te::gm::Coord2D m_withinVtx1
Definition: TileIndexer.h:173
te::gm::Coord2D m_withinVtx0
Definition: TileIndexer.h:172
~TileIndexer()
Destructor.
const te::gm::Polygon & m_referencePolygon
Reference polygon.
Definition: TileIndexer.h:159
Polygon tile indexing class for optmized geometrical relational tests.
Definition: TileIndexer.h:54
double y
y-coordinate.
Definition: Coord2D.h:114
te::gm::LinearRing const * m_withinRingPtr
Definition: TileIndexer.h:171
bool within(const te::gm::Point &geometry) const
It returns true if the given geometry is within the indexed reference polygon.
bool addRing(const unsigned int &ri)
Update the tile index with the information of the supplied ring.
double x
x-coordinate.
Definition: Coord2D.h:113
Base exception class for plugin module.
const double & getLowerLeftY() const
It returns a constant refernce to the y coordinate of the lower left corner.
const double & getUpperRightY() const
It returns a constant refernce to the x coordinate of the upper right corner.
#define TE_TR(message)
It marks a string in order to get translated.
Definition: Translator.h:242
bool getTileIndex(const te::gm::Point &p1, const te::gm::Point &p2, unsigned int &firstTile, unsigned int &lastTile) const
Gets tile index intervals in y direction for a given segment.
Definition: TileIndexer.cpp:37
const double & getY(std::size_t i) const
It returns the n-th y coordinate value.
bool withinOrTouches(const te::gm::Point &geometry) const
It returns true if the given geometry is within or touches the indexed reference polygon.
A LinearRing is a LineString that is both closed and simple.
Definition: LinearRing.h:53
std::size_t getNPoints() const
it returns the number of points (vertexes) in the geometry.
const double & getY() const
It returns the Point y-coordinate value.
Definition: Point.h:152
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.
const double & getX(std::size_t i) const
It returns the n-th x coordinate value.
Polygon tile indexing class for optmized geometrical relational tests.
double m_dy
Tile resolution along "y" axis.
Definition: TileIndexer.h:158
TileIndexer * clone() const
Returns a clone of this instance (the caller of this method must thake the ownership of the returned ...
Definition: TileIndexer.cpp:80
TileSegIndex * m_withinTileIndexPtr
Definition: TileIndexer.h:164
void clear()
Clear all internal resources.
TileIndexer(const TileIndexer &)
Constructor.
Definition: TileIndexer.cpp:85
Polygon is a subclass of CurvePolygon whose rings are defined by linear rings.
Definition: Polygon.h:50
std::vector< TileSegIndex * > m_tileIndex
Each tile segments index vector.
Definition: TileIndexer.h:160
std::vector< std::pair< unsigned int, unsigned int > > TileSegIndex
Definition: TileIndexer.h:58
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
double getHeight() const
It returns the envelope height.
const double & getX() const
It returns the Point x-coordinate value.
Definition: Point.h:138
void init()
Init internal variables.
Definition: TileIndexer.cpp:75