GeoTessCPP  2.1
Software to facilitate storage and retrieval of 3D information about the Earth.
 All Classes Namespaces Files Functions Variables Typedefs Friends Macros
GeoTessPosition.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 GEOTESSPOSITION_OBJECT_H
37 #define GEOTESSPOSITION_OBJECT_H
38 
39 // **** _SYSTEM INCLUDES_ ******************************************************
40 
41 #include <iostream>
42 #include <string>
43 #include <fstream>
44 #include <vector>
45 #include <sstream>
46 
47 // use standard library objects
48 using namespace std;
49 
50 // **** _LOCAL INCLUDES_ *******************************************************
51 
52 #include "CPPUtils.h"
53 #include "GeoTessUtils.h"
54 #include "GeoTessModel.h"
55 #include "GeoTessGrid.h"
56 #include "GeoTessMetaData.h"
57 #include "CpuTimer.h"
58 #include "GeoTessProfile.h"
59 #include "GeoTessData.h"
60 
61 // **** _BEGIN GEOTESS NAMESPACE_ **********************************************
62 
63 namespace geotess {
64 
65 // **** _FORWARD REFERENCES_ ***************************************************
66 
67 class GeoTessInterpolatorType;
68 class GeoTessProfile;
69 
70 // **** _CLASS DEFINITION_ *****************************************************
71 
102 {
103 private:
104 
108  int refCount;
109 
115  int* maxTessLevel;
116 
122  int* tessLevels;
123 
132  int* triangle;
133 
139  double errorValue;
140 
151  void updatePosition2D(int layerid, const double* const uVector);
152 
170  void checkTessellation(const int& tid)
171  {
172  if (triangle[tid] < 0)
173  {
174  tessLevels[tid] = 0;
175  triangle[tid] = grid.getTriangle(tid, 0, 0);
176  getContainingTriangle(tid);
177  update2D(tid);
178  }
179  }
180 
188  void updateRadius(int lid, double rad)
189  {
190  if ((radius < 0.) || (rad != radius) || (lid != layerId))
191  {
192  radius = rad;
193  layerId = lid;
194  tessid = layerTessIds[lid];
195  checkTessellation(tessid);
196  clearRadialCoefficients();
197  }
198  }
199 
200  void clearRadialCoefficients()
201  {
202  for (int i=0; i<(int)radialIndexes.size(); ++i)
203  {
204  radialIndexes[i].clear();
205  radialCoefficients[i].clear();
206  }
207  }
208 
215  void updateRadialCoefficients()
216  {
217  // make sure dimensions of radialIndexes and radialCoefficients
218  // are at least as big as the number of vertices involved in interpolation.
219  if (radialIndexes.size() < vertices[tessid].size())
220  {
221  radialIndexes.resize(vertices[tessid].size());
222  radialCoefficients.resize(vertices[tessid].size());
223  }
224 
225  // if radial interpolation coefficients have already been computed
226  // do nothing.
227  if (radialIndexes[0].size() == 0)
228  {
229  vector<int>& v = vertices[tessid];
230  for (int i = 0; i < (int)v.size(); ++i)
231  modlProfiles[v[i]][layerId]->setInterpolationCoefficients(radialInterpolatorType,
232  radialIndexes[i], radialCoefficients[i], radius, radiusOutOfRangeAllowed);
233  }
234  }
235 
240  static const double TWALK_TOLERANCE;
241 
252  void getContainingTriangle(int tid);
253 
262  int biggerTriangle(int t1, int t2)
263  {
264  const int* tv = grid.getTriangleVertexIndexes(t1);
265  double dot1 = GeoTessUtils::dot(grid.getVertex(tv[0]), grid.getVertex(tv[1]))
266  + GeoTessUtils::dot(grid.getVertex(tv[1]), grid.getVertex(tv[2]))
267  + GeoTessUtils::dot(grid.getVertex(tv[2]), grid.getVertex(tv[0]));
268 
269  tv = grid.getTriangleVertexIndexes(t2);
270  double dot2 = GeoTessUtils::dot(grid.getVertex(tv[0]), grid.getVertex(tv[1]))
271  + GeoTessUtils::dot(grid.getVertex(tv[1]), grid.getVertex(tv[2]))
272  + GeoTessUtils::dot(grid.getVertex(tv[2]), grid.getVertex(tv[0]));
273 
274  return dot2 > dot1 ? t1 : t2;
275 
276  }
277 
278 protected:
279 
281 
285  double radius;
286 
290  double earthRadius;
291 
299  vector<double> layerRadii;
300 
304  int layerId;
305 
309  int tessid;
310 
318  vector< vector< int> > vertices;
319 
325  vector< vector< double> > linearCoefficients;
326 
333  //vector< vector< double> > nnCoefficients;
334 
338  vector< vector< double> > hCoefficients;
339 
354  vector<vector<int> > radialIndexes;
355 
373  vector<vector<double> > radialCoefficients;
374 
375 
380  const GeoTessInterpolatorType& radialInterpolatorType;
381 
386  GeoTessModel* model;
387 
391  GeoTessGrid& grid;
392 
396  GeoTessProfile *** modlProfiles;
397  double const* const* gridVertices;
398  int const* const* gridTriangles;
399  int const* gridDescendants;
400  const vector<vector<Edge*> >& gridEdges;
401  const int* layerTessIds;
402  int nLayers;
403 
418  bool radiusOutOfRangeAllowed;
419 
423  double unitVector[3];
424 
428  int getTriangle(int tid)
429  { checkTessellation(tid); return triangle[tid]; };
430 
435  virtual void update2D(int tid) = ABSTRACT;
436 
440  GeoTessPosition(GeoTessModel* model, const GeoTessInterpolatorType& radialType);
441 
443 
444 public:
445 
455  static GeoTessPosition* getGeoTessPosition(GeoTessModel* model);
456 
471  static GeoTessPosition* getGeoTessPosition(GeoTessModel* model,
472  const GeoTessInterpolatorType& horizontalType);
473 
487  static GeoTessPosition* getGeoTessPosition(GeoTessModel* model,
488  const GeoTessInterpolatorType& horizontalType, const GeoTessInterpolatorType& radialType);
489 
493  virtual ~GeoTessPosition();
494 
501  virtual const GeoTessInterpolatorType& getInterpolatorType() const = ABSTRACT;
502 
509  virtual double getValue(int attribute);
510 
531  void setModel(GeoTessModel* newModel);
532 
537  bool noEmptyProfiles();
538 
559  void set(double lat, double lon, double depth)
560  {
561  double uVector[3] = {0.0, 0.0, 0.0};
562  GeoTessUtils::getVectorDegrees(lat, lon, uVector);
563  double newRadius = GeoTessUtils::getEarthRadius(uVector) - depth;
564  set(uVector, newRadius);
565  }
566 
579  void set(const double* const uVector, const double& newRadius)
580  {
581  updatePosition2D(nLayers - 1, uVector);
582 
583  int lid = getLayerId(newRadius);
584 
585  updatePosition2D(lid, uVector);
586  updateRadius(lid, newRadius);
587  }
588 
606  void set(int layid, double lat, double lon, double depth)
607  {
608  if (layid < 0)
609  set(lat, lon, depth);
610  else
611  {
612  double uVector[3];
613  GeoTessUtils::getVectorDegrees(lat, lon, uVector);
614  updatePosition2D(layid, uVector);
615  updateRadius(layid, GeoTessUtils::getEarthRadius(uVector) - depth);
616  }
617  }
618 
629  void set(int layid, const double* const uVector, double rad)
630  {
631  if (layid < 0)
632  set(uVector, rad);
633  else
634  {
635  updatePosition2D(layid, uVector);
636  if (rad >= 0.0) updateRadius(layid, rad);
637  }
638  }
639 
647  void setTop(int layid, const double* const uVector)
648  {
649  updatePosition2D(layid, uVector);
650  updateRadius(layid, getRadiusTop(layid));
651  }
652 
661  void setBottom(int layid, const double* const uVector)
662  {
663  updatePosition2D(layid, uVector);
664  updateRadius(layid, getRadiusBottom(layid));
665  }
666 
674  void setRadius(int layid, double rad)
675  {
676  if (tessid < 0)
677  {
678  ostringstream os;
679  os << endl << "ERROR in GeoTessPosition::setRadius" << endl
680  << "Geographic position has not been specified." << endl;
681  throw GeoTessException(os, __FILE__, __LINE__, 3001);
682  }
683  updateRadius(layid, rad);
684  }
685 
692  void setRadius(double rad)
693  {
694  if (tessid < 0)
695  if (tessid < 0)
696  {
697  ostringstream os;
698  os << endl << "ERROR in GeoTessPosition::setRadius" << endl
699  << "Geographic position has not been specified." << endl;
700  throw GeoTessException(os, __FILE__, __LINE__, 3002);
701  }
702  updateRadius(getLayerId(rad), rad);
703  }
704 
716  void setDepth(int layer, double depth)
717  {
718  setRadius(layer, getEarthRadius()-depth);
719  }
720 
727  void setDepth(double depth)
728  {
729  setRadius(getEarthRadius()-depth);
730  }
731 
737  void setTop(int layid)
738  {
739  if (tessid < 0)
740  {
741  ostringstream os;
742  os << endl << "ERROR in GeoTessPosition::setRadius" << endl
743  << "Geographic position has not been specified." << endl;
744  throw GeoTessException(os, __FILE__, __LINE__, 3003);
745  }
746  tessid = layerTessIds[layid];
747  checkTessellation(tessid);
748  updateRadius(layid, getRadiusTop(layid));
749  }
750 
757  void setBottom(int layid)
758  {
759  if (tessid < 0)
760  {
761  ostringstream os;
762  os << endl << "ERROR in GeoTessPosition::setRadius" << endl
763  << "Geographic position has not been specified." << endl;
764  throw GeoTessException(os, __FILE__, __LINE__, 3004);
765  }
766  tessid = layerTessIds[layid];
767  checkTessellation(tessid);
768  updateRadius(layid, getRadiusBottom(layid));
769  }
770 
778  double getRadiusTop(int layid);
779 
786  double getRadiusBottom(int layid);
787 
793  double getEarthRadius()
794  {
795  if (earthRadius < 0.)
796  earthRadius = GeoTessUtils::getEarthRadius(unitVector);
797  return earthRadius;
798  }
799 
806  double* getVector() { return unitVector; };
807 
814  void copyVector(double* u)
815  { u[0] = unitVector[0]; u[1] = unitVector[1]; u[2] = unitVector[2]; };
816 
822  int getTriangle() { return triangle[tessid]; };
823 
828  int getNVertices() { return vertices[tessid].size(); };
829 
837  const vector<int>& getVertices() const { return vertices[tessid]; };
838 
844  int getIndexOfClosestVertex() const;
845 
852  const double* getClosestVertex() const
853  {
854  return grid.getVertex(getIndexOfClosestVertex());
855  }
856 
863  int getVertex(int index)
864  { return vertices[tessid][index]; }
865 
871  void getCoefficients(map<int, double>& coefficients)
872  {
873  coefficients.clear();
874  vector<int>& vtx = vertices[tessid];
875  vector<double>& hc = hCoefficients[tessid];
876  for (int i = 0; i < (int) vtx.size(); ++i)
877  modlProfiles[vtx[i]][layerId]->getCoefficients(coefficients, radius, hc[i]);
878  }
879 
889  void setMaxTessLevel(int layid, int maxTess)
890  {
891  maxTessLevel[layerTessIds[layid]] = maxTess;
892  triangle[layerTessIds[layid]] = -1;
893  checkTessellation(tessid);
894  }
895 
905  int getMaxTessLevel(int layid)
906  { return maxTessLevel[layerTessIds[layid]]; }
907 
914  int getTessLevel() const { return tessLevels[tessid]; };
915 
924  int getTessLevel(const int& tId) { checkTessellation(tId); return tessLevels[tId]; }
925 
931  double getRadiusTop()
932  { return getRadiusTop(layerId); };
933 
940  { return getRadiusBottom(layerId); };
941 
947  double getDepthTop()
948  {
949  return getEarthRadius() - getRadiusTop(layerId);
950  }
951 
957  double getDepthBottom()
958  {
959  return getEarthRadius() - getRadiusBottom(layerId);
960  }
961 
968  double getDepthTop(int layid)
969  {
970  return getEarthRadius() - getRadiusTop(layid);
971  }
972 
979  double getDepthBottom(int layid)
980  {
981  return getEarthRadius() - getRadiusBottom(layid);
982  }
983 
990  double getLayerThickness(int layid)
991  {
992  return getRadiusTop(layid) - getRadiusBottom(layid);
993  }
994 
1001  {
1002  return getRadiusTop() - getRadiusBottom();
1003  }
1004 
1010  double getRadius() { return radius; };
1011 
1017  double getDepth()
1018  { return getEarthRadius() - radius; };
1019 
1023  GeoTessModel* getModel() { return model; }
1024 
1028  int getTessID() { return tessid; };
1029 
1040  int getLayerId(double rad)
1041  {
1042  for (int i=0; i<nLayers; ++i)
1043  if (rad <= getRadiusTop(i))
1044  return i;
1045 
1046  for (int i=nLayers-1; i>=0; --i)
1047  if (getLayerThickness(i) > 0)
1048  return i;
1049 
1050  return nLayers-1;
1051  };
1052 
1056  int getLayerId() { return layerId; };
1057 
1062  string toString();
1063 
1070  double getErrorValue()
1071  {
1072  return errorValue;
1073  }
1074 
1081  void setErrorValue(double errVal)
1082  {
1083  errorValue = errVal;
1084  }
1085 
1094  {
1095  vector<int>& vtid = vertices[tessid];
1096  vector<double>& htid = hCoefficients[tessid];
1097  for (int v = 0; v < (int) vtid.size(); ++v)
1098  if (htid[v] > 0.999999999)
1099  return vtid[v];
1100  return -1;
1101  }
1102 
1127  void getWeights(map<int, double>& weights, double dkm)
1128  {
1129  vector<int>& vtx = vertices[tessid];
1130  vector<double>& htid = hCoefficients[tessid];
1131  model->getPointMap();
1132  for (int i = 0; i < (int) vtx.size(); ++i)
1133  modlProfiles[vtx[i]][layerId]->getWeights(weights, dkm, radius, htid[i]);
1134  }
1135 
1143  const vector<double>& getHorizontalCoefficients() const
1144  {
1145  return hCoefficients[tessid];
1146  }
1147 
1156  double getHorizontalCoefficient(int index) const
1157  {
1158  return hCoefficients[tessid][index];
1159  }
1160 
1177  {
1178  return radiusOutOfRangeAllowed;
1179  }
1180 
1196  void setRadiusOutOfRangeAllowed(bool allowed)
1197  {
1198  if (allowed != radiusOutOfRangeAllowed)
1199  clearRadialCoefficients();
1200 
1201  radiusOutOfRangeAllowed = allowed;
1202  }
1203 
1207  void addReference() { ++refCount; }
1208 
1213  {
1214  if (isNotReferenced())
1215  {
1216  ostringstream os;
1217  os << endl << "ERROR in Polygon::removeReference" << endl
1218  << "Reference count (" << refCount << ") is already zero." << endl;
1219  throw GeoTessException(os, __FILE__, __LINE__, 3005);
1220  }
1221 
1222  --refCount;
1223  }
1224 
1231  {
1232  return refCount;
1233  }
1234 
1239  bool isNotReferenced() { return refCount == 0; }
1240 
1241 }; // end class GeoTessModel
1242 
1243 } // end namespace geotess
1244 
1245 #endif // GEOTESSPOSITION_OBJECT_H
void set(const double *const uVector, const double &newRadius)
Definition: GeoTessPosition.h:579
void copyVector(double *u)
Definition: GeoTessPosition.h:814
double getDepthBottom(int layid)
Definition: GeoTessPosition.h:979
double * getVector()
Definition: GeoTessPosition.h:806
double getEarthRadius()
Definition: GeoTessPosition.h:793
void setBottom(int layid, const double *const uVector)
Definition: GeoTessPosition.h:661
bool isRadiusOutOfRangeAllowed()
Definition: GeoTessPosition.h:1176
double getDepthTop(int layid)
Definition: GeoTessPosition.h:968
double getDepthTop()
Definition: GeoTessPosition.h:947
int getTessLevel() const
Definition: GeoTessPosition.h:914
const double * getClosestVertex() const
Definition: GeoTessPosition.h:852
Information about an interpolated point at an arbitrary position in a model.
Definition: GeoTessPosition.h:101
double getLayerThickness()
Definition: GeoTessPosition.h:1000
void setDepth(double depth)
Definition: GeoTessPosition.h:727
const vector< double > & getHorizontalCoefficients() const
Definition: GeoTessPosition.h:1143
void setTop(int layid, const double *const uVector)
Definition: GeoTessPosition.h:647
Enumeration of the interpolation algorithms supported by GeoTess including LINEAR, NATURAL_NEIGHBOR and CUBIC_SPLINE.
Definition: GeoTessInterpolatorType.h:71
Manages the geometry and topology of one or more multi-level triangular tessellations of a unit spher...
Definition: GeoTessGrid.h:163
void setTop(int layid)
Definition: GeoTessPosition.h:737
void set(int layid, double lat, double lon, double depth)
Definition: GeoTessPosition.h:606
int getLayerId(double rad)
Definition: GeoTessPosition.h:1040
int getVertexIndex()
Definition: GeoTessPosition.h:1093
double getHorizontalCoefficient(int index) const
Definition: GeoTessPosition.h:1156
void setBottom(int layid)
Definition: GeoTessPosition.h:757
int getReferenceCount()
Definition: GeoTessPosition.h:1230
void setErrorValue(double errVal)
Definition: GeoTessPosition.h:1081
void setDepth(int layer, double depth)
Definition: GeoTessPosition.h:716
int getVertex(int index)
Definition: GeoTessPosition.h:863
int getTessLevel(const int &tId)
Definition: GeoTessPosition.h:924
An exception class for all GeoTess objects.
Definition: GeoTessException.h:65
void set(int layid, const double *const uVector, double rad)
Definition: GeoTessPosition.h:629
double getErrorValue()
Definition: GeoTessPosition.h:1070
void addReference()
Definition: GeoTessPosition.h:1207
void removeReference()
Definition: GeoTessPosition.h:1212
void setRadius(int layid, double rad)
Definition: GeoTessPosition.h:674
int getNVertices()
Definition: GeoTessPosition.h:828
double getRadius()
Definition: GeoTessPosition.h:1010
#define ABSTRACT
Global constant used to make pure virtual functions readable.
Definition: CPPGlobals.h:78
double getDepth()
Definition: GeoTessPosition.h:1017
int getTriangle()
Definition: GeoTessPosition.h:822
const vector< int > & getVertices() const
Definition: GeoTessPosition.h:837
GeoTessModel * getModel()
Definition: GeoTessPosition.h:1023
GeoTessPointMap * getPointMap()
Definition: GeoTessModel.h:1051
Abstract class that manages the radii and data values that span a single layer associated with a sing...
Definition: GeoTessProfile.h:96
Top level class that manages the GeoTessMetaData, GeoTessGrid and Data that comprise a 3D Earth model...
Definition: GeoTessModel.h:119
int getTessID()
Definition: GeoTessPosition.h:1028
bool isNotReferenced()
Definition: GeoTessPosition.h:1239
void setRadiusOutOfRangeAllowed(bool allowed)
Definition: GeoTessPosition.h:1196
double getDepthBottom()
Definition: GeoTessPosition.h:957
double getRadiusBottom()
Definition: GeoTessPosition.h:939
void set(double lat, double lon, double depth)
Definition: GeoTessPosition.h:559
double getLayerThickness(int layid)
Definition: GeoTessPosition.h:990
#define GEOTESS_EXP_IMP
Definition: CPPGlobals.h:71
void getWeights(map< int, double > &weights, double dkm)
Definition: GeoTessPosition.h:1127
void setRadius(double rad)
Definition: GeoTessPosition.h:692
void getCoefficients(map< int, double > &coefficients)
Definition: GeoTessPosition.h:871
double getRadiusTop()
Definition: GeoTessPosition.h:931
int getLayerId()
Definition: GeoTessPosition.h:1056
int getMaxTessLevel(int layid)
Definition: GeoTessPosition.h:905
void setMaxTessLevel(int layid, int maxTess)
Definition: GeoTessPosition.h:889