Added distance on earth function.

This commit is contained in:
vng 2013-08-06 19:38:30 +03:00
parent ccd6fbed75
commit 10dd9a2277
4 changed files with 62 additions and 3 deletions

30
storage/distance.cpp Normal file
View file

@ -0,0 +1,30 @@
#include "distance.hpp"
#include "../std/algorithm.hpp"
#include "../std/cmath.hpp"
namespace earth
{
double const PI = atan(1.0) * 4.0;
double Degree2Rad(double deg)
{
return deg / 180.0 * PI;
}
double DistanceOnSphere(double lat1Deg, double lon1Deg, double lat2Deg, double lon2Deg)
{
double const lat1 = Degree2Rad(lat1Deg);
double const lat2 = Degree2Rad(lat2Deg);
double const lon1 = Degree2Rad(lon1Deg);
double const lon2 = Degree2Rad(lon2Deg);
double const dlat = sin((lat2 - lat1) / 2.0);
double const dlon = sin((lon2 - lon1) / 2.0);
double const y = dlat * dlat + dlon * dlon * cos(lat1) * cos(lat2);
return 2.0 * atan2(sqrt(y), sqrt(max(0.0, 1.0 - y)));
}
}

21
storage/distance.hpp Normal file
View file

@ -0,0 +1,21 @@
#pragma once
namespace earth
{
inline double RadiusM() { return 6378000; }
double Degree2Rad(double deg);
/// @name Distance
/// @param[in] lat1, lat2, lon1, lon2 - in degrees.
//@{
double DistanceOnSphere(double lat1Deg, double lon1Deg, double lat2Deg, double lon2Deg);
inline double Distance(double lat1Deg, double lon1Deg, double lat2Deg, double lon2Deg)
{
return RadiusM() * DistanceOnSphere(lat1Deg, lon1Deg, lat2Deg, lon2Deg);
}
//@}
}

View file

@ -6,13 +6,14 @@ CONFIG -= app_bundle
INCLUDEPATH += ../3rdparty/boost ../3rdparty/googletest/include
HEADERS += \
storage.hpp \
article_info.hpp \
storage_common.hpp \
distance.hpp \
storage.hpp \
SOURCES += \
storage.cpp \
article_info.cpp \
distance.cpp \
storage.cpp \
# env sources
SOURCES += \

View file

@ -1,6 +1,7 @@
#include <gtest/gtest.h>
#include "storage.hpp"
#include "distance.hpp"
#include "../env/message_std.hpp"
#include "../env/logging.hpp"
@ -188,3 +189,9 @@ TEST(Storage, StorageReadWriteTest)
fs::DeleteFile(name);
}
TEST(Distance, Smoke)
{
// Equator length from wiki.
EXPECT_TRUE(fabs(earth::Distance(0, 0, 0, 180) / 1000.0 - 40075 / 2.0) < 1.0);
}