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 "../core/logger/Logger.h"
30 #include "../core/translator/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_Transform.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 <cmath>
74 #include <string>
75 #include <vector>
76 
78 
80 
82 {
83  te::da::Fields* fields = new te::da::Fields;
84  te::da::Select* select = new te::da::Select;
85 
86  std::vector<te::dt::Property*> firstProps = getTabularProps(m_firstConverter->getResult());
87  std::vector<te::dt::Property*> secondProps = getTabularProps(m_secondConverter->getResult());
88 
89 // Get DataSetType from DataSource to compare geometry SRID with DataSetType from Layer.
90  std::unique_ptr<te::da::DataSetType>firstDsTypeSource(m_inFirstDsrc->getDataSetType(m_inFirstDsetName));
91  std::unique_ptr<te::da::DataSetType>secondDsTypeSource(m_inSecondDsrc->getDataSetType(m_inSecondDsetName));
92 
93  te::gm::GeometryProperty* firstGeomSource = te::da::GetFirstGeomProperty(firstDsTypeSource.get());
94  te::gm::GeometryProperty* secondGeomSource = te::da::GetFirstGeomProperty(secondDsTypeSource.get());
95 
98 
99 // Get properties to set in select clause
100  for(std::size_t i = 0; i < firstProps.size(); ++i)
101  {
102  te::da::Field* f_field = new te::da::Field(m_inFirstDsetName + "." + firstProps[i]->getName() + " ", "A_" + firstProps[i]->getName());
103  fields->push_back(f_field);
104  }
105 
106  for(std::size_t i = 0; i < secondProps.size(); ++i)
107  {
108  te::da::Field* f_field = new te::da::Field(m_inSecondDsetName + "." + secondProps[i]->getName() + " ", "B_" + secondProps[i]->getName());
109  fields->push_back(f_field);
110  }
111 
112  te::da::Expression* e_firstParam;
113  te::da::Expression* e_secondParam;
114 
115 // Compare geometry SRID from DataSource with DataSetLayer
116  // Create Expression ST_setSRID for the First Layer
117  if (firstGeomSource->getSRID() != firstGeom->getSRID())
118  {
119  //te::da::LiteralInt32* firstSRID = new te::da::LiteralInt32(firstGeom->getSRID());
120  e_firstParam = new te::da::ST_Transform(new te::da::PropertyName(m_firstConverter->getResult()->getName() + "." + firstGeom->getName()), firstGeom->getSRID());
121  }
122  else
123  {
124  e_firstParam = new te::da::PropertyName(m_firstConverter->getResult()->getName() + "." + firstGeom->getName());
125  }
126 
127  // Create Expression ST_setSRID for the Second Layer
128  if (secondGeomSource->getSRID() != secondGeom->getSRID())
129  {
130  //te::da::LiteralInt32* secondSRID = new te::da::LiteralInt32(secondGeom->getSRID());
131  e_secondParam = new te::da::ST_Transform(new te::da::PropertyName(m_secondConverter->getResult()->getName() + "." + secondGeom->getName()), secondGeom->getSRID());
132  }
133  else
134  {
135  e_secondParam = new te::da::PropertyName(m_secondConverter->getResult()->getName() + "." + secondGeom->getName());
136  }
137 
138  te::da::Expression* e_intersection = new te::da::ST_Intersection( e_firstParam, e_secondParam);
139  te::da::Field* f_intersection = new te::da::Field(*e_intersection, "geom");
140  fields->push_back(f_intersection);
141 
142  te::da::FromItem* firstFromItem = new te::da::DataSetName(m_firstConverter->getResult()->getName());
143  te::da::FromItem* secondFromItem = new te::da::DataSetName(m_secondConverter->getResult()->getName());
144 
145  te::da::Expression* e_intersects = new te::da::ST_Intersects(e_firstParam, e_secondParam);
146 
147  te::da::JoinConditionOn* on = new te::da::JoinConditionOn(e_intersects);
148  te::da::Join* join = new te::da::Join(*firstFromItem, *secondFromItem, te::da::INNER_JOIN, *on);
149 
150  te::da::From* from = new te::da::From;
151  from->push_back(join);
152 
153  select->setFields(fields);
154  select->setFrom(from);
155 
156 //Where clause if the object ids were selected.
157  te::da::Where* w_oid = nullptr;
159  {
160  te::da::And* exp_and = new te::da::And(
161  m_firstOidSet->getExpressionByInClause(m_firstConverter->getResult()->getName()),
162  m_secondOidSet->getExpressionByInClause(m_secondConverter->getResult()->getName()));
163 
164  w_oid = new te::da::Where(exp_and);
165  }
166  else if(m_firstOidSet)
167  w_oid = new te::da::Where(m_firstOidSet->getExpressionByInClause(m_firstConverter->getResult()->getName()));
168  else if(m_secondOidSet)
169  w_oid = new te::da::Where(m_secondOidSet->getExpressionByInClause(m_secondConverter->getResult()->getName()));
170 
171  select->setWhere(w_oid);
172 
173  std::unique_ptr<te::da::DataSet> dsQuery = m_inFirstDsrc->query(select);
174  dsQuery->moveBeforeFirst();
175 
176  if(dsQuery->size() == 0)
177  throw te::common::Exception(TE_TR("The Layers do not intersect!"));
178 
179 
180  std::unique_ptr<te::da::DataSetType> outDataSetType(getOutputDsType());
181 
182  std::unique_ptr<te::da::DataSet> outDset(this->updateGeomType(outDataSetType.get(), dsQuery.release()));
183 
184  outDset->moveBeforeFirst();
185 
186  te::vp::Save(m_outDsrc.get(), outDset.get(), outDataSetType.get());
187  return true;
188 
189 }
190 
192 {
193  te::mem::DataSet* dsMem = new te::mem::DataSet(dsType);
194 
195  std::size_t type = 0;
196  std::vector<te::dt::Property*> props = dsType->getProperties();
197 
198  int pk = 0;
199  while(ds->moveNext())
200  {
201  std::string propName;
202  te::mem::DataSetItem* dsItem = new te::mem::DataSetItem(dsMem);
203 
204  dsItem->setInt32(0, pk);
205 
206  for(std::size_t i = 1; i < props.size(); ++i)
207  {
208  type = props[i]->getType();
209  propName = props[i]->getName();
210 
211  if(type != te::dt::GEOMETRY_TYPE)
212  {
213  if (!ds->isNull(propName))
214  {
215  std::unique_ptr<te::dt::AbstractData> value = ds->getValue(propName);
216  dsItem->setValue(i, value.release());
217  }
218  }
219  else
220  {
221  std::unique_ptr<te::gm::Geometry> geom = ds->getGeometry(propName);
222  std::unique_ptr<te::gm::GeometryProperty> geomProp((te::gm::GeometryProperty*)props[i]->clone());
223 
224  if(geomProp->getGeometryType() == te::gm::MultiPolygonType)
225  {
226  if(geom->getGeomTypeId() == te::gm::MultiPolygonType)
227  {
228  dsItem->setGeometry(i, geom.release());
229  }
230  else if(geom->getGeomTypeId() == te::gm::PolygonType)
231  {
232  std::unique_ptr<te::gm::GeometryCollection> newGeom(new te::gm::GeometryCollection(0, te::gm::MultiPolygonType, geom->getSRID()));
233  newGeom->add(geom.release());
234  dsItem->setGeometry(i, newGeom.release());
235  }
236  }
237  else if(geomProp->getGeometryType() == te::gm::MultiLineStringType)
238  {
239  if(geom->getGeomTypeId() == te::gm::MultiLineStringType)
240  {
241  dsItem->setGeometry(i, geom.release());
242  }
243  else if(geom->getGeomTypeId() == te::gm::LineStringType)
244  {
245  std::unique_ptr<te::gm::GeometryCollection> newGeom(new te::gm::GeometryCollection(0, te::gm::MultiLineStringType, geom->getSRID()));
246  newGeom->add(geom.release());
247  dsItem->setGeometry(i, newGeom.release());
248  }
249  }
250  else if(geomProp->getGeometryType() == te::gm::MultiPointType)
251  {
252  if(geom->getGeomTypeId() == te::gm::MultiPointType)
253  {
254  dsItem->setGeometry(i, geom.release());
255  }
256  else if(geom->getGeomTypeId() == te::gm::PointType)
257  {
258  std::unique_ptr<te::gm::GeometryCollection> newGeom(new te::gm::GeometryCollection(0, te::gm::MultiPointType, geom->getSRID()));
259  newGeom->add(geom.release());
260  dsItem->setGeometry(i, newGeom.release());
261  }
262  }
263  }
264  }
265  ++pk;
266  dsMem->add(dsItem);
267  }
268  return dsMem;
269 }
An exception class for the Vector processing module.
virtual std::unique_ptr< te::gm::Geometry > getGeometry(std::size_t i) const =0
Method for retrieving a geometric attribute value.
std::vector< te::dt::Property * > getTabularProps(te::da::DataSetType *dsType)
std::string m_inSecondDsetName
Geometric property.
te::da::DataSetType * getOutputDsType()
void setGeometry(std::size_t i, te::gm::Geometry *value)
It sets the value of the i-th property.
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...
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.
const te::da::ObjectIdSet * m_firstOidSet
A class that models the name of any property of an object.
Base exception class for plugin module.
A class that models the description of a dataset.
Definition: DataSetType.h:72
void setValue(std::size_t i, te::dt::AbstractData *value)
It sets the value of the i-th property.
static te::dt::Date ds(2010, 01, 01)
#define TE_TR(message)
It marks a string in order to get translated.
Definition: Translator.h:242
te::da::DataSourcePtr m_inSecondDsrc
Boolean logic operator: AND.
This is an abstract class that models a query expression.
void add(DataSetItem *item)
It adds a new item to the dataset and takes its ownership.
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.
TEVPEXPORT void Save(te::da::DataSource *source, te::da::DataSet *result, te::da::DataSetType *outDsType, const bool &enableProgress=true)
Implementation of a random-access dataset class for the TerraLib In-Memory Data Access driver...
void setWhere(Where *w)
It sets the filter codition.
Definition: Select.cpp:799
const std::vector< Property * > & getProperties() const
It returns the list of properties describing the CompositeProperty.
URI C++ Library.
Definition: Attributes.h:37
void DataSet()
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
std::unique_ptr< te::da::DataSetTypeConverter > m_firstConverter
A Join clause combines two FromItems.
Definition: Join.h:50
Utility functions for the data access module.
te::da::DataSourcePtr m_outDsrc
This class is designed to declare objects to be thrown as exceptions by TerraLib. ...
std::string m_inFirstDsetName
A Select models a query to be used when retrieving data from a DataSource.
Definition: Select.h:65
te::da::DataSourcePtr m_inFirstDsrc
boost::ptr_vector< FromItem > From
It models the FROM clause for a query.
Definition: From.h:37
std::unique_ptr< te::da::DataSetTypeConverter > m_secondConverter
An implementation of the DatasetItem class for the TerraLib In-Memory Data Access driver...
A dataset is the unit of information manipulated by the data access module of TerraLib.
virtual std::unique_ptr< te::dt::AbstractData > getValue(std::size_t i) const
Method for retrieving any other type of data value stored in the data source.
Spatial intersection operator.
te::da::DataSet * updateGeomType(te::da::DataSetType *dsType, te::da::DataSet *ds)
Configuration flags for the Terrralib Vector Processing module.
Expression * getExpressionByInClause(const std::string source="") const
virtual bool isNull(std::size_t i) const =0
It checks if the attribute value is NULL.
JoinConditionOn is a boolean expression and it specifies which items in a join are considered to matc...
It is a collection of other geometric objects.
TEDATAACCESSEXPORT te::gm::GeometryProperty * GetFirstGeomProperty(const DataSetType *dt)
void setFields(Fields *f)
It sets the list of output expressions used to form the result set.
Definition: Select.cpp:779
void setFrom(From *f)
It sets the list of source information.
Definition: Select.cpp:789
const te::da::ObjectIdSet * m_secondOidSet