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 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 "terralib_config.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/DataSetType.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  if(m_SRID == 0)
80  {
81  te::gm::GeometryProperty* geom = te::da::GetFirstGeomProperty(m_inFirstDsetType.get());
82  m_SRID = geom->getSRID();
83  }
84 
85  std::vector<te::dt::Property*> firstProps = getTabularProps(m_inFirstDsetType.get());
86 
87  IntersectionMember firstMember;
88  firstMember.dt = m_inFirstDsetType.release();
89  if(m_firstOidSet == 0)
90  firstMember.ds = m_inFirstDsrc->getDataSet(m_inFirstDsetName).release();
91  else
92  firstMember.ds = m_inFirstDsrc->getDataSet(m_inFirstDsetName, m_firstOidSet).release();
93  firstMember.props = firstProps;
94 
95  IntersectionMember secondMember;
96  secondMember.dt = m_inSecondDsetType.release();
97  if(m_secondOidSet == 0)
98  secondMember.ds = m_inSecondDsrc->getDataSet(m_inSecondDsetName).release();
99  else
100  secondMember.ds = m_inSecondDsrc->getDataSet(m_inSecondDsetName, m_secondOidSet).release();
101  if(m_copyInputColumns)
102  secondMember.props = getTabularProps(secondMember.dt);
103 
104  std::pair<te::da::DataSetType*, te::da::DataSet*> resultPair;
105  resultPair = this->pairwiseIntersection(m_outDsetName, firstMember, secondMember, m_SRID);
106 
107  if(resultPair.second->size() < 1)
108  throw te::common::Exception(TE_TR("The Layers do not intersect!"));
109 
110  std::auto_ptr<te::da::DataSet> outDataSet(resultPair.second);
111  std::auto_ptr<te::da::DataSetType> outDataSetType(resultPair.first);
112 
113  te::vp::Save(m_outDsrc.get(), outDataSet.get(), outDataSetType.get());
114  return true;
115 
116 }
117 
118 std::pair<te::da::DataSetType*, te::da::DataSet*> te::vp::IntersectionMemory::pairwiseIntersection(std::string newName,
119  IntersectionMember firstMember,
120  IntersectionMember secondMember,
121  std::size_t outputSRID)
122 {
123 
124  //Creating the RTree with the secound layer geometries
126  size_t secGeomPropPos = secondMember.dt->getPropertyPosition(secondMember.dt->findFirstPropertyOfType(te::dt::GEOMETRY_TYPE));
127 
128  size_t secondDsCount = 0;
129  int sridSecond = -1;
130 
131  while(secondMember.ds->moveNext())
132  {
133  std::auto_ptr<te::gm::Geometry> g = secondMember.ds->getGeometry(secGeomPropPos);
134 
135  if(sridSecond == -1)
136  sridSecond = g->getSRID();
137 
138  rtree->insert(*g->getMBR(), secondDsCount);
139 
140  ++secondDsCount;
141  }
142 
143  firstMember.ds->moveBeforeFirst();
144 
145  std::auto_ptr<te::gm::GeometryProperty> fiGeomProp (te::da::GetFirstGeomProperty(firstMember.dt));
146  size_t fiGeomPropPos = firstMember.dt->getPropertyPosition(fiGeomProp.get());
147 
148  // Create the DataSetType and DataSet
149  te::da::DataSetType* outputDt = this->createDataSetType(newName, firstMember.dt, firstMember.props, secondMember.dt, secondMember.props);
150  te::mem::DataSet* outputDs = new te::mem::DataSet(outputDt);
151 
152  std::pair<te::da::DataSetType*, te::da::DataSet*> resultPair;
153 
154  te::common::TaskProgress task("Processing intersection...");
155  task.setTotalSteps(firstMember.ds->size());
156  task.useTimer(true);
157 
158  std::size_t pk = 0;
159 
160  while(firstMember.ds->moveNext())
161  {
162  std::auto_ptr<te::gm::Geometry> currGeom = firstMember.ds->getGeometry(fiGeomPropPos);
163 
164  if(currGeom->getSRID() != sridSecond)
165  currGeom->transform(sridSecond);
166 
167  std::vector<size_t> report;
168  rtree->search(*currGeom->getMBR(), report);
169 
170  if(!report.empty())
171  currGeom->transform(outputSRID);
172 
173  for(size_t i = 0; i < report.size(); ++i)
174  {
175  secondMember.ds->move(report[i]);
176  std::auto_ptr<te::gm::Geometry> secGeom = secondMember.ds->getGeometry(secGeomPropPos);
177 
178  if(secGeom->getSRID() != outputSRID)
179  secGeom->transform(outputSRID);
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(!firstMember.dt->getTitle().empty())
247  name = te::vp::GetSimpleTableName(firstMember.dt->getTitle()) + "_" + 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 (!secondMember.dt->getTitle().empty())
259  name = te::vp::GetSimpleTableName(secondMember.dt->getTitle()) + "_" + 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  int 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(!firstDt->getTitle().empty())
317  prop->setName(te::vp::GetSimpleTableName(firstDt->getTitle()) + "_" + 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  prop->setName(te::vp::GetSimpleTableName(secondDt->getTitle()) + "_" + prop->getName());
325  outputDt->add(prop);
326  }
327 
328  te::gm::GeomType newType = te::vp::GeomOpResultType(te::da::GetFirstGeomProperty(firstDt)->getGeometryType(), te::da::GetFirstGeomProperty(secondDt)->getGeometryType());
329 
330  te::gm::GeometryProperty* newGeomProp = new te::gm::GeometryProperty("geom");
331  newGeomProp->setGeometryType(newType);
332  newGeomProp->setSRID(te::da::GetFirstGeomProperty(firstDt)->getSRID());
333 
334  outputDt->add(newGeomProp);
335 
336  return outputDt;
337 }
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:213
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:347
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.
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: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
te::gm::GeomType GeomOpResultType(te::gm::GeomType firstGeom, te::gm::GeomType secondGeom)
Definition: Utils.cpp:172
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
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:127
std::string GetSimpleTableName(std::string fullName)
Definition: Utils.cpp:162