34 static ossimTrace traceExec (
"ossimEllipsoid:exec");
35 static ossimTrace traceDebug (
"ossimEllipsoid:debug");
44 theName(ellipsoid.theName),
45 theCode(ellipsoid.theCode),
46 theEpsgCode(ellipsoid.theEpsgCode),
49 theFlattening(ellipsoid.theFlattening),
50 theA_squared(ellipsoid.theA_squared),
51 theB_squared(ellipsoid.theB_squared),
52 theEccentricitySquared(ellipsoid.theEccentricitySquared)
72 theEpsgCode(epsg_code),
179 const double& offset,
182 static const char MODULE[] =
"ossimEllipsoid::nearestIntersection";
188 bool success =
false;
191 const double CONVERGENCE_THRESHOLD = 0.0001;
192 const int MAX_NUM_ITERATIONS = 10;
200 double start_x = start.
x();
201 double start_y = start.
y();
202 double start_z = start.
z();
204 double direction_x = direction.
x();
205 double direction_y = direction.
y();
206 double direction_z = direction.
z();
214 double rayLat = rayGpt.
latd();
217 double rayN =
theA * rayScale;
219 double A_offset = rayN + offset;
220 double B_offset = rayN * eccSqComp + offset;
222 double A_offset_inv = 1.0 / A_offset;
223 double B_offset_inv = 1.0 / B_offset;
225 double scaled_x = start_x * A_offset_inv;
226 double scaled_y = start_y * A_offset_inv;
227 double scaled_z = start_z * B_offset_inv;
229 double A_over_B = A_offset * B_offset_inv;
235 double a = (direction_x*direction_x + direction_y*direction_y) * A_offset_inv;
236 a += (direction_z*direction_z * B_offset_inv * A_over_B);
238 double b = 2.0 * ( scaled_x*direction_x + scaled_y*direction_y +
239 scaled_z*direction_z*A_over_B );
241 double c = scaled_x*start_x + scaled_y*start_y;
242 c += (scaled_z*start_z * A_over_B);
248 double root =
b*
b - 4.0*
a*c;
254 double squareRoot = sqrt(root);
255 double oneOver2a = 1.0 / (2.0*
a);
257 double t1 = (-
b + squareRoot) * oneOver2a;
258 double t2 = (-
b - squareRoot) * oneOver2a;
274 double tEstimate = t1;
275 if (fabs(t2) < fabs(t1))
282 double offsetError = fabs( rayGpt.
height() - offset );
283 if ( offsetError < CONVERGENCE_THRESHOLD )
290 }
while ( (!done) && (iterations++ < MAX_NUM_ITERATIONS) );
292 if (iterations >= MAX_NUM_ITERATIONS)
297 <<
"WARNING ossimEllipsoid::nearestIntersection: Max number of iterations reached" 298 <<
" solving for intersection point. Result is probably inaccurate." << std::endl;
355 bool foundCode =
false;
375 const char* majorAxis = kwl.
find(prefix,
377 const char* minorAxis = kwl.
find(prefix,
382 if(majorAxis && minorAxis)
403 const char* prefix)
const 444 double& primeVert)
const 446 double lat, lon, hgt;
451 primeVert =
theA / sqrt(phiFac);
468 NEWMAT::Matrix& jMat)
const 472 double lat, lon, hgt;
481 double N_plus_h = primeVert + hgt;
482 double M_plus_h = merRadius + hgt;
484 jMat(1,1) = -sinPhi * cosLam / M_plus_h;
485 jMat(2,1) = -sinLam / (cosPhi * N_plus_h);
486 jMat(3,1) = cosPhi * cosLam;
487 jMat(1,2) = -sinPhi * sinLam / M_plus_h;
488 jMat(2,2) = cosLam / (cosPhi * N_plus_h);
489 jMat(3,2) = cosPhi * sinLam;
490 jMat(1,3) = cosPhi / M_plus_h;
508 NEWMAT::Matrix& jMat)
const 512 double lat, lon, hgt;
521 double N_plus_h = primeVert + hgt;
522 double M_plus_h = merRadius + hgt;
524 jMat(1,1) = -M_plus_h * sinPhi * cosLam;
525 jMat(2,1) = -M_plus_h * sinPhi * sinLam;
526 jMat(3,1) = M_plus_h * cosPhi;
527 jMat(1,2) = -N_plus_h * cosPhi * sinLam;
528 jMat(2,2) = N_plus_h * cosPhi * cosLam;
530 jMat(1,3) = cosPhi * cosLam;
531 jMat(2,3) = cosPhi * sinLam;
546 double cos2_lat = cos_lat*cos_lat;
547 double sin2_lat = sin_lat*sin_lat;
563 double cos2_lat = cos_lat*cos_lat;
564 double sin2_lat = sin_lat*sin_lat;
573 double &
x,
double &
y,
double &z)
const 584 double& lat,
double& lon,
double& height)
const 591 const double tol = 1e-15;
592 const double d = sqrt(
x*
x +
y*
y);
593 const int MAX_ITER = 10;
597 const double pa2 = d * d * a2;
598 const double qb2 = z * z * b2;
600 const double ae4 = ae2 * ae2;
602 const double c3 = -( ae4/2 + pa2 + qb2 );
603 const double c4 = ae2*( pa2 - qb2 );
604 const double c5 = ae4/4 * ( ae4/4 - pa2 - qb2 );
606 double s0 = 0.5 * (a2 + b2) * hypot( d/
theA, z/
theB );
608 for(
int iterIdx = 0; iterIdx < MAX_ITER; ++iterIdx )
610 const double pol = c5 + s0 * ( c4 + s0 * ( c3 + s0 * s0 ) );
611 const double der = c4 + s0 * ( 2 * c3 + 4 * s0 * s0 );
613 const double ds = - pol / der;
616 if( fabs( ds ) < tol * s0 )
618 const double t = s0 - 0.5 * (a2 + b2);
619 const double x_ell = d / ( 1.0 + t/a2 );
620 const double y_ell = z / ( 1.0 + t/b2 );
622 height = ( d - x_ell ) * x_ell/a2 + ( z - y_ell ) * y_ell/b2;
623 height /= hypot( x_ell/a2 , y_ell/b2 );
633 double d = sqrt(
x*
x +
y*
y);
639 double height1 = 0.0;
641 const int MAX_ITER = 10;
642 if (fabs(phi2) > 1e-16 )
644 while ( (p > 1e-17) && (iterIdx < MAX_ITER))
648 height1 = (d / cos(phi1) - N1);
650 p = fabs(phi2 - phi1);
659 height1 = (d / cos(phi1)) - N1;
674 NEWMAT::Matrix& m = localToWorld.
getData();
684 double inverse_length = 1.0/sqrt(
x*
x +
y*
y + z*z);
690 double length_XY = sqrt(
x*
x +
y*
y);
691 double inverse_length_XY = 1.0/length_XY;
694 m[0][0] = -
y*inverse_length_XY;
695 m[1][0] =
x*inverse_length_XY;
699 double Vy_x = -z*
x*inverse_length_XY;
700 double Vy_y = -z*
y*inverse_length_XY;
701 double Vy_z = length_XY;
702 inverse_length = 1.0/sqrt(Vy_x*Vy_x + Vy_y*Vy_y + Vy_z*Vy_z);
703 m[0][1] = Vy_x*inverse_length;
704 m[1][1] = Vy_y*inverse_length;
705 m[2][1] = Vy_z*inverse_length;
723 if (
this != ©_me)
const NEWMAT::Matrix & getData() const
static const char * MINOR_AXIS_KW
double theEccentricitySquared
static ossimEllipsoidFactory * instance()
ossim_uint32 getEpsgCode() const
Represents serializable keyword/value map.
bool loadState(const ossimKeywordlist &kwl, const char *prefix=0)
const char * find(const char *key) const
void jacobianWrtGeo(const ossimEcefPoint &location, NEWMAT::Matrix &jMat) const
const ossimEcefPoint & origin() const
void prinRadiiOfCurv(const ossimEcefPoint &location, double &merRadius, double &primeVert) const
ossim_uint32 toUInt32() const
double latd() const
Will convert the radian measure to degrees.
double evaluate(const ossimEcefPoint &) const
void add(const char *prefix, const ossimKeywordlist &kwl, bool overwrite=true)
const ossimEllipsoid * wgs84() const
static const char * ELLIPSE_CODE_KW
static const char * MAJOR_AXIS_KW
unsigned int ossim_uint32
double eccentricitySquared() const
const ossimEllipsoid * create(const ossimString &code) const
void latLonHeightToXYZ(double lat, double lon, double height, double &x, double &y, double &z) const
void gradient(const ossimEcefPoint &location, ossimEcefVector &result) const
ossimEcefPoint extend(const double &t) const
static const char * ELLIPSE_NAME_KW
void geodeticRadii(const double &latitude, ossimDpt &radii) const
static NEWMAT::Matrix createIdentity()
const ossimEcefVector & direction() const
ossim_uint32 findEpsgCode(const ossimString &alpha_code) const
Given an alpha code (for example "WE" for WGS84), returns the corresponding EPSG code or 0 if not fou...
double geodeticRadius(const double &latitude) const
void jacobianWrtEcef(const ossimEcefPoint &location, NEWMAT::Matrix &jMat) const
const char * c_str() const
Returns a pointer to a null-terminated array of characters representing the string's contents...
bool saveState(ossimKeywordlist &kwl, const char *prefix=0) const
static const char * ELLIPSE_EPSG_CODE_KW
const ossimEllipsoid & operator=(const ossimEllipsoid ©_me)
void computeLocalToWorldTransformFromXYZ(double x, double y, double z, ossimMatrix4x4 &localToWorld) const
bool nearestIntersection(const ossimEcefRay &ray, ossimEcefPoint &rtnPt) const
void XYZToLatLonHeight(double x, double y, double z, double &lat, double &lon, double &height) const
OSSIMDLLEXPORT std::ostream & ossimNotify(ossimNotifyLevel level=ossimNotifyLevel_WARN)