LineToPolygonMemory.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 LineToPolygonMemory.h
22 
23  \brief Line to Polygon Vector Processing functions.
24 */
25 
26 //Terralib
27 
28 #include "../common/progress/TaskProgress.h"
29 #include "../core/logger/Logger.h"
30 #include "../core/translator/Translator.h"
31 
32 #include "../dataaccess/dataset/DataSet.h"
33 #include "../dataaccess/dataset/DataSetAdapter.h"
34 #include "../dataaccess/utils/Utils.h"
35 
36 #include "../geometry/GeometryProperty.h"
37 #include "../geometry/Utils.h"
38 
39 #include "../memory/DataSet.h"
40 #include "../memory/DataSetItem.h"
41 
42 #include "LineToPolygonMemory.h"
43 #include "Utils.h"
44 
45 // STL
46 #include <iostream>
47 #include <string>
48 
50 
52 
54 {
55  std::unique_ptr<te::da::DataSetType> outDsType = buildOutDataSetType();
56 
58 
59  std::string geomName = geomProp->getName();
60  std::size_t geomPos = te::da::GetPropertyPos(m_converter->getResult(), geomName);
61 
62  std::unique_ptr<te::da::DataSet> inDsetSrc;
63 
64  if(m_oidSet == nullptr)
65  inDsetSrc = m_inDsrc->getDataSet(m_inDsetName);
66  else
67  inDsetSrc = m_inDsrc->getDataSet(m_inDsetName, m_oidSet);
68 
69  std::unique_ptr<te::da::DataSetAdapter> inDset(te::da::CreateAdapter(inDsetSrc.get(), m_converter.get()));
70 
71  std::unique_ptr<te::mem::DataSet> outDSet(new te::mem::DataSet(outDsType.get()));
72 
73  te::common::TaskProgress task("Processing...");
74  task.setTotalSteps((int)inDset->size());
75  task.useTimer(true);
76 
77  inDset->moveBeforeFirst();
78  while(inDset->moveNext())
79  {
80  try
81  {
82  te::mem::DataSetItem* outDsItem = new te::mem::DataSetItem(outDSet.get());
83  bool geomState = true;
84 
85  for(size_t i = 0; i < outDsItem->getNumProperties(); ++i)
86  {
87  if(outDsItem->getPropertyDataType(i) != te::dt::GEOMETRY_TYPE)
88  {
89  int pos = static_cast<int>(m_converter->getResult()->getPropertyPosition(outDsItem->getPropertyName(i)));
90 
91  if(!inDset->isNull(pos))
92  outDsItem->setValue(i, inDset->getValue(outDsItem->getPropertyName(i)).get()->clone());
93  }
94  else
95  {
96  std::unique_ptr<te::gm::Geometry> geom = inDset->getGeometry(geomPos);
97  if(!geom->isValid())
98  {
99  geomState = false;
100  continue;
101  }
102 
103  std::unique_ptr<te::gm::MultiPolygon> polygonResult = line2Polygon(geom.get());
104 
105  if (polygonResult->isEmpty())
106  {
107  geomState = false;
108  continue;
109  }
110 
111  if (!polygonResult->isValid())
112  {
113  te::gm::Geometry* valid_geom = te::gm::Validate(polygonResult.get());
114  polygonResult.reset(dynamic_cast<te::gm::MultiPolygon*>(valid_geom));
115 
116  if (!polygonResult.get() || !polygonResult->isValid())
117  {
118  geomState = false;
119  continue;
120  }
121  }
122 
123  outDsItem->setGeometry(i, polygonResult.release());
124  }
125  }
126  if(!geomState)
127  continue;
128 
129  outDSet->add(outDsItem);
130 
131  if (task.isActive() == false)
132  throw te::vp::Exception(TE_TR("Operation canceled!"));
133 
134  task.pulse();
135  }
136  catch(te::common::Exception& e)
137  {
138  TE_LOG_ERROR("Vector Processing - Line to Polygon - " + e.what());
139  task.pulse();
140  continue;
141  }
142  }
143 
144  te::vp::Save(m_outDsrc.get(), outDSet.get(), outDsType.get());
145  return true;
146 }
147 
148 std::unique_ptr<te::gm::MultiPolygon> te::vp::LineToPolygonMemory::line2Polygon(te::gm::Geometry* geom)
149 {
150  std::vector<te::gm::Polygon*> polygons;
151  std::unique_ptr<te::gm::MultiPolygon> polygonResult(new te::gm::MultiPolygon(0, te::gm::MultiPolygonType, geom->getSRID()));
152 
153  getPolygons(geom, polygons);
154 
155  for(std::size_t i = 0; i < polygons.size(); ++i)
156  polygonResult->add(polygons[i]);
157 
158  return polygonResult;
159 }
160 
161 void te::vp::LineToPolygonMemory::getPolygons(te::gm::Geometry* geom, std::vector<te::gm::Polygon*>& polygons)
162 {
163  if(geom == nullptr)
164  return;
165 
166  switch(geom->getGeomTypeId())
167  {
169  getPolygons(dynamic_cast<te::gm::GeometryCollection*>(geom), polygons);
170  break;
171 
173  getPolygons(dynamic_cast<te::gm::LineString*>(geom), polygons);
174  break;
175 
177  getPolygons(dynamic_cast<te::gm::LineString*>(geom), polygons);
178  break;
179 
181  getPolygons(dynamic_cast<te::gm::LineString*>(geom), polygons);
182  break;
183 
185  getPolygons(dynamic_cast<te::gm::LineString*>(geom), polygons);
186  break;
187 
188  default:
189  break;
190  }
191 }
192 
193 void te::vp::LineToPolygonMemory::getPolygons(te::gm::GeometryCollection* gc, std::vector<te::gm::Polygon*>& polygons)
194 {
195  assert(gc);
196 
197  for(std::size_t i = 0; i < gc->getNumGeometries(); ++i)
198  getPolygons(gc->getGeometryN(i), polygons);
199 }
200 
201 void te::vp::LineToPolygonMemory::getPolygons(te::gm::LineString* l, std::vector<te::gm::Polygon*>& polygons)
202 {
203  assert(l);
204 
206 
207  te::gm::LinearRing* ring = nullptr;
208 
209  std::size_t size = l->getNPoints();
210 
211  if(l->isClosed())
212  {
214 
215  for(std::size_t i = 0; i < size; ++i)
216  ring->setPoint(i, l->getX(i), l->getY(i));
217  }
218  else
219  {
220  if(!m_forceClose)
221  return;
222 
223  ring = new te::gm::LinearRing(size + 1, te::gm::LineStringType);
224 
225  for(std::size_t i = 0; i < size; ++i)
226  ring->setPoint(i, l->getX(i), l->getY(i));
227 
228  ring->setPoint(size, l->getX(0), l->getY(0));
229  }
230 
231  p->add(ring);
232 
233  getPolygons(p, polygons);
234 }
235 
236 void te::vp::LineToPolygonMemory::getPolygons(te::gm::Polygon* p, std::vector<te::gm::Polygon*>& polygons)
237 {
238  assert(p);
239  polygons.push_back(p);
240 }
std::size_t getNumGeometries() const
It returns the number of geometries in this GeometryCollection.
void add(Curve *ring)
It adds the ring to the curve polygon.
MultiPolygon is a MultiSurface whose elements are Polygons.
Definition: MultiPolygon.h:50
Geometric property.
void setGeometry(std::size_t i, te::gm::Geometry *value)
It sets the value of the i-th property.
std::string getPropertyName(std::size_t pos) const
It returns the name of the pos-th property.
int getPropertyDataType(std::size_t pos) const
It returns the type of the pos-th property.
Base exception class for plugin module.
virtual const char * what() const
It outputs the exception message.
void useTimer(bool flag)
Used to define if task use progress timer information.
GeomType getGeomTypeId() const _NOEXCEPT_OP(true)
It returns the geometry subclass type identifier.
std::unique_ptr< te::gm::MultiPolygon > line2Polygon(te::gm::Geometry *geom)
This class can be used to inform the progress of a task.
Definition: TaskProgress.h:53
TEDATAACCESSEXPORT std::size_t GetPropertyPos(const DataSet *dataset, const std::string &name)
void setValue(std::size_t i, te::dt::AbstractData *value)
It sets the value of the i-th property.
const te::da::ObjectIdSet * m_oidSet
te::da::DataSourcePtr m_outDsrc
#define TE_TR(message)
It marks a string in order to get translated.
Definition: Translator.h:242
std::size_t getNumProperties() const
It returns the number of properties.
bool isActive() const
Verify if the task is active.
bool isClosed() const
It returns true if the curve is closed (startPoint = endPoint).
const double & getY(std::size_t i) const
It returns the n-th y coordinate value.
void setTotalSteps(int value)
Set the task total stepes.
te::gm::GeometryCollection * gc
TEVPEXPORT void Save(te::da::DataSource *source, te::da::DataSet *result, te::da::DataSetType *outDsType, const bool &enableProgress=true)
A LinearRing is a LineString that is both closed and simple.
Definition: LinearRing.h:53
Implementation of a random-access dataset class for the TerraLib In-Memory Data Access driver...
int getSRID() const _NOEXCEPT_OP(true)
It returns the Spatial Reference System ID associated to this geometric object.
LineString is a curve with linear interpolation between points.
Definition: LineString.h:62
void getPolygons(te::gm::Geometry *geom, std::vector< te::gm::Polygon * > &polygons)
void setPoint(std::size_t i, const double &x, const double &y)
It sets the value of the specified point.
const double & getX(std::size_t i) const
It returns the n-th x coordinate value.
URI C++ Library.
Definition: Attributes.h:37
std::unique_ptr< te::da::DataSetTypeConverter > m_converter
te::gm::Polygon * p
std::size_t getNPoints() const
It returns the number of points (vertexes) in the linestring.
Definition: LineString.h:193
void pulse()
Calls setCurrentStep() function using getCurrentStep() + 1.
Utility functions for the data access module.
This class is designed to declare objects to be thrown as exceptions by TerraLib. ...
Geometry is the root class of the geometries hierarchy, it follows OGC and ISO standards.
Geometry * getGeometryN(std::size_t i) const
It returns the n-th geometry in this GeometryCollection.
te::da::DataSourcePtr m_inDsrc
An implementation of the DatasetItem class for the TerraLib In-Memory Data Access driver...
Polygon is a subclass of CurvePolygon whose rings are defined by linear rings.
Definition: Polygon.h:50
#define TE_LOG_ERROR(message)
Use this tag in order to log a message to the TerraLib default logger with the ERROR level...
Definition: Logger.h:337
It is a collection of other geometric objects.
TEDATAACCESSEXPORT te::gm::GeometryProperty * GetFirstGeomProperty(const DataSetType *dt)
Line to Polygon Vector Processing functions.
TEDATAACCESSEXPORT DataSetAdapter * CreateAdapter(DataSet *ds, DataSetTypeConverter *converter, bool isOwner=false)
TEGEOMEXPORT te::gm::Geometry * Validate(te::gm::Geometry *geom)
Get/create a valid version of the geometry given. If the geometry is a polygon or multi polygon...
std::unique_ptr< te::da::DataSetType > buildOutDataSetType()
const std::string & getName() const
It returns the property name.
Definition: Property.h:127