separate logic between polyline compression algorithm and JSON formatting.

fixes and closes #1245
This commit is contained in:
Dennis Luxen 2014-10-28 17:31:51 -04:00
parent b227c90c18
commit c791188811
6 changed files with 132 additions and 51 deletions

View File

@ -25,16 +25,16 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#include "PolylineCompressor.h" #include "polyline_compressor.hpp"
#include "../DataStructures/SegmentInformation.h" #include "../DataStructures/SegmentInformation.h"
#include <osrm/Coordinate.h> #include <osrm/Coordinate.h>
void PolylineCompressor::encodeVectorSignedNumber(std::vector<int> &numbers, std::string PolylineCompressor::encode_vector(std::vector<int> &numbers) const
std::string &output) const
{ {
const unsigned end = static_cast<unsigned>(numbers.size()); std::string output;
for (unsigned i = 0; i < end; ++i) const auto end = numbers.size();
for (std::size_t i = 0; i < end; ++i)
{ {
numbers[i] <<= 1; numbers[i] <<= 1;
if (numbers[i] < 0) if (numbers[i] < 0)
@ -44,12 +44,14 @@ void PolylineCompressor::encodeVectorSignedNumber(std::vector<int> &numbers,
} }
for (const int number : numbers) for (const int number : numbers)
{ {
encodeNumber(number, output); output += encode_number(number);
} }
return output;
} }
void PolylineCompressor::encodeNumber(int number_to_encode, std::string &output) const std::string PolylineCompressor::encode_number(int number_to_encode) const
{ {
std::string output;
while (number_to_encode >= 0x20) while (number_to_encode >= 0x20)
{ {
const int next_value = (0x20 | (number_to_encode & 0x1f)) + 63; const int next_value = (0x20 | (number_to_encode & 0x1f)) + 63;
@ -67,46 +69,29 @@ void PolylineCompressor::encodeNumber(int number_to_encode, std::string &output)
{ {
output += static_cast<char>(number_to_encode); output += static_cast<char>(number_to_encode);
} }
return output;
} }
JSON::String std::string
PolylineCompressor::printEncodedString(const std::vector<SegmentInformation> &polyline) const PolylineCompressor::get_encoded_string(const std::vector<SegmentInformation> &polyline) const
{ {
std::string output; std::string output;
std::vector<int> delta_numbers; std::vector<int> delta_numbers;
if (!polyline.empty()) if (polyline.empty())
{ {
FixedPointCoordinate last_coordinate = {0, 0}; return {};
for (const auto &segment : polyline)
{
if (segment.necessary)
{
const int lat_diff = segment.location.lat - last_coordinate.lat;
const int lon_diff = segment.location.lon - last_coordinate.lon;
delta_numbers.emplace_back(lat_diff);
delta_numbers.emplace_back(lon_diff);
last_coordinate = segment.location;
}
}
encodeVectorSignedNumber(delta_numbers, output);
} }
JSON::String return_value(output); FixedPointCoordinate previous_coordinate = {0, 0};
return return_value;
}
JSON::Array
PolylineCompressor::printUnencodedString(const std::vector<SegmentInformation> &polyline) const
{
JSON::Array json_geometry_array;
for (const auto &segment : polyline) for (const auto &segment : polyline)
{ {
if (segment.necessary) if (segment.necessary)
{ {
JSON::Array json_coordinate; const int lat_diff = segment.location.lat - previous_coordinate.lat;
json_coordinate.values.push_back(segment.location.lat / COORDINATE_PRECISION); const int lon_diff = segment.location.lon - previous_coordinate.lon;
json_coordinate.values.push_back(segment.location.lon / COORDINATE_PRECISION); delta_numbers.emplace_back(lat_diff);
json_geometry_array.values.push_back(json_coordinate); delta_numbers.emplace_back(lon_diff);
previous_coordinate = segment.location;
} }
} }
return json_geometry_array; return encode_vector(delta_numbers);
} }

View File

@ -0,0 +1,47 @@
/*
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
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.
*/
#ifndef POLYLINECOMPRESSOR_H_
#define POLYLINECOMPRESSOR_H_
struct SegmentInformation;
#include <string>
#include <vector>
class PolylineCompressor
{
private:
std::string encode_vector(std::vector<int> &numbers) const;
std::string encode_number(const int number_to_encode) const;
public:
std::string get_encoded_string(const std::vector<SegmentInformation> &polyline) const;
};
#endif /* POLYLINECOMPRESSOR_H_ */

View File

@ -0,0 +1,56 @@
/*
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
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 "polyline_formatter.hpp"
#include "polyline_compressor.hpp"
#include "../DataStructures/SegmentInformation.h"
#include <osrm/Coordinate.h>
JSON::String
PolylineFormatter::printEncodedString(const std::vector<SegmentInformation> &polyline) const
{
return JSON::String(PolylineCompressor().get_encoded_string(polyline));
}
JSON::Array
PolylineFormatter::printUnencodedString(const std::vector<SegmentInformation> &polyline) const
{
JSON::Array json_geometry_array;
for (const auto &segment : polyline)
{
if (segment.necessary)
{
JSON::Array json_coordinate;
json_coordinate.values.push_back(segment.location.lat / COORDINATE_PRECISION);
json_coordinate.values.push_back(segment.location.lon / COORDINATE_PRECISION);
json_geometry_array.values.push_back(json_coordinate);
}
}
return json_geometry_array;
}

View File

@ -25,8 +25,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#ifndef POLYLINECOMPRESSOR_H_ #ifndef POLYLINE_FORMATTER_H_
#define POLYLINECOMPRESSOR_H_ #define POLYLINE_FORMATTER_H_
struct SegmentInformation; struct SegmentInformation;
@ -35,17 +35,11 @@ struct SegmentInformation;
#include <string> #include <string>
#include <vector> #include <vector>
class PolylineCompressor struct PolylineFormatter
{ {
private:
void encodeVectorSignedNumber(std::vector<int> &numbers, std::string &output) const;
void encodeNumber(int number_to_encode, std::string &output) const;
public:
JSON::String printEncodedString(const std::vector<SegmentInformation> &polyline) const; JSON::String printEncodedString(const std::vector<SegmentInformation> &polyline) const;
JSON::Array printUnencodedString(const std::vector<SegmentInformation> &polyline) const; JSON::Array printUnencodedString(const std::vector<SegmentInformation> &polyline) const;
}; };
#endif /* POLYLINECOMPRESSOR_H_ */ #endif /* POLYLINE_FORMATTER_H_ */

View File

@ -30,7 +30,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <osrm/Coordinate.h> #include <osrm/Coordinate.h>
#include "../typedefs.h" #include "../typedefs.h"
#include "../Algorithms/PolylineCompressor.h" #include "../Algorithms/polyline_formatter.hpp"
#include "../DataStructures/RawRouteData.h" #include "../DataStructures/RawRouteData.h"
#include "../DataStructures/SegmentInformation.h" #include "../DataStructures/SegmentInformation.h"
#include "../DataStructures/TurnInstructions.h" #include "../DataStructures/TurnInstructions.h"
@ -112,9 +112,9 @@ JSON::Value DescriptionFactory::AppendGeometryString(const bool return_encoded)
{ {
if (return_encoded) if (return_encoded)
{ {
return polyline_compressor.printEncodedString(path_description); return PolylineFormatter().printEncodedString(path_description);
} }
return polyline_compressor.printUnencodedString(path_description); return PolylineFormatter().printUnencodedString(path_description);
} }
void DescriptionFactory::BuildRouteSummary(const double distance, const unsigned time) void DescriptionFactory::BuildRouteSummary(const double distance, const unsigned time)

View File

@ -29,8 +29,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#define DESCRIPTIONFACTORY_H_ #define DESCRIPTIONFACTORY_H_
#include "../Algorithms/DouglasPeucker.h" #include "../Algorithms/DouglasPeucker.h"
#include "../Algorithms/PolylineCompressor.h"
#include "../DataStructures/phantom_node.hpp" #include "../DataStructures/phantom_node.hpp"
#include "../DataStructures/JSONContainer.h"
#include "../DataStructures/SegmentInformation.h" #include "../DataStructures/SegmentInformation.h"
#include "../DataStructures/TurnInstructions.h" #include "../DataStructures/TurnInstructions.h"
#include "../typedefs.h" #include "../typedefs.h"
@ -47,7 +47,6 @@ struct PathData;
class DescriptionFactory class DescriptionFactory
{ {
DouglasPeucker polyline_generalizer; DouglasPeucker polyline_generalizer;
PolylineCompressor polyline_compressor;
PhantomNode start_phantom, target_phantom; PhantomNode start_phantom, target_phantom;
double DegreeToRadian(const double degree) const; double DegreeToRadian(const double degree) const;