1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152
|
#pragma once
#include "glGrib/Options.h"
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <string>
namespace glGrib
{
class Projection
{
public:
enum type
{
XYZ=0,
POLAR_NORTH=1,
POLAR_SOUTH=2,
MERCATOR=3,
LATLON=4
};
virtual const glm::vec3 project (const glm::vec3 & xyz, const glm::mat3 & coordm) const = 0;
virtual int unproject (const glm::vec3 & xa, const glm::vec3 & xb, glm::vec3 * xyz, const glm::mat3 & coordm) const = 0;
virtual const glm::mat4 getView (const glm::vec3 & p, const float dist, const glm::mat3 & coordm,
const glm::vec3 & center, const glm::vec3 & up, const float roll) const = 0;
virtual int getType () const = 0;
virtual bool setLon0 (const float &) const = 0;
static type typeFromString (std::string str);
};
class ProjectionXYZ : public Projection
{
public:
const glm::vec3 project (const glm::vec3 & xyz, const glm::mat3 & coordm) const override;
int unproject (const glm::vec3 & xa, const glm::vec3 & xb, glm::vec3 * xyz, const glm::mat3 & coordm) const override;
const glm::mat4 getView (const glm::vec3 & p, const float dist, const glm::mat3 & coordm,
const glm::vec3 & center, const glm::vec3 & up, const float roll) const override;
int getType () const override { return Projection::XYZ; }
bool setLon0 (const float &) const override { return false; }
};
class ProjectionLatLon : public Projection
{
public:
const glm::vec3 project (const glm::vec3 & xyz, const glm::mat3 & coordm) const override;
int unproject (const glm::vec3 & xa, const glm::vec3 & xb, glm::vec3 * xyz, const glm::mat3 & coordm) const override;
const glm::mat4 getView (const glm::vec3 & p, const float dist, const glm::mat3 & coordm,
const glm::vec3 & center, const glm::vec3 & up, const float roll) const override;
int getType () const override { return Projection::LATLON; }
bool setLon0 (const float & lon) const override { lon0 = lon; return true; }
private:
mutable float lon0 = 180.0; // Latitude of right handside
};
class ProjectionMercator : public Projection
{
public:
const glm::vec3 project (const glm::vec3 & xyz, const glm::mat3 & coordm) const override;
int unproject (const glm::vec3 & xa, const glm::vec3 & xb, glm::vec3 * xyz, const glm::mat3 & coordm) const override;
const glm::mat4 getView (const glm::vec3 & p, const float dist, const glm::mat3 & coordm,
const glm::vec3 & center, const glm::vec3 & up, const float roll) const override;
int getType () const override { return Projection::MERCATOR; }
bool setLon0 (const float & lon) const override { lon0 = lon; return true; }
private:
mutable float lon0 = 180.0; // Latitude of right handside
};
class ProjectionPolarNorth : public Projection
{
public:
const glm::vec3 project (const glm::vec3 & xyz, const glm::mat3 & coordm) const override;
int unproject (const glm::vec3 & xa, const glm::vec3 & xb, glm::vec3 * xyz, const glm::mat3 & coordm) const override;
const glm::mat4 getView (const glm::vec3 & p, const float dist, const glm::mat3 & coordm,
const glm::vec3 & center, const glm::vec3 & up, const float roll) const override;
int getType () const override { return Projection::POLAR_NORTH; }
bool setLon0 (const float &) const override { return false; }
};
class ProjectionPolarSouth : public Projection
{
public:
const glm::vec3 project (const glm::vec3 & xyz, const glm::mat3 & coordm) const override;
int unproject (const glm::vec3 & xa, const glm::vec3 & xb, glm::vec3 * xyz, const glm::mat3 & coordm) const override;
const glm::mat4 getView (const glm::vec3 & p, const float dist, const glm::mat3 & coordm,
const glm::vec3 & center, const glm::vec3 & up, const float roll) const override;
int getType () const override { return Projection::POLAR_SOUTH; }
bool setLon0 (const float &) const override { return false; }
};
class ProjectionSet
{
public:
ProjectionSet ()
{
setup ();
}
ProjectionSet & operator= (const ProjectionSet & ps)
{
if (this != &ps)
{
setup ();
current_ = ps.current_;
}
return *this;
}
Projection * current () const
{
return proj[current_];
}
Projection * next ()
{
current_++; current_ %= 5; return current ();
}
void setType (const Projection::type & type)
{
current_ = type;
}
virtual const std::string currentName () const
{
#define if_type(x) case Projection::x: return #x
switch (current_)
{
if_type (XYZ);
if_type (POLAR_NORTH);
if_type (POLAR_SOUTH);
if_type (MERCATOR);
if_type (LATLON);
}
#undef if_type
return "";
}
private:
int current_ = Projection::XYZ;
void setup ()
{
proj[0] = &proj_xyz;
proj[1] = &proj_polar_north;
proj[2] = &proj_polar_south;
proj[3] = &proj_mercator;
proj[4] = &proj_latlon;
}
Projection * proj[5];
ProjectionXYZ proj_xyz;
ProjectionPolarNorth proj_polar_north;
ProjectionPolarSouth proj_polar_south;
ProjectionMercator proj_mercator;
ProjectionLatLon proj_latlon;
};
}
|