123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407 |
- #ifndef BOOST_GEOMETRY_PROJECTIONS_IGH_HPP
- #define BOOST_GEOMETRY_PROJECTIONS_IGH_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/projects.hpp>
- #include <boost/geometry/srs/projections/impl/factory_entry.hpp>
- #include <boost/geometry/srs/projections/proj/gn_sinu.hpp>
- #include <boost/geometry/srs/projections/proj/moll.hpp>
- #include <boost/geometry/util/math.hpp>
- namespace boost { namespace geometry
- {
- namespace projections
- {
- #ifndef DOXYGEN_NO_DETAIL
- namespace detail { namespace igh
- {
- template <typename T>
- struct par_igh_zone
- {
- T x0;
- T y0;
- T lam0;
- };
-
-
-
-
-
-
-
-
-
- template <typename T, typename Parameters>
- struct par_igh
- {
- moll_spheroid<T, Parameters> moll;
- sinu_spheroid<T, Parameters> sinu;
- par_igh_zone<T> zones[12];
- T dy0;
-
-
- template <typename Params>
- inline par_igh(Params const& params, Parameters & par)
- : moll(params, par)
- , sinu(params, par)
- {}
- inline void fwd(int zone, Parameters const& par, T const& lp_lon, T const& lp_lat, T & xy_x, T & xy_y) const
- {
- if (zone <= 2 || zone >= 9)
- moll.fwd(par, lp_lon, lp_lat, xy_x, xy_y);
- else
- sinu.fwd(par, lp_lon, lp_lat, xy_x, xy_y);
- }
- inline void inv(int zone, Parameters const& par, T const& xy_x, T const& xy_y, T & lp_lon, T & lp_lat) const
- {
- if (zone <= 2 || zone >= 9)
- moll.inv(par, xy_x, xy_y, lp_lon, lp_lat);
- else
- sinu.inv(par, xy_x, xy_y, lp_lon, lp_lat);
- }
- inline void set_zone(int zone, T const& x_0, T const& y_0, T const& lon_0)
- {
- zones[zone - 1].x0 = x_0;
- zones[zone - 1].y0 = y_0;
- zones[zone - 1].lam0 = lon_0;
- }
- inline par_igh_zone<T> const& get_zone(int zone) const
- {
- return zones[zone - 1];
- }
- };
-
- template <typename T>
- inline T d4044118() { return (T(40) + T(44)/T(60.) + T(11.8)/T(3600.)) * geometry::math::d2r<T>(); }
- template <typename T>
- inline T d10() { return T(10) * geometry::math::d2r<T>(); }
- template <typename T>
- inline T d20() { return T(20) * geometry::math::d2r<T>(); }
- template <typename T>
- inline T d30() { return T(30) * geometry::math::d2r<T>(); }
- template <typename T>
- inline T d40() { return T(40) * geometry::math::d2r<T>(); }
- template <typename T>
- inline T d50() { return T(50) * geometry::math::d2r<T>(); }
- template <typename T>
- inline T d60() { return T(60) * geometry::math::d2r<T>(); }
- template <typename T>
- inline T d80() { return T(80) * geometry::math::d2r<T>(); }
- template <typename T>
- inline T d90() { return T(90) * geometry::math::d2r<T>(); }
- template <typename T>
- inline T d100() { return T(100) * geometry::math::d2r<T>(); }
- template <typename T>
- inline T d140() { return T(140) * geometry::math::d2r<T>(); }
- template <typename T>
- inline T d160() { return T(160) * geometry::math::d2r<T>(); }
- template <typename T>
- inline T d180() { return T(180) * geometry::math::d2r<T>(); }
- static const double epsilon = 1.e-10;
- template <typename T, typename Parameters>
- struct base_igh_spheroid
- {
- par_igh<T, Parameters> m_proj_parm;
- template <typename Params>
- inline base_igh_spheroid(Params const& params, Parameters & par)
- : m_proj_parm(params, par)
- {}
-
-
- inline void fwd(Parameters const& par, T lp_lon, T const& lp_lat, T& xy_x, T& xy_y) const
- {
- static const T d4044118 = igh::d4044118<T>();
- static const T d20 = igh::d20<T>();
- static const T d40 = igh::d40<T>();
- static const T d80 = igh::d80<T>();
- static const T d100 = igh::d100<T>();
- int z;
- if (lp_lat >= d4044118) {
- z = (lp_lon <= -d40 ? 1: 2);
- }
- else if (lp_lat >= 0) {
- z = (lp_lon <= -d40 ? 3: 4);
- }
- else if (lp_lat >= -d4044118) {
- if (lp_lon <= -d100) z = 5;
- else if (lp_lon <= -d20) z = 6;
- else if (lp_lon <= d80) z = 7;
- else z = 8;
- }
- else {
- if (lp_lon <= -d100) z = 9;
- else if (lp_lon <= -d20) z = 10;
- else if (lp_lon <= d80) z = 11;
- else z = 12;
- }
- lp_lon -= this->m_proj_parm.get_zone(z).lam0;
- this->m_proj_parm.fwd(z, par, lp_lon, lp_lat, xy_x, xy_y);
- xy_x += this->m_proj_parm.get_zone(z).x0;
- xy_y += this->m_proj_parm.get_zone(z).y0;
- }
-
-
- inline void inv(Parameters const& par, T xy_x, T xy_y, T& lp_lon, T& lp_lat) const
- {
- static const T d4044118 = igh::d4044118<T>();
- static const T d10 = igh::d10<T>();
- static const T d20 = igh::d20<T>();
- static const T d40 = igh::d40<T>();
- static const T d50 = igh::d50<T>();
- static const T d60 = igh::d60<T>();
- static const T d80 = igh::d80<T>();
- static const T d90 = igh::d90<T>();
- static const T d100 = igh::d100<T>();
- static const T d160 = igh::d160<T>();
- static const T d180 = igh::d180<T>();
- static const T c2 = 2.0;
- const T y90 = this->m_proj_parm.dy0 + sqrt(c2);
- int z = 0;
- if (xy_y > y90+epsilon || xy_y < -y90+epsilon)
- z = 0;
- else if (xy_y >= d4044118)
- z = (xy_x <= -d40? 1: 2);
- else if (xy_y >= 0)
- z = (xy_x <= -d40? 3: 4);
- else if (xy_y >= -d4044118) {
- if (xy_x <= -d100) z = 5;
- else if (xy_x <= -d20) z = 6;
- else if (xy_x <= d80) z = 7;
- else z = 8;
- }
- else {
- if (xy_x <= -d100) z = 9;
- else if (xy_x <= -d20) z = 10;
- else if (xy_x <= d80) z = 11;
- else z = 12;
- }
- if (z)
- {
- int ok = 0;
- xy_x -= this->m_proj_parm.get_zone(z).x0;
- xy_y -= this->m_proj_parm.get_zone(z).y0;
- this->m_proj_parm.inv(z, par, xy_x, xy_y, lp_lon, lp_lat);
- lp_lon += this->m_proj_parm.get_zone(z).lam0;
- switch (z) {
- case 1: ok = (lp_lon >= -d180-epsilon && lp_lon <= -d40+epsilon) ||
- ((lp_lon >= -d40-epsilon && lp_lon <= -d10+epsilon) &&
- (lp_lat >= d60-epsilon && lp_lat <= d90+epsilon)); break;
- case 2: ok = (lp_lon >= -d40-epsilon && lp_lon <= d180+epsilon) ||
- ((lp_lon >= -d180-epsilon && lp_lon <= -d160+epsilon) &&
- (lp_lat >= d50-epsilon && lp_lat <= d90+epsilon)) ||
- ((lp_lon >= -d50-epsilon && lp_lon <= -d40+epsilon) &&
- (lp_lat >= d60-epsilon && lp_lat <= d90+epsilon)); break;
- case 3: ok = (lp_lon >= -d180-epsilon && lp_lon <= -d40+epsilon); break;
- case 4: ok = (lp_lon >= -d40-epsilon && lp_lon <= d180+epsilon); break;
- case 5: ok = (lp_lon >= -d180-epsilon && lp_lon <= -d100+epsilon); break;
- case 6: ok = (lp_lon >= -d100-epsilon && lp_lon <= -d20+epsilon); break;
- case 7: ok = (lp_lon >= -d20-epsilon && lp_lon <= d80+epsilon); break;
- case 8: ok = (lp_lon >= d80-epsilon && lp_lon <= d180+epsilon); break;
- case 9: ok = (lp_lon >= -d180-epsilon && lp_lon <= -d100+epsilon); break;
- case 10: ok = (lp_lon >= -d100-epsilon && lp_lon <= -d20+epsilon); break;
- case 11: ok = (lp_lon >= -d20-epsilon && lp_lon <= d80+epsilon); break;
- case 12: ok = (lp_lon >= d80-epsilon && lp_lon <= d180+epsilon); break;
- }
- z = (!ok? 0: z);
- }
-
- if (!z) lp_lon = HUGE_VAL;
- if (!z) lp_lat = HUGE_VAL;
- }
- static inline std::string get_name()
- {
- return "igh_spheroid";
- }
- };
-
- template <typename Params, typename Parameters, typename T>
- inline void setup_igh(Params const& , Parameters& par, par_igh<T, Parameters>& proj_parm)
- {
- static const T d0 = 0;
- static const T d4044118 = igh::d4044118<T>();
- static const T d20 = igh::d20<T>();
- static const T d30 = igh::d30<T>();
- static const T d60 = igh::d60<T>();
- static const T d100 = igh::d100<T>();
- static const T d140 = igh::d140<T>();
- static const T d160 = igh::d160<T>();
-
- T lp_lam = 0, lp_phi = d4044118;
- T xy1_x, xy1_y;
- T xy3_x, xy3_y;
-
- proj_parm.set_zone(3, -d100, d0, -d100);
- proj_parm.set_zone(4, d30, d0, d30);
- proj_parm.set_zone(5, -d160, d0, -d160);
- proj_parm.set_zone(6, -d60, d0, -d60);
- proj_parm.set_zone(7, d20, d0, d20);
- proj_parm.set_zone(8, d140, d0, d140);
-
- proj_parm.set_zone(1, -d100, d0, -d100);
-
-
-
-
- proj_parm.fwd(1, par, lp_lam, lp_phi, xy1_x, xy1_y);
- proj_parm.fwd(3, par, lp_lam, lp_phi, xy3_x, xy3_y);
-
- proj_parm.dy0 = xy3_y - xy1_y;
- proj_parm.zones[0].y0 = proj_parm.dy0;
-
- proj_parm.set_zone(2, d30, proj_parm.dy0, d30);
- proj_parm.set_zone(9, -d160, -proj_parm.dy0, -d160);
- proj_parm.set_zone(10, -d60, -proj_parm.dy0, -d60);
- proj_parm.set_zone(11, d20, -proj_parm.dy0, d20);
- proj_parm.set_zone(12, d140, -proj_parm.dy0, d140);
-
-
- }
- }}
- #endif
-
- template <typename T, typename Parameters>
- struct igh_spheroid : public detail::igh::base_igh_spheroid<T, Parameters>
- {
- template <typename Params>
- inline igh_spheroid(Params const& params, Parameters & par)
- : detail::igh::base_igh_spheroid<T, Parameters>(params, par)
- {
- detail::igh::setup_igh(params, par, this->m_proj_parm);
- }
- };
- #ifndef DOXYGEN_NO_DETAIL
- namespace detail
- {
-
- BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION_FI(srs::spar::proj_igh, igh_spheroid)
-
- BOOST_GEOMETRY_PROJECTIONS_DETAIL_FACTORY_ENTRY_FI(igh_entry, igh_spheroid)
- BOOST_GEOMETRY_PROJECTIONS_DETAIL_FACTORY_INIT_BEGIN(igh_init)
- {
- BOOST_GEOMETRY_PROJECTIONS_DETAIL_FACTORY_INIT_ENTRY(igh, igh_entry)
- }
- }
- #endif
- }
- }}
- #endif
|