53 using namespace geotess;
92 Location(
const double &lat,
const double &lon,
const double &depth=0);
95 Location(
const double v[],
const double &radius);
118 string toString()
const;
126 void setLocation(
const double& lat,
const double& lon,
const double& depth);
134 { v[0]=u[0]; v[1]=u[1]; v[2]=u[2]; radius=r; }
140 void setRadius(
const double &r);
146 double getRadius()
const;
159 double getDepth()
const;
165 void setDepth(
const double &depth);
173 double distance(
const Location& other)
const;
186 double distanceDegrees(
const Location& other)
const;
195 double azimuth(
const Location& other)
const;
204 double azimuthDegrees(
const Location& other)
const;
221 double azimuth(
const Location& other,
const double& errorValue)
const;
238 double azimuthDegrees(
const Location& other,
const double& errorValue)
const;
244 double getLat()
const;
251 {
return asin(v[2]); }
258 {
return asin(v[2]) * RAD_TO_DEG; }
266 double getLon()
const;
272 double getLatDegrees()
const;
280 double getLonDegrees()
const;
299 void move(
const double &azimuth,
const double &distance,
Location &loc)
const;
336 bool vectorTripleProduct(
const Location& other,
double vtp[])
const;
350 void move(
const double vtp[],
const double& a,
Location& loc)
const;
362 void move_north(
const double x[],
const double &distance,
double z[])
const;
372 void move_north(
const double &distance,
Location &loc)
const;
382 void rotate (
const double x[],
const double p[],
const double &a,
392 double scalarTripleProduct(
const Location& loc1,
const Location& loc2)
const;
400 double scalarTripleProduct(
const double u[],
const double w[])
const;
407 double scalarTripleProduct(
const double u[],
const double v[],
408 const double w[])
const;
416 bool vectorTripleProduct(
const double u[],
const double v[],
double vtp[])
const;
425 bool vectorTripleProductNorthPole(
const double u[],
double w[])
const;
432 void move(
const double v[],
const double vtp[],
const double& a,
442 double angle(
const double u[],
const double v[])
const;
450 double dot(
const Location& other)
const;
458 double dot(
const double u[],
const double v[])
const;
468 double cross(
const double u[],
const double v[],
double w[])
const;
477 double crossNorth(
const double u[],
double w[])
const;
485 double normalize(
double v[])
const;
491 double length(
const double v[])
const;
527 inline void Location::setLocation(
const double& latitude,
528 const double& longitude,
const double& depth)
531 double x = atan((1.0 - EARTH_E) * tan(latitude));
537 v[0] = x * cos(longitude);
538 v[1] = x * sin(longitude);
539 radius = getEarthRadius() - depth;
542 inline double Location::getLat()
const
545 return atan(tan(asin(v[2]))/(1-EARTH_E));
548 inline double Location::getLon()
const
550 return atan2(v[1],v[0]);
553 inline double Location::getLatDegrees()
const
555 return RAD_TO_DEG * getLat();
558 inline double Location::getLonDegrees()
const
560 return RAD_TO_DEG * getLon();
563 inline double Location::getRadius()
const
568 inline void Location::setRadius(
const double &r)
573 inline double Location::getDepth()
const
575 return getEarthRadius() - radius;
578 inline void Location::setDepth(
const double &depth)
580 radius = getEarthRadius() - depth;
583 inline double Location::distance(
const Location& other)
const
585 return angle(v, other.
v);
588 inline double Location::distanceDegrees(
const Location& other)
const
590 return angle(v, other.
v) * RAD_TO_DEG;
593 inline double Location::azimuth(
const Location& other)
const
595 return azimuth(other, 0.);
598 inline double Location::azimuth(
const Location& other,
const double& errorValue)
const
600 double azim=errorValue;
604 if (cross(v, other.
v, c2) > 0.)
612 if (crossNorth(v, c) > 0.)
618 if (c2[2] < 0.) azim = 2.0 * PI - azim;
624 inline double Location::azimuthDegrees(
const Location& other)
const
626 return azimuth(other) * RAD_TO_DEG;
629 inline double Location::azimuthDegrees(
const Location& other,
const double& errorValue)
const
631 double az = azimuth(other, errorValue);
632 if (az != errorValue)
638 inline void Location::move(
const double &azimuth,
const double &distance,
643 move_north(v, distance, x);
646 rotate(x, v, -azimuth, loc.
v);
651 inline void Location::move_north(
const double x[],
const double &distance,
655 vectorTripleProductNorthPole(x, c);
656 move(x, c, distance, z);
660 inline void Location::move_north(
const double &distance,
Location &loc)
const
663 vectorTripleProductNorthPole(v, vtp);
664 move(v, vtp, distance, loc.
v);
670 inline void Location::move(
const double vtp[],
const double& a,
Location& loc)
const
672 move(v, vtp, a, loc.
v);
679 inline void Location::move(
const double w[],
const double vtp[],
680 const double& a,
double u[])
const
682 double cosa = cos(a);
683 double sina = sin(a);
684 u[0] = cosa * w[0] + sina * vtp[0];
685 u[1] = cosa * w[1] + sina * vtp[1];
686 u[2] = cosa * w[2] + sina * vtp[2];
691 inline bool Location::vectorTripleProduct(
const Location& other,
double vtp[])
const
693 return vectorTripleProduct(v, other.
v, vtp);
698 inline bool Location::vectorTripleProduct(
const double u[],
const double s[],
703 q0 = u[1] * s[2] - u[2] * s[1];
704 q1 = u[2] * s[0] - u[0] * s[2];
705 q2 = u[0] * s[1] - u[1] * s[0];
707 w[0] = q1 * u[2] - q2 * u[1];
708 w[1] = q2 * u[0] - q0 * u[2];
709 w[2] = q0 * u[1] - q1 * u[0];
713 return normalize(w) != 0.;
718 inline bool Location::vectorTripleProductNorthPole(
const double u[],
723 w[2] = u[1] * u[1] + u[0] * u[0];
724 return normalize(w) != 0.;
727 inline double Location::scalarTripleProduct(
const Location& loc1,
const Location& loc2)
const
729 return scalarTripleProduct(loc1.
v, loc2.
v, v);
732 inline double Location::scalarTripleProduct(
const double u[],
const double p[],
733 const double w[])
const
735 return u[0] * p[1] * w[2] + p[0] * w[1] * u[2] + w[0] * u[1] * p[2] -
736 w[0] * p[1] * u[2] - u[0] * w[1] * p[2] - p[0] * u[1] * w[2];
739 inline double Location::scalarTripleProduct(
const double v1[],
740 const double v2[])
const
742 return scalarTripleProduct(v1, v2, v);
749 rotate(v, p.
v, a, loc.
v);
754 inline void Location::rotate (
const double x[],
const double p[],
755 const double &a,
double z[])
const
757 double d = x[0] * p[0] + x[1] * p[1] + x[2] * p[2];
759 if (d <= -1. || d >= 1.0)
761 z[0] = x[0]; z[1] = x[1]; z[2] = x[2];
765 double cosa = cos(a);
766 double sina = sin(a);
768 z[0] = cosa * x[0] + d * p[0] + sina * (p[1] * x[2] - p[2] * x[1]);
769 z[1] = cosa * x[1] + d * p[1] + sina * (p[2] * x[0] - p[0] * x[2]);
770 z[2] = cosa * x[2] + d * p[2] + sina * (p[0] * x[1] - p[1] * x[0]);
771 double len = sqrt(z[0] * z[0] + z[1] * z[1] + z[2] * z[2]);
779 inline double Location::angle(
const double u[],
const double w[])
const
781 return acos(max(min(dot(u, w), 1.0), -1.0));
784 inline double Location::dot(
const Location& other)
const
786 return v[0] * other.
v[0] + v[1] * other.
v[1] + v[2] * other.
v[2];
790 inline double Location::dot(
const double u[],
const double s[])
const
792 return u[0] * s[0] + u[1] * s[1] + u[2] * s[2];
800 if (cross(v, x.
v, loc.
v) > 0.)
809 inline double Location::cross(
const double u[],
const double s[],
812 w[0] = u[1] * s[2] - u[2] * s[1];
813 w[1] = u[2] * s[0] - u[0] * s[2];
814 w[2] = u[0] * s[1] - u[1] * s[0];
820 inline double Location::crossNorth(
const double u[],
double w[])
const
822 double len = u[0] * u[0] + u[1] * u[1];
842 inline double Location::normalize(
double u[])
const
844 double len = length(u);
847 u[0] = u[1] = u[2] = 0.0;
859 inline double Location::length(
const double u[])
const
861 double l = dot(u, u);
862 if (l > 0.)
return sqrt(l);
866 inline string Location::toString()
const
871 << std::setprecision(4)
872 << std::setw(9) << getLatDegrees()
874 << std::setw(10) << getLonDegrees()
876 << std::setprecision(3)
877 << std::setw(10) << getDepth();
The Location Class manages a single point in/on the Earth, which is described by the GRS80 ellipsoid.
double getGeocentricLatDegrees() const
Retrieve the geocentric latitude of this Location, degrees.
Location(const Location &location)
Location(const double v[], const double &radius)
static int getClassCount()
static double EARTH_RADIUS
double getEarthRadius() const
void setLocation(const double *u, const double &r)
bool operator!=(const Location &other)
static int locationClassCount
void setUnitVector(double x[3])
double distanceKm(Location &other) const
bool operator==(const Location &other) const
Location(const Location &loc1, const Location &loc2)
Location & operator=(const Location &other)
double getGeocentricLat() const
Retrieve the geocentric latitude of this Location, radians.
const double * getUnitVector()
Location(const double &lat, const double &lon, const double &depth=0)
void getUnitVector(double x[3])