Vectorizer.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/Vectorizer.cpp
22 
23  \brief It implements the vectorizer, based on TerraLib 4 algorithm.
24 */
25 
26 // TerraLib
27 #include "../common/progress/TaskProgress.h"
28 #include "../core/logger/Logger.h"
29 #include "../core/translator/Translator.h"
30 #include "../geometry/Coord2D.h"
31 #include "../geometry/Envelope.h"
32 #include "../geometry/FixGeometryTopology.h"
33 #include "../geometry/Line.h"
34 #include "../geometry/LinearRing.h"
35 #include "../geometry/Point.h"
36 #include "../geometry/Polygon.h"
37 #include "../geometry/Utils.h"
38 #include "Band.h"
39 #include "BandProperty.h"
40 #include "Config.h"
41 #include "Grid.h"
42 #include "Vectorizer.h"
44 #include "Exception.h"
45 
46 // Boost
47 #include <boost/lexical_cast.hpp>
48 
49 // STL
50 #include <iostream>
51 #include <memory>
52 
53 // The 8 cardinals directions used by vectorize method
54 #define NORTHWEST 0
55 #define NORTH 1
56 #define NORTHEAST 2
57 #define EAST 3
58 #define SOUTHEAST 4
59 #define SOUTH 5
60 #define SOUTHWEST 6
61 #define WEST 7
62 
63 #define APPENDPOINTINLINE( newDirection ) \
64  currChainCodePoint.first += (long int)m_directions[ newDirection ].x; \
65  currChainCodePoint.second += (long int)m_directions[ newDirection ].y; \
66  chainCode.push_back( currChainCodePoint );
67 
68 te::rst::Vectorizer::Vectorizer(Raster* r, std::size_t b, unsigned int mp,
69  const bool noDataExclusion )
70  : m_rasterPtr(r),
71  m_rasterBand(static_cast<unsigned int>(b)),
72  m_maxPolygons(mp)
73 {
74  assert(b < m_rasterPtr->getNumberOfBands());
75 
76 // grid parameters
81 
82 // no data value parameters
83  m_noDataValue = noDataExclusion ?
85  :
86  std::numeric_limits< double >::max();
87 
88 // setting the directions
89  m_directions[NORTHWEST] = te::gm::Coord2D(-1, -1);/* NW - 0 */
90  m_directions[NORTH] = te::gm::Coord2D( 0, -1);/* N - 1 */
91  m_directions[NORTHEAST] = te::gm::Coord2D( 1, -1);/* EN - 2 */
92  m_directions[EAST] = te::gm::Coord2D( 1, 0);/* E - 3 */
93  m_directions[SOUTHEAST] = te::gm::Coord2D( 1, 1);/* SE - 4 */
94  m_directions[SOUTH] = te::gm::Coord2D( 0, 1);/* S - 5 */
95  m_directions[SOUTHWEST] = te::gm::Coord2D(-1, 1);/* WS - 6 */
96  m_directions[WEST] = te::gm::Coord2D(-1, 0);/* W - 7 */
97 }
98 
100 {
101 }
102 
104 {
105  clear();
106 }
107 
109 {
110  if(this != &rhs)
111  {
112  }
113 
114  return *this;
115 }
116 
117 bool te::rst::Vectorizer::run(std::vector<te::gm::Geometry*>& polygons,
118  std::vector< double > * const polygonsValues )
119 {
120  polygons.clear();
121  if( polygonsValues ) polygonsValues->clear();
122 
123  clear();
124 
125  // Vector of all polygons.
126 
127  std::vector<VectorizerPolygonStructure> containerPolygons;
128 
129 // creating a new RTree
131 
132  double currentPixelValue;
133  int countObjects = 0;
134  std::vector<std::size_t> indexVec;
136 
137 // scanning rotulated image in row order to vectorize the cells
138 
139  te::gm::Coord2D last_line_ll_point;
140  te::gm::Coord2D last_line_ll_point_indexed;
141  te::gm::Coord2D last_line_lr_point;
142  te::gm::Coord2D last_line_lr_point_indexed;
143  std::unique_ptr< te::gm::LinearRing > newRingPtr;
144  std::unique_ptr< te::gm::Polygon > newPolPtr;
145  const VectorizerPolygonStructure dummy_ps;
146 
147  try
148  {
149  for (unsigned int currentLine = 0; currentLine < m_nLines ; currentLine++)
150  {
151  task.pulse();
152 
153  // cleaning the tileindexers that will not be used anymore
154 
155  last_line_ll_point_indexed.x = 0.0;
156  last_line_ll_point_indexed.y = ((double) currentLine) - 1.0;
157 
158  last_line_lr_point_indexed.x = ((double) m_nColumns) - 1.0;
159  last_line_lr_point_indexed.y = ((double) currentLine) - 1.0;
160 
161  last_line_ll_point = m_rasterPtr->getGrid()->gridToGeo(last_line_ll_point_indexed.x, last_line_ll_point_indexed.y);
162  last_line_lr_point = m_rasterPtr->getGrid()->gridToGeo(last_line_lr_point_indexed.x, last_line_lr_point_indexed.y);
163 
164  te::gm::Envelope last_line_bbox(last_line_ll_point.x, last_line_ll_point.y,
165  last_line_lr_point.x, last_line_lr_point.y);
166 
167  indexVec.clear();
168  rTreePolygons.search(last_line_bbox, indexVec);
169 
170  for(unsigned int indexVec_index = 0; indexVec_index < indexVec.size(); indexVec_index++)
171  {
172  te::rst::VectorizerPolygonStructure& curr_pol_struct =
173  containerPolygons[indexVec[indexVec_index]];
174  const te::gm::Envelope& env = *(curr_pol_struct.m_polygonPtr->getMBR());
175 
176  double curr_pol_ll_x = env.getLowerLeftX();
177  double curr_pol_ll_y = env.getLowerLeftY();
178 
179  if(m_rasterPtr->getGrid()->geoToGrid(curr_pol_ll_x, curr_pol_ll_y).y < ((double)currentLine) )
180  {
181  rTreePolygons.remove( env, indexVec[indexVec_index] );
182  curr_pol_struct.m_indexerPtr.reset();
183  }
184  }
185 
186  // iterating through columns
187 
188  for (unsigned int currentCol = 0; currentCol < m_nColumns; currentCol++)
189  {
190  // verifying if the current point is already inside a polygon generated before
191 
192  te::gm::Coord2D coordWorld = m_rasterPtr->getGrid()->gridToGeo(currentCol, currentLine);
193  te::gm::Envelope boxPoint(coordWorld.x, coordWorld.y, coordWorld.x, coordWorld.y);
194  te::gm::Point pointWorld(coordWorld.x, coordWorld.y, m_rasterPtr->getSRID());
195 
196  bool exist = false;
197  indexVec.clear();
198  rTreePolygons.search(boxPoint, indexVec);
199  m_rasterPtr->getValue(currentCol, currentLine, currentPixelValue, m_rasterBand);
200 
201  if (!indexVec.empty())
202  {
203  unsigned int indexVec_index = 0;
204 
205  while(indexVec_index < indexVec.size())
206  {
207  const VectorizerPolygonStructure& pol_str_ref =
208  containerPolygons[indexVec[indexVec_index]];
209 
210  if (currentPixelValue == pol_str_ref.m_value)
211  {
212  if ( pol_str_ref.m_indexerPtr->within(pointWorld) )
213  {
214  exist = true;
215  break;
216  }
217  }
218 
219  ++indexVec_index;
220  }
221  }
222 
223  if( exist == false )
224  {
225  // we found a new class
226 
227  newRingPtr.reset( new te::gm::LinearRing(0, te::gm::LineStringType) );
228 
229  if(detectEdge(currentCol, currentLine, *newRingPtr))
230  {
231 // std::cout << std::endl << "new polygon index " << countObjects << " :" ;
232 // for( unsigned int newRingIdx = 0 ; newRingIdx < newRingPtr->size() ;
233 // ++newRingIdx )
234 // {
235 // std::cout << " [" << newRingPtr->getPointN( newRingIdx )->getX()
236 // << " ; " << newRingPtr->getPointN( newRingIdx )->getY()
237 // << "]";
238 // }
239 // std::cout << std::endl;
240 
241  newPolPtr.reset( new te::gm::Polygon(0, te::gm::PolygonType) );
242  newPolPtr->setSRID( m_rasterPtr->getSRID() );
243  newPolPtr->add( newRingPtr.release() );
244 
245  // verifying if the polygon is a hole of other one
246 
247  unsigned int indexVec_index = 0;
248  while(indexVec_index < indexVec.size())
249  {
250  VectorizerPolygonStructure& pol_struct_ref =
251  containerPolygons[indexVec[indexVec_index]];
252 
253  if( currentPixelValue != pol_struct_ref.m_value )
254  {
255  if (pol_struct_ref.m_indexerPtr->within(pointWorld))
256  {
257  pol_struct_ref.m_polygonPtr->add((te::gm::LinearRing*) newPolPtr->operator[](0)->clone() );
258  pol_struct_ref.m_indexerPtr->addRing(static_cast<unsigned int>(pol_struct_ref.m_polygonPtr->getNumRings() - 1));
259 
260  break;
261  }
262  }
263 
264  ++indexVec_index;
265  }
266 
267  indexVec.clear();
268 
269  // inserting the new polygon into tree and container
270 
271  containerPolygons.push_back(dummy_ps);
272  containerPolygons.back().reset( newPolPtr.release(),
273  currentPixelValue, m_rasterPtr->getResolutionY() );
274 
275  rTreePolygons.insert(*containerPolygons.back().m_polygonPtr->getMBR(),
276  containerPolygons.size() - 1);
277 
278  ++countObjects;
279  }
280  else
281  {
282  // no more polygons will be generated
283 
284  currentCol = m_nColumns;
285  currentLine = m_nLines;
286  }
287 
288  if(m_maxPolygons)
289  {
290  if(countObjects >= ((int) m_maxPolygons))
291  {
292  // no more polygons will be generated
293 
294  currentCol = m_nColumns;
295  currentLine = m_nLines;
296  }
297  }
298  }
299  }
300  }
301  }
302  catch( const te::rst::Exception& e )
303  {
304  throw te::rst::Exception( "Vectorizer error:" + std::string( e.what() ) );
305  }
306  catch(...)
307  {
308  throw te::rst::Exception( "Vectorizer error" );
309  }
310 
311  // generating output data
312 
313  const std::size_t containerPolygonsSize = containerPolygons.size();
314  std::size_t fixedSize = 0;
315 
316  for( std::size_t containerPolygonsIdx = 0 ; containerPolygonsIdx <
317  containerPolygonsSize ; ++containerPolygonsIdx )
318  {
319  VectorizerPolygonStructure& polStructure = containerPolygons[ containerPolygonsIdx ];
320 
321  if( polStructure.m_value != m_noDataValue )
322  {
323  std::vector<te::gm::Geometry*> fixed;
325 
326  bool isFixed = te::gm::FixGeometryTopology::fixTopology(*polStructure.m_polygonPtr.get(), fixed, error);
327  if(!isFixed)
328  {
329  std::string message = TE_TR("Vectorizer") + std::string(": ") +
330  TE_TR("Could not fix geometry") + std::string(": ") + error.m_message + std::string("; ") +
331  TE_TR("Coordinate") + std::string(": (") + boost::lexical_cast<std::string>(error.m_coordinate.getX()) + std::string(",") +
332  boost::lexical_cast<std::string>(error.m_coordinate.getY()) + std::string("); ") +
333  TE_TR("Geometry WKT") + std::string(": ") + polStructure.m_polygonPtr->asText();
334 
335  TE_CORE_LOG_ERROR(TE_TR("Raster"), message);
336  continue;
337  }
338 
339  fixedSize = fixed.size();
340 
341  polygons.insert(polygons.end(), fixed.begin(), fixed.end());
342 
343  if( polygonsValues )
344  {
345  while( fixedSize )
346  {
347  polygonsValues->push_back( polStructure.m_value );
348  --fixedSize;
349  }
350  }
351 
352  polStructure.clear();
353  }
354  }
355 
356  return true;
357 }
358 
359 bool te::rst::Vectorizer::detectEdge(long segmentInitialCol, long segmentInitialRow, te::gm::LinearRing& outputLine)
360 {
361  assert( startingEdgeTest(segmentInitialCol, segmentInitialRow) );
362 
363  outputLine.makeEmpty();
364 
365 // current polygon pixel values
366  double pol_pixels_value = 0;
367  m_rasterPtr->getValue(segmentInitialCol, segmentInitialRow, pol_pixels_value, m_rasterBand);
368 
369 // generating chain code by following the polygon borders
370 
371  short currentSegmentInitialLeavingDirection = EAST;
372  bool currentSegmentInitialLeavingDirectionWasSet = false;
373  short currentDirection = EAST;
374  short currentPixelInitialNextTestDirection = EAST;
375  short currentPixelNextTestDirection = EAST;
376  short currentPixelCorner = NORTHWEST;
377  short cornerToDirectionRotAngle = 0;
378  short cornerRotationOffset = 0;
379  std::pair< long int, long int > currChainCodePoint( 0, 0 );
380  std::vector< std::pair< long int, long int > > chainCode;
381  chainCode.push_back( currChainCodePoint );
382  int currentCol = segmentInitialCol;
383  int currentRow = segmentInitialRow;
384  int nextCol = segmentInitialCol;
385  int nextRow = segmentInitialRow;
386  double currentPixelValue = 0;
387  bool lookForNextPixel = true;
388  bool nextPixelWasFound = false;
389 
390  while(lookForNextPixel)
391  {
392  // finding the next direction
393 
394  nextPixelWasFound = false;
395  currentPixelInitialNextTestDirection = currentPixelNextTestDirection = (currentDirection + 6) % 8;
396 
397  do
398  {
399  nextCol = currentCol + (int) m_directions[currentPixelNextTestDirection].x;
400  nextRow = currentRow + (int) m_directions[currentPixelNextTestDirection].y;
401 
402  if ((nextCol > -1) && (nextRow > -1) &&
403  (nextCol < (int) m_nColumns ) && (nextRow < (int) m_nLines))
404  {
405  m_rasterPtr->getValue(nextCol, nextRow, currentPixelValue, m_rasterBand);
406  // curr_pixel_value = m_noDataValue;
407 
408  if (currentPixelValue == pol_pixels_value)
409  {
410  nextPixelWasFound = true;
411  currentDirection = currentPixelNextTestDirection;
412  break;
413  }
414  }
415 
416  currentPixelNextTestDirection = (currentPixelNextTestDirection + 2) % 8;
417  }
418  while (currentPixelInitialNextTestDirection != currentPixelNextTestDirection);
419 
420  // Setting the initial segment leaving direction
421 
422  if( !currentSegmentInitialLeavingDirectionWasSet )
423  {
424  currentSegmentInitialLeavingDirectionWasSet = true;
425  currentSegmentInitialLeavingDirection = currentDirection;
426  }
427 
428  // generating the polygon line following the current state
429 
430  if (!nextPixelWasFound)
431  {
432  // there is only one point inside the polygon
433  // that is the last one
434 
439 
440  // Finish de process for the current line
441 
442  lookForNextPixel = false;
443  }
444  else if(
445  ( currentCol == segmentInitialCol )
446  &&
447  ( currentRow == segmentInitialRow )
448  &&
449  ( currentDirection == currentSegmentInitialLeavingDirection )
450  &&
451  ( chainCode.size() > 1 )
452  )
453  {
454  // We are back to the fist pixel again (going to the same direction)
455 
456  // Final stiching of the inital pixel to close the line
457 
458  switch (currentPixelCorner)
459  {
460  case SOUTHEAST:
461  {
464  break;
465  }
466  case SOUTHWEST:
467  {
469  break;
470  }
471  default:
472  {
473  throw te::common::Exception(TE_TR("Invalid final corner"));
474  break;
475  }
476  }
477 
478  // Ending the process for the current edge
479 
480  lookForNextPixel = false;
481  }
482  else
483  {
484  // Stitching the current pixel border line segments following next direction
485  // preparing to a junction with the next pixel
486 
487  cornerToDirectionRotAngle = ( currentDirection < currentPixelCorner ) ?
488  ( currentDirection + 8 ) : currentDirection;
489  cornerToDirectionRotAngle -= currentPixelCorner;
490 
491  for( cornerRotationOffset = 2 ; cornerRotationOffset < cornerToDirectionRotAngle ;
492  cornerRotationOffset += 2 )
493  {
494  currentPixelCorner = ( currentPixelCorner + 2 ) % 8;
495 
496  switch( currentPixelCorner )
497  {
498  case NORTHWEST :
500  break;
501  case NORTHEAST :
503  break;
504  case SOUTHEAST :
506  break;
507  case SOUTHWEST :
509  break;
510  default :
511  throw te::common::Exception(TE_TR("Invalid corner"));
512  break;
513  }
514  }
515 
516  // Setting the next pixel corner
517 
518  switch (currentDirection)
519  {
520  case EAST:
521  {
522  switch (currentPixelCorner)
523  {
524  case NORTHWEST:
525  {
526  break;
527  }
528  case NORTHEAST:
529  {
530  currentPixelCorner = NORTHWEST;
531  break;
532  }
533  case SOUTHEAST:
534  {
535  currentPixelCorner = SOUTHWEST;
536  break;
537  }
538  case SOUTHWEST:
539  {
540  break;
541  }
542  default:
543  {
544  throw te::common::Exception(TE_TR("Invalid corner"));
545  break;
546  }
547  }
548 
549  break;
550  }
551  case SOUTH:
552  {
553  switch (currentPixelCorner)
554  {
555  case NORTHWEST:
556  {
557  break;
558  }
559  case NORTHEAST:
560  {
561  break;
562  }
563  case SOUTHEAST:
564  {
565  currentPixelCorner = NORTHEAST;
566  break;
567  }
568  case SOUTHWEST:
569  {
570  currentPixelCorner = NORTHWEST;
571  break;
572  }
573  default:
574  {
575  throw te::common::Exception(TE_TR("Invalid corner"));
576  break;
577  }
578  }
579 
580  break;
581  }
582  case WEST:
583  {
584  switch (currentPixelCorner)
585  {
586  case NORTHWEST:
587  {
588  currentPixelCorner = NORTHEAST;
589  break;
590  }
591  case NORTHEAST:
592  {
593  break;
594  }
595  case SOUTHEAST:
596  {
597  break;
598  }
599  case SOUTHWEST:
600  {
601  currentPixelCorner = SOUTHEAST;
602  break;
603  }
604  default:
605  {
606  throw te::common::Exception(TE_TR("Invalid corner"));
607  break;
608  }
609  }
610 
611  break;
612  }
613  case NORTH:
614  {
615  switch (currentPixelCorner)
616  {
617  case NORTHWEST:
618  {
619  currentPixelCorner = SOUTHWEST;
620  break;
621  }
622  case NORTHEAST:
623  {
624  currentPixelCorner = SOUTHEAST;
625  break;
626  }
627  case SOUTHEAST:
628  {
629  break;
630  }
631  case SOUTHWEST:
632  {
633  break;
634  }
635  default:
636  {
637  throw te::common::Exception(TE_TR("Invalid corner"));
638  break;
639  }
640  }
641 
642  break;
643  }
644  default:
645  {
646  throw te::common::Exception(TE_TR("Invalid direction"));
647  break;
648  }
649  }
650  }
651 
652  // updating the current state
653 
654  currentCol = nextCol;
655  currentRow = nextRow;
656  }
657 
658  // closing the chain if necessary
659 
660  if( !chainCode.empty() )
661  {
662  if( chainCode.front() != chainCode.back() )
663  {
664  chainCode.push_back( chainCode.front() );
665  }
666  }
667 
668  // changing lines coords to world coords
669 
670  const unsigned int chainCodeSize = static_cast<unsigned int>(chainCode.size());
671 
672  outputLine.setNumCoordinates( chainCodeSize );
673 
674  double row = 0;
675  double col = 0;
676  double xCoord = 0;
677  double yCoord = 0;
678  const te::rst::Grid& grid = *m_rasterPtr->getGrid();
679 
680  for (unsigned int chainCodeIdx = 0; chainCodeIdx < chainCodeSize; chainCodeIdx++)
681  {
682  col = ( (double)segmentInitialCol ) - 0.5 +
683  ( (double)chainCode[ chainCodeIdx ].first );
684  row = ( (double)segmentInitialRow ) - 0.5 +
685  ( (double)chainCode[ chainCodeIdx ].second );
686  grid.gridToGeo( col, row, xCoord, yCoord );
687  outputLine.setPoint( chainCodeIdx, xCoord, yCoord );
688  }
689 
690  outputLine.setSRID( m_rasterPtr->getSRID() );
691 
692  // updating the line box
693 
694  outputLine.computeMBR(false);
695 
696  return true;
697 }
698 
699 bool te::rst::Vectorizer::startingEdgeTest(const int& x, const int& y)
700 {
701  double current_val = 0;
702  double test_val = 0;
703  m_rasterPtr->getValue(x, y, current_val, m_rasterBand);
704 
705  if( x > 0 )
706  {
707  m_rasterPtr->getValue(x - 1, y, test_val, m_rasterBand);
708  if( current_val == test_val ) return false;
709  }
710 
711  if( y > 0 )
712  {
713  m_rasterPtr->getValue(x, y-1, test_val, m_rasterBand);
714  if( current_val == test_val ) return false;
715  }
716 
717  return true;
718 }
719 
721 {
722 }
An exception class for the Raster module.
te::gm::Envelope * getExtent()
Returns the geographic extension of the raster data.
It gives access to values in one band (dimension) of a raster.
void computeMBR(bool cascade) const
It computes the minimum bounding rectangle for the linestring.
double y
y-coordinate.
Definition: Coord2D.h:114
It describes one band (or dimension) of a raster.
unsigned long m_nColumns
The number of columns.
Definition: Vectorizer.h:144
double x
x-coordinate.
Definition: Coord2D.h:113
#define WEST
Definition: Vectorizer.cpp:61
A class that represents an R-tree.
unsigned int getNumberOfColumns() const
Returns the raster number of columns.
#define SOUTHWEST
Definition: Vectorizer.cpp:60
void makeEmpty()
It clears all the coordinates.
#define NORTHEAST
Definition: Vectorizer.cpp:56
bool detectEdge(long segmentInitialCol, long segmentInitialRow, te::gm::LinearRing &outputLine)
Detects an edge of a cell in Raster.
Definition: Vectorizer.cpp:359
std::unique_ptr< te::gm::Polygon > m_polygonPtr
A pointer to the stored polygon instance.
This class can be used to inform the progress of a task.
Definition: TaskProgress.h:53
const double & getLowerLeftY() const
It returns a constant refernce to the y coordinate of the lower left corner.
Raster * m_rasterPtr
A pointer to the input image.
Definition: Vectorizer.h:139
An utility struct for representing 2D coordinates.
Definition: Coord2D.h:40
double getY() const
It returns the y-coordinate.
Definition: Coord2D.h:108
bool startingEdgeTest(const int &x, const int &y)
Tests if the current point is a edge start.
Definition: Vectorizer.cpp:699
double m_noDataValue
Value to indicate elements where there is no data, default is std::numeric_limits<double>::max().
Definition: BandProperty.h:136
#define TE_TR(message)
It marks a string in order to get translated.
Definition: Translator.h:242
#define TE_CORE_LOG_ERROR(channel, message)
Use this tag in order to log a message to a specified logger with the ERROR level.
Definition: Logger.h:267
void geoToGrid(const double &x, const double &y, double &col, double &row) const
Get the grid point associated to a spatial location.
unsigned long m_nLines
The number of lines.
Definition: Vectorizer.h:143
double getResolutionY() const
Returns the grid vertical (y-axis) resolution.
Configuration flags for the Raster module of TerraLib.
It implements the vectorizer, based on TerraLib 4 algorithm.
void clear()
Clear all internally allocated resources.
Definition: Vectorizer.cpp:720
te::gm::Coord2D m_directions[8]
Directions vector.
Definition: Vectorizer.h:140
int b
Definition: TsRtree.cpp:32
A LinearRing is a LineString that is both closed and simple.
Definition: LinearRing.h:53
A polygon container node class.
double m_resX
Resolution X.
Definition: Vectorizer.h:141
Vectorizer(Raster *r, std::size_t b, unsigned int mp=0, const bool noDataExclusion=true)
Constructor.
Definition: Vectorizer.cpp:68
A point with x and y coordinate values.
Definition: Point.h:50
void setPoint(std::size_t i, const double &x, const double &y)
It sets the value of the specified point.
~Vectorizer()
Destructor.
Definition: Vectorizer.cpp:103
unsigned int m_rasterBand
The raster band to be used.
Definition: Vectorizer.h:145
An Envelope defines a 2D rectangular region.
An abstract class for raster data strucutures.
unsigned int getNumberOfRows() const
Returns the raster number of rows.
unsigned int m_maxPolygons
The maximum allowed number of polygons to be created.
Definition: Vectorizer.h:146
BandProperty * getProperty()
Returns the band property.
void setNumCoordinates(std::size_t size)
It reserves room for the number of coordinates in this LineString.
double getResolutionX() const
Returns the grid horizontal (x-axis) resolution.
double m_resY
Resolution Y.
Definition: Vectorizer.h:142
double m_value
The pixel value related to a polygon.
It implements the vectorizer, based on TerraLib 4 algorithm.
Definition: Vectorizer.h:64
void pulse()
Calls setCurrentStep() function using getCurrentStep() + 1.
virtual const Band * getBand(std::size_t i) const =0
Returns the raster i-th band.
Grid * getGrid()
It returns the raster grid.
std::unique_ptr< te::rst::TileIndexer > m_indexerPtr
A pointer to the polygon tile indexer pointer.
This class is designed to declare objects to be thrown as exceptions by TerraLib. ...
double m_noDataValue
The used dummy value.
Definition: Vectorizer.h:138
virtual void getValue(unsigned int c, unsigned int r, double &value, std::size_t b=0) const
Returns the attribute value of a band of a cell.
#define SOUTH
Definition: Vectorizer.cpp:59
int getSRID() const
Returns the raster spatial reference system identifier.
Polygon is a subclass of CurvePolygon whose rings are defined by linear rings.
Definition: Polygon.h:50
double getX() const
It returns the x-coordinate.
Definition: Coord2D.h:102
#define SOUTHEAST
Definition: Vectorizer.cpp:58
A rectified grid is the spatial support for raster data.
#define NORTH
Definition: Vectorizer.cpp:55
A polygon container node class.
#define APPENDPOINTINLINE(newDirection)
Definition: Vectorizer.cpp:63
const double & getLowerLeftX() const
It returns a constant reference to the x coordinate of the lower left corner.
static bool fixTopology(const te::gm::Geometry &geometry, std::vector< te::gm::Geometry * > &fixedGeometryVector, TopologyValidationError topologyError)
This method gets a topologically inconsistent geometry and calls specific functions to fix this geome...
void gridToGeo(const double &col, const double &row, double &x, double &y) const
Get the spatial location of a grid point.
void setSRID(int srid)
It sets the Spatial Reference System ID of the linestring.
double getResolutionY() const
Returns the raster vertical (y-axis) resolution.
bool run(std::vector< te::gm::Geometry * > &polygons, std::vector< double > *const polygonsValues=0)
Returns true if current algorithm implementation runs ok, false otherwise.
Definition: Vectorizer.cpp:117
Vectorizer & operator=(const Vectorizer &rhs)
Assignment operator.
Definition: Vectorizer.cpp:108
void reset(te::gm::Polygon *polPtr, const double &v, const double &tidy)
Reset the current instance.
A rectified grid is the spatial support for raster data.
Definition: raster/Grid.h:68
This struct contains informations about GEOS TopologyValidationError.
#define EAST
Definition: Vectorizer.cpp:57
#define NORTHWEST
Definition: Vectorizer.cpp:54
unsigned int col