IntersectionMemory.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 AggregationMemory.h
22 
23  \brief Aggregation Vector Processing functions.
24 */
25 
26 //Terralib
27 
28 #include "../BuildConfig.h"
29 #include "../common/progress/TaskProgress.h"
30 #include "../common/Logger.h"
31 #include "../common/Translator.h"
32 
33 #include "../dataaccess/dataset/DataSet.h"
34 #include "../dataaccess/dataset/DataSetAdapter.h"
35 #include "../dataaccess/utils/Utils.h"
36 #include "../datatype/Property.h"
37 
38 #include "../datatype/SimpleProperty.h"
39 #include "../datatype/StringProperty.h"
40 
41 #include "../geometry/Geometry.h"
42 #include "../geometry/GeometryCollection.h"
43 #include "../geometry/GeometryProperty.h"
44 #include "../geometry/MultiLineString.h"
45 #include "../geometry/MultiPoint.h"
46 #include "../geometry/MultiPolygon.h"
47 #include "../geometry/Utils.h"
48 
49 #include "../memory/DataSet.h"
50 #include "../memory/DataSetItem.h"
51 
52 #include "../sam.h"
53 
54 #include "IntersectionMemory.h"
55 #include "Config.h"
56 #include "Exception.h"
57 #include "Utils.h"
58 
59 // STL
60 #include <map>
61 #include <math.h>
62 #include <string>
63 #include <vector>
64 
65 // BOOST
66 #include <boost/lexical_cast.hpp>
67 #include <boost/algorithm/string.hpp>
68 
69 
71 {}
72 
74 {}
75 
76 
77 bool te::vp::IntersectionMemory::run() throw(te::common::Exception)
78 {
79  std::vector<te::dt::Property*> firstProps = getTabularProps(m_firstConverter->getResult());
80 
81  IntersectionMember firstMember;
82  firstMember.dt = m_firstConverter->getResult();
83 
84  if (m_firstOidSet == 0)
85  firstMember.ds = te::da::CreateAdapter(m_inFirstDsrc->getDataSet(m_inFirstDsetName).release(), m_firstConverter.get());
86  else
87  firstMember.ds = te::da::CreateAdapter(m_inFirstDsrc->getDataSet(m_inFirstDsetName, m_firstOidSet).release(), m_firstConverter.get());
88 
89  firstMember.props = firstProps;
90 
91  IntersectionMember secondMember;
92  secondMember.dt = m_secondConverter->getResult();
93 
94  if (m_secondOidSet == 0)
95  secondMember.ds = te::da::CreateAdapter(m_inSecondDsrc->getDataSet(m_inSecondDsetName).release(), m_secondConverter.get());
96  else
97  secondMember.ds = te::da::CreateAdapter(m_inSecondDsrc->getDataSet(m_inSecondDsetName, m_secondOidSet).release(), m_secondConverter.get());
98 
99  if(m_copyInputColumns)
100  secondMember.props = getTabularProps(secondMember.dt);
101 
102  std::pair<te::da::DataSetType*, te::da::DataSet*> resultPair;
103  resultPair = this->pairwiseIntersection(m_outDsetName, firstMember, secondMember);
104 
105  if(resultPair.second->size() < 1)
106  throw te::common::Exception(TE_TR("The Layers do not intersect!"));
107 
108  std::auto_ptr<te::da::DataSet> outDataSet(resultPair.second);
109  std::auto_ptr<te::da::DataSetType> outDataSetType(resultPair.first);
110 
111  te::vp::Save(m_outDsrc.get(), outDataSet.get(), outDataSetType.get());
112  return true;
113 
114 }
115 
116 std::pair<te::da::DataSetType*, te::da::DataSet*> te::vp::IntersectionMemory::pairwiseIntersection(std::string newName,
117  IntersectionMember firstMember,
118  IntersectionMember secondMember)
119 {
120 
121  //Creating the RTree with the secound layer geometries
123  size_t secGeomPropPos = secondMember.dt->getPropertyPosition(secondMember.dt->findFirstPropertyOfType(te::dt::GEOMETRY_TYPE));
124  te::gm::GeometryProperty* geomProp = te::da::GetFirstGeomProperty(secondMember.dt);
125 
126  size_t secondDsCount = 0;
127  int sridSecond = -1;
128 
129  secondMember.ds->moveBeforeFirst();
130  while(secondMember.ds->moveNext())
131  {
132  std::auto_ptr<te::gm::Geometry> g = secondMember.ds->getGeometry(secGeomPropPos);
133 
134  if(sridSecond == -1)
135  sridSecond = geomProp->getSRID();
136 
137  rtree->insert(*g->getMBR(), secondDsCount);
138 
139  ++secondDsCount;
140  }
141 
142  firstMember.ds->moveBeforeFirst();
143 
144  te::gm::GeometryProperty* fiGeomProp = te::da::GetFirstGeomProperty(firstMember.dt);
145  size_t fiGeomPropPos = firstMember.dt->getPropertyPosition(fiGeomProp);
146 
147  // Create the DataSetType and DataSet
148  te::da::DataSetType* outputDt = this->createDataSetType(newName, firstMember.dt, firstMember.props, secondMember.dt, secondMember.props);
149  te::mem::DataSet* outputDs = new te::mem::DataSet(outputDt);
150 
151  std::pair<te::da::DataSetType*, te::da::DataSet*> resultPair;
152 
153  te::common::TaskProgress task("Processing intersection...");
154  task.setTotalSteps((int)firstMember.ds->size());
155  task.useTimer(true);
156 
157  int pk = 0;
158 
159  while(firstMember.ds->moveNext())
160  {
161  std::auto_ptr<te::gm::Geometry> currGeom = firstMember.ds->getGeometry(fiGeomPropPos);
162 
163  if(currGeom->getSRID() != sridSecond)
164  currGeom->transform(sridSecond);
165 
166  std::vector<size_t> report;
167  rtree->search(*currGeom->getMBR(), report);
168 
169  if(!report.empty())
170  currGeom->transform(fiGeomProp->getSRID());
171 
172  for(size_t i = 0; i < report.size(); ++i)
173  {
174  secondMember.ds->move(report[i]);
175  std::auto_ptr<te::gm::Geometry> secGeom = secondMember.ds->getGeometry(secGeomPropPos);
176  secGeom->setSRID(sridSecond);
177 
178  if (secGeom->getSRID() != fiGeomProp->getSRID())
179  secGeom->transform(fiGeomProp->getSRID());
180 
181  if(!currGeom->intersects(secGeom.get()))
182  continue;
183 
184  te::mem::DataSetItem* item = new te::mem::DataSetItem(outputDs);
185  std::auto_ptr<te::gm::Geometry> resultGeom;
186 
187  if(currGeom->isValid() && secGeom->isValid())
188  resultGeom.reset(currGeom->intersection(secGeom.get()));
189 
190  if(resultGeom.get()!=0 && resultGeom->isValid())
191  {
193 
194  if(fiGeomProp->getGeometryType() == te::gm::MultiPolygonType)
195  {
196  if(resultGeom->getGeomTypeId() == te::gm::MultiPolygonType)
197  {
198  item->setGeometry("geom", resultGeom.release());
199  }
200  else if(resultGeom->getGeomTypeId() == te::gm::PolygonType)
201  {
202  te::gm::MultiPolygon* newGeom = new te::gm::MultiPolygon(0, te::gm::MultiPolygonType, resultGeom->getSRID());
203  newGeom->add(resultGeom.release());
204  item->setGeometry("geom", newGeom);
205  }
206  }
207  else if(fiGeomProp->getGeometryType() == te::gm::MultiLineStringType)
208  {
209  if(resultGeom->getGeomTypeId() == te::gm::MultiLineStringType)
210  {
211  item->setGeometry("geom", resultGeom.release());
212  }
213  else if(resultGeom->getGeomTypeId() == te::gm::LineStringType)
214  {
215  te::gm::MultiLineString* newGeom = new te::gm::MultiLineString(0, te::gm::MultiLineStringType, resultGeom->getSRID());
216  newGeom->add(resultGeom.release());
217  item->setGeometry("geom", newGeom);
218  }
219  }
220  else if(fiGeomProp->getGeometryType() == te::gm::MultiPointType)
221  {
222  if(resultGeom->getGeomTypeId() == te::gm::MultiPointType)
223  {
224  item->setGeometry("geom", resultGeom.release());
225  }
226  else if(resultGeom->getGeomTypeId() == te::gm::PointType)
227  {
228  te::gm::MultiPoint* newGeom = new te::gm::MultiPoint(0, te::gm::MultiPointType, resultGeom->getSRID());
229  newGeom->add(resultGeom.release());
230  item->setGeometry("geom", newGeom);
231  }
232  }
233  }
234  else
235  {
236 #ifdef TERRALIB_LOGGER_ENABLED
237  te::common::Logger::logDebug("vp", "Intersection - Invalid geometry found");
238 #endif //TERRALIB_LOGGER_ENABLED
239  continue;
240  }
241 
242  for(size_t j = 0; j < firstMember.props.size(); ++j)
243  {
244  std::string name = firstMember.props[j]->getName();
245 
246  if (!m_inFirstDsetName.empty())
247  name = te::vp::GetSimpleTableName(m_inFirstDsetName) + "_" + name;
248 
249  te::dt::AbstractData* ad = firstMember.ds->getValue(firstMember.props[j]->getName()).release();
250 
251  item->setValue(name, ad);
252  }
253 
254  for(size_t j = 0; j < secondMember.props.size(); ++j)
255  {
256  std::string name = secondMember.props[j]->getName();
257 
258  if (!m_inSecondDsetName.empty())
259  name = te::vp::GetSimpleTableName(m_inSecondDsetName) + "_" + name;
260 
261  te::dt::AbstractData* ad = secondMember.ds->getValue(secondMember.props[j]->getName()).release();
262 
263  item->setValue(name, ad);
264  }
265 
266  item->setInt32(newName + "_id", pk);
267  ++pk;
268 
269  outputDs->moveNext();
270 
271  std::size_t aux = te::da::GetFirstSpatialPropertyPos(outputDs);
272 
273  if(!item->isNull(aux))
274  outputDs->add(item);
275  }
276 
277  if(task.isActive() == false)
278  {
279  delete outputDt;
280  delete outputDs;
281 
282  throw te::common::Exception(TE_TR("Operation canceled!"));
283  }
284 
285  task.pulse();
286  }
287 
288  outputDs->moveBeforeFirst();
289 
290  resultPair.first = outputDt;
291  resultPair.second = outputDs;
292  return resultPair;
293 }
294 
296  te::da::DataSetType* firstDt,
297  std::vector<te::dt::Property*> firstProps,
298  te::da::DataSetType* secondDt,
299  std::vector<te::dt::Property*> secondProps)
300 {
301  te::da::DataSetType* outputDt = new te::da::DataSetType(newName);
302 
303 
304 
305  te::dt::SimpleProperty* pkProperty = new te::dt::SimpleProperty(newName + "_id", te::dt::INT32_TYPE);
306  pkProperty->setAutoNumber(true);
307  outputDt->add(pkProperty);
308 
309  te::da::PrimaryKey* pk = new te::da::PrimaryKey(newName + "_pk", outputDt);
310  pk->add(pkProperty);
311  outputDt->setPrimaryKey(pk);
312 
313  for(size_t i = 0; i < firstProps.size(); ++i)
314  {
315  te::dt::Property* prop = firstProps[i]->clone();
316  if (!m_inFirstDsetName.empty())
317  prop->setName(te::vp::GetSimpleTableName(m_inFirstDsetName) + "_" + prop->getName());
318  outputDt->add(prop);
319  }
320 
321  for(size_t i = 0; i < secondProps.size(); ++i)
322  {
323  te::dt::Property* prop = secondProps[i]->clone();
324  if (!m_inSecondDsetName.empty())
325  prop->setName(te::vp::GetSimpleTableName(m_inSecondDsetName) + "_" + prop->getName());
326  outputDt->add(prop);
327  }
328 
329  te::gm::GeomType newType = setGeomResultType(te::da::GetFirstGeomProperty(firstDt)->getGeometryType(), te::da::GetFirstGeomProperty(secondDt)->getGeometryType());
330 
331  te::gm::GeometryProperty* newGeomProp = new te::gm::GeometryProperty("geom");
332  newGeomProp->setGeometryType(newType);
333  newGeomProp->setSRID(te::da::GetFirstGeomProperty(firstDt)->getSRID());
334 
335  outputDt->add(newGeomProp);
336 
337  return outputDt;
338 }
void setAutoNumber(bool a)
It tells if the property is an autonumber or not.
MultiPolygon is a MultiSurface whose elements are Polygons.
Definition: MultiPolygon.h:50
Geometric property.
An exception class for the Vector processing module.
void add(te::dt::Property *p)
It adds a property to the list of properties of the primary key.
Definition: PrimaryKey.h:123
GeomType
Each enumerated type is compatible with a Well-known Binary (WKB) type code.
Definition: Enums.h:41
void setGeometry(std::size_t i, te::gm::Geometry *value)
It sets the value of the i-th property.
Utility functions for the data access module.
void setSRID(int srid)
It sets the spatial reference system identifier associated to this property.
void setGeometryType(GeomType t)
It sets the geometry subtype.
An atomic property like an integer or double.
A class that represents an R-tree.
Definition: Index.h:56
A class that models the description of a dataset.
Definition: DataSetType.h:72
bool isNull(std::size_t i) const
void useTimer(bool flag)
Used to define if task use progress timer information.
std::vector< te::dt::Property * > props
void Save(te::da::DataSource *source, te::da::DataSet *result, te::da::DataSetType *outDsType)
Definition: Utils.cpp:172
virtual Property * clone() const =0
It returns a clone of the object.
This class can be used to inform the progress of a task.
Definition: TaskProgress.h:53
void setValue(std::size_t i, te::dt::AbstractData *value)
It sets the value of the i-th property.
#define TE_TR(message)
It marks a string in order to get translated.
Definition: Translator.h:346
It models a property definition.
Definition: Property.h:59
bool isActive() const
Verify if the task is active.
te::da::DataSetType * createDataSetType(std::string newName, te::da::DataSetType *firstDt, std::vector< te::dt::Property * > firstProps, te::da::DataSetType *secondDt, std::vector< te::dt::Property * > secondProps)
void add(DataSetItem *item)
It adds a new item to the dataset and takes its ownership.
Definition: DataSet.cpp:172
virtual bool move(std::size_t i)=0
It moves the dataset internal pointer to a given position.
void setTotalSteps(int value)
Set the task total stepes.
void setInt32(std::size_t i, boost::int32_t value)
It sets the value of the i-th property.
virtual bool moveNext()=0
It moves the internal pointer to the next item of the collection.
Implementation of a random-access dataset class for the TerraLib In-Memory Data Access driver...
Definition: DataSet.h:65
void setName(const std::string &name)
It sets the property name.
Definition: Property.h:137
MultiPoint is a GeometryCollection whose elements are restricted to points.
Definition: MultiPoint.h:50
TEDATAACCESSEXPORT std::size_t GetFirstSpatialPropertyPos(const te::da::DataSet *dataset)
It returns the first dataset spatial property or NULL if none is found.
Definition: Utils.cpp:462
int getSRID() const
It returns the spatial reference system identifier associated to this property.
URI C++ Library.
GeomType getGeometryType() const
It returns the geometry subtype allowed for the property.
std::pair< te::da::DataSetType *, te::da::DataSet * > pairwiseIntersection(std::string newName, IntersectionMember firstMember, IntersectionMember secondMember)
virtual std::size_t size() const =0
It returns the collection size, if it is known.
void pulse()
Calls setCurrentStep() function using getCurrentStep() + 1.
A base class for values that can be retrieved from the data access module.
Definition: AbstractData.h:57
int search(const te::gm::Envelope &mbr, std::vector< DATATYPE > &report) const
Range search query.
Definition: Index.h:326
This class is designed to declare objects to be thrown as exceptions by TerraLib. ...
Definition: Exception.h:58
virtual std::auto_ptr< te::gm::Geometry > getGeometry(std::size_t i) const =0
Method for retrieving a geometric attribute value.
bool moveBeforeFirst()
It moves the internal pointer to a position before the first item in the collection.
Definition: DataSet.cpp:328
bool moveNext()
It moves the internal pointer to the next item of the collection.
Definition: DataSet.cpp:316
void add(Constraint *c)
It adds a new constraint.
MultiLineString is a MultiCurve whose elements are LineStrings.
An implementation of the DatasetItem class for the TerraLib In-Memory Data Access driver...
Definition: DataSetItem.h:56
Property * findFirstPropertyOfType(const int t) const
returns the first property of the given data type. Caller doesn't take ownership of the returned poin...
void insert(const te::gm::Envelope &mbr, const DATATYPE &data)
It inserts an item into the tree.
Definition: Index.h:313
It describes a primary key (pk) constraint.
Definition: PrimaryKey.h:52
void add(Geometry *g)
It adds the geometry into the collection.
virtual bool moveBeforeFirst()=0
It moves the internal pointer to a position before the first item in the collection.
std::size_t getPropertyPosition(const std::string &name) const
It returns the property position based on its name.
Configuration flags for the Terrralib Vector Processing module.
TEDATAACCESSEXPORT te::gm::GeometryProperty * GetFirstGeomProperty(const DataSetType *dt)
Definition: Utils.cpp:557
TEDATAACCESSEXPORT DataSetAdapter * CreateAdapter(DataSet *ds, DataSetTypeConverter *converter, bool isOwner=false)
Definition: Utils.cpp:644
void setPrimaryKey(PrimaryKey *pk)
It sets the primary key constraint.
virtual std::auto_ptr< te::dt::AbstractData > getValue(std::size_t i) const
Method for retrieving any other type of data value stored in the data source.
Definition: DataSet.cpp:151
const std::string & getName() const
It returns the property name.
Definition: Property.h:127
std::string GetSimpleTableName(std::string fullName)
Definition: Utils.cpp:162