mapstorage.cc
author hegyi
Thu, 01 Mar 2007 16:28:13 +0000
changeset 198 d6cc0579b94b
parent 195 125c56c1efda
child 199 128195bbab73
permissions -rw-r--r--
Shape feature of EPS can be used.
     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 
    28 const int i_d=20;
    29 const double a_d=0.05;
    30 const double p_d=40000;
    31 
    32 MapStorage::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 
    63 MapStorage::~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 
    77 int 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 
    92 void 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 
   105 void 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 
   119 std::string MapStorage::getActiveEdgeMap(int prop)
   120 {
   121   return active_edgemaps[prop];
   122 }
   123 
   124 std::string MapStorage::getActiveNodeMap(int prop)
   125 {
   126   return active_nodemaps[prop];
   127 }
   128 
   129 std::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 
   143 std::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 
   157 sigc::signal<void, bool, int> MapStorage::signal_prop_ch()
   158 {
   159   return signal_prop;
   160 }
   161 
   162 int 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 
   177 double 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 
   190 double 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 
   203 double 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 
   225 double 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 
   247 int 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 
   417 void 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 
   441 void 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 
   502 void MapStorage::ArrowPosReadOK()
   503 {
   504   arrow_pos_read_ok = true;
   505 }
   506 
   507 void 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 
   531 void 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 
   538 void MapStorage::set_attraction(double attraction_p)
   539 {
   540   attraction=attraction_p;
   541 }
   542 
   543 void MapStorage::set_propulsation(double propulsation_p)
   544 {
   545   propulsation=propulsation_p;
   546 }
   547 
   548 void MapStorage::set_iteration(int iterations_p)
   549 {
   550   iterations=iterations_p;
   551 }
   552 
   553 void MapStorage::redesign_data_changed()
   554 {
   555   signal_design_win.emit(attraction, propulsation, iterations);
   556 }
   557 
   558 void 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 
   574 const std::string& MapStorage::getBackgroundFilename()
   575 {
   576   return background_file_name;
   577 }
   578 
   579 bool MapStorage::isBackgroundSet()
   580 {
   581   return background_set;
   582 }
   583 
   584 double MapStorage::getBackgroundScaling()
   585 {
   586   return background_scaling;
   587 }
   588 
   589 void MapStorage::setBackgroundScaling(double scaling)
   590 {
   591   background_scaling = scaling;
   592 }
   593 
   594 void MapStorage::exportGraphToEPS(std::vector<bool> options, std::string filename, std::string shapemap)
   595 {
   596   Graph::NodeMap<int> _shapes(graph, 0);
   597   Graph::NodeMap<int> _nodeColors(graph, 0);
   598   Graph::EdgeMap<int> _edgeColors(graph, 0);
   599   Graph::NodeMap<double> _nodeSizes(graph, 6.0);
   600   Graph::EdgeMap<double> _edgeWidths(graph, 1.0);
   601   bool _drawArrows=options[ARROWS];
   602   bool _enableParallel=options[PAR];
   603 
   604   std::string emptyString="";
   605   Graph::NodeMap<std::string> _nodeTextMap(graph,emptyString);
   606 
   607   //_nodeTextMap=(Graph::NodeMap<void> *)&emptyStringMap;
   608 
   609   if(options[N_MAPS])
   610     {
   611       if(active_nodemaps[N_RADIUS]!="")
   612 	{
   613 	  _nodeSizes=*(nodemap_storage[active_nodemaps[N_RADIUS]]);
   614 	}
   615       if(active_nodemaps[N_COLOR]!="")
   616 	{
   617 	  for(NodeIt ni(graph);ni!=INVALID;++ni)
   618 	    {
   619 	      _nodeColors[ni]=(int)((*(nodemap_storage[active_nodemaps[N_COLOR]]))[ni]);
   620 	    }
   621 	}
   622       if(active_nodemaps[N_TEXT]!="")
   623 	{
   624 	  for(NodeIt ni(graph);ni!=INVALID;++ni)
   625 	    {
   626 	      std::ostringstream o;
   627 	      o << ((*(nodemap_storage[active_nodemaps[N_TEXT]]))[ni]);
   628 	      _nodeTextMap[ni]=o.str();	      
   629 	    }
   630 	}
   631     }
   632   if(options[E_MAPS])
   633     {
   634       if(active_edgemaps[E_WIDTH]!="")
   635 	{
   636 	  _edgeWidths=*(edgemap_storage[active_edgemaps[E_WIDTH]]);
   637 	}
   638       if(active_edgemaps[E_COLOR]!="")
   639 	{
   640 	  for(EdgeIt ei(graph);ei!=INVALID;++ei)
   641 	    {
   642 	      _edgeColors[ei]=(int)((*(edgemap_storage[active_edgemaps[E_COLOR]]))[ei]);
   643 	    }
   644 	}
   645     }
   646   if(shapemap!="")
   647     {
   648       if((minOfNodeMap(shapemap)>=0)&&(maxOfNodeMap(shapemap)<=4))
   649 	{
   650 	  _shapes=*(nodemap_storage[shapemap]);
   651 	}
   652     }
   653 
   654   Palette palette;
   655   Palette paletteW(true);
   656 
   657   graphToEps(graph,filename).
   658     title("Sample .eps figure (fits to A4)").
   659     copyright("(C) 2006 LEMON Project").
   660     absoluteNodeSizes().absoluteEdgeWidths().
   661     nodeScale(2).nodeSizes(_nodeSizes).
   662     coords(coords).
   663     nodeShapes(_shapes).
   664     nodeColors(composeMap(paletteW,_nodeColors)).
   665     edgeColors(composeMap(palette,_edgeColors)).
   666     edgeWidthScale(0.3).edgeWidths(_edgeWidths).
   667     nodeTexts(_nodeTextMap).nodeTextSize(7).
   668     enableParallel(_enableParallel).parEdgeDist(5).
   669     drawArrows(_drawArrows).arrowWidth(7).arrowLength(7).
   670     run();
   671 
   672 }