GAP.cpp
Go to the documentation of this file.
1 
2 #include "../Config.h"
3 #include "GAP.h"
4 
5 #include <geos.h>
6 #include <geos/geom/Coordinate.h>
7 #include <geos/geom/LineSegment.h>
8 #include <geos/geosAlgorithm.h>
9 #include <geos/simplify/DouglasPeuckerLineSimplifier.h>
10 #include <geos/algorithm/distance/DiscreteHausdorffDistance.h>
11 
12 #include <terralib/geometry/Coord2d.h>
14 
15 
16 te::gm::Coord2D appGetCenterPointOfPoints(std::vector<te::gm::Coord2D> &pts)
17 {
18  double x = 0;
19  double y = 0;
20  for (size_t i = 0; i < pts.size(); i++)
21  {
22  x += pts[i].getX();
23  y += pts[i].getY();
24  }
25  return(te::gm::Coord2D(x / pts.size(), y / pts.size()));
26 }
27 
29 {
30 public:
32 
34  {
35  if ((a.x - c.x) >= 0 && (b.x - c.x) < 0)
36  return true;
37  if ((a.x - c.x) < 0 && (b.x - c.x) >= 0)
38  return false;
39  if ((a.x - c.x) == 0 && (b.x - c.x) == 0) {
40  if (a.y - c.y >= 0 || b.y - c.y >= 0)
41  return a.y > b.y;
42  return b.y > a.y;
43  }
44 
45  // compute the cross product of vectors (center -> a) x (center -> b)
46  double det = (a.x - c.x) * (b.y - c.y) - (b.x - c.x) * (a.y - c.y);
47  if (det < 0)
48  return true;
49  if (det > 0)
50  return false;
51 
52  // points a and b are on the same line from the center
53  // check which point is closer to the center
54  double d1 = (a.x - c.x) * (a.x - c.x) + (a.y - c.y) * (a.y - c.y);
55  double d2 = (b.x - c.x) * (b.x - c.x) + (b.y - c.y) * (b.y - c.y);
56  return d1 > d2;
57  }
58 
60 };
61 
62 
63 double Distance(const double pt1x, const double pt1y, const double pt2x, const double pt2y)
64 {
65  double dx,
66  dy,
67  dist;
68 
69  dx = pt1x - pt2x;
70  dx = dx * dx;
71  dy = pt1y - pt2y;
72  dy = dy * dy;
73  dist = sqrt(dy + dx);
74  return(dist);
75 }
76 
77 
79 {
80  return(Distance(pt1.getX(), pt1.getY(), pt2.getX(), pt2.getY()));
81 }
82 
83 
84 float coef_angular(double fx, double fy, double lx, double ly)
85 {
86  float dx = (float)fx - (float)lx;
87  float coef = std::numeric_limits< float >::max();
88  if (dx)
89  coef = ((float)fy - (float)ly) / dx;
90 
91  return coef;
92 }
93 
95 {
96  double d0c = Distance(first, cent);
97  double d1c = Distance(last, cent);
98  double dcc = Distance(c, cent);
99  if (dcc > d0c && dcc > d1c)
100  return false;
101 
102  double m01 = coef_angular(first.x, first.y, last.x, last.y);
103  double m0c = coef_angular(first.x, first.y, c.x, c.y);
104 
105  if (m01 == std::numeric_limits< float >::max()) //segmento na vertical
106  {
107  if (m0c == 0)
108  {
109  if (dcc > d0c)
110  return false;
111  else
112  return true;
113  }
114  if (m0c > 0)
115  return true;
116  else
117  return false;
118  }
119 
120  if (m0c == std::numeric_limits< float >::max()) //ponto na vertical
121  {
122  if (m01 == 0)
123  {
124  if (dcc > d0c)
125  return false;
126  else
127  return true;
128  }
129  if (m01 < 0)
130  return true;
131  else
132  return false;
133  }
134 
135  else if (m0c < m01)
136  return true;
137 
138  return false;
139 }
140 
142 {
143  // Adapted from TWO-DIMENSIONAL CLIPPING: A VECTOR-BASED APPROACH
144  // Hans J.W. Spoelder, Fons H. Ullings in:
145  //// Graphics Gems I, pp.701,
146 
147  double a, b, c,
148  px, py, lx, ly, lpx, lpy, s;
149 
150  px = pto.getX() - pfr.getX();
151  py = pto.getY() - pfr.getY();
152  lx = lto.getX() - lfr.getX();
153  ly = lto.getY() - lfr.getY();
154  lpx = pfr.getX() - lfr.getX();
155  lpy = pfr.getY() - lfr.getY();
156 
157  a = py * lx - px * ly;
158  b = lpx * ly - lpy * lx;
159  c = lpx * py - lpy * px;
160 
161  if (a == 0) // Linhas paralelas
162  return false;
163  else
164  {
165  if (a > 0)
166  {
167  if ((b < 0) || (b > a) || (c < 0) || (c > a))
168  return false;
169  }
170  else
171  {
172  if ((b > 0) || (b < a) || (c > 0) || (c < a))
173  return false;
174  }
175  if (pt)
176  {
177  s = b / a;
178  pt->x = (pfr.getX() + (px*s));
179  pt->y = (pfr.getY() + (py*s));
180  }
181  }
182  return true;
183 }
184 
185 double SegmentDistance(double fx, double fy, double lx, double ly, double ptx, double pty, double *pix, double *piy)
186 {
187  double ux = lx - fx;
188  double uy = ly - fy;
189  double vx = ptx - fx;
190  double vy = pty - fy;
191  double uv = (ux*vx + uy*vy);
192  if (uv < 0.)
193  {
194  if (pix && piy)
195  {
196  *pix = lx;
197  *piy = ly;
198  }
199  return (sqrt(vx*vx + vy*vy));
200  }
201  else
202  {
203  ux = fx - lx;
204  uy = fy - ly;
205  vx = ptx - lx;
206  vy = pty - ly;
207  uv = (ux*vx + uy*vy);
208  if (uv < 0.)
209  {
210  if (pix && piy)
211  {
212  *pix = fx;
213  *piy = fy;
214  }
215  return (sqrt(vx*vx + vy*vy));
216  }
217  }
218 
219  double a, b, c, k, dist, aabb;
220 
221  a = ly - fy;
222  b = fx - lx;
223  c = lx*fy - fx*ly;
224  aabb = a*a + b*b;
225 
226  dist = fabs((a*ptx + b*pty + c) / (sqrt(aabb)));
227  if (pix && piy)
228  {
229  k = b*ptx - a*pty;
230  *pix = (b*k - a*c) / aabb;
231  *piy = (-a*k - b*c) / aabb;
232  }
233 
234  return dist;
235 
236 }
237 
239 {
240  //double pix, piy;
241  //double dist = SegmentDistance(fseg.getX(), fseg.getY(), lseg.getX(), lseg.getY(), pt.getX(), pt.getY(), &pix, &piy);
242  //if (pti)
243  //{
244  // pti->x = pix;
245  // pti->y = piy;
246  //}
247  //return dist;
248  geos::geom::LineSegment ls(fseg.x, fseg.y, lseg.x, lseg.y);
249  geos::geom::Coordinate c(pt.x, pt.y);
250  geos::geom::Coordinate c_int;
251  if (pti)
252  {
253  ls.closestPoint(c, c_int);
254  pti->x = c_int.x;
255  pti->y = c_int.y;
256  }
257  return(ls.distance(c));
258 }
259 
260 
262 {
263  std::vector<geos::geom::Coordinate> coordpts;
264  for (std::size_t j = 0; j < ls->size(); ++j)
265  {
266  std::unique_ptr<te::gm::Point> lpt = std::move(ls->getPointN(j));
267  geos::geom::Coordinate coo(lpt->getX(), lpt->getY());
268  coordpts.push_back(coo);
269  }
270  geos::simplify::DouglasPeuckerLineSimplifier douglas(coordpts);
271  douglas.setDistanceTolerance(snap);
272  geos::simplify::DouglasPeuckerLineSimplifier::CoordsVectAutoPtr simplified = douglas.simplify();
273  if (simplified.get()->at(0) != simplified.get()->at(simplified->size() - 1))
274  simplified->insert(simplified->end(), simplified.get()->at(0));
275 
276  te::gm::LineString* lsout = new te::gm::LineString(simplified->size(), te::gm::LineStringType);
277 
278  for (std::size_t j = 0; j < simplified->size(); ++j)
279  {
280  geos::geom::Coordinate c1 = simplified.get()->at(j);
281  lsout->setPoint(j, c1.x, c1.y);
282  }
283 
284  return lsout;
285 }
286 
287 
289 {
290  if (m_ptid < rhs.m_ptid)
291  return true;
292  if (m_ptid == rhs.m_ptid)
293  {
294  if (m_distance < rhs.m_distance)
295  return true;
296  }
297  return false;
298 }
299 
300 
302 {
303  return (m_xnew == rhs.m_xnew && m_ynew == rhs.m_ynew);
304 }
305 
306 
308 {
309  double d0 = Distance(m_seg.getCoordinates()[0], m_centroid);
310  double d1 = Distance(m_seg.getCoordinates()[1], m_centroid);
311  double dp = Distance(pt, m_centroid);
312  if (dp < d0 && dp < d1)
313  return true;
314 
315  //return false;
316  float dx = (float)m_seg.getCoordinates()[1].getX() - (float)m_seg.getCoordinates()[0].getX();
317  float dxpt = (float)pt.getX() - (float)m_seg.getCoordinates()[0].getX();
318  float coef_seg = std::numeric_limits< float >::max();
319  float coef_pt = std::numeric_limits< float >::max();
320  if (dx)
321  coef_seg = ((float)m_seg.getCoordinates()[1].getY() - (float)m_seg.getCoordinates()[0].getY()) / dx;
322  if (dxpt)
323  coef_pt = ((float)pt.getY() - (float)m_seg.getCoordinates()[0].getY()) / dxpt;
324 
325  if (!dx)//segmento vertical ->
326  {
327  if (coef_pt > 0)
328  return true;
329  else
330  return false;
331  }
332 
333  if (!dxpt)
334  {
335  if (coef_seg < 0)
336  return true;
337  else
338  return false;
339  }
340 
341  if (coef_pt < coef_seg)
342  return true;
343 
344  return false;
345 }
346 
348 {
349  m_inter.push_back(inter);
350 }
351 
353 {
354  std::unique_ptr<te::da::DataSourceTransactor> t = source->getTransactor();
355 
356  std::map<std::string, std::string> options;
357 
358  try
359  {
360  if (source->getType() == "OGR")
361  {
362  // create the dataset
363  source->createDataSet(outDsType, options);
364 
365  // copy from memory to output datasource
366  result->moveBeforeFirst();
367  std::string name = outDsType->getName();
368  source->add(name, result, options);
369  }
370  else
371  {
372  t->begin();
373 
374  // create the dataset
375  t->createDataSet(outDsType, options);
376 
377  // copy from memory to output datasource
378  result->moveBeforeFirst();
379  std::string name = outDsType->getName();
380  t->add(name, result, options);
381 
382  t->commit();
383  }
384 
385  }
386  catch (te::common::Exception& e)
387  {
388  t->rollBack();
389  throw e;
390  }
391  catch (std::exception& e)
392  {
393  t->rollBack();
394  throw e;
395  }
396 }
397 
398 
399 bool GAP::Polygon2Points(te::gm::Polygon* pol, int32_t id)
400 {
401  for (size_t nlr = 0; nlr < pol->getNumRings(); nlr++)
402  {
403  te::gm::LinearRing *lr = dynamic_cast<te::gm::LinearRing*>(pol->getRingN(nlr));
404  for (size_t i = 0; i < lr->getNPoints() - 1; i++)
405  {
406  te::gm::Coord2D pt(lr->getPointN(i)->getX(), lr->getPointN(i)->getY());
407  m_nodetree->insert(pt, std::pair<int32_t, int32_t>(id, (int32_t)i));
408  }
409  }
410  return true;
411 }
412 
413 
415 {
416  std::vector<te::gm::Line*> reportline;
417 
418  for (size_t nlr = 0; nlr < pol->getNumRings(); nlr++)
419  {
420  te::gm::LinearRing *lr = dynamic_cast<te::gm::LinearRing*>(pol->getRingN(nlr));
421  for (size_t i = 0; i < lr->getNPoints() - 1; i++)
422  {
423  te::gm::Point first(*lr->getPointN(i));
424  te::gm::Point last(*lr->getPointN(i + 1));
425  te::gm::Line *l = new te::gm::Line(first, last, te::gm::LineStringType, pol->getSRID());
426  te::gm::Envelope e(*l->getMBR());
427  rtree.insert(e, l);
428  }
429  }
430  return true;
431 }
432 
434 {
435  for (size_t nlr = 0; nlr < pol->getNumRings(); nlr++)
436  {
437  te::gm::LinearRing *lr = dynamic_cast<te::gm::LinearRing*>(pol->getRingN(nlr));
438  for (size_t i = 0; i < lr->getNPoints() - 1; i++)
439  {
440  te::gm::Point first(*lr->getPointN(i));
441  te::gm::Point last(*lr->getPointN(i + 1));
442  te::gm::Line *l = new te::gm::Line(first, last, te::gm::LineStringType, pol->getSRID());
443  m_line.push_back(l);
444  }
445  }
446  return true;
447 }
448 
449 bool GAP::LoadPolygons(std::string &filename, std::string &inDsetName, Pol_OUT out)
450 {
451  std::map<std::string, std::string> srcInfo;
452  srcInfo["URI"] = filename;
453  srcInfo["DRIVER"] = "ESRI Shapefile";
454 
456  srcDs->open();
457 
458  if (!srcDs->dataSetExists(inDsetName))
459  {
460  std::cout << "Input dataset not found: " << inDsetName << std::endl;
461  return false;
462  }
463 
464  std::unique_ptr<te::da::DataSet> inDset = srcDs->getDataSet(inDsetName);
465  std::unique_ptr<te::da::DataSetType> inDsetType = srcDs->getDataSetType(inDsetName);
466  std::size_t geo_pos = te::da::GetFirstPropertyPos(inDset.get(), te::dt::GEOMETRY_TYPE);
467  std::size_t id_pos = te::da::GetPropertyPos(inDset.get(), "FID");
468 
469  inDset->moveBeforeFirst();
470  while (inDset->moveNext())
471  {
472  std::unique_ptr<te::gm::Geometry> gin = inDset->getGeometry(geo_pos);
473  std::string geostype = gin.get()->getGeometryType();
474  if (geostype == "MultiPolygon")
475  {
476  te::gm::MultiPolygon *g = dynamic_cast<te::gm::MultiPolygon*>(gin.get()->clone());
477  std::size_t np = g->getNumGeometries();
478  for (std::size_t i = 0; i < np; ++i)
479  {
480  te::gm::Polygon *p = dynamic_cast<te::gm::Polygon*>(g->getGeometryN(i));
481  p->setSRID(g->getSRID());
482  m_srid = p->getSRID();
483  if (out == Polygon_out)
484  {
485  m_pol.insert(std::pair<size_t, te::gm::Polygon*>(inDset->getInt32(id_pos), p));
486  double area = p->getArea();
487  int32_t id = (int32_t)inDset->getInt32(id_pos);
488  // m_original_area.insert(std::pair<size_t, double>(id, area));
489  m_original_area[i] = area;
490  }
491  if (out == RTree_out)
492  Polygon2RTree(p, m_rtree);
493  if (out == Line_out)
494  Polygon2Lines(p);
495  if (out == Point_out)
496  {
497  Polygon2Points(p, inDset->getInt32(id_pos));
498  m_srid = p->getSRID();
499  }
500  }
501  }
502  if (geostype == "Polygon")
503  {
504  te::gm::Polygon *p = dynamic_cast<te::gm::Polygon*>(gin.get()->clone());
505  p->setSRID(gin->getSRID());
506  m_srid = p->getSRID();
507  if (out == Polygon_out)
508  m_pol.insert(std::pair<size_t, te::gm::Polygon*>(inDset->getInt32(id_pos), p));
509  if (out == RTree_out)
510  Polygon2RTree(p, m_rtree);
511  if (out == Line_out)
512  Polygon2Lines(p);
513  if (out == Point_out)
514  {
515  Polygon2Points(p, inDset->getInt32(id_pos));
516  m_srid = p->getSRID();
517  }
518  }
519  }
520 
521  return true;
522 
523 }
524 
526 {
527  m_dist_min = 0.0005;
528  m_tol = m_dist_min / 5;
529  m_filename1 = "D:/Dados_GAP/AGD2015_22761_pol.shp";
530  m_inDS1 = "AGD2015_22761_pol";
531  m_filename2 = "D:/Dados_GAP/desflorestamento4674_dissolve.shp"; //Desflorestamento
532  m_inDS2 = "desflorestamento4674_dissolve";
533  //m_filename1 = "D:/Dados_GAP/1agreg.shp";
534  //m_inDS1 = "1agreg";
535  // m_filename2 = "D:/Dados_GAP/desf_1449.shp";
536  // m_inDS2 = "desf_1449";
537  // m_filename2 = "D:/Dados_GAP/polygons_int0.shp";
538  // m_inDS2 = "polygons_int0";
539 
541  m_nodetree = new KD_TREE(e);
542  m_nodetree_step2 = new KD_TREE(e);
543 }
544 
545 bool GAP::run()
546 {
547  // return run5();
548 
549  //m_filename2 = "D:/Dados_GAP/poly163_step2.shp"; //Desflorestamento
550  //m_inDS2 = "poly163_step2";
551  //if (!LoadPolygons(m_filename2, m_inDS2, Polygon_out)) //Desflorestamento para polygon
552  // return false;
553  //m_pols_2 = m_pol;
554  if (!LoadPolygons(m_filename1, m_inDS1, RTree_out)) //Agregado para segmentos (rtree)
555  return false;
556 
557  if (!LoadPolygons(m_filename1, m_inDS1, Point_out)) //Agregado para Point (kdtree)
558  return false;
559 
560  if (!LoadPolygons(m_filename2, m_inDS2, Polygon_out)) //Desflorestamento para polygon
561  return false;
562 
563  std::vector< std::pair< size_t, te::gm::Polygon* > > pols_step00; //poligonos gerados no step0
564  std::vector< std::pair< size_t, te::gm::Polygon* > > pols_step0; //poligonos gerados no step0
565  std::vector< std::pair< size_t, te::gm::Polygon* > > pols_step1; //poligonos gerados no step1
566  std::vector< std::pair< size_t, te::gm::Polygon* > > pols_step2; //poligonos gerados no step2
567  std::vector< std::pair< size_t, te::gm::Polygon* > > pols_step3; //poligonos gerados no step3
568  std::vector< std::pair< size_t, te::gm::Polygon* > > pols_final; //poligonos gerados no step3a
569 
570  step00(pols_step00);
571  if (step0(pols_step00, pols_step0))
572  {
573  if (step1(pols_step0, pols_step1))
574  {
575  if (step2(pols_step1, pols_step2))
576  {
577  pols_step1.clear();
578 
579  if (step3(pols_step2, pols_step3))
580  {
581  pols_step2.clear();
582  SavePol(pols_step3, "step3");
583  if (step4(pols_step3, pols_final))
584  {
585  pols_step3.clear();
586  SavePol(pols_final, "final");
587  pols_final.clear();
588  }
589  }
590  }
591  }
592  }
593 
594  return false;
595 }
596 
597 bool GAP::step00(std::vector< std::pair< size_t, te::gm::Polygon* > > &polsout)
598 {
599  for (std::map<size_t, te::gm::Polygon*>::iterator it = m_pol.begin(); it != m_pol.end(); it++) // Para cada poligono do desflorestamento
600  {
601  te::gm::Polygon *pol = it->second;
602  int32_t polid = (int32_t)it->first;
603  te::gm::Coord2D *cent = pol->getCentroidCoord();
604  double area = pol->getArea();
605  if (area < (m_dist_min*m_dist_min) || !cent) //No conseguiu gerar centroide e area menor que tolerancia
606  {
607  std::cout << "Polygon ERROR 0" << polid << " area " << area << std::endl;
608  continue;
609  }
610 
611  te::gm::LineString *lin = GEOS_DouglasPeucker(dynamic_cast<te::gm::LineString*>(pol->getExteriorRing()), m_tol);
612  // te::gm::LineString *lin = dynamic_cast<te::gm::LineString*>(pol->getExteriorRing());
613 
614  if (lin->size() > 4)
615  {
616  te::gm::Polygon *pol_s = new te::gm::Polygon(0, te::gm::PolygonType, m_srid);
617  size_t npts = lin->getNPoints();
618  if (!lin->isClosed())
619  npts++;
620  te::gm::LinearRing *pol_ring = new te::gm::LinearRing( npts, te::gm::LineStringType, m_srid);
621  size_t i;
622  for (i = 0; i < lin->getNPoints(); i++)
623  {
624  te::gm::Coord2D p_d(lin->getCoordinates()[i]); //ponto do desflorestamento
625  m_pol_points.push_back(GAP_inter(polid, (int32_t)i, p_d.getX(), p_d.getY(), p_d.getX(), p_d.getY(), p_d.getX(), p_d.getY(),
626  0., 0., "desf", true));
627  pol_ring->setPointN(i, te::gm::Point(p_d.getX(), p_d.getY(), m_srid));
628  }
629  if (!pol_ring->isClosed())
630  pol_ring->setPointN(i, te::gm::Point(lin->getCoordinates()[0].getX(), lin->getCoordinates()[0].getY(), m_srid));
631  if (pol_ring->isClosed())
632  {
633  pol_s->push_back(pol_ring);
634  polsout.push_back(std::pair<int32_t, te::gm::Polygon *>(polid, pol_s));
635  }
636  delete lin;
637  }
638  else
639  {
640  std::cout << "ERROR 00 " << polid << std::endl;
641  delete lin;
642  continue;
643  }
644  }
645 
646  SavePol(polsout, "step00");
647 
648  m_pol_points.clear();
649  return true;
650 
651 }
652 
653 bool GAP::step0(std::vector< std::pair< size_t, te::gm::Polygon* > > &pols, std::vector< std::pair< size_t, te::gm::Polygon* > > &polsout)
654 {
655  std::vector<KD_NODE*> reportsnode;
656  std::map<double, te::gm::Coord2D> p_agreg;
657  // std::map< const te::gm::Coord2D, std::pair<size_t, double> > p_agreg_sel;
658  // std::map< const te::gm::Coord2D, std::pair<size_t, double> >::iterator it_agreg;
659  std::map< const te::gm::Coord2D, std::pair<size_t, double> > p_agreg_sel;
660  std::map< const te::gm::Coord2D, std::pair<size_t, double> >::iterator it_agreg;
661  std::vector<te::gm::Coord2D> pol_points;
662 
663  for (std::vector< std::pair<size_t, te::gm::Polygon*> >::iterator it = pols.begin(); it != pols.end(); it++) // Para cada poligono do desflorestamento
664  {
665  te::gm::Polygon *pol = it->second;
666  int32_t polid = (int32_t)it->first;
667  te::gm::Coord2D *cent = pol->getCentroidCoord();
668  double area = pol->getArea();
669  if (area < (m_dist_min*m_dist_min) || !cent) //No conseguiu gerar centroide e area menor que tolerancia
670  {
671  std::cout << "Polygon ERROR " << polid << " area " << area << std::endl;
672  continue;
673  }
674 
675  te::gm::LineString *lin = dynamic_cast<te::gm::LineString*>(pol->getExteriorRing());
676 
677  te::sam::rtree::Index<te::gm::Line*> rtree_pol; //rtree com os segmentos deste poligono
678  Polygon2RTree(pol, rtree_pol);
679 
680  //Procurar pontos do agregado que estejam na proximidade e externos aos pontos do desflorestamento
681  for (size_t i = 0; i < lin->getNPoints()-1; i++)
682  {
683  te::gm::Coord2D p_d(lin->getCoordinates()[i]); //ponto do desflorestamento
684 
685  te::gm::Envelope ept(p_d.x - m_dist_min, p_d.y - m_dist_min,
686  p_d.x + m_dist_min, p_d.y + m_dist_min);
687  m_nodetree->search(ept, reportsnode);
688 
689  for (size_t j = 0; j < reportsnode.size(); j++)
690  {
691  te::gm::Coord2D c = reportsnode[j]->getKey();
692  double dist = Distance(c, p_d);
693  if (dist < m_dist_min)
694  {
695  if (pointLocate(c, pol) != geos::geom::Location::INTERIOR)
696  {
697  p_agreg.insert(std::pair<double, te::gm::Coord2D>(dist, c)); //Ordena os pontos pela proximidade ao ponto do desflorestamento
698  }
699  }
700  }
701  if (p_agreg.size())
702  {
703  // const geos::geom::Coordinate c(p_agreg.begin()->second.x, p_agreg.begin()->second.y);
704  const te::gm::Coord2D c(p_agreg.begin()->second.x, p_agreg.begin()->second.y);
705  double d = Distance(p_agreg.begin()->second, p_d);
706  // it_agreg = std::find(p_agreg_sel.begin(), p_agreg_sel.end(), c);
707  for (it_agreg = p_agreg_sel.begin(); it_agreg != p_agreg_sel.end(); it_agreg++)
708  {
709  if ((*it_agreg).first == c)
710  break;
711  }
712 
713  if (it_agreg != p_agreg_sel.end())
714  {
715  if ((*it_agreg).second.first == 0 && i == lin->getNPoints() - 2) //first point and penultimate point
716  {
717  //ignore
718  p_agreg_sel.insert(std::pair<te::gm::Coord2D, std::pair<size_t, double> >(p_d, std::pair<size_t, double>(i, 0)));
719  }
720  else
721  if (d < (*it_agreg).second.second)
722  {
723  (*it_agreg).second.first = i;
724  (*it_agreg).second.second = d;
725  }
726  }
727  else
728  p_agreg_sel.insert(std::pair<te::gm::Coord2D, std::pair<size_t, double> >(c, std::pair<size_t, double>(i, d)));
729  }
730  p_agreg.clear();
731  reportsnode.clear();
732  }
733 
734  for (size_t i = 0; i < lin->getNPoints()-1; i++)
735  {
736  te::gm::Coord2D p_d(lin->getCoordinates()[i]); //ponto do desflorestamento
737 
738  for (it_agreg = p_agreg_sel.begin(); it_agreg != p_agreg_sel.end(); it_agreg++)
739  {
740  if ((*it_agreg).second.first == i)
741  break;
742  }
743  if (it_agreg != p_agreg_sel.end()) //
744  {
745  if ((*it_agreg).second.second == 0) //ignore
746  {
747  m_pol_points.push_back(GAP_inter(polid, (int32_t)i, p_d.getX(), p_d.getY(), p_d.getX(), p_d.getY(), p_d.getX(), p_d.getY(),
748  0., 0., "not_used", true));
749  continue;
750  }
751 
752  te::gm::Coord2D pp(it_agreg->first.x, it_agreg->first.y);
753  if (!verifyIntersections(p_d, pp, rtree_pol))
754  {
755  pol_points.push_back(pp); //Pega o ponto mais proximo
756  m_pol_points.push_back(GAP_inter(polid, (int32_t)i, p_d.getX(), p_d.getY(), p_d.getX(), p_d.getY(), pp.x, pp.y,
757  it_agreg->second.second, it_agreg->second.second, "agreg", true));
758  }
759  else
760  {
761  pol_points.push_back(p_d);
762  m_pol_points.push_back(GAP_inter(polid, (int32_t)i, p_d.getX(), p_d.getY(), p_d.getX(), p_d.getY(), p_d.getX(), p_d.getY(),
763  0., 0., "desf", true));
764  }
765  }
766  else
767  {
768  pol_points.push_back(p_d);
769  m_pol_points.push_back(GAP_inter(polid, (int32_t)i, p_d.getX(), p_d.getY(), p_d.getX(), p_d.getY(), p_d.getX(), p_d.getY(),
770  0., 0., "desf", true));
771  }
772  } //dos pontos do poligono
773 
774  p_agreg_sel.clear();
775 
776  if (pol_points.size() < 3)
777  {
778  std::cout << "Step0 - out Polygon ERROR " << polid << std::endl;
779  pol_points.clear();
780  continue;
781  }
782 
783  te::gm::Polygon *pol_new = new te::gm::Polygon(0, te::gm::PolygonType, m_srid);
784  te::gm::LinearRing *pol_ring = new te::gm::LinearRing(pol_points.size() + 1, te::gm::LineStringType, m_srid);
785  size_t pp;
786  for (pp = 0; pp < pol_points.size(); pp++)
787  pol_ring->setPointN(pp, te::gm::Point(pol_points[pp].getX(), pol_points[pp].getY(), m_srid));
788 
789  pol_ring->setPointN(pp, te::gm::Point(pol_points[0].getX(), pol_points[0].getY(), m_srid));
790 
791  pol_points.clear();
792 
793  pol_new->push_back(pol_ring);
794  if (pol_new->getArea() <= 0)
795  {
796  std::cout << "Step0 - ERROR " << polid << std::endl;
797  delete pol_new;
798  }
799  else
800  polsout.push_back(std::pair<int32_t, te::gm::Polygon *>(polid, pol_new));
801  } //dos poligonos
802 
803 
804  SavePol(polsout, "step0");
805 
806  m_pol_points.clear();
807  return true;
808 }
809 
810 // Move os pontos do desflorestamento para a borda do agregado (junta pelos vertices)
811 bool GAP::step1(std::vector< std::pair< size_t, te::gm::Polygon* > > &pols, std::vector< std::pair< size_t, te::gm::Polygon* > > &polsout)
812 {
813  std::vector<te::gm::Line*> reportline;
814  std::vector<te::gm::Coord2D> pol_points;
815  std::map< double, std::pair<size_t, te::gm::Coord2D> > map_seg;
816  std::map< double, std::pair<size_t, te::gm::Coord2D> > :: iterator it_seg;
817  std::map<const te::gm::Coord2D, std::pair<size_t, double> > map_pts_used;
818  std::map<const te::gm::Coord2D, std::pair<size_t, double> >::iterator it_pts_used;
819 
820  for (std::vector< std::pair<size_t, te::gm::Polygon*> >::iterator it = pols.begin(); it != pols.end(); it++) // Para cada poligono do desflorestamento
821  {
822  te::gm::Polygon *pol = it->second;
823  int32_t polid = (int32_t)it->first;
824  te::gm::LinearRing *lin = dynamic_cast<te::gm::LinearRing*>(pol->getExteriorRing());
825 
826  te::sam::rtree::Index<te::gm::Line*> rtree_pol; //rtree com os segmentos deste poligono
827  Polygon2RTree(pol, rtree_pol);
828 
829  for (size_t i = 0; i < lin->getNPoints()-1; i++) //Para cada ponto do desflorestamento
830  {
831  te::gm::Coord2D pt0 = lin->getCoordinates()[i];
832 
833  te::gm::Envelope ept(pt0.x - m_dist_min, pt0.y - m_dist_min,
834  pt0.x + m_dist_min, pt0.y + m_dist_min);
835  m_rtree.search(ept, reportline); //procura segmentos do agregado
836 
837  double dist;
838  if (!reportline.size()) //nao tem agregado proximo --> nao mexe no vertice
839  {
840  //pol_points.push_back(pt0);
841  //m_pol_points.push_back(GAP_inter(polid, (int32_t)i, pt0.getX(), pt0.getY(), pt0.getX(), pt0.getY(), pt0.getX(), pt0.getY(),
842  // 0., 0., "desf", true));
843  //continue;
844  }
845  else
846  {
847  bool addpt = false;
848  te::gm::Coord2D ptint;
849  size_t seg_sel = 0;
850 
851  //Pegar os segmentos do agregado e ordena-los pela distancia do p0 do desflorestamento
852  for (size_t rl = 0; rl < reportline.size(); rl++)
853  {
854  dist = coordToSegmentDistance(reportline[rl]->getCoordinates()[0], reportline[rl]->getCoordinates()[1], pt0, &ptint);
855  map_seg.insert(std::pair< double, std::pair<size_t, te::gm::Coord2D> >(dist, std::pair<size_t, te::gm::Coord2D>(rl, ptint)));
856  }
857 
858  for (it_seg = map_seg.begin(); it_seg != map_seg.end(); it_seg++)
859  {
860  dist = it_seg->first;
861  seg_sel = it_seg->second.first;
862  ptint = it_seg->second.second;
863  te::gm::Line *l_agreg = reportline[seg_sel];
864  bool achou = false;
865 
866  if (dist <= m_dist_min)
867  {
868  if (pointLocate(ptint, pol) != geos::geom::Location::INTERIOR)
869  {
870  if (!verifyIntersections(pt0, ptint, rtree_pol))
871  {
872  for (it_pts_used = map_pts_used.begin(); it_pts_used != map_pts_used.end(); it_pts_used++)
873  {
874  if ((*it_pts_used).first == ptint)
875  {
876  achou = true;
877  if (it_pts_used != map_pts_used.end()) //Tem outro ponto do desflorestametno com esse mesmo ponto de intersecção, usa o mais proximo
878  {
879  if (dist < it_pts_used->second.second)
880  it_pts_used->second.first = i;
881  }
882  }
883  } //for (it_pts_used = map_pts_used.begin(); it_pts_used != map_pts_used.end(); it_pts_used++)
884  if (!achou)
885  {
886  map_pts_used.insert(std::pair<te::gm::Coord2D, std::pair<size_t, double>>(ptint, std::pair<size_t, double>(i, dist)));
887  }
888  //else
889  //{
890  // pol_points.push_back(ptint);
891  // m_pol_points.push_back(GAP_inter(polid, (int32_t)i, pt0.getX(), pt0.getY(), ptint.getX(), ptint.getY(), ptint.getX(), ptint.getY(),
892  // dist, 0., "inter", true));
893  // addpt = true;
894  // break;
895  //}
896  }
897  }
898  }// if (dist <= m_dist_min)
899  } //for (it_seg = map_seg.begin(); it_seg != map_seg.end(); it_seg++)
900 
901  //if (!addpt)
902  //{
903  // pol_points.push_back(pt0);
904  // m_pol_points.push_back(GAP_inter(polid, (int32_t)i, pt0.getX(), pt0.getY(), pt0.getX(), pt0.getY(), pt0.getX(), pt0.getY(),
905  // 0., 0., "desf", true));
906  //}
907  map_seg.clear();
908  reportline.clear();
909  } //if (!reportline.size()) ... else
910  } //Para cada segmento do desflorestamento
911 
912  for (size_t i = 0; i < lin->getNPoints()-1; i++) //Para cada ponto do desflorestamento
913  {
914  bool addpt = false;
915  te::gm::Coord2D pt0 = lin->getCoordinates()[i];
916  for (it_pts_used = map_pts_used.begin(); it_pts_used != map_pts_used.end(); it_pts_used++)
917  {
918  if ((*it_pts_used).second.first == i)
919  {
920  pol_points.push_back(it_pts_used->first);
921  m_pol_points.push_back(GAP_inter(polid, (int32_t)i, pt0.getX(), pt0.getY(), pt0.getX(), pt0.getY(), it_pts_used->first.getX(), it_pts_used->first.getY(),
922  (*it_pts_used).second.second, 0., "agreg", true));
923  addpt = true;
924  break;
925  }
926  }
927  if (!addpt)
928  {
929  pol_points.push_back(pt0);
930  m_pol_points.push_back(GAP_inter(polid, (int32_t)i, pt0.getX(), pt0.getY(), pt0.getX(), pt0.getY(), pt0.getX(), pt0.getY(),
931  0., 0., "desf", true));
932  }
933  }
934  map_pts_used.clear();
935 
936 
937  if (pol_points.size() < 3)
938  {
939  std::cout << "Step1 - out Polygon ERROR " << polid << std::endl;
940  pol_points.clear();
941  continue;
942  }
943 
944  te::gm::Polygon *pol_new = new te::gm::Polygon(0, te::gm::PolygonType, m_srid);
945  te::gm::LinearRing *pol_ring = new te::gm::LinearRing(pol_points.size() + 1, te::gm::LineStringType, m_srid);
946  size_t pp;
947  for (pp = 0; pp < pol_points.size(); pp++)
948  pol_ring->setPointN(pp, te::gm::Point(pol_points[pp].getX(), pol_points[pp].getY(), m_srid));
949 
950  pol_ring->setPointN(pp, te::gm::Point(pol_points[0].getX(), pol_points[0].getY(), m_srid));
951 
952  pol_points.clear();
953 
954  pol_new->push_back(pol_ring);
955  if (pol_new->getArea() <= 0)
956  {
957  std::cout << "Step1 - ERROR " << polid << std::endl;
958  delete pol_new;
959  }
960  else
961  polsout.push_back(std::pair<int32_t, te::gm::Polygon *>(polid, pol_new));
962  } // Para cada poligono do desflorestamento
963 
964  SavePol(polsout, "step1");
965 
966  m_pol_points.clear();
967  return true;
968 }
969 
970 
971 //Add intersection points from agregado
972 bool GAP::step2(std::vector< std::pair< size_t, te::gm::Polygon* > > &pols, std::vector< std::pair< size_t, te::gm::Polygon* > > &polsout)
973 {
974  std::vector<te::gm::Coord2D> pt_out;
975  std::vector<te::gm::Line*> reportline;
976  std::map<double, te::gm::Coord2D> map_int;
977 
978  for (std::vector< std::pair<size_t, te::gm::Polygon*> >::iterator it = pols.begin(); it != pols.end(); it++) // Para cada poligono do desflorestamento
979  {
980  te::gm::Polygon *pol = it->second;
981  int32_t polid = (int32_t)it->first;
982  te::gm::LinearRing *lin = dynamic_cast<te::gm::LinearRing*>(pol->getExteriorRing());
983 
984  size_t i;
985  for (i = 0; i < lin->getNPoints() - 1; i++) //Cria segmento com os pontos da borda (i ~ i+1)
986  {
987  te::gm::Coord2D first(lin->getCoordinates()[i]);
988 
989  //if (std::find(pt_out.begin(), pt_out.end(), first) == pt_out.end()) //Não coloca pontos repetidos
990  {
991  pt_out.push_back(te::gm::Coord2D(first));
992  m_pol_points.push_back(GAP_inter(polid, (int32_t)i, first.getX(), first.getY(), first.getX(), first.getY(), first.getX(), first.getY(),
993  0., 0., "desf", true));
994  }
995  te::gm::Coord2D last(lin->getCoordinates()[i + 1]);
997  line->setCoord(0, first.getX(), first.getY());
998  line->setCoord(1, last.getX(), last.getY());
999  double dist01 = Distance(first, last);
1000  te::gm::Envelope ept(line->getMBR()->getLowerLeftX() - m_dist_min, line->getMBR()->getLowerLeftY() - m_dist_min,
1001  line->getMBR()->getUpperRightX() + m_dist_min, line->getMBR()->getUpperRightY() + m_dist_min);
1002  m_rtree.search(ept, reportline); //procura segmentos do agregado
1003  if (!reportline.size()) //não tem agregado próximo
1004  continue;
1005 
1006  te::gm::Coord2D ptint;
1007  for (size_t rl = 0; rl < reportline.size(); rl++)
1008  {
1009  if (segInterPoint(reportline[rl]->getCoordinates()[0], reportline[rl]->getCoordinates()[1], first, last, &ptint))
1010  {
1011  double dist = Distance(first, ptint);
1012  map_int.insert(std::pair<double, te::gm::Coord2D>(dist, te::gm::Coord2D(ptint)));
1013  }
1014  }
1015  for (std::map<double, te::gm::Coord2D>::iterator it = map_int.begin(); it != map_int.end(); it++)
1016  //if (std::find(pt_out.begin(), pt_out.end(), (*it).second) == pt_out.end()) //Não coloca pontos repetidos
1017  {
1018  pt_out.push_back(te::gm::Coord2D((*it).second));
1019  m_pol_points.push_back(GAP_inter(polid, (int32_t)i, (*it).second.getX(), (*it).second.getY(), (*it).second.getX(), (*it).second.getY(), (*it).second.getX(), (*it).second.getY(),
1020  (*it).first, 0., "agreg", true));
1021  }
1022 
1023  reportline.clear();
1024  map_int.clear();
1025  }
1026  pt_out.push_back(te::gm::Coord2D(lin->getCoordinates()[i])); //ultimo ponto para fechar poligono
1027 
1028  if (pt_out.size() < 3)
1029  {
1030  std::cout << "Step2 - out Polygon ERROR " << polid << std::endl;
1031  pt_out.clear();
1032  continue;
1033  }
1034 
1035  te::gm::Polygon *pol_new = new te::gm::Polygon(0, te::gm::PolygonType, m_srid);
1036  te::gm::LinearRing *pol_ring = new te::gm::LinearRing(pt_out.size() + 1, te::gm::LineStringType, m_srid);
1037  size_t pp;
1038  for (pp = 0; pp < pt_out.size(); pp++)
1039  {
1040  pol_ring->setPointN(pp, te::gm::Point(pt_out[pp].getX(), pt_out[pp].getY(), m_srid));
1041  m_nodetree_step2->insert(te::gm::Coord2D(pt_out[pp].getX(), pt_out[pp].getY()), std::pair<int32_t, int32_t>(polid, (int32_t)pp));
1042  }
1043 
1044  pol_ring->setPointN(pp, te::gm::Point(pt_out[0].getX(), pt_out[0].getY(), m_srid));
1045 
1046  pt_out.clear();
1047 
1048  pol_new->push_back(pol_ring);
1049  polsout.push_back(std::pair<int32_t, te::gm::Polygon *>(polid, pol_new));
1050  } // Para cada poligono do desflorestamento
1051 
1052  SavePol(polsout, "step2");
1053 
1054  m_pol_points.clear();
1055 
1056  return true;
1057 }
1058 
1059 bool GAP::step3(std::vector< std::pair< size_t, te::gm::Polygon* > > &pols, std::vector< std::pair< size_t, te::gm::Polygon* > > &polsout)
1060 {
1061  std::vector<KD_NODE*> reportsnode;
1062  std::vector<te::gm::Coord2D> pt_out;
1063  std::map< double, std::pair<te::gm::Coord2D, te::gm::Coord2D> > map_inter;
1064 
1066  std::vector< te::sam::kdtree::Node< te::gm::Coord2D, GAP_pt_extern, GAP_pt_extern > *> reportsnode_int;
1067 
1068  std::vector<int32_t> pts_to_remove;
1069 
1070  for (std::vector< std::pair<size_t, te::gm::Polygon*> >::iterator it = pols.begin(); it != pols.end(); it++) // Para cada poligono do desflorestamento
1071  {
1072  te::gm::Polygon *pol = it->second;
1073  int32_t polid = (int32_t)it->first;
1074  te::gm::LinearRing *lin = dynamic_cast<te::gm::LinearRing*>(pol->getExteriorRing());
1075  if (lin->getNPoints() < 4)
1076  {
1077  for (size_t i = 0; i < lin->getNPoints() - 1; i++)
1078  std::cout << "ERROR " << polid << " " << lin->getPointN(i)->getX() << " " << lin->getPointN(i)->getY() << std::endl;
1079  continue;
1080  }
1081 
1082  te::gm::Coord2D *cent = pol->getCentroidCoord();
1083  if (!cent) //poligono bixado
1084  {
1085  for (size_t i = 0; i < lin->getNPoints() - 1; i++)
1086  std::cout << "ERROR " << polid << " " << lin->getPointN(i)->getX() << " " << lin->getPointN(i)->getY() << std::endl;
1087  continue;
1088  }
1089 
1090  double area = pol->getArea();
1091  if (area <= 0)
1092  {
1093  std::cout << "ERROR " << polid << " area " << area << std::endl;
1094  continue;
1095  }
1096 
1097  te::gm::Envelope e;
1099  size_t i;
1100  //Procurar pontos do agregado que estejam na proximidade e externos ao desflorestamento
1101  for (i = 0; i < lin->getNPoints() - 1; i++) //Cria segmento com os pontos da borda (i ~ i+1)
1102  {
1103  te::gm::Coord2D first(lin->getCoordinates()[i]);
1104  te::gm::Coord2D last(lin->getCoordinates()[i + 1]);
1106  line->setCoord(0, first.getX(), first.getY());
1107  line->setCoord(1, last.getX(), last.getY());
1108 
1109  double dist01 = Distance(first, last);
1110  if (dist01 == 0)
1111  continue;
1112 
1113  te::gm::Envelope ept(line->getMBR()->getLowerLeftX() - m_dist_min, line->getMBR()->getLowerLeftY() - m_dist_min,
1114  line->getMBR()->getUpperRightX() + m_dist_min, line->getMBR()->getUpperRightY() + m_dist_min);
1115  m_nodetree->search(ept, reportsnode);
1116 
1117  for (size_t j = 0; j < reportsnode.size(); j++)
1118  {
1119  te::gm::Coord2D pint;
1120  te::gm::Coord2D c = reportsnode[j]->getKey();
1121 
1122  double distsc = coordToSegmentDistance(first, last, c, &pint); //Distance agregado point to desflorestamento segment
1123  if (distsc == 0.) continue;
1124 
1125  if (distsc < m_dist_min)
1126  {
1127  kdtree_int->search(te::gm::Envelope(c.x, c.y, c.x, c.y), reportsnode_int);
1128  if (reportsnode_int.size())
1129  {
1130  if (distsc <= reportsnode_int[0]->getData().m_dist)
1131  {
1132  if (!(Distance(pint, first) == 0. || Distance(pint, last) == 0.)) //Ponto de interseccao é o proprio ponto do segmento - ignora
1133  if (fabs(distsc - reportsnode_int[0]->getData().m_dist) < m_tol
1134  && (i - reportsnode_int[0]->getData().m_seg_id) == 1)
1135  //ponto do agregado exatamente entre dois segmentos consecutivos -> junta esses segmentos
1136  {
1137  pts_to_remove.push_back((int32_t)i);
1138  }
1139  else
1140  kdtree_int->insert(c, GAP_pt_extern(pint, (int32_t)i, distsc));
1141  }
1142  reportsnode_int.clear();
1143  continue;
1144  }
1145 
1146  // double dist0int = Distance(first, pint);
1147  double dist0c = Distance(first, c);
1148  if (/*dist01 > dist0c && */dist0c != 0) //pega só os pontos dentro da área de abrangencia do segmento (se o ponto estiver além do last não usa
1149  {
1150  if (Distance(pint, first) == 0. || Distance(pint, last) == 0.) //Ponto de interseccao é o proprio ponto do segmento - ignora
1151  continue;
1152 
1153  // if (isInside(first, last, c, *cent)) //So usa pontos fora do pol
1154  te::gm::Point pc(c.x, c.y, m_srid);
1155  if (pol->disjoint(dynamic_cast<te::gm::Geometry*>(&pc)))
1156  kdtree_int->insert(c, GAP_pt_extern(pint, (int32_t)i, distsc));
1157 
1158  reportsnode_int.clear();
1159  }
1160  }
1161  } // for (size_t j = 0; j < reportsnode.size(); j++)
1162  reportsnode.clear();
1163  } //for (i = 0; i < lin->getNPoints() - 1; i++)
1164 
1165  //Adds intersection points
1166  for (i = 0; i < lin->getNPoints() - 1; i++) //Cria segmento com os pontos da borda (i ~ i+1)
1167  {
1168  if (std::find(pts_to_remove.begin(), pts_to_remove.end(), i) != pts_to_remove.end()) //Este ponto não entra -> vide caso de juntar 2 segmentos
1169  continue;
1170 
1171  te::gm::Coord2D first(lin->getCoordinates()[i]);
1172  te::gm::Coord2D last(lin->getCoordinates()[i + 1]);
1174  line->setCoord(0, first.getX(), first.getY());
1175  line->setCoord(1, last.getX(), last.getY());
1176 
1177  //if (std::find(pt_out.begin(), pt_out.end(), first) == pt_out.end()) //Não coloca pontos repetidos
1178  {
1179  m_pol_points.push_back(GAP_inter(polid, (int32_t)i, first.getX(), first.getY(), first.getX(), first.getY(), lin->getPointN(i)->getX(), lin->getPointN(i)->getY(),
1180  0., 0., "desf", true));
1181  pt_out.push_back(te::gm::Coord2D(first));
1182  }
1183 
1184  double dist01 = Distance(first, last);
1185 
1186  te::gm::Envelope ept(line->getMBR()->getLowerLeftX() - m_dist_min, line->getMBR()->getLowerLeftY() - m_dist_min,
1187  line->getMBR()->getUpperRightX() + m_dist_min, line->getMBR()->getUpperRightY() + m_dist_min);
1188  kdtree_int->search(ept, reportsnode_int);
1189 
1190  if (reportsnode_int.size())
1191  {
1192  te::gm::Coord2D k_pint = reportsnode_int[0]->getData().m_ptint;
1193  double k_dist = reportsnode_int[0]->getData().m_dist;
1194  std::vector<size_t> k_sel;
1195  size_t j_sel;
1196  //Procurar pontos de intersecao repetidos,se achar usar o pont do agregado mais distante
1197  for (size_t j = 0; j < reportsnode_int.size(); j++)
1198  {
1199  if (reportsnode_int[j]->getData().m_seg_id == (int32_t)i)
1200  {
1201  te::gm::Coord2D k_pint = reportsnode_int[j]->getData().m_ptint;
1202  double k_dist = reportsnode_int[j]->getData().m_dist;
1203  j_sel = j;
1204 
1205  for (size_t jj = j; jj < reportsnode_int.size(); jj++)
1206  {
1207  if (Distance(k_pint, reportsnode_int[jj]->getData().m_ptint) < m_tol) //Achou mesmo ponto de interseccao
1208  {
1209  if (reportsnode_int[jj]->getData().m_dist > k_dist)
1210  {
1211  k_dist = reportsnode_int[jj]->getData().m_dist;
1212  j_sel = jj;
1213  }
1214  }
1215  }
1216  k_sel.push_back(j_sel);
1217  }
1218  }
1219 
1220  for (size_t j = 0; j < k_sel.size(); j++)
1221  {
1222  if (reportsnode_int[k_sel[j]]->getData().m_dist != 0)
1223  {
1224  double dist0int = Distance(first, reportsnode_int[k_sel[j]]->getData().m_ptint);
1225  if (dist0int < dist01)
1226  {
1227  map_inter.insert(std::pair< double, std::pair<te::gm::Coord2D, te::gm::Coord2D> >
1228  (dist0int, std::pair<te::gm::Coord2D, te::gm::Coord2D>(reportsnode_int[k_sel[j]]->getKey(), reportsnode_int[k_sel[j]]->getData().m_ptint)));
1229  }
1230  }
1231  }
1232  }
1233 
1234  for (std::map< double, std::pair<te::gm::Coord2D, te::gm::Coord2D> >::iterator it = map_inter.begin(); it != map_inter.end(); it++)
1235  {
1236  te::gm::Coord2D c = (*it).second.first;
1237  te::gm::Coord2D pint = (*it).second.second;
1238  bool inside = false;
1239  if (Distance(*cent, c) < Distance(*cent, pint))
1240  inside = true;
1241  // if (std::find(pt_out.begin(), pt_out.end(), c) == pt_out.end()) //Não coloca pontos repetidos
1242  {
1243  pt_out.push_back(te::gm::Coord2D(c));
1244  m_pol_points.push_back(GAP_inter(polid, (int32_t)i, first.getX(), first.getY(), pint.getX(), pint.getY(), c.getX(), c.getY(),
1245  Distance(first, c), dist01, "agreg", inside));
1246  }
1247  }
1248  map_inter.clear();
1249  reportsnode_int.clear();
1250  }
1251 
1252  pt_out.push_back(te::gm::Coord2D(lin->getCoordinates()[i]));
1253 
1254  delete kdtree_int;
1255  pts_to_remove.clear();
1256 
1257  if (pt_out.size() < 3 || (pt_out.size() == 3 && pt_out[0] == pt_out[2]))
1258  {
1259  pt_out.clear();
1260  std::cout << "ERROR " << polid << std::endl;
1261  continue;
1262  }
1263 
1264  te::gm::Polygon *pol_new = new te::gm::Polygon(0, te::gm::PolygonType, m_srid);
1265  te::gm::LinearRing *pol_ring = new te::gm::LinearRing(pt_out.size() + 1, te::gm::LineStringType, m_srid);
1266  size_t pp;
1267  for (pp = 0; pp < pt_out.size(); pp++)
1268  {
1269  // std::cout << polid << " " << pp << " " << pt_out[pp].getX() << " " << pt_out[pp].getY() << std::endl;
1270  pol_ring->setPointN(pp, te::gm::Point(pt_out[pp].getX(), pt_out[pp].getY(), m_srid));
1271  }
1272 
1273  pol_ring->setPointN(pp, te::gm::Point(pt_out[0].getX(), pt_out[0].getY(), m_srid));
1274  pt_out.clear();
1275 
1276  if (pol_ring->size() <= 3)
1277  {
1278  std::cout << "ERROR " << polid << std::endl;
1279  delete pol_ring;
1280  continue;
1281  }
1282  pol_new->push_back(pol_ring);
1283  if (pol_new->getArea() <= 0)
1284  {
1285  std::cout << "ERROR sem area " << polid << std::endl;
1286  delete pol_new;
1287  continue;
1288  }
1289 
1290  te::gm::Geometry* result = te::gm::Validate((dynamic_cast<te::gm::Geometry*>(pol_new)));
1291 
1292  if (result->getGeomTypeId() == te::gm::MultiPolygonType)
1293  {
1294  std::cout << "Step3 - Divide " << polid << std::endl;
1295  te::gm::MultiPolygon* mp = dynamic_cast<te::gm::MultiPolygon*>(result);
1296  for (size_t i = 0; i < mp->getNumGeometries(); i++)
1297  polsout.push_back(std::pair<size_t, te::gm::Polygon*>(polid, dynamic_cast<te::gm::Polygon*>(mp->getGeometryN(i))));
1298  }
1299  else
1300  polsout.push_back(std::pair<size_t, te::gm::Polygon*>(polid, pol_new));
1301 
1302  } //for (size_t p = 0; p < m_pols_2.size(); p++)
1303 
1304 
1305  return true;
1306 
1307 }
1308 
1309 
1310 // Move os pontos do desflorestamento para a borda do agregado (junta pelos vertices)
1311 bool GAP::step4(std::vector< std::pair< size_t, te::gm::Polygon* > > &pols, std::vector< std::pair< size_t, te::gm::Polygon* > > &polsout)
1312 {
1313  std::vector<te::gm::Line*> reportline, reportline_pol;
1314  std::vector<te::gm::Coord2D> pol_points;
1315  std::map<double, te::gm::Coord2D> map_inter;
1316 
1317  for (std::vector< std::pair<size_t, te::gm::Polygon*> >::iterator it = pols.begin(); it != pols.end(); it++) // Para cada poligono do desflorestamento
1318  {
1319  te::gm::Polygon *pol = it->second;
1320  int32_t polid = (int32_t)it->first;
1321  te::gm::LinearRing *lin = dynamic_cast<te::gm::LinearRing*>(pol->getExteriorRing());
1322 
1323  te::gm::Coord2D *cent = pol->getCentroidCoord();
1324  double area = pol->getArea();
1325  if (area < (m_dist_min*m_dist_min) || !cent) //No conseguiu gerar centroide e area menor que tolerancia
1326  {
1327  std::cout << "Polygon ERROR " << polid << " area " << area << std::endl;
1328  continue;
1329  }
1330 
1331  te::sam::rtree::Index<te::gm::Line*> rtree_pol; //rtree com os segmentos deste poligono
1332  Polygon2RTree(pol, rtree_pol);
1333 
1334  for (size_t i = 0; i < lin->getNPoints() - 1; i++) //Para cada segmento do desflorestamento
1335  {
1336  te::gm::Coord2D pt0 = lin->getCoordinates()[i];
1337  te::gm::Coord2D pt1 = lin->getCoordinates()[i + 1];
1338  double dist01 = Distance(pt0, pt1); //comprimento do segmento do desflorestamento
1339  if (dist01 == 0)
1340  continue;
1341 
1342  te::gm::Line *line_desf = new te::gm::Line(*lin->getPointN(i), *lin->getPointN(i + 1), te::gm::LineStringType, m_srid);
1343  te::gm::Envelope ept(line_desf->getMBR()->getLowerLeftX() - m_dist_min, line_desf->getMBR()->getLowerLeftY() - m_dist_min,
1344  line_desf->getMBR()->getUpperRightX() + m_dist_min, line_desf->getMBR()->getUpperRightY() + m_dist_min);
1345  m_rtree.search(ept, reportline); //procura segmentos do agregado
1346 
1347  double dist, dist_aux;
1348  if (!reportline.size()) //nao tem agregado proximo --> nao mexe no vertice
1349  {
1350  pol_points.push_back(pt0);
1351  m_pol_points.push_back(GAP_inter(polid, (int32_t)i, pt0.getX(), pt0.getY(), pt0.getX(), pt0.getY(), pt0.getX(), pt0.getY(),
1352  0., 0., "desf", true));
1353  continue;
1354  }
1355  else
1356  {
1357  bool addpt = false;
1358  te::gm::Coord2D ptint, ptint_aux;
1359  size_t seg_sel = 0;
1360  dist = coordToSegmentDistance(reportline[0]->getCoordinates()[0], reportline[0]->getCoordinates()[1], pt0, &ptint);
1361 
1362  //Pegar apenas o segmento do agregado mais proximo do p0 do desflorestamento e que naõ tenha sido usado anteriormente
1363  for (size_t rl = 1; rl < reportline.size(); rl++)
1364  {
1365  dist_aux = coordToSegmentDistance(reportline[rl]->getCoordinates()[0], reportline[rl]->getCoordinates()[1], pt0, &ptint_aux);
1366  if (dist_aux < dist)
1367  {
1368  dist = dist_aux;
1369  seg_sel = rl;
1370  ptint = ptint_aux;
1371  }
1372  }
1373 
1374  te::gm::Line *l_agreg = reportline[seg_sel];
1375 
1376  if (dist <= m_dist_min)
1377  {
1378  double distpt0 = Distance(pt0, reportline[seg_sel]->getCoordinates()[0]); //distancia de p0 do segmento do agregado do p0 do segmento do desflorestamento
1379  double distpt1 = Distance(pt0, reportline[seg_sel]->getCoordinates()[1]); //distancia de p1 do segmento do agregado do p0 do segmento do desflorestamento
1380  if (distpt0 < distpt1 && distpt0 < m_dist_min) //p0 mais proximo;
1381  {
1382  te::gm::Point pc(reportline[seg_sel]->getCoordinates()[0].x, reportline[seg_sel]->getCoordinates()[0].y, m_srid);
1383  if (pol->disjoint(dynamic_cast<te::gm::Geometry*>(&pc)))
1384  {
1385  te::gm::Line segp0pint(te::gm::Point(pt0.x, pt0.y), pc, te::gm::LineStringType, m_srid);
1386  te::gm::Envelope ept(segp0pint.getMBR()->getLowerLeftX() - m_tol, segp0pint.getMBR()->getLowerLeftY() - m_tol,
1387  segp0pint.getMBR()->getUpperRightX() + m_tol, segp0pint.getMBR()->getUpperRightY() + m_tol);
1388  rtree_pol.search(ept, reportline_pol); //procura segmentos do poligono
1389  bool temoutroseg = false;
1390  for (size_t pl = 0; pl < reportline_pol.size(); pl++)
1391  {
1392  if (!(reportline_pol[pl]->getCoordinates()[0] == pt0) && !(reportline_pol[pl]->getCoordinates()[1] == pt0)) //Não testa com ele mesmo
1393  {
1394  if (!reportline_pol[pl]->disjoint(dynamic_cast<te::gm::Geometry*>(&segp0pint)))
1395  temoutroseg = true;
1396  }
1397  }
1398 
1399  reportline_pol.clear();
1400  if (!temoutroseg)
1401  {
1402  pol_points.push_back(reportline[seg_sel]->getCoordinates()[0]);
1403  m_pol_points.push_back(GAP_inter(polid, (int32_t)i, pt0.getX(), pt0.getY(), ptint.getX(), ptint.getY(), reportline[seg_sel]->getCoordinates()[0].getX(), reportline[seg_sel]->getCoordinates()[0].getY(),
1404  dist, distpt0, "agreg0", true));
1405  addpt = true;
1406  }
1407  }
1408  }
1409  else if (distpt1 < distpt0 && distpt1 < m_dist_min) //p1 mais proximo;
1410  {
1411  te::gm::Point pc(reportline[seg_sel]->getCoordinates()[1].x, reportline[seg_sel]->getCoordinates()[1].y, m_srid);
1412  if (pol->disjoint(dynamic_cast<te::gm::Geometry*>(&pc)))
1413  {
1414  te::gm::Line segp0pint(te::gm::Point(pt0.x, pt0.y), pc, te::gm::LineStringType, m_srid);
1415  te::gm::Envelope ept(segp0pint.getMBR()->getLowerLeftX() - m_tol, segp0pint.getMBR()->getLowerLeftY() - m_tol,
1416  segp0pint.getMBR()->getUpperRightX() + m_tol, segp0pint.getMBR()->getUpperRightY() + m_tol);
1417  rtree_pol.search(ept, reportline_pol); //procura segmentos do poligono
1418  bool temoutroseg = false;
1419  for (size_t pl = 0; pl < reportline_pol.size(); pl++)
1420  {
1421  if (!(reportline_pol[pl]->getCoordinates()[0] == pt0) && !(reportline_pol[pl]->getCoordinates()[1] == pt0)) //Não testa com ele mesmo
1422  {
1423  if (!reportline_pol[pl]->disjoint(dynamic_cast<te::gm::Geometry*>(&segp0pint)))
1424  temoutroseg = true;
1425  }
1426  }
1427 
1428  reportline_pol.clear();
1429  if (!temoutroseg)
1430  {
1431  pol_points.push_back(reportline[seg_sel]->getCoordinates()[1]);
1432  m_pol_points.push_back(GAP_inter(polid, (int32_t)i, pt0.getX(), pt0.getY(), ptint.getX(), ptint.getY(), reportline[seg_sel]->getCoordinates()[1].getX(), reportline[seg_sel]->getCoordinates()[1].getY(),
1433  dist, distpt1, "agreg1", true));
1434  addpt = true;
1435  }
1436  }
1437  }
1438  if (!addpt)
1439  {
1440  double distpt0_int = Distance(pt0, ptint);
1441  if (distpt0_int < m_dist_min)
1442  {
1443  te::gm::Point pc(ptint.x, ptint.y, m_srid);
1444 
1445  if (pointLocate(ptint, pol) != geos::geom::Location::INTERIOR)
1446  //double distlin_pint = coordToSegmentDistance(pt0, pt1, ptint, 0);
1447  //if (!pol->contains(dynamic_cast<te::gm::Geometry*>(&pc)) || distlin_pint <= m_tol) //Inserts if point is not inside or is boundary
1448  // if (!isInside(pt0, pt1, ptint, *cent))
1449  //if (pol->disjoint(dynamic_cast<te::gm::Geometry*>(&pc)))
1450  {
1451  te::gm::Line segp0pint(te::gm::Point(pt0.x, pt0.y), pc, te::gm::LineStringType, m_srid);
1452  te::gm::Envelope ept(segp0pint.getMBR()->getLowerLeftX() - m_tol, segp0pint.getMBR()->getLowerLeftY() - m_tol,
1453  segp0pint.getMBR()->getUpperRightX() + m_tol, segp0pint.getMBR()->getUpperRightY() + m_tol);
1454  rtree_pol.search(ept, reportline_pol); //procura segmentos do poligono
1455  bool temoutroseg = false;
1456  for (size_t pl = 0; pl < reportline_pol.size(); pl++)
1457  {
1458  if (!(reportline_pol[pl]->getCoordinates()[0] == pt0) && !(reportline_pol[pl]->getCoordinates()[1] == pt0)) //Não testa com ele mesmo
1459  {
1460  if (reportline_pol[pl]->intersects(dynamic_cast<te::gm::Geometry*>(&segp0pint)))
1461  temoutroseg = true;
1462  }
1463  }
1464 
1465  reportline_pol.clear();
1466  if (!temoutroseg)
1467  {
1468  pol_points.push_back(ptint);
1469  m_pol_points.push_back(GAP_inter(polid, (int32_t)i, pt0.getX(), pt0.getY(), ptint.getX(), ptint.getY(), ptint.getX(), ptint.getY(),
1470  dist, 0., "inter", true));
1471  addpt = true;
1472  }
1473  }
1474  else //calcula intersecção dos segmentos
1475  {
1476  if (segInterPoint(reportline[seg_sel]->getCoordinates()[0], reportline[seg_sel]->getCoordinates()[1], pt0, pt1, &ptint))
1477  {
1478  te::gm::Line segp0pint(te::gm::Point(pt0.x, pt0.y), pc, te::gm::LineStringType, m_srid);
1479  rtree_pol.search(*segp0pint.getMBR(), reportline_pol); //procura segmentos do poligono
1480  bool temoutroseg = false;
1481  for (size_t pl = 0; pl < reportline_pol.size(); pl++)
1482  {
1483  if (!(reportline_pol[pl]->getCoordinates()[0] == pt0) && !(reportline_pol[pl]->getCoordinates()[1] == pt0)) //Não testa com ele mesmo
1484  {
1485  if (!reportline_pol[pl]->disjoint(dynamic_cast<te::gm::Geometry*>(&segp0pint)))
1486  temoutroseg = true;
1487  }
1488  }
1489 
1490  reportline_pol.clear();
1491  if (!temoutroseg)
1492  {
1493  pol_points.push_back(ptint);
1494  m_pol_points.push_back(GAP_inter(polid, (int32_t)i, pt0.getX(), pt0.getY(), ptint.getX(), ptint.getY(), ptint.getX(), ptint.getY(),
1495  dist, 0., "inter", true));
1496  addpt = true;
1497  }
1498  }
1499  }
1500  }
1501  }
1502  } // if (dist <= m_dist_min)
1503  if (!addpt)
1504  {
1505  pol_points.push_back(pt0);
1506  m_pol_points.push_back(GAP_inter(polid, (int32_t)i, pt0.getX(), pt0.getY(), pt0.getX(), pt0.getY(), pt0.getX(), pt0.getY(),
1507  0., 0., "desf", true));
1508  }
1509  reportline.clear();
1510  } //if (!reportline.size()) ... else
1511  } //Para cada segmento do desflorestamento
1512 
1513  //std::unique(pol_points.begin(), pol_points.end());
1514 
1515  if (pol_points.size() < 3)
1516  {
1517  std::cout << "Step4 - out Polygon ERROR " << polid << std::endl;
1518  pol_points.clear();
1519  continue;
1520  }
1521 
1522  te::gm::Polygon *pol_new = new te::gm::Polygon(0, te::gm::PolygonType, m_srid);
1523  te::gm::LinearRing *pol_ring = new te::gm::LinearRing(pol_points.size() + 1, te::gm::LineStringType, m_srid);
1524  size_t pp;
1525  for (pp = 0; pp < pol_points.size(); pp++)
1526  pol_ring->setPointN(pp, te::gm::Point(pol_points[pp].getX(), pol_points[pp].getY(), m_srid));
1527 
1528  pol_ring->setPointN(pp, te::gm::Point(pol_points[0].getX(), pol_points[0].getY(), m_srid));
1529 
1530  pol_points.clear();
1531 
1532  pol_new->push_back(pol_ring);
1533  if (pol_new->getArea() <= 0)
1534  {
1535  std::cout << "Step4 - ERROR " << polid << std::endl;
1536  delete pol_new;
1537  }
1538  else
1539  polsout.push_back(std::pair<int32_t, te::gm::Polygon *>(polid, pol_new));
1540  } // Para cada poligono do desflorestamento
1541 
1542  return true;
1543 }
1544 
1545 
1546 
1547 bool GAP::SavePol(std::vector< std::pair<size_t, te::gm::Polygon*> >& pols, std::string step)
1548 {
1549  std::string pol("poly_all");
1550  std::string pt("point_all");
1551  std::string dir("D:/Dados_GAP/");
1552  m_filenameout = dir + pol + step + ".shp";
1553  m_inDSout = pol + step;
1554  std::string connInfo("file://");
1555  connInfo += m_filenameout;
1557  Dspol->open();
1558  std::string polDS;
1559  polDS = pol + step;
1560  if (Dspol->dataSetExists(polDS))
1561  {
1562  std::cout << "A dataset with the same requested output dataset name already exists: " << polDS << std::endl;
1563  return false;
1564  }
1565 
1566  std::unique_ptr<te::da::DataSetType> dtp(new te::da::DataSetType(polDS));
1568  p0->setAutoNumber(true);
1573  p1->setSRID(m_srid);
1574  dtp->add(p0);
1575  dtp->add(pidori);
1576  dtp->add(pori);
1577  dtp->add(pnew);
1578  dtp->add(p1);
1579  te::mem::DataSet* dsp = new te::mem::DataSet(dtp.get());
1580 
1581  std::string connInfo("file://");
1582  std::string filenamept = dir + pt + step + ".shp";
1583  connInfo += filenamept;
1584 
1586 
1587  Dspt->open();
1588  std::string ptDS;
1589  ptDS = pt + step;
1590  if (Dspt->dataSetExists(ptDS))
1591  {
1592  std::cout << "A dataset with the same requested output dataset name already exists: " << ptDS << std::endl;
1593  return false;
1594  }
1595 
1596  std::unique_ptr<te::da::DataSetType> dtpt(new te::da::DataSetType(ptDS));
1598  prop0->setAutoNumber(true);
1612  prop1->setSRID(m_srid);
1613  dtpt->add(prop0);
1614  dtpt->add(propid);
1615  dtpt->add(propptid);
1616  dtpt->add(propdist0);
1617  dtpt->add(propdist00);
1618  dtpt->add(propx);
1619  dtpt->add(propy);
1620  dtpt->add(propxi);
1621  dtpt->add(propyi);
1622  dtpt->add(propxn);
1623  dtpt->add(propyn);
1624  dtpt->add(propt);
1625  dtpt->add(propr);
1626  dtpt->add(prop1);
1627  te::mem::DataSet* dspt = new te::mem::DataSet(dtpt.get());
1628 
1629  int32_t id = 0;
1630  for (std::vector< std::pair<size_t, te::gm::Polygon*> >::iterator it = pols.begin(); it != pols.end(); it++)
1631  {
1632  te::gm::Polygon *pol = it->second;
1633  te::mem::DataSetItem* dataSetItem = new te::mem::DataSetItem(dsp);
1634  dataSetItem->setInt32("FID", id++);
1635  dataSetItem->setInt32("FIDoriginal", (int32_t)it->first);
1636  dataSetItem->setDouble("Areaoriginal", m_original_area[(int32_t)it->first]);
1637  dataSetItem->setDouble("Areanew", pol->getArea());
1638  dataSetItem->setGeometry("geometry", dynamic_cast<te::gm::Geometry*>(pol->clone()));
1639  dsp->add(dataSetItem);
1640 
1641  // te::gm::LinearRing *lin = dynamic_cast<te::gm::LinearRing*>(pols[ii]->getExteriorRing());
1642 
1643  }
1644 
1645  for (size_t pp = 0; pp < m_pol_points.size(); pp++)
1646  {
1647  te::mem::DataSetItem* dataSetItem = new te::mem::DataSetItem(dspt);
1648  dataSetItem->setInt32("FID", (int32_t)pp);
1649  dataSetItem->setInt32("POLID", m_pol_points[pp].m_polid);
1650  dataSetItem->setInt32("ptorder", m_pol_points[pp].m_ptid);
1651  dataSetItem->setDouble("dist0", m_pol_points[pp].m_distance);
1652  dataSetItem->setDouble("dist00", m_pol_points[pp].m_distance0);
1653  dataSetItem->setDouble("x", m_pol_points[pp].m_x);
1654  dataSetItem->setDouble("y", m_pol_points[pp].m_y);
1655  dataSetItem->setDouble("xint", m_pol_points[pp].m_xint);
1656  dataSetItem->setDouble("yint", m_pol_points[pp].m_yint);
1657  dataSetItem->setDouble("newx", m_pol_points[pp].m_xnew);
1658  dataSetItem->setDouble("newy", m_pol_points[pp].m_ynew);
1659  dataSetItem->setString("tipo", m_pol_points[pp].m_tipo);
1660  dataSetItem->setInt32("inside", (m_pol_points[pp].m_inside) ? 0 : 1);
1661  dataSetItem->setGeometry("pt", dynamic_cast<te::gm::Geometry*>(new te::gm::Point(m_pol_points[pp].m_xnew, m_pol_points[pp].m_ynew)));
1662  dspt->add(dataSetItem);
1663  }
1664  Save(Dspol.get(), dsp, dtp.get());
1665  Save(Dspt.get(), dspt, dtpt.get());
1666 
1667  // pols.clear();
1668 
1669 
1670  return true;
1671 
1672 }
1673 
1674 //verifing and removing loops in borderline
1675 void GAP::verify_polygon(std::vector<te::gm::Coord2D> &pt_out)
1676 {
1679  te::gm::Point pint;
1680 
1681  double x0 = pt_out[0].x; //Initial point
1682  double y0 = pt_out[0].y;
1683 
1684  for (size_t i = 0; i < pt_out.size() - 1; i++)
1685  {
1686  l0.setCoord(0, pt_out[i].x, pt_out[i].y);
1687  l0.setCoord(1, pt_out[i+1].x, pt_out[i+1].y);
1688  for (size_t ii = i; ii < pt_out.size() - 1; ii++)
1689  {
1690  l1.setCoord(0, pt_out[ii].x, pt_out[ii].y);
1691  l1.setCoord(1, pt_out[ii + 1].x, pt_out[ii + 1].y);
1692  if (l0.intersection(l1, pint))
1693  {
1694  if ((pint.getX() == l0.getCoordinates()[0].getX() && pint.getY() == l0.getCoordinates()[0].getY()) ||
1695  (pint.getX() == l0.getCoordinates()[1].getX() && pint.getY() == l0.getCoordinates()[1].getY()) ||
1696  pint.getX() == x0 && pint.getY() == y0)
1697  continue;
1698  else //remove points that tracing the loop
1699  {
1700  for (size_t j = i + 1; (j < ii && j < pt_out.size()-1); j++)
1701  pt_out.erase(pt_out.begin() + j);
1702  break;
1703  }
1704  }
1705  }
1706  }
1707 }
1708 
1710 {
1711  std::vector<te::gm::Line*> reportline_pol;
1712  bool temoutroseg = false;
1713  size_t n_pts = 0;
1714 
1715  te::gm::Point pc(ptint.x, ptint.y, m_srid);
1716  te::gm::Line segp0pint(te::gm::Point(pt0.x, pt0.y), pc, te::gm::LineStringType, m_srid);
1717  rtree_pol.search(*segp0pint.getMBR(), reportline_pol); //procura segmentos do poligono
1718  for (size_t pl = 0; pl < reportline_pol.size(); pl++)
1719  {
1720  if (!(reportline_pol[pl]->getCoordinates()[0] == pt0) && !(reportline_pol[pl]->getCoordinates()[1] == pt0)) //Não testa com ele mesmo
1721  {
1722  if (reportline_pol[pl]->intersects(dynamic_cast<te::gm::Geometry*>(&segp0pint)))
1723  {
1724  te::gm::Coord2D pint_agreg;
1725  te::gm::Coord2D p0 = reportline_pol[pl]->getCoordinates()[0];
1726  te::gm::Coord2D p1 = reportline_pol[pl]->getCoordinates()[1];
1727  double dist = coordToSegmentDistance(p0, p1, ptint, &pint_agreg);
1728  if (pint_agreg == p0 || pint_agreg == p1)
1729  {
1730  n_pts++;
1731  continue;
1732  }
1733  if (dist < segp0pint.getLength())
1734  temoutroseg = true;
1735  }
1736  }
1737  }
1738 
1739  if (n_pts>1)
1740  temoutroseg = true;
1741 
1742  reportline_pol.clear();
1743  return temoutroseg;
1744 
1745 }
1746 
1747 
1749 {
1750  const geos::geom::Coordinate p(pt.x, pt.y);
1751  std::unique_ptr<geos::geom::Geometry> geos_pol(te::gm::GEOSWriter::write(dynamic_cast<te::gm::Geometry*>(pol)));
1752  geos::geom::GeometryFactory factory;
1753  geos::geom::Point* geos_pt = factory.createPoint(p);
1754  double dist = geos_pol->getBoundary()->distance(geos_pt);
1755  delete geos_pt;
1756  if (dist < 0.1e-12)
1757  return geos::geom::Location::BOUNDARY;
1758 
1759  geos::algorithm::PointLocator loc;
1760  return loc.locate(p, geos_pol.get());
1761 }
void insert(const kdKey &key, const kdDataItem &item)
It inserts the data with a given key in tree.
std::size_t getNumRings() const
It returns the number of rings in this CurvePolygon.
Definition: CurvePolygon.h:153
void setAutoNumber(bool a)
It tells if the property is an autonumber or not.
std::size_t getNumGeometries() const
It returns the number of geometries in this GeometryCollection.
int pointLocate(te::gm::Coord2D &pt, te::gm::Polygon *pol)
Definition: GAP.cpp:1748
TEXSDEXPORT void Save(All *all, te::xml::AbstractWriter &writer)
void push_back(Curve *ring)
It adds the curve to the curve polygon.
MultiPolygon is a MultiSurface whose elements are Polygons.
Definition: MultiPolygon.h:50
static std::unique_ptr< DataSource > make(const std::string &driver, const te::core::URI &connInfo)
Geometric property.
double coordToSegmentDistance(te::gm::Coord2D &fseg, te::gm::Coord2D &lseg, te::gm::Coord2D &pt, te::gm::Coord2D *pti)
Definition: GAP.cpp:238
void setGeometry(std::size_t i, te::gm::Geometry *value)
It sets the value of the i-th property.
A Line is LineString with 2 points.
Definition: Line.h:50
virtual std::unique_ptr< DataSourceTransactor > getTransactor()=0
It returns the set of parameters used to set up the access channel to the underlying repository...
void setSRID(int srid)
It sets the spatial reference system identifier associated to this property.
double y
y-coordinate.
Definition: Coord2D.h:114
void setDouble(std::size_t i, double value)
It sets the value of the i-th property.
An atomic property like an integer or double.
te::gm::Coord2D appGetCenterPointOfPoints(std::vector< te::gm::Coord2D > &pts)
Definition: GAP.cpp:16
void setSRID(int srid)
It sets the Spatial Reference System ID of the geometry and all its parts if it is a GeometryCollecti...
bool step2(std::vector< std::pair< size_t, te::gm::Polygon * > > &pols, std::vector< std::pair< size_t, te::gm::Polygon * > > &polsout)
Definition: GAP.cpp:972
boost::shared_ptr< DataSource > DataSourcePtr
Coord2D * getCoordinates() const
It returns a pointer to the internal array of coordinates.
Definition: LineString.h:456
bool step3(std::vector< std::pair< size_t, te::gm::Polygon * > > &pols, std::vector< std::pair< size_t, te::gm::Polygon * > > &polsout)
Definition: GAP.cpp:1059
static te::dt::Date dx(2010, 12, 31)
double x
x-coordinate.
Definition: Coord2D.h:113
bool step00(std::vector< std::pair< size_t, te::gm::Polygon * > > &polsout)
Definition: GAP.cpp:597
A class that models the description of a dataset.
Definition: DataSetType.h:72
te::gm::LineString * GEOS_DouglasPeucker(te::gm::LineString *ls, double snap)
Definition: GAP.cpp:261
virtual double getLength() const
The length of this curve in the unit associated to its spatial reference system.
virtual void createDataSet(DataSetType *dt, const std::map< std::string, std::string > &options)
It creates the dataset schema definition in the target data source.
GeomType getGeomTypeId() const _NOEXCEPT_OP(true)
It returns the geometry subclass type identifier.
bool step1(std::vector< std::pair< size_t, te::gm::Polygon * > > &pols, std::vector< std::pair< size_t, te::gm::Polygon * > > &polsout)
Definition: GAP.cpp:811
const double & getUpperRightX() const
It returns a constant refernce to the x coordinate of the upper right corner.
te::gm::Coord2D c
Definition: GAP.cpp:59
Curve * getExteriorRing() const
It returns the exterior ring of this CurvePolygon.
TEDATAACCESSEXPORT std::size_t GetPropertyPos(const DataSet *dataset, const std::string &name)
int32_t m_ptid
Definition: GAP.h:54
virtual void add(const std::string &datasetName, DataSet *d, const std::map< std::string, std::string > &options, std::size_t limit=0)
It adds data items to the dataset in the data source.
std::unique_ptr< Point > getPointN(std::size_t i) const
It returns the specified point in this LineString.
virtual bool disjoint(const Geometry *const rhs) const _NOEXCEPT_OP(false)
It returns true if the geometry object is spatially disjoint from rhs geometry.
bool intersection(const Line &line, Point &coord) const
Definition: Line.cpp:87
const double & getLowerLeftY() const
It returns a constant refernce to the y coordinate of the lower left corner.
bool Polygon2Points(te::gm::Polygon *pol, int32_t id)
Definition: GAP.cpp:399
double m_distance
Definition: GAP.h:61
An utility struct for representing 2D coordinates.
Definition: Coord2D.h:40
double getY() const
It returns the y-coordinate.
Definition: Coord2D.h:108
bool LoadPolygons(std::string &filename, std::string &inDsetName, Pol_OUT out)
Definition: GAP.cpp:449
An abstract class for data providers like a DBMS, Web Services or a regular file. ...
const double & getUpperRightY() const
It returns a constant refernce to the x coordinate of the upper right corner.
te::gm::Point * pt2
bool isClosed() const
It returns true if the curve is closed (startPoint = endPoint).
void add(DataSetItem *item)
It adds a new item to the dataset and takes its ownership.
virtual std::string getType() const =0
It returns the data source type name (in UPPER CASE). Ex: POSTGIS, SQLITE, WFS, WMS, or MYSQL.
unsigned int line
virtual te::dt::AbstractData * clone() const
It clones the linestring.
void setInt32(std::size_t i, boost::int32_t value)
It sets the value of the i-th property.
int b
Definition: TsRtree.cpp:32
A LinearRing is a LineString that is both closed and simple.
Definition: LinearRing.h:53
Implementation of a random-access dataset class for the TerraLib In-Memory Data Access driver...
bool operator==(const GAP_inter &)
Definition: GAP.cpp:301
int getSRID() const _NOEXCEPT_OP(true)
It returns the Spatial Reference System ID associated to this geometric object.
Pol_OUT
Definition: GAP.h:30
LineString is a curve with linear interpolation between points.
Definition: LineString.h:62
double m_ynew
Definition: GAP.h:60
Definition: GAP.h:34
const double & getY() const
It returns the Point y-coordinate value.
Definition: Point.h:152
A point with x and y coordinate values.
Definition: Point.h:50
const Envelope * getMBR() const _NOEXCEPT_OP(true)
It returns the minimum bounding rectangle for the geometry in an internal representation.
void setPoint(std::size_t i, const double &x, const double &y)
It sets the value of the specified point.
An Envelope defines a 2D rectangular region.
te::gm::Point * pt1
void DataSet()
static te::dt::DateTime d(2010, 8, 9, 15, 58, 39)
bool step0(std::vector< std::pair< size_t, te::gm::Polygon * > > &pols, std::vector< std::pair< size_t, te::gm::Polygon * > > &polsout)
Definition: GAP.cpp:653
void verify_polygon(std::vector< te::gm::Coord2D > &pt_out)
Definition: GAP.cpp:1675
te::gm::Polygon * p
void setCoord(int index, double x, double y, double z=0., double m=0.)
Definition: Line.cpp:114
float coef_angular(double fx, double fy, double lx, double ly)
Definition: GAP.cpp:84
std::size_t getNPoints() const
It returns the number of points (vertexes) in the linestring.
Definition: LineString.h:193
A class that represents a two dimensional K-d Tree (2-d Tree).
int search(const te::gm::Envelope &mbr, std::vector< DATATYPE > &report) const
Range search query.
bool isInside(te::gm::Coord2D &first, te::gm::Coord2D &last, te::gm::Coord2D &c, te::gm::Coord2D &cent)
Definition: GAP.cpp:94
double SegmentDistance(double fx, double fy, double lx, double ly, double ptx, double pty, double *pix, double *piy)
Function that evaluates the distance between a point and a segment.
Definition: GAP.cpp:185
static geos::geom::Geometry * write(const Geometry *teGeom)
It reads a TerraLib geometry and make a GEOS geometry.
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.
GAP()
Definition: GAP.cpp:525
A class that converts a TerraLib geometry to a GEOS geometry.
bool Polygon2RTree(te::gm::Polygon *pol, te::sam::rtree::Index< te::gm::Line * > &rtree)
Definition: GAP.cpp:414
bool run()
Definition: GAP.cpp:545
double getArea() const
It returns the area of this surface, as measured in the spatial reference system of this surface...
double Distance(const double pt1x, const double pt1y, const double pt2x, const double pt2y)
Definition: GAP.cpp:63
Geometry * getGeometryN(std::size_t i) const
It returns the n-th geometry in this GeometryCollection.
bool verifyIntersections(te::gm::Coord2D &pt0, te::gm::Coord2D &pc, te::sam::rtree::Index< te::gm::Line * > &rtree_pol)
Definition: GAP.cpp:1709
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.
Polygon is a subclass of CurvePolygon whose rings are defined by linear rings.
Definition: Polygon.h:50
double getX() const
It returns the x-coordinate.
Definition: Coord2D.h:102
Definition: GAP.h:35
te::sam::kdtree::Index< KD_NODE > KD_TREE
Definition: GAP.h:28
Definition: GAP.h:33
void insert(const te::gm::Envelope &mbr, const DATATYPE &data)
It inserts an item into the tree.
void clear()
It clears all tree nodes.
void insert_inter(GAP_inter *inter)
Definition: GAP.cpp:347
virtual bool moveBeforeFirst()=0
It moves the internal pointer to a position before the first item in the collection.
const double & getLowerLeftX() const
It returns a constant reference to the x coordinate of the lower left corner.
Coord2D * getCentroidCoord() const
It returns the mathematical centroid for this surface as a coordinate.
bool Polygon2Lines(te::gm::Polygon *pol)
Definition: GAP.cpp:433
te::gm::LineString * l1
bool operator<(const GAP_inter &)
Definition: GAP.cpp:288
void setPointN(std::size_t i, const Point &p)
It sets the value of the specified point to this new one.
TEDATAACCESSEXPORT std::size_t GetFirstPropertyPos(const te::da::DataSet *dataset, int datatype)
Definition: GAP.h:38
void setString(std::size_t i, const std::string &value)
It sets the value of the i-th property.
double m_xnew
Definition: GAP.h:59
void search(const te::gm::Envelope &e, std::vector< KdTreeNode * > &report) const
Range search query.
bool SavePol(std::vector< std::pair< size_t, te::gm::Polygon * > > &pols, std::string step)
Definition: GAP.cpp:1547
bool operator()(te::gm::Coord2D &a, te::gm::Coord2D &b)
Definition: GAP.cpp:33
bool step4(std::vector< std::pair< size_t, te::gm::Polygon * > > &pols, std::vector< std::pair< size_t, te::gm::Polygon * > > &polsout)
Definition: GAP.cpp:1311
bool isInside(te::gm::Coord2D &pt)
Definition: GAP.cpp:307
void Save(te::da::DataSource *source, te::da::DataSet *result, te::da::DataSetType *outDsType)
Definition: GAP.cpp:352
bool segInterPoint(te::gm::Coord2D &pfr, te::gm::Coord2D &pto, te::gm::Coord2D &lfr, te::gm::Coord2D &lto, te::gm::Coord2D *pt)
Definition: GAP.cpp:141
const double & getX() const
It returns the Point x-coordinate value.
Definition: Point.h:138
TEGEOMEXPORT te::gm::Geometry * Validate(te::gm::Geometry *geom)
Get/create a valid version of the geometry given. If the geometry is a polygon or multi polygon...
sortpoints(te::gm::Coord2D &pt)
Definition: GAP.cpp:31
Curve * getRingN(std::size_t i) const
It returns the n-th ring for this curve polygon as a curve.
Definition: CurvePolygon.h:193
std::size_t size() const
It returns the number of points (vertexes) in the geometry.
Definition: LineString.h:262
const std::string & getName() const
It returns the property name.
Definition: Property.h:127