Turn Angles in OSRM were computed using a lookahead of 10 meters.
This PR adds more advanced coordinate extraction, analysing the road to detect offsets due to OSM way modelling. In addition it improves the handling of bearings. Right now OSM reports bearings simply based on the very first coordinate along a way. With this PR, we store the bearings for a turn correctly, making the bearings for turns correct.
This commit is contained in:
@@ -292,6 +292,29 @@ Coordinate interpolateLinear(double factor, const Coordinate from, const Coordin
|
||||
return {std::move(interpolated_lon), std::move(interpolated_lat)};
|
||||
}
|
||||
|
||||
// compute the signed area of a triangle
|
||||
double signedArea(const Coordinate first_coordinate,
|
||||
const Coordinate second_coordinate,
|
||||
const Coordinate third_coordinate)
|
||||
{
|
||||
const auto lat_1 = static_cast<double>(toFloating(first_coordinate.lat));
|
||||
const auto lon_1 = static_cast<double>(toFloating(first_coordinate.lon));
|
||||
const auto lat_2 = static_cast<double>(toFloating(second_coordinate.lat));
|
||||
const auto lon_2 = static_cast<double>(toFloating(second_coordinate.lon));
|
||||
const auto lat_3 = static_cast<double>(toFloating(third_coordinate.lat));
|
||||
const auto lon_3 = static_cast<double>(toFloating(third_coordinate.lon));
|
||||
return 0.5 * (-lon_2 * lat_1 + lon_3 * lat_1 + lon_1 * lat_2 - lon_3 * lat_2 - lon_1 * lat_3 +
|
||||
lon_2 * lat_3);
|
||||
}
|
||||
|
||||
// check if a set of three coordinates is given in CCW order
|
||||
bool isCCW(const Coordinate first_coordinate,
|
||||
const Coordinate second_coordinate,
|
||||
const Coordinate third_coordinate)
|
||||
{
|
||||
return signedArea(first_coordinate, second_coordinate, third_coordinate) > 0;
|
||||
}
|
||||
|
||||
} // ns coordinate_calculation
|
||||
} // ns util
|
||||
} // ns osrm
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
#include "util/guidance/turn_bearing.hpp"
|
||||
|
||||
#include <boost/assert.hpp>
|
||||
|
||||
namespace osrm
|
||||
{
|
||||
namespace util
|
||||
{
|
||||
namespace guidance
|
||||
{
|
||||
|
||||
constexpr double bearing_scale = 360.0 / 256.0;
|
||||
|
||||
// discretizes a bearing into distinct units of 1.4 degrees
|
||||
TurnBearing::TurnBearing(const double value) : bearing(value / bearing_scale)
|
||||
{
|
||||
BOOST_ASSERT_MSG(value >= 0 && value <= 360.0, "Bearing value needs to be between 0 and 360");
|
||||
}
|
||||
|
||||
double TurnBearing::Get() const { return bearing * bearing_scale; }
|
||||
|
||||
} // namespace guidance
|
||||
} // namespace util
|
||||
} // namespace osrm
|
||||
Reference in New Issue
Block a user