GeoTessCPP  2.2
Software to facilitate storage and retrieval of 3D information about the Earth.
GeoTessProfile.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 PROFILE_OBJECT_H
37 #define PROFILE_OBJECT_H
38 
39 // **** _SYSTEM INCLUDES_ ******************************************************
40 
41 #include <vector>
42 #include <iostream>
43 #include <string>
44 #include <fstream>
45 #include <map>
46 
47 // use standard library objects
48 using namespace std;
49 
50 // **** _LOCAL INCLUDES_ *******************************************************
51 
52 #include "GeoTessProfileType.h"
53 #include "GeoTessData.h"
54 #include "GeoTessDataArray.h"
55 
56 // **** _BEGIN GEOTESS NAMESPACE_ **********************************************
57 
58 namespace geotess {
59 
60 // **** _FORWARD REFERENCES_ ***************************************************
61 
62 class GeoTessInterpolatorType;
63 class GeoTessMetaData;
64 class IFStreamAscii;
65 class IFStreamBinary;
66 
67 
68 // **** _CLASS DEFINITION_ *****************************************************
69 
97 {
98 private:
99 
103  static int aClassCount;
104 
105 public:
106 
126  static GeoTessProfile* newProfile(const vector<float>& radii, vector<GeoTessData*>& data);
127 
128  static GeoTessProfile* newProfile(const vector<float>& radii, vector<vector<double> >& data);
129  static GeoTessProfile* newProfile(const vector<float>& radii, vector<vector<float> >& data);
130  static GeoTessProfile* newProfile(const vector<float>& radii, vector<vector<LONG_INT> >& data);
131  static GeoTessProfile* newProfile(const vector<float>& radii, vector<vector<int> >& data);
132  static GeoTessProfile* newProfile(const vector<float>& radii, vector<vector<short> >& data);
133  static GeoTessProfile* newProfile(const vector<float>& radii, vector<vector<byte> >& data);
134 
157  static GeoTessProfile* newProfile(float* radii, const int& nRadii, GeoTessData** data, const int& nData);
158 
159  static GeoTessProfile* newProfile(float* radii, const int& nRadii, double** values, const int& nNodes, const int& nAttributes)
160  {
161  if (nNodes < 1 && nRadii == 2)
162  return GeoTessProfile::newProfile(radii, nRadii, NULL, 0);
163 
164  if (nNodes == 1)
165  {
166  GeoTessData* d[1];
167  d[0] = GeoTessData::getData(values[0], nAttributes);
168  return GeoTessProfile::newProfile(radii, nRadii, d, nNodes);
169  }
170 
171  GeoTessData** d = new GeoTessData*[nNodes];
172  for (int i=0; i<nNodes; ++i) d[i] = GeoTessData::getData(values[i], nAttributes);
173  GeoTessProfile* profile = GeoTessProfile::newProfile(radii, nRadii, d, nNodes);
174  delete[] d;
175  return profile;
176  }
177 
178  static GeoTessProfile* newProfile(float* radii, const int& nRadii, float** values, const int& nNodes, const int& nAttributes)
179  {
180  if (nNodes < 1 && nRadii == 2)
181  return GeoTessProfile::newProfile(radii, nRadii, NULL, 0);
182 
183  if (nNodes == 1)
184  {
185  GeoTessData* d[1];
186  d[0] = GeoTessData::getData(values[0], nAttributes);
187  return GeoTessProfile::newProfile(radii, nRadii, d, nNodes);
188  }
189 
190  GeoTessData** d = new GeoTessData*[nNodes];
191  for (int i=0; i<nNodes; ++i) d[i] = GeoTessData::getData(values[i], nAttributes);
192  GeoTessProfile* profile = GeoTessProfile::newProfile(radii, nRadii, d, nNodes);
193  delete[] d;
194  return profile;
195  }
196 
197  static GeoTessProfile* newProfile(float* radii, const int& nRadii, LONG_INT** values, const int& nNodes, const int& nAttributes)
198  {
199  if (nNodes < 1 && nRadii == 2)
200  return GeoTessProfile::newProfile(radii, nRadii, NULL, 0);
201 
202  if (nNodes == 1)
203  {
204  GeoTessData* d[1];
205  d[0] = GeoTessData::getData(values[0], nAttributes);
206  return GeoTessProfile::newProfile(radii, nRadii, d, nNodes);
207  }
208 
209  GeoTessData** d = new GeoTessData*[nNodes];
210  for (int i=0; i<nNodes; ++i) d[i] = GeoTessData::getData(values[i], nAttributes);
211  GeoTessProfile* profile = GeoTessProfile::newProfile(radii, nRadii, d, nNodes);
212  delete[] d;
213  return profile;
214  }
215 
216  static GeoTessProfile* newProfile(float* radii, const int& nRadii, int** values, const int& nNodes, const int& nAttributes)
217  {
218  if (nNodes < 1 && nRadii == 2)
219  return GeoTessProfile::newProfile(radii, nRadii, NULL, 0);
220 
221  if (nNodes == 1)
222  {
223  GeoTessData* d[1];
224  d[0] = GeoTessData::getData(values[0], nAttributes);
225  return GeoTessProfile::newProfile(radii, nRadii, d, nNodes);
226  }
227 
228  GeoTessData** d = new GeoTessData*[nNodes];
229  for (int i=0; i<nNodes; ++i) d[i] = GeoTessData::getData(values[i], nAttributes);
230  GeoTessProfile* profile = GeoTessProfile::newProfile(radii, nRadii, d, nNodes);
231  delete[] d;
232  return profile;
233  }
234 
235  static GeoTessProfile* newProfile(float* radii, const int& nRadii, short** values, const int& nNodes, const int& nAttributes)
236  {
237  if (nNodes < 1 && nRadii == 2)
238  return GeoTessProfile::newProfile(radii, nRadii, NULL, 0);
239 
240  if (nNodes == 1)
241  {
242  GeoTessData* d[1];
243  d[0] = GeoTessData::getData(values[0], nAttributes);
244  return GeoTessProfile::newProfile(radii, nRadii, d, nNodes);
245  }
246 
247  GeoTessData** d = new GeoTessData*[nNodes];
248  for (int i=0; i<nNodes; ++i) d[i] = GeoTessData::getData(values[i], nAttributes);
249  GeoTessProfile* profile = GeoTessProfile::newProfile(radii, nRadii, d, nNodes);
250  delete[] d;
251  return profile;
252  }
253 
254  static GeoTessProfile* newProfile(float* radii, const int& nRadii, byte** values, const int& nNodes, const int& nAttributes)
255  {
256  if (nNodes < 1 && nRadii == 2)
257  return GeoTessProfile::newProfile(radii, nRadii, NULL, 0);
258 
259  if (nNodes == 1)
260  {
261  GeoTessData* d[1];
262  d[0] = GeoTessData::getData(values[0], nAttributes);
263  return GeoTessProfile::newProfile(radii, nRadii, d, nNodes);
264  }
265 
266  GeoTessData** d = new GeoTessData*[nNodes];
267  for (int i=0; i<nNodes; ++i) d[i] = GeoTessData::getData(values[i], nAttributes);
268  GeoTessProfile* profile = GeoTessProfile::newProfile(radii, nRadii, d, nNodes);
269  delete[] d;
270  return profile;
271  }
272 
276  static string class_name() { return "Profile"; };
277 
281  virtual int class_size() const { return (int) sizeof(GeoTessProfile); };
282 
283  virtual LONG_INT getMemory() = ABSTRACT;
284 
288  static int class_count() { return aClassCount; };
289 
295  virtual const GeoTessProfileType& getType() const = ABSTRACT;
296 
301  virtual bool operator == (const GeoTessProfile& p) const { return (getType() == p.getType()); }
302 
307  virtual double getValue(const GeoTessInterpolatorType& rInterpType,
308  int attributeIndex, double radius, bool allowRadiusOutOfRange) const = ABSTRACT;
309 
314  double getValue(const vector<int>& nodeIds,
315  const vector<double>& coefficients, int attributeIndex) const
316  {
317  double value = 0;
318  for (int i=0; i<(int)nodeIds.size(); ++i)
319  value += getValue(attributeIndex, nodeIds[i])*coefficients[i];
320  return value;
321  }
322 
331  virtual double getValue(int attributeIndex, int nodeIndex) const = ABSTRACT;
332 
343  virtual bool isNaN(int nodeIndex, int attributeIndex) = ABSTRACT;
344 
351  virtual double getValueTop(int attributeIndex) const = ABSTRACT;
352 
359  virtual double getValueBottom(int attributeIndex) const
360  {
361  return getValue(attributeIndex, 0);
362  }
363 
368  virtual float getRadius(int i) const = ABSTRACT;
369 
373  virtual int getNRadii() const = ABSTRACT;
374 
378  virtual int getNData() const = ABSTRACT;
379 
384  virtual float* getRadii() = ABSTRACT;
385 
391  virtual GeoTessData** getData() = ABSTRACT;
392 
397  virtual GeoTessData* getData(int i) = ABSTRACT;
398 
402  virtual const GeoTessData& getData(int i) const = ABSTRACT;
403 
410  virtual void setData(int index, GeoTessData* data) = ABSTRACT;
411 
418  virtual void setData(const vector<GeoTessData*>& inData) = ABSTRACT;
419 
425  virtual void setRadii(const vector<float>& newRadii) = ABSTRACT;
426 
430  virtual void setRadius(int index, float radius) = ABSTRACT;
431 
435  virtual float getRadiusTop() const = ABSTRACT;
436 
440  virtual const GeoTessData& getDataTop() const = ABSTRACT;
441 
445  virtual GeoTessData* getDataTop() = ABSTRACT;
446 
450  virtual float getRadiusBottom() const = ABSTRACT;
451 
455  virtual const GeoTessData& getDataBottom() const = ABSTRACT;
456 
460  virtual GeoTessData* getDataBottom() = ABSTRACT;
461 
465  double getThickness() { return getRadiusTop() - getRadiusBottom(); }
466 
472  int getRadiusIndex(double radius) const
473  { return getRadiusIndex(radius, -1); }
474 
486  virtual int getRadiusIndex(double radius, int jlo) const
487  {
488  // note that ProfileNPoint will override this method.
489  return 0;
490  }
491 
504  virtual double getInterpolationCoefficient(int i, double radius,
505  bool allowOutOfRange) const
506  {
507  if (!allowOutOfRange && (radius < getRadiusBottom() || radius > getRadiusTop()))
508  return NaN_DOUBLE;
509 
510  // note that ProfileNPoint will override this method.
511  return 1.;
512  }
513 
521  virtual int getPointIndex(int nodeIndex) const = ABSTRACT;
522 
527  virtual int findClosestRadiusIndex(double radius) const = ABSTRACT;
528 
530 
537  virtual void getWeights(map<int, double>& weights,
538  double dkm, double radius, double hcoefficient) const
539  {
540  // get the point index of the one-and-only node.
541 
542  int index = getPointIndex(0);
543 
544  // find the current weight of the point, if it exists.
545  // either set the weight of pointIndex (if it does not already exist),
546  // or add the new weight to the existing weight.
547 
548  map<int, double>::iterator it = weights.find(index);
549  if (it == weights.end())
550  weights[index] = dkm * hcoefficient;
551  else
552  it->second += dkm * hcoefficient;
553  }
554 
561  virtual void getCoefficients(map<int, double>& coefficients, double radius,
562  double horizontalCoefficient) const
563  {
564  // this works for Profile types Constant, Thin and Surface since they only have a single node
565  // in the profile. It does not work for ProfileNPoint and ProfileEmpty so they override this method.
566 
567  coefficients[getPointIndex(0)] = horizontalCoefficient;
568  }
569 
573  GeoTessProfile() { ++aClassCount; };
574 
578  virtual ~GeoTessProfile() { --aClassCount; };
579 
583  static GeoTessProfile* newProfile(IFStreamBinary& ifs, GeoTessMetaData& gtmd);
584 
588  static GeoTessProfile* newProfile(IFStreamAscii& ifs, GeoTessMetaData& gtmd);
589 
593  virtual void write(IFStreamBinary& ofs) = ABSTRACT;
594 
598  virtual void write(IFStreamAscii& ofs) = ABSTRACT;
599 
607  virtual void setPointIndex(int nodeIndex, int pointIndex) = ABSTRACT;
608 
616  virtual void resetPointIndices() = ABSTRACT;
617 
618  virtual void setInterpolationCoefficients(const GeoTessInterpolatorType& interpType,
619  vector<int>& nodeIndexes, vector<double>& coefficients,
620  double& radius, bool& allowOutOfRange)
621  {
622  // this code works for Profiles constant, thin and surface.
623  // ProfileNPoint and ProfileEmpty will override it.
624  nodeIndexes.push_back(0);
625  if (!allowOutOfRange && (radius < getRadiusBottom() || radius > getRadiusTop()))
626  coefficients.push_back(NaN_DOUBLE);
627  else
628  coefficients.push_back(1.);
629  }
630 
634  virtual GeoTessProfile* copy() = ABSTRACT;
635 
637 
638 }; // end class Profile
639 
640 } // end namespace geotess
641 
642 #endif // PROFILE_OBJECT_H
static GeoTessProfile * newProfile(float *radii, const int &nRadii, byte **values, const int &nNodes, const int &nAttributes)
Definition: GeoTessProfile.h:254
double getValue(const vector< int > &nodeIds, const vector< double > &coefficients, int attributeIndex) const
Retrieve the value of the specified attribute interpolated at the specified radius.
Definition: GeoTessProfile.h:314
Definition: ArrayReuse.h:55
Enumeration of the interpolation algorithms supported by GeoTess including LINEAR, NATURAL_NEIGHBOR and CUBIC_SPLINE.
Definition: GeoTessInterpolatorType.h:71
virtual double getValueBottom(int attributeIndex) const
Retrieve the value of the specified attribute at the bottom of the layer.
Definition: GeoTessProfile.h:359
Enumeration of the valid Profile types, including EMPTY, THIN, CONSTANT, NPOINT and SURFACE...
Definition: GeoTessProfileType.h:69
static int class_count()
Returns the class instance count.
Definition: GeoTessProfile.h:288
virtual const GeoTessProfileType & getType() const
One of EMPTY, THIN, CONSTANT, NPOINT, SURFACE.
double getThickness()
Return the thickness of the layer in km.
Definition: GeoTessProfile.h:465
virtual double getInterpolationCoefficient(int i, double radius, bool allowOutOfRange) const
find interpolation coefficient.
Definition: GeoTessProfile.h:504
static GeoTessProfile * newProfile(float *radii, const int &nRadii, float **values, const int &nNodes, const int &nAttributes)
Definition: GeoTessProfile.h:178
virtual int getRadiusIndex(double radius, int jlo) const
Find index i such that radius is >= radii[i] and < radii[i+1].
Definition: GeoTessProfile.h:486
#define byte
signed-byte typedef
Definition: CPPGlobals.h:94
#define ABSTRACT
Global constant used to make pure virtual functions readable.
Definition: CPPGlobals.h:78
#define LONG_INT
Definition: CPPGlobals.h:111
Abstract class that manages the radii and data values that span a single layer associated with a sing...
Definition: GeoTessProfile.h:96
Abstract base class that manages the data values attached to a single grid point. ...
Definition: GeoTessData.h:75
virtual int class_size() const
Returns the class size.
Definition: GeoTessProfile.h:281
static GeoTessProfile * newProfile(float *radii, const int &nRadii, short **values, const int &nNodes, const int &nAttributes)
Definition: GeoTessProfile.h:235
static GeoTessProfile * newProfile(float *radii, const int &nRadii, double **values, const int &nNodes, const int &nAttributes)
Definition: GeoTessProfile.h:159
#define GEOTESS_EXP_IMP
Definition: CPPGlobals.h:71
static GeoTessProfile * newProfile(float *radii, const int &nRadii, LONG_INT **values, const int &nNodes, const int &nAttributes)
Definition: GeoTessProfile.h:197
int getRadiusIndex(double radius) const
Find index i such that radius is >= radii[i] and < radii[i+1].
Definition: GeoTessProfile.h:472
static GeoTessProfile * newProfile(float *radii, const int &nRadii, int **values, const int &nNodes, const int &nAttributes)
Definition: GeoTessProfile.h:216
static string class_name()
Returns the class name.
Definition: GeoTessProfile.h:276