123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320 |
- #ifndef BOOST_GEOMETRY_PROJECTIONS_ISEA_HPP
- #define BOOST_GEOMETRY_PROJECTIONS_ISEA_HPP
- #include <sstream>
- #include <boost/core/ignore_unused.hpp>
- #include <boost/geometry/core/assert.hpp>
- #include <boost/geometry/srs/projections/impl/base_static.hpp>
- #include <boost/geometry/srs/projections/impl/base_dynamic.hpp>
- #include <boost/geometry/srs/projections/impl/factory_entry.hpp>
- #include <boost/geometry/srs/projections/impl/pj_param.hpp>
- #include <boost/geometry/srs/projections/impl/projects.hpp>
- #include <boost/geometry/util/math.hpp>
- namespace boost { namespace geometry
- {
- namespace projections
- {
- #ifndef DOXYGEN_NO_DETAIL
- namespace detail { namespace isea
- {
- static const double epsilon = std::numeric_limits<double>::epsilon();
-
- static const double isea_scale = 0.8301572857837594396028083;
-
- static const double v_lat = 0.46364760899944494524;
-
- static const double e_rad = 0.91843818702186776133;
-
- static const double f_rad = 0.18871053072122403508;
-
- static const double table_g = 0.6615845383;
-
- static const double table_h = 0.1909830056;
-
- static const double isea_std_lat = 1.01722196792335072101;
- static const double isea_std_lon = .19634954084936207740;
- template <typename T>
- inline T deg30_rad() { return T(30) * geometry::math::d2r<T>(); }
- template <typename T>
- inline T deg120_rad() { return T(120) * geometry::math::d2r<T>(); }
- template <typename T>
- inline T deg72_rad() { return T(72) * geometry::math::d2r<T>(); }
- template <typename T>
- inline T deg90_rad() { return geometry::math::half_pi<T>(); }
- template <typename T>
- inline T deg144_rad() { return T(144) * geometry::math::d2r<T>(); }
- template <typename T>
- inline T deg36_rad() { return T(36) * geometry::math::d2r<T>(); }
- template <typename T>
- inline T deg108_rad() { return T(108) * geometry::math::d2r<T>(); }
- template <typename T>
- inline T deg180_rad() { return geometry::math::pi<T>(); }
- inline bool downtri(int tri) { return (((tri - 1) / 5) % 2 == 1); }
-
- struct hex {
- int iso;
- int x, y, z;
- };
-
- inline
- int hex_xy(struct hex *h) {
- if (!h->iso) return 1;
- if (h->x >= 0) {
- h->y = -h->y - (h->x+1)/2;
- } else {
-
- h->y = -h->y - h->x/2;
- }
- h->iso = 0;
- return 1;
- }
- inline
- int hex_iso(struct hex *h) {
- if (h->iso) return 1;
- if (h->x >= 0) {
- h->y = (-h->y - (h->x+1)/2);
- } else {
-
- h->y = (-h->y - (h->x)/2);
- }
- h->z = -h->x - h->y;
- h->iso = 1;
- return 1;
- }
- template <typename T>
- inline
- int hexbin2(T const& width, T x, T y, int *i, int *j)
- {
- T z, rx, ry, rz;
- T abs_dx, abs_dy, abs_dz;
- int ix, iy, iz, s;
- struct hex h;
- static const T cos_deg30 = cos(deg30_rad<T>());
- x = x / cos_deg30;
- y = y - x / 2.0;
-
- x /= width;
- y /= width;
- z = -x - y;
- rx = floor(x + 0.5);
- ix = (int)rx;
- ry = floor(y + 0.5);
- iy = (int)ry;
- rz = floor(z + 0.5);
- iz = (int)rz;
- s = ix + iy + iz;
- if (s) {
- abs_dx = fabs(rx - x);
- abs_dy = fabs(ry - y);
- abs_dz = fabs(rz - z);
- if (abs_dx >= abs_dy && abs_dx >= abs_dz) {
- ix -= s;
- } else if (abs_dy >= abs_dx && abs_dy >= abs_dz) {
- iy -= s;
- } else {
- iz -= s;
- }
- }
- h.x = ix;
- h.y = iy;
- h.z = iz;
- h.iso = 1;
- hex_xy(&h);
- *i = h.x;
- *j = h.y;
- return ix * 100 + iy;
- }
-
-
- enum isea_address_form {
- isea_addr_q2di, isea_addr_seqnum,
- isea_addr_plane, isea_addr_q2dd,
- isea_addr_projtri, isea_addr_vertex2dd, isea_addr_hex
- };
- template <typename T>
- struct isea_dgg {
- T o_lat, o_lon, o_az;
- T radius;
- unsigned long serial;
-
- int aperture;
- int resolution;
- int triangle;
- int quad;
-
-
- isea_address_form output;
- };
- template <typename T>
- struct isea_pt {
- T x, y;
- };
- template <typename T>
- struct isea_geo {
- T lon, lat;
- };
- template <typename T>
- struct isea_address {
- T x,y;
- int type;
- int number;
- };
-
- enum snyder_polyhedron {
- snyder_poly_hexagon = 0, snyder_poly_pentagon = 1,
- snyder_poly_tetrahedron = 2, snyder_poly_cube = 3,
- snyder_poly_octahedron = 4, snyder_poly_dodecahedron = 5,
- snyder_poly_icosahedron = 6
- };
- template <typename T>
- struct snyder_constants {
- T g, G, theta, ea_w, ea_a, ea_b, g_w, g_a, g_b;
- };
- template <typename T>
- inline const snyder_constants<T> * constants()
- {
-
- static snyder_constants<T> result[] = {
- {23.80018260, 62.15458023, 60.0, 3.75, 1.033, 0.968, 5.09, 1.195, 1.0},
- {20.07675127, 55.69063953, 54.0, 2.65, 1.030, 0.983, 3.59, 1.141, 1.027},
- {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
- {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
- {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
- {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
- {37.37736814, 36.0, 30.0, 17.27, 1.163, 0.860, 13.14, 1.584, 1.0}
- };
- return result;
- }
- template <typename T>
- inline const isea_geo<T> * vertex()
- {
- static isea_geo<T> result[] = {
- { 0.0, deg90_rad<T>()},
- { deg180_rad<T>(), v_lat},
- {-deg108_rad<T>(), v_lat},
- {-deg36_rad<T>(), v_lat},
- { deg36_rad<T>(), v_lat},
- { deg108_rad<T>(), v_lat},
- {-deg144_rad<T>(), -v_lat},
- {-deg72_rad<T>(), -v_lat},
- { 0.0, -v_lat},
- { deg72_rad<T>(), -v_lat},
- { deg144_rad<T>(), -v_lat},
- { 0.0, -deg90_rad<T>()}
- };
- return result;
- }
-
- static int tri_v1[] = {0, 0, 0, 0, 0, 0, 6, 7, 8, 9, 10, 2, 3, 4, 5, 1, 11, 11, 11, 11, 11};
-
- template <typename T>
- inline const isea_geo<T> * icostriangles()
- {
- static isea_geo<T> result[] = {
- { 0.0, 0.0},
- {-deg144_rad<T>(), e_rad},
- {-deg72_rad<T>(), e_rad},
- { 0.0, e_rad},
- { deg72_rad<T>(), e_rad},
- { deg144_rad<T>(), e_rad},
- {-deg144_rad<T>(), f_rad},
- {-deg72_rad<T>(), f_rad},
- { 0.0, f_rad},
- { deg72_rad<T>(), f_rad},
- { deg144_rad<T>(), f_rad},
- {-deg108_rad<T>(), -f_rad},
- {-deg36_rad<T>(), -f_rad},
- { deg36_rad<T>(), -f_rad},
- { deg108_rad<T>(), -f_rad},
- { deg180_rad<T>(), -f_rad},
- {-deg108_rad<T>(), -e_rad},
- {-deg36_rad<T>(), -e_rad},
- { deg36_rad<T>(), -e_rad},
- { deg108_rad<T>(), -e_rad},
- { deg180_rad<T>(), -e_rad},
- };
- return result;
- }
- template <typename T>
- inline T az_adjustment(int triangle)
- {
- T adj;
- isea_geo<T> v;
- isea_geo<T> c;
- v = vertex<T>()[tri_v1[triangle]];
- c = icostriangles<T>()[triangle];
-
-
- adj = atan2(cos(v.lat) * sin(v.lon - c.lon),
- cos(c.lat) * sin(v.lat)
- - sin(c.lat) * cos(v.lat) * cos(v.lon - c.lon));
- return adj;
- }
- template <typename T>
- inline isea_pt<T> isea_triangle_xy(int triangle)
- {
- isea_pt<T> c;
- T Rprime = 0.91038328153090290025;
- triangle = (triangle - 1) % 20;
- c.x = table_g * ((triangle % 5) - 2) * 2.0;
- if (triangle > 9) {
- c.x += table_g;
- }
- switch (triangle / 5) {
- case 0:
- c.y = 5.0 * table_h;
- break;
- case 1:
- c.y = table_h;
- break;
- case 2:
- c.y = -table_h;
- break;
- case 3:
- c.y = -5.0 * table_h;
- break;
- default:
-
- BOOST_THROW_EXCEPTION( projection_exception() );
- };
- c.x *= Rprime;
- c.y *= Rprime;
- return c;
- }
-
- template <typename T>
- inline T sph_azimuth(T const& f_lon, T const& f_lat, T const& t_lon, T const& t_lat)
- {
- T az;
- az = atan2(cos(t_lat) * sin(t_lon - f_lon),
- cos(f_lat) * sin(t_lat)
- - sin(f_lat) * cos(t_lat) * cos(t_lon - f_lon)
- );
- return az;
- }
-
- template <typename T>
- inline int isea_snyder_forward(isea_geo<T> * ll, isea_pt<T> * out)
- {
- static T const two_pi = detail::two_pi<T>();
- static T const d2r = geometry::math::d2r<T>();
- int i;
-
- T g;
-
- T G;
-
- T theta;
-
- T q, Rprime, H, Ag, Azprime, Az, dprime, f, rho,
- x, y;
-
- T cot_theta, tan_g, az_offset;
-
- int Az_adjust_multiples;
- snyder_constants<T> c;
-
-
- c = constants<T>()[snyder_poly_icosahedron];
- theta = c.theta * d2r;
- g = c.g * d2r;
- G = c.G * d2r;
- for (i = 1; i <= 20; i++) {
- T z;
- isea_geo<T> center;
- center = icostriangles<T>()[i];
-
- z = acos(sin(center.lat) * sin(ll->lat)
- + cos(center.lat) * cos(ll->lat) * cos(ll->lon - center.lon));
-
- if (z > g + 0.000005) {
- continue;
- }
- Az = sph_azimuth(center.lon, center.lat, ll->lon, ll->lat);
-
-
- az_offset = az_adjustment<T>(i);
- Az -= az_offset;
-
-
- if (Az < 0.0) {
- Az += two_pi;
- }
-
- Az_adjust_multiples = 0;
- while (Az < 0.0) {
- Az += deg120_rad<T>();
- Az_adjust_multiples--;
- }
- while (Az > deg120_rad<T>() + epsilon) {
- Az -= deg120_rad<T>();
- Az_adjust_multiples++;
- }
-
- cot_theta = 1.0 / tan(theta);
- tan_g = tan(g);
-
-
- q = atan2(tan_g, cos(Az) + sin(Az) * cot_theta);
-
- if (z > q + 0.000005) {
- continue;
- }
-
-
-
-
-
- Rprime = 0.91038328153090290025;
-
- H = acos(sin(Az) * sin(G) * cos(g) - cos(Az) * cos(G));
-
-
- Ag = Az + G + H - deg180_rad<T>();
-
- Azprime = atan2(2.0 * Ag, Rprime * Rprime * tan_g * tan_g - 2.0 * Ag * cot_theta);
-
-
- dprime = Rprime * tan_g / (cos(Azprime) + sin(Azprime) * cot_theta);
-
- f = dprime / (2.0 * Rprime * sin(q / 2.0));
-
- rho = 2.0 * Rprime * f * sin(z / 2.0);
-
- Azprime += deg120_rad<T>() * Az_adjust_multiples;
-
- x = rho * sin(Azprime);
- y = rho * cos(Azprime);
-
- out->x = x;
- out->y = y;
- return i;
- }
-
-
-
- std::stringstream ss;
- ss << "impossible transform: " << ll->lon * geometry::math::r2d<T>()
- << " " << ll->lat * geometry::math::r2d<T>() << " is not on any triangle.";
- BOOST_THROW_EXCEPTION( projection_exception(ss.str()) );
-
- return 0;
- }
-
-
-
- template <typename T>
- inline isea_geo<T> snyder_ctran(isea_geo<T> * np, isea_geo<T> * pt)
- {
- static T const pi = detail::pi<T>();
- static T const two_pi = detail::two_pi<T>();
- isea_geo<T> npt;
- T alpha, phi, lambda, lambda0, beta, lambdap, phip;
- T sin_phip;
- T lp_b;
- T cos_p, sin_a;
- phi = pt->lat;
- lambda = pt->lon;
- alpha = np->lat;
- beta = np->lon;
- lambda0 = beta;
- cos_p = cos(phi);
- sin_a = sin(alpha);
-
- sin_phip = sin_a * sin(phi) - cos(alpha) * cos_p * cos(lambda - lambda0);
-
-
- lp_b = atan2(cos_p * sin(lambda - lambda0),
- (sin_a * cos_p * cos(lambda - lambda0) + cos(alpha) * sin(phi)));
- lambdap = lp_b + beta;
-
-
- lambdap = fmod(lambdap, two_pi);
- while (lambdap > pi)
- lambdap -= two_pi;
- while (lambdap < -pi)
- lambdap += two_pi;
- phip = asin(sin_phip);
- npt.lat = phip;
- npt.lon = lambdap;
- return npt;
- }
- template <typename T>
- inline isea_geo<T> isea_ctran(isea_geo<T> * np, isea_geo<T> * pt, T const& lon0)
- {
- static T const pi = detail::pi<T>();
- static T const two_pi = detail::two_pi<T>();
- isea_geo<T> npt;
- np->lon += pi;
- npt = snyder_ctran(np, pt);
- np->lon -= pi;
- npt.lon -= (pi - lon0 + np->lon);
-
- npt.lon += pi;
-
- npt.lon = fmod(npt.lon, two_pi);
- while (npt.lon > pi)
- npt.lon -= two_pi;
- while (npt.lon < -pi)
- npt.lon += two_pi;
- return npt;
- }
-
-
- template <typename T>
- inline int isea_grid_init(isea_dgg<T> * g)
- {
- if (!g)
- return 0;
-
- g->o_lat = isea_std_lat;
- g->o_lon = isea_std_lon;
- g->o_az = 0.0;
- g->aperture = 4;
- g->resolution = 6;
- g->radius = 1.0;
-
- return 1;
- }
- template <typename T>
- inline int isea_orient_isea(isea_dgg<T> * g)
- {
- if (!g)
- return 0;
- g->o_lat = isea_std_lat;
- g->o_lon = isea_std_lon;
- g->o_az = 0.0;
- return 1;
- }
- template <typename T>
- inline int isea_orient_pole(isea_dgg<T> * g)
- {
- static T const half_pi = detail::half_pi<T>();
- if (!g)
- return 0;
- g->o_lat = half_pi;
- g->o_lon = 0.0;
- g->o_az = 0;
- return 1;
- }
- template <typename T>
- inline int isea_transform(isea_dgg<T> * g, isea_geo<T> * in,
- isea_pt<T> * out)
- {
- isea_geo<T> i, pole;
- int tri;
- pole.lat = g->o_lat;
- pole.lon = g->o_lon;
- i = isea_ctran(&pole, in, g->o_az);
- tri = isea_snyder_forward(&i, out);
- out->x *= g->radius;
- out->y *= g->radius;
- g->triangle = tri;
- return tri;
- }
- template <typename T>
- inline void isea_rotate(isea_pt<T> * pt, T const& degrees)
- {
- static T const d2r = geometry::math::d2r<T>();
- static T const two_pi = detail::two_pi<T>();
- T rad;
- T x, y;
- rad = -degrees * d2r;
- while (rad >= two_pi) rad -= two_pi;
- while (rad <= -two_pi) rad += two_pi;
- x = pt->x * cos(rad) + pt->y * sin(rad);
- y = -pt->x * sin(rad) + pt->y * cos(rad);
- pt->x = x;
- pt->y = y;
- }
- template <typename T>
- inline int isea_tri_plane(int tri, isea_pt<T> *pt, T const& radius)
- {
- isea_pt<T> tc;
- if (downtri(tri)) {
- isea_rotate(pt, 180.0);
- }
- tc = isea_triangle_xy<T>(tri);
- tc.x *= radius;
- tc.y *= radius;
- pt->x += tc.x;
- pt->y += tc.y;
- return tri;
- }
-
- template <typename T>
- inline int isea_ptdd(int tri, isea_pt<T> *pt)
- {
- int downtri, quad;
- downtri = (((tri - 1) / 5) % 2 == 1);
- quad = ((tri - 1) % 5) + ((tri - 1) / 10) * 5 + 1;
- isea_rotate(pt, downtri ? 240.0 : 60.0);
- if (downtri) {
- pt->x += 0.5;
-
- pt->y += .86602540378443864672;
- }
- return quad;
- }
- template <typename T>
- inline int isea_dddi_ap3odd(isea_dgg<T> *g, int quad, isea_pt<T> *pt, isea_pt<T> *di)
- {
- static T const pi = detail::pi<T>();
- isea_pt<T> v;
- T hexwidth;
- T sidelength;
- int d, i;
- int maxcoord;
- hex h;
-
- sidelength = (math::pow(T(2), g->resolution) + T(1)) / T(2);
-
- hexwidth = cos(pi / 6.0) / sidelength;
-
- maxcoord = (int) (sidelength * 2.0 + 0.5);
- v = *pt;
- hexbin2(hexwidth, v.x, v.y, &h.x, &h.y);
- h.iso = 0;
- hex_iso(&h);
- d = h.x - h.z;
- i = h.x + h.y + h.y;
-
- if (quad <= 5) {
- if (d == 0 && i == maxcoord) {
-
- quad = 0;
- d = 0;
- i = 0;
- } else if (i == maxcoord) {
-
- quad += 1;
- if (quad == 6)
- quad = 1;
- i = maxcoord - d;
- d = 0;
- } else if (d == maxcoord) {
-
- quad += 5;
- d = 0;
- }
- } else if (quad >= 6) {
- if (i == 0 && d == maxcoord) {
-
- quad = 11;
- d = 0;
- i = 0;
- } else if (d == maxcoord) {
-
- quad += 1;
- if (quad == 11)
- quad = 6;
- d = maxcoord - i;
- i = 0;
- } else if (i == maxcoord) {
-
- quad = (quad - 4) % 5;
- i = 0;
- }
- }
- di->x = d;
- di->y = i;
- g->quad = quad;
- return quad;
- }
- template <typename T>
- inline int isea_dddi(isea_dgg<T> *g, int quad, isea_pt<T> *pt, isea_pt<T> *di)
- {
- isea_pt<T> v;
- T hexwidth;
- int sidelength;
- hex h;
- if (g->aperture == 3 && g->resolution % 2 != 0) {
- return isea_dddi_ap3odd(g, quad, pt, di);
- }
-
- if (g->aperture >0) {
- sidelength = (int) (math::pow(T(g->aperture), T(g->resolution / T(2))) + T(0.5));
- } else {
- sidelength = g->resolution;
- }
- hexwidth = 1.0 / sidelength;
- v = *pt;
- isea_rotate(&v, -30.0);
- hexbin2(hexwidth, v.x, v.y, &h.x, &h.y);
- h.iso = 0;
- hex_iso(&h);
-
- if (quad <= 5) {
- if (h.x == 0 && h.z == -sidelength) {
-
- quad = 0;
- h.z = 0;
- h.y = 0;
- h.x = 0;
- } else if (h.z == -sidelength) {
- quad = quad + 1;
- if (quad == 6)
- quad = 1;
- h.y = sidelength - h.x;
- h.z = h.x - sidelength;
- h.x = 0;
- } else if (h.x == sidelength) {
- quad += 5;
- h.y = -h.z;
- h.x = 0;
- }
- } else if (quad >= 6) {
- if (h.z == 0 && h.x == sidelength) {
-
- quad = 11;
- h.x = 0;
- h.y = 0;
- h.z = 0;
- } else if (h.x == sidelength) {
- quad = quad + 1;
- if (quad == 11)
- quad = 6;
- h.x = h.y + sidelength;
- h.y = 0;
- h.z = -h.x;
- } else if (h.y == -sidelength) {
- quad -= 4;
- h.y = 0;
- h.z = -h.x;
- }
- }
- di->x = h.x;
- di->y = -h.z;
- g->quad = quad;
- return quad;
- }
- template <typename T>
- inline int isea_ptdi(isea_dgg<T> *g, int tri, isea_pt<T> *pt,
- isea_pt<T> *di)
- {
- isea_pt<T> v;
- int quad;
- v = *pt;
- quad = isea_ptdd(tri, &v);
- quad = isea_dddi(g, quad, &v, di);
- return quad;
- }
-
- template <typename T>
- inline int isea_disn(isea_dgg<T> *g, int quad, isea_pt<T> *di)
- {
- int sidelength;
- int sn, height;
- int hexes;
- if (quad == 0) {
- g->serial = 1;
- return g->serial;
- }
-
- hexes = (int) (math::pow(T(g->aperture), T(g->resolution)) + T(0.5));
- if (quad == 11) {
- g->serial = 1 + 10 * hexes + 1;
- return g->serial;
- }
- if (g->aperture == 3 && g->resolution % 2 == 1) {
- height = (int) (math::pow(T(g->aperture), T((g->resolution - 1) / T(2))));
- sn = ((int) di->x) * height;
- sn += ((int) di->y) / height;
- sn += (quad - 1) * hexes;
- sn += 2;
- } else {
- sidelength = (int) (math::pow(T(g->aperture), T(g->resolution / T(2))) + T(0.5));
- sn = (int) ((quad - 1) * hexes + sidelength * di->x + di->y + 2);
- }
- g->serial = sn;
- return sn;
- }
-
-
- template <typename T>
- inline int isea_hex(isea_dgg<T> *g, int tri, isea_pt<T> *pt,
- isea_pt<T> *hex)
- {
- isea_pt<T> v;
- #ifdef BOOST_GEOMETRY_PROJECTIONS_FIXME
- int sidelength;
- int d, i, x, y;
- #endif
- int quad;
- quad = isea_ptdi(g, tri, pt, &v);
- hex->x = ((int)v.x << 4) + quad;
- hex->y = v.y;
- return 1;
- #ifdef BOOST_GEOMETRY_PROJECTIONS_FIXME
- d = (int)v.x;
- i = (int)v.y;
-
- if (g->aperture == 3 && g->resolution % 2 != 0) {
- int offset = (int)(pow(T(3.0), T(g->resolution - 1)) + 0.5);
- d += offset * ((g->quad-1) % 5);
- i += offset * ((g->quad-1) % 5);
- if (quad == 0) {
- d = 0;
- i = offset;
- } else if (quad == 11) {
- d = 2 * offset;
- i = 0;
- } else if (quad > 5) {
- d += offset;
- }
- x = (2*d - i) /3;
- y = (2*i - d) /3;
- hex->x = x + offset / 3;
- hex->y = y + 2 * offset / 3;
- return 1;
- }
-
- sidelength = (int) (pow(T(g->aperture), T(g->resolution / 2.0)) + 0.5);
- if (g->quad == 0) {
- hex->x = 0;
- hex->y = sidelength;
- } else if (g->quad == 11) {
- hex->x = sidelength * 2;
- hex->y = 0;
- } else {
- hex->x = d + sidelength * ((g->quad-1) % 5);
- if (g->quad > 5) hex->x += sidelength;
- hex->y = i + sidelength * ((g->quad-1) % 5);
- }
- return 1;
- #endif
- }
- template <typename T>
- inline isea_pt<T> isea_forward(isea_dgg<T> *g, isea_geo<T> *in)
- {
- int tri;
- isea_pt<T> out, coord;
- tri = isea_transform(g, in, &out);
- if (g->output == isea_addr_plane) {
- isea_tri_plane(tri, &out, g->radius);
- return out;
- }
-
- out.x = out.x / g->radius * isea_scale;
- out.y = out.y / g->radius * isea_scale;
- out.x += 0.5;
- out.y += 2.0 * .14433756729740644112;
- switch (g->output) {
- case isea_addr_projtri:
-
- break;
- case isea_addr_vertex2dd:
- g->quad = isea_ptdd(tri, &out);
- break;
- case isea_addr_q2dd:
-
- g->quad = isea_ptdd(tri, &out);
- break;
- case isea_addr_q2di:
- g->quad = isea_ptdi(g, tri, &out, &coord);
- return coord;
- break;
- case isea_addr_seqnum:
- isea_ptdi(g, tri, &out, &coord);
-
- isea_disn(g, g->quad, &coord);
- return coord;
- break;
- case isea_addr_hex:
- isea_hex(g, tri, &out, &coord);
- return coord;
- break;
- default:
-
- BOOST_GEOMETRY_ASSERT(false);
- break;
- }
- return out;
- }
-
- template <typename T>
- struct par_isea
- {
- isea_dgg<T> dgg;
- };
- template <typename T, typename Parameters>
- struct base_isea_spheroid
- {
- par_isea<T> m_proj_parm;
-
-
- inline void fwd(Parameters const& , T const& lp_lon, T const& lp_lat, T& xy_x, T& xy_y) const
- {
- isea_pt<T> out;
- isea_geo<T> in;
- in.lon = lp_lon;
- in.lat = lp_lat;
- isea_dgg<T> copy = this->m_proj_parm.dgg;
- out = isea_forward(©, &in);
- xy_x = out.x;
- xy_y = out.y;
- }
- static inline std::string get_name()
- {
- return "isea_spheroid";
- }
- };
- template <typename T>
- inline void isea_orient_init(srs::detail::proj4_parameters const& params,
- par_isea<T>& proj_parm)
- {
- std::string opt = pj_get_param_s(params, "orient");
- if (! opt.empty()) {
- if (opt == std::string("isea")) {
- isea_orient_isea(&proj_parm.dgg);
- } else if (opt == std::string("pole")) {
- isea_orient_pole(&proj_parm.dgg);
- } else {
- BOOST_THROW_EXCEPTION( projection_exception(error_ellipsoid_use_required) );
- }
- }
- }
- template <typename T>
- inline void isea_orient_init(srs::dpar::parameters<T> const& params,
- par_isea<T>& proj_parm)
- {
- typename srs::dpar::parameters<T>::const_iterator
- it = pj_param_find(params, srs::dpar::orient);
- if (it != params.end()) {
- srs::dpar::value_orient o = static_cast<srs::dpar::value_orient>(it->template get_value<int>());
- if (o == srs::dpar::orient_isea) {
- isea_orient_isea(&proj_parm.dgg);
- } else if (o == srs::dpar::orient_pole) {
- isea_orient_pole(&proj_parm.dgg);
- } else {
- BOOST_THROW_EXCEPTION( projection_exception(error_ellipsoid_use_required) );
- }
- }
- }
- template <typename T>
- inline void isea_mode_init(srs::detail::proj4_parameters const& params,
- par_isea<T>& proj_parm)
- {
- std::string opt = pj_get_param_s(params, "mode");
- if (! opt.empty()) {
- if (opt == std::string("plane")) {
- proj_parm.dgg.output = isea_addr_plane;
- } else if (opt == std::string("di")) {
- proj_parm.dgg.output = isea_addr_q2di;
- } else if (opt == std::string("dd")) {
- proj_parm.dgg.output = isea_addr_q2dd;
- } else if (opt == std::string("hex")) {
- proj_parm.dgg.output = isea_addr_hex;
- } else {
- BOOST_THROW_EXCEPTION( projection_exception(error_ellipsoid_use_required) );
- }
- }
- }
- template <typename T>
- inline void isea_mode_init(srs::dpar::parameters<T> const& params,
- par_isea<T>& proj_parm)
- {
- typename srs::dpar::parameters<T>::const_iterator
- it = pj_param_find(params, srs::dpar::mode);
- if (it != params.end()) {
- srs::dpar::value_mode m = static_cast<srs::dpar::value_mode>(it->template get_value<int>());
- if (m == srs::dpar::mode_plane) {
- proj_parm.dgg.output = isea_addr_plane;
- } else if (m == srs::dpar::mode_di) {
- proj_parm.dgg.output = isea_addr_q2di;
- } else if (m == srs::dpar::mode_dd) {
- proj_parm.dgg.output = isea_addr_q2dd;
- } else if (m == srs::dpar::mode_hex) {
- proj_parm.dgg.output = isea_addr_hex;
- } else {
- BOOST_THROW_EXCEPTION( projection_exception(error_ellipsoid_use_required) );
- }
- }
- }
-
- template <typename Params, typename T>
- inline void setup_isea(Params const& params, par_isea<T>& proj_parm)
- {
- std::string opt;
- isea_grid_init(&proj_parm.dgg);
- proj_parm.dgg.output = isea_addr_plane;
-
-
- isea_orient_init(params, proj_parm);
- pj_param_r<srs::spar::azi>(params, "azi", srs::dpar::azi, proj_parm.dgg.o_az);
- pj_param_r<srs::spar::lon_0>(params, "lon_0", srs::dpar::lon_0, proj_parm.dgg.o_lon);
- pj_param_r<srs::spar::lat_0>(params, "lat_0", srs::dpar::lat_0, proj_parm.dgg.o_lat);
-
- pj_param_i<srs::spar::aperture>(params, "aperture", srs::dpar::aperture, proj_parm.dgg.aperture);
-
- pj_param_i<srs::spar::resolution>(params, "resolution", srs::dpar::resolution, proj_parm.dgg.resolution);
- isea_mode_init(params, proj_parm);
-
- if (pj_param_exists<srs::spar::rescale>(params, "rescale", srs::dpar::rescale)) {
- proj_parm.dgg.radius = isea_scale;
- }
- if (pj_param_i<srs::spar::resolution>(params, "resolution", srs::dpar::resolution, proj_parm.dgg.resolution)) {
-
- } else {
- proj_parm.dgg.resolution = 4;
- }
- if (pj_param_i<srs::spar::aperture>(params, "aperture", srs::dpar::aperture, proj_parm.dgg.aperture)) {
-
- } else {
- proj_parm.dgg.aperture = 3;
- }
- }
- }}
- #endif
-
- template <typename T, typename Parameters>
- struct isea_spheroid : public detail::isea::base_isea_spheroid<T, Parameters>
- {
- template <typename Params>
- inline isea_spheroid(Params const& params, Parameters const& )
- {
- detail::isea::setup_isea(params, this->m_proj_parm);
- }
- };
- #ifndef DOXYGEN_NO_DETAIL
- namespace detail
- {
-
- BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION_F(srs::spar::proj_isea, isea_spheroid)
-
- BOOST_GEOMETRY_PROJECTIONS_DETAIL_FACTORY_ENTRY_F(isea_entry, isea_spheroid)
- BOOST_GEOMETRY_PROJECTIONS_DETAIL_FACTORY_INIT_BEGIN(isea_init)
- {
- BOOST_GEOMETRY_PROJECTIONS_DETAIL_FACTORY_INIT_ENTRY(isea, isea_entry)
- }
- }
- #endif
- }
- }}
- #endif
|