Skip to content

Commit

Permalink
World countries are rendered on the sphere
Browse files Browse the repository at this point in the history
  • Loading branch information
denizdiktas committed Jun 24, 2023
1 parent 520083f commit a7bbef7
Show file tree
Hide file tree
Showing 4 changed files with 135 additions and 17 deletions.
75 changes: 73 additions & 2 deletions Arrangement_on_surface_2/demo/earth/Geodesic_arcs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include <iterator>
#include <vector>

#include <qmath.h>
#include <qvector3d.h>

#include <CGAL/Exact_predicates_exact_constructions_kernel.h>
Expand Down Expand Up @@ -53,8 +54,7 @@ std::ostream& operator << (std::ostream& os, const Approximate_Vector_3& v)
}


std::vector<std::vector<QVector3D>> Geodesic_arcs::get_approximate_arcs(double
error)
Geodesic_arcs::Approx_arcs Geodesic_arcs::get_approx_arcs(double error)
{
// Construct the arrangement from 12 geodesic arcs.
Geom_traits traits;
Expand Down Expand Up @@ -92,3 +92,74 @@ std::vector<std::vector<QVector3D>> Geodesic_arcs::get_approximate_arcs(double

return arcs;
}


Geodesic_arcs::Approx_arcs Geodesic_arcs::get_approx_arcs(
const Kml::Placemarks& placemarks, double error)
{
// Construct the arrangement from 12 geodesic arcs.
Geom_traits traits;
Arrangement arr(&traits);

auto ctr_p = traits.construct_point_2_object();
auto ctr_cv = traits.construct_curve_2_object();


std::vector<Curve> xcvs;
for (const auto& pm : placemarks)
{
for (const auto& lring : pm.polygons)
{
// convert the nodes to points on unit-sphere
std::vector<Approximate_Vector_3> sphere_points;
for (const auto& node : lring.nodes)
{
const auto phi = qDegreesToRadians(node.lat);
const auto theta = qDegreesToRadians(node.lon);
const auto z = sin(phi);
const auto rxy = cos(phi);
const auto x = rxy * cos(theta);
const auto y = rxy * sin(theta);
Approximate_Vector_3 v(x,y,z);
sphere_points.push_back(v);
}

// add curves
int num_points = sphere_points.size();
for (int i = 0; i < sphere_points.size(); i++)
{
const auto p1 = sphere_points[i];
const auto p2 = sphere_points[(i+1) % num_points];
xcvs.push_back(ctr_cv(ctr_p(p1.x(), p1.y(), p1.z()),
ctr_p(p2.x(), p2.y(), p2.z())));
}
}
}

//xcvs.push_back(ctr_cv(ctr_p(1, 0, 0), ctr_p(0, 1, 0)));
//xcvs.push_back(ctr_cv(ctr_p(1, 0, 0), ctr_p(0, 0, 1)));
//xcvs.push_back(ctr_cv(ctr_p(0, 1, 0), ctr_p(0, 0, 1)));
//xcvs.push_back(ctr_cv(ctr_p(1, 0, 0), ctr_p(0, 1, 0), Dir3(0, 0, -1)));
//xcvs.push_back(ctr_cv(Dir3(0, 0, -1)));

auto approx = traits.approximate_2_object();


std::vector<std::vector<QVector3D>> arcs;
for (const auto& xcv : xcvs)
{
std::vector<Approximate_point_2> v;
auto oi2 = approx(xcv, error, std::back_insert_iterator(v));

std::vector<QVector3D> arc_points;
for (const auto& p : v)
{
const QVector3D arc_point(p.dx(), p.dy(), p.dz());
arc_points.push_back(arc_point);
}
arcs.push_back(std::move(arc_points));
}
//std::cout << "offset count = " << m_arc_offsets.size() << std::endl;

return arcs;
}
9 changes: 7 additions & 2 deletions Arrangement_on_surface_2/demo/earth/Geodesic_arcs.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,19 @@
#include <vector>
#include <qvector3d.h>

#include "Kml_reader.h"


class Geodesic_arcs
{
public:
using Approx_arcs = std::vector<std::vector<QVector3D>>;

std::vector<std::vector<QVector3D>> get_approximate_arcs(double error);

//Line_strip_approx get_approximate_arcs(double error);
Approx_arcs get_approx_arcs(double error);

// generate approximate arcs from KML data
Approx_arcs get_approx_arcs(const Kml::Placemarks& placemarks, double error);
};


Expand Down
56 changes: 50 additions & 6 deletions Arrangement_on_surface_2/demo/earth/Kml_reader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,31 @@

#include <iostream>

#include <qdebug.h>
#include <qfile.h>
#include <qxmlstream.h>

namespace {

std::vector<std::string> split(const std::string& str, const char *delim)
{
std::string sc = str;
char* token = strtok(sc.data(), delim);
char* str_end = token + str.length();

// Keep printing tokens while one of the delimiters present in str[].
std::vector<std::string> results;
while (token != NULL)
{
const auto first = token;
//printf("%s\n", token);
token = strtok(NULL, " ");
results.push_back(std::string(first, token==nullptr ? str_end : token));
}

return results;
}
}

Kml::Placemarks Kml::read(const std::string& file_name)
{
Expand Down Expand Up @@ -42,18 +64,40 @@ Kml::Placemarks Kml::read(const std::string& file_name)
else if (name == "coordinates")
{
xmlReader.readNext();
auto str = xmlReader.text().toString();
auto node_strs = str.split(" ");
auto qstr = xmlReader.text().toString();
auto ptr = qstr.data();
auto str = qstr.toUtf8().toStdString();
auto node_strs = split(str, " ");

for (const auto& node_str : node_strs)
{
if (node_str.isEmpty())
if (node_str.empty())
continue;

auto coord_strs = node_str.split(",");
const auto lon = coord_strs[0].toDouble();
const auto lat = coord_strs[1].toDouble();
auto coord_strs = split(node_str, ",");
const auto lon = std::stod(coord_strs[0]);
const auto lat = std::stod(coord_strs[1]);
lring.nodes.push_back(Node{ lon, lat });
}


//qDebug() << "---------------------------------------";
//for (const auto& node_str : node_strs)
// std::cout << node_str << std::endl;

//qDebug() << qstr;
//auto node_qstrs = qstr.split(" ");
//qDebug() << node_qstrs.size();
//for (const auto& node_str : node_strs)
//{
// if (node_str.isEmpty())
// continue;

// auto coord_strs = node_str.split(",");
// const auto lon = coord_strs[0].toDouble();
// const auto lat = coord_strs[1].toDouble();
// lring.nodes.push_back(Node{ lon, lat });
//}
}
else if (name == "SimpleData")
{
Expand Down
12 changes: 5 additions & 7 deletions Arrangement_on_surface_2/demo/earth/Main_widget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -108,11 +108,8 @@ void Main_widget::timerEvent(QTimerEvent*)

void Main_widget::initializeGL()
{

{
const auto file_name = "C:/work/gsoc2023/data/world_countries.kml";
auto countries = Kml::read(file_name);
}
const auto file_name = "C:/work/gsoc2023/data/world_countries.kml";
auto countries = Kml::read(file_name);


initializeOpenGLFunctions();
Expand All @@ -127,7 +124,8 @@ void Main_widget::initializeGL()
// because we want to compute the error based on camera parameters!
Geodesic_arcs ga;
const double error = 0.001; // calculate this from cam parameters!
auto lsa = ga.get_approximate_arcs(error);
auto lsa = ga.get_approx_arcs(countries, error);
//auto lsa = ga.get_approx_arcs(error);
m_geodesic_arcs = std::make_unique<Line_strips>(lsa);
}

Expand Down Expand Up @@ -258,7 +256,7 @@ void Main_widget::resizeGL(int w, int h)

// Reset projection
qreal aspect = qreal(w) / qreal(h ? h : 1);
const qreal z_near = 1.0, z_far = 100.0, fov = 45.0;
const qreal z_near = 0.1, z_far = 100.0, fov = 45.0;
m_camera.perspective(fov, aspect, z_near, z_far);

{
Expand Down

0 comments on commit a7bbef7

Please sign in to comment.