mirror of https://github.com/CGAL/cgal
World countries are rendered on the sphere
This commit is contained in:
parent
520083fd31
commit
a7bbef7d87
|
|
@ -5,6 +5,7 @@
|
|||
#include <iterator>
|
||||
#include <vector>
|
||||
|
||||
#include <qmath.h>
|
||||
#include <qvector3d.h>
|
||||
|
||||
#include <CGAL/Exact_predicates_exact_constructions_kernel.h>
|
||||
|
|
@ -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;
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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);
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
{
|
||||
|
|
@ -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")
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
@ -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);
|
||||
|
||||
{
|
||||
|
|
|
|||
Loading…
Reference in New Issue