6#include <unordered_map>
36#include "rapidjson/document.h"
37#include <rapidjson/istreamwrapper.h>
39#include "rapidjson/error/en.h"
73 bool debug_flag =
false;
79 void set_debug_flag() {
86 string getOSMBaseURL()
const {
87 if (sourceType ==
"local")
88 return "http://localhost:3000/";
90 return "http://osm-data.bridgesuncc.org/";
92 string getElevationBaseURL()
const {
93 if (sourceType ==
"local")
94 return "http://localhost:3000/";
96 return "http://elevation-data.bridgesuncc.org/";
98 string getGutenbergBaseURL()
const {
99 if (sourceType ==
"local")
100 return "http://localhost:3000/";
102 if (sourceType ==
"testing")
103 return "http://gutenberg-t-data.bridgesuncc.org/";
105 return "http://gutenberg-data.bridgesuncc.org/";
107 string getRedditURL() {
108 if (sourceType ==
"testing")
109 return "http://reddit-t-data.bridgesuncc.org";
110 else if (sourceType ==
"local")
111 return "http://localhost:9999";
113 return "http://reddit-data.bridgesuncc.org";
116 string sourceType =
"live";
118 string getUSCitiesURL() {
119 return "http://static-data.bridgesuncc.org/api/us_cities";
122 string getWorldCitiesURL() {
123 return "http://static-data.bridgesuncc.org/api/world_cities";
126 string getUSStateCountiesURL() {
127 return "http://static-data.bridgesuncc.org/api/us_map?state=";
130 string getWorldCountriesURL() {
131 return "http://static-data.bridgesuncc.org/api/world_map";
134 void defaultDebug() {
135 char* force = getenv(
"FORCE_BRIDGES_DATADEBUG");
136 if (force !=
nullptr)
143 : bridges_inst(br), my_cache(120) {
160 if ( !((type ==
"live") || (type ==
"testing") || (type ==
"local")))
161 throw "Incorrect data server type. Must be live, testing or local";
162 if ((type ==
"testing") || (type ==
"local"))
195 keys.insert(
"state");
196 keys.insert(
"country");
197 keys.insert(
"min_elev");
198 keys.insert(
"max_elev");
199 keys.insert(
"min_pop");
200 keys.insert(
"max_pop");
201 keys.insert(
"min_long");
202 keys.insert(
"max_long");
203 keys.insert(
"min_lat");
204 keys.insert(
"max_lat");
205 keys.insert(
"limit");
206 keys.insert(
"time_zone");
208 unordered_map<string, string>::iterator it;
209 for (it = params.begin(); it != params.end(); it++) {
210 if (keys.find(it->first) == keys.end())
211 throw std::invalid_argument (
"\n\nKey value : " + it->first +
212 " incorrect\n\n Legal key values: \n 'city', 'state', 'country', 'min_lat', 'max_lat', 'min_long', 'max_long', 'min_pop', 'max_pop', 'time_zone', 'limit' ");
215 string url = getUSCitiesURL() +
"?";
216 if (params.find(
"city") != params.end())
217 url +=
"city=" + ServerComm::encodeURLPart(params[
"city"]) +
"&";
218 if (params.find(
"state") != params.end())
219 url +=
"state=" + ServerComm::encodeURLPart(params[
"state"]) +
"&";
220 if (params.find(
"country") != params.end())
221 url +=
"country=" + ServerComm::encodeURLPart(params[
"country"]) +
"&";
222 if (params.find(
"min_lat") != params.end())
223 url +=
"minLat=" + ServerComm::encodeURLPart(params[
"min_lat"]) +
"&";
224 if (params.find(
"max_lat") != params.end())
225 url +=
"maxLat=" + ServerComm::encodeURLPart(params[
"max_lat"]) +
"&";
226 if (params.find(
"min_long") != params.end())
227 url +=
"minLong=" + ServerComm::encodeURLPart(params[
"min_long"]) +
"&";
228 if (params.find(
"max_long") != params.end())
229 url +=
"maxLong=" + ServerComm::encodeURLPart(params[
"max_long"]) +
"&";
230 if (params.find(
"min_elev") != params.end())
231 url +=
"minElevation=" + ServerComm::encodeURLPart(params[
"min_elev"]) +
"&";
232 if (params.find(
"max_elev") != params.end())
233 url +=
"maxElevation=" + ServerComm::encodeURLPart(params[
"max_elev"]) +
"&";
234 if (params.find(
"min_pop") != params.end())
235 url +=
"minPopulation=" + ServerComm::encodeURLPart(params[
"min_pop"]) +
"&";
236 if (params.find(
"maxPopulation") != params.end())
237 url +=
"max_pop=" + ServerComm::encodeURLPart(params[
"max_pop"]) +
"&";
238 if (params.find(
"limit") != params.end())
239 url +=
"limit=" + ServerComm::encodeURLPart(params[
"limit"]) +
"&";
242 url = url.substr(0, url.length() - 1);
245 using namespace rapidjson;
248 ServerComm::makeRequest(url, {
"Accept: application/json"}).c_str()
252 const Value& city_json = doc[
"data"];
253 vector<City> us_cities;
254 for (SizeType i = 0; i < city_json.Size(); i++) {
255 const Value& val = city_json[i];
256 us_cities.push_back (
258 val[
"city"].GetString(),
259 val[
"state"].GetString(),
260 val[
"country"].GetString(),
261 val[
"timezone"].GetString(),
262 val[
"elevation"].GetInt(),
263 val[
"population"].GetInt(),
264 val[
"lat"].GetDouble(),
265 val[
"lon"].GetDouble()
300 bool view_counties =
true) {
303 string url = getUSStateCountiesURL();
304 for (
auto& k : state_names)
305 url += ServerComm::encodeURLPart(k) +
',';
308 url = url.substr(0, url.size() - 1);
311 std::cerr <<
"Hitting: " << url << std::endl;
314 using namespace rapidjson;
317 ServerComm::makeRequest(url, {
"Accept: application/json"}).c_str()
322 vector<USState> states;
323 const Value& state_data = doc[
"data"];
324 for (SizeType i = 0; i < state_names.size(); i++) {
325 const Value& st = state_data[i];
326 const Value& county_data = st[
"counties"];
327 const Value& st_name = st[
"_id"][
"input"];
330 states.push_back(
USState(st_name.GetString()));
331 unordered_map<string, USCounty> counties = states[i].getCounties();
333 states[i].setViewCountiesFlag(view_counties);
337 for (SizeType j = 0; j < county_data.Size(); j++) {
338 const Value& val = county_data[j];
340 string geoid = (val[
"properties"][
"GEOID"]).GetString();
342 (val[
"properties"][
"FIPS_CODE"]).GetString(),
343 (val[
"properties"][
"COUNTY_STATE_CODE"]).GetString(),
344 (val[
"properties"][
"COUNTY_STATE_NAME"]).GetString()
350 states[i].setCounties(counties);
370 vector<Country> country_data;
372 if (countries[0] ==
"all")
375 string url = getWorldCountriesURL();
378 std::cerr <<
"Hitting: " << url << std::endl;
381 using namespace rapidjson;
384 ServerComm::makeRequest(url, {
"Accept: application/json"}).c_str()
389 unordered_map<string, Country> country_map;
390 const Value& country_json = doc[
"data"];
391 for (SizeType i = 0; i < country_json.Size(); i++) {
392 const Value& cval = country_json[i];
393 string name = string(cval[
"name"].GetString());
395 string(cval[
"name"].GetString()),
396 string(cval[
"alpha-2"].GetString()),
397 string(cval[
"alpha-3"].GetString()),
398 cval[
"numeric-3"].GetInt(),
405 for (
auto c : countries) {
406 country_data.push_back(country_map[c]);
424 using namespace rapidjson;
429 ServerComm::makeRequest(
"http://static-data.bridgesuncc.org/api/games",
430 {
"Accept: application/json"}).c_str());
432 const Value& D = d[
"data"];
433 vector<Game> wrapper;
434 for (SizeType i = 0; i < D.Size(); i++) {
435 const Value& V = D[i];
436 const Value& G = V[
"genre"];
438 vector<string> genre;
439 for (SizeType j = 0; j < G.Size(); j++) {
440 genre.push_back(G[j].GetString());
443 Game( V[
"game"].GetString(),
444 V[
"platform"].GetString(),
445 V[
"rating"].GetDouble(),
462 using namespace rapidjson;
464 vector<ActorMovieIMDB> wrapper;
465 string url =
"http://static-data.bridgesuncc.org/api/imdb?limit=" +
469 d.Parse(ServerComm::makeRequest( url, {
"Accept: application/json"}).c_str());
471 const Value& D = d[
"data"];
472 for (SizeType i = 0; i < D.Size(); i++) {
473 const Value& V = D[i];
476 V[
"actor"].GetString(),
477 V[
"movie"].GetString()
495 using namespace rapidjson;
497 vector<ActorMovieIMDB> wrapper;
498 string url =
"http://static-data.bridgesuncc.org/api/imdb2";
501 d.Parse(ServerComm::makeRequest( url, {
"Accept: application/json"}).c_str());
503 const Value& D = d[
"data"];
504 for (SizeType i = 0; i < D.Size(); i++) {
505 const Value& V = D[i];
506 string actor = V[
"actor"].GetString();
507 string movie = V[
"movie"].GetString();
508 double rating = V[
"rating"].GetDouble();
509 const Value& G = V[
"genres"];
510 vector<string> genres;
511 for (SizeType j = 0; j < G.Size(); j++) {
512 genres.push_back(G[j].GetString());
514 wrapper.push_back(
ActorMovieIMDB( actor, movie, (
float)rating, genres));
533 using namespace rapidjson;
535 vector<EarthquakeUSGS> wrapper;
537 d.Parse(ServerComm::makeRequest(
"http://earthquakes-data.bridgesuncc.org/eq",
538 {
"Accept: application/json"}).c_str());
541 d.Parse(ServerComm::makeRequest(
"http://earthquakes-data.bridgesuncc.org/eq/latest/" +
542 to_string(number), {
"Accept: application/json"}).c_str());
545 const Value& D = d[
"Earthquakes"];
546 for (SizeType i = 0; i < D.Size(); i++) {
547 const Value& V = D[i][
"properties"];
548 const Value& G = D[i][
"geometry"][
"coordinates"];
551 V[
"mag"].GetDouble(),
554 V[
"place"].GetString(),
555 V[
"title"].GetString(),
556 V[
"url"].GetString(),
557 V[
"time"].GetString() )
579 bool textonly =
false) {
580 using namespace rapidjson;
582 vector<Shakespeare> wrapper;
584 string url =
"http://static-data.bridgesuncc.org/api/shakespeare/";
586 if (type ==
"plays" || type ==
"poems")
587 url +=
"/" + ServerComm::encodeURLPart(type);
589 url +=
"?format=simple";
592 d.Parse(ServerComm::makeRequest( url, {
"Accept: application/json"}).c_str());
594 const Value& D = d[
"data"];
595 for (SizeType i = 0; i < D.Size(); i++) {
596 const Value& V = D[i];
599 V[
"title"].GetString(),
600 V[
"type"].GetString(),
601 V[
"text"].GetString()
628 using namespace rapidjson;
631 vector<Song> wrapper;
632 string url =
"http://static-data.bridgesuncc.org/api/songs/find/";
634 if (songTitle.size() > 0)
635 url += ServerComm::encodeURLPart(songTitle);
637 throw "Incorrect use of getSong. songTitle should be given.";
640 if (artistName.size() > 0)
641 url +=
"?artistName=" + ServerComm::encodeURLPart(artistName);
644 std::cerr <<
"url: " << url <<
"\n";
645 d.Parse(ServerComm::makeRequest( url, {
"Accept: application/json"}).c_str());
647 string artist = (d.HasMember(
"artist")) ?
648 d[
"artist"].GetString() : string();
649 string song = (d.HasMember(
"song")) ?
650 d[
"song"].GetString() : string();
651 string album = (d.HasMember(
"album")) ?
652 d[
"album"].GetString() : string();
653 string lyrics = (d.HasMember(
"lyrics")) ?
654 d[
"lyrics"].GetString() : string();
655 string release_date = (d.HasMember(
"release_date")) ?
656 d[
"release_date"].GetString() : string();
658 return Song (artist, song, album, lyrics, release_date);
676 using namespace rapidjson;
679 vector<Song> all_songs;
681 string url =
"http://static-data.bridgesuncc.org/api/songs/";
684 d.Parse(ServerComm::makeRequest( url, {
"Accept: application/json"}).c_str());
686 const Value& D = d[
"data"];
689 for (SizeType i = 0; i < D.Size(); i++) {
690 const Value& v = D[i];
693 string artist = (v.HasMember(
"artist")) ? v[
"artist"].GetString() : string();
694 string song = (v.HasMember(
"song")) ? v[
"song"].GetString() : string();
695 string album = (v.HasMember(
"album")) ? v[
"album"].GetString() : string();
696 string lyrics = (v.HasMember(
"lyrics")) ? v[
"lyrics"].GetString() : string();
697 string release_date = (v.HasMember(
"release_date")) ?
698 v[
"release_date"].GetString() : string();
699 all_songs.push_back(
Song ( artist, song, album, lyrics, release_date) );
717 GutenbergBook getAGutenbergBookMetaData(
const rapidjson::Value& V) {
718 using namespace rapidjson;
720 const string s_id = V[
"id"].GetString();
722 const int id = std::stoi(s_id);
724 string title = V[
"title"].GetString();
726 const Value& A = V[
"authors"];
727 vector<string> authors;
728 for (SizeType j = 0; j < A.Size(); j++)
729 authors.push_back(A[j].GetString());
731 const Value& L = V[
"lang"];
732 string lang = L.GetString();
734 const Value& da = V[
"date_added"];
735 string data_added = da.GetString();
737 const Value& G = V[
"genres"];
738 vector<string> genres;
739 for (SizeType j = 0; j < G.Size(); j++)
740 genres.push_back(G[j].GetString());
761 using namespace rapidjson;
764 string url = getGutenbergBaseURL() +
"/meta?id=" + std::to_string(
id);
768 d.Parse(ServerComm::makeRequest( url, {
"Accept: application/json"}).c_str());
770 return getAGutenbergBookMetaData(d[
"book_list"][0]);
783 using namespace rapidjson;
786 string url = getGutenbergBaseURL() +
"/search?search=" +
787 ServerComm::encodeURLPart(term) +
"&type="
788 + ServerComm::encodeURLPart(category);
792 d.Parse(ServerComm::makeRequest(url, {
"Accept: application/json"}).c_str());
794 vector<GutenbergBook> book_list;
795 int size = d[
"book_list"].Size();
798 for (
int k = 0; k < size; k++)
799 book_list.push_back(getAGutenbergBookMetaData(d[
"book_list"][k]));
812 using namespace rapidjson;
815 string data_url = getGutenbergBaseURL() +
"/book?id=" + std::to_string(
id);
818 string hash_value =
"gutenberg" + std::to_string(
id);
821 string book_data = getDataSetJSON(data_url, hash_value,
"gutenberg");
824 d.Parse(book_data.c_str());
826 string s = std::to_string(
id);
827 return d[s.c_str()].GetString();
837 using namespace rapidjson;
840 vector<CancerIncidence> wrapper;
841 string url =
"http://static-data.bridgesuncc.org/api/cancer/withlocations";
843 url +=
"?limit=" + to_string(num);
846 d.Parse(ServerComm::makeRequest( url, {
"Accept: application/json"}).c_str());
849 const Value& D = d[
"data"];
852 for (SizeType i = 0; i < D.Size(); i++) {
853 const Value& v = D[i];
854 const Value& age = v[
"Age"];
856 c.setAgeAdjustedRate( age[
"Age Adjusted Rate"].GetDouble());
857 c.setAgeAdjustedCI_Lower(age[
"Age Adjusted CI Lower"].GetDouble());
858 c.setAgeAdjustedCI_Upper(age[
"Age Adjusted CI Upper"].GetDouble());
860 c.setYear(v[
"Year"].GetInt());
862 const Value& data = v[
"Data"];
863 c.setCrudeRate(data[
"Crude Rate"].GetDouble());
864 c.setCrudeRate_CI_Lower(data[
"Crude CI Lower"].GetDouble());
865 c.setCrudeRate_CI_Upper(data[
"Crude CI Upper"].GetDouble());
866 c.setRace(data[
"Race"].GetString());
867 c.setPopulation(data[
"Population"].GetInt());
868 c.setEventType(data[
"Event Type"].GetString());
869 c.setCount(data[
"Count"].GetInt());
871 c.setAffectedArea(v[
"Area"].GetString());
873 const Value& loc = v[
"loc"];
874 c.setLocationX(loc[0].GetDouble());
875 c.setLocationY(loc[1].GetDouble());
877 wrapper.push_back(c);
889 OSMData getOSMDataFromJSON (
const string& osm_json) {
890 using namespace rapidjson;
894 osm_data.Parse(osm_json.c_str());
899 if (osm_data.HasMember(
"nodes")) {
900 vector<OSMVertex> vertices;
901 Value& nodes = osm_data[
"nodes"];
903 vector<long> vertex_ids;
905 for (SizeType i = 0; i < nodes.Size(); i++) {
906 const Value& node = nodes[i];
909 vertex_ids.push_back(
id);
910 double lat = node[1].GetDouble(), longit = node[2].GetDouble();
911 vertices.push_back(
OSMVertex(
id, lat, longit));
918 if (osm_data.HasMember(
"edges")) {
919 vector<OSMEdge> edges;
920 Value& links = osm_data[
"edges"];
922 for (SizeType i = 0;
i < links.Size();
i++) {
923 const Value& link = links[
i];
926 double dist = link[2].GetDouble();
928 edges.push_back(
OSMEdge(id1, id2, dist));
934 if (osm_data.HasMember(
"meta")) {
936 Value& meta = osm_data[
"meta"];
937 double lat_min = meta[
"lat_min"].GetDouble();
938 double lat_max = meta[
"lat_max"].GetDouble();
939 double longit_min = meta[
"lon_min"].GetDouble();
940 double longit_max = meta[
"lon_max"].GetDouble();
943 osm.
setName(meta[
"name"].GetString());
973 double lat_max,
double long_max,
string level =
"default") {
976 string hash_url = getOSMBaseURL() +
977 "hash?minLon=" + std::to_string(long_min) +
978 "&minLat=" + std::to_string(lat_min) +
979 "&maxLon=" + std::to_string(long_max) +
980 "&maxLat=" + std::to_string(lat_max) +
981 "&level=" + ServerComm::encodeURLPart(level);
985 getOSMBaseURL() +
"coords?minLon=" + std::to_string(long_min) +
986 "&minLat=" + std::to_string(lat_min) +
987 "&maxLon=" + std::to_string(long_max) +
988 "&maxLat=" + std::to_string(lat_max) +
989 "&level=" + ServerComm::encodeURLPart(level);
993 string osm_json = getDataSetJSON(osm_url, hash_url,
"osm");
996 return getOSMDataFromJSON(osm_json);
1014 maxLat,
double maxLon, std::string amenity) {
1016 std::string amenity_url = getOSMBaseURL() +
"amenity?minLon=" +
1017 ServerComm::encodeURLPart(std::to_string(minLon)) +
1018 "&minLat=" + ServerComm::encodeURLPart(std::to_string(minLat)) +
1019 "&maxLon=" + ServerComm::encodeURLPart(std::to_string(maxLon)) +
1020 "&maxLat=" + ServerComm::encodeURLPart(std::to_string(maxLat)) +
1021 "&amenity=" + ServerComm::encodeURLPart(amenity);
1023 std::string hash_url = getOSMBaseURL() +
"hash?minLon=" +
1024 ServerComm::encodeURLPart(std::to_string(minLon)) +
1025 "&minLat=" + ServerComm::encodeURLPart(std::to_string(minLat)) +
1026 "&maxLon=" + ServerComm::encodeURLPart(std::to_string(maxLon)) +
1027 "&maxLat=" + ServerComm::encodeURLPart(std::to_string(maxLat)) +
1028 "&amenity=" + ServerComm::encodeURLPart(amenity);
1032 string amenity_json = getDataSetJSON(amenity_url, hash_url,
"amenity");
1050 const std::string& amenity) {
1051 std::string amenity_url = getOSMBaseURL() +
"amenity?location=" +
1052 ServerComm::encodeURLPart(location) +
1053 "&amenity=" + ServerComm::encodeURLPart(amenity);
1055 std::string hash_url = getOSMBaseURL() +
"hash?location=" +
1056 ServerComm::encodeURLPart(location) +
1057 "&amenity=" + ServerComm::encodeURLPart(amenity);
1061 string amenity_json = getDataSetJSON(amenity_url, hash_url,
"amenity");
1080 using namespace rapidjson;
1082 vector<Amenity> amenities;
1083 Document amenity_content;
1085 amenity_content.Parse(amenity_json.c_str());
1086 if (amenity_content.HasMember(
"nodes")) {
1087 const Value& nodes = amenity_content[
"nodes"];
1088 if (amenity_content.HasMember(
"meta")) {
1089 const Value& meta = amenity_content[
"meta"];
1099 for (SizeType i = 0; i < nodes.Size(); i++) {
1101 const Value& node = nodes[i];
1102 amen.
setId(node[0].GetInt64());
1103 amen.
setLat(node[1].GetDouble());
1104 amen.
setLon(node[2].GetDouble());
1105 amen.
setName(node[3].GetString());
1108 amenities.push_back(amen);
1112 cout <<
"meta data not found!\n";
1117 cout <<
"nodes data not found!\n";
1144 string hash_url = getOSMBaseURL() +
"hash?location=" +
1145 ServerComm::encodeURLPart(location) +
1146 "&level=" + ServerComm::encodeURLPart(level);
1149 string osm_url = getOSMBaseURL() +
1150 "loc?location=" + ServerComm::encodeURLPart(location) +
1151 "&level=" + ServerComm::encodeURLPart(level);
1155 string osm_json = getDataSetJSON(osm_url, hash_url,
"osm");
1157 return getOSMDataFromJSON(osm_json);
1176 const std::string& user,
1178 int subassignment = 0) {
1182 std::string s = this->getAssignment(user, assignment, subassignment);
1184 rapidjson::Document doc;
1185 doc.Parse(s.c_str());
1186 if (doc.HasParseError())
1187 throw "Malformed JSON";
1190 const auto& assjson = doc.FindMember(
"assignmentJSON");
1192 if (assjson == doc.MemberEnd())
1193 throw "Malformed GraphAdjacencyList JSON: no assignmentJSON";
1196 const auto& dataArray = assjson->value.FindMember(
"data");
1198 if (dataArray == assjson->value.MemberEnd()
1199 || dataArray->value.IsArray() ==
false)
1200 throw "Malformed GraphAdjacencyList JSON: No data";
1202 const auto& data = dataArray->value.GetArray()[0];
1205 const auto& dataVisual = data.FindMember(
"visual");
1207 if (dataVisual == data.MemberEnd() ||
1208 dataVisual->value.IsString() ==
false)
1209 throw "Malformed GraphAdjacencyList JSON";
1211 std::string assignment_type = dataVisual->value.GetString();
1213 if (assignment_type !=
"GraphAdjacencyList")
1214 throw "Malformed GraphAdjacencyList JSON: Not a GraphAdjacencyList";
1218 const auto& nodes = data.FindMember(
"nodes");
1219 if (nodes == data.MemberEnd() ||
1220 nodes->value.IsArray() ==
false)
1221 throw "Malformed GraphAdjacencyList JSON: malformed nodes";
1223 const auto& nodeArray = nodes->value.GetArray();
1224 int nbVertex = nodeArray.Size();
1225 for (
int i = 0; i < nbVertex; ++i) {
1228 const auto& vertexJSONstr = nodeArray[i];
1230 const auto& nameJSON = vertexJSONstr.FindMember(
"name");
1231 if (nameJSON != vertexJSONstr.MemberEnd()
1232 && nameJSON->value.IsString()) {
1233 name = nameJSON->value.GetString();
1241 const auto& links = data.FindMember(
"links");
1242 if (links == data.MemberEnd() ||
1243 links->value.IsArray() ==
false)
1244 throw "Malformed GraphAdjacencyList JSON: malformed links";
1246 const auto& linkArray = links->value.GetArray();
1247 int nbLink = linkArray.Size();
1248 for (
int i = 0; i < nbLink; ++i) {
1254 const auto& linkJSONstr = linkArray[i];
1257 const auto& nameJSON = linkJSONstr.FindMember(
"label");
1258 if (nameJSON != linkJSONstr.MemberEnd()
1259 && nameJSON->value.IsString()) {
1260 name = nameJSON->value.GetString();
1264 const auto& srcJSON = linkJSONstr.FindMember(
"source");
1265 if (srcJSON == linkJSONstr.MemberEnd()
1266 || srcJSON->value.IsInt() ==
false) {
1267 throw "Malformed GraphAdjacencyList JSON: malformed link";
1269 src = srcJSON->value.GetInt();
1272 const auto& dstJSON = linkJSONstr.FindMember(
"target");
1273 if (dstJSON == linkJSONstr.MemberEnd()
1274 || dstJSON->value.IsInt() ==
false) {
1275 throw "Malformed GraphAdjacencyList JSON: malformed link";
1277 dest = dstJSON->value.GetInt();
1280 const auto& wgtJSON = linkJSONstr.FindMember(
"weight");
1281 if (wgtJSON == linkJSONstr.MemberEnd()
1282 || wgtJSON->value.IsInt() ==
false) {
1283 throw "Malformed GraphAdjacencyList JSON: malformed link";
1285 wgt = wgtJSON->value.GetInt();
1304 int subassignment = 0) {
1306 std::string s = this->getAssignment(user, assignment, subassignment);
1308 rapidjson::Document doc;
1309 doc.Parse(s.c_str());
1310 if (doc.HasParseError())
1311 throw "Malformed JSON";
1314 std::string assignment_type = doc[
"assignment_type"].GetString();
1316 if (assignment_type !=
"ColorGrid")
1317 throw "Malformed ColorGrid JSON: Not a ColorGrid";
1320 throw "Malformed JSON: Not a Bridges assignment?";
1324 auto& data = doc[
"data"][0];
1326 std::string encoding = data[
"encoding"].GetString();
1327 if (encoding !=
"RAW" && encoding !=
"RLE")
1328 throw "Malformed ColorGrid JSON: encoding not supported";
1331 const auto& dimensions = data[
"dimensions"];
1332 int dimx = dimensions[0].GetInt();
1333 int dimy = dimensions[1].GetInt();
1336 std::cerr <<
"Dimensions: " << dimx <<
"x" << dimy << std::endl;
1339 std::string base64_encoded_assignment = data[
"nodes"][0].GetString();
1345 if (encoding ==
"RAW") {
1347 std::cerr <<
"decoding RAW" << std::endl;
1349 std::cerr <<
"length: " << decoded.size() << std::endl;
1350 if (decoded.size() < dimx * dimy * 4)
1351 throw "Malformed ColorGrid JSON: nodes is smaller than expected";
1360 for (
int x = 0; x < dimx; ++x) {
1361 for (
int y = 0; y < dimy; ++y) {
1363 (
int)decoded[base + 1],
1364 (
int)decoded[base + 2],
1365 (
int)decoded[base + 3]
1373 else if (encoding ==
"RLE") {
1375 std::cerr <<
"Decoding RLE" << std::endl;
1377 int currentInDecoded = 0;
1378 int currentInCG = 0;
1379 while (currentInDecoded != decoded.size()) {
1380 if (currentInDecoded + 5 > decoded.size())
1381 throw "Malformed ColorGrid JSON: nodes is not a multiple of 5";
1383 int repeat = (
BYTE) decoded[currentInDecoded++];
1384 int r = (
BYTE) decoded[currentInDecoded++];
1385 int g = (
BYTE) decoded[currentInDecoded++];
1386 int b = (
BYTE) decoded[currentInDecoded++];
1387 int a = (
BYTE) decoded[currentInDecoded++];
1390 std::cerr <<
"indecoded: " << currentInDecoded
1391 <<
" repeat: " << (
int)repeat
1392 <<
" color(" << (int)r <<
"," << (
int)g <<
"," << (int)b <<
"," << (
int)a <<
")"
1397 while (repeat >= 0) {
1398 int posX = currentInCG / dimy;
1399 int posY = currentInCG % dimy;
1400 if (posX >= dimx || posY >= dimy) {
1402 std::cerr << posX <<
" " << dimx <<
" " << posY <<
" " << dimy << std::endl;
1403 throw "Malformed ColorGrid JSON: Too much data in nodes";
1405 cg.
set(posX, posY, c);
1412 std::cerr <<
"written " << currentInCG <<
" pixels" << std::endl;
1413 if (currentInCG != dimx * dimy)
1414 throw "Malformed ColorGrid JSON: Not enough data in nodes";
1420 throw "Malformed ColorGrid JSON";
1433 std::string getAssignment(std::string user,
1435 int subassignment = 0) {
1436 std::vector<std::string> headers;
1438 std::stringstream ss;
1442 ss << bridges_inst->getServerURL();
1444 ss << bridges::Bridges::getDefaultServerURL();
1445 ss <<
"/assignmentJSON/"
1446 << assignment <<
".";
1447 ss << std::setfill(
'0') << std::setw(2) << subassignment;
1448 ss <<
"/" << ServerComm::encodeURLPart(user);
1450 std::string url = ss.str();
1452 std::string s = bridges::ServerComm::makeRequest(url, headers);
1457 void removeFirstOccurence (std::string & str,
const std::string & toRemove) {
1458 size_t pos = str.find(toRemove);
1459 if (pos != std::string::npos) {
1460 str.erase(pos, toRemove.length());
1473 void getWikidataActorMovieDirect (
int yearbegin,
int yearend, std::vector<MovieActorWikidata>& vout) {
1474 std::string codename =
"wikidata-actormovie-" + std::to_string(yearbegin) +
"-" + std::to_string(yearend);
1476 bool from_cache =
false;
1478 if (my_cache.
inCache(codename)) {
1479 json = my_cache.
getDoc(codename);
1485 std::cout <<
"Exception while reading from cache. Ignoring cache and continue.\n( What was:" << ce.
what() <<
")" << std::endl;
1489 std::vector<std::string> http_headers;
1490 http_headers.push_back(
"User-Agent: bridges-cxx");
1491 http_headers.push_back(
"Accept: application/json");
1493 string url =
"https://query.wikidata.org/sparql?";
1502 std::string sparqlquery =
1503 "SELECT ?movie ?movieLabel ?actor ?actorLabel WHERE \
1505 ?movie wdt:P31 wd:Q11424.\
1506 ?movie wdt:P161 ?actor.\
1507 ?movie wdt:P364 wd:Q1860.\
1508 ?movie wdt:P577 ?date.\
1509 FILTER(YEAR(?date) >= " + std::to_string(yearbegin) +
" && YEAR(?date) <= " + std::to_string(yearend) +
").\
1510 SERVICE wikibase:label { bd:serviceParam wikibase:language \"en\". } \
1512 url +=
"query=" + ServerComm::encodeURLPart(sparqlquery);
1514 url +=
"format=json";
1517 std::cout <<
"URL: " << url <<
"\n";
1520 json = ServerComm::makeRequest(url, http_headers);
1523 my_cache.
putDoc(codename, json);
1527 std::cerr <<
"Exception while storing in cache. Weird but not critical. (What was: " << ce.
what() <<
" )" << std::endl;
1532 using namespace rapidjson;
1533 rapidjson::Document doc;
1534 doc.Parse(json.c_str());
1535 if (doc.HasParseError())
1536 throw "Malformed JSON";
1539 const auto& resultsArray = doc[
"results"][
"bindings"].GetArray();
1541 for (
auto& mak_json : resultsArray) {
1547 std::string actoruri = mak_json[
"actor"][
"value"].GetString();
1548 std::string movieuri = mak_json[
"movie"][
"value"].GetString();
1549 removeFirstOccurence (actoruri,
"http://www.wikidata.org/entity/");
1551 removeFirstOccurence (movieuri,
"http://www.wikidata.org/entity/");
1555 mak.
setActorName(mak_json[
"actorLabel"][
"value"].GetString());
1556 mak.
setMovieName(mak_json[
"movieLabel"][
"value"].GetString());
1557 vout.push_back(mak);
1562 throw "Malformed JSON: Not from wikidata?";
1586 std::vector<MovieActorWikidata> ret;
1587 for (
int y = yearbegin; y <= yearend; ++y) {
1589 getWikidataActorMovieDirect (y, y, ret);
1607 double minLat,
double minLon,
1608 double maxLat,
double maxLon,
double res = 0.0166) {
1613 std::string elev_url = getElevationBaseURL() +
1614 "elevation?minLon=" + ServerComm::encodeURLPart(std::to_string(minLon)) +
1615 "&minLat=" + ServerComm::encodeURLPart(std::to_string(minLat)) +
1616 "&maxLon=" + ServerComm::encodeURLPart(std::to_string(maxLon)) +
1617 "&maxLat=" + ServerComm::encodeURLPart(std::to_string(maxLat)) +
1618 "&resX=" + ServerComm::encodeURLPart(std::to_string(res)) +
1619 "&resY=" + ServerComm::encodeURLPart(std::to_string(res));
1622 cout <<
"Elevation URL:" << elev_url <<
"\n";
1623 cout <<
"Elevation URL:" << elev_url <<
"\n";
1625 std::string hash_url = getElevationBaseURL() +
1626 "hash?minLon=" + ServerComm::encodeURLPart(std::to_string(minLon)) +
1627 "&minLat=" + ServerComm::encodeURLPart(std::to_string(minLat)) +
1628 "&maxLon=" + ServerComm::encodeURLPart(std::to_string(maxLon)) +
1629 "&maxLat=" + ServerComm::encodeURLPart(std::to_string(maxLat)) +
1630 "&resX=" + ServerComm::encodeURLPart(std::to_string(res)) +
1631 "&resY=" + ServerComm::encodeURLPart(std::to_string(res));
1634 cout <<
"Hash URL:" << hash_url <<
"\n";
1639 string elev_json = getDataSetJSON(elev_url, hash_url,
"elevation");
1655 stringstream ss(elev_json);
1657 int rows, cols, elev_val;
1658 double ll_x, ll_y, cell_size;
1662 ss >> tmp >> cols >> tmp >> rows >>
1663 tmp >> ll_x >> tmp >> ll_y >>
1667 throw "Parse Error";
1676 for (
int i = 0; i < rows; i++) {
1677 for (
int j = 0; j < cols; j++) {
1679 elev_data.
setVal(i, j, elev_val);
1683 throw "Parse Error";
1695 string base_url = getRedditURL();
1696 string url = base_url +
"/listJSON";
1698 std::cout <<
"hitting url: " << url <<
"\n";
1700 using namespace rapidjson;
1703 std::string s = ServerComm::makeRequest(url, {
"Accept: application/json"});
1705 std::cout <<
"Returned JSON:" << s <<
"\n";
1708 doc.Parse(s.c_str());
1711 std::cerr <<
"malformed subreddit list" <<
"\n";
1712 std::cerr <<
"Original exception: " << (std::string)re <<
"\n";
1716 std::vector<std::string> subreddits;
1718 for (
auto& m : doc.GetArray()) {
1720 std::string subred = m.GetString();
1721 subreddits.push_back(subred);
1726 std::cerr <<
"malformed subreddit list" <<
"\n";
1727 std::cerr <<
"Original exception: " << (std::string)re <<
"\n";
1745 string base_url = getRedditURL();
1747 cout <<
"reddit base url:" << base_url <<
"\n";
1749 string url = base_url +
"/cache?subreddit=" + ServerComm::encodeURLPart(subreddit) +
1750 "&time_request=" + std::to_string(time_request);
1753 cout <<
"reddit url:" << url <<
"\n";
1756 using namespace rapidjson;
1759 std::string s = ServerComm::makeRequest(url, {
"Accept: application/json"});
1761 std::cout <<
"Returned JSON:" << s <<
"\n";
1763 doc.Parse(s.c_str());
1766 vector<Reddit> reddit_posts;
1767 for (
auto& m : doc.GetObject()) {
1770 std::cout << m.name.GetString() <<
"\n";
1772 auto& postJSON = m.value;
1774 std::string
id = postJSON[
"id"].GetString();
1775 std::string title = postJSON[
"title"].GetString();
1776 std::string author = postJSON[
"author"].GetString();
1777 int score = postJSON[
"score"].GetInt();
1778 float vote_ratio = postJSON[
"vote_ratio"].GetDouble();
1779 int comment_count = postJSON[
"comment_count"].GetInt();
1780 std::string subreddit = postJSON[
"subreddit"].GetString();
1781 int posttime = postJSON[
"post_time"].GetDouble();
1782 std::string url = postJSON[
"url"].GetString();
1783 std::string text = postJSON[
"text"].GetString();
1788 r.setAuthor(author);
1790 r.setVoteRatio(vote_ratio);
1791 r.setCommentCount(comment_count);
1792 r.setSubreddit(subreddit);
1793 r.setPostTime(posttime);
1796 reddit_posts.push_back(r);
1799 std::cerr <<
"malformed Reddit post" <<
"\n";
1800 std::cerr <<
"Original exception: " << (std::string)re <<
"\n";
1804 return reddit_posts;
1817 string getHashCode (
string hash_url,
string data_type) {
1819 if (data_type ==
"osm" || data_type ==
"amenity" ||
1820 data_type ==
"elevation") {
1821 hash_value = ServerComm::makeRequest(hash_url, {
"Accept: application/json"});
1823 else if (data_type ==
"gutenberg")
1824 hash_value = hash_url;
1850 std::string getDataSetJSON(std::string data_url, std::string hash_url,
1851 std::string data_type) {
1853 std::string data_json =
"";
1858 cerr <<
"Checking the cache: Hash url: " << hash_url <<
"\n";
1861 string hash_value = getHashCode(hash_url, data_type);
1863 bool dataloaded =
false;
1865 if ((hash_value !=
"false") && (my_cache.
inCache(hash_value) ==
true)) {
1867 data_json = my_cache.
getDoc(hash_value);
1872 std::cout <<
"Exception while reading from cache. "
1873 <<
"Ignoring cache and continuing..\n (What was:" << ce.
what() <<
")\n";
1881 std::cerr <<
"Hitting data URL: " << data_url <<
"\n";
1884 data_json = ServerComm::makeRequest(data_url,
1885 {
"Accept: application/json"});
1891 if (hash_value ==
"false") {
1893 std::cerr <<
"Hitting hash URL: " << hash_value <<
"\n";
1895 hash_value = getHashCode(hash_url, data_type);
1899 if (hash_value ==
"false") {
1900 std::cerr <<
"Error while gathering hash value for " << data_type <<
" dataset..\n"
1901 <<
"Weird but not critical.\n";
1904 my_cache.
putDoc(hash_value, data_json);
1909 std::cerr <<
"Exception while storing in cache. " <<
1910 "Weird but not critical.\n" <<
1911 "(What was: " << ce.
what() <<
")\n";
1913 std::cerr <<
"Tried to store hash=" << hash_value <<
1914 " key = " << data_json << std::endl;
const vector< string > all_us_states
Definition: MapConstants.h:14
const vector< string > all_countries
Definition: MapConstants.h:27
Class that hold Open Street Map Amenity data.
Definition: Amenity.h:22
void setLat(double latitude)
Definition: Amenity.h:90
void setId(long id)
Definition: Amenity.h:73
void setLon(double longitude)
Definition: Amenity.h:108
void setName(string n)
Definition: Amenity.h:124
This class contains methods to connect and transmit a user's data structure representation to the Bri...
Definition: Bridges.h:51
virtual const char * what() const noexcept
Definition: Cache.h:26
This class provides an API to various data sources used in BRIDGES.
Definition: DataSource.h:69
vector< ActorMovieIMDB > getActorMovieIMDBData2()
Get ActorMovie IMDB Data Data is retrieved, formatted into a list of ActorMovieIMDB objects.
Definition: DataSource.h:494
vector< Amenity > getAmenityData(double minLat, double minLon, double maxLat, double maxLon, std::string amenity)
Definition: DataSource.h:1013
DataSource(bridges::Bridges &br)
Definition: DataSource.h:147
vector< City > getUSCities(unordered_map< string, string > params)
Retrieves US city data based on a set of filtering parameters.
Definition: DataSource.h:190
vector< USState > getUSMapCountyData(vector< string > state_names, bool view_counties=true)
Get US State boundaries and counties of specified states.
Definition: DataSource.h:299
OSMData getOSMData(string location, string level="default")
Definition: DataSource.h:1142
vector< Song > getSongData()
Get data of the songs (including lyrics) using the Genius API https://docs.genius....
Definition: DataSource.h:675
std::vector< MovieActorWikidata > getWikidataActorMovie(int yearbegin, int yearend)
This function returns the Movie and Actors playing in them between two years.
Definition: DataSource.h:1575
vector< USState > getUSMapCountyData()
Get US State boundaries and counties af all 50 states.
Definition: DataSource.h:287
string getGutenbergBookText(int id=0)
Get the full text of the book with the provided id.
Definition: DataSource.h:811
vector< CancerIncidence > getCancerIncidenceData(int num=0)
Retrieves the CDC dataset of Cancer Incidence. Data is retrieved into a vector of records See CancerI...
Definition: DataSource.h:836
vector< GutenbergBook > getGutenbergBookMetaData(string term, string category)
Search the gutenberg data for retrieving meta data of books matching a string and a category.
Definition: DataSource.h:782
OSMData getOSMData(double lat_min, double long_min, double lat_max, double long_max, string level="default")
Get OpenStreetMap data given a bounding rectangle of lat/long values.
Definition: DataSource.h:972
vector< Amenity > parseAmenityData(string amenity_json)
Parses the amenity string and returns an AmenityData object.
Definition: DataSource.h:1079
vector< Shakespeare > getShakespeareData(string type="", bool textonly=false)
Get data of Shakespeare works (plays, poems)
Definition: DataSource.h:578
Song getSong(string songTitle, string artistName="")
Get data of a particular songs (including lyrics) using the Genius API (https://docs....
Definition: DataSource.h:627
bridges::GraphAdjList< int, std::string > getGraphFromAssignment(const std::string &user, int assignment, int subassignment=0)
Definition: DataSource.h:1175
ElevationData parseElevationData(string elev_json)
Parses the elevation data string and retuns an Elevation object.
Definition: DataSource.h:1651
vector< Reddit > getRedditData(string subreddit, int time_request=-9999)
retrieves the reddit posts from a subreddit.
Definition: DataSource.h:1744
vector< Game > getGameData()
Get meta data of the IGN games collection.
Definition: DataSource.h:423
vector< Amenity > getAmenityData(const std::string &location, const std::string &amenity)
Definition: DataSource.h:1049
bridges::ColorGrid getColorGridFromAssignment(const std::string &user, int assignment, int subassignment=0)
Definition: DataSource.h:1302
void setSourceType(string type)
set data server type
Definition: DataSource.h:159
ElevationData getElevationData(double minLat, double minLon, double maxLat, double maxLon, double res=0.0166)
Definition: DataSource.h:1606
vector< ActorMovieIMDB > getActorMovieIMDBData(int number=0)
Get ActorMovie IMDB Data Data is retrieved, formatted into a list of ActorMovieIMDB objects.
Definition: DataSource.h:461
vector< Country > getWorldMapData(vector< string > countries)
Definition: DataSource.h:368
vector< USState > getUSMapData()
Get US State data of all 50 states.
Definition: DataSource.h:277
vector< EarthquakeUSGS > getEarthquakeUSGSData(int number=0)
Get USGS earthquake data.
Definition: DataSource.h:532
vector< Country > getWorldMapData()
Definition: DataSource.h:365
std::vector< std::string > getAvailableSubreddits()
retrieves the subreddits made available by BRIDGES
Definition: DataSource.h:1694
DataSource(bridges::Bridges *br=nullptr)
Definition: DataSource.h:142
GutenbergBook getGutenbergBookMetaData(int id=0)
Get meta data of a single Gutenberg book This function retrieves, and formats the data into a list of...
Definition: DataSource.h:760
A class to hold actor movie data – using IMDB dataset.
Definition: ActorMovieIMDB.h:31
A class representing the attributes for cancer incidence.
Definition: CancerIncidence.h:32
Class that holds data of a city.
Definition: City.h:29
Class that hold earthquake data, for use with USGIS retrieved quake data.
Definition: EarthquakeUSGS.h:28
Class that hold elevation data.
Definition: ElevationData.h:27
void setyll(int y_ll)
Definition: ElevationData.h:206
void setxll(int x_ll)
Definition: ElevationData.h:189
void setVal(int r, int c, int val)
Definition: ElevationData.h:151
void setCellSize(float cell_size)
Definition: ElevationData.h:224
A Game object, used along with the Games data source.
Definition: Game.h:34
A Gutenberg Book object (meta data and book's full text)
Definition: GutenbergBook.h:32
This is a helper class for accessing actor-movie data from Wikidata.
Definition: MovieActorWikidata.h:23
void setMovieURI(std::string mu)
Definition: MovieActorWikidata.h:40
void setActorName(std::string an)
Definition: MovieActorWikidata.h:64
void setActorURI(std::string au)
Definition: MovieActorWikidata.h:48
void setMovieName(std::string mn)
Definition: MovieActorWikidata.h:56
Class that hold Open Street Map Data.
Definition: OSMData.h:38
void setEdges(const vector< OSMEdge > &e)
set edges
Definition: OSMData.h:307
void setVertices(const vector< OSMVertex > &verts)
replace the vertices stored by this new set.
Definition: OSMData.h:269
void setName(const string &n)
change the name of the dataset
Definition: OSMData.h:224
void setLatLongRange(double *lat_range, double *longit_range)
set the latitude and longitude range of the dataset
Definition: OSMData.h:111
Class that hold Open Street Map edges.
Definition: OSMEdge.h:27
Class that hold Open Street Map vertices.
Definition: OSMVertex.h:33
long OSMVertexID
Definition: OSMVertex.h:35
An object to represent a Reddit post, used along with the Reddit data source.
Definition: Reddit.h:28
A Shakespeare Data source object containing sonnets, poems and plays.
Definition: Shakespeare.h:31
A Song object, used along with the Songs data source.
Definition: Song.h:27
This object contains US county related information.
Definition: USCounty.h:26
This is a class in BRIDGES for representing an image.
Definition: ColorGrid.h:22
This class represents Color, and supports rgba, hexadecimal and named color values.
Definition: Color.h:50
This class provides methods to represent adjacency list based graphs.
Definition: GraphAdjList.h:110
void addVertex(const K &k, const E1 &e=E1())
Adds a vertex to the graph.
Definition: GraphAdjList.h:175
void addEdge(const K &src, const K &dest, const E2 &data=E2())
Definition: GraphAdjList.h:198
void set(int row, int col, E val)
Set the grid value for the (row, col) element.
Definition: Grid.h:186
virtual void putDoc(const std::string &hash_value, const std::string &content) override
Definition: Cache.h:229
virtual bool inCache(const std::string &hash_value) override
Definition: Cache.h:222
virtual std::string getDoc(const std::string &hash_value) override
Definition: Cache.h:213
vector< BYTE > decode(string const &encoded_string)
Definition: base64.h:100
Definition: ActorMovieIMDB.h:10
these methods convert byte arrays in to base64 codes and are used in BRIDGES to represent the color a...
Definition: alltypes.h:4
unsigned char BYTE
Definition: base64.h:43