mirror of
https://github.com/SatDump/SatDump
synced 2026-08-13 17:47:30 -04:00
209 lines
No EOL
11 KiB
C++
209 lines
No EOL
11 KiB
C++
#include "map_drawer.h"
|
|
#include "nlohmann/json.hpp"
|
|
#include <fstream>
|
|
#include "shapefile.h"
|
|
|
|
namespace map
|
|
{
|
|
template <typename T>
|
|
void drawProjectedMap(cimg_library::CImg<T> &map_image, std::vector<std::string> shapeFiles, T color[3], std::function<std::pair<int, int>(float, float, int, int)> projectionFunc)
|
|
{
|
|
for (std::string currentShapeFile : shapeFiles)
|
|
{
|
|
nlohmann::json shapeFile;
|
|
{
|
|
std::ifstream istream(currentShapeFile);
|
|
istream >> shapeFile;
|
|
istream.close();
|
|
}
|
|
|
|
for (const nlohmann::json &mapStruct : shapeFile.at("features"))
|
|
{
|
|
if (mapStruct["type"] != "Feature")
|
|
continue;
|
|
|
|
std::string geometryType = mapStruct["geometry"]["type"];
|
|
|
|
if (geometryType == "Polygon")
|
|
{
|
|
std::vector<std::vector<std::pair<float, float>>> all_coordinates = mapStruct["geometry"]["coordinates"].get<std::vector<std::vector<std::pair<float, float>>>>();
|
|
|
|
for (std::vector<std::pair<float, float>> coordinates : all_coordinates)
|
|
{
|
|
for (int i = 0; i < (int)coordinates.size() - 1; i++)
|
|
{
|
|
std::pair<float, float> start = projectionFunc(coordinates[i].second, coordinates[i].first,
|
|
map_image.height(), map_image.width());
|
|
std::pair<float, float> end = projectionFunc(coordinates[i + 1].second, coordinates[i + 1].first,
|
|
map_image.height(), map_image.width());
|
|
|
|
if (start.first == -1 || end.first == -1)
|
|
continue;
|
|
|
|
map_image.draw_line(start.first, start.second, end.first, end.second, color);
|
|
}
|
|
|
|
{
|
|
std::pair<float, float> start = projectionFunc(coordinates[0].second, coordinates[0].first,
|
|
map_image.height(), map_image.width());
|
|
std::pair<float, float> end = projectionFunc(coordinates[coordinates.size() - 1].second, coordinates[coordinates.size() - 1].first,
|
|
map_image.height(), map_image.width());
|
|
|
|
if (start.first == -1 || end.first == -1)
|
|
continue;
|
|
|
|
map_image.draw_line(start.first, start.second, end.first, end.second, color);
|
|
}
|
|
}
|
|
}
|
|
else if (geometryType == "MultiPolygon")
|
|
{
|
|
std::vector<std::vector<std::vector<std::pair<float, float>>>> all_all_coordinates = mapStruct["geometry"]["coordinates"].get<std::vector<std::vector<std::vector<std::pair<float, float>>>>>();
|
|
|
|
for (std::vector<std::vector<std::pair<float, float>>> all_coordinates : all_all_coordinates)
|
|
{
|
|
for (std::vector<std::pair<float, float>> coordinates : all_coordinates)
|
|
{
|
|
for (int i = 0; i < (int)coordinates.size() - 1; i++)
|
|
{
|
|
std::pair<float, float> start = projectionFunc(coordinates[i].second, coordinates[i].first,
|
|
map_image.height(), map_image.width());
|
|
std::pair<float, float> end = projectionFunc(coordinates[i + 1].second, coordinates[i + 1].first,
|
|
map_image.height(), map_image.width());
|
|
|
|
if (start.first == -1 || end.first == -1)
|
|
continue;
|
|
|
|
map_image.draw_line(start.first, start.second, end.first, end.second, color);
|
|
}
|
|
|
|
{
|
|
std::pair<float, float> start = projectionFunc(coordinates[0].second, coordinates[0].first,
|
|
map_image.height(), map_image.width());
|
|
|
|
std::pair<float, float> end = projectionFunc(coordinates[coordinates.size() - 1].second, coordinates[coordinates.size() - 1].first,
|
|
map_image.height(),
|
|
map_image.width());
|
|
if (start.first == -1 || end.first == -1)
|
|
continue;
|
|
|
|
map_image.draw_line(start.first, start.second, end.first, end.second, color);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else if (geometryType == "LineString")
|
|
{
|
|
std::vector<std::pair<float, float>> coordinates = mapStruct["geometry"]["coordinates"].get<std::vector<std::pair<float, float>>>();
|
|
|
|
for (int i = 0; i < (int)coordinates.size() - 1; i++)
|
|
{
|
|
std::pair<float, float> start = projectionFunc(coordinates[i].second, coordinates[i].first,
|
|
map_image.height(), map_image.width());
|
|
std::pair<float, float> end = projectionFunc(coordinates[i + 1].second, coordinates[i + 1].first,
|
|
map_image.height(), map_image.width());
|
|
|
|
if (start.first == -1 || end.first == -1)
|
|
continue;
|
|
|
|
map_image.draw_line(start.first, start.second, end.first, end.second, color);
|
|
}
|
|
|
|
{
|
|
std::pair<float, float> start = projectionFunc(coordinates[0].second, coordinates[0].first,
|
|
map_image.height(), map_image.width());
|
|
std::pair<float, float> end = projectionFunc(coordinates[coordinates.size() - 1].second, coordinates[coordinates.size() - 1].first,
|
|
map_image.height(), map_image.width());
|
|
|
|
if (start.first == -1 || end.first == -1)
|
|
continue;
|
|
|
|
map_image.draw_line(start.first, start.second, end.first, end.second, color);
|
|
}
|
|
}
|
|
else if (geometryType == "Point")
|
|
{
|
|
std::pair<float, float> coordinates = mapStruct["geometry"]["coordinates"].get<std::pair<float, float>>();
|
|
std::pair<float, float> cc = projectionFunc(coordinates.second, coordinates.first,
|
|
map_image.height(), map_image.width());
|
|
|
|
if (cc.first == -1 || cc.first == -1)
|
|
continue;
|
|
|
|
map_image.draw_point(cc.first, cc.second, color);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
template void drawProjectedMap(cimg_library::CImg<unsigned char> &, std::vector<std::string>, unsigned char[3], std::function<std::pair<int, int>(float, float, int, int)>);
|
|
template void drawProjectedMap(cimg_library::CImg<unsigned short> &, std::vector<std::string>, unsigned short[3], std::function<std::pair<int, int>(float, float, int, int)>);
|
|
|
|
template <typename T>
|
|
void drawProjectedMapShapefile(cimg_library::CImg<T> &map_image, std::vector<std::string> shapeFiles, T color[3], std::function<std::pair<int, int>(float, float, int, int)> projectionFunc)
|
|
{
|
|
for (std::string currentShapeFile : shapeFiles)
|
|
{
|
|
std::ifstream inputFile(currentShapeFile, std::ios::binary);
|
|
shapefile::Shapefile shape_file(inputFile);
|
|
|
|
std::function<void(std::vector<std::vector<shapefile::point_t>>)> polylineDraw = [color, &map_image, &projectionFunc](std::vector<std::vector<shapefile::point_t>> parts)
|
|
{
|
|
for (std::vector<shapefile::point_t> coordinates : parts)
|
|
{
|
|
for (int i = 0; i < (int)coordinates.size() - 1; i++)
|
|
{
|
|
std::pair<float, float> start = projectionFunc(coordinates[i].y, coordinates[i].x,
|
|
map_image.height(), map_image.width());
|
|
std::pair<float, float> end = projectionFunc(coordinates[i + 1].y, coordinates[i + 1].x,
|
|
map_image.height(), map_image.width());
|
|
|
|
if (start.first == -1 || end.first == -1)
|
|
return;
|
|
|
|
map_image.draw_line(start.first, start.second, end.first, end.second, color);
|
|
}
|
|
|
|
{
|
|
std::pair<float, float> start = projectionFunc(coordinates[0].y, coordinates[0].x,
|
|
map_image.height(), map_image.width());
|
|
std::pair<float, float> end = projectionFunc(coordinates[coordinates.size() - 1].y, coordinates[coordinates.size() - 1].x,
|
|
map_image.height(), map_image.width());
|
|
|
|
if (start.first == -1 || end.first == -1)
|
|
return;
|
|
|
|
map_image.draw_line(start.first, start.second, end.first, end.second, color);
|
|
}
|
|
}
|
|
};
|
|
|
|
std::function<void(shapefile::point_t)> pointDraw = [color, &map_image, &projectionFunc](shapefile::point_t coordinates)
|
|
{
|
|
std::pair<float, float> cc = projectionFunc(coordinates.y, coordinates.x,
|
|
map_image.height(), map_image.width());
|
|
|
|
if (cc.first == -1 || cc.first == -1)
|
|
return;
|
|
|
|
map_image.draw_point(cc.first, cc.second, color);
|
|
};
|
|
|
|
for (shapefile::PolyLineRecord polylineRecord : shape_file.polyline_records)
|
|
polylineDraw(polylineRecord.parts_points);
|
|
|
|
for (shapefile::PolygonRecord polygonRecord : shape_file.polygon_records)
|
|
polylineDraw(polygonRecord.parts_points);
|
|
|
|
for (shapefile::PointRecord pointRecord : shape_file.point_records)
|
|
pointDraw(pointRecord.point);
|
|
|
|
for (shapefile::MultiPointRecord multipointRecord : shape_file.multipoint_records)
|
|
for (shapefile::point_t p : multipointRecord.points)
|
|
pointDraw(p);
|
|
}
|
|
}
|
|
|
|
template void drawProjectedMapShapefile(cimg_library::CImg<unsigned char> &, std::vector<std::string>, unsigned char[3], std::function<std::pair<int, int>(float, float, int, int)>);
|
|
template void drawProjectedMapShapefile(cimg_library::CImg<unsigned short> &, std::vector<std::string>, unsigned short[3], std::function<std::pair<int, int>(float, float, int, int)>);
|
|
} |