From 9b0d3dfaeb259ed9bb22fb4fe462d6397ce8ab65 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20Gru=C3=9F?= Date: Sun, 31 May 2015 13:57:27 +0200 Subject: [PATCH 1/6] polyline string as parameter added --- algorithms/polyline_compressor.cpp | 38 ++++++++++++++++++++++++++++ algorithms/polyline_compressor.hpp | 4 +++ data_structures/route_parameters.cpp | 8 ++++++ include/osrm/route_parameters.hpp | 2 ++ server/api_grammar.hpp | 7 +++-- 5 files changed, 57 insertions(+), 2 deletions(-) diff --git a/algorithms/polyline_compressor.cpp b/algorithms/polyline_compressor.cpp index d5fd5828b..f4eca7350 100644 --- a/algorithms/polyline_compressor.cpp +++ b/algorithms/polyline_compressor.cpp @@ -88,3 +88,41 @@ PolylineCompressor::get_encoded_string(const std::vector &po } return encode_vector(delta_numbers); } + +std::vector PolylineCompressor::decode_string(const std::string geometry_string) const +{ + std::vector new_coordinates; + int index = 0, len = geometry_string.size(); + int lat = 0, lng = 0; + + while (index < len) + { + int b, shift = 0, result = 0; + do + { + b = geometry_string.at(index++) - 63; + result |= (b & 0x1f) << shift; + shift += 5; + } while (b >= 0x20); + int dlat = ((result & 1) != 0 ? ~(result >> 1) : (result >> 1)); + lat += dlat; + + shift = 0; + result = 0; + do + { + b = geometry_string.at(index++) - 63; + result |= (b & 0x1f) << shift; + shift += 5; + } while (b >= 0x20); + int dlng = ((result & 1) != 0 ? ~(result >> 1) : (result >> 1)); + lng += dlng; + + FixedPointCoordinate p; + p.lat = COORDINATE_PRECISION * (((double) lat / 1E5)); + p.lon = COORDINATE_PRECISION * (((double) lng / 1E5)); + new_coordinates.push_back(p); + } + + return new_coordinates; +} diff --git a/algorithms/polyline_compressor.hpp b/algorithms/polyline_compressor.hpp index 933ac7afa..82440d9e2 100644 --- a/algorithms/polyline_compressor.hpp +++ b/algorithms/polyline_compressor.hpp @@ -30,6 +30,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. struct SegmentInformation; +#include + #include #include @@ -42,6 +44,8 @@ class PolylineCompressor public: std::string get_encoded_string(const std::vector &polyline) const; + + std::vector decode_string(const std::string geometry_string) const; }; #endif /* POLYLINECOMPRESSOR_H_ */ diff --git a/data_structures/route_parameters.cpp b/data_structures/route_parameters.cpp index 3b615e2c4..86b955358 100644 --- a/data_structures/route_parameters.cpp +++ b/data_structures/route_parameters.cpp @@ -31,6 +31,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include +#include "../algorithms/polyline_compressor.hpp" + RouteParameters::RouteParameters() : zoom_level(18), print_instructions(false), alternate_route(true), geometry(true), compression(true), deprecatedAPI(false), uturn_default(false), classify(false), @@ -131,3 +133,9 @@ void RouteParameters::addCoordinate( static_cast(COORDINATE_PRECISION * boost::fusion::at_c<0>(received_coordinates)), static_cast(COORDINATE_PRECISION * boost::fusion::at_c<1>(received_coordinates))); } + +void RouteParameters::getCoordinatesFromGeometry(const std::string geometry_string) +{ + PolylineCompressor pc; + coordinates = pc.decode_string(geometry_string); +} diff --git a/include/osrm/route_parameters.hpp b/include/osrm/route_parameters.hpp index 9babbd763..bc413d73b 100644 --- a/include/osrm/route_parameters.hpp +++ b/include/osrm/route_parameters.hpp @@ -78,6 +78,8 @@ struct RouteParameters void setCompressionFlag(const bool flag); void addCoordinate(const boost::fusion::vector &received_coordinates); + + void getCoordinatesFromGeometry(const std::string geometry_string); short zoom_level; bool print_instructions; diff --git a/server/api_grammar.hpp b/server/api_grammar.hpp index a629cfbf7..158f1f7cc 100644 --- a/server/api_grammar.hpp +++ b/server/api_grammar.hpp @@ -42,7 +42,7 @@ template struct APIGrammar : qi::grammar> -(uturns); query = ('?') >> (+(zoom | output | jsonp | checksum | location | hint | timestamp | u | cmp | language | instruction | geometry | alt_route | old_API | num_results | - matching_beta | gps_precision | classify)); + matching_beta | gps_precision | classify | geometry_string)); zoom = (-qi::lit('&')) >> qi::lit('z') >> '=' >> qi::short_[boost::bind(&HandlerT::setZoomLevel, handler, ::_1)]; @@ -83,17 +83,20 @@ template struct APIGrammar : qi::grammar> qi::lit("classify") >> '=' >> qi::bool_[boost::bind(&HandlerT::setClassify, handler, ::_1)]; + geometry_string = (-qi::lit('&')) >> qi::lit("geometry_string") >> '=' >> + stringforPolyline[boost::bind(&HandlerT::getCoordinatesFromGeometry, handler, ::_1)]; string = +(qi::char_("a-zA-Z")); stringwithDot = +(qi::char_("a-zA-Z0-9_.-")); stringwithPercent = +(qi::char_("a-zA-Z0-9_.-") | qi::char_('[') | qi::char_(']') | (qi::char_('%') >> qi::char_("0-9A-Z") >> qi::char_("0-9A-Z"))); + stringforPolyline = +(qi::char_("a-zA-Z0-9_.-[]{}@?|\\%~`^")); } qi::rule api_call, query; qi::rule service, zoom, output, string, jsonp, checksum, location, hint, timestamp, stringwithDot, stringwithPercent, language, instruction, geometry, cmp, alt_route, u, - uturns, old_API, num_results, matching_beta, gps_precision, classify; + uturns, old_API, num_results, matching_beta, gps_precision, classify, geometry_string, stringforPolyline; HandlerT *handler; }; From 8b62d044532c7ea3af99037fd8562d9eaf74de4f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20Gru=C3=9F?= Date: Sun, 31 May 2015 14:05:53 +0200 Subject: [PATCH 2/6] test added --- unit_tests/algorithms/geometry_string.cpp | 69 +++++++++++++++++++++++ 1 file changed, 69 insertions(+) create mode 100644 unit_tests/algorithms/geometry_string.cpp diff --git a/unit_tests/algorithms/geometry_string.cpp b/unit_tests/algorithms/geometry_string.cpp new file mode 100644 index 000000000..4e0f55f33 --- /dev/null +++ b/unit_tests/algorithms/geometry_string.cpp @@ -0,0 +1,69 @@ +/* + +Copyright (c) 2015, Project OSRM contributors +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 +#include + +#include "../../algorithms/polyline_compressor.hpp" +#include "../../data_structures/coordinate_calculation.hpp" + +#include + +#include +#include + +BOOST_AUTO_TEST_CASE(geometry_string) +{ + // Polyline string for the 5 coordinates + const std::string polyline = "_c`|@_c`|@o}@_pRo}@}oRm}@apRo}@_pR"; + PolylineCompressor pc; + std::vector coords = pc.decode_string(polyline); + + // Test coordinates; these would be the coordinates we give the loc parameter, + // e.g. loc=10.00,10.0&loc=10.01,10.1... + FixedPointCoordinate coord1(10.00 * COORDINATE_PRECISION, 10.0 * COORDINATE_PRECISION); + FixedPointCoordinate coord2(10.01 * COORDINATE_PRECISION, 10.1 * COORDINATE_PRECISION); + FixedPointCoordinate coord3(10.02 * COORDINATE_PRECISION, 10.2 * COORDINATE_PRECISION); + FixedPointCoordinate coord4(10.03 * COORDINATE_PRECISION, 10.3 * COORDINATE_PRECISION); + FixedPointCoordinate coord5(10.04 * COORDINATE_PRECISION, 10.4 * COORDINATE_PRECISION); + + // Put the test coordinates into the vector for comparison + std::vector cmp_coords; + cmp_coords.emplace_back(coord1); + cmp_coords.emplace_back(coord2); + cmp_coords.emplace_back(coord3); + cmp_coords.emplace_back(coord4); + cmp_coords.emplace_back(coord5); + + BOOST_CHECK_EQUAL(cmp_coords.size(), coords.size()); + + for(unsigned i = 0; i < cmp_coords.size(); ++i) + { + BOOST_CHECK_CLOSE(cmp_coords.at(i).lat, coords.at(i).lat, 0.0001); + BOOST_CHECK_CLOSE(cmp_coords.at(i).lon, coords.at(i).lon, 0.0001); + } +} From ee3b296a9957ddc438557f06501a68c7b7031374 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20Gru=C3=9F?= Date: Sun, 31 May 2015 15:18:08 +0200 Subject: [PATCH 3/6] fixed values of test --- unit_tests/algorithms/geometry_string.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/unit_tests/algorithms/geometry_string.cpp b/unit_tests/algorithms/geometry_string.cpp index 4e0f55f33..c545e0d69 100644 --- a/unit_tests/algorithms/geometry_string.cpp +++ b/unit_tests/algorithms/geometry_string.cpp @@ -63,7 +63,12 @@ BOOST_AUTO_TEST_CASE(geometry_string) for(unsigned i = 0; i < cmp_coords.size(); ++i) { - BOOST_CHECK_CLOSE(cmp_coords.at(i).lat, coords.at(i).lat, 0.0001); - BOOST_CHECK_CLOSE(cmp_coords.at(i).lon, coords.at(i).lon, 0.0001); + const double cmp1_lat = coords.at(i).lat; + const double cmp2_lat = cmp_coords.at(i).lat; + BOOST_CHECK_CLOSE(cmp1_lat, cmp2_lat, 0.0001); + + const double cmp1_lon = coords.at(i).lon; + const double cmp2_lon = cmp_coords.at(i).lon; + BOOST_CHECK_CLOSE(cmp1_lon, cmp2_lon, 0.0001); } } From 79d2083a0028f8ee2c09f42aba2555cbaaf0ef50 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20Gru=C3=9F?= Date: Sun, 31 May 2015 15:28:31 +0200 Subject: [PATCH 4/6] changed parameter from geometry_string to locs --- server/api_grammar.hpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/server/api_grammar.hpp b/server/api_grammar.hpp index 158f1f7cc..470954f74 100644 --- a/server/api_grammar.hpp +++ b/server/api_grammar.hpp @@ -42,7 +42,7 @@ template struct APIGrammar : qi::grammar> -(uturns); query = ('?') >> (+(zoom | output | jsonp | checksum | location | hint | timestamp | u | cmp | language | instruction | geometry | alt_route | old_API | num_results | - matching_beta | gps_precision | classify | geometry_string)); + matching_beta | gps_precision | classify | locs)); zoom = (-qi::lit('&')) >> qi::lit('z') >> '=' >> qi::short_[boost::bind(&HandlerT::setZoomLevel, handler, ::_1)]; @@ -83,7 +83,7 @@ template struct APIGrammar : qi::grammar> qi::lit("classify") >> '=' >> qi::bool_[boost::bind(&HandlerT::setClassify, handler, ::_1)]; - geometry_string = (-qi::lit('&')) >> qi::lit("geometry_string") >> '=' >> + locs = (-qi::lit('&')) >> qi::lit("locs") >> '=' >> stringforPolyline[boost::bind(&HandlerT::getCoordinatesFromGeometry, handler, ::_1)]; string = +(qi::char_("a-zA-Z")); @@ -96,7 +96,7 @@ template struct APIGrammar : qi::grammar api_call, query; qi::rule service, zoom, output, string, jsonp, checksum, location, hint, timestamp, stringwithDot, stringwithPercent, language, instruction, geometry, cmp, alt_route, u, - uturns, old_API, num_results, matching_beta, gps_precision, classify, geometry_string, stringforPolyline; + uturns, old_API, num_results, matching_beta, gps_precision, classify, locs, stringforPolyline; HandlerT *handler; }; From 4d73f98050ed7b8dbdf6572d85982093f9dc69e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20Gru=C3=9F?= Date: Tue, 2 Jun 2015 13:06:06 +0200 Subject: [PATCH 5/6] made geometry_string a const reference --- algorithms/polyline_compressor.cpp | 2 +- algorithms/polyline_compressor.hpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/algorithms/polyline_compressor.cpp b/algorithms/polyline_compressor.cpp index f4eca7350..6377592b7 100644 --- a/algorithms/polyline_compressor.cpp +++ b/algorithms/polyline_compressor.cpp @@ -89,7 +89,7 @@ PolylineCompressor::get_encoded_string(const std::vector &po return encode_vector(delta_numbers); } -std::vector PolylineCompressor::decode_string(const std::string geometry_string) const +std::vector PolylineCompressor::decode_string(const std::string &geometry_string) const { std::vector new_coordinates; int index = 0, len = geometry_string.size(); diff --git a/algorithms/polyline_compressor.hpp b/algorithms/polyline_compressor.hpp index 82440d9e2..a148200ca 100644 --- a/algorithms/polyline_compressor.hpp +++ b/algorithms/polyline_compressor.hpp @@ -45,7 +45,7 @@ class PolylineCompressor public: std::string get_encoded_string(const std::vector &polyline) const; - std::vector decode_string(const std::string geometry_string) const; + std::vector decode_string(const std::string &geometry_string) const; }; #endif /* POLYLINECOMPRESSOR_H_ */ From 782fba2ce75b347ef109f8561b3004a801f769c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20Gru=C3=9F?= Date: Tue, 2 Jun 2015 13:15:31 +0200 Subject: [PATCH 6/6] updated to 1E6 based polyline format --- algorithms/polyline_compressor.cpp | 4 ++-- unit_tests/algorithms/geometry_string.cpp | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/algorithms/polyline_compressor.cpp b/algorithms/polyline_compressor.cpp index 6377592b7..0db75dcc6 100644 --- a/algorithms/polyline_compressor.cpp +++ b/algorithms/polyline_compressor.cpp @@ -119,8 +119,8 @@ std::vector PolylineCompressor::decode_string(const std::s lng += dlng; FixedPointCoordinate p; - p.lat = COORDINATE_PRECISION * (((double) lat / 1E5)); - p.lon = COORDINATE_PRECISION * (((double) lng / 1E5)); + p.lat = COORDINATE_PRECISION * (((double) lat / 1E6)); + p.lon = COORDINATE_PRECISION * (((double) lng / 1E6)); new_coordinates.push_back(p); } diff --git a/unit_tests/algorithms/geometry_string.cpp b/unit_tests/algorithms/geometry_string.cpp index c545e0d69..035b3217c 100644 --- a/unit_tests/algorithms/geometry_string.cpp +++ b/unit_tests/algorithms/geometry_string.cpp @@ -39,7 +39,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. BOOST_AUTO_TEST_CASE(geometry_string) { // Polyline string for the 5 coordinates - const std::string polyline = "_c`|@_c`|@o}@_pRo}@}oRm}@apRo}@_pR"; + const std::string polyline = "_gjaR_gjaR_pR_ibE_pR_ibE_pR_ibE_pR_ibE"; PolylineCompressor pc; std::vector coords = pc.decode_string(polyline);