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 {
return GeoTessProfileType::NPOINT; };
251 if (!GeoTessProfile::operator==(p))
return false;
253 if (nNodes != p.
getNRadii())
return false;
255 for (
int i = 0; i < nNodes; ++i)
257 (!(*(data[i]) == p.
getData(i))))
270 bool isNaN(
int nodeIndex,
int attributeIndex)
271 {
return data[nodeIndex]->isNaN(attributeIndex); };
277 virtual float getRadius(
int i)
const {
return radii[i]; };
295 float* fa =
new float [nNodes];
296 for (
int i=0; i<nNodes; ++i) fa[i] = radii[i];
308 for (
int i=0; i<nNodes; ++i) da[i] = data[i];
326 virtual void setData(
const vector<GeoTessData*>& inData);
331 virtual void setRadii(
const vector<float>& newRadii)
332 {
for (
int i=0; i<nNodes; ++i) radii[i] = newRadii[i]; }
335 {
if (index < nNodes) radii[index] = radius; }
341 {
delete data[index]; data[index] = inData; }
378 virtual double getValue(
int attributeIndex,
int radiusIndex)
const
379 {
return data[radiusIndex]->getDouble(attributeIndex); }
388 {
return data[nNodes-1]->getDouble(attributeIndex); }
394 virtual double getInterpolationCoefficient(
int index,
double radius)
const;
401 int attributeIndex,
double radius,
402 bool allowRadiusOutOfRange)
const;
408 virtual int getRadiusIndex(
double radius,
int jlo)
const;
413 virtual double getInterpolationCoefficient(
int index,
double radius,
414 bool allowOutOfRange)
const;
451 virtual int findClosestRadiusIndex(
double radius)
const
453 int i = GeoTessProfile::getRadiusIndex(radius);
454 return abs(radii[i+1] - radius) < abs(radii[i] - radius) ? i+1 : i;
464 virtual void setPointIndex(
int nodeIndex,
int pointIndex)
466 if (pointIndices == NULL)
468 if (pointIndex < 0)
return;
470 pointIndices =
new int [nNodes];
471 for (
int i = 0; i < nNodes; ++i) pointIndices[i] = -1;
473 pointIndices[nodeIndex] = pointIndex;
483 virtual void resetPointIndices()
485 if (pointIndices != NULL)
486 delete[] pointIndices;
497 virtual int getPointIndex(
int nodeIndex)
const
498 {
return pointIndices == NULL ? -1 : pointIndices[nodeIndex]; }
506 virtual void getWeights(map<int, double>& weights,
507 double dkm,
double radius,
double hcoefficient)
const
509 int node = GeoTessProfile::getRadiusIndex(radius);
515 int pointIndex = pointIndices == NULL ? -1 : pointIndices[node];
517 double c = getInterpolationCoefficient(node, radius,
true);
520 map<int, double>::iterator it = weights.find(pointIndex);
521 if (it == weights.end())
522 weights[pointIndex] = dkm * hcoefficient * c;
524 it->second += dkm * hcoefficient * c;
530 pointIndex = pointIndices == NULL ? -1 : pointIndices[node+1];
533 map<int, double>::iterator it = weights.find(pointIndex);
534 if (it == weights.end())
535 weights[pointIndex] = dkm * hcoefficient * c;
537 it->second += dkm * hcoefficient * c;
547 virtual void getCoefficients(map<int, double>& coefficients,
double radius,
548 double horizontalCoefficient)
const
550 int node = GeoTessProfile::getRadiusIndex(radius);
553 double c = getInterpolationCoefficient(node, radius,
true);
555 int pointIndex = pointIndices == NULL ? -1 : pointIndices[node];
558 coefficients[pointIndex] = c * horizontalCoefficient;
560 pointIndex = pointIndices == NULL ? -1 : pointIndices[node+1];
563 coefficients[pointIndex] = (1.0 - c) * horizontalCoefficient;
566 virtual void setInterpolationCoefficients(
const GeoTessInterpolatorType& interpType,
567 vector<int>& nodeIndexes, vector<double>& coefficients,
568 double& radius,
bool& allowOutOfRange)
572 if (radius < radii[0])
574 nodeIndexes.push_back(0);
575 coefficients.push_back(allowOutOfRange ? 1 : NaN_DOUBLE);
577 else if (radius > radii[nNodes-1])
579 nodeIndexes.push_back(nNodes-1);
580 coefficients.push_back(allowOutOfRange ? 1 : NaN_DOUBLE);
584 int index = getRadiusIndex(radius, -1);
585 double c = ((double)radii[index + 1] - radius) /
586 ((double)radii[index + 1] - (
double)radii[index]);
587 nodeIndexes.push_back(index);
588 coefficients.push_back(c);
591 nodeIndexes.push_back(index+1);
592 coefficients.push_back(1.-c);
600 virtual GeoTessProfile* copy()
602 GeoTessData** d =
new GeoTessData* [nNodes];
603 float* r =
new float [nNodes];
604 for (
int i = 0; i < nNodes; ++i)
606 d[i] = data[i]->copy();
609 return new GeoTessProfileNPoint(r, d, nNodes);
627 inline double GeoTessProfileNPoint::getInterpolationCoefficient(
int index,
double radius)
const
629 if (radius <= radii[index])
return 1.0;
630 if (radius >= radii[index + 1])
return 0.0;
631 return (radii[index + 1] - radius) / (radii[index + 1] - radii[index]);
647 int attributeIndex,
double radius,
bool allowRadiusOutOfRange)
const
649 if (!allowRadiusOutOfRange &&
650 ((radius < (
double)radii[0]) || (radius > (
double)radii[nNodes-1])))
653 int index = getRadiusIndex(radius, -1);
655 double r0 = radii[index];
656 double v0 = data[index]->getDouble(attributeIndex);
658 if (radius <= r0)
return v0;
660 double r1 = radii[index + 1];
661 double v1 = data[index + 1]->getDouble(attributeIndex);
663 if (radius >= r1)
return v1;
665 double a = (r1 - radius) / (r1 - r0);
668 double v = a * v0 + b * v1;
676 check(attributeIndex);
677 return v + ((a * a * a - a) * y2[attributeIndex][index]
678 + (b * b * b - b) * y2[attributeIndex][index + 1])
679 * (r1 - r0) * (r1 - r0) / 6.0;
683 os << endl <<
"ERROR in ProfileNPoint::getValue" << endl
684 <<
"InterpolatorType: " << radialType.
name()
685 <<
" cannot be applied to a Profile." << endl
686 <<
"Must specify LINEAR or SPLINE" << endl;
698 inline void GeoTessProfileNPoint::check(
int attributeIndex)
const
702 y2 =
new double* [data[0]->size()];
703 for (
int i=0; i<data[0]->size(); ++i)
706 if (y2[attributeIndex] == NULL)
707 y2[attributeIndex] = spline(radii, data, attributeIndex, 1.0e30, 1.0e30);
714 #endif // PROFILENPOINT_OBJECT_H
virtual void setRadius(int index, float radius)
Definition: GeoTessProfileNPoint.h:334
virtual int getNRadii() const
string name() const
Definition: GeoTessEnumType.h:143
Opens a file for binary read and write access.
Definition: IFStreamBinary.h:79
virtual int getNData() const
Definition: GeoTessProfileNPoint.h:287
Enumeration of the interpolation algorithms supported by GeoTess including LINEAR, NATURAL_NEIGHBOR and CUBIC_SPLINE.
Definition: GeoTessInterpolatorType.h:71
virtual int getNRadii() const
Definition: GeoTessProfileNPoint.h:282
Enumeration of the valid Profile types, including EMPTY, THIN, CONSTANT, NPOINT and SURFACE...
Definition: GeoTessProfileType.h:69
virtual GeoTessData ** getData()
virtual const GeoTessData & getData(int i) const
Definition: GeoTessProfileNPoint.h:321
virtual float getRadiusBottom() const
Definition: GeoTessProfileNPoint.h:361
virtual void setRadii(const vector< float > &newRadii)
Definition: GeoTessProfileNPoint.h:331
virtual float getRadiusTop() const
Definition: GeoTessProfileNPoint.h:346
virtual void setData(int index, GeoTessData *inData)
Definition: GeoTessProfileNPoint.h:340
GeoTessProfileNPoint(float *r, GeoTessData **dat, int size)
Definition: GeoTessProfileNPoint.h:150
virtual GeoTessData * getDataBottom()
Definition: GeoTessProfileNPoint.h:371
An exception class for all GeoTess objects.
Definition: GeoTessException.h:65
virtual const GeoTessProfileType & getType() const
Definition: GeoTessProfileNPoint.h:243
Opens ascii file for read and write access.
Definition: IFStreamAscii.h:80
static string class_name()
Definition: GeoTessProfileNPoint.h:230
virtual GeoTessData * getDataTop()
Definition: GeoTessProfileNPoint.h:356
virtual float * getRadii()
Definition: GeoTessProfileNPoint.h:293
virtual int class_size() const
Definition: GeoTessProfileNPoint.h:235
GeoTessProfileNPoint(const vector< float > &r, vector< GeoTessData * > &d)
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)
Definition: GeoTessProfileNPoint.h:270
virtual GeoTessData * getData(int i)
Definition: GeoTessProfileNPoint.h:316
virtual GeoTessData ** getData()
Definition: GeoTessProfileNPoint.h:305
virtual const GeoTessData & getDataTop() const
Definition: GeoTessProfileNPoint.h:351
virtual float getRadius(int i) const
Definition: GeoTessProfileNPoint.h:277
int ordinal() const
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
#define GEOTESS_EXP_IMP
Definition: CPPGlobals.h:71
virtual double getValue(int attributeIndex, int radiusIndex) const
Definition: GeoTessProfileNPoint.h:378
virtual float getRadius(int i) const
virtual double getValueTop(int attributeIndex) const
Definition: GeoTessProfileNPoint.h:387
virtual const GeoTessData & getDataBottom() const
Definition: GeoTessProfileNPoint.h:366