2015-01-20 10:24:49 -05:00
|
|
|
#ifndef COORDINATE_CALCULATION
|
|
|
|
#define COORDINATE_CALCULATION
|
|
|
|
|
2016-02-23 15:23:13 -05:00
|
|
|
#include "util/coordinate.hpp"
|
2016-01-21 07:07:24 -05:00
|
|
|
|
2016-03-16 16:54:29 -04:00
|
|
|
#include <boost/math/constants/constants.hpp>
|
|
|
|
|
2015-01-20 10:24:49 -05:00
|
|
|
#include <utility>
|
|
|
|
|
2016-01-05 10:51:13 -05:00
|
|
|
namespace osrm
|
|
|
|
{
|
|
|
|
namespace util
|
|
|
|
{
|
2016-03-16 16:54:29 -04:00
|
|
|
namespace coordinate_calculation
|
|
|
|
{
|
2016-01-05 10:51:13 -05:00
|
|
|
|
2016-03-16 16:54:29 -04:00
|
|
|
const constexpr long double DEGREE_TO_RAD = 0.017453292519943295769236907684886;
|
|
|
|
const constexpr long double RAD_TO_DEGREE = 1. / DEGREE_TO_RAD;
|
2016-01-12 09:41:30 -05:00
|
|
|
// earth radius varies between 6,356.750-6,378.135 km (3,949.901-3,963.189mi)
|
|
|
|
// The IUGG value for the equatorial radius is 6378.137 km (3963.19 miles)
|
|
|
|
const constexpr long double EARTH_RADIUS = 6372797.560856;
|
2016-03-16 16:54:29 -04:00
|
|
|
// radius used by WGS84
|
|
|
|
const constexpr double EARTH_RADIUS_WGS84 = 6378137.0;
|
2016-01-12 09:41:30 -05:00
|
|
|
|
2016-03-16 16:54:29 -04:00
|
|
|
namespace detail
|
2015-01-20 10:24:49 -05:00
|
|
|
{
|
2016-03-28 14:38:19 -04:00
|
|
|
// earth circumference devided by 2
|
|
|
|
const constexpr double MAXEXTENT = EARTH_RADIUS_WGS84 * boost::math::constants::pi<double>();
|
|
|
|
// ^ math functions are not constexpr since they have side-effects (setting errno) :(
|
|
|
|
const double MAX_LATITUDE = RAD_TO_DEGREE * (2.0 * std::atan(std::exp(180.0 * DEGREE_TO_RAD)) -
|
|
|
|
boost::math::constants::half_pi<double>());
|
|
|
|
const constexpr double MAX_LONGITUDE = 180.0;
|
2016-03-16 16:54:29 -04:00
|
|
|
}
|
|
|
|
|
2016-03-28 14:38:19 -04:00
|
|
|
//! Takes the squared euclidean distance of the input coordinates. Does not return meters!
|
|
|
|
double squaredEuclideanDistance(const FloatCoordinate &lhs, const FloatCoordinate &rhs);
|
2016-02-24 15:26:30 -05:00
|
|
|
|
2016-02-23 15:23:13 -05:00
|
|
|
double haversineDistance(const Coordinate first_coordinate, const Coordinate second_coordinate);
|
2016-01-04 07:30:03 -05:00
|
|
|
|
2016-02-23 15:23:13 -05:00
|
|
|
double greatCircleDistance(const Coordinate first_coordinate, const Coordinate second_coordinate);
|
2016-01-04 07:30:03 -05:00
|
|
|
|
2016-03-28 14:38:19 -04:00
|
|
|
std::pair<double, FloatCoordinate>
|
|
|
|
projectPointOnSegment(const FloatCoordinate &projected_xy_source,
|
|
|
|
const FloatCoordinate &projected_xy_target,
|
|
|
|
const FloatCoordinate &projected_xy_coordinate);
|
|
|
|
|
2016-02-23 15:23:13 -05:00
|
|
|
double perpendicularDistance(const Coordinate segment_source,
|
|
|
|
const Coordinate segment_target,
|
|
|
|
const Coordinate query_location);
|
2016-01-04 07:30:03 -05:00
|
|
|
|
2016-02-23 15:23:13 -05:00
|
|
|
double perpendicularDistance(const Coordinate segment_source,
|
|
|
|
const Coordinate segment_target,
|
|
|
|
const Coordinate query_location,
|
|
|
|
Coordinate &nearest_location,
|
2016-01-04 07:30:03 -05:00
|
|
|
double &ratio);
|
|
|
|
|
2016-03-26 12:28:22 -04:00
|
|
|
Coordinate centroid(const Coordinate lhs, const Coordinate rhs);
|
|
|
|
|
2016-02-23 15:23:13 -05:00
|
|
|
double bearing(const Coordinate first_coordinate, const Coordinate second_coordinate);
|
2016-01-21 06:58:24 -05:00
|
|
|
|
|
|
|
// Get angle of line segment (A,C)->(C,B)
|
2016-02-23 15:23:13 -05:00
|
|
|
double computeAngle(const Coordinate first, const Coordinate second, const Coordinate third);
|
2016-01-28 08:13:39 -05:00
|
|
|
|
2016-03-01 16:30:31 -05:00
|
|
|
// factor in [0,1]. Returns point along the straight line between from and to. 0 returns from, 1
|
|
|
|
// returns to
|
|
|
|
Coordinate interpolateLinear(double factor, const Coordinate from, const Coordinate to);
|
2016-02-24 04:29:23 -05:00
|
|
|
|
2016-01-28 08:13:39 -05:00
|
|
|
namespace mercator
|
|
|
|
{
|
2016-03-16 16:54:29 -04:00
|
|
|
// This is the global default tile size for all Mapbox Vector Tiles
|
|
|
|
const constexpr double TILE_SIZE = 256.0;
|
|
|
|
// Converts projected mercator degrees to PX
|
|
|
|
const constexpr double DEGREE_TO_PX = detail::MAXEXTENT / 180.0;
|
|
|
|
|
2016-03-16 16:31:30 -04:00
|
|
|
double degreeToPixel(FloatLatitude lat, unsigned zoom);
|
|
|
|
double degreeToPixel(FloatLongitude lon, unsigned zoom);
|
2016-02-23 15:23:13 -05:00
|
|
|
FloatLatitude yToLat(const double value);
|
|
|
|
double latToY(const FloatLatitude latitude);
|
2016-03-28 14:38:19 -04:00
|
|
|
|
|
|
|
FloatCoordinate fromWGS84(const FloatCoordinate &wgs84_coordinate);
|
|
|
|
FloatCoordinate toWGS84(const FloatCoordinate &mercator_coordinate);
|
|
|
|
|
|
|
|
void xyzToMercator(
|
|
|
|
const int x, const int y, const int z, double &minx, double &miny, double &maxx, double &maxy);
|
|
|
|
void xyzToWGS84(
|
|
|
|
const int x, const int y, const int z, double &minx, double &miny, double &maxx, double &maxy);
|
2016-01-28 08:13:39 -05:00
|
|
|
} // ns mercator
|
|
|
|
} // ns coordinate_calculation
|
|
|
|
} // ns util
|
|
|
|
} // ns osrm
|
2016-01-05 10:51:13 -05:00
|
|
|
|
2015-01-22 10:33:27 -05:00
|
|
|
#endif // COORDINATE_CALCULATION
|