From 4e68f3a7e1ee5b00c561af224247036baed55f94 Mon Sep 17 00:00:00 2001 From: Huyen Chau Nguyen Date: Wed, 25 Apr 2018 11:00:13 -0400 Subject: [PATCH] change haversine computation to cheap ruler in distance tables --- features/support/data_classes.js | 8 +- features/testbot/distance.feature | 19 ++ features/testbot/distance_matrix.feature | 237 ++++++++++++----------- include/engine/geospatial_query.hpp | 8 +- 4 files changed, 157 insertions(+), 115 deletions(-) diff --git a/features/support/data_classes.js b/features/support/data_classes.js index a383540d6..1fad997a0 100644 --- a/features/support/data_classes.js +++ b/features/support/data_classes.js @@ -21,7 +21,8 @@ module.exports = { matchRe = want.match(/^\/(.*)\/$/), // we use this for matching before/after bearing matchBearingListAbs = want.match(/^((\d+)->(\d+))(,(\d+)->(\d+))*\s+\+\-(.+)$/), - matchIntersectionListAbs = want.match(/^(((((true|false):\d+)\s{0,1})+,{0,1})+;{0,1})+\s+\+\-(.+)$/); + matchIntersectionListAbs = want.match(/^(((((true|false):\d+)\s{0,1})+,{0,1})+;{0,1})+\s+\+\-(.+)$/), + matchRangeNumbers = want.match(/\d+\+\-\d+/); function inRange(margin, got, want) { var fromR = parseFloat(want) - margin, @@ -105,6 +106,11 @@ module.exports = { return inRange(margin, got, matchAbs[1]); } else if (matchRe) { // regex: /a,b,.*/ return got.match(matchRe[1]); + } else if (matchRangeNumbers) { + let real_want_and_margin = want.split('+-'), + margin = parseFloat(real_want_and_margin[1].trim()), + real_want = parseFloat(real_want_and_margin[0].trim()); + return inRange(margin, got, real_want); } else { return false; } diff --git a/features/testbot/distance.feature b/features/testbot/distance.feature index 8500c1df1..1b76f45a6 100644 --- a/features/testbot/distance.feature +++ b/features/testbot/distance.feature @@ -226,3 +226,22 @@ Feature: Distance calculation | x | v | xv,xv | 424m +-1 | | x | w | xw,xw | 360m +-1 | | x | y | xy,xy | 316m +-1 | + + + # Check rounding errors + Scenario: Distances Long distances + Given a grid size of 1000 meters + Given the node map + """ + a b c d + """ + + And the ways + | nodes | + | abcd | + + When I route I should get + | from | to | distance | + | a | b | 1000m +-3 | + | a | c | 2000m +-3 | + | a | d | 3000m +-3 | diff --git a/features/testbot/distance_matrix.feature b/features/testbot/distance_matrix.feature index 46f60d7de..104727350 100644 --- a/features/testbot/distance_matrix.feature +++ b/features/testbot/distance_matrix.feature @@ -17,9 +17,9 @@ Feature: Basic Distance Matrix | ab | When I request a travel distance matrix I should get - | | a | b | - | a | 0 | 100 | - | b | 100 | 0 | + | | a | b | + | a | 0 | 100+-1 | + | b | 100+-1 | 0 | Scenario: Testbot - Travel distance matrix of minimal network with toll exclude Given the query options @@ -39,11 +39,11 @@ Feature: Basic Distance Matrix | bd | motorway | yes | not drivable for exclude=toll and exclude=motorway,toll | When I request a travel distance matrix I should get - | | a | b | c | d | - | a | 0 | 100 | | | - | b | 100 | 0 | | | - | c | | | 0 | 100 | - | d | | | 100 | 0 | + | | a | b | c | d | + | a | 0 | 100+-1 | | | + | b | 100+-1 | 0 | | | + | c | | | 0 | 100+-1 | + | d | | | 100+-1 | 0 | Scenario: Testbot - Travel distance matrix of minimal network with motorway exclude Given the query options @@ -63,8 +63,8 @@ Feature: Basic Distance Matrix | bd | residential | | When I request a travel distance matrix I should get - | | a | b | c | d | - | a | 0 | 300 | 100 | 200 | + | | a | b | c | d | + | a | 0 | 300+-2 | 100+-2 | 200+-2 | Scenario: Testbot - Travel distance matrix of minimal network disconnected motorway exclude @@ -85,8 +85,8 @@ Feature: Basic Distance Matrix | efgh | residential | | When I request a travel distance matrix I should get - | | a | b | e | - | a | 0 | 50 | | + | | a | b | e | + | a | 0 | 50+-1 | | Scenario: Testbot - Travel distance matrix of minimal network with motorway and toll excludes @@ -107,8 +107,8 @@ Feature: Basic Distance Matrix | efgh | residential | | | When I request a travel distance matrix I should get - | | a | b | e | g | - | a | 0 | 100 | | | + | | a | b | e | g | + | a | 0 | 100+-1 | | | Scenario: Testbot - Travel distance matrix with different way speeds Given the node map @@ -123,22 +123,22 @@ Feature: Basic Distance Matrix | cd | tertiary | When I request a travel distance matrix I should get - | | a | b | c | d | - | a | 0 | 100 | 200 | 299.9 | - | b | 100 | 0 | 100 | 200 | - | c | 200 | 100 | 0 | 100 | - | d | 299.9 | 200 | 100 | 0 | + | | a | b | c | d | + | a | 0 | 100+-1 | 200+-1 | 300+-1 | + | b | 100+-1 | 0 | 100+-1 | 200+-1 | + | c | 200+-1 | 100+-1 | 0 | 100+-1 | + | d | 300+-1 | 200+-1 | 100+-1 | 0 | When I request a travel distance matrix I should get - | | a | b | c | d | - | a | 0 | 100 | 200 | 299.9 | + | | a | b | c | d | + | a | 0 | 100+-1 | 200+-1 | 300+-1 | When I request a travel distance matrix I should get - | | a | - | a | 0 | - | b | 100 | - | c | 200 | - | d | 299.9 | + | | a | + | a | 0 | + | b | 100+-1 | + | c | 200+-1 | + | d | 300+-1 | Scenario: Testbot - Travel distance matrix of small grid Given the node map @@ -156,11 +156,11 @@ Feature: Basic Distance Matrix | cf | When I request a travel distance matrix I should get - | | a | b | e | f | - | a | 0 | 100 | 200 | 299.9 | - | b | 100 | 0 | 100 | 200 | - | e | 200 | 100 | 0 | 100 | - | f | 299.9 | 200 | 100 | 0 | + | | a | b | e | f | + | a | 0 | 100+-1 | 200+-1 | 300+-1 | + | b | 100+-1 | 0 | 100+-1 | 200+-1 | + | e | 200+-1 | 100+-1 | 0 | 100+-1 | + | f | 300+-1 | 200+-1 | 100+-1 | 0 | Scenario: Testbot - Travel distance matrix of network with unroutable parts Given the node map @@ -173,9 +173,9 @@ Feature: Basic Distance Matrix | ab | yes | When I request a travel distance matrix I should get - | | a | b | - | a | 0 | 100 | - | b | | 0 | + | | a | b | + | a | 0 | 100+-1 | + | b | | 0 | Scenario: Testbot - Travel distance matrix of network with oneways Given the node map @@ -191,11 +191,11 @@ Feature: Basic Distance Matrix | by | | When I request a travel distance matrix I should get - | | x | y | d | e | - | x | 0 | 299.9 | 399.9 | 299.9 | - | y | 499.9 | 0 | 299.9 | 200 | - | d | 200 | 299.9 | 0 | 300 | - | e | 299.9 | 399.9 | 100 | 0 | + | | x | y | d | e | + | x | 0 | 300+-2 | 400+-2 | 300+-2 | + | y | 500+-2 | 0 | 300+-2 | 200+-2 | + | d | 200+-2 | 300+-2 | 0 | 300+-2 | + | e | 300+-2 | 400+-2 | 100+-2 | 0 | Scenario: Testbot - Rectangular travel distance matrix Given the node map @@ -213,47 +213,47 @@ Feature: Basic Distance Matrix | cf | When I request a travel distance matrix I should get - | | a | b | e | f | - | a | 0 | 100 | 200 | 299.9 | + | | a | b | e | f | + | a | 0 | 100+-1 | 200+-1 | 300+-1 | When I request a travel distance matrix I should get - | | a | - | a | 0 | - | b | 100 | - | e | 200 | - | f | 299.9 | + | | a | + | a | 0 | + | b | 100+-1 | + | e | 200+-1 | + | f | 300+-1 | When I request a travel distance matrix I should get - | | a | b | e | f | - | a | 0 | 100 | 200 | 299.9 | - | b | 100 | 0 | 100 | 200 | + | | a | b | e | f | + | a | 0 | 100+-1 | 200+-1 | 300+-1 | + | b | 100+-1 | 0 | 100+-1 | 200+-1 | When I request a travel distance matrix I should get - | | a | b | - | a | 0 | 100 | - | b | 100 | 0 | - | e | 200 | 100 | - | f | 299.9 | 200 | + | | a | b | + | a | 0 | 100+-1 | + | b | 100+-1 | 0 | + | e | 200+-1 | 100+-1 | + | f | 300+-1 | 200+-1 | When I request a travel distance matrix I should get - | | a | b | e | f | - | a | 0 | 100 | 200 | 299.9 | - | b | 100 | 0 | 100 | 200 | - | e | 200 | 100 | 0 | 100 | + | | a | b | e | f | + | a | 0 | 100+-1 | 200+-1 | 300+-1 | + | b | 100+-1 | 0 | 100+-1 | 200+-1 | + | e | 200+-1 | 100+-1 | 0 | 100+-1 | When I request a travel distance matrix I should get - | | a | b | e | - | a | 0 | 100 | 200 | - | b | 100 | 0 | 100 | - | e | 200 | 100 | 0 | - | f | 299.9 | 200 | 100 | + | | a | b | e | + | a | 0 | 100+-1 | 200+-1 | + | b | 100+-1 | 0 | 100+-1 | + | e | 200+-1 | 100+-1 | 0 | + | f | 300+-1 | 200+-1 | 100+-1 | When I request a travel distance matrix I should get - | | a | b | e | f | - | a | 0 | 100 | 200 | 299.9 | - | b | 100 | 0 | 100 | 200 | - | e | 200 | 100 | 0 | 100 | - | f | 299.9 | 200 | 100 | 0 | + | | a | b | e | f | + | a | 0 | 100+-1 | 200+-1 | 300+-1 | + | b | 100+-1 | 0 | 100+-1 | 200+-1 | + | e | 200+-1 | 100+-1 | 0 | 100+-1 | + | f | 300+-1 | 200+-1 | 100+-1 | 0 | Scenario: Testbot - Travel distance 3x2 matrix @@ -273,9 +273,9 @@ Feature: Basic Distance Matrix When I request a travel distance matrix I should get - | | b | e | f | - | a | 100 | 200 | 299.9 | - | b | 0 | 100 | 200 | + | | b | e | f | + | a | 100+-1 | 200+-1 | 300+-1 | + | b | 0 | 100+-1 | 200+-1 | Scenario: Testbot - All coordinates are from same small component Given a grid size of 300 meters @@ -295,9 +295,9 @@ Feature: Basic Distance Matrix | fg | When I request a travel distance matrix I should get - | | f | g | - | f | 0 | 300 | - | g | 300 | 0 | + | | f | g | + | f | 0 | 300+-2 | + | g | 300+-2 | 0 | Scenario: Testbot - Coordinates are from different small component and snap to big CC Given a grid size of 300 meters @@ -329,11 +329,11 @@ Feature: Basic Distance Matrix | i | h | 300m | When I request a travel distance matrix I should get - | | f | g | h | i | - | f | 0 | 300 | 0 | 300 | - | g | 300 | 0 | 300 | 0 | - | h | 0 | 300 | 0 | 300 | - | i | 300 | 0 | 300 | 0 | + | | f | g | h | i | + | f | 0 | 300+-2 | 0 | 300+-2 | + | g | 300+-2 | 0 | 300+-2 | 0 | + | h | 0 | 300+-2 | 0 | 300+-2 | + | i | 300+-2 | 0 | 300+-2 | 0 | Scenario: Testbot - Travel distance matrix with loops Given the node map @@ -350,11 +350,11 @@ Feature: Basic Distance Matrix | da | yes | When I request a travel distance matrix I should get - | | 1 | 2 | 3 | 4 | - | 1 | 0 | 100 | 399.9 | 499.9 | - | 2 | 699.9 | 0 | 299.9 | 399.9 | - | 3 | 399.9 | 499.9 | 0 | 100 | - | 4 | 299.9 | 399.9 | 699.9 | 0 | + | | 1 | 2 | 3 | 4 | + | 1 | 0 | 100+-1 | 400+-1 | 500+-1 | + | 2 | 700+-1 | 0 | 300+-1 | 400+-1 | + | 3 | 400+-1 | 500+-1 | 0 | 100+-1 | + | 4 | 300+-1 | 400+-1 | 700+-1 | 0 | Scenario: Testbot - Travel distance matrix based on segment durations @@ -391,12 +391,12 @@ Feature: Basic Distance Matrix | ce | When I request a travel distance matrix I should get - | | a | b | c | d | e | - | a | 0 | 100 | 200 | 299.9 | 399.9 | - | b | 100 | 0 | 100 | 200 | 300 | - | c | 200 | 100 | 0 | 100 | 200 | - | d | 299.9 | 200 | 100 | 0 | 300 | - | e | 399.9 | 300 | 200 | 300 | 0 | + | | a | b | c | d | e | + | a | 0 | 100+-2 | 200+-2 | 300+-2 | 400+-2 | + | b | 100+-2 | 0 | 100+-2 | 200+-2 | 300+-2 | + | c | 200+-2 | 100+-2 | 0 | 100+-2 | 200+-2 | + | d | 300+-2 | 200+-2 | 100+-2 | 0 | 300+-2 | + | e | 400+-2 | 300+-2 | 200+-2 | 300+-2 | 0 | Scenario: Testbot - Travel distance matrix for alternative loop paths Given the profile file @@ -435,15 +435,15 @@ Feature: Basic Distance Matrix | ca | yes | When I request a travel distance matrix I should get - | | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | - | 1 | 0 | 1099.8 | 300 | 200 | 599.9 | 499.9 | 899.9 | 799.9 | - | 2 | 100 | 0 | 399.9 | 299.9 | 699.9 | 599.9 | 999.8 | 899.9 | - | 3 | 899.9 | 799.9 | 0 | 1099.8 | 299.9 | 200 | 599.9 | 499.9 | - | 4 | 999.8 | 899.9 | 100 | 0 | 399.9 | 300 | 699.9 | 599.9 | - | 5 | 599.9 | 499.9 | 899.9 | 799.9 | 0 | 1099.8 | 300 | 200 | - | 6 | 699.9 | 599.9 | 999.8 | 899.9 | 100 | 0 | 399.9 | 299.9 | - | 7 | 299.9 | 200 | 599.9 | 499.9 | 899.9 | 799.9 | 0 | 1099.8 | - | 8 | 399.9 | 300 | 699.9 | 599.9 | 999.8 | 899.9 | 100 | 0 | + | | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | + | 1 | 0 | 1100+-5 | 300+-5 | 200+-5 | 600+-5 | 500+-5 | 900+-5 | 800+-5 | + | 2 | 100+-5 | 0 | 400+-5 | 300+-5 | 700+-5 | 600+-5 | 1000+-5 | 900+-5 | + | 3 | 900+-5 | 800+-5 | 0 | 1100+-5 | 300+-5 | 200+-5 | 600+-5 | 500+-5 | + | 4 | 1000+-5 | 900+-5 | 100+-5 | 0 | 400+-5 | 300+-5 | 700+-5 | 600+-5 | + | 5 | 600+-5 | 500+-5 | 900+-5 | 800+-5 | 0 | 1100+-5 | 300+-5 | 200+-5 | + | 6 | 700+-5 | 600+-5 | 1000+-5 | 900+-5 | 100+-5 | 0 | 400+-5 | 300+-5 | + | 7 | 300+-5 | 200+-5 | 600+-5 | 500+-5 | 900+-5 | 800+-5 | 0 | 1100+-5 | + | 8 | 400+-5 | 300+-5 | 700+-5 | 600+-5 | 1000+-5 | 900+-5 | 100+-5 | 0 | Scenario: Testbot - Travel distance matrix with ties Given the node map @@ -465,18 +465,35 @@ Feature: Basic Distance Matrix | a | c | ac,ac | 200m | 20s | 20 | When I route I should get - | from | to | route | distance | - | a | b | ab,ab | 299.9m | - | a | c | ac,ac | 200m | - | a | d | ab,bd,bd | 499.9m | + | from | to | route | distance | + | a | b | ab,ab | 300m +- 1 | + | a | c | ac,ac | 200m | + | a | d | ab,bd,bd | 500m +- 1 | When I request a travel distance matrix I should get - | | a | b | c | d | - | a | 0 | 299.9 | 200 | 499.9 | + | | a | b | c | d | + | a | 0 | 300+-2 | 200+-2 | 500+-2 | When I request a travel distance matrix I should get - | | a | - | a | 0 | - | b | 299.9 | - | c | 200 | - | d | 499.9 | + | | a | + | a | 0 | + | b | 300+-2 | + | c | 200+-2 | + | d | 500+-2 | + + + # Check rounding errors + Scenario: Testbot - Long distances in tables + Given a grid size of 1000 meters + Given the node map + """ + a b c d + """ + + And the ways + | nodes | + | abcd | + + When I request a travel distance matrix I should get + | | a | b | c | d | + | a | 0 | 1000+-3 | 2000+-3 | 3000+-3 | diff --git a/include/engine/geospatial_query.hpp b/include/engine/geospatial_query.hpp index cd53f34f4..4ecfc8118 100644 --- a/include/engine/geospatial_query.hpp +++ b/include/engine/geospatial_query.hpp @@ -465,7 +465,7 @@ template class GeospatialQuery current < forward_geometry.begin() + data.fwd_segment_position; ++current) { - forward_distance_offset += util::coordinate_calculation::haversineDistance( + forward_distance_offset += util::coordinate_calculation::fccApproximateDistance( datafacade.GetCoordinateOfNode(*current), datafacade.GetCoordinateOfNode(*std::next(current))); } @@ -475,7 +475,7 @@ template class GeospatialQuery EdgeWeight forward_weight = forward_weights[data.fwd_segment_position]; EdgeDuration forward_duration = forward_durations[data.fwd_segment_position]; - EdgeDistance forward_distance = util::coordinate_calculation::haversineDistance( + EdgeDistance forward_distance = util::coordinate_calculation::fccApproximateDistance( datafacade.GetCoordinateOfNode(forward_geometry(data.fwd_segment_position)), point_on_segment); @@ -494,7 +494,7 @@ template class GeospatialQuery current < forward_geometry.end() - data.fwd_segment_position - 2; ++current) { - reverse_distance_offset += util::coordinate_calculation::haversineDistance( + reverse_distance_offset += util::coordinate_calculation::fccApproximateDistance( datafacade.GetCoordinateOfNode(*current), datafacade.GetCoordinateOfNode(*std::next(current))); } @@ -503,7 +503,7 @@ template class GeospatialQuery reverse_weights[reverse_weights.size() - data.fwd_segment_position - 1]; EdgeDuration reverse_duration = reverse_durations[reverse_durations.size() - data.fwd_segment_position - 1]; - EdgeDistance reverse_distance = util::coordinate_calculation::haversineDistance( + EdgeDistance reverse_distance = util::coordinate_calculation::fccApproximateDistance( point_on_segment, datafacade.GetCoordinateOfNode(forward_geometry(data.fwd_segment_position + 1)));