PGROUTING  3.2
pgrouting::alphashape::Pgr_alphaShape Class Reference

#include "pgr_alphaShape.h"

Inheritance diagram for pgrouting::alphashape::Pgr_alphaShape:
Collaboration diagram for pgrouting::alphashape::Pgr_alphaShape:

Classes

struct  EdgesFilter
 

Public Member Functions

 Pgr_alphaShape ()=delete
 
 Pgr_alphaShape (const std::vector< Pgr_edge_xy_t > &edges)
 
void clear ()
 clear More...
 
std::string get_error () const
 get_error More...
 
std::string get_log () const
 get_log More...
 
std::string get_notice () const
 get_notice More...
 
bool has_error () const
 get_error More...
 
std::vector< Bpolyoperator() (double alpha) const
 

Public Attributes

std::ostringstream error
 Stores the error information. More...
 
std::ostringstream log
 Stores the hint information. More...
 
std::ostringstream notice
 Stores the notice information. More...
 

Private Member Functions

std::vector< Bpolybuild_best_alpha () const
 
bool faceBelongs (const Triangle face, double alpha) const
 
void make_triangles ()
 
double radius (const Triangle t) const
 
void recursive_build (const Triangle face, std::set< Triangle > &used, std::set< E > &border_edges, double alpha) const
 

Private Attributes

G graph
 sides graph More...
 
std::map< Triangle, std::set< Triangle > > m_adjacent_triangles
 t -> {adj_t} More...
 

Friends

std::ostream & operator<< (std::ostream &, const Pgr_alphaShape &)
 

Detailed Description

Definition at line 63 of file pgr_alphaShape.h.

Constructor & Destructor Documentation

◆ Pgr_alphaShape() [1/2]

pgrouting::alphashape::Pgr_alphaShape::Pgr_alphaShape ( )
delete

◆ Pgr_alphaShape() [2/2]

pgrouting::alphashape::Pgr_alphaShape::Pgr_alphaShape ( const std::vector< Pgr_edge_xy_t > &  edges)
explicit

Definition at line 167 of file pgr_alphaShape.cpp.

167  :
168 graph(UNDIRECTED) {
169  graph.insert_edges(edges);
170  make_triangles();
171 }

References graph, pgrouting::graph::Pgr_base_graph< G, T_V, T_E >::insert_edges(), and make_triangles().

Member Function Documentation

◆ build_best_alpha()

std::vector< Bpoly > pgrouting::alphashape::Pgr_alphaShape::build_best_alpha ( ) const
private

Definition at line 248 of file pgr_alphaShape.cpp.

248  {
249  std::map<Triangle, double> border_triangles;
250  std::map<Triangle, double> inner_triangles;
251 
252  size_t i(0);
253  for (const auto &t : m_adjacent_triangles) {
254  if (t.second.size() == 2) {
255  border_triangles[t.first] = radius(t.first);
256  } else {
257  inner_triangles[t.first] = radius(t.first);
258  }
259  ++i;
260  }
261  pgassert(border_triangles.size() + inner_triangles.size() == i);
262 
263  auto max_border_triangle = *std::min_element(border_triangles.begin(), border_triangles.end(), CompareRadius());
264  auto max_inner_triangle = *std::min_element(inner_triangles.begin(), inner_triangles.end(), CompareRadius());
265 
266  double max_border_radius = max_border_triangle.second;
267  double max_inner_radius = max_inner_triangle.second;
268 
269 
270  auto count = border_triangles.size() + inner_triangles.size();
271  while (max_border_radius >= max_inner_radius) {
272  auto max_border_triangle = *std::min_element(border_triangles.begin(), border_triangles.end(), CompareRadius());
273  auto max_inner_triangle = *std::min_element(inner_triangles.begin(), inner_triangles.end(), CompareRadius());
274  /*
275  * Removing largest border triangle
276  */
277  border_triangles.erase(max_border_triangle.first);
278 
279  /*
280  * Adjacent triangles of a border triangle
281  * - are no longer inner triangles
282  * - are now border triangles
283  */
284  for (const auto &t : m_adjacent_triangles.at(max_border_triangle.first)) {
285  if (inner_triangles.find(t) != inner_triangles.end()) {
286  inner_triangles.erase(t);
287  border_triangles[t] = radius(t);
288  }
289  }
290 
291  auto new_max_border_triangle = *std::min_element(
292  border_triangles.begin(), border_triangles.end(), CompareRadius());
293  auto new_max_inner_triangle = *std::min_element(
294  inner_triangles.begin(), inner_triangles.end(), CompareRadius());
295 
296  if (new_max_border_triangle.second < new_max_inner_triangle.second) {
297  /*
298  * Roll back and exit loop
299  */
300  for (const auto &t : m_adjacent_triangles.at(max_border_triangle.first)) {
301  border_triangles.erase(t);
302  inner_triangles[t] = radius(t);
303  }
304  border_triangles[max_border_triangle.first] = max_border_triangle.second;
305  break;
306  }
307  max_border_radius = new_max_border_triangle.second;
308  max_inner_radius = new_max_inner_triangle.second;
309  pgassert(count > (border_triangles.size() + inner_triangles.size()));
310  count = border_triangles.size() + inner_triangles.size();;
311  }
312 
313  pgassert(max_border_radius > 0);
314  log << "Using Alpha:" << max_border_radius * max_border_radius;
315  return this->operator()(max_border_radius);
316 }

