All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
IntersectionQuery.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 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/PropertyName.h"
50 #include "../dataaccess/query/Select.h"
51 #include "../dataaccess/query/ST_Intersection.h"
52 #include "../dataaccess/query/ST_Intersects.h"
53 #include "../dataaccess/query/Where.h"
54 #include "../dataaccess/utils/Utils.h"
55 
56 #include "../geometry/Geometry.h"
57 #include "../geometry/GeometryCollection.h"
58 #include "../geometry/GeometryProperty.h"
59 #include "../geometry/Utils.h"
60 
61 #include "../memory/DataSet.h"
62 #include "../memory/DataSetItem.h"
63 
64 #include "IntersectionQuery.h"
65 #include "Config.h"
66 #include "Exception.h"
67 #include "Utils.h"
68 
69 // STL
70 #include <map>
71 #include <math.h>
72 #include <string>
73 #include <vector>
74 
76 {}
77 
79 {}
80 
81 
83 {
84  if(m_SRID == 0)
85  {
86  te::gm::GeometryProperty* geom = te::da::GetFirstGeomProperty(m_inFirstDsetType.get());
87  m_SRID = geom->getSRID();
88  }
89 
90  te::da::Fields* fields = new te::da::Fields;
91  te::da::Select* select = new te::da::Select;
92 
93  std::vector<te::dt::Property*> firstProps = getTabularProps(m_inFirstDsetType.get());
94  std::vector<te::dt::Property*> secondProps;
95  if(m_copyInputColumns)
96  secondProps = getTabularProps(m_inSecondDsetType.get());
97 
98  te::gm::GeometryProperty* firstGeom;
99  te::gm::GeometryProperty* secondGeom;
100 
101  firstGeom = te::da::GetFirstGeomProperty(m_inFirstDsetType.get());
102  secondGeom = te::da::GetFirstGeomProperty(m_inSecondDsetType.get());
103 
104  std::string firstTableName = te::vp::GetSimpleTableName(m_inFirstDsetType->getTitle());
105  std::string secondTableName = te::vp::GetSimpleTableName(m_inSecondDsetType->getTitle());
106 
107  for(std::size_t i = 0; i < firstProps.size(); ++i)
108  {
109  te::da::Field* f_field = new te::da::Field(firstTableName + "." + firstProps[i]->getName() + " ", firstTableName + "_" + firstProps[i]->getName());
110  fields->push_back(f_field);
111  }
112 
113  for(std::size_t i = 0; i < secondProps.size(); ++i)
114  {
115  te::da::Field* f_field = new te::da::Field(secondTableName + "." + secondProps[i]->getName() + " ", secondTableName + "_" + secondProps[i]->getName());
116  fields->push_back(f_field);
117  }
118 
119  te::da::Expression* e_intersection = new te::da::ST_Intersection( new te::da::PropertyName(m_inFirstDsetType->getName() + "." + firstGeom->getName()),
120  new te::da::PropertyName(m_inSecondDsetType->getName() + "." + secondGeom->getName()));
121  te::da::Field* f_intersection = new te::da::Field(*e_intersection, "geom");
122  fields->push_back(f_intersection);
123 
124  te::da::FromItem* firstFromItem = new te::da::DataSetName(m_inFirstDsetType->getName());
125  te::da::FromItem* secondFromItem = new te::da::DataSetName(m_inSecondDsetType->getName());
126  te::da::Expression* e_intersects = new te::da::ST_Intersects( new te::da::PropertyName(m_inFirstDsetType->getName() + "." + firstGeom->getName()),
127  new te::da::PropertyName(m_inSecondDsetType->getName() + "." + secondGeom->getName()));
128  te::da::JoinConditionOn* on = new te::da::JoinConditionOn(e_intersects);
129  te::da::Join* join = new te::da::Join(*firstFromItem, *secondFromItem, te::da::INNER_JOIN, *on);
130 
131  te::da::From* from = new te::da::From;
132  from->push_back(join);
133 
134  select->setFields(fields);
135  select->setFrom(from);
136 
137 //Where clause if the object ids were selected.
138  te::da::Where* w_oid = 0;
139  if(m_firstOidSet && m_secondOidSet)
140  {
141  te::da::And* exp_and = new te::da::And(m_firstOidSet->getExpression(m_inFirstDsetType->getName()), m_secondOidSet->getExpression(m_inSecondDsetType->getName()));
142  w_oid = new te::da::Where(exp_and);
143  }
144  else if(m_firstOidSet)
145  w_oid = new te::da::Where(m_firstOidSet->getExpression(m_inFirstDsetType->getName()));
146  else if(m_secondOidSet)
147  w_oid = new te::da::Where(m_secondOidSet->getExpression(m_inSecondDsetType->getName()));
148 
149  select->setWhere(w_oid);
150 
151  std::auto_ptr<te::da::DataSet> dsQuery = m_inFirstDsrc->query(select);
152  dsQuery->moveBeforeFirst();
153 
154  if(dsQuery->size() == 0)
155  throw te::common::Exception(TE_TR("The Layers do not intersect!"));
156 
157 
158  std::auto_ptr<te::da::DataSetType> outDataSetType(new te::da::DataSetType(m_outDsetName));
159 
160  te::dt::SimpleProperty* pkProperty = new te::dt::SimpleProperty(m_outDsetName + "_id", te::dt::INT32_TYPE);
161  pkProperty->setAutoNumber(true);
162  outDataSetType->add(pkProperty);
163 
164  te::da::PrimaryKey* pk = new te::da::PrimaryKey(m_outDsetName + "_pk", outDataSetType.get());
165  pk->add(pkProperty);
166  outDataSetType->setPrimaryKey(pk);
167 
168  for(size_t i = 0; i < firstProps.size(); ++i)
169  {
170  te::dt::Property* prop = firstProps[i]->clone();
171  if(!m_inFirstDsetType->getTitle().empty())
172  prop->setName(te::vp::GetSimpleTableName(m_inFirstDsetType->getTitle()) + "_" + prop->getName());
173  outDataSetType->add(prop);
174  }
175 
176  for(size_t i = 0; i < secondProps.size(); ++i)
177  {
178  te::dt::Property* prop = secondProps[i]->clone();
179  prop->setName(te::vp::GetSimpleTableName(m_inSecondDsetType->getTitle()) + "_" + prop->getName());
180  outDataSetType->add(prop);
181  }
182 
183  te::gm::GeomType newType = te::vp::GeomOpResultType(te::da::GetFirstGeomProperty(m_inFirstDsetType.get())->getGeometryType(),
184  te::da::GetFirstGeomProperty(m_inSecondDsetType.get())->getGeometryType());
185 
186  te::gm::GeometryProperty* newGeomProp = new te::gm::GeometryProperty("geom");
187  newGeomProp->setGeometryType(newType);
188  newGeomProp->setSRID(te::da::GetFirstGeomProperty(m_inFirstDsetType.get())->getSRID());
189 
190  outDataSetType->add(newGeomProp);
191 
192  std::auto_ptr<te::da::DataSet> outDset(this->updateGeomType(outDataSetType.get(), dsQuery.release()));
193 
194  outDset->moveBeforeFirst();
195 
196  return save(outDset, outDataSetType);
197 }
198 
200 {
201  te::mem::DataSet* dsMem = new te::mem::DataSet(dsType);
202 
203  std::size_t type = 0;
204  std::vector<te::dt::Property*> props = dsType->getProperties();
205 
206  std::size_t pk = 0;
207  while(ds->moveNext())
208  {
209  std::string propName;
210  te::mem::DataSetItem* dsItem = new te::mem::DataSetItem(dsMem);
211 
212  dsItem->setInt32(0, pk);
213 
214  for(std::size_t i = 1; i < props.size(); ++i)
215  {
216  type = props[i]->getType();
217  propName = props[i]->getName();
218 
219  if(type != te::dt::GEOMETRY_TYPE)
220  {
221  if (!ds->isNull(propName))
222  {
223  std::auto_ptr<te::dt::AbstractData> value = ds->getValue(propName);
224  dsItem->setValue(i, value.release());
225  }
226  }
227  else
228  {
229  std::auto_ptr<te::gm::Geometry> geom = ds->getGeometry(propName);
230  std::auto_ptr<te::gm::GeometryProperty> geomProp((te::gm::GeometryProperty*)props[i]->clone());
231 
232  if(geomProp->getGeometryType() == te::gm::MultiPolygonType)
233  {
234  if(geom->getGeomTypeId() == te::gm::MultiPolygonType)
235  {
236  dsItem->setGeometry(i, geom.release());
237  }
238  else if(geom->getGeomTypeId() == te::gm::PolygonType)
239  {
240  std::auto_ptr<te::gm::GeometryCollection> newGeom(new te::gm::GeometryCollection(0, te::gm::MultiPolygonType, geom->getSRID()));
241  newGeom->add(geom.release());
242  dsItem->setGeometry(i, newGeom.release());
243  }
244  }
245  else if(geomProp->getGeometryType() == te::gm::MultiLineStringType)
246  {
247  if(geom->getGeomTypeId() == te::gm::MultiLineStringType)
248  {
249  dsItem->setGeometry(i, geom.release());
250  }
251  else if(geom->getGeomTypeId() == te::gm::LineStringType)
252  {
253  std::auto_ptr<te::gm::GeometryCollection> newGeom(new te::gm::GeometryCollection(0, te::gm::MultiLineStringType, geom->getSRID()));
254  newGeom->add(geom.release());
255  dsItem->setGeometry(i, newGeom.release());
256  }
257  }
258  else if(geomProp->getGeometryType() == te::gm::MultiPointType)
259  {
260  if(geom->getGeomTypeId() == te::gm::MultiPointType)
261  {
262  dsItem->setGeometry(i, geom.release());
263  }
264  else if(geom->getGeomTypeId() == te::gm::PointType)
265  {
266  std::auto_ptr<te::gm::GeometryCollection> newGeom(new te::gm::GeometryCollection(0, te::gm::MultiPointType, geom->getSRID()));
267  newGeom->add(geom.release());
268  dsItem->setGeometry(i, newGeom.release());
269  }
270  }
271  }
272  }
273  ++pk;
274  dsMem->add(dsItem);
275  }
276  return dsMem;
277 }
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
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:345
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:168
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:136
const std::vector< Property * > & getProperties() const
It returns the list of properties describing the CompositeProperty.
int getSRID() const
It returns the spatial reference system identifier associated to this property.
virtual bool isNull(std::size_t i) const =0
It checks if the attribute value is NULL.
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
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
te::gm::GeomType GeomOpResultType(te::gm::GeomType firstGeom, te::gm::GeomType secondGeom)
Definition: Utils.cpp:167
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:508
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:126
std::string GetSimpleTableName(std::string fullName)
Definition: Utils.cpp:157