GeoTessCPP: rstt/GeoTessCPP/include/GeoTessProfileNPoint.h Source File

GeoTessCPP 2.2.3 Software to facilitate storage and retrieval of 3D information about the Earth.

GeoTessProfileNPoint.h
Go to the documentation of this file.
1 //- ****************************************************************************
2 //-
3 //- Copyright 2009 National Technology & Engineering Solutions of Sandia, LLC
4 //- (NTESS). Under the terms of Contract DE-NA0003525 with NTESS, the U.S.
5 //- Government 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 //- 1. Redistributions of source code must retain the above copyright notice,
14 //- this list of conditions and the following disclaimer.
15 //-
16 //- 2. Redistributions in binary form must reproduce the above copyright
17 //- notice, this list of conditions and the following disclaimer in the
18 //- documentation and/or other materials provided with the distribution.
19 //-
20 //- 3. Neither the name of the copyright holder nor the names of its
21 //- contributors may be used to endorse or promote products derived from
22 //- this software without specific prior written permission.
23 //-
24 //- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
25 //- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26 //- IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27 //- ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
28 //- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
29 //- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
30 //- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
31 //- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
32 //- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
33 //- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
34 //- POSSIBILITY OF SUCH DAMAGE.
35 //-
36 //- ****************************************************************************
37
38 #ifndef PROFILENPOINT_OBJECT_H
39 #define PROFILENPOINT_OBJECT_H
40
41 // **** _SYSTEM INCLUDES_ ******************************************************
42
43 #include <iostream>
44 #include <string>
45 #include <fstream>
46 #include <sstream>
47
48 // use standard library objects
49 using namespace std;
50
51 // **** _LOCAL INCLUDES_ *******************************************************
52
53 #include "GeoTessUtils.h"
54 #include "GeoTessException.h"
55 #include "GeoTessData.h"
56 #include "GeoTessProfile.h"
57 #include "GeoTessProfileType.h"
58 #include "GeoTessInterpolatorType.h"
59
60 // **** _BEGIN GEOTESS NAMESPACE_ **********************************************
61
62 namespace geotess {
63
64 // **** _FORWARD REFERENCES_ ***************************************************
65
66 class GeoTessMetaData;
67 class IFStreamAscii;
68 class IFStreamBinary;
69
70 // **** _CLASS DEFINITION_ *****************************************************
71
82 class GEOTESS_EXP_IMP GeoTessProfileNPoint : virtual public GeoTessProfile
83 {
84 private:
85
89 int nNodes;
90
94 float* radii;
95
99 GeoTessData** data;
100
107 mutable double** y2;
108
116 int* pointIndices;
117
121 GeoTessProfileNPoint() : GeoTessProfile(), nNodes(0), radii(NULL), data(NULL),
122 y2(NULL), pointIndices(NULL) {};
123
128 double* spline(float* x, GeoTessData** y, int attributeIndex,
129 double yp1, double ypn) const;
130
136 void check(int attributeIndex) const;
137
138 public:
139
152 GeoTessProfileNPoint(float* r, GeoTessData** dat, int size) : GeoTessProfile(), nNodes(size), radii(NULL),
153 data(NULL), y2(NULL), pointIndices(NULL)
154 {
155 radii = new float[size];
156 data = new GeoTessData*[size];
157 for (int i=0; i<size; ++i)
158 {
159 radii[i] = r[i];
160 data[i] = dat[i];
161 }
162
163 if (radii[0] > radii[size - 1])
164 {
165 ostringstream os;
166 os << endl << "ERROR in ProfileNPoint::ProfileNPoint" << endl
167 << "Profile has negative thickness" << endl;
168 os << "radii = ";
169 for (int i=0; i<size; ++i)
170 os << radii[i] << ", ";
171 os << endl;
172 throw GeoTessException(os, __FILE__, __LINE__, 4301);
173 }
174 }
175
187 GeoTessProfileNPoint(const vector<float>& r, vector<GeoTessData*>& d)
188 : GeoTessProfile(), nNodes(r.size()), radii(NULL),
189 data(NULL), y2(NULL), pointIndices(NULL)
190 {
191 radii = new float[nNodes];
192 data = new GeoTessData*[nNodes];
193 for (int i=0; i<nNodes; ++i)
194 {
195 radii[i] = r[i];
196 data[i] = d[i];
197 }
198
199 if (r.size() != d.size())
200 {
201 ostringstream os;
202 os << endl << "ERROR in ProfileNPoint::ProfileNPoint" << endl
203 << "radii.size() != data.size()" << endl;
204 os << "radii.size = " << r.size() << endl;
205 os << "data.size = " << d.size() << endl;
206 throw GeoTessException(os, __FILE__, __LINE__, 4302);
207 }
208
209 if (radii[0] > radii[nNodes - 1])
210 {
211 ostringstream os;
212 os << endl << "ERROR in ProfileNPoint::ProfileNPoint" << endl
213 << "Profile has negative thickness" << endl;
214 os << "radii = ";
215 for (int i=0; i<nNodes; ++i)
216 os << radii[i] << ", ";
217 os << endl;
218 throw GeoTessException(os, __FILE__, __LINE__, 4303);
219 }
220 }
221
227 GeoTessProfileNPoint(float* rad, const vector<GeoTessData*>& dat);
228
232 static string class_name() { return "ProfileNPoint"; };
233
237 virtual int class_size() const
238 { return (int) sizeof(GeoTessProfileNPoint); };
239
240 virtual LONG_INT getMemory()
241 {
242 LONG_INT sz = (LONG_INT)sizeof(GeoTessProfileNPoint);
243 if (nNodes > 0)
244 {
245 // add memory for radii
246 sz += nNodes*(LONG_INT)sizeof(float);
247
248 // add memory for data. assumption is made that
249 // GeoTessData objects at all nodes have the same type and
250 // number of attributes.
251 sz += nNodes*(LONG_INT)sizeof(GeoTessData*);
252 sz += nNodes*data[0]->getMemory();
253
254 if (pointIndices)
255 sz += nNodes * (LONG_INT)(sizeof(int));
256 if (y2)
257 sz += data[0]->size() * nNodes * (LONG_INT)sizeof(double);
258 }
259 return sz;
260 }
261
267 virtual const GeoTessProfileType& getType() const
268 { return GeoTessProfileType::NPOINT; };
269
273 virtual bool operator == (const GeoTessProfile& p) const
274 {
275 if (!GeoTessProfile::operator==(p)) return false;
276
277 if (nNodes != p.getNRadii()) return false;
278
279 for (int i = 0; i < nNodes; ++i)
280 if ((radii[i] != p.getRadius(i)) ||
281 (!(*(data[i]) == p.getData(i))))
282 return false;
283
284 return true;
285 }
286
294 bool isNaN(int nodeIndex, int attributeIndex)
295 { return data[nodeIndex]->isNaN(attributeIndex); };
296
301 virtual float getRadius(int i) const { return radii[i]; };
302
306 virtual int getNRadii() const { return nNodes; };
307
311 virtual int getNData() const { return nNodes; };
312
317 virtual float* getRadii()
318 {
319 float* fa = new float [nNodes];
320 for (int i=0; i<nNodes; ++i) fa[i] = radii[i];
321 return fa;
322 }
323
329 virtual GeoTessData** getData()
330 {
331 GeoTessData** da = new GeoTessData*[nNodes];
332 for (int i=0; i<nNodes; ++i) da[i] = data[i];
333 return da;
334 }
335
336
340 virtual GeoTessData* getData(int i) { return data[i]; };
341
345 virtual const GeoTessData& getData(int i) const { return *(data[i]); };
346
350 virtual void setData(const vector<GeoTessData*>& inData);
351
355 virtual void setRadii(const vector<float>& newRadii)
356 { for (int i=0; i<nNodes; ++i) radii[i] = newRadii[i]; }
357
358 virtual void setRadius(int index, float radius)
359 { if (index < nNodes) radii[index] = radius; }
360
364 virtual void setData(int index, GeoTessData* inData)
365 { delete data[index]; data[index] = inData; }
366
370 virtual float getRadiusTop() const { return radii[nNodes - 1]; };
371
375 virtual const GeoTessData& getDataTop() const { return *data[nNodes - 1]; };
376
380 virtual GeoTessData* getDataTop() { return data[nNodes - 1]; };
381
385 virtual float getRadiusBottom() const { return radii[0]; };
386
390 virtual const GeoTessData& getDataBottom() const { return *data[0]; };
391
395 virtual GeoTessData* getDataBottom() { return data[0]; };
396
397
402 virtual double getValue(int attributeIndex, int radiusIndex) const
403 { return data[radiusIndex]->getDouble(attributeIndex); }
404
411 virtual double getValueTop(int attributeIndex) const
412 { return data[nNodes-1]->getDouble(attributeIndex); }
413
418 virtual double getInterpolationCoefficient(int index, double radius) const;
419
424 virtual double getValue(const GeoTessInterpolatorType& radialType,
425 int attributeIndex, double radius,
426 bool allowRadiusOutOfRange) const;
427
432 virtual int getRadiusIndex(double radius, int jlo) const;
433
437 virtual double getInterpolationCoefficient(int index, double radius,
438 bool allowOutOfRange) const;
439
441
445 GeoTessProfileNPoint(IFStreamBinary& ifs, GeoTessMetaData& gtmd);
446
450 GeoTessProfileNPoint(IFStreamAscii& ifs, GeoTessMetaData& gtmd);
451
455 virtual ~GeoTessProfileNPoint();
456
460 virtual void write(IFStreamBinary& ofs);
461
465 virtual void write(IFStreamAscii& ofs);
466
475 virtual int findClosestRadiusIndex(double radius) const
476 {
477 int i = GeoTessProfile::getRadiusIndex(radius);
478 return abs(radii[i+1] - radius) < abs(radii[i] - radius) ? i+1 : i;
479 }
480
488 virtual void setPointIndex(int nodeIndex, int pointIndex)
489 {
490 if (pointIndices == NULL)
491 {
492 if (pointIndex < 0) return;
493
494 pointIndices = new int [nNodes];
495 for (int i = 0; i < nNodes; ++i) pointIndices[i] = -1;
496 }
497 pointIndices[nodeIndex] = pointIndex;
498 }
499
507 virtual void resetPointIndices()
508 {
509 if (pointIndices != NULL)
510 delete[] pointIndices;
511 pointIndices = NULL;
512 }
513
521 virtual int getPointIndex(int nodeIndex) const
522 { return pointIndices == NULL ? -1 : pointIndices[nodeIndex]; }
523
530 virtual void getWeights(map<int, double>& weights,
531 double dkm, double radius, double hcoefficient) const
532 {
533 int node = GeoTessProfile::getRadiusIndex(radius);
534
535 //TODO: need getInterpolationCoefficient to work for cubic spline interpolator. It currently does not.
536
537 // get coefficient at node influencing position radius
538
539 int pointIndex = pointIndices == NULL ? -1 : pointIndices[node];
540
541 double c = getInterpolationCoefficient(node, radius, true);
542 if (c > 0.0)
543 {
544 map<int, double>::iterator it = weights.find(pointIndex);
545 if (it == weights.end())
546 weights[pointIndex] = dkm * hcoefficient * c;
547 else
548 it->second += dkm * hcoefficient * c;
549 }
550
551 // now get coefficient at node+1 influencing position radius
552
553 c = 1.0 - c;
554 pointIndex = pointIndices == NULL ? -1 : pointIndices[node+1];
555 if (c > 0.0)
556 {
557 map<int, double>::iterator it = weights.find(pointIndex);
558 if (it == weights.end())
559 weights[pointIndex] = dkm * hcoefficient * c;
560 else
561 it->second += dkm * hcoefficient * c;
562 }
563 }
564
571 virtual void getCoefficients(map<int, double>& coefficients, double radius,
572 double horizontalCoefficient) const
573 {
574 int node = GeoTessProfile::getRadiusIndex(radius);
575
576 //TODO: need getInterpolationCoefficient to work for cubic spline interpolator. It currently does not.
577 double c = getInterpolationCoefficient(node, radius, true);
578
579 int pointIndex = pointIndices == NULL ? -1 : pointIndices[node];
580
581 if (c > 0.0)
582 coefficients[pointIndex] = c * horizontalCoefficient;
583
584 pointIndex = pointIndices == NULL ? -1 : pointIndices[node+1];
585
586 if (c < 1.0)
587 coefficients[pointIndex] = (1.0 - c) * horizontalCoefficient;
588 }
589
590 virtual void setInterpolationCoefficients(const GeoTessInterpolatorType& interpType,
591 vector<int>& nodeIndexes, vector<double>& coefficients,
592 double& radius, bool& allowOutOfRange)
593 {
594 //TODO: need this method to work for cubic spline interpolator. It currently does not.
595
596 if (radius < radii[0])
597 {
598 nodeIndexes.push_back(0);
599 coefficients.push_back(allowOutOfRange ? 1 : NaN_DOUBLE);
600 }
601 else if (radius > radii[nNodes-1])
602 {
603 nodeIndexes.push_back(nNodes-1);
604 coefficients.push_back(allowOutOfRange ? 1 : NaN_DOUBLE);
605 }
606 else
607 {
608 int index = getRadiusIndex(radius, -1);
609 double c = ((double)radii[index + 1] - radius) /
610 ((double)radii[index + 1] - (double)radii[index]);
611 nodeIndexes.push_back(index);
612 coefficients.push_back(c);
613 if (c < 1.)
614 {
615 nodeIndexes.push_back(index+1);
616 coefficients.push_back(1.-c);
617 }
618 }
619 }
620
624 virtual GeoTessProfile* copy()
625 {
626 GeoTessData** d = new GeoTessData* [nNodes];
627 float* r = new float [nNodes];
628 for (int i = 0; i < nNodes; ++i)
629 {
630 d[i] = data[i]->copy();
631 r[i] = radii[i];
632 }
633 return new GeoTessProfileNPoint(r, d, nNodes);
634 }
635
637
638 }; // end class ProfileNPoint
639
651 inline double GeoTessProfileNPoint::getInterpolationCoefficient(int index, double radius) const
652 {
653 if (radius <= radii[index]) return 1.0;
654 if (radius >= radii[index + 1]) return 0.0;
655 return (radii[index + 1] - radius) / (radii[index + 1] - radii[index]);
656 }
657
670 inline double GeoTessProfileNPoint::getValue(const GeoTessInterpolatorType& radialType,
671 int attributeIndex, double radius, bool allowRadiusOutOfRange) const
672 {
673 if (!allowRadiusOutOfRange &&
674 ((radius < (double)radii[0]) || (radius > (double)radii[nNodes-1])))
675 return NaN_DOUBLE;
676
677 int index = getRadiusIndex(radius, -1);
678
679 double r0 = radii[index];
680 double v0 = data[index]->getDouble(attributeIndex);
681
682 if (radius <= r0) return v0;
683
684 double r1 = radii[index + 1];
685 double v1 = data[index + 1]->getDouble(attributeIndex);
686
687 if (radius >= r1) return v1;
688
689 double a = (r1 - radius) / (r1 - r0);
690
691 double b = 1. - a;
692 double v = a * v0 + b * v1;
693
694 switch (radialType.ordinal())
695 {
696 case 0: // LINEAR
697 return v;
698
699 case 2: // CUBIC_SPLINE
700 check(attributeIndex);
701 return v + ((a * a * a - a) * y2[attributeIndex][index]
702 + (b * b * b - b) * y2[attributeIndex][index + 1])
703 * (r1 - r0) * (r1 - r0) / 6.0;
704
705 default:
706 ostringstream os;
707 os << endl << "ERROR in ProfileNPoint::getValue" << endl
708 << "InterpolatorType: " << radialType.name()
709 << " cannot be applied to a Profile." << endl
710 << "Must specify LINEAR or SPLINE" << endl;
711 throw GeoTessException(os, __FILE__, __LINE__, 4304);
712 }
713 }
714
716
722 inline void GeoTessProfileNPoint::check(int attributeIndex) const
723 {
724 if (y2 == NULL)
725 {
726 y2 = new double* [data[0]->size()];
727 for (int i=0; i<data[0]->size(); ++i)
728 y2[i] = NULL;
729 }
730 if (y2[attributeIndex] == NULL)
731 y2[attributeIndex] = spline(radii, data, attributeIndex, 1.0e30, 1.0e30);
732 }
733
735
736 } // end namespace geotess
737
738 #endif // PROFILENPOINT_OBJECT_H
geotess::GeoTessProfileNPoint::getRadii
virtual float * getRadii()
Definition: GeoTessProfileNPoint.h:317
geotess::GeoTessProfileNPoint::getValueTop
virtual double getValueTop(int attributeIndex) const
Definition: GeoTessProfileNPoint.h:411
geotess
Definition: ArrayReuse.h:57
GeoTessException.h
geotess::GeoTessProfile
Abstract class that manages the radii and data values that span a single layer associated with a sing...
Definition: GeoTessProfile.h:99
GeoTessProfileType.h
geotess::GeoTessProfileNPoint::getDataBottom
virtual GeoTessData * getDataBottom()
Definition: GeoTessProfileNPoint.h:395
GeoTessData.h
geotess::GeoTessProfileNPoint::setData
virtual void setData(const vector< GeoTessData * > &inData)
geotess::GeoTessData::getMemory
virtual LONG_INT getMemory()
GeoTessProfile.h
geotess::GeoTessProfileType
Enumeration of the valid Profile types, including EMPTY, THIN, CONSTANT, NPOINT and SURFACE.
Definition: GeoTessProfileType.h:72
geotess::GeoTessProfileNPoint::GeoTessProfileNPoint
GeoTessProfileNPoint(const vector< float > &r, vector< GeoTessData * > &d)
Definition: GeoTessProfileNPoint.h:187
geotess::GeoTessProfileNPoint::getType
virtual const GeoTessProfileType & getType() const
Definition: GeoTessProfileNPoint.h:267
geotess::GeoTessProfileNPoint::GeoTessProfileNPoint
GeoTessProfileNPoint(float *r, GeoTessData **dat, int size)
Definition: GeoTessProfileNPoint.h:152
geotess::GeoTessProfileNPoint::getDataTop
virtual GeoTessData * getDataTop()
Definition: GeoTessProfileNPoint.h:380
geotess::GeoTessProfileNPoint::class_name
static string class_name()
Definition: GeoTessProfileNPoint.h:232
geotess::GeoTessProfileNPoint::getMemory
virtual LONG_INT getMemory()
Definition: GeoTessProfileNPoint.h:240
geotess::GeoTessProfileNPoint::getNData
virtual int getNData() const
Definition: GeoTessProfileNPoint.h:311
geotess::GeoTessEnumType::name
string name() const
Definition: GeoTessEnumType.h:145
geotess::GeoTessProfile::getRadius
virtual float getRadius(int i) const
geotess::GeoTessData::size
virtual int size() const
geotess::GeoTessProfileNPoint::getDataBottom
virtual const GeoTessData & getDataBottom() const
Definition: GeoTessProfileNPoint.h:390
geotess::GeoTessProfileNPoint::getData
virtual const GeoTessData & getData(int i) const
Definition: GeoTessProfileNPoint.h:345
geotess::GeoTessProfileNPoint::getData
virtual GeoTessData * getData(int i)
Definition: GeoTessProfileNPoint.h:340
geotess::GeoTessProfileNPoint::isNaN
bool isNaN(int nodeIndex, int attributeIndex)
Definition: GeoTessProfileNPoint.h:294
geotess::GeoTessProfileNPoint::getData
virtual GeoTessData ** getData()
Definition: GeoTessProfileNPoint.h:329
geotess::GeoTessProfileNPoint::getRadius
virtual float getRadius(int i) const
Definition: GeoTessProfileNPoint.h:301
geotess::GeoTessEnumType::ordinal
int ordinal() const
Definition: GeoTessEnumType.h:150
GeoTessUtils.h
geotess::GeoTessProfile::getNRadii
virtual int getNRadii() const
geotess::IFStreamAscii
Opens ascii file for read and write access.
Definition: IFStreamAscii.h:83
geotess::GeoTessProfileNPoint::getNRadii
virtual int getNRadii() const
Definition: GeoTessProfileNPoint.h:306
LONG_INT
#define LONG_INT
Definition: CPPGlobals.h:113
geotess::GeoTessProfileNPoint::getDataTop
virtual const GeoTessData & getDataTop() const
Definition: GeoTessProfileNPoint.h:375
geotess::GeoTessProfileNPoint::setRadius
virtual void setRadius(int index, float radius)
Definition: GeoTessProfileNPoint.h:358
geotess::GeoTessProfileNPoint::getInterpolationCoefficient
virtual double getInterpolationCoefficient(int index, double radius, bool allowOutOfRange) const
geotess::GeoTessData
Abstract base class that manages the data values attached to a single grid point.
Definition: GeoTessData.h:78
GeoTessInterpolatorType.h
geotess::GeoTessProfileNPoint::getRadiusTop
virtual float getRadiusTop() const
Definition: GeoTessProfileNPoint.h:370
GEOTESS_EXP_IMP
#define GEOTESS_EXP_IMP
Definition: CPPGlobals.h:73
geotess::IFStreamBinary
Opens a file for binary read and write access.
Definition: IFStreamBinary.h:82
geotess::GeoTessData::getDouble
virtual double getDouble(int attributeIndex) const
geotess::GeoTessMetaData
Basic metadata information about a GeoTessModel.
Definition: GeoTessMetaData.h:98
geotess::GeoTessProfileNPoint
A Profile object consisting of N monotonically increasing radii that span the radial extent of a laye...
Definition: GeoTessProfileNPoint.h:83
geotess::GeoTessProfileNPoint::getValue
virtual double getValue(int attributeIndex, int radiusIndex) const
Definition: GeoTessProfileNPoint.h:402
geotess::GeoTessProfileNPoint::getRadiusBottom
virtual float getRadiusBottom() const
Definition: GeoTessProfileNPoint.h:385
geotess::GeoTessProfileNPoint::GeoTessProfileNPoint
GeoTessProfileNPoint(float *rad, const vector< GeoTessData * > &dat)
geotess::GeoTessProfileNPoint::setRadii
virtual void setRadii(const vector< float > &newRadii)
Definition: GeoTessProfileNPoint.h:355
geotess::GeoTessException
An exception class for all GeoTess objects.
Definition: GeoTessException.h:68
geotess::GeoTessProfileNPoint::getRadiusIndex
virtual int getRadiusIndex(double radius, int jlo) const
geotess::GeoTessProfileNPoint::class_size
virtual int class_size() const
Definition: GeoTessProfileNPoint.h:237
geotess::GeoTessProfileNPoint::setData
virtual void setData(int index, GeoTessData *inData)
Definition: GeoTessProfileNPoint.h:364
geotess::GeoTessProfile::getData
virtual GeoTessData ** getData()
geotess::GeoTessInterpolatorType
Enumeration of the interpolation algorithms supported by GeoTess including LINEAR,...
Definition: GeoTessInterpolatorType.h:74
geotess::GeoTessData::isNaN
virtual bool isNaN(int attributeIndex) const