References pgrouting::Pgr_messages::log, m_adjacent_triangles, operator()(), pgassert, and radius().

Referenced by operator()().

◆ clear()

void pgrouting::Pgr_messages::clear ( )
inherited

clear

Clears All the messages

Definition at line 59 of file pgr_messages.cpp.

59  {
60  log.str("");
61  log.clear();
62 
63  notice.str("");
64  notice.clear();
65 
66  error.str("");
67  error.clear();
68 }

References pgrouting::Pgr_messages::error, pgrouting::Pgr_messages::log, and pgrouting::Pgr_messages::notice.

Referenced by do_pgr_pickDeliver().

◆ faceBelongs()

bool pgrouting::alphashape::Pgr_alphaShape::faceBelongs ( const Triangle  face,
double  alpha 
) const
private

Definition at line 243 of file pgr_alphaShape.cpp.

243  {
244  return radius(t) <= alpha;
245 }

References radius().

Referenced by recursive_build().

◆ get_error()

std::string pgrouting::Pgr_messages::get_error ( ) const
inherited

get_error

Returns
the current contents of the log and clears the log

Definition at line 53 of file pgr_messages.cpp.

53  {
54  auto str = error.str();
55  return str;
56 }

References pgrouting::Pgr_messages::error.

Referenced by do_pgr_many_withPointsDD(), do_pgr_pickDeliver(), do_pgr_pickDeliverEuclidean(), do_pgr_withPoints(), do_pgr_withPointsKsp(), and pgrouting::vrp::Pgr_pickDeliver::Pgr_pickDeliver().

◆ get_log()

std::string pgrouting::Pgr_messages::get_log ( ) const
inherited

◆ get_notice()

std::string pgrouting::Pgr_messages::get_notice ( ) const
inherited

get_notice

Returns
the current contents of the log and clears the log

Definition at line 42 of file pgr_messages.cpp.

42  {
43  auto str = notice.str();
44  return str;
45 }

References pgrouting::Pgr_messages::notice.

◆ has_error()

bool pgrouting::Pgr_messages::has_error ( ) const
inherited

get_error

Returns
the current contents of the log and clears the log

Definition at line 48 of file pgr_messages.cpp.

48  {
49  return !error.str().empty();
50 }

References pgrouting::Pgr_messages::error.

Referenced by do_pgr_many_withPointsDD(), do_pgr_withPoints(), and do_pgr_withPointsKsp().

◆ make_triangles()

void pgrouting::alphashape::Pgr_alphaShape::make_triangles ( )
private

Definition at line 174 of file pgr_alphaShape.cpp.

