📄 position.hpp
字号:
#pragma ident "$Id: Position.hpp 693 2007-07-19 14:56:11Z pben $"/** * @file Position.hpp * class gpstk::Position encapsulates 3-D positions, including geographic positions, * expressed as geodetic (with respect to an ellipsoidal geoid), geocentric or * Earth-centered, Earth-fixed (cartesian) coordinates, as well as ordinary * positions defined by spherical or cartesian coordinates. Position inherits * from class Triple. */#ifndef GPSTK_POSITION_HPP#define GPSTK_POSITION_HPP//============================================================================//// This file is part of GPSTk, the GPS Toolkit.//// The GPSTk is free software; you can redistribute it and/or modify// it under the terms of the GNU Lesser General Public License as published// by the Free Software Foundation; either version 2.1 of the License, or// any later version.//// The GPSTk is distributed in the hope that it will be useful,// but WITHOUT ANY WARRANTY; without even the implied warranty of// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the// GNU Lesser General Public License for more details.//// You should have received a copy of the GNU Lesser General Public// License along with GPSTk; if not, write to the Free Software Foundation,// Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA// // Copyright 2004, The University of Texas at Austin////============================================================================#include "Exception.hpp"#include "StringUtils.hpp"#include "DayTime.hpp" // for FormatException#include "Triple.hpp"#include "GeoidModel.hpp"#include "Xvt.hpp"namespace gpstk{ /** @addtogroup geodeticgroup */ //@{ // The following forward declaration of Position and range are the only // way I can get range to be a member of namespace gpstk. class Position; double range(const Position& A, const Position& B) throw(GeometryException); /** * A position representation class for common 3D geographic position formats, * including geodetic (geodetic latitude, longitude, and height above the geoid) * geocentric (geocentric latitude, longitude, and radius from Earth's center), * cartesian (Earth-centered, Earth-fixed) and spherical (theta,phi,radius). * * Internally, the representation of Position consists of three coordinate * values (double), two doubles from a geoid model (see below, storing these * doubles is preferred over adding GeoidModel to calling arguments everywhere), * a flag of type 'enum CoordinateSystem' giving the coordinate system, and a * tolerance for use in comparing Positions. Class Position inherits from class * Triple, which is how the coordinate values are stored (Triple actually uses * std::valarray<double> of length 3). It is important to note that * Triple:: routines are properly used by Positions ONLY in the Cartesian * coordinate system. * * Only geodetic coordinates depend on a geoid, and then (for an ellipsoidal * geoid) only on the semi-major axis of the Earth and the square of its * eccentricity. Input of this geoid information (usually a pointer to a * GeoidModel) is required by functions involving constructors of, or * transformation to or from, Geodetic coordinates. However since a default * is supplied (WGS84), the user need never deal with geiods unless desired. * In fact, if the geodetic coordinate system is avoided, the Position class * can be interpreted simply as 3D vectors in any context, particularly since * the class inherits from Triple, which includes many vector manipulation * routines (although the Triple:: routines assume Cartesian coordinates). * Even the requirement that lengths (radius, height and the cartesian * coordinates) have units of meters is required only if geodetic coordinates * are used (because the semi-major axis in GeoidModel is in meters); * without using Geodetic one could apply the class using any units for * length as long as setTolerance() is called appropriately. * * Position relies on a series of fundamental routines to transform from * one coordinate system to another, these include, for example * void Position::convertGeodeticToCartesian(const Triple& llh, Triple& xyz, * const double A, const double eccSq); * void Position::convertSphericalToCartesian(const Triple& tpr, Triple& xyz); * These functions use Triple in the calling arguments. * * Position will throw exceptions (gpstk::GeometryException) on bad input * (e.g. negative radius or latitude > 90 degrees); otherwise the class * attempts to handle all points, even the pole and the origin, consistently * and without throwing exceptions. * At or very near the poles, the transformation routines will set * latitude = +/-90 degrees, which is theta = 0 or 180, and (arbitrarily) * longitude = 0. At or very near the origin, the transformation routines * will set latitude = 0, which is theta = 90, and (arbitrarily) longitude = 0; * radius will be set to zero and geodetic height will be set to * -radius(Earth) (= -6378137.0 in WGS84). The tolerance used in testing * 'at or near the pole or origin' is radius < POSITION_TOLERANCE/5. * Note that this implies that a Position that is very near the origin may * be SET to the exact origin by the transformation routines, and that * thereby information about direction (e.g. latitude and longitude) * may be LOST. The user is warned to be very careful when working * near either the pole or the origin. * * Position includes setToString() and printf() functions similar to those * in gpstk::DayTime; this allows flexible and powerful I/O of Position to * strings and streams. * * @sa positiontest.cpp for examples. */ class Position : public Triple { public: // ----------- Part 1: coordinate systems -------------------------------- // /// The coordinate systems supported by Position enum CoordinateSystem { Unknown=0, ///< unknown coordinate system Geodetic, ///< geodetic latitude, longitude, and height above geoid Geocentric, ///< geocentric (regular spherical coordinates) Cartesian, ///< cartesian (Earth-centered, Earth-fixed) Spherical ///< spherical coordinates (theta,phi,radius) }; /// return string giving name of coordinate system std::string getSystemName() throw(); // ----------- Part 2: member functions: tolerance ----------------------- // /// One millimeter tolerance. static const double ONE_MM_TOLERANCE; /// One centimeter tolerance. static const double ONE_CM_TOLERANCE; /// One micron tolerance. static const double ONE_UM_TOLERANCE; /// Default tolerance for time equality in days. static double POSITION_TOLERANCE; /// Changes the POSITION_TOLERANCE for all Position objects static double setPositionTolerance(const double tol) { POSITION_TOLERANCE = tol; return POSITION_TOLERANCE; } /// Returns the current POSITION_TOLERANCE. static double getPositionTolerance() { return POSITION_TOLERANCE; } /** * Sets the tolerance for output and comparisons, for this object only. * See the constants in this file (e.g. ONE_MM_TOLERANCE) * for some easy to use tolerance values. * @param tol Tolerance in meters to be used by comparison operators. * @sa Position-Specific Definitions */ Position& setTolerance(const double tol) throw(); // ----------- Part 3: member functions: constructors -------------------- // /** * Default constructor. * Initializes to zero, Unknown coordinates */ Position() throw(); /** * Explicit constructor. Coordinate system may be specified on input, * but defaults to Cartesian. Pointer to GeoidModel may be specified, * but default is NULL (in which case WGS84 values will be used). * @param a first coordinate [ X(m), or latitude (degrees N) ] * @param b second coordinate [ Y(m), or longitude (degrees E) ] * @param c third coordinate [ Z, height above ellipsoid or radius, in m ] * @param s coordinate system * @param geoid pointer to GeoidModel * @throw GeometryException on invalid input. */ Position(const double& a, const double& b, const double& c, CoordinateSystem s = Cartesian, GeoidModel *geoid = NULL) throw(GeometryException); /** * Explicit constructor. Coordinate system may be specified on input, * but defaults to Cartesian. Pointer to GeoidModel may be specified, * but default is NULL (in which case WGS84 values will be used). * @param ABC double array[3] coordinate values * @param s CoordinateSystem * @param geoid pointer to GeoidModel * @throw GeometryException on invalid input. */ Position(const double ABC[3], CoordinateSystem s = Cartesian, GeoidModel *geoid = NULL) throw(GeometryException); /** * Explicit constructor. Coordinate system may be specified on input, * but defaults to Cartesian. Pointer to GeoidModel may be specified, * but default is NULL (in which case WGS84 values will be used). * @param ABC coordinate values * @param s CoordinateSystem * @param geoid pointer to GeoidModel * @throw GeometryException on invalid input. */ Position(const Triple& ABC, CoordinateSystem s = Cartesian, GeoidModel *geoid = NULL) throw(GeometryException); /** * Explicit constructor from Xvt. The coordinate system is Cartesian, * and the velocity and time information in the input is ignored. * @param xvt Input Xvt object, xvt.x contains the Cartesian coordinates */ Position(const Xvt& xvt) throw(); /// Destructor. ~Position() throw() {} // ----------- Part 4: member functions: arithmetic ---------------------- // /** Subtract a Position from this Position. Perform the subtraction in * Cartesian coordinates, but return this Position to the system it * had originally. * @param right Position to subtract from this one. * @return new Position, in the original system. */ Position& operator-=(const Position& right) throw(); /** Add a Position to this Position. Perform the addition in * Cartesian coordinates, but return this Position to the system it * had originally. * @param right Position to add to this one. * @return new Position, in the original system. */ Position& operator+=(const Position& right) throw(); /** * Difference two Positions, returning result as a Position in Cartesian * coordinates, the only system in which a position difference makes sense. * @param right Position to subtract from this one. * @return difference as Position. */ friend Position operator-(const Position& left, const Position& right) throw(); /** * Add two Positions, returning result as a Position in Cartesian * coordinates, the only system in which a position sum makes sense. * @param right Position to add to this one. * @return The new Position. */ friend Position operator+(const Position& left, const Position& right) throw(); /** Multiply a Position by a double scalar on the left. * @param right Position to be multiplied by the scalar * @param scale the (double) scalar * @return The new Position. */ friend Position operator*(const double& scale, const Position& right) { Position tmp(right); tmp.theArray *= scale; return tmp; } /** Multiply a Position by a double scalar on the right. * @param left Position to be multiplied by the scalar * @param scale the (double) scalar * @return The new Position. */ friend Position operator*(const Position& left, const double& scale) { return operator*(scale, left); } /** Multiply a Position by an integer scalar on the left. * @param right Position to be multiplied by the scalar * @param scale the (int) scalar * @return The new Position. */ friend Position operator*(const int& scale, const Position& right) { return operator*(double(scale), right); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -