src/terralib/attributefill/Utils.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\attributefill\core\Utils.cpp
22 
23  \brief Utility functions for Attribute Fill.
24 */
25 
26 // TerraLib
27 #include "../core/translator/Translator.h"
28 #include "../geometry/Envelope.h"
29 #include "../geometry/MultiPolygon.h"
30 #include "../geometry/Polygon.h"
31 #include "../geometry/Utils.h"
32 #include "../raster/Band.h"
33 #include "../raster/BandProperty.h"
34 
35 #include "Utils.h"
36 
37 // STL
38 #include <tuple>
39 
40 std::string te::attributefill::GetOperationFullName(const int& e)
41 {
42  switch(e)
43  {
45  return "Value";
47  return "Minimum value";
49  return "Maximum value";
51  return "Mean";
53  return "Sum of values";
55  return "Total number of values";
57  return "Total not null values";
59  return "Total number of distinct values";
61  return "Standard deviation";
63  return "Variance";
65  return "Skewness";
67  return "Kurtosis";
69  return "Amplitude";
71  return "Median";
73  return "Coefficient variation";
75  return "Mode";
77  return "Class with highest occurrence";
79  return "Class with highest intersection area";
81  return "Percentage per Class";
83  return "Minimum Distance";
85  return "Minimum Distance From Centroid";
87  return "Presence";
89  return "Weighted by Area";
91  return "Weighted Sum by Area";
93  return "Percentage of each Class by Area";
95  return "Percentage of Total Area";
96  default:
97  return "";
98  }
99 }
100 
101 std::pair<uint32_t, uint32_t> te::attributefill::GeoToGrid(const te::gm::Coord2D& coord, const te::rst::Grid& grid)
102 {
103  double colD=-1, rowD=-1;
104  grid.geoToGrid(coord.getX(), coord.getY(), colD, rowD);
105  int col = static_cast<int>(std::round(colD));
106  int row = static_cast<int>(std::round(rowD));
107 
108  if(col < 0 || col >= (int)grid.getNumberOfColumns())
109  col = std::numeric_limits<uint32_t>::max();
110  if(row < 0 || row >= (int)grid.getNumberOfRows())
111  row = std::numeric_limits<uint32_t>::max();
112 
113  return std::make_pair(col, row);
114 }
115 
117  const te::gm::Polygon &polygon,
118  uint32_t &minimumRow, uint32_t &minimumColumn,
119  uint32_t &maximumRow, uint32_t &maximumColumn)
120 {
121  std::unique_ptr<te::gm::Polygon> polygonTemp(
122  dynamic_cast<te::gm::Polygon*>(polygon.clone()));
123 
124  if (polygonTemp->getSRID() != raster.getSRID())
125  polygonTemp->transform(raster.getSRID());
126 
127  auto polygonEnvelope = polygonTemp->getMBR();
128 
129  auto lowerLeftCoord2D = polygonEnvelope->getLowerLeft();
130  auto upperRightCoord2D = polygonEnvelope->getUpperRight();
131 
132  auto grid = raster.getGrid();
133 
134  std::tie(minimumColumn, maximumRow) = GeoToGrid(lowerLeftCoord2D, *grid);
135  if(minimumColumn == std::numeric_limits<uint32_t>::max())
136  minimumColumn = 0;
137 
138  if(maximumRow == std::numeric_limits<uint32_t>::max())
139  maximumRow = grid->getNumberOfRows()-1;
140 
141  std::tie(maximumColumn, minimumRow) = GeoToGrid(upperRightCoord2D, *grid);
142  if(minimumRow == std::numeric_limits<uint32_t>::max())
143  minimumRow = 0;
144 
145  if(maximumColumn == std::numeric_limits<uint32_t>::max())
146  maximumColumn = grid->getNumberOfColumns()-1;
147 }
148 
150  const unsigned int &band,
151  const te::gm::Polygon &polygon,
152  const uint32_t &minimumRow,
153  const uint32_t &minimumColumn,
154  const uint32_t &maximumRow,
155  const uint32_t &maximumColumn,
156  std::map<double, int> &values)
157 {
158  assert(band < raster.getNumberOfBands());
159 
160  auto noDataValue = raster.getBand(band)->getProperty()->m_noDataValue;
161 
162  std::unique_ptr<te::gm::Geometry> polygonTemp(
163  dynamic_cast<te::gm::Geometry*>(polygon.clone()));
164 
165  if (polygonTemp->getSRID() != raster.getSRID())
166  polygonTemp->transform(raster.getSRID());
167 
168  auto grid = raster.getGrid();
169 
170  auto xResolution = grid->getResolutionX();
171  auto yResolution = grid->getResolutionY();
172 
173  for(uint32_t row = minimumRow; row <= maximumRow; ++row)
174  {
175  for(uint32_t col = minimumColumn; col <= maximumColumn; ++col)
176  {
177  auto pixelCenter = grid->gridToGeo(col, row);
178 
179  std::unique_ptr<te::gm::Envelope> pixelEnvelope( new te::gm::Envelope(pixelCenter.getX()-(xResolution/2.),
180  pixelCenter.getY()-(yResolution/2.),
181  pixelCenter.getX()+(xResolution/2.),
182  pixelCenter.getY()+(yResolution/2.)));
183 
184  std::unique_ptr<te::gm::Geometry> pixelEnvelopeAsGeometry(
185  te::gm::GetGeomFromEnvelope(pixelEnvelope.get(), raster.getSRID()));
186 
187  if(pixelEnvelopeAsGeometry->intersects(polygonTemp.get()) == false)
188  continue;
189 
190  double value;
191  raster.getValue(col, row, value, band);
192 
193  if(value == noDataValue)
194  continue;
195 
196  ++values[value];
197  }
198  }
199 }
200 
202  const unsigned int &band,
203  const te::gm::Polygon &polygon,
204  const uint32_t &minimumRow,
205  const uint32_t &minimumColumn,
206  const uint32_t &maximumRow,
207  const uint32_t &maximumColumn,
208  std::map<double, double> &percentOfEachClassByArea)
209 {
210  assert(band < raster.getNumberOfBands());
211 
212  double polygonArea = polygon.getArea();
213 
214  std::unique_ptr<te::gm::Geometry> polygonTemp(
215  dynamic_cast<te::gm::Geometry*>(polygon.clone()));
216 
217  if (polygonTemp->getSRID() != raster.getSRID())
218  polygonTemp->transform(raster.getSRID());
219 
220  auto grid = raster.getGrid();
221 
222  auto xResolution = grid->getResolutionX();
223  auto yResolution = grid->getResolutionY();
224 
225  for(uint32_t row = minimumRow; row <= maximumRow; ++row)
226  {
227  for(uint32_t col = minimumColumn; col <= maximumColumn; ++col)
228  {
229  auto pixelCenter = grid->gridToGeo(col, row);
230 
231  std::unique_ptr<te::gm::Envelope> pixelEnvelope( new te::gm::Envelope(pixelCenter.getX()-(xResolution/2.),
232  pixelCenter.getY()-(yResolution/2.),
233  pixelCenter.getX()+(xResolution/2.),
234  pixelCenter.getY()+(yResolution/2.)));
235 
236  std::unique_ptr<te::gm::Geometry> pixelEnvelopeAsGeometry(
237  te::gm::GetGeomFromEnvelope(pixelEnvelope.get(), raster.getSRID()));
238 
239  std::unique_ptr<te::gm::Geometry> pixelIntersectedGeometry(
240  pixelEnvelopeAsGeometry->intersection(polygonTemp.get()));
241 
242  if(pixelIntersectedGeometry == nullptr)
243  continue;
244 
245  double currentPixelArea;
246 
247  switch (pixelIntersectedGeometry->getGeomTypeId()) {
248  case te::gm::PolygonType:
249  {
250  te::gm::Polygon polygon = *dynamic_cast<te::gm::Polygon*>(pixelIntersectedGeometry.get());
251  currentPixelArea = polygon.getArea()/polygonArea;
252  }
253  break;
255  {
256  te::gm::MultiPolygon multiPolygon = *dynamic_cast<te::gm::MultiPolygon*>(pixelIntersectedGeometry.get());
257  currentPixelArea = multiPolygon.getArea()/polygonArea;
258  }
259  break;
260  default:
261  currentPixelArea = 0;
262  break;
263  }
264 
265  double value;
266  raster.getValue(col, row, value, band);
267 
268  std::map<double, double>::iterator it = percentOfEachClassByArea.find(value);
269  if(it != percentOfEachClassByArea.end())
270  percentOfEachClassByArea[it->first] += currentPixelArea;
271  else
272  percentOfEachClassByArea.insert(std::pair<double, double>(value, currentPixelArea));
273  }
274  }
275 }
unsigned int getNumberOfRows() const
Returns the grid number of rows.
MultiPolygon is a MultiSurface whose elements are Polygons.
Definition: MultiPolygon.h:50
unsigned int band
TEATTRIBUTEFILLEXPORT void GetValuesFromBand(const te::rst::Raster &raster, const unsigned int &band, const gm::Polygon &polygon, const uint32_t &minimumRow, const uint32_t &minimumColumn, const uint32_t &maximumRow, const uint32_t &maximumColumn, std::map< double, int > &values)
Gets the pixel values for a specific band that intersects the polygon.
TEATTRIBUTEFILLEXPORT std::pair< uint32_t, uint32_t > GeoToGrid(const te::gm::Coord2D &coord, const rst::Grid &grid)
Convert the coordinate to the grid col/row postion of the pixel .
An utility struct for representing 2D coordinates.
Definition: Coord2D.h:40
double getY() const
It returns the y-coordinate.
Definition: Coord2D.h:108
double m_noDataValue
Value to indicate elements where there is no data, default is std::numeric_limits<double>::max().
Definition: BandProperty.h:136
void geoToGrid(const double &x, const double &y, double &col, double &row) const
Get the grid point associated to a spatial location.
TEATTRIBUTEFILLEXPORT void GetMinMaxLineAndColumn(const te::rst::Raster &raster, const te::gm::Polygon &polygon, uint32_t &minimumRow, uint32_t &minimumColumn, uint32_t &maximumRow, uint32_t &maximumColumn)
Gets the minimum and maximum row and column values of the raster based on polygon.
virtual te::dt::AbstractData * clone() const
It clones the linestring.
An Envelope defines a 2D rectangular region.
An abstract class for raster data strucutures.
virtual std::size_t getNumberOfBands() const =0
Returns the number of bands (dimension of cells attribute values) in the raster.
BandProperty * getProperty()
Returns the band property.
unsigned int getNumberOfColumns() const
Returns the grid number of columns.
double getResolutionX() const
Returns the grid horizontal (x-axis) resolution.
virtual const Band * getBand(std::size_t i) const =0
Returns the raster i-th band.
Grid * getGrid()
It returns the raster grid.
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.
double getArea() const
It returns the area of this surface, as measured in the spatial reference system of this surface...
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
double getArea() const
It returns the area of this MultiSurface, as measured in the spatial reference system of this multisu...
TEATTRIBUTEFILLEXPORT void GetPercentOfEachClassByArea(const te::rst::Raster &raster, const unsigned int &band, const gm::Polygon &polygon, const uint32_t &minimumRow, const uint32_t &minimumColumn, const uint32_t &maximumRow, const uint32_t &maximumColumn, std::map< double, double > &percentOfEachClassByArea)
Gets the pixel percentage for a specific band that intersects the polygon.
TEATTRIBUTEFILLEXPORT std::string GetOperationFullName(const int &e)
Gets the full name of the operation as string.
A rectified grid is the spatial support for raster data.
Definition: raster/Grid.h:68
unsigned int col
TEGEOMEXPORT Geometry * GetGeomFromEnvelope(const Envelope *const e, int srid)
It creates a Geometry (a polygon) from the given envelope.