36 #ifndef PROFILENPOINT_OBJECT_H
37 #define PROFILENPOINT_OBJECT_H
64 class GeoTessMetaData;
120 y2(NULL), pointIndices(NULL) {};
126 double* spline(
float* x,
GeoTessData** y,
int attributeIndex,
127 double yp1,
double ypn)
const;
134 void check(
int attributeIndex)
const;
151 data(NULL), y2(NULL), pointIndices(NULL)
153 radii =
new float[size];
155 for (
int i=0; i<size; ++i)
161 if (radii[0] > radii[size - 1])
164 os << endl <<
"ERROR in ProfileNPoint::ProfileNPoint" << endl
165 <<
"Profile has negative thickness" << endl;
167 for (
int i=0; i<size; ++i)
168 os << radii[i] <<
", ";
187 data(NULL), y2(NULL), pointIndices(NULL)
189 radii =
new float[nNodes];
191 for (
int i=0; i<nNodes; ++i)
197 if (r.size() != d.size())
200 os << endl <<
"ERROR in ProfileNPoint::ProfileNPoint" << endl
201 <<
"radii.size() != data.size()" << endl;
202 os <<
"radii.size = " << r.
size() << endl;
203 os <<
"data.size = " << d.size() << endl;
207 if (radii[0] > radii[nNodes - 1])
210 os << endl <<
"ERROR in ProfileNPoint::ProfileNPoint" << endl
211 <<
"Profile has negative thickness" << endl;
213 for (
int i=0; i<nNodes; ++i)
214 os << radii[i] <<
", ";
244 sz += nNodes*(
LONG_INT)
sizeof(
float);
253 sz += nNodes * (
LONG_INT)(
sizeof(
int));
255 sz += data[0]->
size() * nNodes * (
LONG_INT)
sizeof(
double);
266 {
return GeoTessProfileType::NPOINT; };
273 if (!GeoTessProfile::operator==(p))
return false;
275 if (nNodes != p.
getNRadii())
return false;
277 for (
int i = 0; i < nNodes; ++i)
279 (!(*(data[i]) == p.
getData(i))))
292 bool isNaN(
int nodeIndex,
int attributeIndex)
293 {
return data[nodeIndex]->
isNaN(attributeIndex); };
299 virtual float getRadius(
int i)
const {
return radii[i]; };
317 float* fa =
new float [nNodes];
318 for (
int i=0; i<nNodes; ++i) fa[i] = radii[i];
330 for (
int i=0; i<nNodes; ++i) da[i] = data[i];
348 virtual void setData(
const vector<GeoTessData*>& inData);
353 virtual void setRadii(
const vector<float>& newRadii)
354 {
for (
int i=0; i<nNodes; ++i) radii[i] = newRadii[i]; }
357 {
if (index < nNodes) radii[index] = radius; }
363 {
delete data[index]; data[index] = inData; }
400 virtual double getValue(
int attributeIndex,
int radiusIndex)
const
401 {
return data[radiusIndex]->
getDouble(attributeIndex); }
410 {
return data[nNodes-1]->
getDouble(attributeIndex); }
416 virtual double getInterpolationCoefficient(
int index,
double radius)
const;
423 int attributeIndex,
double radius,
424 bool allowRadiusOutOfRange)
const;
430 virtual int getRadiusIndex(
double radius,
int jlo)
const;
435 virtual double getInterpolationCoefficient(
int index,
double radius,
436 bool allowOutOfRange)
const;
473 virtual int findClosestRadiusIndex(
double radius)
const
475 int i = GeoTessProfile::getRadiusIndex(radius);
476 return abs(radii[i+1] - radius) < abs(radii[i] - radius) ? i+1 : i;
486 virtual void setPointIndex(
int nodeIndex,
int pointIndex)
488 if (pointIndices == NULL)
490 if (pointIndex < 0)
return;
492 pointIndices =
new int [nNodes];
493 for (
int i = 0; i < nNodes; ++i) pointIndices[i] = -1;
495 pointIndices[nodeIndex] = pointIndex;
505 virtual void resetPointIndices()
507 if (pointIndices != NULL)
508 delete[] pointIndices;
519 virtual int getPointIndex(
int nodeIndex)
const
520 {
return pointIndices == NULL ? -1 : pointIndices[nodeIndex]; }
528 virtual void getWeights(map<int, double>& weights,
529 double dkm,
double radius,
double hcoefficient)
const
531 int node = GeoTessProfile::getRadiusIndex(radius);
537 int pointIndex = pointIndices == NULL ? -1 : pointIndices[node];
539 double c = getInterpolationCoefficient(node, radius,
true);
542 map<int, double>::iterator it = weights.find(pointIndex);
543 if (it == weights.end())
544 weights[pointIndex] = dkm * hcoefficient * c;
546 it->second += dkm * hcoefficient * c;
552 pointIndex = pointIndices == NULL ? -1 : pointIndices[node+1];
555 map<int, double>::iterator it = weights.find(pointIndex);
556 if (it == weights.end())
557 weights[pointIndex] = dkm * hcoefficient * c;
559 it->second += dkm * hcoefficient * c;
569 virtual void getCoefficients(map<int, double>& coefficients,
double radius,
570 double horizontalCoefficient)
const
572 int node = GeoTessProfile::getRadiusIndex(radius);
575 double c = getInterpolationCoefficient(node, radius,
true);
577 int pointIndex = pointIndices == NULL ? -1 : pointIndices[node];
580 coefficients[pointIndex] = c * horizontalCoefficient;
582 pointIndex = pointIndices == NULL ? -1 : pointIndices[node+1];
585 coefficients[pointIndex] = (1.0 - c) * horizontalCoefficient;
588 virtual void setInterpolationCoefficients(
const GeoTessInterpolatorType& interpType,
589 vector<int>& nodeIndexes, vector<double>& coefficients,
590 double& radius,
bool& allowOutOfRange)
594 if (radius < radii[0])
596 nodeIndexes.push_back(0);
597 coefficients.push_back(allowOutOfRange ? 1 : NaN_DOUBLE);
599 else if (radius > radii[nNodes-1])
601 nodeIndexes.push_back(nNodes-1);
602 coefficients.push_back(allowOutOfRange ? 1 : NaN_DOUBLE);
606 int index = getRadiusIndex(radius, -1);
607 double c = ((double)radii[index + 1] - radius) /
608 ((double)radii[index + 1] - (
double)radii[index]);
609 nodeIndexes.push_back(index);
610 coefficients.push_back(c);
613 nodeIndexes.push_back(index+1);
614 coefficients.push_back(1.-c);
622 virtual GeoTessProfile* copy()
624 GeoTessData** d =
new GeoTessData* [nNodes];
625 float* r =
new float [nNodes];
626 for (
int i = 0; i < nNodes; ++i)
628 d[i] = data[i]->copy();
631 return new GeoTessProfileNPoint(r, d, nNodes);
649 inline double GeoTessProfileNPoint::getInterpolationCoefficient(
int index,
double radius)
const
651 if (radius <= radii[index])
return 1.0;
652 if (radius >= radii[index + 1])
return 0.0;
653 return (radii[index + 1] - radius) / (radii[index + 1] - radii[index]);
669 int attributeIndex,
double radius,
bool allowRadiusOutOfRange)
const
671 if (!allowRadiusOutOfRange &&
672 ((radius < (
double)radii[0]) || (radius > (
double)radii[nNodes-1])))
675 int index = getRadiusIndex(radius, -1);
677 double r0 = radii[index];
678 double v0 = data[index]->
getDouble(attributeIndex);
680 if (radius <= r0)
return v0;
682 double r1 = radii[index + 1];
683 double v1 = data[index + 1]->
getDouble(attributeIndex);
685 if (radius >= r1)
return v1;
687 double a = (r1 - radius) / (r1 - r0);
690 double v = a * v0 + b * v1;
698 check(attributeIndex);
699 return v + ((a * a * a - a) * y2[attributeIndex][index]
700 + (b * b * b - b) * y2[attributeIndex][index + 1])
701 * (r1 - r0) * (r1 - r0) / 6.0;
705 os << endl <<
"ERROR in ProfileNPoint::getValue" << endl
706 <<
"InterpolatorType: " << radialType.
name()
707 <<
" cannot be applied to a Profile." << endl
708 <<
"Must specify LINEAR or SPLINE" << endl;
720 inline void GeoTessProfileNPoint::check(
int attributeIndex)
const
724 y2 =
new double* [data[0]->
size()];
725 for (
int i=0; i<data[0]->size(); ++i)
728 if (y2[attributeIndex] == NULL)
729 y2[attributeIndex] = spline(radii, data, attributeIndex, 1.0e30, 1.0e30);
736 #endif // PROFILENPOINT_OBJECT_H
virtual void setRadius(int index, float radius)
Replace the radius at the specified nodeIndex.
Definition: GeoTessProfileNPoint.h:356
virtual int getNRadii() const
Get the number of radii that comprise this profile.
virtual double getDouble(int attributeIndex) const
Retrieve the value of the attribute at the specified attribute index as a double value.
virtual LONG_INT getMemory()
string name() const
Returns this Enums name.
Definition: GeoTessEnumType.h:143
Definition: ArrayReuse.h:55
Opens a file for binary read and write access.
Definition: IFStreamBinary.h:79
virtual int getNData() const
Get the number of Data objects that comprise this profile.
Definition: GeoTessProfileNPoint.h:309
Enumeration of the interpolation algorithms supported by GeoTess including LINEAR, NATURAL_NEIGHBOR and CUBIC_SPLINE.
Definition: GeoTessInterpolatorType.h:71
virtual int getNRadii() const
Get the number of radii that comprise this profile.
Definition: GeoTessProfileNPoint.h:304
virtual int size() const
Retrieve the number of attributes stored in this Data object.
Enumeration of the valid Profile types, including EMPTY, THIN, CONSTANT, NPOINT and SURFACE...
Definition: GeoTessProfileType.h:69
virtual GeoTessData ** getData()
Retrieve a shallow copy of the array of Data objects associated with this Profile.
virtual const GeoTessData & getData(int i) const
Retrieve a reference the i'th Data object.
Definition: GeoTessProfileNPoint.h:343
virtual float getRadiusBottom() const
Get the radius at the bottom of the profile, in km.
Definition: GeoTessProfileNPoint.h:383
virtual void setRadii(const vector< float > &newRadii)
Replace the radii currently associated with this Profile with new values.
Definition: GeoTessProfileNPoint.h:353
virtual float getRadiusTop() const
Get the radius at the top of the profile, in km.
Definition: GeoTessProfileNPoint.h:368
virtual void setData(int index, GeoTessData *inData)
Resets the data object to the new input data.
Definition: GeoTessProfileNPoint.h:362
GeoTessProfileNPoint(float *r, GeoTessData **dat, int size)
Standard constructor.
Definition: GeoTessProfileNPoint.h:150
virtual GeoTessData * getDataBottom()
Get the Data object at the bottom of the profile.
Definition: GeoTessProfileNPoint.h:393
An exception class for all GeoTess objects.
Definition: GeoTessException.h:65
virtual bool isNaN(int attributeIndex) const
Returns true if the specified attribute is NaN.
virtual const GeoTessProfileType & getType() const
Returns ProfileType (NPOINT).
Definition: GeoTessProfileNPoint.h:265
Opens ascii file for read and write access.
Definition: IFStreamAscii.h:80
static string class_name()
Returns the class name.
Definition: GeoTessProfileNPoint.h:230
virtual GeoTessData * getDataTop()
Get the Data object at the top of the profile.
Definition: GeoTessProfileNPoint.h:378
virtual float * getRadii()
Retrieve a copy of the array of radii values in km.
Definition: GeoTessProfileNPoint.h:315
virtual int class_size() const
Returns the class size.
Definition: GeoTessProfileNPoint.h:235
#define LONG_INT
Definition: CPPGlobals.h:111
GeoTessProfileNPoint(const vector< float > &r, vector< GeoTessData * > &d)
Standard constructor.
Definition: GeoTessProfileNPoint.h:185
Abstract class that manages the radii and data values that span a single layer associated with a sing...
Definition: GeoTessProfile.h:96
Abstract base class that manages the data values attached to a single grid point. ...
Definition: GeoTessData.h:75
bool isNaN(int nodeIndex, int attributeIndex)
Return true if the specified Data value is NaN.
Definition: GeoTessProfileNPoint.h:292
virtual GeoTessData * getData(int i)
Retrieve a reference the i'th Data object.
Definition: GeoTessProfileNPoint.h:338
virtual GeoTessData ** getData()
Retrieve a shallow copy of the array of Data objects associated with this Profile.
Definition: GeoTessProfileNPoint.h:327
virtual const GeoTessData & getDataTop() const
Get the Data object at the top of the profile.
Definition: GeoTessProfileNPoint.h:373
virtual float getRadius(int i) const
Get the i'th radius value in this profile in km.
Definition: GeoTessProfileNPoint.h:299
int ordinal() const
Returns this Enums ordinal.
Definition: GeoTessEnumType.h:148
A Profile object consisting of N monotonically increasing radii that span the radial extent of a laye...
Definition: GeoTessProfileNPoint.h:80
virtual LONG_INT getMemory()
Definition: GeoTessProfileNPoint.h:238
#define GEOTESS_EXP_IMP
Definition: CPPGlobals.h:71
virtual double getValue(int attributeIndex, int radiusIndex) const
Retrieve the value of the specified attributes at the specified radius index.
Definition: GeoTessProfileNPoint.h:400
virtual float getRadius(int i) const
Get the i'th radius value in this profile in km.
virtual double getValueTop(int attributeIndex) const
Retrieve the value of the specified attribute at the top of the layer.
Definition: GeoTessProfileNPoint.h:409
virtual const GeoTessData & getDataBottom() const
Get the Data object at the bottom of the profile.
Definition: GeoTessProfileNPoint.h:388