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
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 
286  static int class_count() { return aClassCount; };
287 
293  virtual const GeoTessProfileType& getType() const = ABSTRACT;
294 
299  virtual bool operator == (const GeoTessProfile& p) const { return (getType() == p.getType()); }
300 
305  virtual double getValue(const GeoTessInterpolatorType& rInterpType,
306  int attributeIndex, double radius, bool allowRadiusOutOfRange) const = ABSTRACT;
307 
312  double getValue(const vector<int>& nodeIds,
313  const vector<double>& coefficients, int attributeIndex) const
314  {
315  double value = 0;
316  for (int i=0; i<(int)nodeIds.size(); ++i)
317  value += getValue(attributeIndex, nodeIds[i])*coefficients[i];
318  return value;
319  }
320 
329  virtual double getValue(int attributeIndex, int nodeIndex) const = ABSTRACT;
330 
341  virtual bool isNaN(int nodeIndex, int attributeIndex) = ABSTRACT;
342 
349  virtual double getValueTop(int attributeIndex) const = ABSTRACT;
350 
357  virtual double getValueBottom(int attributeIndex) const
358  {
359  return getValue(attributeIndex, 0);
360  }
361 
366  virtual float getRadius(int i) const = ABSTRACT;
367 
371  virtual int getNRadii() const = ABSTRACT;
372 
376  virtual int getNData() const = ABSTRACT;
377 
382  virtual float* getRadii() = ABSTRACT;
383 
389  virtual GeoTessData** getData() = ABSTRACT;
390 
395  virtual GeoTessData* getData(int i) = ABSTRACT;
396 
400  virtual const GeoTessData& getData(int i) const = ABSTRACT;
401 
408  virtual void setData(int index, GeoTessData* data) = ABSTRACT;
409 
416  virtual void setData(const vector<GeoTessData*>& inData) = ABSTRACT;
417 
423  virtual void setRadii(const vector<float>& newRadii) = ABSTRACT;
424 
428  virtual float getRadiusTop() const = ABSTRACT;
429 
433  virtual const GeoTessData& getDataTop() const = ABSTRACT;
434 
438  virtual GeoTessData* getDataTop() = ABSTRACT;
439 
443  virtual float getRadiusBottom() const = ABSTRACT;
444 
448  virtual const GeoTessData& getDataBottom() const = ABSTRACT;
449 
453  virtual GeoTessData* getDataBottom() = ABSTRACT;
454 
458  double getThickness() { return getRadiusTop() - getRadiusBottom(); }
459 
465  int getRadiusIndex(double radius) const
466  { return getRadiusIndex(radius, -1); }
467 
479  virtual int getRadiusIndex(double radius, int jlo) const
480  {
481  // note that ProfileNPoint will override this method.
482  return 0;
483  }
484 
497  virtual double getInterpolationCoefficient(int i, double radius,
498  bool allowOutOfRange) const
499  {
500  if (!allowOutOfRange && (radius < getRadiusBottom() || radius > getRadiusTop()))
501  return NaN_DOUBLE;
502 
503  // note that ProfileNPoint will override this method.
504  return 1.;
505  }
506 
514  virtual int getPointIndex(int nodeIndex) const = ABSTRACT;
515 
520  virtual int findClosestRadiusIndex(double radius) const = ABSTRACT;
521 
523 
530  virtual void getWeights(map<int, double>& weights,
531  double dkm, double radius, double hcoefficient) const
532  {
533  // get the point index of the one-and-only node.
534 
535  int index = getPointIndex(0);
536 
537  // find the current weight of the point, if it exists.
538  // either set the weight of pointIndex (if it does not already exist),
539  // or add the new weight to the existing weight.
540 
541  map<int, double>::iterator it = weights.find(index);
542  if (it == weights.end())
543  weights[index] = dkm * hcoefficient;
544  else
545  it->second += dkm * hcoefficient;
546  }
547 
554  virtual void getCoefficients(map<int, double>& coefficients, double radius,
555  double horizontalCoefficient) const
556  {
557  // this works for Profile types Constant, Thin and Surface since they only have a single node
558  // in the profile. It does not work for ProfileNPoint and ProfileEmpty so they override this method.
559 
560  coefficients[getPointIndex(0)] = horizontalCoefficient;
561  }
562 
566  GeoTessProfile() { ++aClassCount; };
567 
571  virtual ~GeoTessProfile() { --aClassCount; };
572 
576  static GeoTessProfile* newProfile(IFStreamBinary& ifs, GeoTessMetaData& gtmd);
577 
581  static GeoTessProfile* newProfile(IFStreamAscii& ifs, GeoTessMetaData& gtmd);
582 
586  virtual void write(IFStreamBinary& ofs) = ABSTRACT;
587 
591  virtual void write(IFStreamAscii& ofs) = ABSTRACT;
592 
600  virtual void setPointIndex(int nodeIndex, int pointIndex) = ABSTRACT;
601 
609  virtual void resetPointIndices() = ABSTRACT;
610 
611  virtual void setInterpolationCoefficients(const GeoTessInterpolatorType& interpType,
612  vector<int>& nodeIndexes, vector<double>& coefficients,
613  double& radius, bool& allowOutOfRange)
614  {
615  // this code works for Profiles constant, thin and surface.
616  // ProfileNPoint and ProfileEmpty will override it.
617  nodeIndexes.push_back(0);
618  if (!allowOutOfRange && (radius < getRadiusBottom() || radius > getRadiusTop()))
619  coefficients.push_back(NaN_DOUBLE);
620  else
621  coefficients.push_back(1.);
622  }
623 
627  virtual GeoTessProfile* copy() = ABSTRACT;
628 
630 
631 }; // end class Profile
632 
633 } // end namespace geotess
634 
635 #endif // PROFILE_OBJECT_H