Implemented: check for problematic arc in Antarctica (looks like it is repeating 2 points in the south pole so that they can be seen in the projected planar coordinates when the coordinates are wrapped along the x-axis (longitude)

This commit is contained in:
denizdiktas 2023-07-04 14:36:21 +03:00
parent 32446d30c2
commit d5c4d3fd64
4 changed files with 160 additions and 34 deletions

View File

@ -206,3 +206,67 @@ Kml::Nodes Kml::get_duplicates(const Placemarks& placemarks)
return duplicate_nodes;
}
Kml::Nodes Kml::Polygon::get_all_nodes() const
{
Nodes all_nodes;
auto source_first = outer_boundary.nodes.begin();
auto source_last = outer_boundary.nodes.end();
all_nodes.insert(all_nodes.begin(), source_first, source_last);
for (const auto& inner_boundary : inner_boundaries)
{
auto source_first = inner_boundary.nodes.begin();
auto source_last = inner_boundary.nodes.end();
all_nodes.insert(all_nodes.begin(), source_first, source_last);
}
return all_nodes;
}
Kml::Nodes Kml::Placemark::get_all_nodes() const
{
Nodes all_nodes;
for (const auto& polygon : polygons)
{
auto polygon_nodes = polygon.get_all_nodes();
auto first = std::make_move_iterator(polygon_nodes.begin());
auto last = std::make_move_iterator(polygon_nodes.end());
all_nodes.insert(all_nodes.end(), first, last);
}
return all_nodes;
}
Kml::Arcs Kml::LinearRing::get_arcs() const
{
Arcs arcs;
const int num_nodes = nodes.size();
for (int i = 0; i < num_nodes - 1; ++i)
{
const auto from = nodes[i];
const auto to = nodes[i + 1];
arcs.push_back(Arc{ from, to });
}
return arcs;
}
void Kml::LinearRing::get_arcs(Arcs& arcs) const
{
auto a = get_arcs();
arcs.insert(arcs.end(), a.begin(), a.end());
}
Kml::Arcs Kml::Placemark::get_all_arcs() const
{
Arcs all_arcs;
for (const auto& polygon : polygons)
{
polygon.outer_boundary.get_arcs(all_arcs);
for (const auto& inner_boundary : polygon.inner_boundaries)
inner_boundary.get_arcs(all_arcs);
}
return all_arcs;
}

View File

@ -2,6 +2,7 @@
#ifndef KML_READER_H
#define KML_READER_H
#include <iostream>
#include <string>
#include <vector>
@ -24,11 +25,26 @@ public:
bool operator == (const Node& r) const;
Vec3d get_coords_3d(const double r = 1.0) const;
QVector3D get_coords_3f(const double r=1.0) const;
friend std::ostream& operator << (std::ostream& os, const Node& n)
{
os << n.lon << ", " << n.lat;
return os;
}
};
using Nodes = std::vector<Node>;
struct Arc
{
Node from, to;
};
using Arcs = std::vector<Arc>;
struct LinearRing
{
std::vector<Node> nodes;
Arcs get_arcs() const;
void get_arcs(Arcs& arcs) const;
};
using LinearRings = std::vector<LinearRing>;
@ -37,15 +53,23 @@ public:
{
LinearRing outer_boundary;
LinearRings inner_boundaries;
// when collecting nodes start from the outer boundary and then get nodes
// from individual inner boundaries in the order
Nodes get_all_nodes() const;
};
struct Placemark
{
std::vector<Polygon> polygons;
std::string name;
};
using Nodes = std::vector<Node>;
// collects all nodes from all polygons
Nodes get_all_nodes() const;
Arcs get_all_arcs() const;
};
using Placemarks = std::vector<Placemark>;

View File

