COIN-OR::LEMON - Graph Library

source: glemon-0.x/mapstorage.cc @ 197:c1084e2bff10

Last change on this file since 197:c1084e2bff10 was 195:125c56c1efda, checked in by Hegyi Péter, 13 years ago

Mapstorage does not need to know NoteBookTab? furthermore.

File size: 15.6 KB
Line 
1/* -*- C++ -*-
2 *
3 * This file is a part of LEMON, a generic C++ optimization library
4 *
5 * Copyright (C) 2003-2006
6 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
7 * (Egervary Research Group on Combinatorial Optimization, EGRES).
8 *
9 * Permission to use, modify and distribute this software is granted
10 * provided that this copyright notice appears in all copies. For
11 * precise terms see the accompanying LICENSE file.
12 *
13 * This software is provided "AS IS" with no warranty of any kind,
14 * express or implied, and with no claim as to its suitability for any
15 * purpose.
16 *
17 */
18
19#include <limits>
20#include <cmath>
21#include <gtkmm.h>
22
23#include <mapstorage.h>
24#include <gui_writer.h>
25#include <gui_reader.h>
26#include <lemon/graph_to_eps.h>
27
28const int i_d=20;
29const double a_d=0.05;
30const double p_d=40000;
31
32MapStorage::MapStorage() : modified(false), file_name(""), arrow_pos_read_ok(false), iterations(i_d), attraction(a_d), propulsation(p_d), background_set(false)
33{
34  nodemap_storage["coordinates_x"] = new Graph::NodeMap<double>(graph);
35  coords.setXMap(*nodemap_storage["coordinates_x"]);
36  nodemap_storage["coordinates_y"] = new Graph::NodeMap<double>(graph);
37  coords.setYMap(*nodemap_storage["coordinates_y"]);
38
39  edgemap_storage["arrow_pos_x"] = new Graph::EdgeMap<double>(graph);
40  arrow_pos.setXMap(*edgemap_storage["arrow_pos_x"]);
41  edgemap_storage["arrow_pos_y"] = new Graph::EdgeMap<double>(graph);
42  arrow_pos.setYMap(*edgemap_storage["arrow_pos_y"]);
43
44  nodemap_storage["label"] = new Graph::NodeMap<double>(graph);
45  edgemap_storage["label"] = new Graph::EdgeMap<double>(graph);
46
47  nodemap_default["label"] = 1.0;
48  edgemap_default["label"] = 1.0;
49
50  active_nodemaps.resize(NODE_PROPERTY_NUM);
51  for(int i=0;i<NODE_PROPERTY_NUM;i++)
52    {
53      active_nodemaps[i]="";
54    }
55
56  active_edgemaps.resize(EDGE_PROPERTY_NUM);
57  for(int i=0;i<EDGE_PROPERTY_NUM;i++)
58    {
59      active_edgemaps[i]="";
60    }
61}
62
63MapStorage::~MapStorage()
64{
65  for (std::map<std::string, Graph::NodeMap<double>*>::const_iterator it =
66      nodemap_storage.begin(); it != nodemap_storage.end(); ++it)
67  {
68    delete it->second;
69  }
70  for (std::map<std::string, Graph::EdgeMap<double>*>::const_iterator it =
71      edgemap_storage.begin(); it != edgemap_storage.end(); ++it)
72  {
73    delete it->second;
74  }
75}
76
77int MapStorage::addNodeMap(const std::string & name, Graph::NodeMap<double> *nodemap, double default_value)
78{
79  if( nodemap_storage.find(name) == nodemap_storage.end() )
80    {
81      nodemap_storage[name]=nodemap;
82      // set the maps default value
83      nodemap_default[name] = default_value;
84
85      //announce changement in maps
86      signal_node_map.emit(name);
87      return 0;
88    }
89  return 1;
90}
91
92void MapStorage::changeActiveMap(bool itisedge, int prop, std::string mapname)
93{
94  if(itisedge)
95    {
96      active_edgemaps[prop]=mapname;
97    }
98  else
99    {
100      active_nodemaps[prop]=mapname;
101    }
102  signal_prop.emit(itisedge, prop);
103}
104
105void MapStorage::broadcastActiveMaps()
106{
107  for(int i=0;i<NODE_PROPERTY_NUM;i++)
108    {
109      signal_map_win.emit(false, i, active_nodemaps[i]);
110    }
111 
112  for(int i=0;i<EDGE_PROPERTY_NUM;i++)
113    {
114      signal_map_win.emit(true, i, active_edgemaps[i]);
115    }
116}
117
118
119std::string MapStorage::getActiveEdgeMap(int prop)
120{
121  return active_edgemaps[prop];
122}
123
124std::string MapStorage::getActiveNodeMap(int prop)
125{
126  return active_nodemaps[prop];
127}
128
129std::vector<std::string> MapStorage::getEdgeMapList()
130{
131  std::vector<std::string> eml;
132  eml.resize(edgemap_storage.size());
133  int i=0;
134  std::map< std::string,Graph::EdgeMap<double> * >::iterator emsi=beginOfEdgeMaps();
135  for(;emsi!=endOfEdgeMaps();emsi++)
136    {
137      eml[i]=(emsi->first);
138      i++;
139    }
140  return eml;
141}
142
143std::vector<std::string> MapStorage::getNodeMapList()
144{
145  std::vector<std::string> nml;
146  nml.resize(nodemap_storage.size());
147  int i=0;
148  std::map< std::string,Graph::NodeMap<double> * >::iterator nmsi=beginOfNodeMaps();
149  for(;nmsi!=endOfNodeMaps();nmsi++)
150    {
151      nml[i]=(nmsi->first);
152      i++;
153    }
154  return nml;
155}
156
157sigc::signal<void, bool, int> MapStorage::signal_prop_ch()
158{
159  return signal_prop;
160}
161
162int MapStorage::addEdgeMap(const std::string & name, Graph::EdgeMap<double> *edgemap, double default_value)
163{
164  if( edgemap_storage.find(name) == edgemap_storage.end() )
165    {
166      edgemap_storage[name]=edgemap;
167      // set the maps default value
168      edgemap_default[name] = default_value;
169
170      //announce changement in maps
171      signal_edge_map.emit(name);
172      return 0;
173    }
174  return 1;
175}
176
177double MapStorage::maxOfNodeMap(const std::string & name)
178{
179  double max=0;
180  for (NodeIt j(graph); j!=INVALID; ++j)
181  {
182    if( (*nodemap_storage[name])[j]>max )
183    {
184      max=(*nodemap_storage[name])[j];
185    }
186  }
187  return max;
188}
189
190double MapStorage::maxOfEdgeMap(const std::string & name)
191{
192  double max=0;
193  for (EdgeIt j(graph); j!=INVALID; ++j)
194  {
195    if( (*edgemap_storage[name])[j]>max )
196    {
197      max=(*edgemap_storage[name])[j];
198    }
199  }
200  return max;
201}
202
203double MapStorage::minOfNodeMap(const std::string & name)
204{
205  NodeIt j(graph);
206  double min;
207  if(j!=INVALID)
208    {
209      min=(*nodemap_storage[name])[j];
210    }
211  else
212    {
213      min=0;
214    }
215  for (; j!=INVALID; ++j)
216  {
217    if( (*nodemap_storage[name])[j]<min )
218    {
219      min=(*nodemap_storage[name])[j];
220    }
221  }
222  return min;
223}
224
225double MapStorage::minOfEdgeMap(const std::string & name)
226{
227  EdgeIt j(graph);
228  double min;
229  if(j!=INVALID)
230    {
231      min=(*edgemap_storage[name])[j];
232    }
233  else
234    {
235      min=0;
236    }
237  for (EdgeIt j(graph); j!=INVALID; ++j)
238  {
239    if( (*edgemap_storage[name])[j]<min )
240    {
241      min=(*edgemap_storage[name])[j];
242    }
243  }
244  return min;
245}
246
247int MapStorage::readFromFile(const std::string &filename)
248{
249  bool read_x = false;
250  bool read_y = false;
251  bool read_edge_id = false;
252
253  try {
254    LemonReader lreader(filename);
255    ContentReader content(lreader);
256    lreader.run();
257
258    if (content.nodeSetNum() < 1)
259    {
260      Gtk::MessageDialog mdialog("No nodeset found in file.");
261      mdialog.run();
262      clear();
263      return 1;
264    }
265
266    if (content.edgeSetNum() < 1)
267    {
268      Gtk::MessageDialog mdialog("No edgeset found in file.");
269      mdialog.run();
270      clear();
271      return 1;
272    }
273
274    const std::vector<std::string>& nodeMapNames = content.nodeSetMaps(0);
275    const std::vector<std::string>& edgeMapNames = content.edgeSetMaps(0);
276
277    GraphReader<Graph> greader(filename, graph);
278    for (std::vector<std::string>::const_iterator it = nodeMapNames.begin();
279        it != nodeMapNames.end(); ++it)
280    {
281      if (*it == "coordinates_x")
282      {
283        read_x = true;
284        //std::cout << "read X nodemap" << std::endl;
285      }
286      else if (*it == "coordinates_y")
287      {
288        read_y = true;
289        //std::cout << "read Y nodemap" << std::endl;
290      }
291      else if (*it == "label")
292      {
293        //std::cout << "read id nodemap" << std::endl;
294      }
295      else
296      {
297        nodemap_storage[*it] = new Graph::NodeMap<double>(graph);
298        //std::cout << "read " << *it << " nodemap" << std::endl;
299      }
300      greader.readNodeMap(*it, *nodemap_storage[*it]);
301    }
302    for (std::vector<std::string>::const_iterator it = edgeMapNames.begin();
303        it != edgeMapNames.end(); ++it)
304    {
305      if (*it == "label")
306      {
307        //std::cout << "read id edgemap" << std::endl;
308        read_edge_id = true;
309      }
310      else
311      {
312        edgemap_storage[*it] = new Graph::EdgeMap<double>(graph);
313        //std::cout << "read " << *it << " edgemap" << std::endl;
314      }
315      greader.readEdgeMap(*it, *edgemap_storage[*it]);
316    }
317    GuiReader gui_reader(greader, this);
318    greader.run();
319  } catch (Exception& error) {
320    Gtk::MessageDialog mdialog(error.what());
321    mdialog.run();
322    clear();
323    return 1;
324  }
325
326  if (!read_edge_id)
327  {
328    edgemap_storage["label"] = new Graph::EdgeMap<double>(graph);
329    int i = 1;
330    for (EdgeIt e(graph); e != INVALID; ++e)
331    {
332      (*edgemap_storage["label"])[e] = i++;
333    }
334  }
335
336  if (!read_x || !read_y)
337  {
338    int node_num = 0;
339    for (NodeIt n(graph); n != INVALID; ++n)
340    {
341      node_num++;
342    }
343    const double pi = 3.142;
344    double step = 2 * pi / (double) node_num;
345    int i = 0;
346    for (NodeIt n(graph); n != INVALID; ++n)
347    {
348      nodemap_storage["coordinates_x"]->set(n, 250.0 * std::cos(i * step));
349      nodemap_storage["coordinates_y"]->set(n, 250.0 * std::sin(i * step));
350      i++;
351    }
352  }
353
354  if (!arrow_pos_read_ok)
355  {
356    arrow_pos_read_ok = false;
357    for (EdgeIt e(graph); e != INVALID; ++e)
358    {
359      if (graph.source(e) == graph.target(e))
360      {
361        arrow_pos.set(e, coords[graph.source(e)] + XY(0.0, 80.0));
362      }
363      else
364      {
365        arrow_pos.set(e, (coords[graph.source(e)] + coords[graph.target(e)]) / 2.0);
366      }
367    }
368  }
369
370  // fill in the default values for the maps
371  for (std::map<std::string, Graph::NodeMap<double>*>::const_iterator it =
372      nodemap_storage.begin(); it != nodemap_storage.end(); ++it)
373  {
374    if ((it->first != "label") &&
375        (it->first != "coordiantes_x") &&
376        (it->first != "coordinates_y"))
377    {
378      nodemap_default[it->first] = 0.0;
379    }
380    else if (it->first == "label")
381    {
382      NodeIt n(graph);
383      double max = (*nodemap_storage["label"])[n];
384      for (; n != INVALID; ++n)
385      {
386        if ((*nodemap_storage["label"])[n] > max)
387          max = (*nodemap_storage["label"])[n];
388      }
389      nodemap_default["label"] = max + 1.0;
390    }
391  }
392  for (std::map<std::string, Graph::EdgeMap<double>*>::const_iterator it =
393      edgemap_storage.begin(); it != edgemap_storage.end(); ++it)
394  {
395    if (it->first != "label")
396    {
397      edgemap_default[it->first] = 0.0;
398    }
399    else
400    {
401      double max = std::numeric_limits<double>::min();
402      for (EdgeIt e(graph); e != INVALID; ++e)
403      {
404        if ((*edgemap_storage["label"])[e] > max)
405          max = (*edgemap_storage["label"])[e];
406      }
407      if (max > std::numeric_limits<double>::min())
408        edgemap_default["label"] = max + 1.0;
409      else
410        edgemap_default["label"] = 1.0;
411    }
412  }
413
414  return 0;
415}
416
417void MapStorage::writeToFile(const std::string &filename)
418{
419  GraphWriter<Graph> gwriter(filename, graph);
420
421  for (std::map<std::string, Graph::NodeMap<double>*>::const_iterator it =
422      nodemap_storage.begin(); it != nodemap_storage.end(); ++it)
423  {
424    gwriter.writeNodeMap(it->first, *(it->second));
425  }
426  for (std::map<std::string, Graph::EdgeMap<double>*>::const_iterator it =
427      edgemap_storage.begin(); it != edgemap_storage.end(); ++it)
428  {
429    if ((it->first != "arrow_pos_x") &&
430        (it->first != "arrow_pos_y"))
431    {
432      gwriter.writeEdgeMap(it->first, *(it->second));
433    }
434  }
435
436  GuiWriter gui_writer(gwriter, this);
437
438  gwriter.run();
439}
440
441void MapStorage::clear()
442{
443  for (std::map<std::string, Graph::NodeMap<double>*>::iterator it =
444      nodemap_storage.begin(); it != nodemap_storage.end(); ++it)
445  {
446    if ((it->first != "coordinates_x") &&
447        (it->first != "coordinates_y") &&
448        (it->first != "label"))
449    {
450      delete it->second;
451      nodemap_storage.erase(it);
452    }
453  }
454  for (std::map<std::string, Graph::EdgeMap<double>*>::iterator it =
455      edgemap_storage.begin(); it != edgemap_storage.end(); ++it)
456  {
457    if ((it->first != "label") &&
458        (it->first != "arrow_pos_x") &&
459        (it->first != "arrow_pos_y"))
460    {
461      delete it->second;
462      edgemap_storage.erase(it);
463    }
464  }
465  for (std::map<std::string, double>::iterator it =
466      nodemap_default.begin(); it != nodemap_default.end(); ++it)
467  {
468    if (it->first != "label")
469      nodemap_default.erase(it);
470  }
471  for (std::map<std::string, double>::iterator it =
472      edgemap_default.begin(); it != edgemap_default.end(); ++it)
473  {
474    if (it->first != "label")
475      edgemap_default.erase(it);
476  }
477  graph.clear();
478  file_name = "";
479  modified = false;
480
481  arrow_pos_read_ok = false;
482 
483  for(int i=0;i<NODE_PROPERTY_NUM;i++)
484    {
485      changeActiveMap(false, i, "");
486      signal_map_win.emit(false, i, "");
487    }
488 
489  for(int i=0;i<EDGE_PROPERTY_NUM;i++)
490    {
491      changeActiveMap(true, i, "");
492      signal_map_win.emit(true, i, "");
493    }
494
495  attraction=a_d;
496  propulsation=p_d;
497  iterations=i_d;
498
499  signal_design_win.emit(attraction, propulsation, iterations);
500}
501
502void MapStorage::ArrowPosReadOK()
503{
504  arrow_pos_read_ok = true;
505}
506
507void MapStorage::mapChanged(bool itisedge, std::string mapname)
508{
509  if(itisedge)
510    {
511      for(int i=0;i<EDGE_PROPERTY_NUM;i++)
512        {
513          if(active_edgemaps[i]==mapname)
514            {
515              signal_prop.emit(itisedge, i);
516            }
517        }
518    }
519  else
520    {
521      for(int i=0;i<NODE_PROPERTY_NUM;i++)
522        {
523          if(active_nodemaps[i]==mapname)
524            {
525              signal_prop.emit(itisedge, i);
526            }
527        }
528    }
529}
530
531void MapStorage::get_design_data(double & attraction_p, double & propulsation_p, int & iterations_p)
532{
533  attraction_p=attraction;
534  propulsation_p=propulsation;
535  iterations_p=iterations;
536}
537
538void MapStorage::set_attraction(double attraction_p)
539{
540  attraction=attraction_p;
541}
542
543void MapStorage::set_propulsation(double propulsation_p)
544{
545  propulsation=propulsation_p;
546}
547
548void MapStorage::set_iteration(int iterations_p)
549{
550  iterations=iterations_p;
551}
552
553void MapStorage::redesign_data_changed()
554{
555  signal_design_win.emit(attraction, propulsation, iterations);
556}
557
558void MapStorage::setBackground(const std::string& file_name)
559{
560  if (file_name == background_file_name) return;
561  if (file_name == "")
562  {
563    background_file_name = "";
564    background_set = false;
565  }
566  else
567  {
568    background_file_name = file_name;
569    background_set = true;
570  }
571  signal_background.emit();
572}
573
574const std::string& MapStorage::getBackgroundFilename()
575{
576  return background_file_name;
577}
578
579bool MapStorage::isBackgroundSet()
580{
581  return background_set;
582}
583
584double MapStorage::getBackgroundScaling()
585{
586  return background_scaling;
587}
588
589void MapStorage::setBackgroundScaling(double scaling)
590{
591  background_scaling = scaling;
592}
593
594void MapStorage::exportGraphToEPS(std::vector<bool> options, std::string filename)
595{
596  Graph::NodeMap<int> _nodeColors(graph, 0);
597  Graph::EdgeMap<int> _edgeColors(graph, 0);
598  Graph::NodeMap<double> _nodeSizes(graph, 6.0);
599  Graph::EdgeMap<double> _edgeWidths(graph, 1.0);
600  bool _drawArrows=options[ARROWS];
601  bool _enableParallel=options[PAR];
602
603  std::string emptyString="";
604  Graph::NodeMap<std::string> _nodeTextMap(graph,emptyString);
605
606  //_nodeTextMap=(Graph::NodeMap<void> *)&emptyStringMap;
607
608  if(options[N_MAPS])
609    {
610      if(active_nodemaps[N_RADIUS]!="")
611        {
612          _nodeSizes=*(nodemap_storage[active_nodemaps[N_RADIUS]]);
613        }
614      if(active_nodemaps[N_COLOR]!="")
615        {
616          for(NodeIt ni(graph);ni!=INVALID;++ni)
617            {
618              _nodeColors[ni]=(int)((*(nodemap_storage[active_nodemaps[N_COLOR]]))[ni]);
619            }
620        }
621      if(active_nodemaps[N_TEXT]!="")
622        {
623          for(NodeIt ni(graph);ni!=INVALID;++ni)
624            {
625              std::ostringstream o;
626              o << ((*(nodemap_storage[active_nodemaps[N_TEXT]]))[ni]);
627              _nodeTextMap[ni]=o.str();       
628            }
629        }
630    }
631  if(options[E_MAPS])
632    {
633      if(active_edgemaps[E_WIDTH]!="")
634        {
635          _edgeWidths=*(edgemap_storage[active_edgemaps[E_WIDTH]]);
636        }
637      if(active_edgemaps[E_COLOR]!="")
638        {
639          for(EdgeIt ei(graph);ei!=INVALID;++ei)
640            {
641              _edgeColors[ei]=(int)((*(edgemap_storage[active_edgemaps[E_COLOR]]))[ei]);
642            }
643        }
644    }
645
646  Palette palette;
647  Palette paletteW(true);
648
649  graphToEps(graph,filename).
650    title("Sample .eps figure (fits to A4)").
651    copyright("(C) 2006 LEMON Project").
652    absoluteNodeSizes().absoluteEdgeWidths().
653    nodeScale(2).nodeSizes(_nodeSizes).
654    coords(coords).
655    nodeColors(composeMap(paletteW,_nodeColors)).
656    edgeColors(composeMap(palette,_edgeColors)).
657    edgeWidthScale(0.3).edgeWidths(_edgeWidths).
658    nodeTexts(_nodeTextMap).nodeTextSize(7).
659    enableParallel(_enableParallel).parEdgeDist(4).
660    drawArrows(_drawArrows).arrowWidth(7).arrowLength(7).
661    run();
662
663}
Note: See TracBrowser for help on using the repository browser.