Compare commits

..

8 Commits

Author SHA1 Message Date
Daniel Patterson 54ab5373cf Fix tests - backported changes need old namespace. 2017-01-18 22:58:43 -08:00
Daniel Patterson 57bd2cda0f Update changelog and version for 5.5.4 2017-01-18 22:25:20 -08:00
Moritz Kobitzsch bfbdd18834 fix emitting invalid turn types, now surfacing due to changes in obvious detection
Conflicts:
	features/guidance/dedicated-turn-roads.feature
	include/extractor/guidance/intersection.hpp
2017-01-18 17:22:14 +01:00
Daniel J. Hofmann 5159d57201 Changelog Item for #3561 2017-01-17 12:54:38 +01:00
Michael Krasnyk bc38275146 Added missing backward_speed for cycleways 2017-01-17 12:53:08 +01:00
Moritz Kobitzsch c77add50e2 cherry-pick https://github.com/Project-OSRM/osrm-backend/pull/3555 2017-01-17 10:27:33 +01:00
Michael Krasnyk 37e36fd165 Fix possible division by zero by clamping latitude to 85.05°
Resolves #3530
2017-01-17 10:08:27 +01:00
Michael Krasnyk 341109a8f4 Adjusted number of nodes in annotation, resolves #3515
Conflicts:
	CHANGELOG.md
