Open
Graph Drawing
Framework

 v. 2023.09 (Elderberry)
 

GeometricDrawing.h
Go to the documentation of this file.
1 
31 #pragma once
32 
33 #ifdef OGDF_INCLUDE_CGAL
34 
35 # include <ogdf/basic/EdgeArray.h>
48 
49 # include <map>
50 # include <tuple>
51 # include <vector>
52 
53 namespace ogdf {
54 namespace internal {
55 namespace gcm {
56 namespace graph {
57 
61 template<typename Kernel_, typename Graph_>
62 class GeometricDrawing : public Drawing<Kernel_, Graph_> {
63 public:
64  using Kernel = Kernel_;
65  using Graph = Graph_;
66  using Node = typename Graph::Node;
67  using Edge = typename Graph::Edge;
68 
69  using Point = geometry::Point_t<Kernel>;
70  using LineSegment = geometry::LineSegment_t<Kernel>;
71 
72 private:
73  Graph& g;
74 
75  using PointToNodeMap = std::map<Point, Node>;
76  using PointToNodeMapIterator = typename PointToNodeMap::iterator;
77 
78  std::vector<Edge> visited_edges;
79 
80  PointToNodeMap point_to_node;
81 
82  datastructure::NodeVector<Point, Graph> node_to_point;
83 
84  OGDFFaceWrapper m_outer_face;
85  bool outer_face_initialized {false};
86 
87 public:
88  explicit GeometricDrawing(Graph& _g) : Drawing<Kernel_, Graph>(_g), g(_g), node_to_point(g) {
89  /*nothing to do*/
90  }
91 
92  inline void set_outer_face(OGDFFaceWrapper ef) {
93  m_outer_face = ef;
94  outer_face_initialized = true;
95  }
96 
97  inline OGDFFaceWrapper& outer_face() {
98  OGDF_ASSERT(outer_face_initialized);
99  return m_outer_face;
100  }
101 
102  inline const OGDFFaceWrapper& outer_face() const {
103  OGDF_ASSERT(outer_face_initialized);
104  return m_outer_face;
105  }
106 
107  inline void clear() {
108  point_to_node.clear();
109  node_to_point.clear();
110  outer_face_initialized = false;
111  }
112 
113  size_t number_of_points() const { return node_to_point.size(); }
114 
115  const std::vector<Point>& points() const { return node_to_point; }
116 
117  // does not keep the consitency with add node!
118  inline void set_point(const Node& v, const Point& p) {
119  OGDF_ASSERT((size_t)v->index() <= g.max_node_index());
120  if (g.max_node_index() >= node_to_point.size()) {
121  node_to_point.resize(g.max_node_index() + 1);
122  }
123  node_to_point[v] = p;
124  }
125 
126  inline Point get_point(const Node& v) const {
127  OGDF_ASSERT((size_t)v->index() < node_to_point.size());
128  return node_to_point[v];
129  }
130 
131  inline Point& operator[](const Node& v) {
132  OGDF_ASSERT((size_t)v->index() < node_to_point.size());
133  return node_to_point[v];
134  }
135 
136  inline Point operator[](const Node& v) const { return get_point(v); }
137 
138  inline LineSegment get_segment(const Edge& e) const {
139  return {get_point(e->source()), get_point(e->target())};
140  }
141 
142  inline geometry::Bbox bbox() const {
145  double xmax = -xmin;
146  double ymax = -ymin;
147 
148  geometry::Bbox bb(xmin, ymin, xmax, ymax);
149  for (Node v : g.nodes()) {
150  bb += get_point(v).bbox();
151  }
152  return bb;
153  }
154 };
155 
156 template<typename Kernel, typename Graph, typename EdgeList>
157 void generate_graph_from_list(const std::vector<geometry::Point_t<Kernel>>& nodes,
158  const EdgeList& edge_list, std::vector<typename Graph::Edge>& map_edge,
159  GeometricDrawing<Kernel, Graph>& d) {
160  using Node = typename Graph::Node;
161  using Edge = typename Graph::Edge;
162  using Point = typename geometry::Point_t<Kernel>;
163 
164  std::vector<Node> node_map;
165  std::vector<Point> map;
166  Graph& g = d.get_graph();
167  for (const Point& p : nodes) {
168  node_map.push_back(g.add_node());
169  d.set_point(node_map.back(), p); //TODO check ?
170  }
171  for (const std::tuple<unsigned int, unsigned int, unsigned int>& edge : edge_list) {
172  if (node_map[std::get<0>(edge)] != node_map[std::get<1>(edge)]) {
173  const Edge e = g.add_edge(node_map[std::get<0>(edge)], node_map[std::get<1>(edge)]);
174  map_edge.push_back(e);
175  } else {
176  map_edge.push_back(nullptr);
177  }
178  }
179 # ifdef OGDF_DEBUG
180  for (const auto e : map_edge) {
181  OGDF_ASSERT(!e || e->graphOf() == &g.get_ogdf_graph());
182  }
183 # endif
184 }
185 
186 template<typename Kernel, typename Graph, typename EdgeList>
187 void generate_graph_from_list(std::map<unsigned int, geometry::Point_t<Kernel>>& nodes,
188  const EdgeList& edge_list, std::vector<typename Graph::Edge>& map_edge,
189  std::map<unsigned int, typename Graph::Node>& node_map, GeometricDrawing<Kernel, Graph>& d) {
190  using Edge = typename Graph::Edge;
191 
192  Graph& g = d.get_graph();
193  for (const std::tuple<unsigned int, unsigned int, unsigned int>& edge : edge_list) {
194  unsigned int source = std::get<0>(edge);
195  unsigned int target = std::get<1>(edge);
196 
197 
198  if (node_map.find(source) == node_map.end()) {
199  auto u = g.add_node();
200  d.set_point(u, nodes[source]);
201  node_map.insert(std::make_pair(source, u));
202  }
203  if (node_map.find(target) == node_map.end()) {
204  auto u = g.add_node();
205  d.set_point(u, nodes[target]);
206  node_map.insert(std::make_pair(target, u));
207  }
208  }
209 
210  for (const std::tuple<unsigned int, unsigned int, unsigned int>& edge : edge_list) {
211  if (node_map[std::get<0>(edge)] != node_map[std::get<1>(edge)]) {
212  const Edge e = g.add_edge(node_map[std::get<0>(edge)], node_map[std::get<1>(edge)]);
213  OGDF_ASSERT(e != nullptr);
214  map_edge.push_back(e);
215  } else {
216  map_edge.push_back(nullptr);
217  }
218  }
219 
220 # ifdef OGDF_DEBUG
221  for (const auto e : map_edge) {
222  OGDF_ASSERT(!e || e->graphOf() == &g.get_ogdf_graph());
223  }
224 # endif
225 }
226 
227 template<typename Kernel, typename Graph, typename EdgeList>
228 void generate_graph_from_list(std::map<unsigned int, geometry::Point_t<Kernel>>& nodes,
229  const EdgeList& edge_list, std::vector<typename Graph::Edge>& map_edge,
230  GeometricDrawing<Kernel, Graph>& g) {
231  std::map<unsigned int, typename Graph::Node> node_map;
232  generate_graph_from_list(nodes, edge_list, map_edge, node_map, g);
233 }
234 
235 template<typename Kernel, typename Graph>
236 std::tuple<datastructure::NodeVector<typename Graph::Node, Graph>,
237  datastructure::EdgeVector<typename Graph::Edge, Graph>>
238 copy(GeometricDrawing<Kernel, Graph>& original, GeometricDrawing<Kernel, Graph>& copy) {
239  using Node = typename Graph::Node;
240  using Edge = typename Graph::Edge;
241 
242  datastructure::NodeVector<Node, Graph> node_map(original);
243  datastructure::EdgeVector<Edge, Graph> edge_map(original);
244 
245  for (auto v : original.nodes()) {
246  node_map[v] = copy.add_node(original.get_point(v));
247  }
248 
249  for (auto e : original.edges()) {
250  edge_map[e] = copy.add_edge(node_map[e->source()], node_map[e->target()]);
251  }
252 
253  return std::make_tuple(node_map, edge_map);
254 }
255 
256 template<typename Kernel, typename Graph>
257 void ogdf_attributes_to_geometric_drawing(const GraphAttributes& ga,
258  GeometricDrawing<Kernel, Graph>& d) {
259  OGDF_ASSERT(&d.get_graph().get_ogdf_graph() == &ga.constGraph());
260  for (auto v : d.get_graph().nodes()) {
261  geometry::Point_t<Kernel> p(ga.x(v), ga.y(v));
262  d.set_point(v, p);
263  }
264 }
265 
266 template<typename Kernel, typename Graph>
267 void geometric_drawing_to_ogdf_attributes(const GeometricDrawing<Kernel, Graph>& d,
268  GraphAttributes& ga) {
269  OGDF_ASSERT(&d.get_graph().get_ogdf_graph() == &ga.constGraph());
270  for (auto v : d.get_graph().nodes()) {
271  auto p = d.get_point(v);
272  ga.x(v) = CGAL::to_double(p.x());
273  ga.y(v) = CGAL::to_double(p.y());
274  }
275 }
276 
277 }
278 }
279 }
280 }
281 
282 #endif
ogdf
The namespace for all OGDF objects.
Definition: multilevelmixer.cpp:39
GraphAttributes.h
Declaration of class GraphAttributes which extends a Graph by additional attributes.
OGDF_ASSERT
#define OGDF_ASSERT(expr)
Assert condition expr. See doc/build.md for more information.
Definition: basic.h:66
ogdf::matching_blossom::infinity
TWeight infinity()
Helper function to get the maximum value for a given weight type.
Definition: utils.h:46
Point.h
OGDFGraphWrapper.h
Universal.h
ogdf::gml::Key::Node
@ Node
ogdf::gml::Key::Edge
@ Edge
OGDFFaceWrapper.h
Converter.h
ogdf::edge
EdgeElement * edge
The type of edges.
Definition: Graph_d.h:74
Rectangle.h
Minisat::Internal::copy
static void copy(const T &from, T &to)
Definition: Alg.h:61
OGDFVector.h
ogdf::gml::Key::Graph
@ Graph
EdgeArray.h
Declaration and implementation of EdgeArray class.
GraphIO.h
Declares class GraphIO which provides access to all graph read and write functionality.
LineSegment.h
Drawing.h
SvgPrinter.h
Generator for visualizing graphs using the XML-based SVG format.
ogdf::gml::Key::Point
@ Point