GeoTessCPP
2.0.0
Software to facilitate storage and retrieval of 3D information about the Earth.
|
00001 //- **************************************************************************** 00002 //- 00003 //- Copyright 2009 Sandia Corporation. Under the terms of Contract 00004 //- DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government 00005 //- retains certain rights in this software. 00006 //- 00007 //- BSD Open Source License. 00008 //- All rights reserved. 00009 //- 00010 //- Redistribution and use in source and binary forms, with or without 00011 //- modification, are permitted provided that the following conditions are met: 00012 //- 00013 //- * Redistributions of source code must retain the above copyright notice, 00014 //- this list of conditions and the following disclaimer. 00015 //- * Redistributions in binary form must reproduce the above copyright 00016 //- notice, this list of conditions and the following disclaimer in the 00017 //- documentation and/or other materials provided with the distribution. 00018 //- * Neither the name of Sandia National Laboratories nor the names of its 00019 //- contributors may be used to endorse or promote products derived from 00020 //- this software without specific prior written permission. 00021 //- 00022 //- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 00023 //- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00024 //- IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 00025 //- ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 00026 //- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 00027 //- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 00028 //- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 00029 //- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 00030 //- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 00031 //- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 00032 //- POSSIBILITY OF SUCH DAMAGE. 00033 //- 00034 //- **************************************************************************** 00035 00036 #ifndef GEOTESSUTILS_OBJECT_H 00037 #define GEOTESSUTILS_OBJECT_H 00038 00039 // **** _SYSTEM INCLUDES_ ****************************************************** 00040 00041 #include <iostream> 00042 #include <fstream> 00043 #include <vector> 00044 #include <map> 00045 #include <string> 00046 00047 // use standard library objects 00048 using namespace std; 00049 00050 // **** _LOCAL INCLUDES_ ******************************************************* 00051 00052 #include "CPPUtils.h" 00053 00054 // **** _BEGIN GEOTESS NAMESPACE_ ********************************************** 00055 00056 namespace geotess 00057 { 00058 00059 // **** _FORWARD REFERENCES_ *************************************************** 00060 00061 // **** _CLASS DEFINITION_ ***************************************************** 00062 00069 class GEOTESS_EXP_IMP GeoTessUtils 00070 { 00071 private: 00072 00073 /* 00074 * Private copy constructor. Not used. 00075 */ 00076 GeoTessUtils(const GeoTessUtils& gtu) 00077 { 00078 } 00079 ; 00080 00081 /* 00082 * Private assignment operator. Not used. 00083 */ 00084 GeoTessUtils& operator=(const GeoTessUtils& gtu) 00085 { 00086 return *this; 00087 } 00088 ; 00089 00090 public: 00091 00102 static bool approximateLatitudes; 00103 00107 GeoTessUtils() 00108 { 00109 } 00110 00114 virtual ~GeoTessUtils() 00115 { 00116 } 00117 00122 static string class_name() 00123 { return "GeoTessUtils"; } 00124 00129 virtual int class_size() const 00130 { return (int) sizeof(GeoTessUtils); } 00131 00136 static string getVersion() { return "2.0.4"; } 00137 00145 static double dot(const double* const v0, const double* const v1) 00146 { return v0[0] * v1[0] + v0[1] * v1[1] + v0[2] * v1[2]; } 00147 00157 static double scalarTripleProduct(const double* const v0, 00158 const double* const v1, const double* const v2) 00159 { 00160 return v0[0] * v1[1] * v2[2] + v1[0] * v2[1] * v0[2] 00161 + v2[0] * v0[1] * v1[2] - v2[0] * v1[1] * v0[2] 00162 - v0[0] * v2[1] * v1[2] - v1[0] * v0[1] * v2[2]; 00163 } 00164 00172 static double getGeoCentricLatitude(const double& lat); 00173 00181 static double getGeoGraphicLatitude(const double& lat); 00182 00187 static string getLatLonString(const double* const v); 00188 00189 00204 static double azimuthDegrees(const double* const v1, const double* const v2, 00205 double errorValue); 00206 00221 static double azimuth(const double* const v1, const double* const v2, 00222 double errorValue); 00223 00238 static void rotate(const double* const x, const double* const p, double a, 00239 double* const z); 00240 00263 static double** getGreatCircle(const double* const v0, 00264 const double* const v1); 00265 00288 static void getGreatCircle(const double* const v0, const double* const v1, 00289 double** const gc); 00290 00315 static double** getGreatCircle(const double* const v, double azimuth); 00316 00341 static void getGreatCircle(const double* const v, double azimuth, 00342 double** const gc); 00343 00356 static int getGreatCirclePoints(double* ptA, double* ptB, 00357 const double& delta, const bool& onCenters); 00358 00372 static double getGreatCirclePoints(double* ptA, double* ptB, 00373 const int& npoints, const bool& onCenters, double** points); 00374 00391 static double getGreatCirclePoints(double* ptA, double* ptB, 00392 const double& delta, const bool& onCenters, double** points, 00393 int& npoints); 00394 00401 static double length(const double* const u) 00402 { 00403 double l = u[0] * u[0] + u[1] * u[1] + u[2] * u[2]; 00404 return l > 0 ? sqrt(l) : 0.; 00405 } 00406 00419 static void getTransform(const double* const u, const double* const v, 00420 double** const t); 00421 00437 static void transform(const double* x, 00438 double const* const * const t, double* const g) 00439 { 00440 g[0] = x[0] * t[0][0] + x[1] * t[0][1] + x[2] * t[0][2]; 00441 g[1] = x[0] * t[1][0] + x[1] * t[1][1] + x[2] * t[1][2]; 00442 g[2] = x[0] * t[2][0] + x[1] * t[2][1] + x[2] * t[2][2]; 00443 } 00444 00450 static void readString(string& s, ifstream& ifs) 00451 { 00452 int sze; 00453 ifs >> sze; 00454 char* c = new char[sze]; 00455 ifs.read(c, sze); 00456 s = c; 00457 delete[] c; 00458 } 00459 00465 static void writeString(ofstream& ofs, const string& s) 00466 { 00467 ofs << s.length(); 00468 ofs.write(s.c_str(), s.length()); 00469 } 00470 00478 static double angle(const double* const v0, 00479 const double* const v1) 00480 { 00481 double dot = v0[0] * v1[0] + v0[1] * v1[1] + v0[2] * v1[2]; 00482 if (dot >= 1.0) 00483 return 0.0; 00484 if (dot <= -1.0) 00485 return PI; 00486 return acos(dot); 00487 } 00488 00496 static double angleDegrees(const double* const v0, 00497 const double* const v1) 00498 { 00499 double dot = v0[0] * v1[0] + v0[1] * v1[1] + v0[2] * v1[2]; 00500 if (dot >= 1.) 00501 return 0.; 00502 if (dot <= -1.) 00503 return 180.; 00504 return CPPUtils::toDegrees(acos(dot)); 00505 } 00506 00518 static double getDistance3D(const double* const v0, double r0, 00519 const double* const v1, double r1) 00520 { 00521 double v[3] = { v0[0] * r0 - v1[0] * r1, v0[1] * r0 - v1[1] * r1, v0[2] * r0 00522 - v1[2] * r1 }; 00523 return length(v); 00524 } 00525 00533 static double getEarthRadius(const double* const v) 00534 { 00535 return EARTH_A / sqrt(1. + EARTH_E / (1 - EARTH_E) * v[2] * v[2]); 00536 } 00537 00544 static double getLat(const double* const v) 00545 { 00546 return getGeoGraphicLatitude(asin(v[2])); 00547 } 00548 00555 static double getLon(const double* const v) 00556 { 00557 return atan2(v[1], v[0]); 00558 } 00559 00566 static double getLatDegrees(const double* const v) 00567 { 00568 // the constant 0.9933 is (1-e*e) where e is the eccentricity of the 00569 // earth 00570 // as defined by the GRS80 ellipsoid. 00571 return CPPUtils::toDegrees(atan(tan(asin(v[2])) / 0.9933056199770992)); 00572 } 00573 00580 static double getLonDegrees(const double* const v) 00581 { 00582 return CPPUtils::toDegrees(atan2(v[1], v[0])); 00583 } 00584 00596 static double* getVectorDegrees(const double& lat, 00597 const double& lon) 00598 { 00599 return getVector(CPPUtils::toRadians(lat), CPPUtils::toRadians(lon)); 00600 } 00601 00612 static double* getVectorDegrees(const double& lat, 00613 const double& lon, double* v) 00614 { 00615 return getVector(CPPUtils::toRadians(lat), CPPUtils::toRadians(lon), v); 00616 } 00617 00629 static double* getVector(const double& lat, const double& lon) 00630 { 00631 double* v = new double[3]; 00632 getVector(lat, lon, v); 00633 return v; 00634 } 00635 00646 static double* getVector(const double& lat, const double& lon, double* v) 00647 { 00648 // convert lat from geographic to geocentric latitude. 00649 double temp = getGeoCentricLatitude(lat); 00650 00651 // z component of v is sin of geocentric latitude. 00652 v[2] = sin(temp); 00653 00654 // set lat = to cos of geocentric latitude 00655 temp = cos(temp); 00656 00657 // compute x and y components of v 00658 v[0] = temp * cos(lon); 00659 v[1] = temp * sin(lon); 00660 00661 return v; 00662 } 00663 00671 static double normalize(double* const u) 00672 { 00673 double len = u[0] * u[0] + u[1] * u[1] + u[2] * u[2]; 00674 if (len > 0.) 00675 { 00676 len = sqrt(len); 00677 u[0] /= len; 00678 u[1] /= len; 00679 u[2] /= len; 00680 } 00681 else 00682 { 00683 len = u[0] = u[1] = u[2] = 0.0; 00684 } 00685 return len; 00686 } 00687 00698 static void cross(const double* const v1, const double* const v2, 00699 double* const rslt) 00700 { 00701 rslt[0] = v1[1] * v2[2] - v1[2] * v2[1]; 00702 rslt[1] = v1[2] * v2[0] - v1[0] * v2[2]; 00703 rslt[2] = v1[0] * v2[1] - v1[1] * v2[0]; 00704 } 00705 00716 static double* crossNormal(const double* const u, 00717 const double* const v) 00718 { 00719 double* w = new double[3]; 00720 w[0] = u[1] * v[2] - u[2] * v[1]; 00721 w[1] = u[2] * v[0] - u[0] * v[2]; 00722 w[2] = u[0] * v[1] - u[1] * v[0]; 00723 normalize(w); 00724 return w; 00725 } 00726 00739 static double crossNormal(const double* const u, 00740 const double* const v, double* const w) 00741 { 00742 w[0] = u[1] * v[2] - u[2] * v[1]; 00743 w[1] = u[2] * v[0] - u[0] * v[2]; 00744 w[2] = u[0] * v[1] - u[1] * v[0]; 00745 return normalize(w); 00746 } 00747 00760 static double crossNorth(const double* const u, double* const w) 00761 { 00762 double len = u[0] * u[0] + u[1] * u[1]; 00763 if (len <= 0.) 00764 { 00765 len = w[0] = w[1] = w[2] = 0.; 00766 } 00767 else 00768 { 00769 len = sqrt(len); 00770 w[0] = u[1] / len; 00771 w[1] = -u[0] / len; 00772 w[2] = 0.; 00773 } 00774 return len; 00775 } 00776 00792 static bool vectorTripleProduct(const double* const v0, 00793 const double* const v1, const double* const v2, double* const rslt) 00794 { 00795 // set q = v0 cross v1 00796 double q0 = v0[1] * v1[2] - v0[2] * v1[1]; 00797 double q1 = v0[2] * v1[0] - v0[0] * v1[2]; 00798 double q2 = v0[0] * v1[1] - v0[1] * v1[0]; 00799 00800 // set w = q cross v2 00801 double w0 = q1 * v2[2] - q2 * v2[1]; 00802 double w1 = q2 * v2[0] - q0 * v2[2]; 00803 double w2 = q0 * v2[1] - q1 * v2[0]; 00804 00805 // set rslt = w 00806 rslt[0] = w0; 00807 rslt[1] = w1; 00808 rslt[2] = w2; 00809 00810 // normalize rslt to unit length. if the length 00811 // of v1 or v2 is zero or they are nearly parallel then 00812 // rslt will = {0,0,0} and the function will return false; 00813 return normalize(rslt) != 0.; 00814 } 00815 00826 static bool vectorTripleProductNorthPole(const double* const u, 00827 double* const w) 00828 { 00829 w[0] = -u[0] * u[2]; 00830 w[1] = -u[1] * u[2]; 00831 w[2] = u[1] * u[1] + u[0] * u[0]; 00832 return normalize(w) != 0.; 00833 } 00834 00847 static bool circumCenter(const double* const v0, 00848 const double* const v1, const double* const v2, double* const vs) 00849 { 00850 vs[0] = v0[1] * (v2[2] - v1[2]) + v2[1] * (v1[2] - v0[2]) 00851 + v1[1] * (v0[2] - v2[2]); 00852 vs[1] = v0[2] * (v2[0] - v1[0]) + v2[2] * (v1[0] - v0[0]) 00853 + v1[2] * (v0[0] - v2[0]); 00854 vs[2] = v0[0] * (v2[1] - v1[1]) + v2[0] * (v1[1] - v0[1]) 00855 + v1[0] * (v0[1] - v2[1]); 00856 return normalize(vs) > 0.; 00857 } 00858 00870 static double* circumCenter(const double* const v0, 00871 const double* const v1, const double* const v2) 00872 { 00873 double* vs = new double[3]; 00874 vs[0] = v0[1] * (v2[2] - v1[2]) + v2[1] * (v1[2] - v0[2]) 00875 + v1[1] * (v0[2] - v2[2]); 00876 vs[1] = v0[2] * (v2[0] - v1[0]) + v2[2] * (v1[0] - v0[0]) 00877 + v1[2] * (v0[0] - v2[0]); 00878 vs[2] = v0[0] * (v2[1] - v1[1]) + v2[0] * (v1[1] - v0[1]) 00879 + v1[0] * (v0[1] - v2[1]); 00880 normalize(vs); 00881 return vs; 00882 } 00883 00896 static bool circumCenter(double const* const * const t, 00897 double* const vs) 00898 { 00899 return circumCenter(t[0], t[1], t[2], vs); 00900 } 00901 00917 static bool moveDistAz(const double* const w, double distance, 00918 double azimuth, double* const u) 00919 { 00920 double n[3] = { 0.0, 0.0, 0.0 }; 00921 if (moveNorth(w, distance, n)) 00922 { 00923 rotate(n, w, azimuth, u); 00924 return true; 00925 } 00926 u[0] = w[0]; 00927 u[1] = w[1]; 00928 u[2] = w[2]; 00929 return false; 00930 } 00931 00945 static void move(const double* const w, const double* const vtp, 00946 double a, double* const u) 00947 { 00948 double cosa = cos(a); 00949 double sina = sin(a); 00950 u[0] = cosa * w[0] + sina * vtp[0]; 00951 u[1] = cosa * w[1] + sina * vtp[1]; 00952 u[2] = cosa * w[2] + sina * vtp[2]; 00953 } 00954 00969 static bool moveNorth(const double* const x, double distance, 00970 double* const z) 00971 { 00972 double vtp[3] = { 0.0, 0.0, 0.0 }; 00973 if (vectorTripleProductNorthPole(x, vtp)) 00974 { 00975 move(x, vtp, distance, z); 00976 return true; 00977 } 00978 00979 z[0] = x[0]; 00980 z[1] = x[1]; 00981 z[2] = x[2]; 00982 return false; 00983 } 00984 00992 static bool isPole(const double* const u) 00993 { 00994 return (u[0] * u[0] + u[1] * u[1]) < 1.0e-15; 00995 } 00996 01006 static bool parallel(const double* const u, const double* const v) 01007 { 01008 return 1.0 - abs(u[0] * v[0] + u[1] * v[1] + u[2] * v[2]) < 2.0e-15; 01009 } 01010 01027 static double* getGreatCirclePoint( 01028 double const* const * const greatCircle, double distance) 01029 { 01030 double* v = new double[3]; 01031 getGreatCirclePoint(greatCircle, distance, v); 01032 return v; 01033 } 01034 01052 static void getGreatCirclePoint( 01053 double const* const * const greatCircle, double distance, 01054 double* const v) 01055 { 01056 double cosa = cos(distance); 01057 double sina = sin(distance); 01058 v[0] = cosa * greatCircle[0][0] + sina * greatCircle[1][0]; 01059 v[1] = cosa * greatCircle[0][1] + sina * greatCircle[1][1]; 01060 v[2] = cosa * greatCircle[0][2] + sina * greatCircle[1][2]; 01061 } 01062 01069 static double getTriangleArea(const double* const v0, 01070 const double* const v1, const double* const v2) 01071 { 01072 double v10[3] = { v1[0] - v0[0], v1[1] - v0[1], v1[2] - v0[2] }; 01073 double v20[3] = { v2[0] - v0[0], v2[1] - v0[1], v2[2] - v0[2] }; 01074 double u[3] = { v10[1] * v20[2] - v10[2] * v20[1], v10[2] * v20[0] 01075 - v10[0] * v20[2], v10[0] * v20[1] - v10[1] * v20[0] }; 01076 return sqrt(u[0] * u[0] + u[1] * u[1] + u[2] * u[2]) / 2.; 01077 } 01078 01086 static double* center(double const * const * const v, int n) 01087 { 01088 double* x = new double[3]; 01089 x[0] = x[1] = x[2] = 0.0; 01090 if (n == 0) 01091 return x; 01092 01093 for (int i = 0; i < n; ++i) 01094 { 01095 x[0] += v[i][0]; 01096 x[1] += v[i][1]; 01097 x[2] += v[i][2]; 01098 } 01099 normalize(x); 01100 return x; 01101 } 01102 01110 static void center(vector<double*> v, double* x) 01111 { 01112 x[0] = x[1] = x[2] = 0.0; 01113 01114 for (size_t i = 0; i < v.size(); ++i) 01115 { 01116 x[0] += v[i][0]; 01117 x[1] += v[i][1]; 01118 x[2] += v[i][2]; 01119 } 01120 normalize(x); 01121 } 01122 }; 01123 // end class GeoTessUtils 01124 01125 // **** _INLINE FUNCTION IMPLEMENTATIONS_ ************************************** 01126 01127 01132 static const double geocentric[] = { 0.0, 0.003047423602671013, 01133 0.006094847970838097, 0.009142273869969656, 0.012189702065478763, 01134 0.015237133322695492, 0.018284568406839258, 0.021332008082991166, 01135 0.024379453116066336, 0.027426904270786288, 0.030474362311651265, 01136 0.03352182800291262, 0.03656930210854519, 0.03961678539221966, 01137 0.04266427861727495, 0.04571178254669065, 0.04875929794305942, 01138 0.05180682556855937, 0.05485436618492655, 0.057901920553427404, 01139 0.06094948943483121, 0.06399707358938257, 0.06704467377677387, 01140 0.0700922907561179, 0.07313992528592034, 0.07618757812405218, 01141 0.07923525002772251, 0.08228294175345101, 0.08533065405704056, 01142 0.08837838769354987, 0.0914261434172662, 0.094473921981678, 01143 0.09752172413944764, 0.10056955064238413, 0.1036174022414159, 01144 0.10666527968656359, 0.1097131837269129, 0.11276111511058741, 01145 0.11580907458472142, 0.11885706289543299, 0.12190508078779674, 01146 0.1249531290058169, 0.1280012082924004, 0.13104931938932968, 01147 0.13409746303723613, 0.13714563997557289, 0.140193850942588, 01148 0.14324209667529803, 0.14629037790946073, 0.14933869537954875, 01149 0.15238704981872267, 0.15543544195880452, 0.1584838725302512, 01150 0.1615323422621277, 0.16458085188208085, 0.16762940211631275, 01151 0.17067799368955427, 0.17372662732503877, 0.17677530374447592, 01152 0.17982402366802488, 0.1828727878142688, 0.18592159690018817, 01153 0.18897045164113468, 0.19201935275080542, 0.19506830094121663, 01154 0.19811729692267788, 0.201166341403766, 0.20421543509129933, 01155 0.20726457869031198, 0.21031377290402786, 0.21336301843383518, 01156 0.21641231597926083, 0.21946166623794464, 0.22251106990561403, 01157 0.22556052767605864, 0.2286100402411045, 0.2316596082905894, 01158 0.23470923251233702, 0.23775891359213203, 0.24080865221369493, 01159 0.2438584490586569, 0.24690830480653495, 0.2499582201347069, 01160 0.25300819571838656, 0.25605823223059876, 0.25910833034215514, 01161 0.2621584907216286, 0.26520871403532986, 0.2682590009472821, 01162 0.27130935211919693, 0.2743597682104497, 0.27741024987805574, 01163 0.2804607977766458, 0.28351141255844176, 0.28656209487323325, 01164 0.2896128453683528, 0.29266366468865285, 0.29571455347648123, 01165 0.29876551237165794, 0.3018165420114511, 0.3048676430305536, 01166 0.30791881606105975, 0.3109700617324416, 0.314021380671526, 01167 0.317072773502471, 0.32012424084674285, 0.3231757833230931, 01168 0.3262274015475356, 0.3292790961333235, 0.3323308676909266, 01169 0.3353827168280087, 0.3384346441494046, 0.34148665025709846, 01170 0.34453873575020055, 0.34759090122492536, 0.3506431472745693, 01171 0.35369547448948857, 0.35674788345707703, 0.3598003747617447, 01172 0.3628529489848955, 0.36590560670490546, 0.36895834849710163, 01173 0.3720111749337399, 0.3750640865839841, 0.3781170840138844, 01174 0.3811701677863562, 0.384223338461159, 0.3872765965948754, 01175 0.39032994274089, 0.393383377449369, 0.39643690126723913, 01176 0.3994905147381674, 0.4025442184025402, 0.40559801279744334, 01177 0.40865189845664174, 0.41170587591055896, 0.4147599456862576, 01178 0.41781410830741905, 0.42086836429432384, 0.423922714163832, 01179 0.4269771584293634, 0.43003169760087806, 0.43308633218485754, 01180 0.4361410626842845, 0.43919588959862493, 0.4422508134238082, 01181 0.44530583465220863, 0.44836095377262664, 0.4514161712702699, 01182 0.4544714876267352, 0.45752690331998996, 0.4605824188243536, 01183 0.46363803461047975, 0.4666937511453385, 0.4697495688921976, 01184 0.4728054883106056, 0.47586150985637393, 0.4789176339815591, 01185 0.4819738611344456, 0.48503019175952866, 0.4880866262974967, 01186 0.49114316518521534, 0.49419980885570924, 0.49725655773814614, 01187 0.5003134122578201, 0.5033703728361352, 0.5064274398905888, 01188 0.5094846138347555, 0.5125418950782715, 0.5155992840268179, 01189 0.5186567810821053, 0.5217143866418585, 0.5247721010998003, 01190 0.5278299248456365, 0.5308878582650406, 0.5339459017396384, 01191 0.5370040556469939, 0.5400623203605933, 0.5431206962498311, 01192 0.5461791836799952, 0.5492377830122528, 0.5522964946036362, 01193 0.5553553188070278, 0.5584142559711474, 0.5614733064405376, 01194 0.5645324705555501, 0.5675917486523328, 0.5706511410628154, 01195 0.5737106481146972, 0.5767702701314332, 0.5798300074322218, 01196 0.5828898603319916, 0.5859498291413889, 0.5890099141667653, 01197 0.5920701157101648, 0.5951304340693124, 0.598190869537602, 01198 0.6012514224040836, 0.6043120929534528, 0.6073728814660381, 01199 0.6104337882177904, 0.6134948134802714, 0.6165559575206421, 01200 0.6196172206016525, 0.6226786029816302, 0.6257401049144706, 01201 0.6288017266496251, 0.6318634684320923, 0.6349253305024066, 01202 0.6379873130966289, 0.6410494164463364, 0.6441116407786132, 01203 0.6471739863160405, 0.6502364532766877, 0.6532990418741025, 01204 0.6563617523173022, 0.6594245848107654, 0.6624875395544221, 01205 0.6655506167436465, 0.6686138165692472, 0.6716771392174603, 01206 0.6747405848699405, 0.6778041537037534, 0.6808678458913681, 01207 0.6839316616006491, 0.6869956009948498, 0.6900596642326039, 01208 0.6931238514679199, 0.6961881628501729, 0.6992525985240989, 01209 0.7023171586297877, 0.7053818433026762, 0.7084466526735433, 01210 0.7115115868685029, 0.7145766460089984, 0.7176418302117967, 01211 0.7207071395889835, 0.7237725742479568, 0.7268381342914229, 01212 0.72990381981739, 0.7329696309191651, 0.7360355676853481, 01213 0.7391016301998271, 0.7421678185417753, 0.7452341327856461, 01214 0.7483005730011691, 0.7513671392533465, 0.7544338316024497, 01215 0.7575006501040149, 0.7605675948088417, 0.7636346657629879, 01216 0.7667018630077682, 0.7697691865797504, 0.7728366365107536, 01217 0.7759042128278457, 0.7789719155533406, 0.7820397447047971, 01218 0.7851077002950162, 0.7881757823320402, 0.7912439908191506, 01219 0.794312325754867, 0.7973807871329465, 0.8004493749423818, 01220 0.8035180891674011, 0.8065869297874673, 0.8096558967772779, 01221 0.8127249901067641, 0.8157942097410916, 0.8188635556406603, 01222 0.821933027761104, 0.8250026260532924, 0.8280723504633305, 01223 0.83114220093256, 0.8342121773975598, 0.8372822797901482, 01224 0.8403525080373838, 0.8434228620615665, 0.8464933417802403, 01225 0.8495639471061945, 0.8526346779474664, 0.8557055342073429, 01226 0.8587765157843639, 0.8618476225723242, 0.8649188544602767, 01227 0.8679902113325356, 0.8710616930686791, 0.8741332995435535, 01228 0.8772050306272762, 0.8802768861852399, 0.8833488660781164, 01229 0.8864209701618606, 0.889493198287715, 0.8925655503022143, 01230 0.8956380260471897, 0.8987106253597743, 0.9017833480724076, 01231 0.9048561940128412, 0.9079291630041441, 0.9110022548647081, 01232 0.9140754694082539, 0.9171488064438367, 0.9202222657758528, 01233 0.9232958472040453, 0.9263695505235116, 0.929443375524709, 01234 0.9325173219934624, 0.9355913897109707, 0.9386655784538146, 01235 0.941739887993964, 0.9448143180987851, 0.9478888685310487, 01236 0.9509635390489382, 0.9540383294060569, 0.9571132393514377, 01237 0.9601882686295503, 0.9632634169803111, 0.9663386841390907, 01238 0.9694140698367245, 0.9724895737995205, 0.9755651957492697, 01239 0.9786409354032554, 0.9817167924742626, 0.9847927666705888, 01240 0.9878688576960531, 0.9909450652500075, 0.9940213890273466, 01241 0.9970978287185187, 1.0001743840095367, 1.0032510545819884, 01242 1.0063278401130493, 1.0094047402754918, 1.0124817547376985, 01243 1.0155588831636737, 1.0186361252130536, 1.0217134805411217, 01244 1.0247909487988172, 1.0278685296327505, 1.0309462226852142, 01245 1.0340240275941965, 1.0371019439933935, 1.0401799715122235, 01246 1.0432581097758389, 1.0463363584051413, 1.0494147170167933, 01247 1.0524931852232333, 1.0555717626326906, 1.0586504488491968, 01248 1.0617292434726033, 1.0648081460985928, 1.0678871563186967, 01249 1.0709662737203076, 1.0740454978866965, 1.0771248283970258, 01250 1.0802042648263666, 1.0832838067457127, 1.086363453721997, 01251 1.089443205318108, 1.092523061092904, 1.0956030206012313, 01252 1.098683083393939, 1.1017632490178968, 1.1048435170160098, 01253 1.1079238869272385, 1.1110043582866118, 1.1140849306252474, 01254 1.1171656034703676, 1.120246376345317, 1.123327248769581, 01255 1.1264082202588015, 1.129489290324798, 1.1325704584755818, 01256 1.1356517242153787, 1.1387330870446435, 1.141814546460081, 01257 1.1448961019546642, 1.147977753017652, 1.1510594991346106, 01258 1.1541413397874303, 1.157223274454347, 1.1603053026099588, 01259 1.1633874237252504, 1.1664696372676073, 1.1695519427008403, 01260 1.1726343394852028, 1.1757168270774128, 1.1787994049306725, 01261 1.1818820724946881, 1.1849648292156931, 1.1880476745364656, 01262 1.1911306078963526, 1.194213628731289, 1.1972967364738196, 01263 1.2003799305531206, 1.2034632103950214, 1.206546575422025, 01264 1.209630025053332, 1.2127135587048612, 1.2157971757892707, 01265 1.2188808757159835, 1.2219646578912058, 1.2250485217179534, 01266 1.2281324665960707, 1.231216491922257, 1.2343005970900864, 01267 1.2373847814900338, 1.2404690445094946, 1.2435533855328118, 01268 1.2466378039412964, 1.2497222991132528, 1.2528068704240023, 01269 1.2558915172459055, 1.2589762389483887, 1.2620610348979655, 01270 1.265145904458263, 1.268230846990045, 1.2713158618512368, 01271 1.27440094839695, 1.2774861059795064, 1.2805713339484646, 01272 1.2836566316506417, 1.286741998430143, 1.2898274336283824, 01273 1.292912936584111, 1.295998506633441, 1.299084143109872, 01274 1.3021698453443156, 1.3052556126651222, 1.3083414443981063, 01275 1.3114273398665721, 1.3145132983913408, 1.3175993192907758, 01276 1.3206854018808087, 1.3237715454749663, 1.3268577493843976, 01277 1.3299440129178983, 1.3330303353819408, 1.3361167160806975, 01278 1.33920315431607, 1.342289649387715, 1.3453762005930718, 01279 1.34846280722739, 1.3515494685837555, 1.3546361839531185, 01280 1.3577229526243213, 1.3608097738841256, 1.3638966470172398, 01281 1.366983571306347, 1.370070546032133, 1.3731575704733139, 01282 1.3762446439066645, 1.379331765607045, 1.3824189348474314, 01283 1.3855061508989417, 1.388593413030866, 1.3916807205106922, 01284 1.3947680726041385, 1.3978554685751772, 1.4009429076860678, 01285 1.4040303891973824, 1.4071179123680362, 1.4102054764553156, 01286 1.4132930807149071, 1.4163807244009277, 1.4194684067659513, 01287 1.4225561270610403, 1.425643884535773, 1.4287316784382749, 01288 1.4318195080152447, 1.4349073725119876, 1.4379952711724417, 01289 1.4410832032392094, 1.4441711679535851, 1.4472591645555866, 01290 1.4503471922839841, 1.453435250376329, 1.4565233380689855, 01291 1.4596114545971586, 1.4626995991949252, 1.4657877710952634, 01292 1.468875969530083, 1.4719641937302546, 1.4750524429256404, 01293 1.4781407163451246, 1.481229013216642, 1.4843173327672103, 01294 1.4874056742229587, 1.490494036809159, 1.4935824197502554, 01295 1.4966708222698952, 1.499759243590959, 1.502847682935591, 01296 1.5059361395252298, 1.5090246125806384, 1.512113101321935, 01297 1.5152016049686239, 1.5182901227396248, 1.5213786538533045, 01298 1.524467197527508, 1.527555752979587, 1.5306443194264325, 01299 1.533732896084505, 1.536821482169865, 1.539910076898203, 01300 1.5429986794848713, 1.5460872891449153, 1.5491759050931018, 01301 1.5522645265439523, 1.5553531527117719, 1.558441782810682, 01302 1.561530416054649, 1.5646190516575167, 1.567707688833036, 01303 1.5707963267948966 }; 01304 01309 static const double geographic[] = { 0.0, 0.0030886379618605825, 01310 0.006177275137379901, 0.0092659107402475, 0.012354543984214532, 01311 0.015443174083124565, 0.01853180025094438, 0.021620421701794772, 01312 0.0247090376499813, 0.027797647310025125, 0.030886249896693734, 01313 0.0339748446250317, 0.037063430710391455, 0.040152007368464, 01314 0.043240573815309616, 0.0463291292673886, 0.049417672941591925, 01315 0.05250620405527188, 0.05559472182627276, 0.05868322547296149, 01316 0.0617717142142582, 0.06486018726966679, 0.06794864385930552, 01317 0.0710370832039375, 0.07412550452500125, 0.07721390704464104, 01318 0.08030228998573746, 0.08339065257193778, 0.08647899402768627, 01319 0.0895673135782546, 0.0926556104497721, 0.09574388386925607, 01320 0.09883213306464193, 0.10192035726481347, 0.10500855569963301, 01321 0.10809672759997133, 0.11118487219773797, 0.11427298872591114, 01322 0.11736107641856755, 0.12044913451091256, 0.1235371622393099, 01323 0.12662515884131142, 0.12971312355568715, 0.13280105562245464, 01324 0.13588895428290887, 0.13897681877965185, 0.14206464835662186, 01325 0.1451524422591234, 0.14824019973385638, 0.1513279200289453, 01326 0.15441560239396898, 0.1575032460799894, 0.16059085033958118, 01327 0.16367841442686046, 0.16676593759751412, 0.16985341910882873, 01328 0.17294085821971925, 0.17602825419075818, 0.17911560628420423, 01329 0.18220291376403075, 0.18529017589595478, 0.1883773919474653, 01330 0.19146456118785166, 0.19455168288823224, 0.1976387563215826, 01331 0.20072578076276354, 0.20381275548854957, 0.20689967977765683, 01332 0.209986552910771, 0.21307337417057526, 0.2161601428417781, 01333 0.2192468582111411, 0.22233351956750647, 0.22542012620182456, 01334 0.22850667740718159, 0.23159317247882658, 0.234679610714199, 01335 0.23776599141295568, 0.24085231387699807, 0.24393857741049915, 01336 0.24702478131993025, 0.250110924914088, 0.25319700750412083, 01337 0.25628302840355577, 0.25936898692832455, 0.2624548823967905, 01338 0.26554071412977437, 0.26862648145058093, 0.2717121836850245, 01339 0.2747978201614555, 0.27788339021078556, 0.2809688931665142, 01340 0.2840543283647537, 0.28713969514425475, 0.2902249928464323, 01341 0.2933102208153901, 0.29639537839794666, 0.2994804649436597, 01342 0.3025654798048515, 0.3056504223366336, 0.3087352918969311, 01343 0.31182008784650794, 0.31490480954899097, 0.3179894563708943, 01344 0.3210740276816437, 0.3241585228536002, 0.3272429412620848, 01345 0.33032728228540187, 0.33341154530486283, 0.33649572970480984, 01346 0.33957983487263954, 0.3426638601988257, 0.34574780507694325, 01347 0.34883166890369055, 0.3519154510789131, 0.3549991510056258, 01348 0.35808276809003553, 0.3611663017415644, 0.36424975137287147, 01349 0.36733311639987526, 0.37041639624177586, 0.37349959032107694, 01350 0.37658269806360756, 0.3796657188985439, 0.3827486522584309, 01351 0.38583149757920354, 0.3889142543002084, 0.39199692186422425, 01352 0.3950794997174837, 0.39816198730969365, 0.4012443840940563, 01353 0.4043266895272892, 0.4074089030696463, 0.41049102418493755, 01354 0.41357305234054986, 0.4166549870074662, 0.419736827660286, 01355 0.4228185737772445, 0.42590022484023243, 0.4289817803348154, 01356 0.43206323975025296, 0.4351446025795178, 0.4382258683193147, 01357 0.4413070364700987, 0.44438810653609495, 0.4474690780253156, 01358 0.45054995044957946, 0.45363072332452903, 0.45671139616964923, 01359 0.4597919685082848, 0.4628724398676581, 0.4659528097788865, 01360 0.4690330777769999, 0.47211324340095756, 0.4751933061936653, 01361 0.4782732657019926, 0.4813531214767887, 0.48443287307289956, 01362 0.48751252004918405, 0.49059206196853006, 0.49367149839787067, 01363 0.4967508289082, 0.4998300530745889, 0.5029091704761999, 01364 0.5059881806963037, 0.5090670833222932, 0.5121458779456998, 01365 0.515224564162206, 0.5183031415716631, 0.5213816097781034, 01366 0.5244599683897553, 0.5275382170190575, 0.5306163552826731, 01367 0.533694382801503, 0.5367722992007001, 0.5398501041096824, 01368 0.542927797162146, 0.5460053779960794, 0.549082846253775, 01369 0.5521602015818429, 0.5552374436312231, 0.558314572057198, 01370 0.5613915865194048, 0.5644684866818472, 0.567545272212908, 01371 0.5706219427853598, 0.5736984980763777, 0.57677493776755, 01372 0.5798512615448891, 0.5829274690988434, 0.5860035601243078, 01373 0.589079534320634, 0.5921553913916412, 0.5952311310456269, 01374 0.5983067529953761, 0.6013822569581719, 0.6044576426558057, 01375 0.6075329098145854, 0.6106080581653462, 0.6136830874434589, 01376 0.6167579973888396, 0.6198327877459584, 0.6229074582638479, 01377 0.6259820086961115, 0.6290564388009326, 0.632130748341082, 01378 0.6352049370839259, 0.6382790048014341, 0.6413529512701875, 01379 0.644426776271385, 0.6475004795908512, 0.6505740610190438, 01380 0.6536475203510599, 0.6567208573866427, 0.6597940719301885, 01381 0.6628671637907525, 0.6659401327820553, 0.669012978722489, 01382 0.6720857014351223, 0.6751583007477069, 0.6782307764926824, 01383 0.6813031285071816, 0.684375356633036, 0.6874474607167802, 01384 0.6905194406096566, 0.6935912961676205, 0.6966630272513432, 01385 0.6997346337262175, 0.702806115462361, 0.7058774723346197, 01386 0.7089487042225724, 0.7120198110105327, 0.7150907925875537, 01387 0.7181616488474303, 0.7212323796887021, 0.7243029850146564, 01388 0.7273734647333301, 0.7304438187575129, 0.7335140470047483, 01389 0.7365841493973367, 0.7396541258623366, 0.7427239763315661, 01390 0.7457937007416041, 0.7488632990337925, 0.7519327711542364, 01391 0.7550021170538048, 0.7580713366881324, 0.7611404300176188, 01392 0.7642093970074293, 0.7672782376274956, 0.7703469518525148, 01393 0.7734155396619501, 0.7764840010400295, 0.779552335975746, 01394 0.7826205444628564, 0.7856886264998802, 0.7887565820900994, 01395 0.7918244112415559, 0.7948921139670508, 0.7979596902841429, 01396 0.8010271402151462, 0.8040944637871283, 0.8071616610319086, 01397 0.8102287319860549, 0.8132956766908815, 0.816362495192447, 01398 0.8194291875415499, 0.8224957537937274, 0.8255621940092505, 01399 0.8286285082531213, 0.8316946965950694, 0.8347607591095485, 01400 0.8378266958757314, 0.8408925069775065, 0.8439581925034738, 01401 0.8470237525469397, 0.8500891872059131, 0.8531544965830998, 01402 0.8562196807858983, 0.8592847399263936, 0.8623496741213532, 01403 0.8654144834922204, 0.8684791681651088, 0.8715437282707976, 01404 0.8746081639447237, 0.8776724753269767, 0.8807366625622927, 01405 0.8838007258000469, 0.8868646651942474, 0.8899284809035285, 01406 0.8929921730911432, 0.8960557419249562, 0.8991191875774363, 01407 0.9021825102256493, 0.9052457100512501, 0.9083087872404745, 01408 0.9113717419841312, 0.9144345744775944, 0.9174972849207942, 01409 0.9205598735182088, 0.923622340478856, 0.9266846860162834, 01410 0.9297469103485603, 0.9328090136982676, 0.9358709962924899, 01411 0.9389328583628043, 0.9419946001452715, 0.945056221880426, 01412 0.9481177238132663, 0.9511791061932441, 0.9542403692742544, 01413 0.9573015133146252, 0.9603625385771062, 0.9634234453288585, 01414 0.9664842338414438, 0.969544904390813, 0.9726054572572946, 01415 0.9756658927255841, 0.9787262110847318, 0.9817864126281313, 01416 0.9848464976535075, 0.9879064664629048, 0.9909663193626747, 01417 0.9940260566634633, 0.9970856786801994, 1.000145185732081, 01418 1.0032045781425638, 1.0062638562393464, 1.0093230203543588, 01419 1.0123820708237492, 1.0154410079878686, 1.0184998321912604, 01420 1.0215585437826438, 1.0246171431149014, 1.0276756305450656, 01421 1.0307340064343031, 1.0337922711479026, 1.036850425055258, 01422 1.039908468529856, 1.04296640194926, 1.0460242256950962, 01423 1.049081940153038, 1.0521395457127913, 1.0551970427680788, 01424 1.0582544317166251, 1.061311712960141, 1.0643688869043078, 01425 1.0674259539587614, 1.0704829145370764, 1.0735397690567505, 01426 1.0765965179391872, 1.0796531616096812, 1.0827097004973996, 01427 1.085766135035368, 1.088822465660451, 1.0918786928133375, 01428 1.0949348169385227, 1.097990838484291, 1.101046757902699, 01429 1.104102575649558, 1.1071582921844167, 1.1102139079705429, 01430 1.1132694234749065, 1.1163248391681613, 1.1193801555246266, 01431 1.12243537302227, 1.1254904921426878, 1.1285455133710884, 01432 1.1316004371962716, 1.1346552641106122, 1.137709994610039, 01433 1.1407646291940186, 1.143819168365533, 1.1468736126310646, 01434 1.149927962500573, 1.1529822184874776, 1.1560363811086392, 01435 1.1590904508843376, 1.162144428338255, 1.165198313997453, 01436 1.1682521083923565, 1.171305812056729, 1.1743594255276575, 01437 1.1774129493455274, 1.1804663840540066, 1.1835197302000213, 01438 1.1865729883337375, 1.1896261590085404, 1.1926792427810122, 01439 1.1957322402109125, 1.1987851518611565, 1.201837978297795, 01440 1.204890720089991, 1.207943377810001, 1.2109959520331517, 01441 1.2140484433378194, 1.217100852305408, 1.2201531795203273, 01442 1.2232054255699714, 1.226257591044696, 1.2293096765377982, 01443 1.232361682645492, 1.235413609966888, 1.2384654591039699, 01444 1.241517230661573, 1.2445689252473608, 1.2476205434718035, 01445 1.2506720859481537, 1.2537235532924256, 1.2567749461233706, 01446 1.259826265062455, 1.2628775107338368, 1.2659286837643429, 01447 1.2689797847834456, 1.2720308144232386, 1.2750817733184152, 01448 1.2781326621062439, 1.2811834814265437, 1.2842342319216635, 01449 1.2872849142364546, 1.2903355290182508, 1.2933860769168408, 01450 1.2964365585844468, 1.2994869746756996, 1.3025373258476145, 01451 1.3055876127595665, 1.308637836073268, 1.3116879964527417, 01452 1.3147380945642977, 1.31778813107651, 1.3208381066601895, 01453 1.3238880219883615, 1.3269378777362395, 1.3299876745812016, 01454 1.3330374132027645, 1.3360870942825596, 1.339136718504307, 01455 1.3421862865537921, 1.3452357991188382, 1.3482852568892825, 01456 1.351334660556952, 1.3543840108156358, 1.3574333083610615, 01457 1.3604825538908687, 1.3635317481045846, 1.366580891703597, 01458 1.3696299853911307, 1.3726790298722187, 1.37572802585368, 01459 1.3787769740440912, 1.381825875153762, 1.3848747298947086, 01460 1.3879235389806277, 1.3909723031268717, 1.3940210230504206, 01461 1.3970696994698577, 1.4001183331053422, 1.4031669246785838, 01462 1.4062154749128157, 1.4092639845327688, 1.4123124542646455, 01463 1.415360884836092, 1.418409276976174, 1.4214576314153478, 01464 1.424505948885436, 1.4275542301195985, 1.4306024758523086, 01465 1.4336506868193237, 1.4366988637576603, 1.4397470074055667, 01466 1.442795118502496, 1.4458431977890798, 1.4488912460070997, 01467 1.4519392638994637, 1.454987252210175, 1.4580352116843092, 01468 1.4610831430679836, 1.464131047108333, 1.4671789245534805, 01469 1.4702267761525125, 1.4732746026554489, 1.4763224048132186, 01470 1.4793701833776305, 1.4824179391013466, 1.4854656727378561, 01471 1.4885133850414456, 1.491561076767174, 1.4946087486708444, 01472 1.4976564015089762, 1.5007040360387784, 1.5037516530181227, 01473 1.506799253205514, 1.5098468373600653, 1.5128944062414693, 01474 1.51594196060997, 1.5189895012263372, 1.522037028851837, 01475 1.525084544248206, 1.5281320481776215, 1.531179541402677, 01476 1.5342270246863512, 1.537274498791984, 1.5403219644832453, 01477 1.5433694225241104, 1.5464168736788304, 1.5494643187119053, 01478 1.5525117583880574, 1.555559193472201, 1.558606624729418, 01479 1.5616540529249268, 1.5647014788240585, 1.5677489031922254, 01480 1.5707963267948966 }; 01481 01482 inline double GeoTessUtils::getGeoCentricLatitude(const double& lat) 01483 { 01484 // convert lat from geographic to geocentric latitude. 01485 01486 if (!approximateLatitudes) 01487 return atan((1 - EARTH_E) * tan(lat)); 01488 01489 if (lat >= PI / 2) 01490 return PI / 2; 01491 else if (lat <= -PI / 2) 01492 return -PI / 2; 01493 else if (lat < 0) 01494 { 01495 double tmp = -lat / (PI / 2 / (513 - 1)); 01496 int i = (int) tmp; 01497 return -geocentric[i] - (tmp - i) * (geocentric[i + 1] - geocentric[i]); 01498 } 01499 else 01500 { 01501 double tmp = lat / (PI / 2 / (513 - 1)); 01502 int i = (int) tmp; 01503 return geocentric[i] + (tmp - i) * (geocentric[i + 1] - geocentric[i]); 01504 } 01505 } 01506 01507 inline double GeoTessUtils::getGeoGraphicLatitude(const double& lat) 01508 { 01509 // the constant 0.9933 is (1-e*e) where e is the eccentricity of the 01510 // earth as defined by the GRS80 ellipsoid. 01511 01512 if (!approximateLatitudes) 01513 return atan(tan(lat) / (1 - EARTH_E)); 01514 01515 if (lat >= PI / 2) 01516 return PI / 2; 01517 else if (lat <= -PI / 2) 01518 return -PI / 2; 01519 else if (lat < 0) 01520 { 01521 double tmp = -lat / (PI / 2 / (513 - 1)); 01522 int i = (int) tmp; 01523 return -geographic[i] - (tmp - i) * (geographic[i + 1] - geographic[i]); 01524 } 01525 else 01526 { 01527 double tmp = lat / (PI / 2 / (513 - 1)); 01528 int i = (int) tmp; 01529 return geographic[i] + (tmp - i) * (geographic[i + 1] - geographic[i]); 01530 } 01531 } 01532 01533 } // end namespace geotess 01534 01535 #endif // GEOTESSUTILS_OBJECT_H