174  {
175  /*
176  * triangle sides:
177  * a_r, b, c edge descriptor
178  */
179  BGL_FORALL_EDGES(c, graph.graph, BG) {
180  /*
181  * triangle vertices:
182  * u, v, w vertex descriptor
183  */
184  auto u = graph.source(c);
185  auto v = graph.target(c);
186 
187  std::vector<Triangle> adjacent_to_side;
188 
189  size_t i = 0;
190  BGL_FORALL_OUTEDGES(u, b, graph.graph, BG) {
191  ++i;
192  auto w = graph.adjacent(u, b);
193  if (w == v) {
194  pgassert(b == c);
195  continue;
196  }
197 
198  auto a_r = boost::edge(v, w, graph.graph);
199  if (!a_r.second) continue;
200 
201  Triangle face{{a_r.first, b, c}};
202  adjacent_to_side.push_back(face);
203  }
204 
205  /*
206  * All vertices must have at least 2 edges
207  * So cycle above must have passed at least twice
208  */
209  pgassert(i > 1);
210 
211  if (adjacent_to_side.size() == 2) {
212  m_adjacent_triangles[adjacent_to_side[0]].insert(adjacent_to_side[1]);
213  m_adjacent_triangles[adjacent_to_side[1]].insert(adjacent_to_side[0]);
214  } else {
215  if (m_adjacent_triangles.find(adjacent_to_side[0]) == m_adjacent_triangles.end()) {
216  m_adjacent_triangles[adjacent_to_side[0]].clear();
217  }
218  }
219  }
220 }

References pgrouting::graph::Pgr_base_graph< G, T_V, T_E >::adjacent(), graph, pgrouting::graph::Pgr_base_graph< G, T_V, T_E >::graph, m_adjacent_triangles, pgassert, pgrouting::graph::Pgr_base_graph< G, T_V, T_E >::source(), and pgrouting::graph::Pgr_base_graph< G, T_V, T_E >::target().

Referenced by Pgr_alphaShape().

◆ operator()()

std::vector< Bpoly > pgrouting::alphashape::Pgr_alphaShape::operator() ( double  alpha) const

Definition at line 368 of file pgr_alphaShape.cpp.

368  {
369  std::vector<Bpoly> shape;
370 
371  if (alpha <= 0) return build_best_alpha();
372 
373  std::set<Triangle> used;
374  using Subgraph = boost::filtered_graph<BG, EdgesFilter, boost::keep_all>;
375 
376  for (const auto &t : m_adjacent_triangles) {
377  EdgesFilter border_edges;
378  /*
379  * Recurse through the triangles to get the border sides
380  */
381  recursive_build(t.first, used, border_edges.edges, alpha);
382  /*
383  * triangle was already processed
384  * or is not part of the shape
385  */
386  if (border_edges.edges.empty()) continue;
387 
388  std::vector<Bpoly> polys;
389  Bpoly polygon;
390  double area = 0;
391  while (!border_edges.edges.empty()) {
392  auto first_edge = *border_edges.edges.begin();
393  border_edges.edges.erase(first_edge);
394 
395  Subgraph subg(graph.graph, border_edges, {});
396 
397  auto source = boost::source(first_edge, subg);
398  auto target = boost::target(first_edge, subg);
399 
400 
401  auto predecessors = get_predecessors(source, target, subg);
402  std::set<E> edges_used;
403  auto poly = get_polygon(source, target, predecessors, subg, edges_used);
404 
405  for (const auto &e : edges_used) {
406  border_edges.edges.erase(e);
407  }
408 
409  pgassert(bg::num_points(poly) >= 3 || bg::num_points(poly) == 0);
410 
411  if (bg::num_points(poly) == 0) continue;
412 
413  /*
414  * A polygon must have at least 3 vertices
415  */
416  if (bg::num_points(poly) >= 3) {
417  if (area == 0) {
418  /*
419  * consider the first polygon as the outer polygon
420  */
421  polygon = poly;
422  area = bg::area(poly);
423  } else {
424  auto new_area = bg::area(poly);
425  if (new_area > area) {
426  /*
427  * if new poly is larger than the current outer polygon
428  * - save current outer polygon as inner ring
429  * - save new poly as outer polygon
430  */
431  polys.push_back(polygon);
432  area = new_area;
433  polygon = poly;
434  } else {
435  /*
436  * New poly is inner ring
437  */
438  polys.push_back(poly);
439  }
440  }
441  }
442  }
443 
444  /*
445  * Add inner rings to the polygon
446  */
447  if (!polys.empty()) {
448  polygon.inners().resize(polys.size());
449  size_t i(0);
450  for (const auto &inner_ring : polys) {
451  bg::assign(polygon.inners()[i++], inner_ring);
452  }
453  }
454 
455  /*
456  * Add the polygon to the alpha shape
457  */
458  shape.push_back(polygon);
459  }
460 
461  return shape;
462 }

