GeoTessCPP  2.0.0
Software to facilitate storage and retrieval of 3D information about the Earth.
 All Classes Namespaces Files Functions Variables Typedefs Friends Macros
GeoTessUtils.h
Go to the documentation of this file.
1 //- ****************************************************************************
2 //-
3 //- Copyright 2009 Sandia Corporation. Under the terms of Contract
4 //- DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government
5 //- retains certain rights in this software.
6 //-
7 //- BSD Open Source License.
8 //- All rights reserved.
9 //-
10 //- Redistribution and use in source and binary forms, with or without
11 //- modification, are permitted provided that the following conditions are met:
12 //-
13 //- * Redistributions of source code must retain the above copyright notice,
14 //- this list of conditions and the following disclaimer.
15 //- * Redistributions in binary form must reproduce the above copyright
16 //- notice, this list of conditions and the following disclaimer in the
17 //- documentation and/or other materials provided with the distribution.
18 //- * Neither the name of Sandia National Laboratories nor the names of its
19 //- contributors may be used to endorse or promote products derived from
20 //- this software without specific prior written permission.
21 //-
22 //- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
23 //- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24 //- IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25 //- ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
26 //- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
27 //- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
28 //- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
29 //- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
30 //- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
31 //- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32 //- POSSIBILITY OF SUCH DAMAGE.
33 //-
34 //- ****************************************************************************
35 
36 #ifndef GEOTESSUTILS_OBJECT_H
37 #define GEOTESSUTILS_OBJECT_H
38 
39 // **** _SYSTEM INCLUDES_ ******************************************************
40 
41 #include <iostream>
42 #include <fstream>
43 #include <vector>
44 #include <map>
45 #include <string>
46 
47 // use standard library objects
48 using namespace std;
49 
50 // **** _LOCAL INCLUDES_ *******************************************************
51 
52 #include "CPPUtils.h"
53 
54 // **** _BEGIN GEOTESS NAMESPACE_ **********************************************
55 
56 namespace geotess
57 {
58 
59 // **** _FORWARD REFERENCES_ ***************************************************
60 
61 // **** _CLASS DEFINITION_ *****************************************************
62 
70 {
71 private:
72 
73  /*
74  * Private copy constructor. Not used.
75  */
76  GeoTessUtils(const GeoTessUtils& gtu)
77  {
78  }
79  ;
80 
81  /*
82  * Private assignment operator. Not used.
83  */
84  GeoTessUtils& operator=(const GeoTessUtils& gtu)
85  {
86  return *this;
87  }
88  ;
89 
90 public:
91 
102  static bool approximateLatitudes;
103 
108  {
109  }
110 
114  virtual ~GeoTessUtils()
115  {
116  }
117 
122  static string class_name()
123  { return "GeoTessUtils"; }
124 
129  virtual int class_size() const
130  { return (int) sizeof(GeoTessUtils); }
131 
136  static string getVersion() { return "2.0.6"; }
137 
145  static double dot(const double* const v0, const double* const v1)
146  { return v0[0] * v1[0] + v0[1] * v1[1] + v0[2] * v1[2]; }
147 
157  static double scalarTripleProduct(const double* const v0,
158  const double* const v1, const double* const v2)
159  {
160  return v0[0] * v1[1] * v2[2] + v1[0] * v2[1] * v0[2]
161  + v2[0] * v0[1] * v1[2] - v2[0] * v1[1] * v0[2]
162  - v0[0] * v2[1] * v1[2] - v1[0] * v0[1] * v2[2];
163  }
164 
172  static double getGeoCentricLatitude(const double& lat);
173 
181  static double getGeoGraphicLatitude(const double& lat);
182 
187  static string getLatLonString(const double* const v);
188 
189 
204  static double azimuthDegrees(const double* const v1, const double* const v2,
205  double errorValue);
206 
221  static double azimuth(const double* const v1, const double* const v2,
222  double errorValue);
223 
238 static void rotate(const double* const x, const double* const p, double a,
239  double* const z);
240 
263  static double** getGreatCircle(const double* const v0,
264  const double* const v1);
265 
288  static void getGreatCircle(const double* const v0, const double* const v1,
289  double** const gc);
290 
315  static double** getGreatCircle(const double* const v, double azimuth);
316 
341  static void getGreatCircle(const double* const v, double azimuth,
342  double** const gc);
343 
356  static int getGreatCirclePoints(double* ptA, double* ptB,
357  const double& delta, const bool& onCenters);
358 
372  static double getGreatCirclePoints(double* ptA, double* ptB,
373  const int& npoints, const bool& onCenters, double** points);
374 
391  static double getGreatCirclePoints(double* ptA, double* ptB,
392  const double& delta, const bool& onCenters, double** points,
393  int& npoints);
394 
401  static double length(const double* const u)
402  {
403  double l = u[0] * u[0] + u[1] * u[1] + u[2] * u[2];
404  return l > 0 ? sqrt(l) : 0.;
405  }
406 
419  static void getTransform(const double* const u, const double* const v,
420  double** const t);
421 
437  static void transform(const double* x,
438  double const* const * const t, double* const g)
439  {
440  g[0] = x[0] * t[0][0] + x[1] * t[0][1] + x[2] * t[0][2];
441  g[1] = x[0] * t[1][0] + x[1] * t[1][1] + x[2] * t[1][2];
442  g[2] = x[0] * t[2][0] + x[1] * t[2][1] + x[2] * t[2][2];
443  }
444 
450  static void readString(string& s, ifstream& ifs)
451  {
452  int sze;
453  ifs >> sze;
454  char* c = new char[sze];
455  ifs.read(c, sze);
456  s = c;
457  delete[] c;
458  }
459 
465  static void writeString(ofstream& ofs, const string& s)
466  {
467  ofs << s.length();
468  ofs.write(s.c_str(), s.length());
469  }
470 
478  static double angle(const double* const v0,
479  const double* const v1)
480  {
481  double dot = v0[0] * v1[0] + v0[1] * v1[1] + v0[2] * v1[2];
482  if (dot >= 1.0)
483  return 0.0;
484  if (dot <= -1.0)
485  return PI;
486  return acos(dot);
487  }
488 
496  static double angleDegrees(const double* const v0,
497  const double* const v1)
498  {
499  double dot = v0[0] * v1[0] + v0[1] * v1[1] + v0[2] * v1[2];
500  if (dot >= 1.)
501  return 0.;
502  if (dot <= -1.)
503  return 180.;
504  return CPPUtils::toDegrees(acos(dot));
505  }
506 
518  static double getDistance3D(const double* const v0, double r0,
519  const double* const v1, double r1)
520  {
521  double v[3] = { v0[0] * r0 - v1[0] * r1, v0[1] * r0 - v1[1] * r1, v0[2] * r0
522  - v1[2] * r1 };
523  return length(v);
524  }
525 
533  static double getEarthRadius(const double* const v)
534  {
535  return EARTH_A / sqrt(1. + EARTH_E / (1 - EARTH_E) * v[2] * v[2]);
536  }
537 
544  static double getLat(const double* const v)
545  {
546  return getGeoGraphicLatitude(asin(v[2]));
547  }
548 
555  static double getLon(const double* const v)
556  {
557  return atan2(v[1], v[0]);
558  }
559 
566  static double getLatDegrees(const double* const v)
567  {
568  // the constant 0.9933 is (1-e*e) where e is the eccentricity of the
569  // earth
570  // as defined by the GRS80 ellipsoid.
571  return CPPUtils::toDegrees(atan(tan(asin(v[2])) / 0.9933056199770992));
572  }
573 
580  static double getLonDegrees(const double* const v)
581  {
582  return CPPUtils::toDegrees(atan2(v[1], v[0]));
583  }
584 
596  static double* getVectorDegrees(const double& lat,
597  const double& lon)
598  {
599  return getVector(CPPUtils::toRadians(lat), CPPUtils::toRadians(lon));
600  }
601 
612  static double* getVectorDegrees(const double& lat,
613  const double& lon, double* v)
614  {
615  return getVector(CPPUtils::toRadians(lat), CPPUtils::toRadians(lon), v);
616  }
617 
629  static double* getVector(const double& lat, const double& lon)
630  {
631  double* v = new double[3];
632  getVector(lat, lon, v);
633  return v;
634  }
635 
646  static double* getVector(const double& lat, const double& lon, double* v)
647  {
648  // convert lat from geographic to geocentric latitude.
649  double temp = getGeoCentricLatitude(lat);
650 
651  // z component of v is sin of geocentric latitude.
652  v[2] = sin(temp);
653 
654  // set lat = to cos of geocentric latitude
655  temp = cos(temp);
656 
657  // compute x and y components of v
658  v[0] = temp * cos(lon);
659  v[1] = temp * sin(lon);
660 
661  return v;
662  }
663 
671  static double normalize(double* const u)
672  {
673  double len = u[0] * u[0] + u[1] * u[1] + u[2] * u[2];
674  if (len > 0.)
675  {
676  len = sqrt(len);
677  u[0] /= len;
678  u[1] /= len;
679  u[2] /= len;
680  }
681  else
682  {
683  len = u[0] = u[1] = u[2] = 0.0;
684  }
685  return len;
686  }
687 
698  static void cross(const double* const v1, const double* const v2,
699  double* const rslt)
700  {
701  rslt[0] = v1[1] * v2[2] - v1[2] * v2[1];
702  rslt[1] = v1[2] * v2[0] - v1[0] * v2[2];
703  rslt[2] = v1[0] * v2[1] - v1[1] * v2[0];
704  }
705 
716  static double* crossNormal(const double* const u,
717  const double* const v)
718  {
719  double* w = new double[3];
720  w[0] = u[1] * v[2] - u[2] * v[1];
721  w[1] = u[2] * v[0] - u[0] * v[2];
722  w[2] = u[0] * v[1] - u[1] * v[0];
723  normalize(w);
724  return w;
725  }
726 
739  static double crossNormal(const double* const u,
740  const double* const v, double* const w)
741  {
742  w[0] = u[1] * v[2] - u[2] * v[1];
743  w[1] = u[2] * v[0] - u[0] * v[2];
744  w[2] = u[0] * v[1] - u[1] * v[0];
745  return normalize(w);
746  }
747 
760  static double crossNorth(const double* const u, double* const w)
761  {
762  double len = u[0] * u[0] + u[1] * u[1];
763  if (len <= 0.)
764  {
765  len = w[0] = w[1] = w[2] = 0.;
766  }
767  else
768  {
769  len = sqrt(len);
770  w[0] = u[1] / len;
771  w[1] = -u[0] / len;
772  w[2] = 0.;
773  }
774  return len;
775  }
776 
792  static bool vectorTripleProduct(const double* const v0,
793  const double* const v1, const double* const v2, double* const rslt)
794  {
795  // set q = v0 cross v1
796  double q0 = v0[1] * v1[2] - v0[2] * v1[1];
797  double q1 = v0[2] * v1[0] - v0[0] * v1[2];
798  double q2 = v0[0] * v1[1] - v0[1] * v1[0];
799 
800  // set w = q cross v2
801  double w0 = q1 * v2[2] - q2 * v2[1];
802  double w1 = q2 * v2[0] - q0 * v2[2];
803  double w2 = q0 * v2[1] - q1 * v2[0];
804 
805  // set rslt = w
806  rslt[0] = w0;
807  rslt[1] = w1;
808  rslt[2] = w2;
809 
810  // normalize rslt to unit length. if the length
811  // of v1 or v2 is zero or they are nearly parallel then
812  // rslt will = {0,0,0} and the function will return false;
813  return normalize(rslt) != 0.;
814  }
815 
826  static bool vectorTripleProductNorthPole(const double* const u,
827  double* const w)
828  {
829  w[0] = -u[0] * u[2];
830  w[1] = -u[1] * u[2];
831  w[2] = u[1] * u[1] + u[0] * u[0];
832  return normalize(w) != 0.;
833  }
834 
847  static bool circumCenter(const double* const v0,
848  const double* const v1, const double* const v2, double* const vs)
849  {
850  vs[0] = v0[1] * (v2[2] - v1[2]) + v2[1] * (v1[2] - v0[2])
851  + v1[1] * (v0[2] - v2[2]);
852  vs[1] = v0[2] * (v2[0] - v1[0]) + v2[2] * (v1[0] - v0[0])
853  + v1[2] * (v0[0] - v2[0]);
854  vs[2] = v0[0] * (v2[1] - v1[1]) + v2[0] * (v1[1] - v0[1])
855  + v1[0] * (v0[1] - v2[1]);
856  return normalize(vs) > 0.;
857  }
858 
870  static double* circumCenter(const double* const v0,
871  const double* const v1, const double* const v2)
872  {
873  double* vs = new double[3];
874  vs[0] = v0[1] * (v2[2] - v1[2]) + v2[1] * (v1[2] - v0[2])
875  + v1[1] * (v0[2] - v2[2]);
876  vs[1] = v0[2] * (v2[0] - v1[0]) + v2[2] * (v1[0] - v0[0])
877  + v1[2] * (v0[0] - v2[0]);
878  vs[2] = v0[0] * (v2[1] - v1[1]) + v2[0] * (v1[1] - v0[1])
879  + v1[0] * (v0[1] - v2[1]);
880  normalize(vs);
881  return vs;
882  }
883 
896  static bool circumCenter(double const* const * const t,
897  double* const vs)
898  {
899  return circumCenter(t[0], t[1], t[2], vs);
900  }
901 
917  static bool moveDistAz(const double* const w, double distance,
918  double azimuth, double* const u)
919  {
920  double n[3] = { 0.0, 0.0, 0.0 };
921  if (moveNorth(w, distance, n))
922  {
923  rotate(n, w, azimuth, u);
924  return true;
925  }
926  u[0] = w[0];
927  u[1] = w[1];
928  u[2] = w[2];
929  return false;
930  }
931 
945  static void move(const double* const w, const double* const vtp,
946  double a, double* const u)
947  {
948  double cosa = cos(a);
949  double sina = sin(a);
950  u[0] = cosa * w[0] + sina * vtp[0];
951  u[1] = cosa * w[1] + sina * vtp[1];
952  u[2] = cosa * w[2] + sina * vtp[2];
953  }
954 
969  static bool moveNorth(const double* const x, double distance,
970  double* const z)
971  {
972  double vtp[3] = { 0.0, 0.0, 0.0 };
973  if (vectorTripleProductNorthPole(x, vtp))
974  {
975  move(x, vtp, distance, z);
976  return true;
977  }
978 
979  z[0] = x[0];
980  z[1] = x[1];
981  z[2] = x[2];
982  return false;
983  }
984 
992  static bool isPole(const double* const u)
993  {
994  return (u[0] * u[0] + u[1] * u[1]) < 1.0e-15;
995  }
996 
1006  static bool parallel(const double* const u, const double* const v)
1007  {
1008  return 1.0 - abs(u[0] * v[0] + u[1] * v[1] + u[2] * v[2]) < 2.0e-15;
1009  }
1010 
1027  static double* getGreatCirclePoint(
1028  double const* const * const greatCircle, double distance)
1029  {
1030  double* v = new double[3];
1031  getGreatCirclePoint(greatCircle, distance, v);
1032  return v;
1033  }
1034 
1052  static void getGreatCirclePoint(
1053  double const* const * const greatCircle, double distance,
1054  double* const v)
1055  {
1056  double cosa = cos(distance);
1057  double sina = sin(distance);
1058  v[0] = cosa * greatCircle[0][0] + sina * greatCircle[1][0];
1059  v[1] = cosa * greatCircle[0][1] + sina * greatCircle[1][1];
1060  v[2] = cosa * greatCircle[0][2] + sina * greatCircle[1][2];
1061  }
1062 
1069  static double getTriangleArea(const double* const v0,
1070  const double* const v1, const double* const v2)
1071  {
1072  double v10[3] = { v1[0] - v0[0], v1[1] - v0[1], v1[2] - v0[2] };
1073  double v20[3] = { v2[0] - v0[0], v2[1] - v0[1], v2[2] - v0[2] };
1074  double u[3] = { v10[1] * v20[2] - v10[2] * v20[1], v10[2] * v20[0]
1075  - v10[0] * v20[2], v10[0] * v20[1] - v10[1] * v20[0] };
1076  return sqrt(u[0] * u[0] + u[1] * u[1] + u[2] * u[2]) / 2.;
1077  }
1078 
1086  static double* center(double const * const * const v, int n)
1087  {
1088  double* x = new double[3];
1089  x[0] = x[1] = x[2] = 0.0;
1090  if (n == 0)
1091  return x;
1092 
1093  for (int i = 0; i < n; ++i)
1094  {
1095  x[0] += v[i][0];
1096  x[1] += v[i][1];
1097  x[2] += v[i][2];
1098  }
1099  normalize(x);
1100  return x;
1101  }
1102 
1110  static void center(vector<double*> v, double* x)
1111  {
1112  x[0] = x[1] = x[2] = 0.0;
1113 
1114  for (size_t i = 0; i < v.size(); ++i)
1115  {
1116  x[0] += v[i][0];
1117  x[1] += v[i][1];
1118  x[2] += v[i][2];
1119  }
1120  normalize(x);
1121  }
1122 };
1123 // end class GeoTessUtils
1124 
1125 // **** _INLINE FUNCTION IMPLEMENTATIONS_ **************************************
1126 
1127 
1132 static const double geocentric[] = { 0.0, 0.003047423602671013,
1133  0.006094847970838097, 0.009142273869969656, 0.012189702065478763,
1134  0.015237133322695492, 0.018284568406839258, 0.021332008082991166,
1135  0.024379453116066336, 0.027426904270786288, 0.030474362311651265,
1136  0.03352182800291262, 0.03656930210854519, 0.03961678539221966,
1137  0.04266427861727495, 0.04571178254669065, 0.04875929794305942,
1138  0.05180682556855937, 0.05485436618492655, 0.057901920553427404,
1139  0.06094948943483121, 0.06399707358938257, 0.06704467377677387,
1140  0.0700922907561179, 0.07313992528592034, 0.07618757812405218,
1141  0.07923525002772251, 0.08228294175345101, 0.08533065405704056,
1142  0.08837838769354987, 0.0914261434172662, 0.094473921981678,
1143  0.09752172413944764, 0.10056955064238413, 0.1036174022414159,
1144  0.10666527968656359, 0.1097131837269129, 0.11276111511058741,
1145  0.11580907458472142, 0.11885706289543299, 0.12190508078779674,
1146  0.1249531290058169, 0.1280012082924004, 0.13104931938932968,
1147  0.13409746303723613, 0.13714563997557289, 0.140193850942588,
1148  0.14324209667529803, 0.14629037790946073, 0.14933869537954875,
1149  0.15238704981872267, 0.15543544195880452, 0.1584838725302512,
1150  0.1615323422621277, 0.16458085188208085, 0.16762940211631275,
1151  0.17067799368955427, 0.17372662732503877, 0.17677530374447592,
1152  0.17982402366802488, 0.1828727878142688, 0.18592159690018817,
1153  0.18897045164113468, 0.19201935275080542, 0.19506830094121663,
1154  0.19811729692267788, 0.201166341403766, 0.20421543509129933,
1155  0.20726457869031198, 0.21031377290402786, 0.21336301843383518,
1156  0.21641231597926083, 0.21946166623794464, 0.22251106990561403,
1157  0.22556052767605864, 0.2286100402411045, 0.2316596082905894,
1158  0.23470923251233702, 0.23775891359213203, 0.24080865221369493,
1159  0.2438584490586569, 0.24690830480653495, 0.2499582201347069,
1160  0.25300819571838656, 0.25605823223059876, 0.25910833034215514,
1161  0.2621584907216286, 0.26520871403532986, 0.2682590009472821,
1162  0.27130935211919693, 0.2743597682104497, 0.27741024987805574,
1163  0.2804607977766458, 0.28351141255844176, 0.28656209487323325,
1164  0.2896128453683528, 0.29266366468865285, 0.29571455347648123,
1165  0.29876551237165794, 0.3018165420114511, 0.3048676430305536,
1166  0.30791881606105975, 0.3109700617324416, 0.314021380671526,
1167  0.317072773502471, 0.32012424084674285, 0.3231757833230931,
1168  0.3262274015475356, 0.3292790961333235, 0.3323308676909266,
1169  0.3353827168280087, 0.3384346441494046, 0.34148665025709846,
1170  0.34453873575020055, 0.34759090122492536, 0.3506431472745693,
1171  0.35369547448948857, 0.35674788345707703, 0.3598003747617447,
1172  0.3628529489848955, 0.36590560670490546, 0.36895834849710163,
1173  0.3720111749337399, 0.3750640865839841, 0.3781170840138844,
1174  0.3811701677863562, 0.384223338461159, 0.3872765965948754,
1175  0.39032994274089, 0.393383377449369, 0.39643690126723913,
1176  0.3994905147381674, 0.4025442184025402, 0.40559801279744334,
1177  0.40865189845664174, 0.41170587591055896, 0.4147599456862576,
1178  0.41781410830741905, 0.42086836429432384, 0.423922714163832,
1179  0.4269771584293634, 0.43003169760087806, 0.43308633218485754,
1180  0.4361410626842845, 0.43919588959862493, 0.4422508134238082,
1181  0.44530583465220863, 0.44836095377262664, 0.4514161712702699,
1182  0.4544714876267352, 0.45752690331998996, 0.4605824188243536,
1183  0.46363803461047975, 0.4666937511453385, 0.4697495688921976,
1184  0.4728054883106056, 0.47586150985637393, 0.4789176339815591,
1185  0.4819738611344456, 0.48503019175952866, 0.4880866262974967,
1186  0.49114316518521534, 0.49419980885570924, 0.49725655773814614,
1187  0.5003134122578201, 0.5033703728361352, 0.5064274398905888,
1188  0.5094846138347555, 0.5125418950782715, 0.5155992840268179,
1189  0.5186567810821053, 0.5217143866418585, 0.5247721010998003,
1190  0.5278299248456365, 0.5308878582650406, 0.5339459017396384,
1191  0.5370040556469939, 0.5400623203605933, 0.5431206962498311,
1192  0.5461791836799952, 0.5492377830122528, 0.5522964946036362,
1193  0.5553553188070278, 0.5584142559711474, 0.5614733064405376,
1194  0.5645324705555501, 0.5675917486523328, 0.5706511410628154,
1195  0.5737106481146972, 0.5767702701314332, 0.5798300074322218,
1196  0.5828898603319916, 0.5859498291413889, 0.5890099141667653,
1197  0.5920701157101648, 0.5951304340693124, 0.598190869537602,
1198  0.6012514224040836, 0.6043120929534528, 0.6073728814660381,
1199  0.6104337882177904, 0.6134948134802714, 0.6165559575206421,
1200  0.6196172206016525, 0.6226786029816302, 0.6257401049144706,
1201  0.6288017266496251, 0.6318634684320923, 0.6349253305024066,
1202  0.6379873130966289, 0.6410494164463364, 0.6441116407786132,
1203  0.6471739863160405, 0.6502364532766877, 0.6532990418741025,
1204  0.6563617523173022, 0.6594245848107654, 0.6624875395544221,
1205  0.6655506167436465, 0.6686138165692472, 0.6716771392174603,
1206  0.6747405848699405, 0.6778041537037534, 0.6808678458913681,
1207  0.6839316616006491, 0.6869956009948498, 0.6900596642326039,
1208  0.6931238514679199, 0.6961881628501729, 0.6992525985240989,
1209  0.7023171586297877, 0.7053818433026762, 0.7084466526735433,
1210  0.7115115868685029, 0.7145766460089984, 0.7176418302117967,
1211  0.7207071395889835, 0.7237725742479568, 0.7268381342914229,
1212  0.72990381981739, 0.7329696309191651, 0.7360355676853481,
1213  0.7391016301998271, 0.7421678185417753, 0.7452341327856461,
1214  0.7483005730011691, 0.7513671392533465, 0.7544338316024497,
1215  0.7575006501040149, 0.7605675948088417, 0.7636346657629879,
1216  0.7667018630077682, 0.7697691865797504, 0.7728366365107536,
1217  0.7759042128278457, 0.7789719155533406, 0.7820397447047971,
1218  0.7851077002950162, 0.7881757823320402, 0.7912439908191506,
1219  0.794312325754867, 0.7973807871329465, 0.8004493749423818,
1220  0.8035180891674011, 0.8065869297874673, 0.8096558967772779,
1221  0.8127249901067641, 0.8157942097410916, 0.8188635556406603,
1222  0.821933027761104, 0.8250026260532924, 0.8280723504633305,
1223  0.83114220093256, 0.8342121773975598, 0.8372822797901482,
1224  0.8403525080373838, 0.8434228620615665, 0.8464933417802403,
1225  0.8495639471061945, 0.8526346779474664, 0.8557055342073429,
1226  0.8587765157843639, 0.8618476225723242, 0.8649188544602767,
1227  0.8679902113325356, 0.8710616930686791, 0.8741332995435535,
1228  0.8772050306272762, 0.8802768861852399, 0.8833488660781164,
1229  0.8864209701618606, 0.889493198287715, 0.8925655503022143,
1230  0.8956380260471897, 0.8987106253597743, 0.9017833480724076,
1231  0.9048561940128412, 0.9079291630041441, 0.9110022548647081,
1232  0.9140754694082539, 0.9171488064438367, 0.9202222657758528,
1233  0.9232958472040453, 0.9263695505235116, 0.929443375524709,
1234  0.9325173219934624, 0.9355913897109707, 0.9386655784538146,
1235  0.941739887993964, 0.9448143180987851, 0.9478888685310487,
1236  0.9509635390489382, 0.9540383294060569, 0.9571132393514377,
1237  0.9601882686295503, 0.9632634169803111, 0.9663386841390907,
1238  0.9694140698367245, 0.9724895737995205, 0.9755651957492697,
1239  0.9786409354032554, 0.9817167924742626, 0.9847927666705888,
1240  0.9878688576960531, 0.9909450652500075, 0.9940213890273466,
1241  0.9970978287185187, 1.0001743840095367, 1.0032510545819884,
1242  1.0063278401130493, 1.0094047402754918, 1.0124817547376985,
1243  1.0155588831636737, 1.0186361252130536, 1.0217134805411217,
1244  1.0247909487988172, 1.0278685296327505, 1.0309462226852142,
1245  1.0340240275941965, 1.0371019439933935, 1.0401799715122235,
1246  1.0432581097758389, 1.0463363584051413, 1.0494147170167933,
1247  1.0524931852232333, 1.0555717626326906, 1.0586504488491968,
1248  1.0617292434726033, 1.0648081460985928, 1.0678871563186967,
1249  1.0709662737203076, 1.0740454978866965, 1.0771248283970258,
1250  1.0802042648263666, 1.0832838067457127, 1.086363453721997,
1251  1.089443205318108, 1.092523061092904, 1.0956030206012313,
1252  1.098683083393939, 1.1017632490178968, 1.1048435170160098,
1253  1.1079238869272385, 1.1110043582866118, 1.1140849306252474,
1254  1.1171656034703676, 1.120246376345317, 1.123327248769581,
1255  1.1264082202588015, 1.129489290324798, 1.1325704584755818,
1256  1.1356517242153787, 1.1387330870446435, 1.141814546460081,
1257  1.1448961019546642, 1.147977753017652, 1.1510594991346106,
1258  1.1541413397874303, 1.157223274454347, 1.1603053026099588,
1259  1.1633874237252504, 1.1664696372676073, 1.1695519427008403,
1260  1.1726343394852028, 1.1757168270774128, 1.1787994049306725,
1261  1.1818820724946881, 1.1849648292156931, 1.1880476745364656,
1262  1.1911306078963526, 1.194213628731289, 1.1972967364738196,
1263  1.2003799305531206, 1.2034632103950214, 1.206546575422025,
1264  1.209630025053332, 1.2127135587048612, 1.2157971757892707,
1265  1.2188808757159835, 1.2219646578912058, 1.2250485217179534,
1266  1.2281324665960707, 1.231216491922257, 1.2343005970900864,
1267  1.2373847814900338, 1.2404690445094946, 1.2435533855328118,
1268  1.2466378039412964, 1.2497222991132528, 1.2528068704240023,
1269  1.2558915172459055, 1.2589762389483887, 1.2620610348979655,
1270  1.265145904458263, 1.268230846990045, 1.2713158618512368,
1271  1.27440094839695, 1.2774861059795064, 1.2805713339484646,
1272  1.2836566316506417, 1.286741998430143, 1.2898274336283824,
1273  1.292912936584111, 1.295998506633441, 1.299084143109872,
1274  1.3021698453443156, 1.3052556126651222, 1.3083414443981063,
1275  1.3114273398665721, 1.3145132983913408, 1.3175993192907758,
1276  1.3206854018808087, 1.3237715454749663, 1.3268577493843976,
1277  1.3299440129178983, 1.3330303353819408, 1.3361167160806975,
1278  1.33920315431607, 1.342289649387715, 1.3453762005930718,
1279  1.34846280722739, 1.3515494685837555, 1.3546361839531185,
1280  1.3577229526243213, 1.3608097738841256, 1.3638966470172398,
1281  1.366983571306347, 1.370070546032133, 1.3731575704733139,
1282  1.3762446439066645, 1.379331765607045, 1.3824189348474314,
1283  1.3855061508989417, 1.388593413030866, 1.3916807205106922,
1284  1.3947680726041385, 1.3978554685751772, 1.4009429076860678,
1285  1.4040303891973824, 1.4071179123680362, 1.4102054764553156,
1286  1.4132930807149071, 1.4163807244009277, 1.4194684067659513,
1287  1.4225561270610403, 1.425643884535773, 1.4287316784382749,
1288  1.4318195080152447, 1.4349073725119876, 1.4379952711724417,
1289  1.4410832032392094, 1.4441711679535851, 1.4472591645555866,
1290  1.4503471922839841, 1.453435250376329, 1.4565233380689855,
1291  1.4596114545971586, 1.4626995991949252, 1.4657877710952634,
1292  1.468875969530083, 1.4719641937302546, 1.4750524429256404,
1293  1.4781407163451246, 1.481229013216642, 1.4843173327672103,
1294  1.4874056742229587, 1.490494036809159, 1.4935824197502554,
1295  1.4966708222698952, 1.499759243590959, 1.502847682935591,
1296  1.5059361395252298, 1.5090246125806384, 1.512113101321935,
1297  1.5152016049686239, 1.5182901227396248, 1.5213786538533045,
1298  1.524467197527508, 1.527555752979587, 1.5306443194264325,
1299  1.533732896084505, 1.536821482169865, 1.539910076898203,
1300  1.5429986794848713, 1.5460872891449153, 1.5491759050931018,
1301  1.5522645265439523, 1.5553531527117719, 1.558441782810682,
1302  1.561530416054649, 1.5646190516575167, 1.567707688833036,
1303  1.5707963267948966 };
1304 
1309 static const double geographic[] = { 0.0, 0.0030886379618605825,
1310  0.006177275137379901, 0.0092659107402475, 0.012354543984214532,
1311  0.015443174083124565, 0.01853180025094438, 0.021620421701794772,
1312  0.0247090376499813, 0.027797647310025125, 0.030886249896693734,
1313  0.0339748446250317, 0.037063430710391455, 0.040152007368464,
1314  0.043240573815309616, 0.0463291292673886, 0.049417672941591925,
1315  0.05250620405527188, 0.05559472182627276, 0.05868322547296149,
1316  0.0617717142142582, 0.06486018726966679, 0.06794864385930552,
1317  0.0710370832039375, 0.07412550452500125, 0.07721390704464104,
1318  0.08030228998573746, 0.08339065257193778, 0.08647899402768627,
1319  0.0895673135782546, 0.0926556104497721, 0.09574388386925607,
1320  0.09883213306464193, 0.10192035726481347, 0.10500855569963301,
1321  0.10809672759997133, 0.11118487219773797, 0.11427298872591114,
1322  0.11736107641856755, 0.12044913451091256, 0.1235371622393099,
1323  0.12662515884131142, 0.12971312355568715, 0.13280105562245464,
1324  0.13588895428290887, 0.13897681877965185, 0.14206464835662186,
1325  0.1451524422591234, 0.14824019973385638, 0.1513279200289453,
1326  0.15441560239396898, 0.1575032460799894, 0.16059085033958118,
1327  0.16367841442686046, 0.16676593759751412, 0.16985341910882873,
1328  0.17294085821971925, 0.17602825419075818, 0.17911560628420423,
1329  0.18220291376403075, 0.18529017589595478, 0.1883773919474653,
1330  0.19146456118785166, 0.19455168288823224, 0.1976387563215826,
1331  0.20072578076276354, 0.20381275548854957, 0.20689967977765683,
1332  0.209986552910771, 0.21307337417057526, 0.2161601428417781,
1333  0.2192468582111411, 0.22233351956750647, 0.22542012620182456,
1334  0.22850667740718159, 0.23159317247882658, 0.234679610714199,
1335  0.23776599141295568, 0.24085231387699807, 0.24393857741049915,
1336  0.24702478131993025, 0.250110924914088, 0.25319700750412083,
1337  0.25628302840355577, 0.25936898692832455, 0.2624548823967905,
1338  0.26554071412977437, 0.26862648145058093, 0.2717121836850245,
1339  0.2747978201614555, 0.27788339021078556, 0.2809688931665142,
1340  0.2840543283647537, 0.28713969514425475, 0.2902249928464323,
1341  0.2933102208153901, 0.29639537839794666, 0.2994804649436597,
1342  0.3025654798048515, 0.3056504223366336, 0.3087352918969311,
1343  0.31182008784650794, 0.31490480954899097, 0.3179894563708943,
1344  0.3210740276816437, 0.3241585228536002, 0.3272429412620848,
1345  0.33032728228540187, 0.33341154530486283, 0.33649572970480984,
1346  0.33957983487263954, 0.3426638601988257, 0.34574780507694325,
1347  0.34883166890369055, 0.3519154510789131, 0.3549991510056258,
1348  0.35808276809003553, 0.3611663017415644, 0.36424975137287147,
1349  0.36733311639987526, 0.37041639624177586, 0.37349959032107694,
1350  0.37658269806360756, 0.3796657188985439, 0.3827486522584309,
1351  0.38583149757920354, 0.3889142543002084, 0.39199692186422425,
1352  0.3950794997174837, 0.39816198730969365, 0.4012443840940563,
1353  0.4043266895272892, 0.4074089030696463, 0.41049102418493755,
1354  0.41357305234054986, 0.4166549870074662, 0.419736827660286,
1355  0.4228185737772445, 0.42590022484023243, 0.4289817803348154,
1356  0.43206323975025296, 0.4351446025795178, 0.4382258683193147,
1357  0.4413070364700987, 0.44438810653609495, 0.4474690780253156,
1358  0.45054995044957946, 0.45363072332452903, 0.45671139616964923,
1359  0.4597919685082848, 0.4628724398676581, 0.4659528097788865,
1360  0.4690330777769999, 0.47211324340095756, 0.4751933061936653,
1361  0.4782732657019926, 0.4813531214767887, 0.48443287307289956,
1362  0.48751252004918405, 0.49059206196853006, 0.49367149839787067,
1363  0.4967508289082, 0.4998300530745889, 0.5029091704761999,
1364  0.5059881806963037, 0.5090670833222932, 0.5121458779456998,
1365  0.515224564162206, 0.5183031415716631, 0.5213816097781034,
1366  0.5244599683897553, 0.5275382170190575, 0.5306163552826731,
1367  0.533694382801503, 0.5367722992007001, 0.5398501041096824,
1368  0.542927797162146, 0.5460053779960794, 0.549082846253775,
1369  0.5521602015818429, 0.5552374436312231, 0.558314572057198,
1370  0.5613915865194048, 0.5644684866818472, 0.567545272212908,
1371  0.5706219427853598, 0.5736984980763777, 0.57677493776755,
1372  0.5798512615448891, 0.5829274690988434, 0.5860035601243078,
1373  0.589079534320634, 0.5921553913916412, 0.5952311310456269,
1374  0.5983067529953761, 0.6013822569581719, 0.6044576426558057,
1375  0.6075329098145854, 0.6106080581653462, 0.6136830874434589,
1376  0.6167579973888396, 0.6198327877459584, 0.6229074582638479,
1377  0.6259820086961115, 0.6290564388009326, 0.632130748341082,
1378  0.6352049370839259, 0.6382790048014341, 0.6413529512701875,
1379  0.644426776271385, 0.6475004795908512, 0.6505740610190438,
1380  0.6536475203510599, 0.6567208573866427, 0.6597940719301885,
1381  0.6628671637907525, 0.6659401327820553, 0.669012978722489,
1382  0.6720857014351223, 0.6751583007477069, 0.6782307764926824,
1383  0.6813031285071816, 0.684375356633036, 0.6874474607167802,
1384  0.6905194406096566, 0.6935912961676205, 0.6966630272513432,
1385  0.6997346337262175, 0.702806115462361, 0.7058774723346197,
1386  0.7089487042225724, 0.7120198110105327, 0.7150907925875537,
1387  0.7181616488474303, 0.7212323796887021, 0.7243029850146564,
1388  0.7273734647333301, 0.7304438187575129, 0.7335140470047483,
1389  0.7365841493973367, 0.7396541258623366, 0.7427239763315661,
1390  0.7457937007416041, 0.7488632990337925, 0.7519327711542364,
1391  0.7550021170538048, 0.7580713366881324, 0.7611404300176188,
1392  0.7642093970074293, 0.7672782376274956, 0.7703469518525148,
1393  0.7734155396619501, 0.7764840010400295, 0.779552335975746,
1394  0.7826205444628564, 0.7856886264998802, 0.7887565820900994,
1395  0.7918244112415559, 0.7948921139670508, 0.7979596902841429,
1396  0.8010271402151462, 0.8040944637871283, 0.8071616610319086,
1397  0.8102287319860549, 0.8132956766908815, 0.816362495192447,
1398  0.8194291875415499, 0.8224957537937274, 0.8255621940092505,
1399  0.8286285082531213, 0.8316946965950694, 0.8347607591095485,
1400  0.8378266958757314, 0.8408925069775065, 0.8439581925034738,
1401  0.8470237525469397, 0.8500891872059131, 0.8531544965830998,
1402  0.8562196807858983, 0.8592847399263936, 0.8623496741213532,
1403  0.8654144834922204, 0.8684791681651088, 0.8715437282707976,
1404  0.8746081639447237, 0.8776724753269767, 0.8807366625622927,
1405  0.8838007258000469, 0.8868646651942474, 0.8899284809035285,
1406  0.8929921730911432, 0.8960557419249562, 0.8991191875774363,
1407  0.9021825102256493, 0.9052457100512501, 0.9083087872404745,
1408  0.9113717419841312, 0.9144345744775944, 0.9174972849207942,
1409  0.9205598735182088, 0.923622340478856, 0.9266846860162834,
1410  0.9297469103485603, 0.9328090136982676, 0.9358709962924899,
1411  0.9389328583628043, 0.9419946001452715, 0.945056221880426,
1412  0.9481177238132663, 0.9511791061932441, 0.9542403692742544,
1413  0.9573015133146252, 0.9603625385771062, 0.9634234453288585,
1414  0.9664842338414438, 0.969544904390813, 0.9726054572572946,
1415  0.9756658927255841, 0.9787262110847318, 0.9817864126281313,
1416  0.9848464976535075, 0.9879064664629048, 0.9909663193626747,
1417  0.9940260566634633, 0.9970856786801994, 1.000145185732081,
1418  1.0032045781425638, 1.0062638562393464, 1.0093230203543588,
1419  1.0123820708237492, 1.0154410079878686, 1.0184998321912604,
1420  1.0215585437826438, 1.0246171431149014, 1.0276756305450656,
1421  1.0307340064343031, 1.0337922711479026, 1.036850425055258,
1422  1.039908468529856, 1.04296640194926, 1.0460242256950962,
1423  1.049081940153038, 1.0521395457127913, 1.0551970427680788,
1424  1.0582544317166251, 1.061311712960141, 1.0643688869043078,
1425  1.0674259539587614, 1.0704829145370764, 1.0735397690567505,
1426  1.0765965179391872, 1.0796531616096812, 1.0827097004973996,
1427  1.085766135035368, 1.088822465660451, 1.0918786928133375,
1428  1.0949348169385227, 1.097990838484291, 1.101046757902699,
1429  1.104102575649558, 1.1071582921844167, 1.1102139079705429,
1430  1.1132694234749065, 1.1163248391681613, 1.1193801555246266,
1431  1.12243537302227, 1.1254904921426878, 1.1285455133710884,
1432  1.1316004371962716, 1.1346552641106122, 1.137709994610039,
1433  1.1407646291940186, 1.143819168365533, 1.1468736126310646,
1434  1.149927962500573, 1.1529822184874776, 1.1560363811086392,
1435  1.1590904508843376, 1.162144428338255, 1.165198313997453,
1436  1.1682521083923565, 1.171305812056729, 1.1743594255276575,
1437  1.1774129493455274, 1.1804663840540066, 1.1835197302000213,
1438  1.1865729883337375, 1.1896261590085404, 1.1926792427810122,
1439  1.1957322402109125, 1.1987851518611565, 1.201837978297795,
1440  1.204890720089991, 1.207943377810001, 1.2109959520331517,
1441  1.2140484433378194, 1.217100852305408, 1.2201531795203273,
1442  1.2232054255699714, 1.226257591044696, 1.2293096765377982,
1443  1.232361682645492, 1.235413609966888, 1.2384654591039699,
1444  1.241517230661573, 1.2445689252473608, 1.2476205434718035,
1445  1.2506720859481537, 1.2537235532924256, 1.2567749461233706,
1446  1.259826265062455, 1.2628775107338368, 1.2659286837643429,
1447  1.2689797847834456, 1.2720308144232386, 1.2750817733184152,
1448  1.2781326621062439, 1.2811834814265437, 1.2842342319216635,
1449  1.2872849142364546, 1.2903355290182508, 1.2933860769168408,
1450  1.2964365585844468, 1.2994869746756996, 1.3025373258476145,
1451  1.3055876127595665, 1.308637836073268, 1.3116879964527417,
1452  1.3147380945642977, 1.31778813107651, 1.3208381066601895,
1453  1.3238880219883615, 1.3269378777362395, 1.3299876745812016,
1454  1.3330374132027645, 1.3360870942825596, 1.339136718504307,
1455  1.3421862865537921, 1.3452357991188382, 1.3482852568892825,
1456  1.351334660556952, 1.3543840108156358, 1.3574333083610615,
1457  1.3604825538908687, 1.3635317481045846, 1.366580891703597,
1458  1.3696299853911307, 1.3726790298722187, 1.37572802585368,
1459  1.3787769740440912, 1.381825875153762, 1.3848747298947086,
1460  1.3879235389806277, 1.3909723031268717, 1.3940210230504206,
1461  1.3970696994698577, 1.4001183331053422, 1.4031669246785838,
1462  1.4062154749128157, 1.4092639845327688, 1.4123124542646455,
1463  1.415360884836092, 1.418409276976174, 1.4214576314153478,
1464  1.424505948885436, 1.4275542301195985, 1.4306024758523086,
1465  1.4336506868193237, 1.4366988637576603, 1.4397470074055667,
1466  1.442795118502496, 1.4458431977890798, 1.4488912460070997,
1467  1.4519392638994637, 1.454987252210175, 1.4580352116843092,
1468  1.4610831430679836, 1.464131047108333, 1.4671789245534805,
1469  1.4702267761525125, 1.4732746026554489, 1.4763224048132186,
1470  1.4793701833776305, 1.4824179391013466, 1.4854656727378561,
1471  1.4885133850414456, 1.491561076767174, 1.4946087486708444,
1472  1.4976564015089762, 1.5007040360387784, 1.5037516530181227,
1473  1.506799253205514, 1.5098468373600653, 1.5128944062414693,
1474  1.51594196060997, 1.5189895012263372, 1.522037028851837,
1475  1.525084544248206, 1.5281320481776215, 1.531179541402677,
1476  1.5342270246863512, 1.537274498791984, 1.5403219644832453,
1477  1.5433694225241104, 1.5464168736788304, 1.5494643187119053,
1478  1.5525117583880574, 1.555559193472201, 1.558606624729418,
1479  1.5616540529249268, 1.5647014788240585, 1.5677489031922254,
1480  1.5707963267948966 };
1481 
1482 inline double GeoTessUtils::getGeoCentricLatitude(const double& lat)
1483 {
1484  // convert lat from geographic to geocentric latitude.
1485 
1486  if (!approximateLatitudes)
1487  return atan((1 - EARTH_E) * tan(lat));
1488 
1489  if (lat >= PI / 2)
1490  return PI / 2;
1491  else if (lat <= -PI / 2)
1492  return -PI / 2;
1493  else if (lat < 0)
1494  {
1495  double tmp = -lat / (PI / 2 / (513 - 1));
1496  int i = (int) tmp;
1497  return -geocentric[i] - (tmp - i) * (geocentric[i + 1] - geocentric[i]);
1498  }
1499  else
1500  {
1501  double tmp = lat / (PI / 2 / (513 - 1));
1502  int i = (int) tmp;
1503  return geocentric[i] + (tmp - i) * (geocentric[i + 1] - geocentric[i]);
1504  }
1505 }
1506 
1507 inline double GeoTessUtils::getGeoGraphicLatitude(const double& lat)
1508 {
1509  // the constant 0.9933 is (1-e*e) where e is the eccentricity of the
1510  // earth as defined by the GRS80 ellipsoid.
1511 
1512  if (!approximateLatitudes)
1513  return atan(tan(lat) / (1 - EARTH_E));
1514 
1515  if (lat >= PI / 2)
1516  return PI / 2;
1517  else if (lat <= -PI / 2)
1518  return -PI / 2;
1519  else if (lat < 0)
1520  {
1521  double tmp = -lat / (PI / 2 / (513 - 1));
1522  int i = (int) tmp;
1523  return -geographic[i] - (tmp - i) * (geographic[i + 1] - geographic[i]);
1524  }
1525  else
1526  {
1527  double tmp = lat / (PI / 2 / (513 - 1));
1528  int i = (int) tmp;
1529  return geographic[i] + (tmp - i) * (geographic[i + 1] - geographic[i]);
1530  }
1531 }
1532 
1533 } // end namespace geotess
1534 
1535 #endif // GEOTESSUTILS_OBJECT_H