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
Profile.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 "ProfileType.h"
53 #include "Data.h"
54 #include "DataArray.h"
55 
56 // **** _BEGIN GEOTESS NAMESPACE_ **********************************************
57 
58 namespace geotess {
59 
60 // **** _FORWARD REFERENCES_ ***************************************************
61 
62 class InterpolatorType;
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 Profile* newProfile(const vector<float>& radii, vector<Data*>& data);
127 
128  static Profile* newProfile(const vector<float>& radii, vector<vector<double> >& data);
129  static Profile* newProfile(const vector<float>& radii, vector<vector<float> >& data);
130  static Profile* newProfile(const vector<float>& radii, vector<vector<LONG_INT> >& data);
131  static Profile* newProfile(const vector<float>& radii, vector<vector<int> >& data);
132  static Profile* newProfile(const vector<float>& radii, vector<vector<short> >& data);
133  static Profile* newProfile(const vector<float>& radii, vector<vector<byte> >& data);
134 
157  static Profile* newProfile(float* radii, const int& nRadii, Data** data, const int& nData);
158 
159  static Profile* newProfile(float* radii, const int& nRadii, double** values, const int& nNodes, const int& nAttributes)
160  {
161  if (nNodes < 1 && nRadii == 2)
162  return Profile::newProfile(radii, nRadii, NULL, 0);
163 
164  if (nNodes == 1)
165  {
166  Data* d[1];
167  d[0] = Data::getData(values[0], nAttributes);
168  return Profile::newProfile(radii, nRadii, d, nNodes);
169  }
170 
171  Data** d = new Data*[nNodes];
172  for (int i=0; i<nNodes; ++i) d[i] = Data::getData(values[i], nAttributes);
173  Profile* profile = Profile::newProfile(radii, nRadii, d, nNodes);
174  delete[] d;
175  return profile;
176  }
177 
178  static Profile* newProfile(float* radii, const int& nRadii, float** values, const int& nNodes, const int& nAttributes)
179  {
180  if (nNodes < 1 && nRadii == 2)
181  return Profile::newProfile(radii, nRadii, NULL, 0);
182 
183  if (nNodes == 1)
184  {
185  Data* d[1];
186  d[0] = Data::getData(values[0], nAttributes);
187  return Profile::newProfile(radii, nRadii, d, nNodes);
188  }
189 
190  Data** d = new Data*[nNodes];
191  for (int i=0; i<nNodes; ++i) d[i] = Data::getData(values[i], nAttributes);
192  Profile* profile = Profile::newProfile(radii, nRadii, d, nNodes);
193  delete[] d;
194  return profile;
195  }
196 
197  static Profile* newProfile(float* radii, const int& nRadii, LONG_INT** values, const int& nNodes, const int& nAttributes)
198  {
199  if (nNodes < 1 && nRadii == 2)
200  return Profile::newProfile(radii, nRadii, NULL, 0);
201 
202  if (nNodes == 1)
203  {
204  Data* d[1];
205  d[0] = Data::getData(values[0], nAttributes);
206  return Profile::newProfile(radii, nRadii, d, nNodes);
207  }
208 
209  Data** d = new Data*[nNodes];
210  for (int i=0; i<nNodes; ++i) d[i] = Data::getData(values[i], nAttributes);
211  Profile* profile = Profile::newProfile(radii, nRadii, d, nNodes);
212  delete[] d;
213  return profile;
214  }
215 
216  static Profile* newProfile(float* radii, const int& nRadii, int** values, const int& nNodes, const int& nAttributes)
217  {
218  if (nNodes < 1 && nRadii == 2)
219  return Profile::newProfile(radii, nRadii, NULL, 0);
220 
221  if (nNodes == 1)
222  {
223  Data* d[1];
224  d[0] = Data::getData(values[0], nAttributes);
225  return Profile::newProfile(radii, nRadii, d, nNodes);
226  }
227 
228  Data** d = new Data*[nNodes];
229  for (int i=0; i<nNodes; ++i) d[i] = Data::getData(values[i], nAttributes);
230  Profile* profile = Profile::newProfile(radii, nRadii, d, nNodes);
231  delete[] d;
232  return profile;
233  }
234 
235  static Profile* newProfile(float* radii, const int& nRadii, short** values, const int& nNodes, const int& nAttributes)
236  {
237  if (nNodes < 1 && nRadii == 2)
238  return Profile::newProfile(radii, nRadii, NULL, 0);
239 
240  if (nNodes == 1)
241  {
242  Data* d[1];
243  d[0] = Data::getData(values[0], nAttributes);
244  return Profile::newProfile(radii, nRadii, d, nNodes);
245  }
246 
247  Data** d = new Data*[nNodes];
248  for (int i=0; i<nNodes; ++i) d[i] = Data::getData(values[i], nAttributes);
249  Profile* profile = Profile::newProfile(radii, nRadii, d, nNodes);
250  delete[] d;
251  return profile;
252  }
253 
254  static Profile* newProfile(float* radii, const int& nRadii, byte** values, const int& nNodes, const int& nAttributes)
255  {
256  if (nNodes < 1 && nRadii == 2)
257  return Profile::newProfile(radii, nRadii, NULL, 0);
258 
259  if (nNodes == 1)
260  {
261  Data* d[1];
262  d[0] = Data::getData(values[0], nAttributes);
263  return Profile::newProfile(radii, nRadii, d, nNodes);
264  }
265 
266  Data** d = new Data*[nNodes];
267  for (int i=0; i<nNodes; ++i) d[i] = Data::getData(values[i], nAttributes);
268  Profile* profile = Profile::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(Profile); };
282 
286  static int class_count() { return aClassCount; };
287 
293  virtual const ProfileType& getType() const = ABSTRACT;
294 
299  virtual bool operator == (const Profile& p) const { return (getType() == p.getType()); }
300 
305  virtual double getValue(const InterpolatorType& 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 
373  virtual Data** getData() = ABSTRACT;
374 
379  virtual Data* getData(int i) = ABSTRACT;
380 
384  virtual const Data& getData(int i) const = ABSTRACT;
385 
392  virtual void setData(int index, Data* data) = ABSTRACT;
393 
400  virtual void setData(const vector<Data*>& inData) = ABSTRACT;
401 
407  virtual void setRadii(const vector<float>& newRadii) = ABSTRACT;
408 
412  virtual float getRadiusTop() const = ABSTRACT;
413 
417  virtual const Data& getDataTop() const = ABSTRACT;
418 
422  virtual Data* getDataTop() = ABSTRACT;
423 
427  virtual float getRadiusBottom() const = ABSTRACT;
428 
432  virtual const Data& getDataBottom() const = ABSTRACT;
433 
437  virtual Data* getDataBottom() = ABSTRACT;
438 
442  virtual int getNRadii() const = ABSTRACT;
443 
447  virtual int getNData() const = ABSTRACT;
448 
452  virtual float* getRadii() = ABSTRACT;
453 
457  double getThickness() { return getRadiusTop() - getRadiusBottom(); }
458 
464  int getRadiusIndex(double radius) const
465  { return getRadiusIndex(radius, -1); }
466 
478  virtual int getRadiusIndex(double radius, int jlo) const
479  {
480  // note that ProfileNPoint will override this method.
481  return 0;
482  }
483 
496  virtual double getInterpolationCoefficient(int i, double radius,
497  bool allowOutOfRange) const
498  {
499  if (!allowOutOfRange && (radius < getRadiusBottom() || radius > getRadiusTop()))
500  return NaN_DOUBLE;
501 
502  // note that ProfileNPoint will override this method.
503  return 1.;
504  }
505 
513  virtual int getPointIndex(int nodeIndex) const = ABSTRACT;
514 
519  virtual int findClosestRadiusIndex(double radius) const = ABSTRACT;
520 
522 
529  virtual void getWeights(map<int, double>& weights,
530  double dkm, double radius, double hcoefficient) const
531  {
532  // get the point index of the one-and-only node.
533 
534  int index = getPointIndex(0);
535 
536  // find the current weight of the point, if it exists.
537  // either set the weight of pointIndex (if it does not already exist),
538  // or add the new weight to the existing weight.
539 
540  map<int, double>::iterator it = weights.find(index);
541  if (it == weights.end())
542  weights[index] = dkm * hcoefficient;
543  else
544  it->second += dkm * hcoefficient;
545  }
546 
553  virtual void getCoefficients(map<int, double>& coefficients, double radius,
554  double horizontalCoefficient) const
555  {
556  // this works for Profile types Constant, Thin and Surface since they only have a single node
557  // in the profile. It does not work for ProfileNPoint and ProfileEmpty so they override this method.
558 
559  coefficients[getPointIndex(0)] = horizontalCoefficient;
560  }
561 
565  Profile() { ++aClassCount; };
566 
570  virtual ~Profile() { --aClassCount; };
571 
575  static Profile* newProfile(IFStreamBinary& ifs, GeoTessMetaData& gtmd);
576 
580  static Profile* newProfile(IFStreamAscii& ifs, GeoTessMetaData& gtmd);
581 
585  virtual void write(IFStreamBinary& ofs) = ABSTRACT;
586 
590  virtual void write(IFStreamAscii& ofs) = ABSTRACT;
591 
599  virtual void setPointIndex(int nodeIndex, int pointIndex) = ABSTRACT;
600 
608  virtual void resetPointIndices() = ABSTRACT;
609 
610  virtual void setInterpolationCoefficients(const InterpolatorType& interpType,
611  vector<int>& nodeIndexes, vector<double>& coefficients,
612  double& radius, bool& allowOutOfRange)
613  {
614  // this code works for Profiles constant, thin and surface.
615  // ProfileNPoint and ProfileEmpty will override it.
616  nodeIndexes.push_back(0);
617  if (!allowOutOfRange && (radius < getRadiusBottom() || radius > getRadiusTop()))
618  coefficients.push_back(NaN_DOUBLE);
619  else
620  coefficients.push_back(1.);
621  }
622 
626  virtual Profile* copy() = ABSTRACT;
627 
629 
630 }; // end class Profile
631 
632 } // end namespace geotess
633 
634 #endif // PROFILE_OBJECT_H