esri_assignment/src/main.cpp

108 lines
3.2 KiB
C++

#include "calc.hpp"
#include "json_output.hpp"
#include "proto_loader.hpp"
#include "spatial_grid.hpp"
#include <iostream>
#include <limits>
#include <string>
#include <utility>
#include <vector>
static void print_usage()
{
std::cout << "ESRI C++ code assignment, E. Nindl 2021\n\n";
std::cout << "Usage:\n";
std::cout << " executable <input-file[s]> <json-ouput-file>\n";
}
std::tuple<double, double, double, double>
total_spatial_extent(std::vector<Magnetics> const& magnetics_recs) {
double x_min = std::numeric_limits<double>::max();
double y_min = std::numeric_limits<double>::max();
double x_max = std::numeric_limits<double>::min();
double y_max = std::numeric_limits<double>::min();
for (auto const& magnetics : magnetics_recs) {
auto const [x_min_i, y_min_i, x_max_i, y_max_i] = ::calc::spatial_extent(magnetics);
x_min = std::min(x_min, x_min_i);
y_min = std::min(y_min, y_min_i);
x_max = std::max(x_max, x_max_i);
y_max = std::max(y_max, y_max_i);
}
return std::make_tuple(x_min, y_min, x_max, y_max);
}
static bool write_output(std::string const& output_file, SpatialGrid<double>& grid)
{
JsonOutput json_output(output_file.c_str());
json_output.add("start_x", grid.start_x());
json_output.add("start_y", grid.start_y());
json_output.add("spacing", grid.spacing);
json_output.add("data", grid.data());
return json_output.write();
}
int main(int argc, char* argv[])
{
if (argc < 3) {
print_usage();
return 1;
}
std::string const output_file{argv[argc - 1]};
std::vector<std::string> input_files;
for (uint32_t i = 1; i < (argc - 1); i++) {
input_files.push_back(argv[i]);
}
std::vector<Magnetics> magnetics_recs;
std::vector<Positions> groundtruth_recs;
try {
for (auto const& input_file : input_files) {
ProtoLoader loader(input_file.c_str());
magnetics_recs.push_back(loader.magnetics());
groundtruth_recs.push_back(loader.groundtruth());
}
} catch (std::exception& e) {
std::cerr << "Error loading input: " << e.what() << "\n";
return 1;
}
for (size_t rec_id = 0; rec_id < magnetics_recs.size(); rec_id++) {
Magnetics& magnetics = magnetics_recs[rec_id];
Positions& groundtruth = groundtruth_recs[rec_id];
::calc::crop_temporal_inersection(magnetics, groundtruth);
if (magnetics.size() == 0) {
std::cerr << "Error in groundtruth data\n";
return 1;
}
::calc::interpolate_positions(magnetics, groundtruth);
}
auto const [x_min, y_min, x_max, y_max] = total_spatial_extent(magnetics_recs);
SpatialGrid<std::vector<double>> grid(x_min, y_min, x_max, y_max);
for (size_t rec_id = 0; rec_id < magnetics_recs.size(); rec_id++) {
Magnetics& magnetics = magnetics_recs[rec_id];
Positions& groundtruth = groundtruth_recs[rec_id];
for (auto& mag : magnetics) {
auto& cell = grid.at(mag.position);
double const magnitude = ::calc::norm(mag.field.cbegin(), mag.field.cend());
cell.push_back(magnitude);
}
}
SpatialGrid<double> average_grid(x_min, y_min, x_max, y_max);
calc::average_grid(grid, average_grid);
if (!write_output(output_file, average_grid)) {
std::cout << "Error writing output file: " << output_file << "\n";
return 1;
}
return 0;
}