GeoTessCPP  2.0.0
Software to facilitate storage and retrieval of 3D information about the Earth.
 All Classes Namespaces Files Functions Variables Typedefs Friends Defines
include/Profile.h
Go to the documentation of this file.
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 PROFILE_OBJECT_H
00037 #define PROFILE_OBJECT_H
00038 
00039 // **** _SYSTEM INCLUDES_ ******************************************************
00040 
00041 #include <vector>
00042 #include <iostream>
00043 #include <string>
00044 #include <fstream>
00045 #include <map>
00046 
00047 // use standard library objects
00048 using namespace std;
00049 
00050 // **** _LOCAL INCLUDES_ *******************************************************
00051 
00052 #include "ProfileType.h"
00053 #include "Data.h"
00054 #include "DataArray.h"
00055 
00056 // **** _BEGIN GEOTESS NAMESPACE_ **********************************************
00057 
00058 namespace geotess {
00059 
00060 // **** _FORWARD REFERENCES_ ***************************************************
00061 
00062 class InterpolatorType;
00063 class GeoTessMetaData;
00064 class IFStreamAscii;
00065 class IFStreamBinary;
00066 
00067 
00068 // **** _CLASS DEFINITION_ *****************************************************
00069 
00096 class GEOTESS_EXP_IMP Profile
00097 {
00098 private:
00099 
00103         static int                                              aClassCount;
00104 
00105 public:
00106 
00126         static Profile* newProfile(const vector<float>& radii, vector<Data*>& data);
00127 
00128         static Profile* newProfile(const vector<float>& radii, vector<vector<double> >& data);
00129         static Profile* newProfile(const vector<float>& radii, vector<vector<float> >& data);
00130         static Profile* newProfile(const vector<float>& radii, vector<vector<LONG_INT> >& data);
00131         static Profile* newProfile(const vector<float>& radii, vector<vector<int> >& data);
00132         static Profile* newProfile(const vector<float>& radii, vector<vector<short> >& data);
00133         static Profile* newProfile(const vector<float>& radii, vector<vector<byte> >& data);
00134 
00157         static Profile* newProfile(float* radii, const int& nRadii, Data** data, const int& nData);
00158 
00159         static Profile* newProfile(float* radii, const int& nRadii, double** values, const int& nNodes, const int& nAttributes)
00160         {
00161                 if (nNodes < 1 && nRadii == 2)
00162                         return Profile::newProfile(radii, nRadii, NULL, 0);
00163 
00164                 if (nNodes == 1)
00165                 {
00166                         Data* d[1];
00167                         d[0] = Data::getData(values[0], nAttributes);
00168                         return Profile::newProfile(radii, nRadii, d, nNodes);
00169                 }
00170 
00171                 Data** d = new Data*[nNodes];
00172                 for (int i=0; i<nNodes; ++i) d[i] = Data::getData(values[i], nAttributes);
00173                 Profile* profile = Profile::newProfile(radii, nRadii, d, nNodes);
00174                 delete[] d;
00175                 return profile;
00176         }
00177 
00178         static Profile* newProfile(float* radii, const int& nRadii, float** values, const int& nNodes, const int& nAttributes)
00179         {
00180                 if (nNodes < 1 && nRadii == 2)
00181                         return Profile::newProfile(radii, nRadii, NULL, 0);
00182 
00183                 if (nNodes == 1)
00184                 {
00185                         Data* d[1];
00186                         d[0] = Data::getData(values[0], nAttributes);
00187                         return Profile::newProfile(radii, nRadii, d, nNodes);
00188                 }
00189 
00190                 Data** d = new Data*[nNodes];
00191                 for (int i=0; i<nNodes; ++i) d[i] = Data::getData(values[i], nAttributes);
00192                 Profile* profile = Profile::newProfile(radii, nRadii, d, nNodes);
00193                 delete[] d;
00194                 return profile;
00195         }
00196 
00197         static Profile* newProfile(float* radii, const int& nRadii, LONG_INT** values, const int& nNodes, const int& nAttributes)
00198         {
00199                 if (nNodes < 1 && nRadii == 2)
00200                         return Profile::newProfile(radii, nRadii, NULL, 0);
00201 
00202                 if (nNodes == 1)
00203                 {
00204                         Data* d[1];
00205                         d[0] = Data::getData(values[0], nAttributes);
00206                         return Profile::newProfile(radii, nRadii, d, nNodes);
00207                 }
00208 
00209                 Data** d = new Data*[nNodes];
00210                 for (int i=0; i<nNodes; ++i) d[i] = Data::getData(values[i], nAttributes);
00211                 Profile* profile = Profile::newProfile(radii, nRadii, d, nNodes);
00212                 delete[] d;
00213                 return profile;
00214         }
00215 
00216         static Profile* newProfile(float* radii, const int& nRadii, int** values, const int& nNodes, const int& nAttributes)
00217         {
00218                 if (nNodes < 1 && nRadii == 2)
00219                         return Profile::newProfile(radii, nRadii, NULL, 0);
00220 
00221                 if (nNodes == 1)
00222                 {
00223                         Data* d[1];
00224                         d[0] = Data::getData(values[0], nAttributes);
00225                         return Profile::newProfile(radii, nRadii, d, nNodes);
00226                 }
00227 
00228                 Data** d = new Data*[nNodes];
00229                 for (int i=0; i<nNodes; ++i) d[i] = Data::getData(values[i], nAttributes);
00230                 Profile* profile = Profile::newProfile(radii, nRadii, d, nNodes);
00231                 delete[] d;
00232                 return profile;
00233         }
00234 
00235         static Profile* newProfile(float* radii, const int& nRadii, short** values, const int& nNodes, const int& nAttributes)
00236         {
00237                 if (nNodes < 1 && nRadii == 2)
00238                         return Profile::newProfile(radii, nRadii, NULL, 0);
00239 
00240                 if (nNodes == 1)
00241                 {
00242                         Data* d[1];
00243                         d[0] = Data::getData(values[0], nAttributes);
00244                         return Profile::newProfile(radii, nRadii, d, nNodes);
00245                 }
00246 
00247                 Data** d = new Data*[nNodes];
00248                 for (int i=0; i<nNodes; ++i) d[i] = Data::getData(values[i], nAttributes);
00249                 Profile* profile = Profile::newProfile(radii, nRadii, d, nNodes);
00250                 delete[] d;
00251                 return profile;
00252         }
00253 
00254         static Profile* newProfile(float* radii, const int& nRadii, byte** values, const int& nNodes, const int& nAttributes)
00255         {
00256                 if (nNodes < 1 && nRadii == 2)
00257                         return Profile::newProfile(radii, nRadii, NULL, 0);
00258 
00259                 if (nNodes == 1)
00260                 {
00261                         Data* d[1];
00262                         d[0] = Data::getData(values[0], nAttributes);
00263                         return Profile::newProfile(radii, nRadii, d, nNodes);
00264                 }
00265 
00266                 Data** d = new Data*[nNodes];
00267                 for (int i=0; i<nNodes; ++i) d[i] = Data::getData(values[i], nAttributes);
00268                 Profile* profile = Profile::newProfile(radii, nRadii, d, nNodes);
00269                 delete[] d;
00270                 return profile;
00271         }
00272 
00276         static  string                          class_name() { return "Profile"; };
00277 
00281         virtual int                                     class_size() const { return (int) sizeof(Profile); };
00282 
00286         static  int                                     class_count() { return aClassCount; };
00287 
00293         virtual const ProfileType&      getType() const = ABSTRACT;
00294 
00299         virtual bool operator == (const Profile& p) const { return (getType() == p.getType()); }
00300 
00305         virtual double                          getValue(const InterpolatorType& rInterpType,
00306                         int attributeIndex, double radius, bool allowRadiusOutOfRange) const   = ABSTRACT;
00307 
00312         double  getValue(const vector<int>& nodeIds,
00313                         const vector<double>& coefficients, int attributeIndex) const
00314         {
00315                 double value = 0;
00316                 for (int i=0; i<(int)nodeIds.size(); ++i)
00317                         value += getValue(attributeIndex, nodeIds[i])*coefficients[i];
00318                 return value;
00319         }
00320 
00329         virtual double getValue(int attributeIndex, int nodeIndex) const  = ABSTRACT;
00330 
00341         virtual bool isNaN(int nodeIndex, int attributeIndex) = ABSTRACT;
00342 
00349         virtual double                    getValueTop(int attributeIndex) const = ABSTRACT;
00350 
00357         virtual double                    getValueBottom(int attributeIndex) const
00358         {
00359                 return getValue(attributeIndex, 0);
00360         }
00361 
00366         virtual float                           getRadius(int i) const = ABSTRACT;
00367 
00371         virtual int                                     getNRadii() const = ABSTRACT;
00372 
00376         virtual int                                     getNData() const = ABSTRACT;
00377 
00382         virtual float*                          getRadii() = ABSTRACT;
00383 
00389         virtual Data**                          getData() = ABSTRACT;
00390 
00395         virtual Data*                           getData(int i) = ABSTRACT;
00396 
00400         virtual const Data&                     getData(int i) const = ABSTRACT;
00401 
00408         virtual void                            setData(int index, Data* data) = ABSTRACT;
00409 
00416         virtual void                            setData(const vector<Data*>& inData) = ABSTRACT;
00417 
00423         virtual void                            setRadii(const vector<float>& newRadii) = ABSTRACT;
00424 
00428         virtual float                           getRadiusTop() const = ABSTRACT;
00429 
00433         virtual const Data&                     getDataTop() const = ABSTRACT;
00434 
00438         virtual Data*                           getDataTop() = ABSTRACT;
00439 
00443         virtual float                           getRadiusBottom() const = ABSTRACT;
00444 
00448         virtual const Data&                     getDataBottom() const = ABSTRACT;
00449 
00453         virtual Data*                           getDataBottom() = ABSTRACT;
00454 
00458         double                                          getThickness() { return getRadiusTop() - getRadiusBottom(); }
00459 
00465         int                                                     getRadiusIndex(double radius) const
00466         { return getRadiusIndex(radius, -1); }
00467 
00479         virtual int                                     getRadiusIndex(double radius, int jlo) const
00480         {
00481                 // note that ProfileNPoint will override this method.
00482                 return 0;
00483         }
00484 
00497         virtual double getInterpolationCoefficient(int i, double radius,
00498                         bool allowOutOfRange) const
00499         {
00500                 if (!allowOutOfRange && (radius < getRadiusBottom() || radius > getRadiusTop()))
00501                         return NaN_DOUBLE;
00502 
00503                 // note that ProfileNPoint will override this method.
00504                 return 1.;
00505         }
00506 
00514         virtual int                                     getPointIndex(int nodeIndex) const = ABSTRACT;
00515 
00520         virtual int                                     findClosestRadiusIndex(double radius) const = ABSTRACT;
00521 
00523 
00530         virtual void                            getWeights(map<int, double>& weights,
00531                         double dkm, double radius, double hcoefficient) const
00532         {
00533                 // get the point index of the one-and-only node.
00534 
00535                 int index = getPointIndex(0);
00536 
00537                 // find the current weight of the point, if it exists.
00538                 // either set the weight of pointIndex (if it does not already exist),
00539                 // or add the new weight to the existing weight.
00540 
00541                 map<int, double>::iterator it = weights.find(index);
00542                 if (it == weights.end())
00543                         weights[index] = dkm * hcoefficient;
00544                 else
00545                         it->second += dkm * hcoefficient;
00546         }
00547 
00554         virtual void                            getCoefficients(map<int, double>& coefficients, double radius,
00555                         double horizontalCoefficient) const
00556         {
00557                 // this works for Profile types Constant, Thin and Surface since they only have a single node
00558                 // in the profile.  It does not work for ProfileNPoint and ProfileEmpty so they override this method.
00559 
00560                 coefficients[getPointIndex(0)] = horizontalCoefficient;
00561         }
00562 
00566         Profile() { ++aClassCount; };
00567 
00571         virtual                                         ~Profile() { --aClassCount; };
00572 
00576         static Profile*                         newProfile(IFStreamBinary& ifs, GeoTessMetaData& gtmd);
00577 
00581         static Profile*                         newProfile(IFStreamAscii& ifs, GeoTessMetaData& gtmd);
00582 
00586         virtual void                                    write(IFStreamBinary& ofs) = ABSTRACT;
00587 
00591         virtual void                                    write(IFStreamAscii& ofs) = ABSTRACT;
00592 
00600         virtual void                                    setPointIndex(int nodeIndex, int pointIndex) = ABSTRACT;
00601 
00609         virtual void resetPointIndices() = ABSTRACT;
00610 
00611         virtual void setInterpolationCoefficients(const InterpolatorType& interpType,
00612                         vector<int>& nodeIndexes, vector<double>& coefficients,
00613                         double& radius, bool& allowOutOfRange)
00614         {
00615                 // this code works for Profiles constant, thin and surface.
00616                 // ProfileNPoint and ProfileEmpty will override it.
00617                 nodeIndexes.push_back(0);
00618                 if (!allowOutOfRange && (radius < getRadiusBottom() || radius > getRadiusTop()))
00619                         coefficients.push_back(NaN_DOUBLE);
00620                 else
00621                         coefficients.push_back(1.);
00622         }
00623 
00627         virtual Profile*      copy() = ABSTRACT;
00628 
00630 
00631 }; // end class Profile
00632 
00633 } // end namespace geotess
00634 
00635 #endif  // PROFILE_OBJECT_H