@ -113,41 +113,60 @@ void Main_widget::keyPressEvent(QKeyEvent* event)
{
case Qt::Key_Q:
{
auto num_arcs = m_country_borders[m_selected_country]->get_num_line_strips();
if (++m_selected_arc == num_arcs)
m_selected_arc--;
std::cout << "selected arc = " << m_selected_arc << std::endl;
auto num_arcs = m_country_borders[m_selected_country_index]->get_num_line_strips();
if (++m_selected_arc_index == num_arcs)
m_selected_arc_index--;
qDebug() << "---------------------------------------";
qDebug() << "selected arc index = " << m_selected_arc_index;
const auto& arc = m_selected_country_arcs[m_selected_arc_index];
std::cout << arc.from << " TO " << arc.to << std::endl;
}
break;
case Qt::Key_A:
{
auto num_arcs = m_country_borders[m_selected_country]->get_num_line_strips();
if (--m_selected_arc < 0)
m_selected_arc = 0;
std::cout << "selected arc = " << m_selected_arc << std::endl;
auto num_arcs = m_country_borders[m_selected_country_index]->get_num_line_strips();
if (--m_selected_arc_index < 0)
m_selected_arc_index = 0;
std::cout << "selected arc = " << m_selected_arc_index << std::endl;
}
break;
case Qt::Key_Up:
m_selected_country++;
if (m_selected_country == m_country_names.size())
m_selected_country--;
std::cout << m_selected_country << ": " << m_country_names[m_selected_country] << std::endl;
m_selected_arc = 0;
m_selected_country_index++;
if (m_selected_country_index == m_country_names.size())
m_selected_country_index--;
std::cout << m_selected_country_index << ": "
<< m_country_names[m_selected_country_index] << std::endl;
m_selected_arc_index = 0;
m_selected_country = &m_countries[m_selected_country_index];
m_selected_country_nodes = m_selected_country->get_all_nodes();
m_selected_country_arcs = m_selected_country->get_all_arcs();
{
auto num_arcs = m_country_borders[m_selected_country_index]->get_num_line_strips();
qDebug() << "num KML arcs = " << m_selected_country_arcs.size();
qDebug() << "num arcs = " << num_arcs;
}
break;
case Qt::Key_Down:
m_selected_country--;
if (m_selected_country < 0)
m_selected_country = 0;
std::cout << m_selected_country << ": " << m_country_names[m_selected_country] << std::endl;
m_selected_arc = 0;
m_selected_country_index--;
if (m_selected_country_index < 0)
m_selected_country_index = 0;
std::cout << m_selected_country_index << ": "
<< m_country_names[m_selected_country_index] << std::endl;
m_selected_arc_index = 0;
m_selected_country = &m_countries[m_selected_country_index];
m_selected_country_nodes = m_selected_country->get_all_nodes();
break;
}
}
#include <shapefil.h>
void readShapefile(const std::string& filename) {
@ -191,11 +210,11 @@ void Main_widget::initializeGL()
//const auto file_name = "C:/work/gsoc2023/data/world_countries.kml";
const auto file_name = "C:/work/gsoc2023/data/ne_110m_admin_0_countries.kml";
auto countries = Kml::read(file_name);
auto dup_nodes = Kml::get_duplicates(countries);
m_countries = Kml::read(file_name);
auto dup_nodes = Kml::get_duplicates(m_countries);
// initialize rendering of DUPLICATE VERTICES
if(0)
if(1)
{
std::vector<QVector3D> vertices;
for (const auto& node : dup_nodes)
@ -206,7 +225,7 @@ void Main_widget::initializeGL()
else
{
// check the arrangement constructed from the GIS data-set
auto created_vertices = Aos::ext_check(countries);
auto created_vertices = Aos::ext_check(m_countries);
m_vertices = std::make_unique<Vertices>(created_vertices);
}
@ -226,15 +245,18 @@ void Main_widget::initializeGL()
//auto lsa = Aos::get_approx_arcs(countries, error);
//auto lsa = Aos::get_approx_arcs(error);
//m_geodesic_arcs = std::make_unique<Line_strips>(lsa);
for (const auto& country : countries)
for (const auto& country : m_countries)
{
m_country_names.push_back(country.name);
auto approx_arcs = Aos::get_approx_arcs(country, error);
auto country_border = std::make_unique<Line_strips>(approx_arcs);
m_country_borders.push_back(std::move(country_border));
}
m_selected_country = 25;
m_selected_arc = 0;
m_selected_country_index = 159; // ANTARCTICA
m_selected_country = &m_countries[m_selected_country_index];
m_selected_country_nodes = m_selected_country->get_all_nodes();
m_selected_country_arcs = m_selected_country->get_all_arcs();
m_selected_arc_index = 0;
}
glClearColor(0, 0, 0, 1);
@ -459,13 +481,19 @@ void Main_widget::paintGL()
for(auto& country_border : m_country_borders)
country_border->draw();
sp.set_uniform("u_color", arc_color);
m_country_borders[m_selected_country]->draw(m_selected_arc);
// draw the selected country in blue color
auto& selected_countru = m_country_borders[m_selected_country_index];
sp.set_uniform("u_color", QVector4D(0, .6, 1, 1));
selected_countru->draw();
// draw the current arc of the selected country in YELLOW
sp.set_uniform("u_color", QVector4D(1, 1, 0, 1));
selected_countru->draw(m_selected_arc_index);
const QVector4D vertex_color(1, 0, 0, 1);
sp.set_uniform("u_color", vertex_color);
glPointSize(5);
m_vertices->draw();
//m_vertices->draw();
sp.unuse();
}

View File

@ -10,12 +10,14 @@
#include <QVector2D>
#include <QBasicTimer>
#include <functional>
#include <memory>
#include <qopenglwidget.h>
#include "Camera.h"
#include "Common_defs.h"
#include "Kml_reader.h"
#include "Line_strips.h"
#include "Shader_program.h"
#include "Sphere.h"
@ -60,11 +62,19 @@ private:
std::unique_ptr<Line_strips> m_geodesic_arcs;
std::unique_ptr<Vertices> m_vertices;
// now we draw boundary-arcs by country
int m_selected_country, m_selected_arc;
// COUNTRY DATA
Kml::Placemarks m_countries;
std::vector<std::string> m_country_names;
std::vector<std::unique_ptr<Line_strips>> m_country_borders;
// now we draw boundary-arcs by country
int m_selected_country_index, m_selected_arc_index;
Kml::Nodes m_selected_country_nodes;
Kml::Arcs m_selected_country_arcs;
Kml::Placemark* m_selected_country;
// Shaders
Shader_program m_sp_smooth;
Shader_program m_sp_per_vertex_color;