PGROUTING  3.2
alphaShape_driver.cpp File Reference
#include "drivers/alpha_shape/alphaShape_driver.h"
#include <cmath>
#include <vector>
#include <string>
#include <utility>
#include <algorithm>
#include "cpp_common/pgr_assert.h"
#include "alphaShape/pgr_alphaShape.h"
#include "cpp_common/pgr_alloc.hpp"
#include "cpp_common/pgr_base_graph.hpp"
#include "cpp_common/bpoint.hpp"
#include "cpp_common/bline.hpp"
#include <boost/geometry/io/wkt/write.hpp>
Include dependency graph for alphaShape_driver.cpp:

Go to the source code of this file.

Namespaces

 anonymous_namespace{alphaShape_driver.cpp}
 this file is not compiled with boost 1.53 or less
 

Functions

bool anonymous_namespace{alphaShape_driver.cpp}::data_eq (const Pgr_edge_xy_t &lhs, const Pgr_edge_xy_t &rhs, int64_t round)
 
void do_alphaShape (Pgr_edge_xy_t *edgesArr, size_t edgesSize, double alpha, GeomText_t **return_tuples, size_t *return_count, char **log_msg, char **notice_msg, char **err_msg)
 

Function Documentation

◆ do_alphaShape()

void do_alphaShape ( Pgr_edge_xy_t edgesArr,
size_t  edgesSize,
double  alpha,
GeomText_t **  return_tuples,
size_t *  return_count,
char **  log_msg,
char **  notice_msg,
char **  err_msg 
)

Definition at line 59 of file alphaShape_driver.cpp.

