X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=simgear%2Fmath%2Fsg_geodesy.hxx;h=f19e4358460e55965399180dc97a403ed5513835;hb=1f37095087fa7aa3d210ba134058b86c3bd6d69e;hp=0024e54185fe0c4e3fac8faf4acaf8fe357b7b4b;hpb=007b0a8fe666eddc104c9b36aa0f62d7ac737ad3;p=simgear.git diff --git a/simgear/math/sg_geodesy.hxx b/simgear/math/sg_geodesy.hxx index 0024e541..f19e4358 100644 --- a/simgear/math/sg_geodesy.hxx +++ b/simgear/math/sg_geodesy.hxx @@ -2,19 +2,10 @@ #define _SG_GEODESY_HXX #include +#include "SGMath.hxx" -/** - * Convert from geocentric coordinates to geodetic coordinates - * @param lat_geoc (in) Geocentric latitude, radians, + = North - * @param radius (in) C.G. radius to earth center (meters) - * @param lat_geod (out) Geodetic latitude, radians, + = North - * @param alt (out) C.G. altitude above mean sea level (meters) - * @param sea_level_r (out) radius from earth center to sea level at - * local vertical (surface normal) of C.G. (meters) - */ -void sgGeocToGeod(double lat_geoc, double radius, - double *lat_geod, double *alt, double *sea_level_r); - +// Compatibility header. +// Please use the SGGeodesy and SGMath functions directly. /** * Convert from geodetic coordinates to geocentric coordinates. @@ -31,8 +22,18 @@ void sgGeocToGeod(double lat_geoc, double radius, * @param sl_radius (out) SEA LEVEL radius to earth center (meters) * @param lat_geoc (out) Geocentric latitude, radians, + = North */ -void sgGeodToGeoc(double lat_geod, double alt, - double *sl_radius, double *lat_geoc ); +inline void sgGeodToGeoc(double lat_geod, double alt, + double *sl_radius, double *lat_geoc) +{ + SGVec3 cart; + SGGeod geod = SGGeod::fromRadM(0, lat_geod, alt); + SGGeodesy::SGGeodToCart(geod, cart); + SGGeoc geoc; + SGGeodesy::SGCartToGeoc(cart, geoc); + *lat_geoc = geoc.getLatitudeRad(); + *sl_radius = SGGeodesy::SGGeodToSeaLevelRadius(geod); +} + /** * Convert a cartesian point to a geodetic lat/lon/altitude. @@ -42,7 +43,14 @@ void sgGeodToGeoc(double lat_geod, double alt, * @param lon (out) Longitude, in radians * @param alt (out) Altitude, in meters above the WGS84 ellipsoid */ -void sgCartToGeod(const double* xyz, double* lat, double* lon, double* alt); +inline void sgCartToGeod(const double* xyz, double* lat, double* lon, double* alt) +{ + SGGeod geod; + SGGeodesy::SGCartToGeod(SGVec3(xyz), geod); + *lat = geod.getLatitudeRad(); + *lon = geod.getLongitudeRad(); + *alt = geod.getElevationM(); +} /** * Convert a cartesian point to a geodetic lat/lon/altitude. @@ -53,10 +61,9 @@ void sgCartToGeod(const double* xyz, double* lat, double* lon, double* alt); */ inline Point3D sgCartToGeod(const Point3D& p) { - double lat, lon, alt, xyz[3]; - xyz[0] = p.x(); xyz[1] = p.y(); xyz[2] = p.z(); - sgCartToGeod(xyz, &lat, &lon, &alt); - return Point3D(lon, lat, alt); + SGGeod geod; + SGGeodesy::SGCartToGeod(SGVec3(p.x(), p.y(), p.z()), geod); + return Point3D::fromSGGeod(geod); } @@ -68,7 +75,14 @@ inline Point3D sgCartToGeod(const Point3D& p) * @param alt (in) Altitude, in meters above the WGS84 ellipsoid * @param xyz (out) Pointer to cartesian point. */ -void sgGeodToCart(double lat, double lon, double alt, double* xyz); +inline void sgGeodToCart(double lat, double lon, double alt, double* xyz) +{ + SGVec3 cart; + SGGeodesy::SGGeodToCart(SGGeod::fromRadM(lon, lat, alt), cart); + xyz[0] = cart(0); + xyz[1] = cart(1); + xyz[2] = cart(2); +} /** * Convert a geodetic lat/lon/altitude to a cartesian point. @@ -79,15 +93,15 @@ void sgGeodToCart(double lat, double lon, double alt, double* xyz); */ inline Point3D sgGeodToCart(const Point3D& geod) { - double xyz[3]; - sgGeodToCart(geod.lat(), geod.lon(), geod.elev(), xyz); - return Point3D(xyz[0], xyz[1], xyz[2]); + SGVec3 cart; + SGGeodesy::SGGeodToCart(SGGeod::fromRadM(geod.lon(), geod.lat(), geod.elev()), cart); + return Point3D::fromSGVec3(cart); } /** * Given a starting position and an offset radial and distance, * calculate an ending positon on a wgs84 ellipsoid. - * @param alt (in) meters + * @param alt (in) meters (unused) * @param lat1 (in) degrees * @param lon1 (in) degrees * @param az1 (in) degrees @@ -96,16 +110,42 @@ inline Point3D sgGeodToCart(const Point3D& geod) * @param lon2 (out) degrees * @param az2 (out) return course in degrees */ -int geo_direct_wgs_84 ( double alt, double lat1, +inline int geo_direct_wgs_84 ( double lat1, double lon1, double az1, + double s, double *lat2, double *lon2, + double *az2 ) +{ + SGGeod p2; + if (!SGGeodesy::direct(SGGeod::fromDeg(lon1, lat1), az1, s, p2, *az2)) + return 1; + *lat2 = p2.getLatitudeDeg(); + *lon2 = p2.getLongitudeDeg(); + return 0; +} +inline int geo_direct_wgs_84 ( double alt, double lat1, double lon1, double az1, double s, double *lat2, double *lon2, - double *az2 ); + double *az2 ) +{ return geo_direct_wgs_84(lat1, lon1, az1, s, lat2, lon2, az2); } +/** + * Given a starting position and an offset radial and distance, + * calculate an ending positon on a wgs84 ellipsoid. + * @param p1 (in) geodetic position + * @param az1 (in) degrees + * @param s (in) distance in meters + * @param p2 (out) geodetic position + * @param az2 (out) return course in degrees + */ +inline int geo_direct_wgs_84(const SGGeod& p1, double az1, + double s, SGGeod& p2, double *az2 ) +{ + return !SGGeodesy::direct(p1, az1, s, p2, *az2); +} /** * Given an altitude and two sets of (lat, lon) calculate great circle * distance between them as well as the starting and ending azimuths. - * @param alt (in) meters + * @param alt (in) meters (unused) * @param lat1 (in) degrees * @param lon1 (in) degrees * @param lat2 (in) degrees @@ -114,9 +154,33 @@ int geo_direct_wgs_84 ( double alt, double lat1, * @param az2 (out) end heading degrees * @param s (out) distance meters */ -int geo_inverse_wgs_84( double alt, double lat1, - double lon1, double lat2, - double lon2, double *az1, double *az2, - double *s ); +inline int geo_inverse_wgs_84( double lat1, double lon1, double lat2, + double lon2, double *az1, double *az2, + double *s ) +{ + return !SGGeodesy::inverse(SGGeod::fromDeg(lon1, lat1), + SGGeod::fromDeg(lon2, lat2), *az1, *az2, *s); +} +inline int geo_inverse_wgs_84( double alt, double lat1, + double lon1, double lat2, + double lon2, double *az1, double *az2, + double *s ) +{ return geo_inverse_wgs_84(lat1, lon1, lat2, lon2, az1, az2, s); } + + +/** + * Given an altitude and two sets of (lat, lon) calculate great circle + * distance between them as well as the starting and ending azimuths. + * @param p1 (in) first position + * @param p2 (in) fsecond position + * @param az1 (out) start heading degrees + * @param az2 (out) end heading degrees + * @param s (out) distance meters + */ +inline int geo_inverse_wgs_84(const SGGeod& p1, const SGGeod& p2, + double *az1, double *az2, double *s ) +{ + return !SGGeodesy::inverse(p1, p2, *az1, *az2, *s); +} #endif // _SG_GEODESY_HXX