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; 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 #ifndef KML_READER_H
#define KML_READER_H #define KML_READER_H
#include <iostream>
#include <string> #include <string>
#include <vector> #include <vector>
@ -24,11 +25,26 @@ public:
bool operator == (const Node& r) const; bool operator == (const Node& r) const;
Vec3d get_coords_3d(const double r = 1.0) const; Vec3d get_coords_3d(const double r = 1.0) const;
QVector3D get_coords_3f(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 struct LinearRing
{ {
std::vector<Node> nodes; std::vector<Node> nodes;
Arcs get_arcs() const;
void get_arcs(Arcs& arcs) const;
}; };
using LinearRings = std::vector<LinearRing>; using LinearRings = std::vector<LinearRing>;
@ -37,15 +53,23 @@ public:
{ {
LinearRing outer_boundary; LinearRing outer_boundary;
LinearRings inner_boundaries; 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 struct Placemark
{ {
std::vector<Polygon> polygons; std::vector<Polygon> polygons;
std::string name; 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>; using Placemarks = std::vector<Placemark>;

View File

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

View File

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