Bridges-C++ 3.5.0-dev2-1-ge3e57bf
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>
6using 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 <WorldMap.h>
18#include <rapidjson/document.h>
19#include <rapidjson/stringbuffer.h>
20#include <rapidjson/writer.h>
21
22namespace bridges {
23 using namespace bridges::datastructure;
24 using namespace rapidjson;
25
26 namespace game {
27 class SocketConnection;
28 }
51 class Bridges {
52 private:
53 static bool profile() {
54 return false;
55 }
56
57 static string getDefaultServerURL() {
58 return "http://assignments.bridgesuncc.org";
59 }
60
61 bool jsonFlag = false; // if JSON is to be printed
62
63 // this flag will turn on all labels in the visualization
64 bool element_labelFlag = false, link_labelFlag = false;
65
66 bool post_visualization_link = true; // post flag of visualization url
67
68 string user_name = string(),
69 api_key = string(); // user credentials
70
71 string map; // for map overlays
72 bool map_as_json = false;
73
74 string description = string(); // visualization description
75
76 string title = string(); // title of visualization
77
78 unsigned int assn_num = 0; // assignment id
79
80 DataStructure* ds_handle = nullptr; // data structure handle
81
82 string server_url = "http://assignments.bridgesuncc.org";
83
84 string BASE_URL = server_url + "/assignments/";
85
86 // map overlay options
87 string map_overlay_options[3] = {"cartesian", "albersusa", "equirectangular"};
88 bool map_overlay = false;
89 string coord_system_type = "cartesian";
90
91 // world coordinate window
92 vector<double> wc_window;
93
94 unsigned int lastAssignNum = 0, subAssignNum = 0;
95
96 // JSON object - contains the data structure representationa
97 rapidjson::Writer<rapidjson::StringBuffer> json_obj;
98
99 public:
100
102 Bridges (0, "", "");
103 }
116 Bridges (const string& name, const string& key) {
117 Bridges (0, name, key);
118 }
139 Bridges (unsigned int num, const string& name, const string& key) {
140 setAssignment(num);
141 setUserName(name);
142 setApiKey(key);
143 setServer("live");
144 }
145
154 void setElementLabelFlag(bool flag) {
155 element_labelFlag = flag;
156 }
165 void setLinkLabelFlag(bool flag) {
166 link_labelFlag = flag;
167 }
168
175 bool getElementLabelFlag() const {
176 return element_labelFlag;
177 }
185 bool getLinkLabelFlag() const {
186 return link_labelFlag;
187 }
188
195 bool getJSONFlag() const {
196 return jsonFlag;
197 }
198
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 }
330 const string& getDescription() const {
331 return description;
332 }
338 void setDescription(const string& descr) {
339 description = descr;
340 }
341
350 ds_handle = ds;
351 }
352
361 setDataStructure(&ds);
362 }
363
370 return ds_handle;
371 }
372
384 void setServer(string server_type) {
385 char* force = getenv("FORCE_BRIDGES_APISERVER");
386 if (force != nullptr) {
387 server_type = force;
388 }
389
390 if (server_type == "live")
391 server_url = "http://assignments.bridgesuncc.org";
392 else if (server_type == "clone")
393 server_url = "http://assignments-clone.bridgesuncc.org";
394 else if (server_type == "games")
395 server_url = "http://games.bridgesuncc.org";
396 else if (server_type == "games-clone")
397 server_url = "http://games-clone.bridgesuncc.org";
398 else if (server_type == "local")
399 server_url = "http://127.0.0.1:3000";
400
401 BASE_URL = server_url + "/assignments/";
402 }
403
411 void setMapOverlay (bool overlay_flag) {
412 map_overlay = overlay_flag;
413 }
414
423 void setMap(string map_str) {
424 map = map_str;
425 setMapAsJSON(false);
426 }
427
428 /*
429 * @brief this function is used when US maps are drawn as
430 * an overlay behind a data structure view or when data
431 * attributes are assignment to states or counties
432 *
433 * See tutorial at https://bridgesuncc.github.io/tutorials/Map.html
434 *
435 */
436 void setMap(const Map* map) {
437 string map_str = map->getMapRepresentation();
440
441 // get the string rep of the map json
442 this->map = map_str;
443 setMapAsJSON(true);
444 }
445
446 // sets the map object
447 void setMap(const Map& map) {
448 setMap(&map);
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://static-data.bridgesuncc.org/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
547 void visualize() {
548 std::chrono::time_point<std::chrono::system_clock> start;
549 std::chrono::time_point<std::chrono::system_clock> end;
550 std::chrono::time_point<std::chrono::system_clock> jsonbuild_start;
551 std::chrono::time_point<std::chrono::system_clock> jsonbuild_end;
552 std::chrono::time_point<std::chrono::system_clock> httprequest_start;
553 std::chrono::time_point<std::chrono::system_clock> httprequest_end;
554
555 if (profile())
556 start = std::chrono::system_clock::now();
557
558 if (getAssignment() != lastAssignNum) { // reset if a new assignment
559 lastAssignNum = getAssignment();
560 subAssignNum = 0;
561 }
562 if (subAssignNum == 99) {
563 cout << "#sub-assignments limit(99) exceeded, visualization not generated .."
564 << endl;
565 return;
566 }
567 if (!ds_handle) {
568 cerr << "Error: Data Structure handle null! Visualization not generated.";
569 return;
570 }
571
572 //
573 // get the JSON of the data structure
574 // each data structure is responsible for generating its own JSON
575 //
576 if (profile())
577 jsonbuild_start = std::chrono::system_clock::now();
578
579 string ds_json;
580 // We are transitioning to using rapidjson to
581 // generate the JSON of the data structure reprsentation
582 Document doc;
583 StringBuffer sb;
584 Writer<StringBuffer> json_writer(sb); // for conversion to string
585 doc.SetObject();
586 if (ds_handle->getDStype() == "Scene") {
587 string ds_part_json = ds_handle->getDataStructureRepresentation();
588 // erase open curly brace
589 ds_part_json.erase(0, 1);
590 ds_json = getJSONHeader() + ds_part_json;
591 }
592 else if (ds_handle->getDStype() == "us_map") {
593 setMap((USMap*) ds_handle);
594 // string tmp = ds_handle->getDataStructureRepresentation();
595 // Document d;
596 // d.SetObject();
597 // Value key, value;
598 // key.SetString("mapdummy");
599 // value.SetBool(true);
600 // d.AddMember(key, value, d.GetAllocator());
601 // ds_json = getJSONHeader(d);
602 ds_json = getJSONHeader() + ds_handle->getDataStructureRepresentation();
603 // ds_json = getJSONHeader();
604 }
605 else if (ds_handle->getDStype() == "world_map") {
606 setMap((WorldMap*) ds_handle);
607 ds_json = getJSONHeader() + ds_handle->getDataStructureRepresentation();
608 //exit(0);
609 }
610 /*
611 else if (ds_handle->getDStype() == "LineChart"){
612
613 // get the header information
614 string s = getJSONHeader(doc);
615
616 // get the data structure representation
617 ds_handle->getDataStructureRepresentation(doc);
618 doc.Accept(json_writer);
619 ds_json = sb.GetString();
620 }
621 */
622 /*
623 else if (ds_handle->getDStype() == "SinglyLinkedList"){
624 ds_json = getJSONHeader() + ds_handle->getDataStructureRepresentation();
625 // getJSONHeader(doc);
626
627 // doc.Accept(json_writer);
628 ds_handle->getDataStructureRepresentation(doc);
629 doc.Accept(json_writer);
630 ds_json = sb.GetString();
631 cout << "DS Rep(in visualize():\n" << sb.GetString() << endl;;
632
633 }
634 */
635 else {
636 ds_json = getJSONHeader() + ds_handle->getDataStructureRepresentation();
637 }
638 if (profile())
639 jsonbuild_end = std::chrono::system_clock::now();
640
641 //
642 // print JSON if flag is on
643 //
644 if (getJSONFlag()) {
645 cout << "JSON[" + ds_handle->getDStype() + "]:\t" << ds_json << endl;
646 }
647
648 if (profile())
649 httprequest_start = std::chrono::system_clock::now();
650
651 try { // send the JSON of assignment to the server
652 ServerComm::makeRequest(BASE_URL + to_string(getAssignment()) + "." +
653 (subAssignNum > 9 ? "" : "0") + to_string(subAssignNum) + "?apikey=" + getApiKey() +
654 "&username=" + getUserName(), {"Content-Type: text/plain"}, ds_json);
655
656 if (post_visualization_link) {
657 cout << "Success: Assignment posted to the server. " << endl
658 << "Check out your visualization at:" << endl << endl
659 << getVisualizeURL() << endl << endl;
660 }
661 subAssignNum++;
662 }
663 catch (const string& error_str) {
664 cerr << "\nPosting assignment to the server failed!" << endl
665 << error_str << endl << endl;
666 cerr << "Provided Bridges Credentials:" << endl <<
667 "\t User Name: " << getUserName() << endl <<
668 "\t API Key: " << getApiKey() << endl <<
669 "\t Assignment Number: " << getAssignment() << endl;
671 }
672 catch (const HTTPException& he) {
673 cerr << "\nPosting assignment to the server failed!" << endl;
674 if (he.httpcode == 401) {
675 cerr << "Provided Bridges Credentials are incorrect:" << endl <<
676 "\t ServerURL: " << getServerURL() << endl <<
677 "\t User Name: " << getUserName() << endl <<
678 "\t API Key: " << getApiKey() << endl <<
679 "\t Assignment Number: " << getAssignment() << endl;
680 }
681 else if (he.httpcode == 413) {
682 cerr << "Assignment is too large." << endl;
683 cerr << "In general the assignment should be smaller than 16MB once serialized to JSON." << endl;
684 }
685 else {
686 std::cerr << he.what() << endl;
687 }
688 throw;
689 }
690 if (profile())
691 httprequest_end = std::chrono::system_clock::now();
692
693 if (profile()) {
694 end = std::chrono::system_clock::now();
695
696 std::chrono::duration<double> totaltime = end - start;
697 std::chrono::duration<double> jsonbuildtime = jsonbuild_end - jsonbuild_start;
698 std::chrono::duration<double> httptime = httprequest_end - httprequest_start;
699 std::cerr << "total visualize() time:" << totaltime.count() << " seconds"
700 << " (including JSON build time: " << jsonbuildtime.count() << " seconds"
701 << " and HTTP request time: " << httptime.count() << " seconds)."
702 << std::endl;
703 }
704 }
705
706 private:
707 string getServerURL() const {
708 return server_url;
709 }
710
711 string getJSONHeader(Document& d) {
712 Value key, value;
713
714 key.SetString("visual", d.GetAllocator());
715 value.SetString(ds_handle->getDStype().c_str(), d.GetAllocator());
716 d.AddMember(key, value, d.GetAllocator());
717
718 key.SetString("title", d.GetAllocator());
719 value.SetString(getTitle().c_str(), d.GetAllocator());
720 d.AddMember(key, value, d.GetAllocator());
721
722 key.SetString("description", d.GetAllocator());
723 value.SetString(getDescription().c_str(), d.GetAllocator());
724 d.AddMember(key, value, d.GetAllocator());
725
726 key.SetString("map", d.GetAllocator());
727 value.SetString(map.c_str(), d.GetAllocator());
728 d.AddMember(key, value, d.GetAllocator());
729
730 key.SetString("map_overlay", d.GetAllocator());
731 value.SetBool((map_overlay) ? true : false);
732 d.AddMember(key, value, d.GetAllocator());
733
734 key.SetString("element_label_flag", d.GetAllocator());
735 value.SetBool(element_labelFlag);
736 d.AddMember(key, value, d.GetAllocator());
737
738 key.SetString("link_label_flag", d.GetAllocator());
739 value.SetBool(link_labelFlag);
740 d.AddMember(key, value, d.GetAllocator());
741
742 key.SetString("coord_system_type", d.GetAllocator());
743 value.SetString(getCoordSystemType().c_str(), d.GetAllocator());
744 d.AddMember(key, value, d.GetAllocator());
745
746 if (wc_window.size() == 4) {// world coord window has been specified
747 Value v;
748 d.SetArray();
749 Value w_array(kArrayType);
750 w_array.PushBack(v.SetDouble(wc_window[0]), d.GetAllocator());
751 w_array.PushBack(v.SetDouble(wc_window[1]), d.GetAllocator());
752 w_array.PushBack(v.SetDouble(wc_window[2]), d.GetAllocator());
753 w_array.PushBack(v.SetDouble(wc_window[3]), d.GetAllocator());
754
755 d.AddMember("window", w_array, d.GetAllocator());
756 }
757 // conver JSON to a string
758 StringBuffer s;
759 Writer<StringBuffer> writer(s);
760 d.Accept(writer);
761
762 return s.GetString();
763 }
764
765 string getJSONHeader () {
767
768 string json_header = OPEN_CURLY +
769 QUOTE + "visual" + QUOTE + COLON + JSONencode(ds_handle->getDStype()) + COMMA +
770 QUOTE + "title" + QUOTE + COLON + JSONencode(getTitle()) + COMMA +
771 QUOTE + "description" + QUOTE + COLON + JSONencode( getDescription()) + COMMA +
772 QUOTE + "map_overlay" + QUOTE + COLON +
773 ((map_overlay) ? "true" : "false") + COMMA;
774 if (map_as_json)
775 json_header += QUOTE + "map" + QUOTE + COLON + map + COMMA;
776 else
777 json_header += QUOTE + "map" + QUOTE + COLON + QUOTE + map + QUOTE + COMMA;
778
779 json_header += QUOTE + "element_label_flag" + QUOTE + COLON + ((element_labelFlag) ? "true" : "false") + COMMA +
780 QUOTE + "link_label_flag" + QUOTE + COLON + ((link_labelFlag) ? "true" : "false") + COMMA +
781 QUOTE + "coord_system_type" + QUOTE + COLON + JSONencode(getCoordSystemType()) +
782 COMMA;
783
784 if (wc_window.size() == 4) { // world coord window has been specified
785 json_header += QUOTE + string("window") + QUOTE + COLON + OPEN_BOX;
786 json_header += std::to_string(wc_window[0]) + COMMA +
787 std::to_string(wc_window[1]) + COMMA +
788 std::to_string(wc_window[2]) + COMMA + std::to_string(wc_window[3]);
789 json_header += CLOSE_BOX + COMMA;
790
791 }
792
793 return json_header;
794 }
795
796 friend DataSource;
798 }; //end of class Bridges
799
800} // end of bridges namespace
801#endif
This class contains methods to connect and transmit a user's data structure representation to the Bri...
Definition: Bridges.h:51
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:185
void setMap(string map_str)
Sets the type of map overlay to use.
Definition: Bridges.h:423
Bridges(const string &name, const string &key)
constructor to bridges
Definition: Bridges.h:116
void setMapOverlay(bool overlay_flag)
Turns on map overlay for subsequent visualizations - used with location specific datasets.
Definition: Bridges.h:411
void visualize()
Definition: Bridges.h:547
const string & getApiKey() const
Definition: Bridges.h:252
void setUserName(string name)
Set user name.
Definition: Bridges.h:239
bool getElementLabelFlag() const
status of flag for element labels
Definition: Bridges.h:175
void setDataStructure(DataStructure &ds)
Definition: Bridges.h:360
void setMap(const Map &map)
Definition: Bridges.h:447
const string & getDescription() const
Definition: Bridges.h:330
void setServer(string server_type)
Definition: Bridges.h:384
void setApiKey(string key)
Set API key credentials.
Definition: Bridges.h:265
const string & getCoordSystemType()
Definition: Bridges.h:500
void setDataStructure(DataStructure *ds)
Definition: Bridges.h:349
void postVisualizationLink(bool link_url)
Definition: Bridges.h:207
void setMapAsJSON(bool b)
Definition: Bridges.h:452
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:338
unsigned int getAssignment() const
Definition: Bridges.h:278
Bridges(unsigned int num, const string &name, const string &key)
constructor to bridges
Definition: Bridges.h:139
Bridges()
Definition: Bridges.h:101
const string & getTitle() const
Definition: Bridges.h:310
void setLinkLabelFlag(bool flag)
Flag that controls if labels of links(edges) are to be turned on/off.
Definition: Bridges.h:165
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:195
void setMap(const Map *map)
Definition: Bridges.h:436
void setElementLabelFlag(bool flag)
Flag that controls if labels of elements (nodes) are to be turned on.
Definition: Bridges.h:154
DataStructure * getDataStructure()
Definition: Bridges.h:369
This class provides an API to various data sources used in BRIDGES.
Definition: DataSource.h:69
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:56
This class provides an API to building, displaying and manipulating World maps and countries in BRIDG...
Definition: WorldMap.h:51
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
these methods convert byte arrays in to base64 codes and are used in BRIDGES to represent the color a...
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: bridges_exception.h:18
long httpcode
Definition: bridges_exception.h:20
Definition: bridges_exception.h:6
virtual const char * what() const noexcept
Definition: bridges_exception.h:13