diff --git a/CHANGELOG.md b/CHANGELOG.md index 95c7d6249..e1b4c4a42 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ - Changes from 5.20.0 - Features: - ADDED: all waypoints in responses now contain a distance property between the original coordinate and the snapped location. [#5255](https://github.com/Project-OSRM/osrm-backend/pull/5255) + # 5.20.0 - Changes from 5.19.0: - Table: diff --git a/docker/Dockerfile b/docker/Dockerfile index 50f531ed6..1180896bb 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -1,15 +1,13 @@ -FROM alpine:3.6 as buildstage - +FROM debian:buster-slim as builder ARG DOCKER_TAG RUN mkdir -p /src && mkdir -p /opt COPY . /src WORKDIR /src RUN NPROC=$(grep -c ^processor /proc/cpuinfo 2>/dev/null || 1) && \ - echo "@testing http://dl-cdn.alpinelinux.org/alpine/edge/testing" >> /etc/apk/repositories && \ - apk update && \ - apk upgrade && \ - apk add git cmake wget make libc-dev gcc g++ bzip2-dev boost-dev zlib-dev expat-dev lua5.2-dev libtbb@testing libtbb-dev@testing && \ + apt-get update && \ + apt-get -y --no-install-recommends install cmake make git gcc g++ libbz2-dev libstxxl-dev libstxxl1v5 libxml2-dev \ + libzip-dev libboost-all-dev lua5.2 liblua5.2-dev libtbb-dev -o APT::Install-Suggests=0 -o APT::Install-Recommends=0 && \ NPROC=$(grep -c ^processor /proc/cpuinfo 2>/dev/null || 1) && \ echo "Building OSRM ${DOCKER_TAG}" && \ git show --format="%H" | head -n1 > /opt/OSRM_GITSHA && \ @@ -33,13 +31,16 @@ RUN NPROC=$(grep -c ^processor /proc/cpuinfo 2>/dev/null || 1) && \ # Multistage build to reduce image size - https://docs.docker.com/engine/userguide/eng-image/multistage-build/#use-multi-stage-builds # Only the content below ends up in the image, this helps remove /src from the image (which is large) -FROM alpine:3.6 as runstage +FROM debian:buster-slim as runstage RUN mkdir -p /src && mkdir -p /opt -RUN echo "@testing http://dl-cdn.alpinelinux.org/alpine/edge/testing" >> /etc/apk/repositories && \ - apk update && \ - apk add boost-filesystem boost-program_options boost-regex boost-iostreams boost-thread libgomp lua5.2 expat libtbb@testing -COPY --from=buildstage /usr/local /usr/local -COPY --from=buildstage /opt /opt +RUN apt-get update && \ +apt-get install -y --no-install-recommends libboost-program-options1.62.0 libboost-regex1.62.0 \ +libboost-date-time1.62.0 libboost-chrono1.62.0 libboost-filesystem1.62.0 \ +libboost-iostreams1.62.0 libboost-thread1.62.0 expat liblua5.2-0 libtbb2 &&\ +rm -rf /var/lib/apt/lists/* +COPY --from=builder /usr/local /usr/local +COPY --from=builder /opt /opt +RUN chmod 0644 -R /opt WORKDIR /opt EXPOSE 5000 diff --git a/docs/http.md b/docs/http.md index cd4fb9885..e2bcd0141 100644 --- a/docs/http.md +++ b/docs/http.md @@ -119,7 +119,6 @@ In addition to the [general options](#general-options) the following options are - `code` if the request was successful `Ok` otherwise see the service dependent and general status codes. - `waypoints` array of `Waypoint` objects sorted by distance to the input coordinate. Each object has at least the following additional properties: - - `distance`: Distance in meters to the supplied input coordinate. - `nodes`: Array of OpenStreetMap node ids. #### Example Requests @@ -906,6 +905,7 @@ Object used to describe waypoint on a route. - `name` Name of the street the coordinate snapped to - `location` Array that contains the `[longitude, latitude]` pair of the snapped coordinate +- `distance` The distance, in metres, from the input coordinate to the snapped coordinate - `hint` Unique internal identifier of the segment (ephemeral, not constant over data updates) This can be used on subsequent request to significantly speed up the query and to connect multiple services. E.g. you can use the `hint` value obtained by the `nearest` query as `hint` values for `route` inputs. diff --git a/include/engine/api/base_api.hpp b/include/engine/api/base_api.hpp index 0e0dad33b..e0c924348 100644 --- a/include/engine/api/base_api.hpp +++ b/include/engine/api/base_api.hpp @@ -6,6 +6,7 @@ #include "engine/api/json_factory.hpp" #include "engine/hint.hpp" +#include "util/coordinate_calculation.hpp" #include #include @@ -53,6 +54,8 @@ class BaseAPI // TODO: check forward/reverse return json::makeWaypoint( phantom.location, + util::coordinate_calculation::fccApproximateDistance(phantom.location, + phantom.input_location), facade.GetNameForID(facade.GetNameIndex(phantom.forward_segment_id.id)).to_string(), Hint{phantom, facade.GetCheckSum()}); } @@ -61,6 +64,8 @@ class BaseAPI // TODO: check forward/reverse return json::makeWaypoint( phantom.location, + util::coordinate_calculation::fccApproximateDistance(phantom.location, + phantom.input_location), facade.GetNameForID(facade.GetNameIndex(phantom.forward_segment_id.id)) .to_string()); } diff --git a/include/engine/api/json_factory.hpp b/include/engine/api/json_factory.hpp index 627a59ead..db30ecc9e 100644 --- a/include/engine/api/json_factory.hpp +++ b/include/engine/api/json_factory.hpp @@ -33,7 +33,7 @@ namespace json namespace detail { -util::json::Array coordinateToLonLat(const util::Coordinate coordinate); +util::json::Array coordinateToLonLat(const util::Coordinate &coordinate); /** * Ensures that a bearing value is a whole number, and clamped to the range 0-359 @@ -86,11 +86,14 @@ util::json::Object makeRoute(const guidance::Route &route, const char *weight_name); // Creates a Waypoint without Hint, see the Hint overload below -util::json::Object makeWaypoint(const util::Coordinate location, std::string name); +util::json::Object +makeWaypoint(const util::Coordinate &location, const double &distance, std::string name); // Creates a Waypoint with Hint, see the overload above when Hint is not needed -util::json::Object -makeWaypoint(const util::Coordinate location, std::string name, const Hint &hint); +util::json::Object makeWaypoint(const util::Coordinate &location, + const double &distance, + std::string name, + const Hint &hint); util::json::Object makeRouteLeg(guidance::RouteLeg leg, util::json::Array steps); diff --git a/include/engine/api/nearest_api.hpp b/include/engine/api/nearest_api.hpp index 8793af6ca..bb55b0634 100644 --- a/include/engine/api/nearest_api.hpp +++ b/include/engine/api/nearest_api.hpp @@ -41,7 +41,6 @@ class NearestAPI final : public BaseAPI [this](const PhantomNodeWithDistance &phantom_with_distance) { auto &phantom_node = phantom_with_distance.phantom_node; auto waypoint = MakeWaypoint(phantom_node); - waypoint.values["distance"] = phantom_with_distance.distance; util::json::Array nodes; diff --git a/src/engine/api/json_factory.cpp b/src/engine/api/json_factory.cpp index 88d59f724..dc887f853 100644 --- a/src/engine/api/json_factory.cpp +++ b/src/engine/api/json_factory.cpp @@ -94,7 +94,7 @@ std::string waypointTypeToString(const guidance::WaypointType waypoint_type) return waypoint_type_names[static_cast(waypoint_type)]; } -util::json::Array coordinateToLonLat(const util::Coordinate coordinate) +util::json::Array coordinateToLonLat(const util::Coordinate &coordinate) { util::json::Array array; array.values.push_back(static_cast(util::toFloating(coordinate.lon))); @@ -240,17 +240,22 @@ util::json::Object makeRoute(const guidance::Route &route, return json_route; } -util::json::Object makeWaypoint(const util::Coordinate location, std::string name) +util::json::Object +makeWaypoint(const util::Coordinate &location, const double &distance, std::string name) { util::json::Object waypoint; waypoint.values["location"] = detail::coordinateToLonLat(location); waypoint.values["name"] = std::move(name); + waypoint.values["distance"] = distance; return waypoint; } -util::json::Object makeWaypoint(const util::Coordinate location, std::string name, const Hint &hint) +util::json::Object makeWaypoint(const util::Coordinate &location, + const double &distance, + std::string name, + const Hint &hint) { - auto waypoint = makeWaypoint(location, name); + auto waypoint = makeWaypoint(location, distance, name); waypoint.values["hint"] = hint.ToBase64(); return waypoint; } diff --git a/src/util/coordinate_calculation.cpp b/src/util/coordinate_calculation.cpp index cb9adb10a..10e64c6cb 100644 --- a/src/util/coordinate_calculation.cpp +++ b/src/util/coordinate_calculation.cpp @@ -153,7 +153,7 @@ double perpendicularDistance(const Coordinate segment_source, web_mercator::fromWGS84(query_location)); nearest_location = web_mercator::toWGS84(projected_nearest); - const double approximate_distance = greatCircleDistance(query_location, nearest_location); + const double approximate_distance = fccApproximateDistance(query_location, nearest_location); BOOST_ASSERT(0.0 <= approximate_distance); return approximate_distance; } diff --git a/unit_tests/library/route.cpp b/unit_tests/library/route.cpp index 2ce75b0e0..6a6faad96 100644 --- a/unit_tests/library/route.cpp +++ b/unit_tests/library/route.cpp @@ -1,6 +1,8 @@ #include #include +#include + #include "coordinates.hpp" #include "equal_json.hpp" #include "fixture.hpp" @@ -32,18 +34,28 @@ BOOST_AUTO_TEST_CASE(test_route_same_coordinates_fixture) // unset snapping dependent hint for (auto &itr : result.values["waypoints"].get().values) + { + // Hint values aren't stable, so blank it out itr.get().values["hint"] = ""; + // Round value to 6 decimal places for double comparison later + itr.get().values["distance"] = + round(itr.get().values["distance"].get().value * 1000000); + } + const auto location = json::Array{{{7.437070}, {43.749248}}}; json::Object reference{ {{"code", "Ok"}, {"waypoints", - json::Array{ - {json::Object{ - {{"name", "Boulevard du Larvotto"}, {"location", location}, {"hint", ""}}}, - json::Object{ - {{"name", "Boulevard du Larvotto"}, {"location", location}, {"hint", ""}}}}}}, + json::Array{{json::Object{{{"name", "Boulevard du Larvotto"}, + {"location", location}, + {"distance", round(0.137249 * 1000000)}, + {"hint", ""}}}, + json::Object{{{"name", "Boulevard du Larvotto"}, + {"location", location}, + {"distance", round(0.137249 * 1000000)}, + {"hint", ""}}}}}}, {"routes", json::Array{{json::Object{ {{"distance", 0.},