/* -*-c++-*- */ /* osgEarth - Geospatial SDK for OpenSceneGraph * Copyright 2020 Pelican Mapping * http://osgearth.org * * osgEarth 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 of the License, or * (at your option) any later version. * * This program 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 this program. If not, see */ #ifndef OSGEARTH_GEOMATH_H #define OSGEARTH_GEOMATH_H 1 #include #include #include #include #include namespace osgEarth { /** * Useful calculations for lat/long points. * Converted from http://www.movable-type.co.uk/scripts/latlong.html */ class OSGEARTH_EXPORT GeoMath { public: /** *Computes the distance between the given points in meters using the Haversine formula * @param lat1Rad * The start latitude in radians * @param lon1Rad * The start longitude in radians * @param lat2Rad * The end latitude in radians * @param lon2Rad * The end longitude in radians * @param radius * The radius of the earth in meters * @returns * The distance between the two points in meters */ static double distance(double lat1Rad, double lon1Rad, double lat2Rad, double lon2Rad, double radius = osg::WGS_84_RADIUS_EQUATOR); /** *Computes the ground distance covered by the given path in meters using the Haversine formula *Assumes the points in Lon, Lat in degrees */ static double distance(const std::vector< osg::Vec3d > &points, double radius = osg::WGS_84_RADIUS_EQUATOR); /** * Computes the ground distance between two points, in meters. */ static double distance(const osg::Vec3d& p1, const osg::Vec3d& p2, const SpatialReference* srs); /** * Computes the initial bearing from one point to the next in radians * @param lat1Rad * The start latitude in radians * @param lon1Rad * The start longitude in radians * @param lat2Rad * The end latitude in radians * @param lon2Rad * The end longitude in radians * @returns * The initial bearing in radians */ static double bearing(double lat1Rad, double lon1Rad, double lat2Rad, double lon2Rad); /** *Computes the midpoint between two points * @param lat1Rad * The start latitude in radians * @param lon1Rad * The start longitude in radians * @param lat2Rad * The end latitude in radians * @param lon2Rad * The end longitude in radians * @param out_latRad * The latitude of the midpoint in radians * @param out_lonRad * The longitude of the midpoint in radians */ static void midpoint(double lat1Rad, double lon1Rad, double lat2Rad, double lon2Rad, double &out_latRad, double &out_lonRad); /** * Computes the destination point given a start point, a bearing and a distance * @param lat1Rad * The latitude in radians * @param lon1Rad * The longitude in radians * @param bearingRad * The bearing in radians * @param distance * The distance in meters * @param out_latRad * The destination point's latitude in radians * @param out_lonRad * The destination points' longitude in radians * @param radius * The radius of the earth in meters */ static void destination(double lat1Rad, double lon1Rad, double bearingRad, double distance, double &out_latRad, double &out_lonRad, double radius = osg::WGS_84_RADIUS_EQUATOR); /** * Calculates the minimum and maximum latitudes along a great circle * between the two geodetic input points. */ static void greatCircleMinMaxLatitude( double lat1Rad, double lon1Rad, double lat2Rad, double lon2Rad, double& out_minLatRad, double& out_maxLatRad); /** * Computes the distance between two points in meters following a rhumb line * @param lat1Rad * The start latitude in radians * @param lon1Rad * The start longitude in radians * @param lat2Rad * The end latitude in radians * @param lon2Rad * The end longitude in radians * @param radius * The radius of the earth in meters * @returns * The distance between the two points in meters following a rhumb line */ static double rhumbDistance(double lat1Rad, double lon1Rad, double lat2Rad, double lon2Rad, double radius = osg::WGS_84_RADIUS_EQUATOR); /** * Computes the distance between two points in meters following a rhumb line * Assumes the points are in Lon, Lat in degrees */ static double rhumbDistance(const std::vector< osg::Vec3d > &points, double radius = osg::WGS_84_RADIUS_EQUATOR); /** *Computes the bearing of the rhumb line between two points in radians * @param lat1Rad * The start latitude in radians * @param lon1Rad * The start longitude in radians * @param lat2Rad * The end latitude in radians * @param lon2Rad * The end longitude in radians */ static double rhumbBearing(double lat1Rad, double lon1Rad, double lat2Rad, double lon2Rad); /** Computes the destination point given a start point, a bearing and a distance along a rhumb line * @param lat1Rad * The latitude in radians * @param lon1Rad * The longitude in radians * @param bearingRad * The bearing in radians * @param distance * The distance in meters * @param out_latRad * The destination point's latitude in radians * @param out_lonRad * The destination points' longitude in radians * @param radius * The radius of the earth in meters */ static void rhumbDestination(double lat1Rad, double lon1Rad, double bearing, double distance, double &out_latRad, double &out_lonRad, double radius = osg::WGS_84_RADIUS_EQUATOR); /** * Computes the intersection(s) of a line with a sphere. * Returns the number of intersections: 0, 1, or 2. */ static unsigned interesectLineWithSphere(const osg::Vec3d& p0, const osg::Vec3d& p1, double radius, osg::Vec3d& out_i0, osg::Vec3d& out_i1); /** * Computes the intersection(s) of a line with a plane. * Returns the number of intersections: 0 or 1. */ static unsigned intersectLineWithPlane(const osg::Vec3d& p0, const osg::Vec3d& p1, const osg::Plane& plane, osg::Vec3d& out_i0); /** * Whether the target point is visible from the eye point in a * spherical earth approximation with the given Radius. */ static bool isPointVisible(const osg::Vec3d& eye, const osg::Vec3d& target, double radius = osg::WGS_84_RADIUS_EQUATOR); }; }; #endif