speed up nearest neighbor query by pruning, move coordinate calculations away from library interface

This commit is contained in:
Dennis Luxen
2015-01-20 16:24:49 +01:00
parent 8f813fbc67
commit 01f3237416
14 changed files with 733 additions and 416 deletions
+31 -2
View File
@@ -1,5 +1,34 @@
/*
Copyright (c) 2015, Project OSRM, Dennis Luxen, others
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <boost/test/unit_test.hpp>
#include "../../data_structures/coordinate_calculation.hpp"
#include <osrm/coordinate.hpp>
#include <cmath>
@@ -11,11 +40,11 @@ BOOST_AUTO_TEST_CASE(regression_test_1347)
FixedPointCoordinate v(10.001 * COORDINATE_PRECISION, -100.002 * COORDINATE_PRECISION);
FixedPointCoordinate q(10.002 * COORDINATE_PRECISION, -100.001 * COORDINATE_PRECISION);
float d1 = FixedPointCoordinate::ComputePerpendicularDistance(u, v, q);
float d1 = coordinate_calculation::ComputePerpendicularDistance(u, v, q);
float ratio;
FixedPointCoordinate nearest_location;
float d2 = FixedPointCoordinate::ComputePerpendicularDistance(u, v, q, nearest_location, ratio);
float d2 = coordinate_calculation::ComputePerpendicularDistance(u, v, q, nearest_location, ratio);
BOOST_CHECK_LE(std::abs(d1 - d2), 0.01f);
}
+17 -16
View File
@@ -1,6 +1,6 @@
/*
Copyright (c) 2014, Project OSRM, Dennis Luxen, others
Copyright (c) 2015, Project OSRM, Dennis Luxen, others
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
@@ -25,6 +25,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "../../data_structures/coordinate_calculation.hpp"
#include "../../data_structures/static_rtree.hpp"
#include "../../data_structures/query_node.hpp"
#include "../../data_structures/edge_based_node.hpp"
@@ -77,7 +78,7 @@ class LinearSearchNN
{
const FixedPointCoordinate &start = coords->at(e.u);
const FixedPointCoordinate &end = coords->at(e.v);
float distance = FixedPointCoordinate::ApproximateEuclideanDistance(
float distance = coordinate_calculation::approx_euclidean_distance(
input_coordinate.lat, input_coordinate.lon, start.lat, start.lon);
if (distance < min_dist)
{
@@ -85,7 +86,7 @@ class LinearSearchNN
min_dist = distance;
}
distance = FixedPointCoordinate::ApproximateEuclideanDistance(
distance = coordinate_calculation::approx_euclidean_distance(
input_coordinate.lat, input_coordinate.lon, end.lat, end.lon);
if (distance < min_dist)
{
@@ -112,7 +113,7 @@ class LinearSearchNN
float current_ratio = 0.;
FixedPointCoordinate nearest;
const float current_perpendicular_distance =
FixedPointCoordinate::ComputePerpendicularDistance(
coordinate_calculation::ComputePerpendicularDistance(
coords->at(e.u), coords->at(e.v), input_coordinate, nearest, current_ratio);
if ((current_perpendicular_distance < min_dist) &&
@@ -148,9 +149,9 @@ class LinearSearchNN
result_phantom_node.location.lat = input_coordinate.lat;
}
const float distance_1 = FixedPointCoordinate::ApproximateEuclideanDistance(
const float distance_1 = coordinate_calculation::approx_euclidean_distance(
coords->at(nearest_edge.u), result_phantom_node.location);
const float distance_2 = FixedPointCoordinate::ApproximateEuclideanDistance(
const float distance_2 = coordinate_calculation::approx_euclidean_distance(
coords->at(nearest_edge.u), coords->at(nearest_edge.v));
const float ratio = std::min(1.f, distance_1 / distance_2);
@@ -285,10 +286,10 @@ void simple_verify_rtree(RTreeT &rtree,
bool found_u = rtree.LocateClosestEndPointForCoordinate(pu, result_u, 1);
bool found_v = rtree.LocateClosestEndPointForCoordinate(pv, result_v, 1);
BOOST_CHECK(found_u && found_v);
float dist_u = FixedPointCoordinate::ApproximateEuclideanDistance(
float dist_u = coordinate_calculation::approx_euclidean_distance(
result_u.lat, result_u.lon, pu.lat, pu.lon);
BOOST_CHECK_LE(dist_u, std::numeric_limits<float>::epsilon());
float dist_v = FixedPointCoordinate::ApproximateEuclideanDistance(
float dist_v = coordinate_calculation::approx_euclidean_distance(
result_v.lat, result_v.lon, pv.lat, pv.lon);
BOOST_CHECK_LE(dist_v, std::numeric_limits<float>::epsilon());
}
@@ -449,30 +450,30 @@ void TestRectangle(double width, double height, double center_lat, double center
/* Distance to line segments of rectangle */
BOOST_CHECK_EQUAL(rect.GetMinDist(north),
FixedPointCoordinate::ApproximateEuclideanDistance(
coordinate_calculation::approx_euclidean_distance(
north, FixedPointCoordinate(rect.max_lat, north.lon)));
BOOST_CHECK_EQUAL(rect.GetMinDist(south),
FixedPointCoordinate::ApproximateEuclideanDistance(
coordinate_calculation::approx_euclidean_distance(
south, FixedPointCoordinate(rect.min_lat, south.lon)));
BOOST_CHECK_EQUAL(rect.GetMinDist(west),
FixedPointCoordinate::ApproximateEuclideanDistance(
coordinate_calculation::approx_euclidean_distance(
west, FixedPointCoordinate(west.lat, rect.min_lon)));
BOOST_CHECK_EQUAL(rect.GetMinDist(east),
FixedPointCoordinate::ApproximateEuclideanDistance(
coordinate_calculation::approx_euclidean_distance(
east, FixedPointCoordinate(east.lat, rect.max_lon)));
/* Distance to corner points */
BOOST_CHECK_EQUAL(rect.GetMinDist(north_east),
FixedPointCoordinate::ApproximateEuclideanDistance(
coordinate_calculation::approx_euclidean_distance(
north_east, FixedPointCoordinate(rect.max_lat, rect.max_lon)));
BOOST_CHECK_EQUAL(rect.GetMinDist(north_west),
FixedPointCoordinate::ApproximateEuclideanDistance(
coordinate_calculation::approx_euclidean_distance(
north_west, FixedPointCoordinate(rect.max_lat, rect.min_lon)));
BOOST_CHECK_EQUAL(rect.GetMinDist(south_east),
FixedPointCoordinate::ApproximateEuclideanDistance(
coordinate_calculation::approx_euclidean_distance(
south_east, FixedPointCoordinate(rect.min_lat, rect.max_lon)));
BOOST_CHECK_EQUAL(rect.GetMinDist(south_west),
FixedPointCoordinate::ApproximateEuclideanDistance(
coordinate_calculation::approx_euclidean_distance(
south_west, FixedPointCoordinate(rect.min_lat, rect.min_lon)));
}