References build_best_alpha(), pgrouting::alphashape::Pgr_alphaShape::EdgesFilter::edges, pgrouting::alphashape::anonymous_namespace{pgr_alphaShape.cpp}::get_polygon(), pgrouting::alphashape::anonymous_namespace{pgr_alphaShape.cpp}::get_predecessors(), graph, pgrouting::graph::Pgr_base_graph< G, T_V, T_E >::graph, m_adjacent_triangles, pgassert, and recursive_build().

Referenced by build_best_alpha().

◆ radius()

double pgrouting::alphashape::Pgr_alphaShape::radius ( const Triangle  t) const
private

Definition at line 227 of file pgr_alphaShape.cpp.

227  {
228  std::vector<E> edges(t.begin(), t.end());
229  auto a = graph.source(edges[0]);
230  auto b = graph.target(edges[0]);
231  auto c = graph.source(edges[1]);
232  c = (c == a || c == b)? graph.target(edges[1]) : c;
233  pgassert(a != b && a != c && b!= c);
234 
235  auto center = circumcenter(graph[a].point, graph[b].point, graph[c].point);
236  return bg::distance(center, graph[a].point);
237 }

References pgrouting::alphashape::anonymous_namespace{pgr_alphaShape.cpp}::circumcenter(), graph, pgassert, pgrouting::graph::Pgr_base_graph< G, T_V, T_E >::source(), and pgrouting::graph::Pgr_base_graph< G, T_V, T_E >::target().

Referenced by build_best_alpha(), and faceBelongs().

◆ recursive_build()

void pgrouting::alphashape::Pgr_alphaShape::recursive_build ( const Triangle  face,
std::set< Triangle > &  used,
std::set< E > &  border_edges,
double  alpha 
) const
private

Definition at line 319 of file pgr_alphaShape.cpp.

323  {
324  /*
325  * Do nothing when the face does not belong to the polygon of the alphashape
326  */
327  if (!faceBelongs(face, alpha)) return;
328 
329  /*
330  * Do nothing when the face has being processed before
331  */
332  auto original = used.size();
333  used.insert(face);
334  if (original == used.size()) return;
335 
336  std::set<E> common_sides;
337  for (const auto &adj_t : m_adjacent_triangles.at(face)) {
338  if (!faceBelongs(adj_t, alpha)) {
339  /*
340  * Adjacent face is not on shape
341  * then side is on the border
342  */
343  std::set_intersection(
344  face.begin(), face.end(),
345  adj_t.begin(), adj_t.end(),
346  std::inserter(border_edges, border_edges.end()));
347  }
348  std::set_intersection(
349  face.begin(), face.end(),
350  adj_t.begin(), adj_t.end(),
351  std::inserter(common_sides, common_sides.end()));
352  recursive_build(adj_t, used, border_edges, alpha);
353  }
354 
355  if (m_adjacent_triangles.at(face).size() == 2) {
356  /*
357  * Side without adjacent triangle (in convex hull)
358  * is part of the border
359  */
360  std::set_difference(
361  face.begin(), face.end(),
362  common_sides.begin(), common_sides.end(),
363  std::inserter(border_edges, border_edges.end()));
364  }
365 }

References faceBelongs(), and m_adjacent_triangles.

Referenced by operator()().

Friends And Related Function Documentation

◆ operator<<

std::ostream& operator<< ( std::ostream &  os,
const Pgr_alphaShape d 
)
friend

Definition at line 468 of file pgr_alphaShape.cpp.

468  {
469  os << d.graph;
470 
471  return os;
472 }

Member Data Documentation

◆ error

◆ graph

G pgrouting::alphashape::Pgr_alphaShape::graph
private

sides graph

Definition at line 93 of file pgr_alphaShape.h.

Referenced by make_triangles(), operator()(), pgrouting::alphashape::operator<<(), Pgr_alphaShape(), and radius().

◆ log

◆ m_adjacent_triangles

std::map<Triangle, std::set<Triangle> > pgrouting::alphashape::Pgr_alphaShape::m_adjacent_triangles
private

t -> {adj_t}

Definition at line 95 of file pgr_alphaShape.h.