2017-01-17 10:02:07 +01:00
14 changed files with 203 additions and 43 deletions
+9 -2
View File
@@ -1,3 +1,12 @@
# 5.5.4
- Changes from 5.5.3
- Bugfixes
- PR #3561 - added missing backwards speeds for cycleways in bicycle profile
- PR #3515 - adjusted number of `nodes` in `annotation`
- Ticket #3430 - Fix possible division by zero by clamping latitude to +/- 85.05
- PR #3555 - Fix an error that occurs when a road forks immediately after exiting a ferry
- PR #3575 - Don't emit invalid turn types for obvious turns at sliproads and roundabouts.
# 5.5.3 # 5.5.3
- Changes from 5.5.2 - Changes from 5.5.2
- Bugfixes: - Bugfixes:
@@ -396,5 +405,3 @@
- `properties.use_turn_restrictions` - `properties.use_turn_restrictions`
- `properties.u_turn_penalty` - `properties.u_turn_penalty`
- `properties.allow_u_turn_at_via` - `properties.allow_u_turn_at_via`
+1 -1
View File
@@ -53,7 +53,7 @@ endif()
project(OSRM C CXX) project(OSRM C CXX)
set(OSRM_VERSION_MAJOR 5) set(OSRM_VERSION_MAJOR 5)
set(OSRM_VERSION_MINOR 5) set(OSRM_VERSION_MINOR 5)
set(OSRM_VERSION_PATCH 3) set(OSRM_VERSION_PATCH 4)
set(OSRM_VERSION "${OSRM_VERSION_MAJOR}.${OSRM_VERSION_MINOR}.${OSRM_VERSION_PATCH}") set(OSRM_VERSION "${OSRM_VERSION_MAJOR}.${OSRM_VERSION_MINOR}.${OSRM_VERSION_PATCH}")
add_definitions(-DOSRM_PROJECT_DIR="${CMAKE_CURRENT_SOURCE_DIR}") add_definitions(-DOSRM_PROJECT_DIR="${CMAKE_CURRENT_SOURCE_DIR}")
@@ -782,3 +782,40 @@ Feature: Slipways and Dedicated Turn Lanes
When I route I should get When I route I should get
| waypoints | route | turns | | waypoints | route | turns |
| s,g | main,sliproad,another,another | depart,turn right,turn left,arrive | | s,g | main,sliproad,another,another | depart,turn right,turn left,arrive |
Scenario: Sliproad before a roundabout
Given the node map
"""
e
a - b - - c - d
'f|l'
m
g
|
.h-_
k - i |
'.j.'
"""
And the ways
| nodes | junction | oneway | highway | name |
| ab | | yes | primary | road |
| bc | | yes | primary | road |
| cd | | yes | primary | road |
| ec | | yes | secondary | |
| cm | | yes | secondary | |
| mg | | yes | primary | |
| gh | | no | primary | |
| hijh | roundabout | yes | primary | |
| ik | | yes | primary | |
| bfm | | yes | primary | |
| gld | | yes | primary | |
And the relations
| type | way:from | way:to | node:via | restriction |
| restriction | bc | cd | c | only_straight |
When I route I should get
| waypoints | route | turns | locations |
| a,k | road,,, | depart,continue right,roundabout turn right exit-1,arrive | a,b,h,k |
@@ -34,6 +34,14 @@ struct IntersectionShapeData
}; };
inline auto makeCompareShapeDataByBearing(const double base_bearing) inline auto makeCompareShapeDataByBearing(const double base_bearing)
{
return [base_bearing](const auto &lhs, const auto &rhs) {
return util::angularDeviation(base_bearing, lhs.bearing) <
util::angularDeviation(base_bearing, rhs.bearing);
};
}
inline auto makeCompareShapeDataAngleToBearing(const double base_bearing)
{ {
return [base_bearing](const auto &lhs, const auto &rhs) { return [base_bearing](const auto &lhs, const auto &rhs) {
return util::angleBetweenBearings(base_bearing, lhs.bearing) < return util::angleBetweenBearings(base_bearing, lhs.bearing) <
+1
View File
@@ -29,6 +29,7 @@ inline void print(const engine::guidance::RouteStep &step)
<< " " << " "
<< " Duration: " << step.duration << " Distance: " << step.distance << " Duration: " << step.duration << " Distance: " << step.distance
<< " Geometry: " << step.geometry_begin << " " << step.geometry_end << " Geometry: " << step.geometry_begin << " " << step.geometry_end
<< " Exit: " << step.maneuver.exit << " Mode: " << (int)step.mode
<< "\n\tIntersections: " << step.intersections.size() << " ["; << "\n\tIntersections: " << step.intersections.size() << " [";
for (const auto &intersection : step.intersections) for (const auto &intersection : step.intersections)
+18 -19
View File
@@ -20,7 +20,7 @@ const constexpr double EARTH_RADIUS_WGS84 = 6378137.0;
// earth circumference devided by 2 // earth circumference devided by 2
const constexpr double MAXEXTENT = EARTH_RADIUS_WGS84 * boost::math::constants::pi<double>(); const constexpr double MAXEXTENT = EARTH_RADIUS_WGS84 * boost::math::constants::pi<double>();
// ^ math functions are not constexpr since they have side-effects (setting errno) :( // ^ math functions are not constexpr since they have side-effects (setting errno) :(
const constexpr double MAX_LATITUDE = 85.; const constexpr double EPSG3857_MAX_LATITUDE = 85.051128779806592378; // 90(4*atan(exp(pi))/pi-1)
const constexpr double MAX_LONGITUDE = 180.0; const constexpr double MAX_LONGITUDE = 180.0;
} }
@@ -29,6 +29,18 @@ const constexpr double DEGREE_TO_PX = detail::MAXEXTENT / 180.0;
// This is the global default tile size for all Mapbox Vector Tiles // This is the global default tile size for all Mapbox Vector Tiles
const constexpr double TILE_SIZE = 256.0; const constexpr double TILE_SIZE = 256.0;
inline FloatLatitude clamp(const FloatLatitude lat)
{
return std::max(std::min(lat, FloatLatitude{detail::EPSG3857_MAX_LATITUDE}),
FloatLatitude{-detail::EPSG3857_MAX_LATITUDE});
}
inline FloatLongitude clamp(const FloatLongitude lon)
{
return std::max(std::min(lon, FloatLongitude{detail::MAX_LONGITUDE}),
FloatLongitude{-detail::MAX_LONGITUDE});
}
inline FloatLatitude yToLat(const double y) inline FloatLatitude yToLat(const double y)
{ {
const auto clamped_y = std::max(-180., std::min(180., y)); const auto clamped_y = std::max(-180., std::min(180., y));
@@ -41,10 +53,9 @@ inline FloatLatitude yToLat(const double y)
inline double latToY(const FloatLatitude latitude) inline double latToY(const FloatLatitude latitude)
{ {
// apparently this is the (faster) version of the canonical log(tan()) version // apparently this is the (faster) version of the canonical log(tan()) version
const double f = std::sin(detail::DEGREE_TO_RAD * static_cast<double>(latitude)); const auto clamped_latitude = clamp(latitude);
const double y = detail::RAD_TO_DEGREE * 0.5 * std::log((1 + f) / (1 - f)); const double f = std::sin(detail::DEGREE_TO_RAD * static_cast<double>(clamped_latitude));
const auto clamped_y = std::max(-180., std::min(180., y)); return detail::RAD_TO_DEGREE * 0.5 * std::log((1 + f) / (1 - f));
return clamped_y;
} }
template <typename T> constexpr double horner(double, T an) { return an; } template <typename T> constexpr double horner(double, T an) { return an; }
@@ -91,18 +102,6 @@ inline double latToYapprox(const FloatLatitude latitude)
-3.23083224835967391884404730e-28); -3.23083224835967391884404730e-28);
} }
inline FloatLatitude clamp(const FloatLatitude lat)
{
return std::max(std::min(lat, FloatLatitude{detail::MAX_LATITUDE}),
FloatLatitude{-detail::MAX_LATITUDE});
}
inline FloatLongitude clamp(const FloatLongitude lon)
{
return std::max(std::min(lon, FloatLongitude{detail::MAX_LONGITUDE}),
FloatLongitude{-detail::MAX_LONGITUDE});
}
inline void pixelToDegree(const double shift, double &x, double &y) inline void pixelToDegree(const double shift, double &x, double &y)
{ {
const double b = shift / 2.0; const double b = shift / 2.0;
@@ -166,9 +165,9 @@ inline void xyzToMercator(
xyzToWGS84(x, y, z, minx, miny, maxx, maxy); xyzToWGS84(x, y, z, minx, miny, maxx, maxy);
minx = static_cast<double>(clamp(util::FloatLongitude{minx})) * DEGREE_TO_PX; minx = static_cast<double>(clamp(util::FloatLongitude{minx})) * DEGREE_TO_PX;
miny = latToY(clamp(util::FloatLatitude{miny})) * DEGREE_TO_PX; miny = latToY(util::FloatLatitude{miny}) * DEGREE_TO_PX;
maxx = static_cast<double>(clamp(util::FloatLongitude{maxx})) * DEGREE_TO_PX; maxx = static_cast<double>(clamp(util::FloatLongitude{maxx})) * DEGREE_TO_PX;
maxy = latToY(clamp(util::FloatLatitude{maxy})) * DEGREE_TO_PX; maxy = latToY(util::FloatLatitude{maxy}) * DEGREE_TO_PX;
} }
} }
} }
+3
View File
@@ -368,10 +368,13 @@ function way_function (way, result)
-- cycleways -- cycleways
if cycleway and cycleway_tags[cycleway] then if cycleway and cycleway_tags[cycleway] then
result.forward_speed = bicycle_speeds["cycleway"] result.forward_speed = bicycle_speeds["cycleway"]
result.backward_speed = bicycle_speeds["cycleway"]
elseif cycleway_left and cycleway_tags[cycleway_left] then elseif cycleway_left and cycleway_tags[cycleway_left] then
result.forward_speed = bicycle_speeds["cycleway"] result.forward_speed = bicycle_speeds["cycleway"]
result.backward_speed = bicycle_speeds["cycleway"]
elseif cycleway_right and cycleway_tags[cycleway_right] then elseif cycleway_right and cycleway_tags[cycleway_right] then
result.forward_speed = bicycle_speeds["cycleway"] result.forward_speed = bicycle_speeds["cycleway"]
result.backward_speed = bicycle_speeds["cycleway"]
end end
-- dismount -- dismount
+3 -1
View File
@@ -1073,7 +1073,8 @@ std::vector<RouteStep> collapseTurns(std::vector<RouteStep> steps)
if (one_back_step.maneuver.instruction.type == TurnType::Sliproad) if (one_back_step.maneuver.instruction.type == TurnType::Sliproad)
{ {
if (current_step.maneuver.instruction.type == TurnType::Suppressed && if (current_step.maneuver.instruction.type == TurnType::Suppressed &&
compatible(one_back_step, current_step)) compatible(one_back_step, current_step) && current_step.intersections.size() == 1 &&
current_step.intersections.front().entry.size() == 2)
{ {
// Traffic light on the sliproad, the road itself will be handled in the next // Traffic light on the sliproad, the road itself will be handled in the next
// iteration, when one-back-index again points to the sliproad. // iteration, when one-back-index again points to the sliproad.
@@ -1441,6 +1442,7 @@ void trimShortSegments(std::vector<RouteStep> &steps, LegGeometry &geometry)
// This can happen if the last coordinate snaps to a node in the unpacked geometry // This can happen if the last coordinate snaps to a node in the unpacked geometry
geometry.locations.pop_back(); geometry.locations.pop_back();
geometry.annotations.pop_back(); geometry.annotations.pop_back();
geometry.osm_node_ids.pop_back();
geometry.segment_offsets.back()--; geometry.segment_offsets.back()--;
// since the last geometry includes the location of arrival, the arrival instruction // since the last geometry includes the location of arrival, the arrival instruction
// geometry overlaps with the previous segment // geometry overlaps with the previous segment
@@ -135,8 +135,9 @@ IntersectionGenerator::ComputeIntersectionShape(const NodeID node_at_center_of_i
} }
return util::reverseBearing(intersection.begin()->bearing); return util::reverseBearing(intersection.begin()->bearing);
}(); }();
std::sort( std::sort(intersection.begin(),
intersection.begin(), intersection.end(), makeCompareShapeDataByBearing(base_bearing)); intersection.end(),
makeCompareShapeDataAngleToBearing(base_bearing));
} }
return intersection; return intersection;
} }
@@ -167,6 +167,14 @@ void IntersectionHandler::assignFork(const EdgeID via_edge,
node_based_graph.GetEdgeData(left.eid).road_classification.IsLowPriorityRoadClass(); node_based_graph.GetEdgeData(left.eid).road_classification.IsLowPriorityRoadClass();
const bool low_priority_right = const bool low_priority_right =
node_based_graph.GetEdgeData(right.eid).road_classification.IsLowPriorityRoadClass(); node_based_graph.GetEdgeData(right.eid).road_classification.IsLowPriorityRoadClass();
const auto same_mode_left =
in_data.travel_mode == node_based_graph.GetEdgeData(left.eid).travel_mode;
const auto same_mode_right =
in_data.travel_mode == node_based_graph.GetEdgeData(right.eid).travel_mode;
const auto suppressed_left_type =
same_mode_left ? TurnType::Suppressed : TurnType::Notification;
const auto suppressed_right_type =
same_mode_right ? TurnType::Suppressed : TurnType::Notification;
if ((angularDeviation(left.angle, STRAIGHT_ANGLE) < MAXIMAL_ALLOWED_NO_TURN_DEVIATION && if ((angularDeviation(left.angle, STRAIGHT_ANGLE) < MAXIMAL_ALLOWED_NO_TURN_DEVIATION &&
angularDeviation(right.angle, STRAIGHT_ANGLE) > FUZZY_ANGLE_DIFFERENCE)) angularDeviation(right.angle, STRAIGHT_ANGLE) > FUZZY_ANGLE_DIFFERENCE))
{ {
@@ -198,7 +206,7 @@ void IntersectionHandler::assignFork(const EdgeID via_edge,
} }
else else
{ {
left.instruction = {TurnType::Suppressed, DirectionModifier::Straight}; left.instruction = {suppressed_left_type, DirectionModifier::Straight};
right.instruction = {findBasicTurnType(via_edge, right), right.instruction = {findBasicTurnType(via_edge, right),
DirectionModifier::SlightRight}; DirectionModifier::SlightRight};
} }
@@ -237,7 +245,7 @@ void IntersectionHandler::assignFork(const EdgeID via_edge,
} }
else else
{ {
right.instruction = {TurnType::Suppressed, DirectionModifier::Straight}; right.instruction = {suppressed_right_type, DirectionModifier::Straight};
left.instruction = {findBasicTurnType(via_edge, left), left.instruction = {findBasicTurnType(via_edge, left),
DirectionModifier::SlightLeft}; DirectionModifier::SlightLeft};
} }
@@ -245,7 +253,7 @@ void IntersectionHandler::assignFork(const EdgeID via_edge,
} }
// left side of fork // left side of fork
if (low_priority_right && !low_priority_left) if (low_priority_right && !low_priority_left)
left.instruction = {TurnType::Suppressed, DirectionModifier::SlightLeft}; left.instruction = {suppressed_left_type, DirectionModifier::SlightLeft};
else else
{ {
if (low_priority_left && !low_priority_right) if (low_priority_left && !low_priority_right)
@@ -256,7 +264,7 @@ void IntersectionHandler::assignFork(const EdgeID via_edge,
// right side of fork // right side of fork
if (low_priority_left && !low_priority_right) if (low_priority_left && !low_priority_right)
right.instruction = {TurnType::Suppressed, DirectionModifier::SlightLeft}; right.instruction = {suppressed_right_type, DirectionModifier::SlightLeft};
else else
{ {
if (low_priority_right && !low_priority_left) if (low_priority_right && !low_priority_left)
@@ -272,6 +280,12 @@ void IntersectionHandler::assignFork(const EdgeID via_edge,
ConnectedRoad &right) const ConnectedRoad &right) const
{ {
// TODO handle low priority road classes in a reasonable way // TODO handle low priority road classes in a reasonable way
const auto suppressed_type = [&](const ConnectedRoad &road) {
const auto in_mode = node_based_graph.GetEdgeData(via_edge).travel_mode;
const auto out_mode = node_based_graph.GetEdgeData(road.eid).travel_mode;
return in_mode == out_mode ? TurnType::Suppressed : TurnType::Notification;
};
if (left.entry_allowed && center.entry_allowed && right.entry_allowed) if (left.entry_allowed && center.entry_allowed && right.entry_allowed)
{ {
left.instruction = {TurnType::Fork, DirectionModifier::SlightLeft}; left.instruction = {TurnType::Fork, DirectionModifier::SlightLeft};
@@ -285,7 +299,7 @@ void IntersectionHandler::assignFork(const EdgeID via_edge,
} }
else else
{ {
center.instruction = {TurnType::Suppressed, DirectionModifier::Straight}; center.instruction = {suppressed_type(center), DirectionModifier::Straight};
} }
} }
else else
+8 -1
View File
@@ -566,6 +566,12 @@ std::pair<std::size_t, std::size_t> TurnHandler::findFork(const EdgeID via_edge,
return true; return true;
}(); }();
const auto has_compatible_modes = std::all_of(
intersection.begin() + right, intersection.begin() + left + 1, [&](const auto &road) {
return node_based_graph.GetEdgeData(road.eid).travel_mode ==
node_based_graph.GetEdgeData(via_edge).travel_mode;
});
// check if all entries in the fork range allow entry // check if all entries in the fork range allow entry
const bool only_valid_entries = [&]() { const bool only_valid_entries = [&]() {
BOOST_ASSERT(right <= left && left < intersection.size()); BOOST_ASSERT(right <= left && left < intersection.size());
@@ -585,7 +591,8 @@ std::pair<std::size_t, std::size_t> TurnHandler::findFork(const EdgeID via_edge,
// TODO check whether 2*NARROW_TURN is too large // TODO check whether 2*NARROW_TURN is too large
if (valid_indices && separated_at_left_side && separated_at_right_side && if (valid_indices && separated_at_left_side && separated_at_right_side &&
not_more_than_three && !has_obvious && has_compatible_classes && only_valid_entries) not_more_than_three && !has_obvious && has_compatible_classes && only_valid_entries &&
has_compatible_modes)
return std::make_pair(right, left); return std::make_pair(right, left);
} }
return std::make_pair(std::size_t{0}, std::size_t{0}); return std::make_pair(std::size_t{0}, std::size_t{0});
+82
View File
@@ -3,6 +3,7 @@
#include "engine/guidance/assemble_overview.hpp" #include "engine/guidance/assemble_overview.hpp"
#include "engine/guidance/assemble_route.hpp" #include "engine/guidance/assemble_route.hpp"
#include "engine/guidance/assemble_steps.hpp" #include "engine/guidance/assemble_steps.hpp"
#include "engine/guidance/post_processing.hpp"
#include <boost/test/test_case_template.hpp> #include <boost/test/test_case_template.hpp>
#include <boost/test/unit_test.hpp> #include <boost/test/unit_test.hpp>
@@ -17,4 +18,85 @@ BOOST_AUTO_TEST_CASE(rfc4648_test_vectors)
// TODO(daniel-j-h): // TODO(daniel-j-h):
} }
BOOST_AUTO_TEST_CASE(trim_short_segments)
{
using namespace osrm::extractor::guidance;
using namespace osrm::engine::guidance;
using namespace osrm::engine;
using namespace osrm::util;
Intersection intersection1{{FloatLongitude{-73.981154}, FloatLatitude{40.767762}},
{302},
{1},
Intersection::NO_INDEX,
0,
{0, 255},
{}};
Intersection intersection2{{FloatLongitude{-73.981495}, FloatLatitude{40.768275}},
{180},
{1},
0,
Intersection::NO_INDEX,
{0, 255},
{}};
// Check that duplicated coordinate in the end is removed
std::vector<RouteStep> steps = {{324,
"Central Park West",
"",
"",
"",
"",
"",
0.2,
1.9076601161280742,
TRAVEL_MODE_DRIVING,
{{FloatLongitude{-73.981492}, FloatLatitude{40.768258}},
329,
348,
{TurnType::ExitRotary, DirectionModifier::Straight},
WaypointType::Depart,
0},
0,
3,
{intersection1}},
{324,
"Central Park West",
"",
"",
"",
"",
"",
0,
0,
TRAVEL_MODE_DRIVING,
{{FloatLongitude{-73.981495}, FloatLatitude{40.768275}},
0,
0,
{TurnType::NoTurn, DirectionModifier::UTurn},
WaypointType::Arrive,
0},
2,
3,
{intersection2}}};
LegGeometry geometry;
geometry.locations = {{FloatLongitude{-73.981492}, FloatLatitude{40.768258}},
{FloatLongitude{-73.981495}, FloatLatitude{40.768275}},
{FloatLongitude{-73.981495}, FloatLatitude{40.768275}}};
geometry.segment_offsets = {0, 2};
geometry.segment_distances = {1.9076601161280742};
geometry.osm_node_ids = {OSMNodeID{0}, OSMNodeID{1}, OSMNodeID{2}};
geometry.annotations = {{1.9076601161280742, 0.2, 0}, {0, 0, 0}};
trimShortSegments(steps, geometry);
BOOST_CHECK_EQUAL(geometry.segment_distances.size(), 1);
BOOST_CHECK_EQUAL(geometry.segment_offsets.size(), 2);
BOOST_CHECK_EQUAL(geometry.segment_offsets.back(), 1);
BOOST_CHECK_EQUAL(geometry.annotations.size(), 1);
BOOST_CHECK_EQUAL(geometry.locations.size(), 2);
BOOST_CHECK_EQUAL(geometry.osm_node_ids.size(), 2);
}
BOOST_AUTO_TEST_SUITE_END() BOOST_AUTO_TEST_SUITE_END()
+7 -10
View File
@@ -117,8 +117,7 @@ BOOST_AUTO_TEST_CASE(compute_angle)
BOOST_CHECK_EQUAL(angle, 180); BOOST_CHECK_EQUAL(angle, 180);
// Tiny changes below our calculation resolution // Tiny changes below our calculation resolution
// This should be equivalent to having two points on the same // This should be equivalent to having two points on the same spot.
// spot.
first = Coordinate{FloatLongitude{0}, FloatLatitude{0}}; first = Coordinate{FloatLongitude{0}, FloatLatitude{0}};
middle = Coordinate{FloatLongitude{1}, FloatLatitude{0}}; middle = Coordinate{FloatLongitude{1}, FloatLatitude{0}};
end = Coordinate{FloatLongitude{1 + std::numeric_limits<double>::epsilon()}, FloatLatitude{0}}; end = Coordinate{FloatLongitude{1 + std::numeric_limits<double>::epsilon()}, FloatLatitude{0}};
@@ -126,14 +125,12 @@ BOOST_AUTO_TEST_CASE(compute_angle)
BOOST_CHECK_EQUAL(angle, 180); BOOST_CHECK_EQUAL(angle, 180);
// Invalid values // Invalid values
/* TODO: Enable this when I figure out how to use BOOST_CHECK_THROW BOOST_CHECK_THROW(
* and not have the whole test case fail... coordinate_calculation::computeAngle(
first = Coordinate(FloatLongitude{0}, FloatLatitude{0}); Coordinate(FloatLongitude{0}, FloatLatitude{0}),
middle = Coordinate(FloatLongitude{1}, FloatLatitude{0}); Coordinate(FloatLongitude{1}, FloatLatitude{0}),
end = Coordinate(FloatLongitude(std::numeric_limits<double>::max()), FloatLatitude{0}); Coordinate(FloatLongitude{std::numeric_limits<double>::max()}, FloatLatitude{0})),
BOOST_CHECK_THROW( coordinate_calculation::computeAngle(first,middle,end), boost::numeric::positive_overflow);
boost::numeric::positive_overflow);
*/
} }
// Regression test for bug captured in #1347 // Regression test for bug captured in #1347
+4 -2
View File
@@ -73,12 +73,14 @@ BOOST_AUTO_TEST_CASE(xyz_to_mercator)
double miny; double miny;
double maxx; double maxx;
double maxy; double maxy;
// http://tools.geofabrik.de/map/#13/85.0500/-175.5876&type=Geofabrik_Standard&grid=1
web_mercator::xyzToMercator(100, 0, 13, minx, miny, maxx, maxy); web_mercator::xyzToMercator(100, 0, 13, minx, miny, maxx, maxy);
BOOST_CHECK_CLOSE(minx, -19548311.361764118075, 0.0001); BOOST_CHECK_CLOSE(minx, -19548311.361764118075, 0.0001);
BOOST_CHECK_CLOSE(miny, 19971868.8804085782, 0.0001); BOOST_CHECK_CLOSE(miny, 20032616.372979045, 0.0001);
BOOST_CHECK_CLOSE(maxx, -19543419.391953866929, 0.0001); BOOST_CHECK_CLOSE(maxx, -19543419.391953866929, 0.0001);
BOOST_CHECK_CLOSE(maxy, 19971868.880408578, 0.0001); BOOST_CHECK_CLOSE(maxy, 20037508.342789277, 0.0001); // Mercator 6378137*pi, WGS 85.0511
} }
BOOST_AUTO_TEST_SUITE_END() BOOST_AUTO_TEST_SUITE_END()