All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
IntersectionMemory.cpp
Go to the documentation of this file.
1 /* Copyright (C) 2008-2013 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 "../common/progress/TaskProgress.h"
29 #include "../common/Logger.h"
30 #include "../common/Translator.h"
31 
32 #include "../dataaccess/dataset/DataSet.h"
33 #include "../dataaccess/dataset/DataSetType.h"
34 #include "../dataaccess/utils/Utils.h"
35 #include "../datatype/Property.h"
36 
37 #include "../datatype/SimpleProperty.h"
38 #include "../datatype/StringProperty.h"
39 
40 #include "../geometry/Geometry.h"
41 #include "../geometry/GeometryCollection.h"
42 #include "../geometry/GeometryProperty.h"
43 #include "../geometry/MultiLineString.h"
44 #include "../geometry/MultiPoint.h"
45 #include "../geometry/MultiPolygon.h"
46 #include "../geometry/Utils.h"
47 
48 #include "../memory/DataSet.h"
49 #include "../memory/DataSetItem.h"
50 
51 #include "../sam.h"
52 
53 #include "IntersectionMemory.h"
54 #include "Config.h"
55 #include "Exception.h"
56 #include "Utils.h"
57 
58 // STL
59 #include <map>
60 #include <math.h>
61 #include <string>
62 #include <vector>
63 
64 // BOOST
65 #include <boost/lexical_cast.hpp>
66 #include <boost/algorithm/string.hpp>
67 
68 
70 {}
71 
73 {}
74 
75 
77 {
78  if(m_SRID == 0)
79  {
80  te::gm::GeometryProperty* geom = te::da::GetFirstGeomProperty(m_inFirstDsetType.get());
81  m_SRID = geom->getSRID();
82  }
83 
84  std::vector<te::dt::Property*> firstProps = getTabularProps(m_inFirstDsetType.get());
85 
86  IntersectionMember firstMember;
87  firstMember.dt = m_inFirstDsetType.release();
88  if(m_firstOidSet == 0)
89  firstMember.ds = m_inFirstDsrc->getDataSet(m_inFirstDsetName).release();
90  else
91  firstMember.ds = m_inFirstDsrc->getDataSet(m_inFirstDsetName, m_firstOidSet).release();
92  firstMember.props = firstProps;
93 
94  IntersectionMember secondMember;
95  secondMember.dt = m_inSecondDsetType.release();
96  if(m_secondOidSet == 0)
97  secondMember.ds = m_inSecondDsrc->getDataSet(m_inSecondDsetName).release();
98  else
99  secondMember.ds = m_inSecondDsrc->getDataSet(m_inSecondDsetName, m_secondOidSet).release();
100  if(m_copyInputColumns)
101  secondMember.props = getTabularProps(secondMember.dt);
102 
103  std::pair<te::da::DataSetType*, te::da::DataSet*> resultPair;
104  resultPair = this->pairwiseIntersection(m_outDsetName, firstMember, secondMember, m_SRID);
105 
106  if(resultPair.second->size() < 1)
107  throw te::common::Exception(TE_TR("The Layers do not intersect!"));
108 
109  std::auto_ptr<te::da::DataSet> outDataSet(resultPair.second);
110  std::auto_ptr<te::da::DataSetType> outDataSetType(resultPair.first);
111 
112  return save(outDataSet, outDataSetType);
113 }
114 
115 std::pair<te::da::DataSetType*, te::da::DataSet*> te::vp::IntersectionMemory::pairwiseIntersection(std::string newName,
116  IntersectionMember firstMember,
117  IntersectionMember secondMember,
118  std::size_t outputSRID)
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 
125  size_t secondDsCount = 0;
126  int sridSecond = -1;
127 
128  while(secondMember.ds->moveNext())
129  {
130  std::auto_ptr<te::gm::Geometry> g = secondMember.ds->getGeometry(secGeomPropPos);
131 
132  if(sridSecond == -1)
133  sridSecond = g->getSRID();
134 
135  rtree->insert(*g->getMBR(), secondDsCount);
136 
137  ++secondDsCount;
138  }
139 
140  firstMember.ds->moveBeforeFirst();
141 
142  std::auto_ptr<te::gm::GeometryProperty> fiGeomProp (te::da::GetFirstGeomProperty(firstMember.dt));
143  size_t fiGeomPropPos = firstMember.dt->getPropertyPosition(fiGeomProp.get());
144 
145  // Create the DataSetType and DataSet
146  te::da::DataSetType* outputDt = this->createDataSetType(newName, firstMember.dt, firstMember.props, secondMember.dt, secondMember.props);
147  te::mem::DataSet* outputDs = new te::mem::DataSet(outputDt);
148 
149  std::pair<te::da::DataSetType*, te::da::DataSet*> resultPair;
150 
151  te::common::TaskProgress task("Processing intersection...");
152  task.setTotalSteps(firstMember.ds->size());
153  task.useTimer(true);
154 
155  std::size_t pk = 0;
156 
157  while(firstMember.ds->moveNext())
158  {
159  std::auto_ptr<te::gm::Geometry> currGeom = firstMember.ds->getGeometry(fiGeomPropPos);
160 
161  if(currGeom->getSRID() != sridSecond)
162  currGeom->transform(sridSecond);
163 
164  std::vector<size_t> report;
165  rtree->search(*currGeom->getMBR(), report);
166 
167  if(!report.empty())
168  currGeom->transform(outputSRID);
169 
170  for(size_t i = 0; i < report.size(); ++i)
171  {
172  secondMember.ds->move(report[i]);
173  std::auto_ptr<te::gm::Geometry> secGeom = secondMember.ds->getGeometry(secGeomPropPos);
174 
175  if(secGeom->getSRID() != outputSRID)
176  secGeom->transform(outputSRID);
177 
178  if(!currGeom->intersects(secGeom.get()))
179  continue;
180 
181  te::mem::DataSetItem* item = new te::mem::DataSetItem(outputDs);
182  std::auto_ptr<te::gm::Geometry> resultGeom;
183 
184  if(currGeom->isValid() && secGeom->isValid())
185  resultGeom.reset(currGeom->intersection(secGeom.get()));
186 
187  if(resultGeom.get()!=0 && resultGeom->isValid())
188  {
190 
191  if(fiGeomProp->getGeometryType() == te::gm::MultiPolygonType)
192  {
193  if(resultGeom->getGeomTypeId() == te::gm::MultiPolygonType)
194  {
195  item->setGeometry("geom", resultGeom.release());
196  }
197  else if(resultGeom->getGeomTypeId() == te::gm::PolygonType)
198  {
199  te::gm::MultiPolygon* newGeom = new te::gm::MultiPolygon(0, te::gm::MultiPolygonType, resultGeom->getSRID());
200  newGeom->add(resultGeom.release());
201  item->setGeometry("geom", newGeom);
202  }
203  }
204  else if(fiGeomProp->getGeometryType() == te::gm::MultiLineStringType)
205  {
206  if(resultGeom->getGeomTypeId() == te::gm::MultiLineStringType)
207  {
208  item->setGeometry("geom", resultGeom.release());
209  }
210  else if(resultGeom->getGeomTypeId() == te::gm::LineStringType)
211  {
212  te::gm::MultiLineString* newGeom = new te::gm::MultiLineString(0, te::gm::MultiLineStringType, resultGeom->getSRID());
213  newGeom->add(resultGeom.release());
214  item->setGeometry("geom", newGeom);
215  }
216  }
217  else if(fiGeomProp->getGeometryType() == te::gm::MultiPointType)
218  {
219  if(resultGeom->getGeomTypeId() == te::gm::MultiPointType)
220  {
221  item->setGeometry("geom", resultGeom.release());
222  }
223  else if(resultGeom->getGeomTypeId() == te::gm::PointType)
224  {
225  te::gm::MultiPoint* newGeom = new te::gm::MultiPoint(0, te::gm::MultiPointType, resultGeom->getSRID());
226  newGeom->add(resultGeom.release());
227  item->setGeometry("geom", newGeom);
228  }
229  }
230  }
231  else
232  {
233  te::common::Logger::logDebug("vp", "Intersection - Invalid geometry found");
234  continue;
235  }
236 
237  for(size_t j = 0; j < firstMember.props.size(); ++j)
238  {
239  std::string name = firstMember.props[j]->getName();
240 
241  if(!firstMember.dt->getTitle().empty())
242  name = te::vp::GetSimpleTableName(firstMember.dt->getTitle()) + "_" + name;
243 
244  te::dt::AbstractData* ad = firstMember.ds->getValue(firstMember.props[j]->getName()).release();
245 
246  item->setValue(name, ad);
247  }
248 
249  for(size_t j = 0; j < secondMember.props.size(); ++j)
250  {
251  std::string name = secondMember.props[j]->getName();
252 
253  if (!secondMember.dt->getTitle().empty())
254  name = te::vp::GetSimpleTableName(secondMember.dt->getTitle()) + "_" + name;
255 
256  te::dt::AbstractData* ad = secondMember.ds->getValue(secondMember.props[j]->getName()).release();
257 
258  item->setValue(name, ad);
259  }
260 
261  item->setInt32(newName + "_id", pk);
262  ++pk;
263 
264  outputDs->moveNext();
265 
266  int aux = te::da::GetFirstSpatialPropertyPos(outputDs);
267 
268  if(!item->isNull(aux))
269  outputDs->add(item);
270  }
271 
272  if(task.isActive() == false)
273  {
274  delete outputDt;
275  delete outputDs;
276 
277  throw te::common::Exception(TE_TR("Operation canceled!"));
278  }
279 
280  task.pulse();
281  }
282 
283  outputDs->moveBeforeFirst();
284 
285  resultPair.first = outputDt;
286  resultPair.second = outputDs;
287  return resultPair;
288 }
289 
291  te::da::DataSetType* firstDt,
292  std::vector<te::dt::Property*> firstProps,
293  te::da::DataSetType* secondDt,
294  std::vector<te::dt::Property*> secondProps)
295 {
296  te::da::DataSetType* outputDt = new te::da::DataSetType(newName);
297 
298 
299 
300  te::dt::SimpleProperty* pkProperty = new te::dt::SimpleProperty(newName + "_id", te::dt::INT32_TYPE);
301  pkProperty->setAutoNumber(true);
302  outputDt->add(pkProperty);
303 
304  te::da::PrimaryKey* pk = new te::da::PrimaryKey(newName + "_pk", outputDt);
305  pk->add(pkProperty);
306  outputDt->setPrimaryKey(pk);
307 
308  for(size_t i = 0; i < firstProps.size(); ++i)
309  {
310  te::dt::Property* prop = firstProps[i]->clone();
311  if(!firstDt->getTitle().empty())
312  prop->setName(te::vp::GetSimpleTableName(firstDt->getTitle()) + "_" + prop->getName());
313  outputDt->add(prop);
314  }
315 
316  for(size_t i = 0; i < secondProps.size(); ++i)
317  {
318  te::dt::Property* prop = secondProps[i]->clone();
319  prop->setName(te::vp::GetSimpleTableName(secondDt->getTitle()) + "_" + prop->getName());
320  outputDt->add(prop);
321  }
322 
323  te::gm::GeomType newType = te::vp::GeomOpResultType(te::da::GetFirstGeomProperty(firstDt)->getGeometryType(), te::da::GetFirstGeomProperty(secondDt)->getGeometryType());
324 
325  te::gm::GeometryProperty* newGeomProp = new te::gm::GeometryProperty("geom");
326  newGeomProp->setGeometryType(newType);
327  newGeomProp->setSRID(te::da::GetFirstGeomProperty(firstDt)->getSRID());
328 
329  outputDt->add(newGeomProp);
330 
331  return outputDt;
332 }
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
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:345
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:168
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:136
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:413
int getSRID() const
It returns the spatial reference system identifier associated to this property.
std::pair< te::da::DataSetType *, te::da::DataSet * > pairwiseIntersection(std::string newName, IntersectionMember firstMember, IntersectionMember secondMember, std::size_t outputSRID)
GeomType getGeometryType() const
It returns the geometry subtype allowed for the property.
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:324
bool moveNext()
It moves the internal pointer to the next item of the collection.
Definition: DataSet.cpp:312
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
te::gm::GeomType GeomOpResultType(te::gm::GeomType firstGeom, te::gm::GeomType secondGeom)
Definition: Utils.cpp:167
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:508
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 & getTitle() const
A human descriptive title for the DataSetType.
Definition: DataSetType.h:130
const std::string & getName() const
It returns the property name.
Definition: Property.h:126
std::string GetSimpleTableName(std::string fullName)
Definition: Utils.cpp:157