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 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 
82 bool te::vp::IntersectionQuery::run() throw(te::common::Exception)
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->getExpressionByInClause(m_inFirstDsetType->getName()), m_secondOidSet->getExpressionByInClause(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->getExpressionByInClause(m_inFirstDsetType->getName()));
146  else if(m_secondOidSet)
147  w_oid = new te::da::Where(m_secondOidSet->getExpressionByInClause(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  te::vp::Save(m_outDsrc.get(), outDset.get(), outDataSetType.get());
197  return true;
198 
199 }
200 
202 {
203  te::mem::DataSet* dsMem = new te::mem::DataSet(dsType);
204 
205  std::size_t type = 0;
206  std::vector<te::dt::Property*> props = dsType->getProperties();
207 
208  std::size_t pk = 0;
209  while(ds->moveNext())
210  {
211  std::string propName;
212  te::mem::DataSetItem* dsItem = new te::mem::DataSetItem(dsMem);
213 
214  dsItem->setInt32(0, pk);
215 
216  for(std::size_t i = 1; i < props.size(); ++i)
217  {
218  type = props[i]->getType();
219  propName = props[i]->getName();
220 
221  if(type != te::dt::GEOMETRY_TYPE)
222  {
223  if (!ds->isNull(propName))
224  {
225  std::auto_ptr<te::dt::AbstractData> value = ds->getValue(propName);
226  dsItem->setValue(i, value.release());
227  }
228  }
229  else
230  {
231  std::auto_ptr<te::gm::Geometry> geom = ds->getGeometry(propName);
232  std::auto_ptr<te::gm::GeometryProperty> geomProp((te::gm::GeometryProperty*)props[i]->clone());
233 
234  if(geomProp->getGeometryType() == te::gm::MultiPolygonType)
235  {
236  if(geom->getGeomTypeId() == te::gm::MultiPolygonType)
237  {
238  dsItem->setGeometry(i, geom.release());
239  }
240  else if(geom->getGeomTypeId() == te::gm::PolygonType)
241  {
242  std::auto_ptr<te::gm::GeometryCollection> newGeom(new te::gm::GeometryCollection(0, te::gm::MultiPolygonType, geom->getSRID()));
243  newGeom->add(geom.release());
244  dsItem->setGeometry(i, newGeom.release());
245  }
246  }
247  else if(geomProp->getGeometryType() == te::gm::MultiLineStringType)
248  {
249  if(geom->getGeomTypeId() == te::gm::MultiLineStringType)
250  {
251  dsItem->setGeometry(i, geom.release());
252  }
253  else if(geom->getGeomTypeId() == te::gm::LineStringType)
254  {
255  std::auto_ptr<te::gm::GeometryCollection> newGeom(new te::gm::GeometryCollection(0, te::gm::MultiLineStringType, geom->getSRID()));
256  newGeom->add(geom.release());
257  dsItem->setGeometry(i, newGeom.release());
258  }
259  }
260  else if(geomProp->getGeometryType() == te::gm::MultiPointType)
261  {
262  if(geom->getGeomTypeId() == te::gm::MultiPointType)
263  {
264  dsItem->setGeometry(i, geom.release());
265  }
266  else if(geom->getGeomTypeId() == te::gm::PointType)
267  {
268  std::auto_ptr<te::gm::GeometryCollection> newGeom(new te::gm::GeometryCollection(0, te::gm::MultiPointType, geom->getSRID()));
269  newGeom->add(geom.release());
270  dsItem->setGeometry(i, newGeom.release());
271  }
272  }
273  }
274  }
275  ++pk;
276  dsMem->add(dsItem);
277  }
278  return dsMem;
279 }
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:213
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:347
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.
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:172
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