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" 47 #include <boost/lexical_cast.hpp> 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 ); 69 const bool noDataExclusion )
71 m_rasterBand(static_cast<unsigned
int>(b)),
74 assert(b < m_rasterPtr->getNumberOfBands());
86 std::numeric_limits< double >::max();
118 std::vector< double > *
const polygonsValues )
121 if( polygonsValues ) polygonsValues->clear();
127 std::vector<VectorizerPolygonStructure> containerPolygons;
132 double currentPixelValue;
133 int countObjects = 0;
134 std::vector<std::size_t> indexVec;
143 std::unique_ptr< te::gm::LinearRing > newRingPtr;
144 std::unique_ptr< te::gm::Polygon > newPolPtr;
149 for (
unsigned int currentLine = 0; currentLine <
m_nLines ; currentLine++)
155 last_line_ll_point_indexed.
x = 0.0;
156 last_line_ll_point_indexed.
y = ((double) currentLine) - 1.0;
158 last_line_lr_point_indexed.
x = ((double)
m_nColumns) - 1.0;
159 last_line_lr_point_indexed.
y = ((double) currentLine) - 1.0;
165 last_line_lr_point.
x, last_line_lr_point.
y);
168 rTreePolygons.search(last_line_bbox, indexVec);
170 for(
unsigned int indexVec_index = 0; indexVec_index < indexVec.size(); indexVec_index++)
173 containerPolygons[indexVec[indexVec_index]];
181 rTreePolygons.remove( env, indexVec[indexVec_index] );
188 for (
unsigned int currentCol = 0; currentCol <
m_nColumns; currentCol++)
198 rTreePolygons.search(boxPoint, indexVec);
201 if (!indexVec.empty())
203 unsigned int indexVec_index = 0;
205 while(indexVec_index < indexVec.size())
208 containerPolygons[indexVec[indexVec_index]];
210 if (currentPixelValue == pol_str_ref.
m_value)
229 if(
detectEdge(currentCol, currentLine, *newRingPtr))
243 newPolPtr->add( newRingPtr.release() );
247 unsigned int indexVec_index = 0;
248 while(indexVec_index < indexVec.size())
251 containerPolygons[indexVec[indexVec_index]];
253 if( currentPixelValue != pol_struct_ref.
m_value )
271 containerPolygons.push_back(dummy_ps);
272 containerPolygons.back().reset( newPolPtr.release(),
275 rTreePolygons.insert(*containerPolygons.back().m_polygonPtr->getMBR(),
276 containerPolygons.size() - 1);
302 catch(
const te::rst::Exception& e )
304 throw te::rst::Exception(
"Vectorizer error:" + std::string( e.what() ) );
308 throw te::rst::Exception(
"Vectorizer error" );
313 const std::size_t containerPolygonsSize = containerPolygons.size();
314 std::size_t fixedSize = 0;
316 for( std::size_t containerPolygonsIdx = 0 ; containerPolygonsIdx <
317 containerPolygonsSize ; ++containerPolygonsIdx )
323 std::vector<te::gm::Geometry*> fixed;
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(
"); ") +
339 fixedSize = fixed.size();
341 polygons.insert(polygons.end(), fixed.begin(), fixed.end());
347 polygonsValues->push_back( polStructure.
m_value );
352 polStructure.
clear();
366 double pol_pixels_value = 0;
371 short currentSegmentInitialLeavingDirection =
EAST;
372 bool currentSegmentInitialLeavingDirectionWasSet =
false;
373 short currentDirection =
EAST;
374 short currentPixelInitialNextTestDirection =
EAST;
375 short currentPixelNextTestDirection =
EAST;
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;
390 while(lookForNextPixel)
394 nextPixelWasFound =
false;
395 currentPixelInitialNextTestDirection = currentPixelNextTestDirection = (currentDirection + 6) % 8;
399 nextCol = currentCol + (
int)
m_directions[currentPixelNextTestDirection].x;
400 nextRow = currentRow + (
int)
m_directions[currentPixelNextTestDirection].y;
402 if ((nextCol > -1) && (nextRow > -1) &&
408 if (currentPixelValue == pol_pixels_value)
410 nextPixelWasFound =
true;
411 currentDirection = currentPixelNextTestDirection;
416 currentPixelNextTestDirection = (currentPixelNextTestDirection + 2) % 8;
418 while (currentPixelInitialNextTestDirection != currentPixelNextTestDirection);
422 if( !currentSegmentInitialLeavingDirectionWasSet )
424 currentSegmentInitialLeavingDirectionWasSet =
true;
425 currentSegmentInitialLeavingDirection = currentDirection;
430 if (!nextPixelWasFound)
442 lookForNextPixel =
false;
445 ( currentCol == segmentInitialCol )
447 ( currentRow == segmentInitialRow )
449 ( currentDirection == currentSegmentInitialLeavingDirection )
451 ( chainCode.size() > 1 )
458 switch (currentPixelCorner)
480 lookForNextPixel =
false;
487 cornerToDirectionRotAngle = ( currentDirection < currentPixelCorner ) ?
488 ( currentDirection + 8 ) : currentDirection;
489 cornerToDirectionRotAngle -= currentPixelCorner;
491 for( cornerRotationOffset = 2 ; cornerRotationOffset < cornerToDirectionRotAngle ;
492 cornerRotationOffset += 2 )
494 currentPixelCorner = ( currentPixelCorner + 2 ) % 8;
496 switch( currentPixelCorner )
518 switch (currentDirection)
522 switch (currentPixelCorner)
553 switch (currentPixelCorner)
584 switch (currentPixelCorner)
615 switch (currentPixelCorner)
654 currentCol = nextCol;
655 currentRow = nextRow;
660 if( !chainCode.empty() )
662 if( chainCode.front() != chainCode.back() )
664 chainCode.push_back( chainCode.front() );
670 const unsigned int chainCodeSize =
static_cast<unsigned int>(chainCode.size());
680 for (
unsigned int chainCodeIdx = 0; chainCodeIdx < chainCodeSize; chainCodeIdx++)
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 );
701 double current_val = 0;
708 if( current_val == test_val )
return false;
714 if( current_val == test_val )
return false;
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.
It describes one band (or dimension) of a raster.
unsigned long m_nColumns
The number of columns.
A class that represents an R-tree.
unsigned int getNumberOfColumns() const
Returns the raster number of columns.
void makeEmpty()
It clears all the coordinates.
bool detectEdge(long segmentInitialCol, long segmentInitialRow, te::gm::LinearRing &outputLine)
Detects an edge of a cell in Raster.
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.
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.
An utility struct for representing 2D coordinates.
double getY() const
It returns the y-coordinate.
bool startingEdgeTest(const int &x, const int &y)
Tests if the current point is a edge start.
double m_noDataValue
Value to indicate elements where there is no data, default is std::numeric_limits<double>::max().
#define TE_TR(message)
It marks a string in order to get translated.
#define TE_CORE_LOG_ERROR(channel, message)
Use this tag in order to log a message to a specified logger with the ERROR level.
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.
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.
te::gm::Coord2D m_directions[8]
Directions vector.
A LinearRing is a LineString that is both closed and simple.
A polygon container node class.
double m_resX
Resolution X.
Vectorizer(Raster *r, std::size_t b, unsigned int mp=0, const bool noDataExclusion=true)
Constructor.
A point with x and y coordinate values.
void setPoint(std::size_t i, const double &x, const double &y)
It sets the value of the specified point.
unsigned int m_rasterBand
The raster band to be used.
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.
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.
double m_value
The pixel value related to a polygon.
It implements the vectorizer, based on TerraLib 4 algorithm.
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.
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.
int getSRID() const
Returns the raster spatial reference system identifier.
Polygon is a subclass of CurvePolygon whose rings are defined by linear rings.
double getX() const
It returns the x-coordinate.
A rectified grid is the spatial support for raster data.
A polygon container node class.
#define APPENDPOINTINLINE(newDirection)
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.
Vectorizer & operator=(const Vectorizer &rhs)
Assignment operator.
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.
This struct contains informations about GEOS TopologyValidationError.
void clear()
Init internal variables.