Smooth.cpp
Go to the documentation of this file.
1 /*!
2 \file terralib/mnt/core/Smooth.cpp
3 
4 \brief This file contains a class to isolines smooth.
5 
6 */
7 
8 #include "Smooth.h"
9 #include "Utils.h"
10 
11 //terralib
12 #include "../../common/progress/TaskProgress.h"
13 #include "../../dataaccess/utils/Utils.h"
14 #include "../../geometry/GeometryProperty.h"
15 #include "../../srs/SpatialReferenceSystemManager.h"
16 
17 te::mnt::Smooth::Smooth() = default;
18 
19 te::mnt::Smooth::~Smooth() = default;
20 
22  std::string inDsetName,
23  std::unique_ptr<te::da::DataSetType> inDsetType)
24 {
25  m_inDsrc = inDsrc;
26  m_inDsetName = inDsetName;
27  m_inDsetType = std::move(inDsetType);
28 
29 }
30 
31 void te::mnt::Smooth::setOutput(te::da::DataSourcePtr outDsrc, std::string dsname)
32 {
33  m_outDsrc = outDsrc;
34  m_outDsetName = dsname;
35 }
36 
37 void te::mnt::Smooth::setParams(double factor, double maxdist, bool simpl_out)
38 {
39  m_factor = factor;
40  m_maxdist = maxdist;
41  m_simpl_out = simpl_out;
42 }
43 
45 {
48  std::vector< std::unique_ptr< te::gm::LineString > > isolines_suavizado;
49 
50  std::string geostype;
51  te::gm::Envelope env;
52  std::string attr;
53 
54  ReadSamples(m_inDsetName, m_inDsrc, attr, m_factor, m_maxdist, DouglasPeucker, mpt, isolines_simp, geostype, env);
55 
56  te::common::TaskProgress task("Smoothing Isolines...", te::common::TaskProgress::UNDEFINED, (int)isolines_simp.getNumGeometries());
57 
58  for (size_t i = 0; i < isolines_simp.getNumGeometries(); i++)
59  {
60  if (!task.isActive())
61  return false;
62  task.pulse();
63  std::unique_ptr<te::gm::LineString> iso(new te::gm::LineString(*dynamic_cast<te::gm::LineString*>(isolines_simp.getGeometryN(i))));
64  if (AdjustCatmullRom(*iso.get()))
65  {
66  if (m_simpl_out)
67  {
68  std::unique_ptr< te::gm::LineString > iso_sim(pointListSimplify(iso.get(), m_factor, m_maxdist, iso->getZ(0)));
69  isolines_suavizado.push_back(std::move(iso_sim));
70  }
71  else
72  isolines_suavizado.push_back(std::move(iso));
73  }
74  }
75 
76  std::vector<double> guidevalues;
77  SaveIso(m_outDsetName, m_outDsrc, isolines_suavizado, guidevalues, m_srid);
78 
79  return true;
80 }
81 
83 {
84  size_t npts = iso.getNPoints();
85  double valuez = iso.getZ(0);
86  if (npts < 3)
87  return false;
88 
89  te::gm::Coord2D *vxy = iso.getCoordinates();
90 
91  te::gm::Coord2D xyA, xyB, xyC, xyD;
92  te::gm::Coord2D pxy;
93 
94  size_t ipts = 0;
95 
96  xyA = vxy[ipts];
97  xyB = vxy[ipts];
98  ipts++;
99  xyC = vxy[ipts];
100 
101  std::vector<te::gm::Coord2D> vab;
102  std::vector<te::gm::Coord2D> vbc;
103  std::vector<te::gm::Coord2D> isout;
104 
105  short getNext = 1;
106  short repeatD = 0;
107  while (ipts < npts)
108  {
109  if (getNext)
110  {
111  if (repeatD)
112  repeatD = 0;
113  else
114  ipts++;
115 
116  if (ipts < npts)
117  xyD = vxy[ipts];
118  else
119  xyD = xyC;
120  }
121  else
122  {
123  getNext = 1;
124  //ipts++;
125  }
126 
127  double a3 = (-xyA.getX() + 3 * (xyB.getX() - xyC.getX()) + xyD.getX()) / 2;
128  double a2 = (2 * xyA.getX() - 5 * xyB.getX() + 4 * xyC.getX() - xyD.getX()) / 2;
129  double a1 = (xyC.getX() - xyA.getX()) / 2;
130  double a0 = xyB.getX();
131 
132  double b3 = (-xyA.getY() + 3 * (xyB.getY() - xyC.getY()) + xyD.getY()) / 2;
133  double b2 = (2 * xyA.getY() - 5 * xyB.getY() + 4 * xyC.getY() - xyD.getY()) / 2;
134  double b1 = (xyC.getY() - xyA.getY()) / 2;
135  double b0 = xyB.getY();
136 
137  double dx = xyC.getX() - xyB.getX();
138  double dy = xyC.getY() - xyB.getY();
139 
140  double stsize = sqrt(dx * dx + dy * dy);
141  int nsteps = (int)(stsize / m_maxdist);
142 
143  for (int j = 0; j < nsteps; j++)
144  {
145  double t = (double)j / (double)nsteps;
146 
147  double x = ((a3 * t + a2) * t + a1) * t + a0;
148  double y = ((b3 * t + b2) * t + b1) * t + b0;
149 
150  if (j)
151  {
152  double dx1 = pxy.getX() - x;
153  double dy1 = pxy.getY() - y;
154 
155  double segSize = sqrt(dx1 * dx1 + dy1 * dy1);
156  double cost = (dx * dx1 + dy * dy1) / (stsize * segSize);
157 
158  if (fabs(cost) < 0.7)
159  {
160  repeatD = 1;
161  getNext = 0;
162 
163  vbc.clear();
164 
165  te::gm::Coord2D pt0, pt1;
166 
167  //Finds longest segment
168  double segsizeAB = te::mnt::Distance(xyA, xyB);
169  double segsizeBC = te::mnt::Distance(xyB, xyC);
170  double segsizeCD = te::mnt::Distance(xyC, xyD);
171 
172  if ((segsizeAB >= segsizeBC) && (segsizeAB >= segsizeCD))
173  {
174  //Uses AB to find middle point, uses C for opposite side
175  middlePointWithSnap(xyA, xyB, pt0, pt1, m_maxdist);
176 
177  if (te::mnt::onSameSide(xyC, pt0, xyA, xyB) == 1)
178  xyA = pt1;
179  else
180  xyA = pt0;
181  }
182  else if ((segsizeBC >= segsizeAB) && (segsizeBC >= segsizeCD))
183  {
184  //Uses BC to find middle point, uses D for opposite side
185  middlePointWithSnap(xyB, xyC, pt0, pt1, m_maxdist);
186 
187  xyD = xyC;
188 
189  if (te::mnt::onSameSide(xyD, pt0, xyB, xyC) == 1)
190  xyC = pt1;
191  else
192  xyC = pt0;
193  }
194  else
195  {
196  // Uses CD to find middle point, uses B for opposite side
197  middlePointWithSnap(xyC, xyD, pt0, pt1, m_maxdist);
198 
199  if (te::mnt::onSameSide(xyB, pt0, xyC, xyD) == 1)
200  xyD = pt1;
201  else
202  xyD = pt0;
203  }
204 
205  break;
206  }
207  }
208 
209  pxy.x = x;
210  pxy.y = y;
211  vbc.push_back(pxy);
212  }
213 
214  if ((!nsteps) || (ipts == npts))
215  {
216  double x = a3 + a2 + a1 + a0;
217  double y = b3 + b2 + b1 + b0;
218 
219  pxy.x = x;
220  pxy.y = y;
221  vbc.push_back(pxy);
222 
223  if ((!nsteps) && (getNext))
224  {
225  xyA = xyB;
226  xyB = xyC;
227  xyC = xyD;
228  }
229  }
230  else if (getNext)
231  {
232  xyA = xyB;
233  xyB = xyC;
234  xyC = xyD;
235  }
236 
237  if (vab.size() > 0)
238  {
239  for (size_t i = 0; i < vab.size(); i++)
240  isout.push_back(vab[i]);
241  vab.clear();
242  }
243 
244  if (ipts == npts)
245  {
246  if (vbc.size() > 0)
247  {
248  for (size_t i = 0; i < vbc.size(); i++)
249  isout.push_back(vbc[i]);
250  vbc.clear();
251  }
252  }
253  else
254  {
255  if (vbc.size() > 0)
256  {
257  for (size_t i = 0; i < vbc.size(); i++)
258  vab.push_back(vbc[i]);
259  vbc.clear();
260  }
261  }
262  }
263 
264  iso.makeEmpty();
265  iso.setNumCoordinates(isout.size());
266  for (size_t i = 0; i < isout.size(); i++)
267  {
268  iso.setPointZ(i, isout[i].getX(), isout[i].getY(), valuez);
269  }
270  isout.clear();
271 
272  return true;
273 }
274 
275 
277 {
278  //Calculates middle point
279  double a = pto.getX() - pfr.getX();
280  double b = pto.getY() - pfr.getY();
281 
282  double x = (a / 2) + pfr.getX();
283  double y = (b / 2) + pfr.getY();
284 
285  te::gm::Coord2D ptm(x, y);
286 
287  if (a == 0)
288  {
289  pt0.x = ptm.getX() + d;
290  pt0.y = ptm.getY();
291  pt1.x = ptm.getX() - d;
292  pt1.y = ptm.getY();
293 
294  return true;
295  }
296 
297  if (b == 0)
298  {
299  pt0.x = ptm.getX();
300  pt0.y = ptm.getY() + d;
301  pt1.x = ptm.getX();
302  pt1.y = ptm.getY() - d;
303 
304  return true;
305  }
306 
307  double bx = pfr.getX() - ptm.getX();
308  double by = pfr.getY() - ptm.getY();
309 
310  double c = -(bx / by);
311 
312  double x0 = sqrt((d * d) / (1 + (c * c)));
313  double x1 = -x0;
314  double y0 = c * x0;
315  double y1 = c * x1;
316 
317  pt0.x = +ptm.getX();
318  pt0.y = y0 + ptm.getY();
319  pt1.x = x1 + ptm.getX();
320  pt1.y = y1 + ptm.getY();
321 
322  return true;
323 }
std::size_t getNumGeometries() const
It returns the number of geometries in this GeometryCollection.
double y
y-coordinate.
Definition: Coord2D.h:114
boost::shared_ptr< DataSource > DataSourcePtr
Coord2D * getCoordinates() const
It returns a pointer to the internal array of coordinates.
Definition: LineString.h:456
static te::dt::Date dx(2010, 12, 31)
double x
x-coordinate.
Definition: Coord2D.h:113
TEMNTEXPORT double Distance(const te::gm::Coord2D &pt1, const te::gm::Coord2D &pt2)
void makeEmpty()
It clears all the coordinates.
This class can be used to inform the progress of a task.
Definition: TaskProgress.h:53
void setOutput(te::da::DataSourcePtr outDsrc, std::string dsname)
Definition: Smooth.cpp:31
std::string m_outDsetName
Definition: Smooth.h:54
bool m_simpl_out
Definition: Smooth.h:59
An utility struct for representing 2D coordinates.
Definition: Coord2D.h:40
double getY() const
It returns the y-coordinate.
Definition: Coord2D.h:108
void setParams(double factor, double max_dist, bool simpl)
Definition: Smooth.cpp:37
te::da::DataSourcePtr m_outDsrc
Definition: Smooth.h:53
bool middlePointWithSnap(te::gm::Coord2D &pfr, te::gm::Coord2D &pto, te::gm::Coord2D &pt0, te::gm::Coord2D &pt1, double d)
Definition: Smooth.cpp:276
void setInput(te::da::DataSourcePtr inDsrc, std::string inDsetName, std::unique_ptr< te::da::DataSetType > inDsetType)
Definition: Smooth.cpp:21
int b
Definition: TsRtree.cpp:32
MultiPoint is a GeometryCollection whose elements are restricted to points.
Definition: MultiPoint.h:50
LineString is a curve with linear interpolation between points.
Definition: LineString.h:62
An Envelope defines a 2D rectangular region.
TEMNTEXPORT te::gm::LineString * pointListSimplify(te::gm::LineString *ls, double snap, double maxdist, double Zvalue)
int m_srid
Attribute with spatial reference information.
Definition: Smooth.h:56
te::gm::Point * pt1
static te::dt::DateTime d(2010, 8, 9, 15, 58, 39)
void setNumCoordinates(std::size_t size)
It reserves room for the number of coordinates in this LineString.
std::unique_ptr< te::da::DataSetType > m_inDsetType
Definition: Smooth.h:51
double m_maxdist
Definition: Smooth.h:58
std::size_t getNPoints() const
It returns the number of points (vertexes) in the linestring.
Definition: LineString.h:193
void pulse()
Calls setCurrentStep() function using getCurrentStep() + 1.
void setPointZ(std::size_t i, const double &x, const double &y, const double &z)
It sets the value of the specified point.
Utility functions for the data access module.
TEMNTEXPORT size_t ReadSamples(std::string &inDsetName, te::da::DataSourcePtr &inDsrc, std::string &atrZ, double tol, double max, Simplify alg, te::gm::MultiPoint &mpt, te::gm::MultiLineString &isolines, std::string &geostype, te::gm::Envelope &env, int srid=0)
Geometry * getGeometryN(std::size_t i) const
It returns the n-th geometry in this GeometryCollection.
MultiLineString is a MultiCurve whose elements are LineStrings.
This file contains a class to isolines smooth. Adapted from SPRING.
double getX() const
It returns the x-coordinate.
Definition: Coord2D.h:102
TEMNTEXPORT int onSameSide(te::gm::Coord2D pt1, te::gm::Coord2D pt2, te::gm::Coord2D fseg, te::gm::Coord2D lseg)
bool AdjustCatmullRom(te::gm::LineString &iso)
Definition: Smooth.cpp:82
const double & getZ(std::size_t i) const
It returns the n-th z coordinate value.
TEMNTEXPORT bool SaveIso(std::string &outDsetName, te::da::DataSourcePtr &outDsrc, std::vector< std::unique_ptr< te::gm::LineString > > &isolist, std::vector< double > &guidevalues, int srid)
bool run()
Definition: Smooth.cpp:44
te::da::DataSourcePtr m_inDsrc
Definition: Smooth.h:49
double m_factor
Definition: Smooth.h:57
std::string m_inDsetName
Definition: Smooth.h:50