Bridges-C++  3.4.5-dev1-6-g935685a
Bridges(C++ API)
Bridges.h
Go to the documentation of this file.
1 #ifndef BRIDGES_H
2 #define BRIDGES_H
3 
4 #include <iostream>
5 #include <algorithm>
6 using namespace std;
7 
8 #include "DataStructure.h" //string, using std
9 #include "ServerComm.h" //vector
10 
11 //#include "DataSource.h"
12 
13 #include <JSONutil.h>
14 #include <alltypes.h>
15 #include <chrono>
16 #include <USMap.h>
17 #include <rapidjson/document.h>
18 #include <rapidjson/stringbuffer.h>
19 #include <rapidjson/writer.h>
20 
21 namespace bridges {
22  using namespace bridges::datastructure;
23  using namespace rapidjson;
24 
25  namespace game {
26  class SocketConnection;
27  }
50  class Bridges {
51  private:
52  static bool profile() {
53  return false;
54  }
55 
56  static string getDefaultServerURL() {
57  return "http://bridges-cs.herokuapp.com";
58  }
59 
60  bool jsonFlag = false; // if JSON is to be printed
61 
62  // this flag will turn on all labels in the visualization
63  bool element_labelFlag = false, link_labelFlag = false;
64 
65  bool post_visualization_link = true; // post flag of visualization url
66 
67  string user_name = string(),
68  api_key = string(); // user credentials
69 
70  string map; // for map overlays
71  bool map_as_json = false;
72 
73  string description = string(); // visualization description
74 
75  string title = string(); // title of visualization
76 
77  unsigned int assn_num = 0; // assignment id
78 
79  DataStructure* ds_handle = nullptr; // data structure handle
80 
81  string server_url = "http://bridges-cs.herokuapp.com";
82 
83  string BASE_URL = server_url + "/assignments/";
84 
85  // map overlay options
86  string map_overlay_options[3] = {"cartesian", "albersusa", "equirectangular"};
87  bool map_overlay = false;
88  string coord_system_type = "cartesian";
89 
90  // world coordinate window
91  vector<double> wc_window;
92 
93  unsigned int lastAssignNum = 0, subAssignNum = 0;
94 
95  // JSON object - contains the data structure representationa
96  rapidjson::Writer<rapidjson::StringBuffer> json_obj;
97 
98  public:
99 
101  Bridges (0, "", "");
102  }
115  Bridges (const string& name, const string& key) {
116  Bridges (0, name, key);
117  }
138  Bridges (unsigned int num, const string& name, const string& key) {
139  setAssignment(num);
140  setUserName(name);
141  setApiKey(key);
142  setServer("live");
143  }
144 
153  void setElementLabelFlag(bool flag) {
154  element_labelFlag = flag;
155  }
164  void setLinkLabelFlag(bool flag) {
165  link_labelFlag = flag;
166  }
167 
174  bool getElementLabelFlag() const {
175  return element_labelFlag;
176  }
184  bool getLinkLabelFlag() const {
185  return link_labelFlag;
186  }
187 
194  bool getJSONFlag() const {
195  return jsonFlag;
196  }
197 
207  void postVisualizationLink(bool link_url) {
208  post_visualization_link = link_url;
209  }
210 
216  void setJSONFlag(bool flag) {
217  jsonFlag = flag;
218  }
219 
227  const string& getUserName() const {
228  return user_name;
229  }
239  void setUserName(string name) {
240  char* force = getenv("FORCE_BRIDGES_USERNAME");
241  if (force != nullptr) {
242  name = force;
243  }
244 
245  user_name = name;
246  }
252  const string& getApiKey() const {
253  return api_key;
254  }
265  void setApiKey(string key) {
266  char* force = getenv("FORCE_BRIDGES_APIKEY");
267  if (force != nullptr) {
268  key = force;
269  }
270  api_key = key;
271  }
278  unsigned int getAssignment() const {
279  return assn_num;
280  }
290  void setAssignment(unsigned int num) {
291  char* force = getenv("FORCE_BRIDGES_ASSIGNMENT");
292  if (force != nullptr) {
293  num = std::atoi(force);
294  }
295 
296  assn_num = num;
297 
298  if (assn_num != lastAssignNum) { // reset if a new assignment
299  lastAssignNum = assn_num;
300  subAssignNum = 0;
301  }
302  }
310  const string& getTitle() const {
311  return title;
312  }
313 
321  void setTitle(const string& t) {
322  title = t;
323  }
329  const string& getDescription() const {
330  return description;
331  }
336  void setDescription(const string& descr) {
337  description = descr;
338  }
339 
348  ds_handle = ds;
349  }
350 
359  setDataStructure(&ds);
360  }
361 
368  return ds_handle;
369  }
370 
382  void setServer(string server_type) {
383  char* force = getenv("FORCE_BRIDGES_APISERVER");
384  if (force != nullptr) {
385  server_type = force;
386  }
387 
388  if (server_type == "live")
389  server_url = "http://bridges-cs.herokuapp.com";
390  else if (server_type == "clone")
391  server_url = "http://bridges-clone.herokuapp.com";
392  else if (server_type == "games")
393  server_url = "http://bridges-games.herokuapp.com";
394  else if (server_type == "local")
395  server_url = "http://127.0.0.1:3000";
396 
397  BASE_URL = server_url + "/assignments/";
398  }
399 
407  void setMapOverlay (bool overlay_flag) {
408  map_overlay = overlay_flag;
409  }
410 
422  void setMap(string map_str) {
423  map = map_str;
424  setMapAsJSON(false);
425  }
426 
427  /*
428  * @brief this function is used when US maps are drawn as
429  * an overlay behind a data structure view or when data
430  * attributes are assignment to states or counties
431  *
432  * See tutorial at https://bridgesuncc.github.io/tutorials/Map.html
433  *
434  */
435  void setMap(const Map* map) {
436  string map_str = map->getMapRepresentation();
437  setMapOverlay(map->getOverlay());
438  setCoordSystemType(map->getProjection());
439 
440  // get the string rep of the map json
441  this->map = map_str;
442  setMapAsJSON(true);
443  }
444 
445  // sets the map object
446  void setMap(const Map& map) {
447  setMap(&map);
448  }
449 
450 
451  // specifies the map object being send as a JSON or not
452  void setMapAsJSON(bool b) {
453  map_as_json = b;
454  }
455 
456  //TODO: What is this get map? This is clearly not how to access map data. What were we trying to do here? [KRS: Probably obsolete?]
457  string getMap(vector<string> states) {
458  string json_str;
459 
460  // form the url and get the state county data
461  string url = "http://bridgesdata.herokuapp.com/api/us_map?state=";
462  url += states[0];
463  // to do muultiple states -- later
464  // for (auto st : states)
465  // url += st + ",";
466  // url = url.substr(0, url.size()-1);
467 
468  return json_str;
469  }
470 
480  void setCoordSystemType (string coord) {
481  std::transform(coord.begin(), coord.end(), coord.begin(), ::tolower);
482  if (coord == "cartesian" || coord == "albersusa" || coord == "equirectangular"
483  || coord == "window")
484  coord_system_type = coord;
485  else {
486  cout << "Unrecognized coordinate system \'" + coord + "\', defaulting to "
487  << "cartesian. Options:";
488  for (auto proj : map_overlay_options)
489  cout << + "\t" ;
490  coord_system_type = "cartesian";
491  }
492  }
500  const string& getCoordSystemType () {
501  return coord_system_type;
502  }
503 
514  void setWindow (int xmin, int xmax, int ymin, int ymax) {
515  setWindow(double(xmin), double(xmax), double(ymin), double(ymax));
516  }
517 
528  void setWindow (double xmin, double xmax, double ymin, double ymax) {
529  wc_window.clear();
530  wc_window.push_back(xmin);
531  wc_window.push_back(xmax);
532  wc_window.push_back(ymin);
533  wc_window.push_back(ymax);
534  }
535 
536  string getVisualizeURL() const {
537  return BASE_URL + to_string(getAssignment()) + "/" + getUserName();
538  }
539 
546  void visualize() {
547  std::chrono::time_point<std::chrono::system_clock> start;
548  std::chrono::time_point<std::chrono::system_clock> end;
549  std::chrono::time_point<std::chrono::system_clock> jsonbuild_start;
550  std::chrono::time_point<std::chrono::system_clock> jsonbuild_end;
551  std::chrono::time_point<std::chrono::system_clock> httprequest_start;
552  std::chrono::time_point<std::chrono::system_clock> httprequest_end;
553 
554  if (profile())
555  start = std::chrono::system_clock::now();
556 
557  if (getAssignment() != lastAssignNum) { // reset if a new assignment
558  lastAssignNum = getAssignment();
559  subAssignNum = 0;
560  }
561  if (subAssignNum == 99) {
562  cout << "#sub-assignments limit(99) exceeded, visualization not generated .."
563  << endl;
564  return;
565  }
566  if (!ds_handle) {
567  cerr << "Error: Data Structure handle null! Visualization not generated.";
568  return;
569  }
570 
571  //
572  // get the JSON of the data structure
573  // each data structure is responsible for generating its own JSON
574  //
575  if (profile())
576  jsonbuild_start = std::chrono::system_clock::now();
577 
578  string ds_json;
579  // We are transitioning to using rapidjson to
580  // generate the JSON of the data structure reprsentation
581  Document doc;
582  StringBuffer sb;
583  Writer<StringBuffer> json_writer(sb); // for conversion to string
584  doc.SetObject();
585  if (ds_handle->getDStype() == "Scene") {
586  string ds_part_json = ds_handle->getDataStructureRepresentation();
587  // erase open curly brace
588  ds_part_json.erase(0, 1);
589  ds_json = getJSONHeader() + ds_part_json;
590  }
591  else if (ds_handle->getDStype() == "us_map") {
592  setMap((USMap*) ds_handle);
593  // string tmp = ds_handle->getDataStructureRepresentation();
594  // Document d;
595  // d.SetObject();
596  // Value key, value;
597  // key.SetString("mapdummy");
598  // value.SetBool(true);
599  // d.AddMember(key, value, d.GetAllocator());
600  // ds_json = getJSONHeader(d);
601  ds_json = getJSONHeader() + ds_handle->getDataStructureRepresentation();
602  // ds_json = getJSONHeader();
603  }
604  /*
605  else if (ds_handle->getDStype() == "LineChart"){
606 
607  // get the header information
608  string s = getJSONHeader(doc);
609 
610  // get the data structure representation
611  ds_handle->getDataStructureRepresentation(doc);
612  doc.Accept(json_writer);
613  ds_json = sb.GetString();
614  }
615  */
616  /*
617  else if (ds_handle->getDStype() == "SinglyLinkedList"){
618  ds_json = getJSONHeader() + ds_handle->getDataStructureRepresentation();
619  // getJSONHeader(doc);
620 
621  // doc.Accept(json_writer);
622  ds_handle->getDataStructureRepresentation(doc);
623  doc.Accept(json_writer);
624  ds_json = sb.GetString();
625  cout << "DS Rep(in visualize():\n" << sb.GetString() << endl;;
626 
627  }
628  */
629  else {
630  ds_json = getJSONHeader() + ds_handle->getDataStructureRepresentation();
631  }
632  if (profile())
633  jsonbuild_end = std::chrono::system_clock::now();
634 
635  //
636  // print JSON if flag is on
637  //
638  if (getJSONFlag()) {
639  cout << "JSON[" + ds_handle->getDStype() + "]:\t" << ds_json << endl;
640  }
641 
642  if (profile())
643  httprequest_start = std::chrono::system_clock::now();
644 
645  try { // send the JSON of assignment to the server
646  ServerComm::makeRequest(BASE_URL + to_string(getAssignment()) + "." +
647  (subAssignNum > 9 ? "" : "0") + to_string(subAssignNum) + "?apikey=" + getApiKey() +
648  "&username=" + getUserName(), {"Content-Type: text/plain"}, ds_json);
649 
650  if (post_visualization_link) {
651  cout << "Success: Assignment posted to the server. " << endl
652  << "Check out your visualization at:" << endl << endl
653  << getVisualizeURL() << endl << endl;
654  }
655  subAssignNum++;
656  }
657  catch (const string& error_str) {
658  cerr << "\nPosting assignment to the server failed!" << endl
659  << error_str << endl << endl;
660  cerr << "Provided Bridges Credentials:" << endl <<
661  "\t User Name: " << getUserName() << endl <<
662  "\t API Key: " << getApiKey() << endl <<
663  "\t Assignment Number: " << getAssignment() << endl;
664  }
665  catch (const HTTPException& he) {
666  cerr << "\nPosting assignment to the server failed!" << endl;
667  if (he.httpcode == 401) {
668  cerr << "Provided Bridges Credentials are incorrect:" << endl <<
669  "\t ServerURL: " << getServerURL() << endl <<
670  "\t User Name: " << getUserName() << endl <<
671  "\t API Key: " << getApiKey() << endl <<
672  "\t Assignment Number: " << getAssignment() << endl;
673  }
674  else if (he.httpcode == 413) {
675  cerr << "Assignment is too large." << endl;
676  cerr << "In general the assignment should be smaller than 16MB once serialized to JSON." << endl;
677  }
678  else {
679  std::cerr << he.what() << endl;
680  }
681  }
682  if (profile())
683  httprequest_end = std::chrono::system_clock::now();
684 
685  if (profile()) {
686  end = std::chrono::system_clock::now();
687 
688  std::chrono::duration<double> totaltime = end - start;
689  std::chrono::duration<double> jsonbuildtime = jsonbuild_end - jsonbuild_start;
690  std::chrono::duration<double> httptime = httprequest_end - httprequest_start;
691  std::cerr << "total visualize() time:" << totaltime.count() << " seconds"
692  << " (including JSON build time: " << jsonbuildtime.count() << " seconds"
693  << " and HTTP request time: " << httptime.count() << " seconds)."
694  << std::endl;
695  }
696  }
697 
698  private:
699  string getServerURL() const {
700  return server_url;
701  }
702 
703  string getJSONHeader(Document& d) {
704  Value key, value;
705 
706  key.SetString("visual", d.GetAllocator());
707  value.SetString(ds_handle->getDStype().c_str(), d.GetAllocator());
708  d.AddMember(key, value, d.GetAllocator());
709 
710  key.SetString("title", d.GetAllocator());
711  value.SetString(getTitle().c_str(), d.GetAllocator());
712  d.AddMember(key, value, d.GetAllocator());
713 
714  key.SetString("description", d.GetAllocator());
715  value.SetString(getDescription().c_str(), d.GetAllocator());
716  d.AddMember(key, value, d.GetAllocator());
717 
718  key.SetString("map", d.GetAllocator());
719  value.SetString(map.c_str(), d.GetAllocator());
720  d.AddMember(key, value, d.GetAllocator());
721 
722  key.SetString("map_overlay", d.GetAllocator());
723  value.SetBool((map_overlay) ? true : false);
724  d.AddMember(key, value, d.GetAllocator());
725 
726  key.SetString("element_label_flag", d.GetAllocator());
727  value.SetBool(element_labelFlag);
728  d.AddMember(key, value, d.GetAllocator());
729 
730  key.SetString("link_label_flag", d.GetAllocator());
731  value.SetBool(link_labelFlag);
732  d.AddMember(key, value, d.GetAllocator());
733 
734  key.SetString("coord_system_type", d.GetAllocator());
735  value.SetString(getCoordSystemType().c_str(), d.GetAllocator());
736  d.AddMember(key, value, d.GetAllocator());
737 
738  if (wc_window.size() == 4) {// world coord window has been specified
739  Value v;
740  d.SetArray();
741  Value w_array(kArrayType);
742  w_array.PushBack(v.SetDouble(wc_window[0]), d.GetAllocator());
743  w_array.PushBack(v.SetDouble(wc_window[1]), d.GetAllocator());
744  w_array.PushBack(v.SetDouble(wc_window[2]), d.GetAllocator());
745  w_array.PushBack(v.SetDouble(wc_window[3]), d.GetAllocator());
746 
747  d.AddMember("window", w_array, d.GetAllocator());
748  }
749  // conver JSON to a string
750  StringBuffer s;
751  Writer<StringBuffer> writer(s);
752  d.Accept(writer);
753 
754  return s.GetString();
755  }
756 
757  string getJSONHeader () {
759 
760  string json_header = OPEN_CURLY +
761  QUOTE + "visual" + QUOTE + COLON + JSONencode(ds_handle->getDStype()) + COMMA +
762  QUOTE + "title" + QUOTE + COLON + JSONencode(getTitle()) + COMMA +
763  QUOTE + "description" + QUOTE + COLON + JSONencode( getDescription()) + COMMA +
764  QUOTE + "map_overlay" + QUOTE + COLON +
765  ((map_overlay) ? "true" : "false") + COMMA;
766  if (map_as_json)
767  json_header += QUOTE + "map" + QUOTE + COLON + map + COMMA;
768  else
769  json_header += QUOTE + "map" + QUOTE + COLON + QUOTE + map + QUOTE + COMMA;
770 
771  json_header += QUOTE + "element_label_flag" + QUOTE + COLON + ((element_labelFlag) ? "true" : "false") + COMMA +
772  QUOTE + "link_label_flag" + QUOTE + COLON + ((link_labelFlag) ? "true" : "false") + COMMA +
773  QUOTE + "coord_system_type" + QUOTE + COLON + JSONencode(getCoordSystemType()) +
774  COMMA;
775 
776  if (wc_window.size() == 4) { // world coord window has been specified
777  json_header += QUOTE + string("window") + QUOTE + COLON + OPEN_BOX;
778  json_header += std::to_string(wc_window[0]) + COMMA +
779  std::to_string(wc_window[1]) + COMMA +
780  std::to_string(wc_window[2]) + COMMA + std::to_string(wc_window[3]);
781  json_header += CLOSE_BOX + COMMA;
782 
783  }
784 
785  return json_header;
786  }
787 
788  friend DataSource;
790  }; //end of class Bridges
791 
792 } // end of bridges namespace
793 #endif
This class contains methods to connect and transmit a user's data structure representation to the Bri...
Definition: Bridges.h:50
string getVisualizeURL() const
Definition: Bridges.h:536
void setWindow(int xmin, int xmax, int ymin, int ymax)
Definition: Bridges.h:514
bool getLinkLabelFlag() const
Return status of flag for link labels.
Definition: Bridges.h:184
void setMap(string map_str)
Sets the type of map overlay to use.
Definition: Bridges.h:422
Bridges(const string &name, const string &key)
constructor to bridges
Definition: Bridges.h:115
void setMapOverlay(bool overlay_flag)
Turns on map overlay for subsequent visualizations - used with location specific datasets.
Definition: Bridges.h:407
void visualize()
Definition: Bridges.h:546
void setUserName(string name)
Set user name.
Definition: Bridges.h:239
bool getElementLabelFlag() const
status of flag for element labels
Definition: Bridges.h:174
void setDataStructure(DataStructure &ds)
Definition: Bridges.h:358
void setMap(const Map &map)
Definition: Bridges.h:446
void setServer(string server_type)
Definition: Bridges.h:382
void setApiKey(string key)
Set API key credentials.
Definition: Bridges.h:265
DataStructure * getDataStructure()
Definition: Bridges.h:367
void setDataStructure(DataStructure *ds)
Definition: Bridges.h:347
void postVisualizationLink(bool link_url)
Definition: Bridges.h:207
const string & getTitle() const
Definition: Bridges.h:310
void setMapAsJSON(bool b)
Definition: Bridges.h:452
const string & getApiKey() const
Definition: Bridges.h:252
void setWindow(double xmin, double xmax, double ymin, double ymax)
sets the world coordinate window defining the space of the user defined objects (or nodes)
Definition: Bridges.h:528
void setDescription(const string &descr)
Definition: Bridges.h:336
unsigned int getAssignment() const
Definition: Bridges.h:278
Bridges(unsigned int num, const string &name, const string &key)
constructor to bridges
Definition: Bridges.h:138
Bridges()
Definition: Bridges.h:100
const string & getCoordSystemType()
Definition: Bridges.h:500
void setLinkLabelFlag(bool flag)
Flag that controls if labels of links(edges) are to be turned on/off.
Definition: Bridges.h:164
void setTitle(const string &t)
Definition: Bridges.h:321
void setAssignment(unsigned int num)
Definition: Bridges.h:290
void setCoordSystemType(string coord)
Definition: Bridges.h:480
const string & getUserName() const
Definition: Bridges.h:227
void setJSONFlag(bool flag)
Definition: Bridges.h:216
string getMap(vector< string > states)
Definition: Bridges.h:457
bool getJSONFlag() const
Definition: Bridges.h:194
void setMap(const Map *map)
Definition: Bridges.h:435
const string & getDescription() const
Definition: Bridges.h:329
void setElementLabelFlag(bool flag)
Flag that controls if labels of elements (nodes) are to be turned on.
Definition: Bridges.h:153
This is the superclass of all data structure types in BRIDGES.
Definition: DataStructure.h:74
virtual const string getDStype() const =0
Abstract class for Map API.
Definition: Map.h:16
virtual const string getProjection() const =0
virtual const bool getOverlay() const =0
virtual const string getMapRepresentation() const =0
This class provides an API to building, displaying and manipulating US maps and counties in BRIDGES.
Definition: USMap.h:52
This is meant to be an internal class, not something that the library user will use.
Definition: SocketConnection.h:48
std::string JSONencode(const T &d)
Definition: JSONutil.h:38
Definition: Array.h:9
Support for drawing Bar charts.
Definition: alltypes.h:4
const string COLON
Definition: DataStructure.h:52
const string OPEN_BOX
Definition: DataStructure.h:55
const string COMMA
Definition: DataStructure.h:51
const string OPEN_CURLY
Definition: DataStructure.h:53
const string CLOSE_BOX
Definition: DataStructure.h:56
const string QUOTE
Definition: DataStructure.h:50
Definition: ServerComm.h:17
virtual const char * what() const noexcept
Definition: ServerComm.h:35
long httpcode
Definition: ServerComm.h:19