GeoTessCPP
2.0.0
Software to facilitate storage and retrieval of 3D information about the Earth.
|
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 "GeoTessProfileType.h" 00053 #include "GeoTessData.h" 00054 #include "GeoTessDataArray.h" 00055 00056 // **** _BEGIN GEOTESS NAMESPACE_ ********************************************** 00057 00058 namespace geotess { 00059 00060 // **** _FORWARD REFERENCES_ *************************************************** 00061 00062 class GeoTessInterpolatorType; 00063 class GeoTessMetaData; 00064 class IFStreamAscii; 00065 class IFStreamBinary; 00066 00067 00068 // **** _CLASS DEFINITION_ ***************************************************** 00069 00096 class GEOTESS_EXP_IMP GeoTessProfile 00097 { 00098 private: 00099 00103 static int aClassCount; 00104 00105 public: 00106 00126 static GeoTessProfile* newProfile(const vector<float>& radii, vector<GeoTessData*>& data); 00127 00128 static GeoTessProfile* newProfile(const vector<float>& radii, vector<vector<double> >& data); 00129 static GeoTessProfile* newProfile(const vector<float>& radii, vector<vector<float> >& data); 00130 static GeoTessProfile* newProfile(const vector<float>& radii, vector<vector<LONG_INT> >& data); 00131 static GeoTessProfile* newProfile(const vector<float>& radii, vector<vector<int> >& data); 00132 static GeoTessProfile* newProfile(const vector<float>& radii, vector<vector<short> >& data); 00133 static GeoTessProfile* newProfile(const vector<float>& radii, vector<vector<byte> >& data); 00134 00157 static GeoTessProfile* newProfile(float* radii, const int& nRadii, GeoTessData** data, const int& nData); 00158 00159 static GeoTessProfile* newProfile(float* radii, const int& nRadii, double** values, const int& nNodes, const int& nAttributes) 00160 { 00161 if (nNodes < 1 && nRadii == 2) 00162 return GeoTessProfile::newProfile(radii, nRadii, NULL, 0); 00163 00164 if (nNodes == 1) 00165 { 00166 GeoTessData* d[1]; 00167 d[0] = GeoTessData::getData(values[0], nAttributes); 00168 return GeoTessProfile::newProfile(radii, nRadii, d, nNodes); 00169 } 00170 00171 GeoTessData** d = new GeoTessData*[nNodes]; 00172 for (int i=0; i<nNodes; ++i) d[i] = GeoTessData::getData(values[i], nAttributes); 00173 GeoTessProfile* profile = GeoTessProfile::newProfile(radii, nRadii, d, nNodes); 00174 delete[] d; 00175 return profile; 00176 } 00177 00178 static GeoTessProfile* newProfile(float* radii, const int& nRadii, float** values, const int& nNodes, const int& nAttributes) 00179 { 00180 if (nNodes < 1 && nRadii == 2) 00181 return GeoTessProfile::newProfile(radii, nRadii, NULL, 0); 00182 00183 if (nNodes == 1) 00184 { 00185 GeoTessData* d[1]; 00186 d[0] = GeoTessData::getData(values[0], nAttributes); 00187 return GeoTessProfile::newProfile(radii, nRadii, d, nNodes); 00188 } 00189 00190 GeoTessData** d = new GeoTessData*[nNodes]; 00191 for (int i=0; i<nNodes; ++i) d[i] = GeoTessData::getData(values[i], nAttributes); 00192 GeoTessProfile* profile = GeoTessProfile::newProfile(radii, nRadii, d, nNodes); 00193 delete[] d; 00194 return profile; 00195 } 00196 00197 static GeoTessProfile* newProfile(float* radii, const int& nRadii, LONG_INT** values, const int& nNodes, const int& nAttributes) 00198 { 00199 if (nNodes < 1 && nRadii == 2) 00200 return GeoTessProfile::newProfile(radii, nRadii, NULL, 0); 00201 00202 if (nNodes == 1) 00203 { 00204 GeoTessData* d[1]; 00205 d[0] = GeoTessData::getData(values[0], nAttributes); 00206 return GeoTessProfile::newProfile(radii, nRadii, d, nNodes); 00207 } 00208 00209 GeoTessData** d = new GeoTessData*[nNodes]; 00210 for (int i=0; i<nNodes; ++i) d[i] = GeoTessData::getData(values[i], nAttributes); 00211 GeoTessProfile* profile = GeoTessProfile::newProfile(radii, nRadii, d, nNodes); 00212 delete[] d; 00213 return profile; 00214 } 00215 00216 static GeoTessProfile* newProfile(float* radii, const int& nRadii, int** values, const int& nNodes, const int& nAttributes) 00217 { 00218 if (nNodes < 1 && nRadii == 2) 00219 return GeoTessProfile::newProfile(radii, nRadii, NULL, 0); 00220 00221 if (nNodes == 1) 00222 { 00223 GeoTessData* d[1]; 00224 d[0] = GeoTessData::getData(values[0], nAttributes); 00225 return GeoTessProfile::newProfile(radii, nRadii, d, nNodes); 00226 } 00227 00228 GeoTessData** d = new GeoTessData*[nNodes]; 00229 for (int i=0; i<nNodes; ++i) d[i] = GeoTessData::getData(values[i], nAttributes); 00230 GeoTessProfile* profile = GeoTessProfile::newProfile(radii, nRadii, d, nNodes); 00231 delete[] d; 00232 return profile; 00233 } 00234 00235 static GeoTessProfile* newProfile(float* radii, const int& nRadii, short** values, const int& nNodes, const int& nAttributes) 00236 { 00237 if (nNodes < 1 && nRadii == 2) 00238 return GeoTessProfile::newProfile(radii, nRadii, NULL, 0); 00239 00240 if (nNodes == 1) 00241 { 00242 GeoTessData* d[1]; 00243 d[0] = GeoTessData::getData(values[0], nAttributes); 00244 return GeoTessProfile::newProfile(radii, nRadii, d, nNodes); 00245 } 00246 00247 GeoTessData** d = new GeoTessData*[nNodes]; 00248 for (int i=0; i<nNodes; ++i) d[i] = GeoTessData::getData(values[i], nAttributes); 00249 GeoTessProfile* profile = GeoTessProfile::newProfile(radii, nRadii, d, nNodes); 00250 delete[] d; 00251 return profile; 00252 } 00253 00254 static GeoTessProfile* newProfile(float* radii, const int& nRadii, byte** values, const int& nNodes, const int& nAttributes) 00255 { 00256 if (nNodes < 1 && nRadii == 2) 00257 return GeoTessProfile::newProfile(radii, nRadii, NULL, 0); 00258 00259 if (nNodes == 1) 00260 { 00261 GeoTessData* d[1]; 00262 d[0] = GeoTessData::getData(values[0], nAttributes); 00263 return GeoTessProfile::newProfile(radii, nRadii, d, nNodes); 00264 } 00265 00266 GeoTessData** d = new GeoTessData*[nNodes]; 00267 for (int i=0; i<nNodes; ++i) d[i] = GeoTessData::getData(values[i], nAttributes); 00268 GeoTessProfile* profile = GeoTessProfile::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(GeoTessProfile); }; 00282 00286 static int class_count() { return aClassCount; }; 00287 00293 virtual const GeoTessProfileType& getType() const = ABSTRACT; 00294 00299 virtual bool operator == (const GeoTessProfile& p) const { return (getType() == p.getType()); } 00300 00305 virtual double getValue(const GeoTessInterpolatorType& 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 GeoTessData** getData() = ABSTRACT; 00390 00395 virtual GeoTessData* getData(int i) = ABSTRACT; 00396 00400 virtual const GeoTessData& getData(int i) const = ABSTRACT; 00401 00408 virtual void setData(int index, GeoTessData* data) = ABSTRACT; 00409 00416 virtual void setData(const vector<GeoTessData*>& inData) = ABSTRACT; 00417 00423 virtual void setRadii(const vector<float>& newRadii) = ABSTRACT; 00424 00428 virtual float getRadiusTop() const = ABSTRACT; 00429 00433 virtual const GeoTessData& getDataTop() const = ABSTRACT; 00434 00438 virtual GeoTessData* getDataTop() = ABSTRACT; 00439 00443 virtual float getRadiusBottom() const = ABSTRACT; 00444 00448 virtual const GeoTessData& getDataBottom() const = ABSTRACT; 00449 00453 virtual GeoTessData* 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 GeoTessProfile() { ++aClassCount; }; 00567 00571 virtual ~GeoTessProfile() { --aClassCount; }; 00572 00576 static GeoTessProfile* newProfile(IFStreamBinary& ifs, GeoTessMetaData& gtmd); 00577 00581 static GeoTessProfile* 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 GeoTessInterpolatorType& 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 GeoTessProfile* copy() = ABSTRACT; 00628 00630 00631 }; // end class Profile 00632 00633 } // end namespace geotess 00634 00635 #endif // PROFILE_OBJECT_H