IntersectionQuery.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 IntersectionQuery.h
22 
23  \brief Intersection 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 
35 #include "../datatype/Property.h"
36 #include "../datatype/SimpleProperty.h"
37 #include "../datatype/StringProperty.h"
38 
39 #include "../dataaccess/dataset/ObjectIdSet.h"
40 #include "../dataaccess/query/And.h"
41 #include "../dataaccess/query/DataSetName.h"
42 #include "../dataaccess/query/Expression.h"
43 #include "../dataaccess/query/Field.h"
44 #include "../dataaccess/query/Fields.h"
45 #include "../dataaccess/query/From.h"
46 #include "../dataaccess/query/FromItem.h"
47 #include "../dataaccess/query/Join.h"
48 #include "../dataaccess/query/JoinConditionOn.h"
49 #include "../dataaccess/query/LiteralInt32.h"
50 #include "../dataaccess/query/PropertyName.h"
51 #include "../dataaccess/query/Select.h"
52 #include "../dataaccess/query/ST_Intersection.h"
53 #include "../dataaccess/query/ST_Intersects.h"
54 #include "../dataaccess/query/ST_SetSRID.h"
55 #include "../dataaccess/query/Where.h"
56 #include "../dataaccess/utils/Utils.h"
57 
58 #include "../geometry/Geometry.h"
59 #include "../geometry/GeometryCollection.h"
60 #include "../geometry/GeometryProperty.h"
61 #include "../geometry/Utils.h"
62 
63 #include "../memory/DataSet.h"
64 #include "../memory/DataSetItem.h"
65 
66 #include "IntersectionQuery.h"
67 #include "Config.h"
68 #include "Exception.h"
69 #include "Utils.h"
70 
71 // STL
72 #include <map>
73 #include <math.h>
74 #include <string>
75 #include <vector>
76 
78 {}
79 
81 {}
82 
83 
84 bool te::vp::IntersectionQuery::run() throw(te::common::Exception)
85 {
86  te::da::Fields* fields = new te::da::Fields;
87  te::da::Select* select = new te::da::Select;
88 
89  std::vector<te::dt::Property*> firstProps = getTabularProps(m_firstConverter->getResult());
90  std::vector<te::dt::Property*> secondProps;
91  if(m_copyInputColumns)
92  secondProps = getTabularProps(m_secondConverter->getResult());
93 
94 // Get DataSetType from DataSource to compare geometry SRID with DataSetType from Layer.
95  std::auto_ptr<te::da::DataSetType>firstDsTypeSource(m_inFirstDsrc->getDataSetType(m_inFirstDsetName));
96  std::auto_ptr<te::da::DataSetType>secondDsTypeSource(m_inSecondDsrc->getDataSetType(m_inSecondDsetName));
97 
98  te::gm::GeometryProperty* firstGeomSource = te::da::GetFirstGeomProperty(firstDsTypeSource.get());
99  te::gm::GeometryProperty* secondGeomSource = te::da::GetFirstGeomProperty(secondDsTypeSource.get());
100 
101  te::gm::GeometryProperty* firstGeom = te::da::GetFirstGeomProperty(m_firstConverter->getResult());
102  te::gm::GeometryProperty* secondGeom = te::da::GetFirstGeomProperty(m_secondConverter->getResult());
103 
104 // Get properties to set in select clause
105  for(std::size_t i = 0; i < firstProps.size(); ++i)
106  {
107  te::da::Field* f_field = new te::da::Field(m_inFirstDsetName + "." + firstProps[i]->getName() + " ", te::vp::GetSimpleTableName(m_inFirstDsetName) + "_" + firstProps[i]->getName());
108  fields->push_back(f_field);
109  }
110 
111  for(std::size_t i = 0; i < secondProps.size(); ++i)
112  {
113  te::da::Field* f_field = new te::da::Field(m_inSecondDsetName + "." + secondProps[i]->getName() + " ", te::vp::GetSimpleTableName(m_inSecondDsetName) + "_" + secondProps[i]->getName());
114  fields->push_back(f_field);
115  }
116 
117  te::da::Expression* e_firstParam;
118  te::da::Expression* e_secondParam;
119 
120 // Compare geometry SRID from DataSource with DataSetLayer
121  // Create Expression ST_setSRID for the First Layer
122  if (firstGeomSource->getSRID() != firstGeom->getSRID())
123  {
124  te::da::LiteralInt32* firstSRID = new te::da::LiteralInt32(firstGeom->getSRID());
125  e_firstParam = new te::da::ST_SetSRID(new te::da::PropertyName(m_firstConverter->getResult()->getName() + "." + firstGeom->getName()), firstSRID);
126  }
127  else
128  {
129  e_firstParam = new te::da::PropertyName(m_firstConverter->getResult()->getName() + "." + firstGeom->getName());
130  }
131 
132  // Create Expression ST_setSRID for the Second Layer
133  if (secondGeomSource->getSRID() != secondGeom->getSRID())
134  {
135  te::da::LiteralInt32* secondSRID = new te::da::LiteralInt32(secondGeom->getSRID());
136  e_secondParam = new te::da::ST_SetSRID(new te::da::PropertyName(m_secondConverter->getResult()->getName() + "." + secondGeom->getName()), secondSRID);
137  }
138  else
139  {
140  e_secondParam = new te::da::PropertyName(m_secondConverter->getResult()->getName() + "." + secondGeom->getName());
141  }
142 
143  te::da::Expression* e_intersection = new te::da::ST_Intersection( e_firstParam, e_secondParam);
144  te::da::Field* f_intersection = new te::da::Field(*e_intersection, "geom");
145  fields->push_back(f_intersection);
146 
147  te::da::FromItem* firstFromItem = new te::da::DataSetName(m_firstConverter->getResult()->getName());
148  te::da::FromItem* secondFromItem = new te::da::DataSetName(m_secondConverter->getResult()->getName());
149 
150  te::da::Expression* e_intersects = new te::da::ST_Intersects(e_firstParam, e_secondParam);
151 
152  te::da::JoinConditionOn* on = new te::da::JoinConditionOn(e_intersects);
153  te::da::Join* join = new te::da::Join(*firstFromItem, *secondFromItem, te::da::INNER_JOIN, *on);
154 
155  te::da::From* from = new te::da::From;
156  from->push_back(join);
157 
158  select->setFields(fields);
159  select->setFrom(from);
160 
161 //Where clause if the object ids were selected.
162  te::da::Where* w_oid = 0;
163  if(m_firstOidSet && m_secondOidSet)
164  {
165  te::da::And* exp_and = new te::da::And(m_firstOidSet->getExpressionByInClause(m_firstConverter->getResult()->getName()), m_secondOidSet->getExpressionByInClause(m_secondConverter->getResult()->getName()));
166  w_oid = new te::da::Where(exp_and);
167  }
168  else if(m_firstOidSet)
169  w_oid = new te::da::Where(m_firstOidSet->getExpressionByInClause(m_firstConverter->getResult()->getName()));
170  else if(m_secondOidSet)
171  w_oid = new te::da::Where(m_secondOidSet->getExpressionByInClause(m_secondConverter->getResult()->getName()));
172 
173  select->setWhere(w_oid);
174 
175  std::auto_ptr<te::da::DataSet> dsQuery = m_inFirstDsrc->query(select);
176  dsQuery->moveBeforeFirst();
177 
178  if(dsQuery->size() == 0)
179  throw te::common::Exception(TE_TR("The Layers do not intersect!"));
180 
181 
182  std::auto_ptr<te::da::DataSetType> outDataSetType(new te::da::DataSetType(m_outDsetName));
183 
184  te::dt::SimpleProperty* pkProperty = new te::dt::SimpleProperty(m_outDsetName + "_id", te::dt::INT32_TYPE);
185  pkProperty->setAutoNumber(true);
186  outDataSetType->add(pkProperty);
187 
188  te::da::PrimaryKey* pk = new te::da::PrimaryKey(m_outDsetName + "_pk", outDataSetType.get());
189  pk->add(pkProperty);
190  outDataSetType->setPrimaryKey(pk);
191 
192  for(size_t i = 0; i < firstProps.size(); ++i)
193  {
194  te::dt::Property* prop = firstProps[i]->clone();
195  if (!m_inFirstDsetName.empty())
196  prop->setName(te::vp::GetSimpleTableName(m_inFirstDsetName) + "_" + prop->getName());
197  outDataSetType->add(prop);
198  }
199 
200  for(size_t i = 0; i < secondProps.size(); ++i)
201  {
202  te::dt::Property* prop = secondProps[i]->clone();
203  if (!m_inSecondDsetName.empty())
204  prop->setName(te::vp::GetSimpleTableName(m_inSecondDsetName) + "_" + prop->getName());
205  outDataSetType->add(prop);
206  }
207 
208  te::gm::GeomType newType = setGeomResultType( te::da::GetFirstGeomProperty(m_firstConverter->getResult())->getGeometryType(),
209  te::da::GetFirstGeomProperty(m_secondConverter->getResult())->getGeometryType());
210 
211  te::gm::GeometryProperty* newGeomProp = new te::gm::GeometryProperty("geom");
212  newGeomProp->setGeometryType(newType);
213  newGeomProp->setSRID(te::da::GetFirstGeomProperty(m_firstConverter->getResult())->getSRID());
214 
215  outDataSetType->add(newGeomProp);
216 
217  std::auto_ptr<te::da::DataSet> outDset(this->updateGeomType(outDataSetType.get(), dsQuery.release()));
218 
219  outDset->moveBeforeFirst();
220 
221  te::vp::Save(m_outDsrc.get(), outDset.get(), outDataSetType.get());
222  return true;
223 
224 }
225 
227 {
228  te::mem::DataSet* dsMem = new te::mem::DataSet(dsType);
229 
230  std::size_t type = 0;
231  std::vector<te::dt::Property*> props = dsType->getProperties();
232 
233  int pk = 0;
234  while(ds->moveNext())
235  {
236  std::string propName;
237  te::mem::DataSetItem* dsItem = new te::mem::DataSetItem(dsMem);
238 
239  dsItem->setInt32(0, pk);
240 
241  for(std::size_t i = 1; i < props.size(); ++i)
242  {
243  type = props[i]->getType();
244  propName = props[i]->getName();
245 
246  if(type != te::dt::GEOMETRY_TYPE)
247  {
248  if (!ds->isNull(propName))
249  {
250  std::auto_ptr<te::dt::AbstractData> value = ds->getValue(propName);
251  dsItem->setValue(i, value.release());
252  }
253  }
254  else
255  {
256  std::auto_ptr<te::gm::Geometry> geom = ds->getGeometry(propName);
257  std::auto_ptr<te::gm::GeometryProperty> geomProp((te::gm::GeometryProperty*)props[i]->clone());
258 
259  if(geomProp->getGeometryType() == te::gm::MultiPolygonType)
260  {
261  if(geom->getGeomTypeId() == te::gm::MultiPolygonType)
262  {
263  dsItem->setGeometry(i, geom.release());
264  }
265  else if(geom->getGeomTypeId() == te::gm::PolygonType)
266  {
267  std::auto_ptr<te::gm::GeometryCollection> newGeom(new te::gm::GeometryCollection(0, te::gm::MultiPolygonType, geom->getSRID()));
268  newGeom->add(geom.release());
269  dsItem->setGeometry(i, newGeom.release());
270  }
271  }
272  else if(geomProp->getGeometryType() == te::gm::MultiLineStringType)
273  {
274  if(geom->getGeomTypeId() == te::gm::MultiLineStringType)
275  {
276  dsItem->setGeometry(i, geom.release());
277  }
278  else if(geom->getGeomTypeId() == te::gm::LineStringType)
279  {
280  std::auto_ptr<te::gm::GeometryCollection> newGeom(new te::gm::GeometryCollection(0, te::gm::MultiLineStringType, geom->getSRID()));
281  newGeom->add(geom.release());
282  dsItem->setGeometry(i, newGeom.release());
283  }
284  }
285  else if(geomProp->getGeometryType() == te::gm::MultiPointType)
286  {
287  if(geom->getGeomTypeId() == te::gm::MultiPointType)
288  {
289  dsItem->setGeometry(i, geom.release());
290  }
291  else if(geom->getGeomTypeId() == te::gm::PointType)
292  {
293  std::auto_ptr<te::gm::GeometryCollection> newGeom(new te::gm::GeometryCollection(0, te::gm::MultiPointType, geom->getSRID()));
294  newGeom->add(geom.release());
295  dsItem->setGeometry(i, newGeom.release());
296  }
297  }
298  }
299  }
300  ++pk;
301  dsMem->add(dsItem);
302  }
303  return dsMem;
304 }
void setAutoNumber(bool a)
It tells if the property is an autonumber or not.
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.
An abstract class that models a source of data in a query.
Definition: FromItem.h:50
The Field class can be used to model an expression that takes part of the output items of a SELECT...
Definition: Field.h:50
An atomic property like an integer or double.
Spatial intersects operator.
Definition: ST_Intersects.h:46
A class that models the name of a dataset used in a From clause.
Definition: DataSetName.h:43
Intersection Vector Processing functions.
A class that models the name of any property of an object.
Definition: PropertyName.h:50
A class that models the description of a dataset.
Definition: DataSetType.h:72
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.
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
Boolean logic operator: AND.
Definition: And.h:46
This is an abstract class that models a query expression.
Definition: Expression.h:47
void add(DataSetItem *item)
It adds a new item to the dataset and takes its ownership.
Definition: DataSet.cpp:172
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 setWhere(Where *w)
It sets the filter codition.
Definition: Select.cpp:947
void setName(const std::string &name)
It sets the property name.
Definition: Property.h:137
const std::vector< Property * > & getProperties() const
It returns the list of properties describing the CompositeProperty.
virtual bool isNull(std::size_t i) const =0
It checks if the attribute value is NULL.
URI C++ Library.
boost::ptr_vector< Field > Fields
Fields is just a boost::ptr_vector of Field pointers.
Definition: Fields.h:37
A class that can be used to model a filter expression that can be applied to a query.
Definition: Where.h:47
A Join clause combines two FromItems.
Definition: Join.h:50
This class is designed to declare objects to be thrown as exceptions by TerraLib. ...
Definition: Exception.h:58
A Select models a query to be used when retrieving data from a DataSource.
Definition: Select.h:65
virtual std::auto_ptr< te::gm::Geometry > getGeometry(std::size_t i) const =0
Method for retrieving a geometric attribute value.
boost::ptr_vector< FromItem > From
It models the FROM clause for a query.
Definition: From.h:37
Spatial Set SRID operator.
Definition: ST_SetSRID.h:46
An implementation of the DatasetItem class for the TerraLib In-Memory Data Access driver...
Definition: DataSetItem.h:56
A dataset is the unit of information manipulated by the data access module of TerraLib.
Definition: DataSet.h:112
Spatial intersection operator.
te::da::DataSet * updateGeomType(te::da::DataSetType *dsType, te::da::DataSet *ds)
It describes a primary key (pk) constraint.
Definition: PrimaryKey.h:52
JoinConditionOn is a boolean expression and it specifies which items in a join are considered to matc...
Configuration flags for the Terrralib Vector Processing module.
It is a collection of other geometric objects.
TEDATAACCESSEXPORT te::gm::GeometryProperty * GetFirstGeomProperty(const DataSetType *dt)
Definition: Utils.cpp:557
void setFields(Fields *f)
It sets the list of output expressions used to form the result set.
Definition: Select.cpp:927
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
void setFrom(From *f)
It sets the list of source information.
Definition: Select.cpp:937
const std::string & getName() const
It returns the property name.
Definition: Property.h:127
std::string GetSimpleTableName(std::string fullName)
Definition: Utils.cpp:162