70  {
71  std::ostringstream log;
72  std::ostringstream err;
73  std::ostringstream notice;
74  try {
75  pgassert(edgesArr);
76  pgassert(edgesSize > 2);
77  pgassert(*return_count == 0);
78  const int64_t round = 100000000000000;
79 
80  std::vector<Pgr_edge_xy_t> edges(edgesArr, edgesArr + edgesSize);
81  /*
82  id | source | target | cost | x1 | y1 | x2 | y2
83  -------+--------+--------+------+------------+------------+----+----
84  1 | 1 | -1 | 1 | 29.1296668 | 40.9434941 | 0 | 0
85  1 | 2 | -1 | 1 | 29.1267903 | 40.9343215 | 0 | 0
86  1 | 3 | -1 | 1 | 29.1296615 | 40.943359 | 0 | 0
87  sort based on y1
88  stable sort on x1
89  */
90 
91  std::sort(edges.begin(), edges.end(),
92  [&](const Pgr_edge_xy_t &lhs, const Pgr_edge_xy_t &rhs) {
93  return
94  std::floor(lhs.y1 * static_cast<double>(round)) < std::floor(rhs.y1 * static_cast<double>(round));
95  });
96  std::stable_sort(edges.begin(), edges.end(),
97  [&](const Pgr_edge_xy_t &lhs, const Pgr_edge_xy_t &rhs) {
98  return
99  std::floor(lhs.x1 * static_cast<double>(round)) < std::floor(rhs.x1 * static_cast<double>(round));
100  });
101  log << "ending sort";
102 
103 
104 
105  int64_t source_id(0);
106  auto prev = edges.front();
107  for (auto &e : edges) {
108  if (data_eq(e, prev, round)) {
109  e.source = source_id;
110  } else {
111  e.source = ++source_id;
112  prev = e;
113  }
114  }
115  std::stable_sort(edges.begin(), edges.end(),
116  [](const Pgr_edge_xy_t &lhs, const Pgr_edge_xy_t &rhs) {
117  return
118  lhs.id < rhs.id;
119  });
120 
121  /*
122  * Vertices of triangle a, b, c
123  */
124  Pgr_edge_xy_t *a(nullptr);
125  Pgr_edge_xy_t *b(nullptr);
126  size_t count(0);
127  for (auto &c : edges) {
128  if (count == 0) {
129  a = &c;
130  ++count;
131  continue;
132  }
133  if (count == 1) {
134  b = &c;
135  pgassert(a->id == b->id);
136  ++count;
137  continue;
138  }
139  pgassert(a->id == b->id);
140  pgassert(a->id == c.id);
141 
142  a->target = b->source;
143  a->x2 = b->x1;
144  a->y2 = b->y1;
145 
146  b->target = c.source;
147  b->x2 = c.x1;
148  b->y2 = c.y1;
149 
150  c.target = a->source;
151  c.x2 = a->x1;
152  c.y2 = a->y1;
153  count = 0;
154  }
155 
156  using Pgr_alphaShape = pgrouting::alphashape::Pgr_alphaShape;
157  Pgr_alphaShape alphaShape(edges);
158 
159  auto results = alphaShape(alpha);
160  log << alphaShape.get_log();
161 
162  /*
163  * returning a sequence of text
164  */
165  if (results.empty()) {
166  *return_count = 1;
167  *return_tuples = pgr_alloc(*return_count, (*return_tuples));
168  std::stringstream ss;
169  ss << "MULTIPOLYGON EMPTY";
170  (*return_tuples)[0].geom = pgr_msg(ss.str().c_str());
171  } else {
172  *return_count = results.size();
173  *return_tuples = pgr_alloc(*return_count, (*return_tuples));
174  size_t row = 0;
175  for (const auto &r : results) {
176  std::stringstream ss;
177  ss << bg::wkt(r);
178  (*return_tuples)[row].geom = pgr_msg(ss.str().c_str());
179  ++row;
180  }
181  }
182 
183 
184  *log_msg = log.str().empty()?
185  *log_msg :
186  pgr_msg(log.str().c_str());
187  *notice_msg = notice.str().empty()?
188  *notice_msg :
189  pgr_msg(notice.str().c_str());
190  } catch (AssertFailedException &except) {
191  (*return_tuples) = pgr_free(*return_tuples);
192  (*return_count) = 0;
193  err << except.what();
194  *err_msg = pgr_msg(err.str().c_str());
195  } catch (std::exception &except) {
196  (*return_tuples) = pgr_free(*return_tuples);
197  (*return_count) = 0;
198  err << except.what();
199  *err_msg = pgr_msg(err.str().c_str());
200  } catch(...) {
201  (*return_tuples) = pgr_free(*return_tuples);
202  (*return_count) = 0;
203  err << "Caught unknown exception!";
204  *err_msg = pgr_msg(err.str().c_str());
205  }
206 }

References anonymous_namespace{alphaShape_driver.cpp}::data_eq(), Pgr_edge_xy_t::id, pgassert, pgr_alloc(), pgr_free(), pgr_msg(), Pgr_edge_xy_t::source, Pgr_edge_xy_t::target, AssertFailedException::what(), Pgr_edge_xy_t::x1, Pgr_edge_xy_t::x2, Pgr_edge_xy_t::y1, and Pgr_edge_xy_t::y2.

Referenced by process().

pgr_alloc
T * pgr_alloc(std::size_t size, T *ptr)
allocates memory
Definition: pgr_alloc.hpp:66
pgr_msg
char * pgr_msg(const std::string &msg)
Definition: pgr_alloc.cpp:30
AssertFailedException::what
virtual const char * what() const
Definition: pgr_assert.cpp:67
anonymous_namespace{alphaShape_driver.cpp}::data_eq
bool data_eq(const Pgr_edge_xy_t &lhs, const Pgr_edge_xy_t &rhs, int64_t round)
Definition: alphaShape_driver.cpp:49
pgassert
#define pgassert(expr)
Uses the standard assert syntax.
Definition: pgr_assert.h:94
pgr_free
T * pgr_free(T *ptr)
Definition: pgr_alloc.hpp:77
pgrouting::alphashape::Pgr_alphaShape
Definition: pgr_alphaShape.h:63
Pgr_edge_xy_t
Definition: pgr_edge_xy_t.h:38
AssertFailedException
Extends std::exception and is the exception that we throw if an assert fails.
Definition: pgr_assert.h:139