36 #ifndef GEOTESSPOSITION_OBJECT_H
37 #define GEOTESSPOSITION_OBJECT_H
66 class GeoTessInterpolatorType;
150 void updatePosition2D(
int layerid,
const double*
const uVector);
169 void checkTessellation(
const int& tid)
171 if (triangle[tid] < 0)
174 triangle[tid] = grid.getTriangle(tid, 0, 0);
175 getContainingTriangle(tid);
187 void updateRadius(
int lid,
double rad)
189 if ((radius < 0.) || (rad != radius) || (lid != layerId))
193 tessid = layerTessIds[lid];
194 checkTessellation(tessid);
195 clearRadialCoefficients();
199 void clearRadialCoefficients()
201 for (
int i=0; i<(int)radialIndexes.size(); ++i)
203 radialIndexes[i].clear();
204 radialCoefficients[i].clear();
214 void updateRadialCoefficients()
218 if (radialIndexes.size() < vertices[tessid].size())
220 radialIndexes.resize(vertices[tessid].size());
221 radialCoefficients.resize(vertices[tessid].size());
226 if (radialIndexes[0].size() == 0)
228 vector<int>& v = vertices[tessid];
229 for (
int i = 0; i < (int)v.size(); ++i)
230 modlProfiles[v[i]][layerId]->setInterpolationCoefficients(radialInterpolatorType,
231 radialIndexes[i], radialCoefficients[i], radius, radiusOutOfRangeAllowed);
239 static const double TWALK_TOLERANCE;
251 void getContainingTriangle(
int tid);
261 int biggerTriangle(
int t1,
int t2)
263 const int* tv = grid.getTriangleVertexIndexes(t1);
264 double dot1 = GeoTessUtils::dot(grid.getVertex(tv[0]), grid.getVertex(tv[1]))
265 + GeoTessUtils::dot(grid.getVertex(tv[1]), grid.getVertex(tv[2]))
266 + GeoTessUtils::dot(grid.getVertex(tv[2]), grid.getVertex(tv[0]));
268 tv = grid.getTriangleVertexIndexes(t2);
269 double dot2 = GeoTessUtils::dot(grid.getVertex(tv[0]), grid.getVertex(tv[1]))
270 + GeoTessUtils::dot(grid.getVertex(tv[1]), grid.getVertex(tv[2]))
271 + GeoTessUtils::dot(grid.getVertex(tv[2]), grid.getVertex(tv[0]));
273 return dot2 > dot1 ? t1 : t2;
298 vector<double> layerRadii;
317 vector< vector< int> > vertices;
324 vector< vector< double> > linearCoefficients;
337 vector< vector< double> > hCoefficients;
353 vector<vector<int> > radialIndexes;
372 vector<vector<double> > radialCoefficients;
396 double const*
const* gridVertices;
397 int const*
const* gridTriangles;
398 int const*
const* gridNeighbors;
399 double const*
const*
const* gridEdges;
400 const int* layerTessIds;
417 bool radiusOutOfRangeAllowed;
422 double unitVector[3];
427 int getTriangle(
int tid)
428 { checkTessellation(tid);
return triangle[tid]; };
434 virtual void update2D(
int tid) =
ABSTRACT;
508 virtual double getValue(
int attribute);
536 bool noEmptyProfiles();
558 void set(
double lat,
double lon,
double depth)
560 double uVector[3] = {0.0, 0.0, 0.0};
561 GeoTessUtils::getVectorDegrees(lat, lon, uVector);
562 double newRadius = GeoTessUtils::getEarthRadius(uVector) - depth;
563 set(uVector, newRadius);
578 void set(
const double*
const uVector,
const double& newRadius)
580 updatePosition2D(nLayers - 1, uVector);
582 int lid = getLayerId(newRadius);
584 updatePosition2D(lid, uVector);
585 updateRadius(lid, newRadius);
605 void set(
int layid,
double lat,
double lon,
double depth)
608 set(lat, lon, depth);
612 GeoTessUtils::getVectorDegrees(lat, lon, uVector);
613 updatePosition2D(layid, uVector);
614 updateRadius(layid, GeoTessUtils::getEarthRadius(uVector) - depth);
628 void set(
int layid,
const double*
const uVector,
double rad)
634 updatePosition2D(layid, uVector);
635 if (rad >= 0.0) updateRadius(layid, rad);
646 void setTop(
int layid,
const double*
const uVector)
648 updatePosition2D(layid, uVector);
649 updateRadius(layid, getRadiusTop(layid));
660 void setBottom(
int layid,
const double*
const uVector)
662 updatePosition2D(layid, uVector);
663 updateRadius(layid, getRadiusBottom(layid));
673 void setRadius(
int layid,
double rad)
678 os << endl <<
"ERROR in GeoTessPosition::setRadius" << endl
679 <<
"Geographic position has not been specified." << endl;
682 updateRadius(layid, rad);
691 void setRadius(
double rad)
697 os << endl <<
"ERROR in GeoTessPosition::setRadius" << endl
698 <<
"Geographic position has not been specified." << endl;
701 updateRadius(getLayerId(rad), rad);
715 void setDepth(
int layer,
double depth)
717 setRadius(layer, getEarthRadius()-depth);
726 void setDepth(
double depth)
728 setRadius(getEarthRadius()-depth);
736 void setTop(
int layid)
741 os << endl <<
"ERROR in GeoTessPosition::setRadius" << endl
742 <<
"Geographic position has not been specified." << endl;
745 tessid = layerTessIds[layid];
746 checkTessellation(tessid);
747 updateRadius(layid, getRadiusTop(layid));
756 void setBottom(
int layid)
761 os << endl <<
"ERROR in GeoTessPosition::setRadius" << endl
762 <<
"Geographic position has not been specified." << endl;
765 tessid = layerTessIds[layid];
766 checkTessellation(tessid);
767 updateRadius(layid, getRadiusBottom(layid));
777 double getRadiusTop(
int layid);
785 double getRadiusBottom(
int layid);
792 double getEarthRadius()
794 if (earthRadius < 0.)
795 earthRadius = GeoTessUtils::getEarthRadius(unitVector);
813 void copyVector(
double* u)
814 { u[0] = unitVector[0]; u[1] = unitVector[1]; u[2] = unitVector[2]; };
836 const vector<int>&
getVertices()
const {
return vertices[tessid]; };
843 int getIndexOfClosestVertex()
const;
851 const double* getClosestVertex()
const
853 return grid.getVertex(getIndexOfClosestVertex());
862 int getVertex(
int index)
863 {
return vertices[tessid][index]; }
870 void getCoefficients(map<int, double>& coefficients)
872 coefficients.clear();
873 vector<int>& vtx = vertices[tessid];
874 vector<double>& hc = hCoefficients[tessid];
875 for (
int i = 0; i < (int) vtx.size(); ++i)
876 modlProfiles[vtx[i]][layerId]->getCoefficients(coefficients, radius, hc[i]);
888 void setMaxTessLevel(
int layid,
int maxTess)
890 maxTessLevel[layerTessIds[layid]] = maxTess;
891 triangle[layerTessIds[layid]] = -1;
892 checkTessellation(tessid);
904 int getMaxTessLevel(
int layid)
905 {
return maxTessLevel[layerTessIds[layid]]; }
923 int getTessLevel(
const int& tId) { checkTessellation(tId);
return tessLevels[tId]; }
930 double getRadiusTop()
938 double getRadiusBottom()
948 return getEarthRadius() - getRadiusTop(layerId);
956 double getDepthBottom()
958 return getEarthRadius() - getRadiusBottom(layerId);
967 double getDepthTop(
int layid)
969 return getEarthRadius() - getRadiusTop(layid);
978 double getDepthBottom(
int layid)
980 return getEarthRadius() - getRadiusBottom(layid);
989 double getLayerThickness(
int layid)
991 return getRadiusTop(layid) - getRadiusBottom(layid);
999 double getLayerThickness()
1001 return getRadiusTop() - getRadiusBottom();
1017 {
return getEarthRadius() - radius; };
1039 int getLayerId(
double rad)
1041 for (
int i=0; i<nLayers; ++i)
1042 if (rad <= getRadiusTop(i))
1045 for (
int i=nLayers-1; i>=0; --i)
1046 if (getLayerThickness(i) > 0)
1069 double getErrorValue()
1080 void setErrorValue(
double errVal)
1082 errorValue = errVal;
1092 int getVertexIndex()
1094 vector<int>& vtid = vertices[tessid];
1095 vector<double>& htid = hCoefficients[tessid];
1096 for (
int v = 0; v < (int) vtid.size(); ++v)
1097 if (htid[v] > 0.999999999)
1126 void getWeights(map<int, double>& weights,
double dkm)
1128 vector<int>& vtx = vertices[tessid];
1129 vector<double>& htid = hCoefficients[tessid];
1130 for (
int i = 0; i < (int) vtx.size(); ++i)
1131 modlProfiles[vtx[i]][layerId]->getWeights(weights, dkm, radius, htid[i]);
1141 const vector<double>& getHorizontalCoefficients()
const
1143 return hCoefficients[tessid];
1154 double getHorizontalCoefficient(
int index)
const
1156 return hCoefficients[tessid][index];
1174 bool isRadiusOutOfRangeAllowed()
1176 return radiusOutOfRangeAllowed;
1194 void setRadiusOutOfRangeAllowed(
bool allowed)
1196 if (allowed != radiusOutOfRangeAllowed)
1197 clearRadialCoefficients();
1199 radiusOutOfRangeAllowed = allowed;
1210 void removeReference()
1212 if (isNotReferenced())
1215 os << endl <<
"ERROR in Polygon::removeReference" << endl
1216 <<
"Reference count (" << refCount <<
") is already zero." << endl;
1228 int getReferenceCount()
1243 #endif // GEOTESSPOSITION_OBJECT_H