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;
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);
Abstract base class that manages the data values attached to a single grid point.
virtual LONG_INT getMemory()
virtual double getDouble(int attributeIndex) const
virtual bool isNaN(int attributeIndex) const
An exception class for all GeoTess objects.
Enumeration of the interpolation algorithms supported by GeoTess including LINEAR,...
Abstract class that manages the radii and data values that span a single layer associated with a sing...
virtual int getNRadii() const
virtual float getRadius(int i) const
virtual GeoTessData ** getData()
A Profile object consisting of N monotonically increasing radii that span the radial extent of a laye...
virtual const GeoTessData & getDataTop() const
virtual GeoTessData * getDataTop()
GeoTessProfileNPoint(const vector< float > &r, vector< GeoTessData * > &d)
GeoTessProfileNPoint(float *r, GeoTessData **dat, int size)
virtual int getRadiusIndex(double radius, int jlo) const
virtual void setRadius(int index, float radius)
virtual void setData(int index, GeoTessData *inData)
bool isNaN(int nodeIndex, int attributeIndex)
virtual void setRadii(const vector< float > &newRadii)
virtual float getRadiusBottom() const
virtual float getRadius(int i) const
virtual GeoTessData * getData(int i)
virtual const GeoTessData & getData(int i) const
virtual double getValue(int attributeIndex, int radiusIndex) const
virtual const GeoTessData & getDataBottom() const
virtual const GeoTessProfileType & getType() const
virtual double getInterpolationCoefficient(int index, double radius, bool allowOutOfRange) const
virtual int getNRadii() const
GeoTessProfileNPoint(float *rad, const vector< GeoTessData * > &dat)
virtual int getNData() const
virtual double getValueTop(int attributeIndex) const
virtual GeoTessData * getDataBottom()
virtual int class_size() const
static string class_name()
virtual float * getRadii()
virtual GeoTessData ** getData()
virtual LONG_INT getMemory()
virtual void setData(const vector< GeoTessData * > &inData)
virtual float getRadiusTop() const
Enumeration of the valid Profile types, including EMPTY, THIN, CONSTANT, NPOINT and SURFACE.
Opens ascii file for read and write access.
Opens a file for binary read and write access.