27 #include "../common/progress/TaskProgress.h"
28 #include "../common/Translator.h"
29 #include "../geometry/Coord2D.h"
30 #include "../geometry/Envelope.h"
31 #include "../geometry/Line.h"
32 #include "../geometry/LinearRing.h"
33 #include "../geometry/Point.h"
34 #include "../geometry/Polygon.h"
35 #include "../geometry/Utils.h"
54 assert(b < m_rasterPtr->getNumberOfBands());
169 int countObjects = 0;
170 std::vector<unsigned int> indexVec;
178 std::auto_ptr< te::gm::LinearRing > newRingPtr;
179 std::auto_ptr< te::gm::Polygon > newPolPtr;
183 for (
unsigned int currentLine = 0; currentLine < m_nLines ; currentLine++)
189 last_line_ll_point_indexed.
x = 0.0;
190 last_line_ll_point_indexed.
y = ((double) currentLine) - 1.0;
192 last_line_lr_point_indexed.
x = ((double) m_nColumns) - 1.0;
193 last_line_lr_point_indexed.
y = ((double) currentLine) - 1.0;
195 last_line_ll_point = m_rasterPtr->getGrid()->gridToGeo(last_line_ll_point_indexed.
x, last_line_ll_point_indexed.
y);
196 last_line_lr_point = m_rasterPtr->getGrid()->gridToGeo(last_line_lr_point_indexed.
x, last_line_lr_point_indexed.
y);
199 last_line_lr_point.
x, last_line_lr_point.
y);
202 m_rTreePolygons->search(last_line_bbox, indexVec);
204 for(
unsigned int indexVec_index = 0; indexVec_index < indexVec.size(); indexVec_index++)
207 m_containerPolygons[indexVec[indexVec_index]];
208 double curr_pol_ll_x = curr_pol_struct.
m_polygonPtr->getMBR()->getLowerLeftX();
209 double curr_pol_ll_y = curr_pol_struct.
m_polygonPtr->getMBR()->getLowerLeftY();
211 if(m_rasterPtr->getGrid()->geoToGrid(curr_pol_ll_x, curr_pol_ll_y).y < currentLine)
219 for (
unsigned int currentCol = 0; currentCol < m_nColumns; currentCol++)
223 te::gm::Coord2D coordWorld = m_rasterPtr->getGrid()->gridToGeo(currentCol, currentLine);
226 te::gm::Point pointWorld(coordWorld.
x, coordWorld.
y, m_rasterPtr->getSRID());
230 m_rTreePolygons->search(boxPoint, indexVec);
231 m_rasterPtr->getValue(currentCol, currentLine, val, m_rasterBand);
233 if (!indexVec.empty())
235 unsigned int indexVec_index = 0;
237 while(indexVec_index < indexVec.size())
239 assert(indexVec[indexVec_index] < m_containerPolygons.size());
242 m_containerPolygons[indexVec[indexVec_index]];
244 if (val == pol_str_ref.m_value)
246 assert( pol_str_ref.m_indexerPtr.get() );
247 if ( pol_str_ref.m_indexerPtr->within( pointWorld) )
265 if(detectEdge(currentCol, currentLine, *newRingPtr))
268 newPolPtr->setSRID( m_rasterPtr->getSRID() );
269 newPolPtr->add( newRingPtr.release() );
273 unsigned int indexVec_index = 0;
274 while(indexVec_index < indexVec.size())
277 m_containerPolygons[indexVec[indexVec_index]];
295 assert(newPolPtr->getMBR()->getWidth() > 0 && newPolPtr->getMBR()->getHeight() > 0);
297 if (val != m_noDataValue)
303 m_containerPolygons.push_back(dummy_ps);
304 m_containerPolygons[m_containerPolygons.size() - 1].
reset(newPolPtr.get(),
308 4.0 * newPolPtr->getMBR()->getHeight()
311 newPolPtr->getMBR()->getWidth()
313 ( (double) newPolPtr->operator[](0)->getNPoints() )
317 m_rasterPtr->getResolutionY()
322 m_rTreePolygons->insert(*newPolPtr->getMBR(), m_containerPolygons.size() - 1);
330 currentCol = m_nColumns;
331 currentLine = m_nLines;
336 if(countObjects >= ((
int) m_maxPolygons))
340 currentCol = m_nColumns;
341 currentLine = m_nLines;
350 throw Exception(
"Memory error - error generating polygons map");
355 delete m_rTreePolygons;
360 for(
unsigned int containerPolygonsSize = 0 ; containerPolygonsSize <
361 m_containerPolygons.size() ; ++containerPolygonsSize )
365 if( ((
double)polStructure.
m_value) != m_noDataValue )
367 polygons.push_back( polStructure.
m_polygonPtr.release() );
368 polStructure.
clear();
377 assert(startingEdgeTest(i, j));
382 double pol_pixels_value = 0;
383 m_rasterPtr->getValue(i, j, pol_pixels_value, m_rasterBand);
386 short curr_dir =
EAST;
387 short new_dir =
EAST;
388 short new_test_start_dir =
EAST;
391 short pinit_leaving_dir =
WEST;
392 bool pinit_leaving_dir_set =
false;
396 int curr_x_index = i;
397 int curr_y_index = j;
398 int next_x_index = i;
399 int next_y_index = j;
401 double curr_pixel_value = 0;
403 bool look_for_next_pixel =
true;
404 bool next_pixel_found =
false;
405 bool must_add_curr_chain_p =
false;
410 while(look_for_next_pixel)
413 new_test_start_dir = (curr_dir + 6) % 8;
414 new_dir = new_test_start_dir;
415 next_pixel_found =
false;
418 next_x_index = curr_x_index + (int) m_directions[new_dir].x;
419 next_y_index = curr_y_index + (int) m_directions[new_dir].y;
421 if ((next_x_index > -1) && (next_y_index > -1) &&
422 (next_x_index < (
long) m_nColumns ) && (next_y_index < (
long) m_nLines))
424 m_rasterPtr->getValue(next_x_index, next_y_index, curr_pixel_value, m_rasterBand);
427 if (curr_pixel_value == pol_pixels_value)
429 next_pixel_found =
true;
434 new_dir = (new_dir + 2) % 8;
435 }
while (new_dir != new_test_start_dir);
438 if (!next_pixel_found)
442 curr_chain_p.
x += m_directions[
EAST].x;
443 curr_chain_p.
y += m_directions[
EAST].y;
447 curr_chain_p.
x += m_directions[
SOUTH].x;
448 curr_chain_p.
y += m_directions[
SOUTH].y;
452 curr_chain_p.
x += m_directions[
WEST].x;
453 curr_chain_p.
y += m_directions[
WEST].y;
457 curr_chain_p.
x += m_directions[
NORTH].x;
458 curr_chain_p.
y += m_directions[
NORTH].y;
462 look_for_next_pixel =
false;
464 else if ((curr_x_index == i) && (curr_y_index == j) &&
465 (pinit_leaving_dir == new_dir))
468 switch (curr_pixel_corner)
472 curr_chain_p.
x += m_directions[
SOUTH].x;
473 curr_chain_p.
y += m_directions[
SOUTH].y;
477 curr_chain_p.
x += m_directions[
WEST].x;
478 curr_chain_p.
y += m_directions[
WEST].y;
482 curr_chain_p.
x += m_directions[
NORTH].x;
483 curr_chain_p.
y += m_directions[
NORTH].y;
491 curr_chain_p.
x += m_directions[
WEST].x;
492 curr_chain_p.
y += m_directions[
WEST].y;
496 curr_chain_p.
x += m_directions[
NORTH].x;
497 curr_chain_p.
y += m_directions[
NORTH].y;
505 curr_chain_p.
x += m_directions[
NORTH].x;
506 curr_chain_p.
y += m_directions[
NORTH].y;
514 std::cout <<
"Error message: Invalid pixel corner " << std::endl;
519 look_for_next_pixel =
false;
524 if (curr_dir == new_dir)
526 curr_chain_p.
x += m_directions[curr_dir].x;
527 curr_chain_p.
y += m_directions[curr_dir].y;
529 must_add_curr_chain_p =
true;
533 if (must_add_curr_chain_p)
538 must_add_curr_chain_p =
false;
545 switch (curr_pixel_corner)
549 curr_chain_p.
x += m_directions[
EAST].x;
550 curr_chain_p.
y += m_directions[
EAST].y;
563 curr_chain_p.
x += m_directions[
WEST].x;
564 curr_chain_p.
y += m_directions[
WEST].y;
568 curr_chain_p.
x += m_directions[
NORTH].x;
569 curr_chain_p.
y += m_directions[
NORTH].y;
573 curr_chain_p.
x += m_directions[
EAST].x;
574 curr_chain_p.
y += m_directions[
EAST].y;
583 curr_chain_p.
x += m_directions[
NORTH].x;
584 curr_chain_p.
y += m_directions[
NORTH].y;
588 curr_chain_p.
x += m_directions[
EAST].x;
589 curr_chain_p.
y += m_directions[
EAST].y;
598 throw(
"Invalid pixel corner");
607 switch (curr_pixel_corner)
611 curr_chain_p.
x += m_directions[
EAST].x;
612 curr_chain_p.
y += m_directions[
EAST].y;
616 curr_chain_p.
x += m_directions[
SOUTH].x;
617 curr_chain_p.
y += m_directions[
SOUTH].y;
626 curr_chain_p.
x += m_directions[
SOUTH].x;
627 curr_chain_p.
y += m_directions[
SOUTH].y;
640 curr_chain_p.
x += m_directions[
NORTH].x;
641 curr_chain_p.
y += m_directions[
NORTH].y;
645 curr_chain_p.
x += m_directions[
EAST].x;
646 curr_chain_p.
y += m_directions[
EAST].y;
650 curr_chain_p.
x += m_directions[
SOUTH].x;
651 curr_chain_p.
y += m_directions[
SOUTH].y;
660 throw(
"Invalid pixel corner");
669 switch (curr_pixel_corner)
673 curr_chain_p.
x += m_directions[
EAST].x;
674 curr_chain_p.
y += m_directions[
EAST].y;
678 curr_chain_p.
x += m_directions[
SOUTH].x;
679 curr_chain_p.
y += m_directions[
SOUTH].y;
683 curr_chain_p.
x += m_directions[
WEST].x;
684 curr_chain_p.
y += m_directions[
WEST].y;
693 curr_chain_p.
x += m_directions[
SOUTH].x;
694 curr_chain_p.
y += m_directions[
SOUTH].y;
698 curr_chain_p.
x += m_directions[
WEST].x;
699 curr_chain_p.
y += m_directions[
WEST].y;
708 curr_chain_p.
x += m_directions[
WEST].x;
709 curr_chain_p.
y += m_directions[
WEST].y;
722 throw(
"Invalid pixel corner");
731 switch (curr_pixel_corner)
740 curr_chain_p.
x += m_directions[
SOUTH].x;
741 curr_chain_p.
y += m_directions[
SOUTH].y;
745 curr_chain_p.
x += m_directions[
WEST].x;
746 curr_chain_p.
y += m_directions[
WEST].y;
750 curr_chain_p.
x += m_directions[
NORTH].x;
751 curr_chain_p.
y += m_directions[
NORTH].y;
760 curr_chain_p.
x += m_directions[
WEST].x;
761 curr_chain_p.
y += m_directions[
WEST].y;
765 curr_chain_p.
x += m_directions[
NORTH].x;
766 curr_chain_p.
y += m_directions[
NORTH].y;
775 curr_chain_p.
x += m_directions[
NORTH].x;
776 curr_chain_p.
y += m_directions[
NORTH].y;
784 throw(
"Invalid pixel corner");
793 throw(
"Invalid new_dir");
800 if ((!pinit_leaving_dir_set) && (curr_x_index == i) &&
803 pinit_leaving_dir_set =
true;
804 pinit_leaving_dir = new_dir;
808 curr_x_index = next_x_index;
809 curr_y_index = next_y_index;
815 const te::gm::Coord2D chain_init_p = m_rasterPtr->getGrid()->gridToGeo(((
double) i) - 0.5, ((
double) j) - 0.5);
816 double min_x = std::numeric_limits<double>::max();
817 double min_y = std::numeric_limits<double>::max();
818 double max_x = (-1.0) * std::numeric_limits<double>::max();
819 double max_y = (-1.0) * std::numeric_limits<double>::max();
823 for (
unsigned int i = 0; i < line.
getNPoints(); i++)
825 tmp_x = chain_init_p.
x + (line.
getX(i) * m_resX);
826 tmp_y = chain_init_p.
y - (line.
getY(i) * m_resY);
828 if (tmp_x < min_x ) min_x = tmp_x;
829 if (tmp_y < min_y ) min_y = tmp_y;
831 if (tmp_x > max_x ) max_x = tmp_x;
832 if (tmp_y > max_y ) max_y = tmp_y;
838 line.
setSRID( m_rasterPtr->getSRID() );
861 int nlines = m_rasterPtr->getNumberOfRows();
862 int ncols = m_rasterPtr->getNumberOfColumns();
867 if ((x == 0) || (y == 0) ||
868 (x == (ncols - 1)) || (y == (nlines - 1)))
873 double current_val = 0;
875 m_rasterPtr->getValue(x, y, current_val, m_rasterBand);
876 m_rasterPtr->getValue(x - 1, y, test_val, m_rasterBand);
889 delete m_rTreePolygons;
893 m_containerPolygons.clear();
Vectorizer(Raster *r, std::size_t b, unsigned int mp=0)
Constructor.
void computeMBR(bool cascade) const
It computes the minimum bounding rectangle for the linestring.
It describes one band (or dimension) of a raster.
void setX(std::size_t i, const double &x)
It sets the n-th x coordinate value.
unsigned long m_nColumns
The number of columns.
Point * getEndPoint() const
It returns the curve end point.
std::auto_ptr< TileIndexer > m_indexerPtr
A pointer to the polygon tile indexer pointer.
unsigned int getNumberOfColumns() const
Returns the raster number of columns.
virtual const Band * getBand(std::size_t i) const =0
Returns the raster i-th band.
void makeEmpty()
It clears all the coordinates.
Point * getStartPoint() const
The length of this Curve in its associated spatial reference.
This class can be used to inform the progress of a task.
Raster * m_rasterPtr
A pointer to the input image.
An utility struct for representing 2D coordinates.
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::max().
#define TE_TR(message)
It marks a string in order to get translated.
const double & getY(std::size_t i) const
It returns the n-th y coordinate value.
unsigned long m_nLines
The number of lines.
double getResolutionY() const
Returns the grid vertical (y-axis) resolution.
It implements the vectorizer, based on TerraLib 4 algorithm.
te::sam::rtree::Index< unsigned int, 8, 4 > * m_rTreePolygons
A RTree instance pointer to optimize the searching of points inside already created polygons...
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.
An exception class for the Raster module.
A polygon container node class.
double m_resX
Resolution X.
bool run(std::vector< te::gm::Geometry * > &polygons)
Returns true if current algorithm implementation runs ok, false otherwise.
void reset(te::gm::Polygon *polPtr, const unsigned int &v, const double &tidy)
Reset the current instance.
std::vector< VectorizerPolygonStructure > m_containerPolygons
Vector of all polygons.
const double & getY() const
It returns the Point y-coordinate value.
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.
const double & getX(std::size_t i) const
It returns the n-th x coordinate value.
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.
It implements the vectorizer, based on TerraLib 4 algorithm.
std::size_t getNPoints() const
It returns the number of points (vertexes) in the linestring.
void pulse()
Calls setCurrentStep() function using getCurrentStep() + 1.
It gives access to values in one band (dimension) of a raster.
Grid * getGrid()
It returns the raster grid.
double m_noDataValue
The used dummy value.
bool detectEdge(long i, long j, te::gm::LinearRing &line)
Detects an edge of a cell in Raster.
std::auto_ptr< te::gm::Polygon > m_polygonPtr
A pointer to the stored polygon instance.
Polygon is a subclass of CurvePolygon whose rings are defined by linear rings.
A polygon container node class.
A rectified grid is the spatial support for raster data.
void setSRID(int srid)
It sets the Spatial Reference System ID of the linestring.
Vectorizer & operator=(const Vectorizer &rhs)
Assignment operator.
Configuration flags for the Raster module of TerraLib.
void setY(std::size_t i, const double &y)
It sets the n-th y coordinate value.
const double & getX() const
It returns the Point x-coordinate value.
unsigned int m_value
The value (color) related to a polygon.
void clear()
Init internal variables.