// // Created by scoliono on 10/14/23. // #include "SigalertMapProvider.h" #include "SigalertRoadSensor.h" #include #include #include using nlohmann::json; SigalertMapProvider::SigalertMapProvider() { m_curl = curl_easy_init(); } SigalertMapProvider::~SigalertMapProvider() { curl_easy_cleanup(m_curl); if (m_static_data.memory) free(m_static_data.memory); if (m_current_data.memory) free(m_current_data.memory); for (auto section : m_allsections) delete section; for (auto sensor : m_allsensors) delete sensor; } size_t SigalertMapProvider::curl_write_callback(void* contents, size_t size, size_t nmemb, void* userp) { size_t realsize = size * nmemb; struct MemoryStruct* mem = static_cast(userp); char* ptr = static_cast(realloc(mem->memory, mem->size + realsize + 1)); if (!ptr) { /* out of memory! */ std::cerr << "not enough memory (realloc returned NULL)" << std::endl; return 0; } mem->memory = ptr; memcpy(&(mem->memory[mem->size]), contents, realsize); mem->size += realsize; mem->memory[mem->size] = 0; return realsize; } void SigalertMapProvider::refreshData() { curl_easy_setopt(m_curl, CURLOPT_URL, SigalertMapProvider::STATIC_DATA_URL); curl_easy_setopt(m_curl, CURLOPT_WRITEFUNCTION, &SigalertMapProvider::curl_write_callback); curl_easy_setopt(m_curl, CURLOPT_WRITEDATA, (void*)&m_static_data); curl_easy_setopt(m_curl, CURLOPT_USERAGENT, "libcurl-agent/1.0"); CURLcode res = curl_easy_perform(m_curl); if (res != CURLE_OK) { std::cerr << "request for static map data failed: " << curl_easy_strerror(res) << std::endl; return; } try { m_static_json = json::parse(m_static_data.memory); } catch (json::parse_error& e) { std::cerr << "JSON error while parsing static map data: " << e.what() << std::endl; return; } populateRoadSensors(); populateRoads(); populateRoadSections(); } /** * Expects road sensors to be populated first. */ void SigalertMapProvider::populateRoads() { auto roads = m_static_json.at("roads"); for (auto& el : roads.items()) { SigalertRoadJson road_json = el.value(); int i = atoi(el.key().c_str()); SigalertRoad* road = new SigalertRoad(i, road_json); m_roads.insert(std::pair(i, static_cast(road))); road->populateSensors(m_allsensors); } } /** * Expects roads to be populated first. */ void SigalertMapProvider::populateRoadSections() { auto sections = m_static_json.at("roadSections"); for (auto& el : sections.items()) { SigalertRoadSectionJson section_json = el.value(); SigalertRoad* road = dynamic_cast(m_roads[section_json.road_id]); SigalertRoadSection* section = new SigalertRoadSection(section_json, road); m_allsections.push_back(section); road->addSection(section); } } void SigalertMapProvider::populateRoadSensors() { auto names = m_static_json.at("sensorNames"); auto pos = m_static_json.at("sensorPositions"); //auto speeds = m_current_json.at("speeds"); size_t idx = 0; for (auto& el : names.items()) { SigalertRoadSensor* sensor = new SigalertRoadSensor(idx, el.value(), pos[idx], -1); m_allsensors.push_back(sensor); idx++; } }