FemMaps/map/SigalertMapProvider.cpp
2023-10-30 00:53:00 -07:00

127 lines
3.4 KiB
C++

//
// Created by scoliono on 10/14/23.
//
#include "SigalertMapProvider.h"
#include "SigalertRoadSensor.h"
#include <iostream>
#include <stdlib.h>
#include <string.h>
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<struct MemoryStruct*>(userp);
char* ptr = static_cast<char*>(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<int, Road*>(i, static_cast<Road*>(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<SigalertRoad*>(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++;
}
}