Fix mathematical assumptions in StaticRTree
StaticRTree now uses projected coordinates internally. That means we can use a euclidean distance measure (squared distance) for sorting the query queue.
This commit is contained in:
@@ -1,92 +0,0 @@
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
#include "util/coordinate_calculation.hpp"
|
||||
|
||||
#include <osrm/coordinate.hpp>
|
||||
|
||||
#include <cmath>
|
||||
|
||||
using namespace osrm;
|
||||
using namespace osrm::util;
|
||||
|
||||
// Regression test for bug captured in #1347
|
||||
BOOST_AUTO_TEST_CASE(regression_test_1347)
|
||||
{
|
||||
Coordinate u(FloatLongitude(-100), FloatLatitude(10));
|
||||
Coordinate v(FloatLongitude(-100.002), FloatLatitude(10.001));
|
||||
Coordinate q(FloatLongitude(-100.001), FloatLatitude(10.002));
|
||||
|
||||
double d1 = coordinate_calculation::perpendicularDistance(u, v, q);
|
||||
|
||||
double ratio;
|
||||
Coordinate nearest_location;
|
||||
double d2 = coordinate_calculation::perpendicularDistance(u, v, q, nearest_location, ratio);
|
||||
|
||||
BOOST_CHECK_LE(std::abs(d1 - d2), 0.01);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(lon_to_pixel)
|
||||
{
|
||||
using namespace coordinate_calculation;
|
||||
BOOST_CHECK_CLOSE(7.416042 * mercator::DEGREE_TO_PX, 825550.019142, 0.1);
|
||||
BOOST_CHECK_CLOSE(7.415892 * mercator::DEGREE_TO_PX, 825533.321218, 0.1);
|
||||
BOOST_CHECK_CLOSE(7.416016 * mercator::DEGREE_TO_PX, 825547.124835, 0.1);
|
||||
BOOST_CHECK_CLOSE(7.41577 * mercator::DEGREE_TO_PX, 825519.74024, 0.1);
|
||||
BOOST_CHECK_CLOSE(7.415808 * mercator::DEGREE_TO_PX, 825523.970381, 0.1);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(lat_to_pixel)
|
||||
{
|
||||
using namespace coordinate_calculation;
|
||||
BOOST_CHECK_CLOSE(mercator::latToY(util::FloatLatitude(43.733947)) * mercator::DEGREE_TO_PX,
|
||||
5424361.75863, 0.1);
|
||||
BOOST_CHECK_CLOSE(mercator::latToY(util::FloatLatitude(43.733799)) * mercator::DEGREE_TO_PX,
|
||||
5424338.95731, 0.1);
|
||||
BOOST_CHECK_CLOSE(mercator::latToY(util::FloatLatitude(43.733922)) * mercator::DEGREE_TO_PX,
|
||||
5424357.90705, 0.1);
|
||||
BOOST_CHECK_CLOSE(mercator::latToY(util::FloatLatitude(43.733697)) * mercator::DEGREE_TO_PX,
|
||||
5424323.24293, 0.1);
|
||||
BOOST_CHECK_CLOSE(mercator::latToY(util::FloatLatitude(43.733729)) * mercator::DEGREE_TO_PX,
|
||||
5424328.17293, 0.1);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(xyz_to_wgs84)
|
||||
{
|
||||
using namespace coordinate_calculation;
|
||||
|
||||
double minx_1;
|
||||
double miny_1;
|
||||
double maxx_1;
|
||||
double maxy_1;
|
||||
mercator::xyzToWSG84(2, 2, 1, minx_1, miny_1, maxx_1, maxy_1);
|
||||
BOOST_CHECK_CLOSE(minx_1, 180, 0.0001);
|
||||
BOOST_CHECK_CLOSE(miny_1, -89.786, 0.0001);
|
||||
BOOST_CHECK_CLOSE(maxx_1, 360, 0.0001);
|
||||
BOOST_CHECK_CLOSE(maxy_1, -85.0511, 0.0001);
|
||||
|
||||
double minx_2;
|
||||
double miny_2;
|
||||
double maxx_2;
|
||||
double maxy_2;
|
||||
mercator::xyzToWSG84(100, 0, 13, minx_2, miny_2, maxx_2, maxy_2);
|
||||
BOOST_CHECK_CLOSE(minx_2, -175.6054, 0.0001);
|
||||
BOOST_CHECK_CLOSE(miny_2, 85.0473, 0.0001);
|
||||
BOOST_CHECK_CLOSE(maxx_2, -175.5615, 0.0001);
|
||||
BOOST_CHECK_CLOSE(maxy_2, 85.0511, 0.0001);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(xyz_to_mercator)
|
||||
{
|
||||
using namespace coordinate_calculation;
|
||||
|
||||
double minx;
|
||||
double miny;
|
||||
double maxx;
|
||||
double maxy;
|
||||
mercator::xyzToMercator(100, 0, 13, minx, miny, maxx, maxy);
|
||||
|
||||
BOOST_CHECK_CLOSE(minx, -19548311.361764118075, 0.0001);
|
||||
BOOST_CHECK_CLOSE(miny, 20032616.372979003936, 0.0001);
|
||||
BOOST_CHECK_CLOSE(maxx, -19543419.391953866929, 0.0001);
|
||||
BOOST_CHECK_CLOSE(maxy, 20037508.342789277434, 0.0001);
|
||||
}
|
||||
@@ -0,0 +1,191 @@
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
#include "util/coordinate_calculation.hpp"
|
||||
|
||||
#include <osrm/coordinate.hpp>
|
||||
|
||||
#include <cmath>
|
||||
|
||||
using namespace osrm;
|
||||
using namespace osrm::util;
|
||||
|
||||
BOOST_AUTO_TEST_SUITE(coordinate_calculation_tests)
|
||||
|
||||
// Regression test for bug captured in #1347
|
||||
BOOST_AUTO_TEST_CASE(regression_test_1347)
|
||||
{
|
||||
Coordinate u(FloatLongitude(-100), FloatLatitude(10));
|
||||
Coordinate v(FloatLongitude(-100.002), FloatLatitude(10.001));
|
||||
Coordinate q(FloatLongitude(-100.001), FloatLatitude(10.002));
|
||||
|
||||
double d1 = coordinate_calculation::perpendicularDistance(u, v, q);
|
||||
|
||||
double ratio;
|
||||
Coordinate nearest_location;
|
||||
double d2 = coordinate_calculation::perpendicularDistance(u, v, q, nearest_location, ratio);
|
||||
|
||||
BOOST_CHECK_LE(std::abs(d1 - d2), 0.01);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(lon_to_pixel)
|
||||
{
|
||||
using namespace coordinate_calculation;
|
||||
BOOST_CHECK_CLOSE(7.416042 * mercator::DEGREE_TO_PX, 825550.019142, 0.1);
|
||||
BOOST_CHECK_CLOSE(7.415892 * mercator::DEGREE_TO_PX, 825533.321218, 0.1);
|
||||
BOOST_CHECK_CLOSE(7.416016 * mercator::DEGREE_TO_PX, 825547.124835, 0.1);
|
||||
BOOST_CHECK_CLOSE(7.41577 * mercator::DEGREE_TO_PX, 825519.74024, 0.1);
|
||||
BOOST_CHECK_CLOSE(7.415808 * mercator::DEGREE_TO_PX, 825523.970381, 0.1);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(lat_to_pixel)
|
||||
{
|
||||
using namespace coordinate_calculation;
|
||||
BOOST_CHECK_CLOSE(mercator::latToY(util::FloatLatitude(43.733947)) * mercator::DEGREE_TO_PX,
|
||||
5424361.75863, 0.1);
|
||||
BOOST_CHECK_CLOSE(mercator::latToY(util::FloatLatitude(43.733799)) * mercator::DEGREE_TO_PX,
|
||||
5424338.95731, 0.1);
|
||||
BOOST_CHECK_CLOSE(mercator::latToY(util::FloatLatitude(43.733922)) * mercator::DEGREE_TO_PX,
|
||||
5424357.90705, 0.1);
|
||||
BOOST_CHECK_CLOSE(mercator::latToY(util::FloatLatitude(43.733697)) * mercator::DEGREE_TO_PX,
|
||||
5424323.24293, 0.1);
|
||||
BOOST_CHECK_CLOSE(mercator::latToY(util::FloatLatitude(43.733729)) * mercator::DEGREE_TO_PX,
|
||||
5424328.17293, 0.1);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(xyz_to_wgs84)
|
||||
{
|
||||
using namespace coordinate_calculation;
|
||||
|
||||
double minx_1;
|
||||
double miny_1;
|
||||
double maxx_1;
|
||||
double maxy_1;
|
||||
mercator::xyzToWGS84(2, 2, 1, minx_1, miny_1, maxx_1, maxy_1);
|
||||
BOOST_CHECK_CLOSE(minx_1, 180, 0.0001);
|
||||
BOOST_CHECK_CLOSE(miny_1, -85.0511, 0.0001);
|
||||
BOOST_CHECK_CLOSE(maxx_1, 360, 0.0001);
|
||||
BOOST_CHECK_CLOSE(maxy_1, -85.0511, 0.0001);
|
||||
|
||||
double minx_2;
|
||||
double miny_2;
|
||||
double maxx_2;
|
||||
double maxy_2;
|
||||
mercator::xyzToWGS84(100, 0, 13, minx_2, miny_2, maxx_2, maxy_2);
|
||||
BOOST_CHECK_CLOSE(minx_2, -175.6054, 0.0001);
|
||||
BOOST_CHECK_CLOSE(miny_2, 85.0473, 0.0001);
|
||||
BOOST_CHECK_CLOSE(maxx_2, -175.5615, 0.0001);
|
||||
BOOST_CHECK_CLOSE(maxy_2, 85.0511, 0.0001);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(xyz_to_mercator)
|
||||
{
|
||||
using namespace coordinate_calculation;
|
||||
|
||||
double minx;
|
||||
double miny;
|
||||
double maxx;
|
||||
double maxy;
|
||||
mercator::xyzToMercator(100, 0, 13, minx, miny, maxx, maxy);
|
||||
|
||||
BOOST_CHECK_CLOSE(minx, -19548311.361764118075, 0.0001);
|
||||
BOOST_CHECK_CLOSE(miny, 20032616.372979003936, 0.0001);
|
||||
BOOST_CHECK_CLOSE(maxx, -19543419.391953866929, 0.0001);
|
||||
BOOST_CHECK_CLOSE(maxy, 20037508.342789277434, 0.0001);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(regression_point_on_segment)
|
||||
{
|
||||
// ^
|
||||
// | t
|
||||
// |
|
||||
// | i
|
||||
// |
|
||||
// |---|---|---|---|---|---|---|--->
|
||||
// |
|
||||
// |
|
||||
// |
|
||||
// |
|
||||
// |
|
||||
// |
|
||||
// |
|
||||
// |
|
||||
// | s
|
||||
FloatCoordinate input{FloatLongitude{55.995715}, FloatLatitude{48.332711}};
|
||||
FloatCoordinate start{FloatLongitude{74.140427}, FloatLatitude{-180}};
|
||||
FloatCoordinate target{FloatLongitude{53.041084}, FloatLatitude{77.21011}};
|
||||
|
||||
FloatCoordinate nearest;
|
||||
double ratio;
|
||||
std::tie(ratio, nearest) = coordinate_calculation::projectPointOnSegment(start, target, input);
|
||||
|
||||
FloatCoordinate diff{target.lon - start.lon, target.lat - start.lat};
|
||||
|
||||
BOOST_CHECK_CLOSE(static_cast<double>(start.lon + FloatLongitude(ratio) * diff.lon), static_cast<double>(nearest.lon), 0.1);
|
||||
BOOST_CHECK_CLOSE(static_cast<double>(start.lat + FloatLatitude(ratio) * diff.lat), static_cast<double>(nearest.lat), 0.1);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(point_on_segment)
|
||||
{
|
||||
// t
|
||||
// |
|
||||
// |---- i
|
||||
// |
|
||||
// s
|
||||
auto result_1 = coordinate_calculation::projectPointOnSegment(
|
||||
{FloatLongitude{0}, FloatLatitude{0}}, {FloatLongitude{0}, FloatLatitude{2}},
|
||||
{FloatLongitude{2}, FloatLatitude{1}});
|
||||
auto reference_ratio_1 = 0.5;
|
||||
auto reference_point_1 = FloatCoordinate{FloatLongitude{0}, FloatLatitude{1}};
|
||||
BOOST_CHECK_EQUAL(result_1.first, reference_ratio_1);
|
||||
BOOST_CHECK_EQUAL(result_1.second.lon, reference_point_1.lon);
|
||||
BOOST_CHECK_EQUAL(result_1.second.lat, reference_point_1.lat);
|
||||
|
||||
// i
|
||||
// :
|
||||
// t
|
||||
// |
|
||||
// |
|
||||
// |
|
||||
// s
|
||||
auto result_2 = coordinate_calculation::projectPointOnSegment(
|
||||
{FloatLongitude{0.}, FloatLatitude{0.}}, {FloatLongitude{0}, FloatLatitude{2}},
|
||||
{FloatLongitude{0}, FloatLatitude{3}});
|
||||
auto reference_ratio_2 = 1.;
|
||||
auto reference_point_2 = FloatCoordinate{FloatLongitude{0}, FloatLatitude{2}};
|
||||
BOOST_CHECK_EQUAL(result_2.first, reference_ratio_2);
|
||||
BOOST_CHECK_EQUAL(result_2.second.lon, reference_point_2.lon);
|
||||
BOOST_CHECK_EQUAL(result_2.second.lat, reference_point_2.lat);
|
||||
|
||||
// t
|
||||
// |
|
||||
// |
|
||||
// |
|
||||
// s
|
||||
// :
|
||||
// i
|
||||
auto result_3 = coordinate_calculation::projectPointOnSegment(
|
||||
{FloatLongitude{0.}, FloatLatitude{0.}}, {FloatLongitude{0}, FloatLatitude{2}},
|
||||
{FloatLongitude{0}, FloatLatitude{-1}});
|
||||
auto reference_ratio_3 = 0.;
|
||||
auto reference_point_3 = FloatCoordinate{FloatLongitude{0}, FloatLatitude{0}};
|
||||
BOOST_CHECK_EQUAL(result_3.first, reference_ratio_3);
|
||||
BOOST_CHECK_EQUAL(result_3.second.lon, reference_point_3.lon);
|
||||
BOOST_CHECK_EQUAL(result_3.second.lat, reference_point_3.lat);
|
||||
|
||||
// t
|
||||
// /
|
||||
// /.
|
||||
// / i
|
||||
// s
|
||||
//
|
||||
auto result_4 = coordinate_calculation::projectPointOnSegment(
|
||||
{FloatLongitude{0}, FloatLatitude{0}}, {FloatLongitude{1}, FloatLatitude{1}},
|
||||
{FloatLongitude{0.5 + 0.1}, FloatLatitude{0.5 - 0.1}});
|
||||
auto reference_ratio_4 = 0.5;
|
||||
auto reference_point_4 = FloatCoordinate{FloatLongitude{0.5}, FloatLatitude{0.5}};
|
||||
BOOST_CHECK_EQUAL(result_4.first, reference_ratio_4);
|
||||
BOOST_CHECK_EQUAL(result_4.second.lon, reference_point_4.lon);
|
||||
BOOST_CHECK_EQUAL(result_4.second.lat, reference_point_4.lat);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_SUITE_END()
|
||||
@@ -26,48 +26,82 @@ BOOST_AUTO_TEST_CASE(get_min_dist_test)
|
||||
// |
|
||||
// +- -80
|
||||
// |
|
||||
RectangleInt2D nw{FloatLongitude(10), FloatLongitude(100), FloatLatitude(10),
|
||||
RectangleInt2D ne{FloatLongitude(10), FloatLongitude(100), FloatLatitude(10),
|
||||
FloatLatitude(80)};
|
||||
// RectangleInt2D ne {FloatLongitude(-100), FloatLongitude(-10), FloatLatitude(10),
|
||||
// FloatLatitude(80)};
|
||||
// RectangleInt2D sw {FloatLongitude(10), FloatLongitude(100), FloatLatitude(-80),
|
||||
// FloatLatitude(-10)};
|
||||
RectangleInt2D se{FloatLongitude(-100), FloatLongitude(-10), FloatLatitude(-80),
|
||||
RectangleInt2D nw{FloatLongitude(-100), FloatLongitude(-10), FloatLatitude(10),
|
||||
FloatLatitude(80)};
|
||||
RectangleInt2D se{FloatLongitude(10), FloatLongitude(100), FloatLatitude(-80),
|
||||
FloatLatitude(-10)};
|
||||
RectangleInt2D sw{FloatLongitude(-100), FloatLongitude(-10), FloatLatitude(-80),
|
||||
FloatLatitude(-10)};
|
||||
|
||||
Coordinate nw_sw{FloatLongitude(9.9), FloatLatitude(9.9)};
|
||||
Coordinate nw_se{FloatLongitude(100.1), FloatLatitude(9.9)};
|
||||
Coordinate nw_ne{FloatLongitude(100.1), FloatLatitude(80.1)};
|
||||
Coordinate nw_nw{FloatLongitude(9.9), FloatLatitude(80.1)};
|
||||
Coordinate nw_s{FloatLongitude(55), FloatLatitude(9.9)};
|
||||
Coordinate nw_e{FloatLongitude(100.1), FloatLatitude(45.0)};
|
||||
Coordinate nw_w{FloatLongitude(9.9), FloatLatitude(45.0)};
|
||||
Coordinate nw_n{FloatLongitude(55), FloatLatitude(80.1)};
|
||||
BOOST_CHECK_CLOSE(nw.GetMinDist(nw_sw), 15611.9, 0.1);
|
||||
BOOST_CHECK_CLOSE(nw.GetMinDist(nw_se), 15611.9, 0.1);
|
||||
BOOST_CHECK_CLOSE(nw.GetMinDist(nw_ne), 11287.4, 0.1);
|
||||
BOOST_CHECK_CLOSE(nw.GetMinDist(nw_nw), 11287.4, 0.1);
|
||||
BOOST_CHECK_CLOSE(nw.GetMinDist(nw_s), 11122.6, 0.1);
|
||||
BOOST_CHECK_CLOSE(nw.GetMinDist(nw_e), 7864.89, 0.1);
|
||||
BOOST_CHECK_CLOSE(nw.GetMinDist(nw_w), 7864.89, 0.1);
|
||||
BOOST_CHECK_CLOSE(nw.GetMinDist(nw_n), 11122.6, 0.1);
|
||||
Coordinate nw_sw{FloatLongitude(-100.1), FloatLatitude(9.9)};
|
||||
Coordinate nw_se{FloatLongitude(-9.9), FloatLatitude(9.9)};
|
||||
Coordinate nw_ne{FloatLongitude(-9.9), FloatLatitude(80.1)};
|
||||
Coordinate nw_nw{FloatLongitude(-100.1), FloatLatitude(80.1)};
|
||||
Coordinate nw_s{FloatLongitude(-55), FloatLatitude(9.9)};
|
||||
Coordinate nw_e{FloatLongitude(-9.9), FloatLatitude(45.0)};
|
||||
Coordinate nw_w{FloatLongitude(-100.1), FloatLatitude(45.0)};
|
||||
Coordinate nw_n{FloatLongitude(-55), FloatLatitude(80.1)};
|
||||
BOOST_CHECK_CLOSE(nw.GetMinSquaredDist(nw_sw), 0.02, 0.1);
|
||||
BOOST_CHECK_CLOSE(nw.GetMinSquaredDist(nw_se), 0.02, 0.1);
|
||||
BOOST_CHECK_CLOSE(nw.GetMinSquaredDist(nw_ne), 0.02, 0.1);
|
||||
BOOST_CHECK_CLOSE(nw.GetMinSquaredDist(nw_nw), 0.02, 0.1);
|
||||
BOOST_CHECK_CLOSE(nw.GetMinSquaredDist(nw_s), 0.01, 0.1);
|
||||
BOOST_CHECK_CLOSE(nw.GetMinSquaredDist(nw_e), 0.01, 0.1);
|
||||
BOOST_CHECK_CLOSE(nw.GetMinSquaredDist(nw_w), 0.01, 0.1);
|
||||
BOOST_CHECK_CLOSE(nw.GetMinSquaredDist(nw_n), 0.01, 0.1);
|
||||
|
||||
Coordinate se_ne{FloatLongitude(-9.9), FloatLatitude(-9.9)};
|
||||
Coordinate se_nw{FloatLongitude(-100.1), FloatLatitude(-9.9)};
|
||||
Coordinate se_sw{FloatLongitude(-100.1), FloatLatitude(-80.1)};
|
||||
Coordinate se_se{FloatLongitude(-9.9), FloatLatitude(-80.1)};
|
||||
Coordinate se_n{FloatLongitude(-55), FloatLatitude(-9.9)};
|
||||
Coordinate se_w{FloatLongitude(-100.1), FloatLatitude(-45.0)};
|
||||
Coordinate se_e{FloatLongitude(-9.9), FloatLatitude(-45.0)};
|
||||
Coordinate se_s{FloatLongitude(-55), FloatLatitude(-80.1)};
|
||||
BOOST_CHECK_CLOSE(se.GetMinDist(se_sw), 11287.4, 0.1);
|
||||
BOOST_CHECK_CLOSE(se.GetMinDist(se_se), 11287.4, 0.1);
|
||||
BOOST_CHECK_CLOSE(se.GetMinDist(se_ne), 15611.9, 0.1);
|
||||
BOOST_CHECK_CLOSE(se.GetMinDist(se_nw), 15611.9, 0.1);
|
||||
BOOST_CHECK_CLOSE(se.GetMinDist(se_s), 11122.6, 0.1);
|
||||
BOOST_CHECK_CLOSE(se.GetMinDist(se_e), 7864.89, 0.1);
|
||||
BOOST_CHECK_CLOSE(se.GetMinDist(se_w), 7864.89, 0.1);
|
||||
BOOST_CHECK_CLOSE(se.GetMinDist(se_n), 11122.6, 0.1);
|
||||
Coordinate ne_sw{FloatLongitude(9.9), FloatLatitude(9.9)};
|
||||
Coordinate ne_se{FloatLongitude(100.1), FloatLatitude(9.9)};
|
||||
Coordinate ne_ne{FloatLongitude(100.1), FloatLatitude(80.1)};
|
||||
Coordinate ne_nw{FloatLongitude(9.9), FloatLatitude(80.1)};
|
||||
Coordinate ne_s{FloatLongitude(55), FloatLatitude(9.9)};
|
||||
Coordinate ne_e{FloatLongitude(100.1), FloatLatitude(45.0)};
|
||||
Coordinate ne_w{FloatLongitude(9.9), FloatLatitude(45.0)};
|
||||
Coordinate ne_n{FloatLongitude(55), FloatLatitude(80.1)};
|
||||
BOOST_CHECK_CLOSE(ne.GetMinSquaredDist(ne_sw), 0.02, 0.1);
|
||||
BOOST_CHECK_CLOSE(ne.GetMinSquaredDist(ne_se), 0.02, 0.1);
|
||||
BOOST_CHECK_CLOSE(ne.GetMinSquaredDist(ne_ne), 0.02, 0.1);
|
||||
BOOST_CHECK_CLOSE(ne.GetMinSquaredDist(ne_nw), 0.02, 0.1);
|
||||
BOOST_CHECK_CLOSE(ne.GetMinSquaredDist(ne_s), 0.01, 0.1);
|
||||
BOOST_CHECK_CLOSE(ne.GetMinSquaredDist(ne_e), 0.01, 0.1);
|
||||
BOOST_CHECK_CLOSE(ne.GetMinSquaredDist(ne_w), 0.01, 0.1);
|
||||
BOOST_CHECK_CLOSE(ne.GetMinSquaredDist(ne_n), 0.01, 0.1);
|
||||
|
||||
Coordinate se_ne{FloatLongitude(100.1), FloatLatitude(-9.9)};
|
||||
Coordinate se_nw{FloatLongitude(9.9), FloatLatitude(-9.9)};
|
||||
Coordinate se_sw{FloatLongitude(9.9), FloatLatitude(-80.1)};
|
||||
Coordinate se_se{FloatLongitude(100.1), FloatLatitude(-80.1)};
|
||||
Coordinate se_n{FloatLongitude(55), FloatLatitude(-9.9)};
|
||||
Coordinate se_w{FloatLongitude(9.9), FloatLatitude(-45.0)};
|
||||
Coordinate se_e{FloatLongitude(100.1), FloatLatitude(-45.0)};
|
||||
Coordinate se_s{FloatLongitude(55), FloatLatitude(-80.1)};
|
||||
BOOST_CHECK_CLOSE(se.GetMinSquaredDist(se_sw), 0.02, 0.1);
|
||||
BOOST_CHECK_CLOSE(se.GetMinSquaredDist(se_se), 0.02, 0.1);
|
||||
BOOST_CHECK_CLOSE(se.GetMinSquaredDist(se_ne), 0.02, 0.1);
|
||||
BOOST_CHECK_CLOSE(se.GetMinSquaredDist(se_nw), 0.02, 0.1);
|
||||
BOOST_CHECK_CLOSE(se.GetMinSquaredDist(se_s), 0.01, 0.1);
|
||||
BOOST_CHECK_CLOSE(se.GetMinSquaredDist(se_e), 0.01, 0.1);
|
||||
BOOST_CHECK_CLOSE(se.GetMinSquaredDist(se_w), 0.01, 0.1);
|
||||
BOOST_CHECK_CLOSE(se.GetMinSquaredDist(se_n), 0.01, 0.1);
|
||||
|
||||
Coordinate sw_ne{FloatLongitude(-9.9), FloatLatitude(-9.9)};
|
||||
Coordinate sw_nw{FloatLongitude(-100.1), FloatLatitude(-9.9)};
|
||||
Coordinate sw_sw{FloatLongitude(-100.1), FloatLatitude(-80.1)};
|
||||
Coordinate sw_se{FloatLongitude(-9.9), FloatLatitude(-80.1)};
|
||||
Coordinate sw_n{FloatLongitude(-55), FloatLatitude(-9.9)};
|
||||
Coordinate sw_w{FloatLongitude(-100.1), FloatLatitude(-45.0)};
|
||||
Coordinate sw_e{FloatLongitude(-9.9), FloatLatitude(-45.0)};
|
||||
Coordinate sw_s{FloatLongitude(-55), FloatLatitude(-80.1)};
|
||||
BOOST_CHECK_CLOSE(sw.GetMinSquaredDist(sw_sw), 0.02, 0.1);
|
||||
BOOST_CHECK_CLOSE(sw.GetMinSquaredDist(sw_se), 0.02, 0.1);
|
||||
BOOST_CHECK_CLOSE(sw.GetMinSquaredDist(sw_ne), 0.02, 0.1);
|
||||
BOOST_CHECK_CLOSE(sw.GetMinSquaredDist(sw_nw), 0.02, 0.1);
|
||||
BOOST_CHECK_CLOSE(sw.GetMinSquaredDist(sw_s), 0.01, 0.1);
|
||||
BOOST_CHECK_CLOSE(sw.GetMinSquaredDist(sw_e), 0.01, 0.1);
|
||||
BOOST_CHECK_CLOSE(sw.GetMinSquaredDist(sw_w), 0.01, 0.1);
|
||||
BOOST_CHECK_CLOSE(sw.GetMinSquaredDist(sw_n), 0.01, 0.1);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_SUITE_END()
|
||||
|
||||
@@ -1,18 +1,18 @@
|
||||
#include "util/coordinate_calculation.hpp"
|
||||
#include "engine/geospatial_query.hpp"
|
||||
#include "util/static_rtree.hpp"
|
||||
#include "extractor/edge_based_node.hpp"
|
||||
#include "engine/geospatial_query.hpp"
|
||||
#include "util/typedefs.hpp"
|
||||
#include "util/rectangle.hpp"
|
||||
#include "util/exception.hpp"
|
||||
#include "util/coordinate_calculation.hpp"
|
||||
#include "util/coordinate.hpp"
|
||||
#include "util/static_rtree.hpp"
|
||||
|
||||
#include "mocks/mock_datafacade.hpp"
|
||||
|
||||
#include <boost/functional/hash.hpp>
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#include <boost/test/auto_unit_test.hpp>
|
||||
#include <boost/test/test_case_template.hpp>
|
||||
|
||||
#include <osrm/coordinate.hpp>
|
||||
#include <boost/functional/hash.hpp>
|
||||
|
||||
#include <cstdint>
|
||||
#include <cmath>
|
||||
@@ -44,8 +44,8 @@ using MiniStaticRTree = StaticRTree<TestData, std::vector<Coordinate>, false, 2,
|
||||
|
||||
// Choosen by a fair W20 dice roll (this value is completely arbitrary)
|
||||
constexpr unsigned RANDOM_SEED = 42;
|
||||
static const int32_t WORLD_MIN_LAT = -90 * COORDINATE_PRECISION;
|
||||
static const int32_t WORLD_MAX_LAT = 90 * COORDINATE_PRECISION;
|
||||
static const int32_t WORLD_MIN_LAT = -85 * COORDINATE_PRECISION;
|
||||
static const int32_t WORLD_MAX_LAT = 85 * COORDINATE_PRECISION;
|
||||
static const int32_t WORLD_MIN_LON = -180 * COORDINATE_PRECISION;
|
||||
static const int32_t WORLD_MAX_LON = 180 * COORDINATE_PRECISION;
|
||||
|
||||
@@ -62,18 +62,23 @@ template <typename DataT> class LinearSearchNN
|
||||
{
|
||||
std::vector<DataT> local_edges(edges);
|
||||
|
||||
std::nth_element(
|
||||
local_edges.begin(), local_edges.begin() + num_results, local_edges.end(),
|
||||
[this, &input_coordinate](const DataT &lhs, const DataT &rhs)
|
||||
{
|
||||
double current_ratio = 0.;
|
||||
Coordinate nearest;
|
||||
const double lhs_dist = coordinate_calculation::perpendicularDistance(
|
||||
coords->at(lhs.u), coords->at(lhs.v), input_coordinate, nearest, current_ratio);
|
||||
const double rhs_dist = coordinate_calculation::perpendicularDistance(
|
||||
coords->at(rhs.u), coords->at(rhs.v), input_coordinate, nearest, current_ratio);
|
||||
return lhs_dist < rhs_dist;
|
||||
});
|
||||
auto projected_input = coordinate_calculation::mercator::fromWGS84(input_coordinate);
|
||||
const auto segment_comparator = [this, &projected_input](const DataT &lhs, const DataT &rhs)
|
||||
{
|
||||
using coordinate_calculation::mercator::fromWGS84;
|
||||
const auto lhs_result = coordinate_calculation::projectPointOnSegment(
|
||||
fromWGS84(coords->at(lhs.u)), fromWGS84(coords->at(lhs.v)), projected_input);
|
||||
const auto rhs_result = coordinate_calculation::projectPointOnSegment(
|
||||
fromWGS84(coords->at(rhs.u)), fromWGS84(coords->at(rhs.v)), projected_input);
|
||||
const auto lhs_squared_dist = coordinate_calculation::squaredEuclideanDistance(
|
||||
lhs_result.second, projected_input);
|
||||
const auto rhs_squared_dist = coordinate_calculation::squaredEuclideanDistance(
|
||||
rhs_result.second, projected_input);
|
||||
return lhs_squared_dist < rhs_squared_dist;
|
||||
};
|
||||
|
||||
std::nth_element(local_edges.begin(), local_edges.begin() + num_results, local_edges.end(),
|
||||
segment_comparator);
|
||||
local_edges.resize(num_results);
|
||||
|
||||
return local_edges;
|
||||
@@ -102,8 +107,6 @@ template <unsigned NUM_NODES, unsigned NUM_EDGES> struct RandomGraphFixture
|
||||
|
||||
RandomGraphFixture() : coords(std::make_shared<std::vector<Coordinate>>())
|
||||
{
|
||||
BOOST_TEST_MESSAGE("Constructing " << NUM_NODES << " nodes and " << NUM_EDGES << " edges.");
|
||||
|
||||
std::mt19937 g(RANDOM_SEED);
|
||||
|
||||
std::uniform_int_distribution<> lat_udist(WORLD_MIN_LAT, WORLD_MAX_LAT);
|
||||
@@ -189,7 +192,6 @@ void simple_verify_rtree(RTreeT &rtree,
|
||||
const std::shared_ptr<std::vector<Coordinate>> &coords,
|
||||
const std::vector<TestData> &edges)
|
||||
{
|
||||
BOOST_TEST_MESSAGE("Verify end points");
|
||||
for (const auto &e : edges)
|
||||
{
|
||||
const Coordinate &pu = coords->at(e.u);
|
||||
@@ -217,7 +219,6 @@ void sampling_verify_rtree(RTreeT &rtree,
|
||||
queries.emplace_back(FixedLongitude(lon_udist(g)), FixedLatitude(lat_udist(g)));
|
||||
}
|
||||
|
||||
BOOST_TEST_MESSAGE("Sampling queries");
|
||||
for (const auto &q : queries)
|
||||
{
|
||||
auto result_rtree = rtree.Nearest(q, 1);
|
||||
@@ -229,13 +230,15 @@ void sampling_verify_rtree(RTreeT &rtree,
|
||||
auto lsnn_u = result_lsnn.back().u;
|
||||
auto lsnn_v = result_lsnn.back().v;
|
||||
|
||||
double current_ratio = 0.;
|
||||
Coordinate nearest;
|
||||
Coordinate rtree_nearest;
|
||||
Coordinate lsnn_nearest;
|
||||
double ratio;
|
||||
const double rtree_dist = coordinate_calculation::perpendicularDistance(
|
||||
coords[rtree_u], coords[rtree_v], q, nearest, current_ratio);
|
||||
coords[rtree_u], coords[rtree_v], q, rtree_nearest, ratio);
|
||||
const double lsnn_dist = coordinate_calculation::perpendicularDistance(
|
||||
coords[lsnn_u], coords[lsnn_v], q, nearest, current_ratio);
|
||||
BOOST_CHECK_LE(std::abs(rtree_dist - lsnn_dist), std::numeric_limits<double>::epsilon());
|
||||
coords[lsnn_u], coords[lsnn_v], q, lsnn_nearest, ratio);
|
||||
|
||||
BOOST_CHECK_CLOSE(rtree_dist, lsnn_dist, 0.0001);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -303,18 +306,16 @@ BOOST_AUTO_TEST_CASE(regression_test)
|
||||
using Edge = std::pair<unsigned, unsigned>;
|
||||
GraphFixture fixture(
|
||||
{
|
||||
Coord{FloatLongitude{0.0}, FloatLatitude{40.0}}, //
|
||||
Coord{FloatLongitude{5.0}, FloatLatitude{35.0}}, //
|
||||
Coord{FloatLongitude{5.0},
|
||||
FloatLatitude{
|
||||
5.0, }}, //
|
||||
Coord{FloatLongitude{10.0}, FloatLatitude{0.0}}, //
|
||||
Coord{FloatLongitude{10.0}, FloatLatitude{20.0}}, //
|
||||
Coord{FloatLongitude{5.0}, FloatLatitude{20.0}}, //
|
||||
Coord{FloatLongitude{100.0}, FloatLatitude{40.0}}, //
|
||||
Coord{FloatLongitude{105.0}, FloatLatitude{35.0}}, //
|
||||
Coord{FloatLongitude{105.0}, FloatLatitude{5.0}}, //
|
||||
Coord{FloatLongitude{110.0}, FloatLatitude{0.0}}, //
|
||||
Coord{FloatLongitude{0.0}, FloatLatitude{40.0}}, //
|
||||
Coord{FloatLongitude{5.0}, FloatLatitude{35.0}}, //
|
||||
Coord{FloatLongitude{5.0}, FloatLatitude{5.0}}, //
|
||||
Coord{FloatLongitude{10.0}, FloatLatitude{0.0}}, //
|
||||
Coord{FloatLongitude{10.0}, FloatLatitude{20.0}}, //
|
||||
Coord{FloatLongitude{5.0}, FloatLatitude{20.0}}, //
|
||||
Coord{FloatLongitude{100.0}, FloatLatitude{40.0}}, //
|
||||
Coord{FloatLongitude{105.0}, FloatLatitude{35.0}}, //
|
||||
Coord{FloatLongitude{105.0}, FloatLatitude{5.0}}, //
|
||||
Coord{FloatLongitude{110.0}, FloatLatitude{0.0}}, //
|
||||
},
|
||||
{Edge(0, 1), Edge(2, 3), Edge(4, 5), Edge(6, 7), Edge(8, 9)});
|
||||
|
||||
@@ -330,6 +331,13 @@ BOOST_AUTO_TEST_CASE(regression_test)
|
||||
auto result_rtree = rtree.Nearest(input, 1);
|
||||
auto result_ls = lsnn.Nearest(input, 1);
|
||||
|
||||
auto distance_rtree = coordinate_calculation::perpendicularDistance(
|
||||
fixture.coords->at(result_rtree.front().u), fixture.coords->at(result_rtree.front().v),
|
||||
input);
|
||||
|
||||
auto distance_lsnn = coordinate_calculation::perpendicularDistance(
|
||||
fixture.coords->at(result_ls.front().u), fixture.coords->at(result_ls.front().v), input);
|
||||
|
||||
BOOST_CHECK(result_rtree.size() == 1);
|
||||
BOOST_CHECK(result_ls.size() == 1);
|
||||
|
||||
@@ -337,69 +345,14 @@ BOOST_AUTO_TEST_CASE(regression_test)
|
||||
BOOST_CHECK_EQUAL(result_ls.front().v, result_rtree.front().v);
|
||||
}
|
||||
|
||||
void TestRectangle(double width, double height, double center_lat, double center_lon)
|
||||
{
|
||||
Coordinate center{FloatLongitude(center_lon), FloatLatitude(center_lat)};
|
||||
|
||||
TestStaticRTree::Rectangle rect;
|
||||
rect.min_lat = center.lat - FixedLatitude(height / 2.0 * COORDINATE_PRECISION);
|
||||
rect.max_lat = center.lat + FixedLatitude(height / 2.0 * COORDINATE_PRECISION);
|
||||
rect.min_lon = center.lon - FixedLongitude(width / 2.0 * COORDINATE_PRECISION);
|
||||
rect.max_lon = center.lon + FixedLongitude(width / 2.0 * COORDINATE_PRECISION);
|
||||
|
||||
const FixedLongitude lon_offset(5. * COORDINATE_PRECISION);
|
||||
const FixedLatitude lat_offset(5. * COORDINATE_PRECISION);
|
||||
Coordinate north(center.lon, rect.max_lat + lat_offset);
|
||||
Coordinate south(center.lon, rect.min_lat - lat_offset);
|
||||
Coordinate west(rect.min_lon - lon_offset, center.lat);
|
||||
Coordinate east(rect.max_lon + lon_offset, center.lat);
|
||||
Coordinate north_east(rect.max_lon + lon_offset, rect.max_lat + lat_offset);
|
||||
Coordinate north_west(rect.min_lon - lon_offset, rect.max_lat + lat_offset);
|
||||
Coordinate south_east(rect.max_lon + lon_offset, rect.min_lat - lat_offset);
|
||||
Coordinate south_west(rect.min_lon - lon_offset, rect.min_lat - lat_offset);
|
||||
|
||||
/* Distance to line segments of rectangle */
|
||||
BOOST_CHECK_EQUAL(rect.GetMinDist(north), coordinate_calculation::greatCircleDistance(
|
||||
north, Coordinate(north.lon, rect.max_lat)));
|
||||
BOOST_CHECK_EQUAL(rect.GetMinDist(south), coordinate_calculation::greatCircleDistance(
|
||||
south, Coordinate(south.lon, rect.min_lat)));
|
||||
BOOST_CHECK_EQUAL(rect.GetMinDist(west), coordinate_calculation::greatCircleDistance(
|
||||
west, Coordinate(rect.min_lon, west.lat)));
|
||||
BOOST_CHECK_EQUAL(rect.GetMinDist(east), coordinate_calculation::greatCircleDistance(
|
||||
east, Coordinate(rect.max_lon, east.lat)));
|
||||
|
||||
/* Distance to corner points */
|
||||
BOOST_CHECK_EQUAL(rect.GetMinDist(north_east),
|
||||
coordinate_calculation::greatCircleDistance(
|
||||
north_east, Coordinate(rect.max_lon, rect.max_lat)));
|
||||
BOOST_CHECK_EQUAL(rect.GetMinDist(north_west),
|
||||
coordinate_calculation::greatCircleDistance(
|
||||
north_west, Coordinate(rect.min_lon, rect.max_lat)));
|
||||
BOOST_CHECK_EQUAL(rect.GetMinDist(south_east),
|
||||
coordinate_calculation::greatCircleDistance(
|
||||
south_east, Coordinate(rect.max_lon, rect.min_lat)));
|
||||
BOOST_CHECK_EQUAL(rect.GetMinDist(south_west),
|
||||
coordinate_calculation::greatCircleDistance(
|
||||
south_west, Coordinate(rect.min_lon, rect.min_lat)));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(rectangle_test)
|
||||
{
|
||||
TestRectangle(10, 10, 5, 5);
|
||||
TestRectangle(10, 10, -5, 5);
|
||||
TestRectangle(10, 10, 5, -5);
|
||||
TestRectangle(10, 10, -5, -5);
|
||||
TestRectangle(10, 10, 0, 0);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(bearing_tests)
|
||||
{
|
||||
using Coord = std::pair<FloatLongitude, FloatLatitude>;
|
||||
using Edge = std::pair<unsigned, unsigned>;
|
||||
GraphFixture fixture(
|
||||
{
|
||||
Coord(FloatLongitude(0.0), FloatLatitude(0.0)),
|
||||
Coord(FloatLongitude(10.0), FloatLatitude(10.0)),
|
||||
Coord(FloatLongitude(0.0), FloatLatitude(0.0)),
|
||||
Coord(FloatLongitude(10.0), FloatLatitude(10.0)),
|
||||
},
|
||||
{Edge(0, 1), Edge(1, 0)});
|
||||
|
||||
@@ -428,9 +381,13 @@ BOOST_AUTO_TEST_CASE(bearing_tests)
|
||||
{
|
||||
auto results = query.NearestPhantomNodes(input, 5, 45, 10);
|
||||
BOOST_CHECK_EQUAL(results.size(), 2);
|
||||
|
||||
BOOST_CHECK(results[0].phantom_node.forward_segment_id.enabled);
|
||||
BOOST_CHECK(!results[0].phantom_node.reverse_segment_id.enabled);
|
||||
BOOST_CHECK_EQUAL(results[0].phantom_node.forward_segment_id.id, 1);
|
||||
BOOST_CHECK_EQUAL(results[0].phantom_node.reverse_segment_id.id, SPECIAL_SEGMENTID);
|
||||
BOOST_CHECK_EQUAL(results[1].phantom_node.forward_segment_id.id, SPECIAL_SEGMENTID);
|
||||
|
||||
BOOST_CHECK(!results[1].phantom_node.forward_segment_id.enabled);
|
||||
BOOST_CHECK(results[1].phantom_node.reverse_segment_id.enabled);
|
||||
BOOST_CHECK_EQUAL(results[1].phantom_node.reverse_segment_id.id, 1);
|
||||
}
|
||||
|
||||
@@ -447,9 +404,13 @@ BOOST_AUTO_TEST_CASE(bearing_tests)
|
||||
{
|
||||
auto results = query.NearestPhantomNodesInRange(input, 11000, 45, 10);
|
||||
BOOST_CHECK_EQUAL(results.size(), 2);
|
||||
|
||||
BOOST_CHECK(results[0].phantom_node.forward_segment_id.enabled);
|
||||
BOOST_CHECK(!results[0].phantom_node.reverse_segment_id.enabled);
|
||||
BOOST_CHECK_EQUAL(results[0].phantom_node.forward_segment_id.id, 1);
|
||||
BOOST_CHECK_EQUAL(results[0].phantom_node.reverse_segment_id.id, SPECIAL_SEGMENTID);
|
||||
BOOST_CHECK_EQUAL(results[1].phantom_node.forward_segment_id.id, SPECIAL_SEGMENTID);
|
||||
|
||||
BOOST_CHECK(!results[1].phantom_node.forward_segment_id.enabled);
|
||||
BOOST_CHECK(results[1].phantom_node.reverse_segment_id.enabled);
|
||||
BOOST_CHECK_EQUAL(results[1].phantom_node.reverse_segment_id.id, 1);
|
||||
}
|
||||
}
|
||||
@@ -461,11 +422,11 @@ BOOST_AUTO_TEST_CASE(bbox_search_tests)
|
||||
|
||||
GraphFixture fixture(
|
||||
{
|
||||
Coord(FloatLongitude(0.0), FloatLatitude(0.0)),
|
||||
Coord(FloatLongitude(1.0), FloatLatitude(1.0)),
|
||||
Coord(FloatLongitude(2.0), FloatLatitude(2.0)),
|
||||
Coord(FloatLongitude(3.0), FloatLatitude(3.0)),
|
||||
Coord(FloatLongitude(4.0), FloatLatitude(4.0)),
|
||||
Coord(FloatLongitude(0.0), FloatLatitude(0.0)),
|
||||
Coord(FloatLongitude(1.0), FloatLatitude(1.0)),
|
||||
Coord(FloatLongitude(2.0), FloatLatitude(2.0)),
|
||||
Coord(FloatLongitude(3.0), FloatLatitude(3.0)),
|
||||
Coord(FloatLongitude(4.0), FloatLatitude(4.0)),
|
||||
},
|
||||
{Edge(0, 1), Edge(1, 2), Edge(2, 3), Edge(3, 4)});
|
||||
|
||||
@@ -478,15 +439,15 @@ BOOST_AUTO_TEST_CASE(bbox_search_tests)
|
||||
mockfacade);
|
||||
|
||||
{
|
||||
RectangleInt2D bbox = {
|
||||
FloatLongitude(0.5), FloatLongitude(1.5), FloatLatitude(0.5), FloatLatitude(1.5)};
|
||||
RectangleInt2D bbox = {FloatLongitude(0.5), FloatLongitude(1.5), FloatLatitude(0.5),
|
||||
FloatLatitude(1.5)};
|
||||
auto results = query.Search(bbox);
|
||||
BOOST_CHECK_EQUAL(results.size(), 2);
|
||||
}
|
||||
|
||||
{
|
||||
RectangleInt2D bbox = {
|
||||
FloatLongitude(1.5), FloatLongitude(3.5), FloatLatitude(1.5), FloatLatitude(3.5)};
|
||||
RectangleInt2D bbox = {FloatLongitude(1.5), FloatLongitude(3.5), FloatLatitude(1.5),
|
||||
FloatLatitude(3.5)};
|
||||
auto results = query.Search(bbox);
|
||||
BOOST_CHECK_EQUAL(results.size(), 3);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user