CellSpaceOperations.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 terralib/cellspace/CellularSpacesOperations.cpp
22 
23  \brief Implementation of the Cellular Spaces operations.
24 */
25 
26 // Terralib
27 #include "../common/progress/TaskProgress.h"
28 #include "../dataaccess.h"
29 #include "../datatype/SimpleProperty.h"
30 #include "../datatype/StringProperty.h"
31 #include "../geometry/Envelope.h"
32 #include "../geometry/GeometryProperty.h"
33 #include "../geometry/Point.h"
34 #include "../geometry/Polygon.h"
35 #include "../maptools/DataSetLayer.h"
36 #include "../memory/DataSet.h"
37 #include "../memory/DataSetItem.h"
38 #include "../raster.h"
39 #include "../sam.h"
40 #include "CellSpaceOperations.h"
41 
42 #include <stdio.h>
43 
44 const int BLOCKSIZE = 10000;
45 
47 
49 
51  const std::string& name,
52  const double& resX,
53  const double& resY,
54  const te::gm::Envelope& env,
55  const int srid,
56  const CellSpaceType type,
57  te::map::AbstractLayerPtr layerBase)
58 {
59  int maxcols = (int)ceil((env.m_urx-env.m_llx)/resX),
60  maxrows = (int)ceil((env.m_ury-env.m_lly)/resY);
61 
62  bool useMask = false;
63  std::unique_ptr<te::da::DataSet> refDs;
64  if(layerBase.get())
65  {
66  refDs = layerBase->getData();
67  useMask=true;
68 
69  if (layerBase->getSchema()->hasRaster())
70  {
71  throw te::common::Exception(TE_TR("Can not generate cellspace based on Raster with mask!"));
72  }
73  }
74 
75  std::unique_ptr<te::da::DataSetType> outputDataSetType(createCellularDataSetType(name, srid, type));
76 
77  std::unique_ptr<te::sam::rtree::Index<size_t, 8> > rtree;
78  if(useMask)
79  rtree.reset(getRtree(layerBase));
80 
81  te::common::TaskProgress task("Processing Cellular Spaces...");
82  task.setTotalSteps(maxrows);
83  task.useTimer(true);
84 
85  te::mem::DataSet* outputDataSet = new te::mem::DataSet(outputDataSetType.get());
86 
87  // Output
88  std::unique_ptr<te::da::DataSource> source = te::da::DataSourceFactory::make(outputSource->getAccessDriver(), outputSource->getConnInfo());
89  source->open();
90 
91  std::map<std::string, std::string> options;
92 
93  std::size_t count = 0;
94 
95  double x, y;
96  for(int lin = 0; lin < maxrows; ++lin)
97  {
98  if (!task.isActive())
99  {
100  throw te::common::Exception(TE_TR("Operation canceled!"));
101  }
102 
103  y = env.m_lly+(lin*resY);
104  for(int col = 0; col < maxcols; ++col)
105  {
106  x = env.m_llx+(col*resX);
107 
108  te::gm::Envelope* env = new te::gm::Envelope(x, y, x+resX, y+resY);
109 
110  std::unique_ptr<te::gm::Geometry> geom;
111  if(type == CELLSPACE_POLYGONS)
112  {
113  geom.reset(te::gm::GetGeomFromEnvelope(env, srid));
114  }
115  else if(type == CELLSPACE_POINTS)
116  {
117  double pX = env->m_llx +( (env->m_urx - env->m_llx) / 2);
118  double pY = env->m_lly +( (env->m_ury - env->m_lly) / 2);
119  geom.reset(new te::gm::Point(pX, pY, srid));
120  }
121 
122  if(useMask)
123  {
124  std::vector<size_t> report;
125  rtree->search(*geom->getMBR(), report);
126 
127  std::size_t geomPos = te::da::GetFirstSpatialPropertyPos(refDs.get());
128 
129  if(!report.empty())
130  {
131  for(std::size_t i = 0; i < report.size(); ++i)
132  {
133  refDs->move(report[i]);
134 
135  std::unique_ptr<te::gm::Geometry> g = refDs->getGeometry(geomPos);
136  g->setSRID(srid);
137 
138  if(geom->intersects(g.get()))
139  {
140  addCell(outputDataSet, col, lin, geom.release());
141  break;
142  }
143  }
144  }
145  }
146  else
147  {
148  addCell(outputDataSet, col, lin, geom.release());
149  }
150 
151  if (count == 0)
152  {
153  source->createDataSet(outputDataSetType.get(), options);
154  source->add(outputDataSetType->getName(), outputDataSet, options);
155 
156  delete outputDataSet;
157 
158  outputDataSet = new te::mem::DataSet(outputDataSetType.get());
159  }
160 
161  if ((count / BLOCKSIZE) >= 1)
162  {
163  source->add(outputDataSetType->getName(), outputDataSet, options);
164 
165  delete outputDataSet;
166 
167  outputDataSet = new te::mem::DataSet(outputDataSetType.get());
168  }
169 
170  ++count;
171  }
172 
173  task.pulse();
174  }
175 
176  if (outputDataSet)
177  {
178  source->add(outputDataSetType->getName(), outputDataSet, options);
179 
180  delete outputDataSet;
181  }
182 
183  source->close();
184 }
185 
187 {
188  char celId[32];
189  sprintf(celId,"C%02dL%02d",col,row);
190 
192  item->setString(0, celId);
193  item->setInt32(1, col);
194  item->setInt32(2, row);
195  item->setGeometry(3, geom);
196  ds->add(item);
197 }
198 
200 {
202 
203  std::unique_ptr<te::da::DataSet> ds = layerBase->getData();
204 
205  std::size_t geomPos = te::da::GetFirstSpatialPropertyPos(ds.get());
206 
207  ds->moveBeforeFirst();
208 
209  int count = 0;
210 
211  while(ds->moveNext())
212  {
213  std::unique_ptr<te::gm::Geometry> geom = ds->getGeometry(geomPos);
214 
215  rtree->insert(*geom->getMBR(), count);
216 
217  ++count;
218  }
219 
220  return rtree;
221 }
222 
224 {
225  te::da::DataSetType* dst = new te::da::DataSetType(name);
226 
229  idProp->setSize(255);
232  te::dt::Property* geomProp = nullptr;
233 
234  if(type == CELLSPACE_POLYGONS)
235  geomProp = new te::gm::GeometryProperty("geom", srid, te::gm::PolygonType);
236  else if(type == CELLSPACE_POINTS)
237  geomProp = new te::gm::GeometryProperty("geom", srid, te::gm::PointType);
238 
239  dst->add(idProp);
240  dst->add(colProp);
241  dst->add(rowProp);
242  dst->add(geomProp);
243 
244  std::string pkName = name + "_pk_id";
245  te::da::PrimaryKey* pk = new te::da::PrimaryKey(pkName, dst);
246  std::vector<te::dt::Property*> pkProp;
247  pkProp.push_back(idProp);
248  pk->setProperties(pkProp);
249 
250  return dst;
251 }
void addCell(te::mem::DataSet *ds, int col, int row, te::gm::Geometry *geom)
Add a cell in the memory dataset.
static std::unique_ptr< DataSource > make(const std::string &driver, const te::core::URI &connInfo)
Geometric property.
void setGeometry(std::size_t i, te::gm::Geometry *value)
It sets the value of the i-th property.
An atomic property like an integer or double.
void setSubtype(StringType t)
It sets the string property sub type.
A class that represents an R-tree.
A class that models the description of a dataset.
Definition: DataSetType.h:72
void useTimer(bool flag)
Used to define if task use progress timer information.
void setSize(std::size_t s)
It sets the maximum number of characters for a varying string, or the number of characters for a fixe...
const int BLOCKSIZE
This class can be used to inform the progress of a task.
Definition: TaskProgress.h:53
double m_urx
Upper right corner x-coordinate.
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
It models a property definition.
Definition: Property.h:59
bool isActive() const
Verify if the task is active.
void add(DataSetItem *item)
It adds a new item to the dataset and takes its ownership.
void setTotalSteps(int value)
Set the task total stepes.
te::da::DataSetType * createCellularDataSetType(const std::string &name, int srid, CellSpaceType type)
Create the DataSetType of the cellular space.
void setInt32(std::size_t i, boost::int32_t value)
It sets the value of the i-th property.
Implementation of a random-access dataset class for the TerraLib In-Memory Data Access driver...
double m_llx
Lower left corner x-coordinate.
TEDATAACCESSEXPORT std::size_t GetFirstSpatialPropertyPos(const te::da::DataSet *dataset)
It returns the first dataset spatial property or NULL if none is found.
A point with x and y coordinate values.
Definition: Point.h:50
An Envelope defines a 2D rectangular region.
void DataSet()
void setProperties(const std::vector< te::dt::Property * > &properties)
It sets the properties that form the primary key.
Definition: PrimaryKey.h:116
void pulse()
Calls setCurrentStep() function using getCurrentStep() + 1.
te::sam::rtree::Index< size_t, 8 > * getRtree(te::map::AbstractLayerPtr layerBase)
Get a RTree with the geometries envelopes of layer.
The type for string types: FIXED_STRING, VAR_STRING or STRING.
This class is designed to declare objects to be thrown as exceptions by TerraLib. ...
Geometry is the root class of the geometries hierarchy, it follows OGC and ISO standards.
double m_lly
Lower left corner y-coordinate.
void add(Constraint *c)
It adds a new constraint.
An implementation of the DatasetItem class for the TerraLib In-Memory Data Access driver...
void insert(const te::gm::Envelope &mbr, const DATATYPE &data)
It inserts an item into the tree.
double m_ury
Upper right corner y-coordinate.
It describes a primary key (pk) constraint.
Definition: PrimaryKey.h:52
void setString(std::size_t i, const std::string &value)
It sets the value of the i-th property.
boost::intrusive_ptr< AbstractLayer > AbstractLayerPtr
unsigned int col
void createCellSpace(te::da::DataSourceInfoPtr outputSource, const std::string &name, const double &resX, const double &resY, const te::gm::Envelope &env, const int srid, CellSpaceType type, te::map::AbstractLayerPtr layerBase)
It creates a Cellular Space.
TEGEOMEXPORT Geometry * GetGeomFromEnvelope(const Envelope *const e, int srid)
It creates a Geometry (a polygon) from the given envelope.
boost::shared_ptr< DataSourceInfo > DataSourceInfoPtr