Referenced by build_best_alpha(), make_triangles(), operator()(), and recursive_build().

◆ notice

std::ostringstream pgrouting::Pgr_messages::notice
mutableinherited

Stores the notice information.

Definition at line 83 of file pgr_messages.h.

Referenced by pgrouting::Pgr_messages::clear(), and pgrouting::Pgr_messages::get_notice().


The documentation for this class was generated from the following files:
pgrouting::graph::Pgr_base_graph::graph
G graph
The graph.
Definition: pgr_base_graph.hpp:260
pgrouting::Bpoly
bg::model::polygon< Bpoint > Bpoly
Definition: bline.hpp:46
pgrouting::alphashape::Pgr_alphaShape::make_triangles
void make_triangles()
Definition: pgr_alphaShape.cpp:174
pgrouting::alphashape::Pgr_alphaShape::faceBelongs
bool faceBelongs(const Triangle face, double alpha) const
Definition: pgr_alphaShape.cpp:243
pgrouting::graph::Pgr_base_graph::target
V target(E e_idx) const
Definition: pgr_base_graph.hpp:561
pgrouting::alphashape::Triangle
std::set< E > Triangle
Definition: pgr_alphaShape.h:60
pgrouting::Pgr_messages::error
std::ostringstream error
Stores the error information.
Definition: pgr_messages.h:85
pgrouting::Pgr_messages::log
std::ostringstream log
Stores the hint information.
Definition: pgr_messages.h:81
pgassert
#define pgassert(expr)
Uses the standard assert syntax.
Definition: pgr_assert.h:94
UNDIRECTED
@ UNDIRECTED
Definition: graph_enum.h:30
pgrouting::graph::Pgr_base_graph::insert_edges
void insert_edges(const T *edges, size_t count)
Inserts count edges of type T into the graph.
Definition: pgr_base_graph.hpp:357
pgrouting::alphashape::Pgr_alphaShape::graph
G graph
sides graph
Definition: pgr_alphaShape.h:93
pgrouting::alphashape::Pgr_alphaShape::build_best_alpha
std::vector< Bpoly > build_best_alpha() const
Definition: pgr_alphaShape.cpp:248
pgrouting::graph::Pgr_base_graph::source
V source(E e_idx) const
Definition: pgr_base_graph.hpp:560
pgrouting::alphashape::Pgr_alphaShape::m_adjacent_triangles
std::map< Triangle, std::set< Triangle > > m_adjacent_triangles
t -> {adj_t}
Definition: pgr_alphaShape.h:95
pgrouting::alphashape::anonymous_namespace{pgr_alphaShape.cpp}::get_polygon
Bpoly get_polygon(V source, V target, const std::vector< V > &predecessors, const B_G &graph, std::set< E > &edges_used)
Definition: pgr_alphaShape.cpp:127
pgrouting::alphashape::BG
boost::adjacency_list< boost::setS, boost::vecS, boost::undirectedS, XY_vertex, Basic_edge > BG
Definition: pgr_alphaShape.h:55
pgrouting::Pgr_messages::notice
std::ostringstream notice
Stores the notice information.
Definition: pgr_messages.h:83
pgrouting::alphashape::Pgr_alphaShape::radius
double radius(const Triangle t) const
Definition: pgr_alphaShape.cpp:227
pgrouting::alphashape::anonymous_namespace{pgr_alphaShape.cpp}::get_predecessors
std::vector< V > get_predecessors(V source, V target, const B_G &subg)
Definition: pgr_alphaShape.cpp:95
pgrouting::alphashape::Pgr_alphaShape::operator()
std::vector< Bpoly > operator()(double alpha) const
Definition: pgr_alphaShape.cpp:368
pgrouting::alphashape::Pgr_alphaShape::recursive_build
void recursive_build(const Triangle face, std::set< Triangle > &used, std::set< E > &border_edges, double alpha) const
Definition: pgr_alphaShape.cpp:319
pgrouting::alphashape::anonymous_namespace{pgr_alphaShape.cpp}::circumcenter
Bpoint circumcenter(const Bpoint a, const Bpoint b, const Bpoint c)
Definition: pgr_alphaShape.cpp:73
pgrouting::graph::Pgr_base_graph::adjacent
V adjacent(V v_idx, E e_idx) const
Definition: pgr_base_graph.hpp:562