LineToPolygonQuery.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 LineToPolygonQuery.h
22 
23  \brief Line To Polygon Vector Processing functions.
24 */
25 
26 //Terralib
27 #include "../dataaccess/dataset/DataSet.h"
28 
29 #include "../datatype/Property.h"
30 
31 #include "../dataaccess/query/And.h"
32 #include "../dataaccess/query/DataSetName.h"
33 #include "../dataaccess/query/EqualTo.h"
34 #include "../dataaccess/query/Expression.h"
35 #include "../dataaccess/query/Field.h"
36 #include "../dataaccess/query/Fields.h"
37 #include "../dataaccess/query/From.h"
38 #include "../dataaccess/query/FromItem.h"
39 #include "../dataaccess/query/GreaterThan.h"
40 #include "../dataaccess/query/GroupBy.h"
41 #include "../dataaccess/query/GroupByItem.h"
42 #include "../dataaccess/query/LiteralBool.h"
43 #include "../dataaccess/query/LiteralInt32.h"
44 #include "../dataaccess/query/PropertyName.h"
45 #include "../dataaccess/query/Select.h"
46 #include "../dataaccess/query/ST_AddPoint.h"
47 #include "../dataaccess/query/ST_Collect.h"
48 #include "../dataaccess/query/ST_Dump.h"
49 #include "../dataaccess/query/ST_IsClosed.h"
50 #include "../dataaccess/query/ST_MakePolygon.h"
51 #include "../dataaccess/query/ST_NPoints.h"
52 #include "../dataaccess/query/ST_SetSRID.h"
53 #include "../dataaccess/query/ST_StartPoint.h"
54 #include "../dataaccess/query/SubSelect.h"
55 #include "../dataaccess/query/Where.h"
56 #include "../dataaccess/utils/Utils.h"
57 
58 #include "../geometry/GeometryProperty.h"
59 
60 #include "LineToPolygonQuery.h"
61 #include "Utils.h"
62 
63 // STL
64 #include <memory>
65 #include <vector>
66 
68 
70 
72 {
73 // Build output dataSetType.
74  std::unique_ptr<te::da::DataSetType> outDsType = buildOutDataSetType();
75 
76 // Make a query to build Polygons.
77  te::da::Select select = getSelectQueryClosedLines(outDsType.get());
78 
79 // Execute query to return a dataSet.
80  std::unique_ptr<te::da::DataSet> dsQuery = m_inDsrc->query(select);
81 
82 // Save result.
83  te::vp::Save(m_outDsrc.get(), dsQuery.get(), outDsType.get());
84 
85  if(m_forceClose)
86  {
87 // Make a query to build not closed lines.
88  select = getSelectQueryForceCloseLines(outDsType.get());
89 
90 // Execute query to return a dataSet.
91  dsQuery = m_inDsrc->query(select);
92 
93 // Save result.
94  te::vp::Save(m_outDsrc.get(), dsQuery.get(), outDsType.get());
95  }
96 
97  return true;
98 }
99 
101 {
102 /************************************************
103  * Get a vector of properties from dataSetType. *
104  ************************************************/
105  std::vector<te::dt::Property*> props = dataSetType->getProperties();
106 
107 
108 
109 /***************************************************************************************
110  * Get DataSetType from DataSource to compare geometry SRID with DataSetType of Layer. *
111  ***************************************************************************************/
112  std::unique_ptr<te::da::DataSetType> sourceDSetType = m_inDsrc->getDataSetType(m_inDsetName);
113  te::gm::GeometryProperty* geomPropSource = te::da::GetFirstGeomProperty(sourceDSetType.get());
114 
116 
117 
118 
119 /******************************************************************************************
120  * Subselect that apply the ST_Dump function in geometric column to separate multi lines. *
121  ******************************************************************************************/
122  te::da::Fields* tabFields = new te::da::Fields;
123  te::da::Fields* makePolygonFields = new te::da::Fields;
124  te::da::Fields* collectFields = new te::da::Fields;
125 
126 
127  for(std::size_t i = 0; i < props.size(); ++i)
128  {
129  if(props[i]->getType() != te::dt::GEOMETRY_TYPE)
130  {
131  te::da::PropertyName* pName = new te::da::PropertyName(props[i]->getName());
132  te::da::Field* field = new te::da::Field(pName);
133  tabFields->push_back(field);
134  }
135  else
136  {
137  te::da::Expression* e_geometry;
138 
139  if (geomPropSource->getSRID() != geomProp->getSRID())
140  {
141  te::da::LiteralInt32* srid = new te::da::LiteralInt32(geomProp->getSRID());
142  e_geometry = new te::da::ST_SetSRID(new te::da::PropertyName(props[i]->getName()), srid);
143  }
144  else
145  {
146  e_geometry = new te::da::PropertyName(props[i]->getName());
147  }
148 
149  makePolygonFields = tabFields->clone().release();
150 
151  te::da::Expression* e_dump = new te::da::ST_Dump(e_geometry);
152  te::da::Expression* e_makePolygon = new te::da::ST_MakePolygon(e_dump);
153  te::da::Field* f_makePolygon = new te::da::Field(*e_makePolygon, " polygon");
154 
155  makePolygonFields->push_back(f_makePolygon);
156  }
157  }
158 
160  te::da::From* fromPol = new te::da::From;
161  fromPol->push_back(fromItemPol);
162 
163  te::da::Expression* e_isClosed = new te::da::ST_IsClosed(te::da::PropertyName(geomProp->getName()));
164 
165  te::da::Where* w = nullptr;
166 
167  if(m_oidSet)
168  {
169  te::da::Expression* e_and = new te::da::And(e_isClosed, m_oidSet->getExpression());
170  w = new te::da::Where(e_and);
171  }
172  else
173  {
174  w = new te::da::Where(e_isClosed);
175  }
176 
177 
178  te::da::Select select_Pol(makePolygonFields, fromPol, w);
179  te::da::SubSelect subSelect_Pol(select_Pol, "pol");
180 
181 
182 
183 /******************************************
184  * SubSelect to create polygons by lines. *
185  ******************************************/
186  collectFields = tabFields->clone().release();
187 
188  te::da::PropertyName* gName = new te::da::PropertyName("polygon");
189  te::da::Expression* e_collect = new te::da::ST_Collect(gName);
190  te::da::Field* f_collect = new te::da::Field(*e_collect, geomProp->getName());
191 
192  collectFields->push_back(f_collect);
193 
194  te::da::FromItem* fromItem = new te::da::SubSelect(subSelect_Pol);
195  te::da::From* from = new te::da::From;
196  from->push_back(fromItem);
197 
198  te::da::GroupBy* groupBy = new te::da::GroupBy();
199 
200  te::da::Fields::iterator f_it;
201 
202  for(f_it = tabFields->begin(); f_it < tabFields->end(); ++f_it)
203  {
204  te::da::GroupByItem* e_groupBy = new te::da::GroupByItem(f_it->getExpression());
205  groupBy->push_back(e_groupBy);
206  }
207 
208  te::da::Select select(collectFields, from, groupBy);
209 
210  return select;
211 }
212 
214 {
215 /************************************************
216  * Get a vector of properties from dataSetType. *
217  ************************************************/
218  std::vector<te::dt::Property*> props = dataSetType->getProperties();
219 
220 
221 
222 /***************************************************************************************
223  * Get DataSetType from DataSource to compare geometry SRID with DataSetType of Layer. *
224  ***************************************************************************************/
225  std::unique_ptr<te::da::DataSetType> sourceDSetType = m_inDsrc->getDataSetType(m_inDsetName);
226  te::gm::GeometryProperty* geomPropSource = te::da::GetFirstGeomProperty(sourceDSetType.get());
227 
229 
230 
231 
232 /******************************************************************************************
233  * Subselect that apply the ST_Dump function in geometric column to separate multi lines. *
234  ******************************************************************************************/
235  te::da::Fields* tabFields = new te::da::Fields;
236  te::da::Fields* dumpFields = new te::da::Fields;
237  te::da::Fields* makePolygonFields = new te::da::Fields;
238  te::da::Fields* collectFields = new te::da::Fields;
239 
240  for(std::size_t i = 0; i < props.size(); ++i)
241  {
242  if(props[i]->getType() != te::dt::GEOMETRY_TYPE)
243  {
244  te::da::PropertyName* pName = new te::da::PropertyName(props[i]->getName());
245  te::da::Field* field = new te::da::Field(pName);
246  tabFields->push_back(field);
247  }
248  else
249  {
250  te::da::Expression* e_geometry;
251 
252  if (geomPropSource->getSRID() != geomProp->getSRID())
253  {
254  te::da::LiteralInt32* srid = new te::da::LiteralInt32(geomProp->getSRID());
255  e_geometry = new te::da::ST_SetSRID(new te::da::PropertyName(props[i]->getName()), srid);
256  }
257  else
258  {
259  e_geometry = new te::da::PropertyName(props[i]->getName());
260  }
261 
262  dumpFields = tabFields->clone().release();
263 
264  te::da::Expression* e_dump = new te::da::ST_Dump(e_geometry);
265  te::da::Field* f_dump = new te::da::Field(*e_dump, "dumpedGeom");
266  dumpFields->push_back(f_dump);
267  }
268  }
269 
270  te::da::FromItem* fromItemDumped = new te::da::DataSetName(m_inDsetName);
271  te::da::From* fromDumped = new te::da::From;
272  fromDumped->push_back(fromItemDumped);
273 
274  te::da::Select dumpSelect(dumpFields, fromDumped);
275  te::da::SubSelect dumpSubSelect(dumpSelect, "t1");
276 
277 
278 
279 /******************************************
280  * SubSelect to create polygons by lines. *
281  ******************************************/
282  makePolygonFields = tabFields->clone().release();
283 
284  te::da::Expression* e_startPoint = new te::da::ST_StartPoint(te::da::PropertyName("t1.dumpedGeom"));
285 
286  te::da::Expression* e_addPoint = new te::da::ST_AddPoint(te::da::PropertyName("t1.dumpedGeom"), *e_startPoint);
287 
288  te::da::Expression* e_makePolygon = new te::da::ST_MakePolygon(e_addPoint);
289 
290  te::da::Field* f_makePolygon = new te::da::Field(*e_makePolygon, "polygon");
291  makePolygonFields->push_back(f_makePolygon);
292 
293  te::da::FromItem* fromItemMakePol = new te::da::SubSelect(dumpSubSelect);
294  te::da::From* fromMakePol = new te::da::From;
295  fromMakePol->push_back(fromItemMakePol);
296 
297  te::da::Expression* e_nPoints = new te::da::ST_NPoints(te::da::PropertyName("t1.dumpedGeom"));
298  te::da::Expression* e_literalInt = new te::da::LiteralInt32(2);
299  te::da::Expression* e_greaterThan = new te::da::GreaterThan(e_nPoints, e_literalInt);
300 
301  te::da::Expression* e_isClosed = new te::da::ST_IsClosed(te::da::PropertyName("t1.dumpedGeom"));
302  te::da::Expression* e_false = new te::da::LiteralBool(false);
303  te::da::Expression* e_equal = new te::da::EqualTo(e_isClosed, e_false);
304 
305  te::da::Expression* e_and = new te::da::And(e_greaterThan, e_equal);
306 
307  te::da::Where* w = nullptr;
308 
309  if(m_oidSet)
310  {
311  te::da::Expression* e_andOid = new te::da::And(e_and, m_oidSet->getExpression());
312  w = new te::da::Where(e_andOid);
313  }
314  else
315  {
316  w = new te::da::Where(e_and);
317  }
318 
319  te::da::Select selectMakePol(makePolygonFields, fromMakePol, w);
320  te::da::SubSelect subSelectMakePol(selectMakePol, "pol");
321 
322 
323 
324 /********************************************************
325  * Select that apply Collect of all generated Polygons. *
326  ********************************************************/
327  collectFields = tabFields->clone().release();
328 
329  te::da::PropertyName* gName = new te::da::PropertyName("polygon");
330  te::da::Expression* e_collect = new te::da::ST_Collect(gName);
331  te::da::Field* f_collect = new te::da::Field(*e_collect, geomProp->getName());
332 
333  collectFields->push_back(f_collect);
334 
335  te::da::FromItem* fromItem = new te::da::SubSelect(subSelectMakePol);
336  te::da::From* from = new te::da::From;
337  from->push_back(fromItem);
338 
339  te::da::GroupBy* groupBy = new te::da::GroupBy();
340 
341  te::da::Fields::iterator f_it;
342 
343  for(f_it = tabFields->begin(); f_it < tabFields->end(); ++f_it)
344  {
345  te::da::GroupByItem* e_groupBy = new te::da::GroupByItem(f_it->getExpression());
346  groupBy->push_back(e_groupBy);
347  }
348 
349  te::da::Select select(collectFields, from, groupBy);
350 
351  return select;
352 }
It models the inequality operator greater than (>).
Definition: GreaterThan.h:46
boost::ptr_vector< GroupByItem > GroupBy
A class that can be used to model a GROUP BY clause.
Definition: GroupBy.h:37
Geometric property.
A class that can be used in a GROUP BY clause.
Definition: GroupByItem.h:50
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...
A class that models the name of a dataset used in a From clause.
Definition: DataSetName.h:43
A class that models the name of any property of an object.
A class that models the description of a dataset.
Definition: DataSetType.h:72
ST_Collect statistical function.
Definition: ST_Collect.h:46
const te::da::ObjectIdSet * m_oidSet
This class models a bool Literal value.
Definition: LiteralBool.h:43
te::da::DataSourcePtr m_outDsrc
#define _NOEXCEPT_OP(x)
Boolean logic operator: AND.
This is an abstract class that models a query expression.
TEVPEXPORT void Save(te::da::DataSource *source, te::da::DataSet *result, te::da::DataSetType *outDsType, const bool &enableProgress=true)
Spatial is cloded operator.
Definition: ST_IsClosed.h:50
te::da::Select getSelectQueryForceCloseLines(da::DataSetType *dataSetType)
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.
bool run() _NOEXCEPT_OP(false)
ST_MakePolygon statistical function.
te::da::Select getSelectQueryClosedLines(da::DataSetType *dataSetType)
std::unique_ptr< te::da::DataSetTypeConverter > m_converter
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
Utility functions for the data access module.
ST_Dump statistical function.
Definition: ST_Dump.h:46
A Select models a query to be used when retrieving data from a DataSource.
Definition: Select.h:65
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
te::da::DataSourcePtr m_inDsrc
It models the comparison operator.
Definition: EqualTo.h:46
Line To Polygon Vector Processing functions.
A Select can be used as a source of information in another query.
Definition: SubSelect.h:49
Spatial add point operator.
Definition: ST_AddPoint.h:46
TEDATAACCESSEXPORT te::gm::GeometryProperty * GetFirstGeomProperty(const DataSetType *dt)
Spatial start point operator.
Definition: ST_StartPoint.h:50
Spatial number of points operator.
Definition: ST_NPoints.h:50
Expression * getExpression() const
It returns the expression that can be used to retrieve the data set that contains the all indentified...
std::unique_ptr< te::da::DataSetType > buildOutDataSetType()