Adding support for polyline compression. Reduces file size, see http://open.mapquestapi.com/common/encodedecode.html

This commit is contained in:
Dennis Luxen 2011-06-27 22:08:53 +00:00
parent 676333ab5a
commit e3b648ea72
4 changed files with 97 additions and 24 deletions

View File

@ -0,0 +1,78 @@
/*
open source routing machine
Copyright (C) Dennis Luxen, others 2010
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU AFFERO General Public License as published by
the Free Software Foundation; either version 3 of the License, or
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
or see http://www.gnu.org/licenses/agpl.txt.
*/
#ifndef POLYLINECOMPRESSOR_H_
#define POLYLINECOMPRESSOR_H_
#include "ExtractorStructs.h"
class PolylineCompressor {
private:
inline string encodeSignedNumber(int number) const {
int signedNumber = number << 1;
if (number < 0) {
signedNumber = ~(signedNumber);
}
return (encodeNumber(signedNumber));
}
inline string encodeNumber(int numberToEncode) const {
ostringstream encodeString;
while (numberToEncode >= 0x20) {
int nextValue = (0x20 | (numberToEncode & 0x1f)) + 63;
encodeString << (static_cast<char> (nextValue));
numberToEncode >>= 5;
}
numberToEncode += 63;
encodeString << (static_cast<char> (numberToEncode));
return encodeString.str();
}
public:
inline void printEncodedString(vector<_Coordinate>& polyline, string &output) {
output += encodeSignedNumber(polyline[0].lat);
output += encodeSignedNumber(polyline[0].lon);
for(unsigned i = 1; i < polyline.size(); i++) {
output += encodeSignedNumber(polyline[i].lat - polyline[i-1].lat);
output += encodeSignedNumber(polyline[i].lon - polyline[i-1].lon);
}
}
inline void printUnencodedString(vector<_Coordinate> & polyline, string & output) {
string tmp;
for(unsigned i = 0; i < polyline.size(); i++) {
convertLatLon(polyline[i].lat, tmp);
output += "[";
output += tmp;
convertLatLon(polyline[i].lon, tmp);
output += ", ";
output += tmp;
output += "]";
if( i < polyline.size()-1 ) {
output += ",";
}
}
}
};
#endif /* POLYLINECOMPRESSOR_H_ */

View File

@ -29,13 +29,17 @@ or see http://www.gnu.org/licenses/agpl.txt.
#include "../typedefs.h"
#include "../DataStructures/ExtractorStructs.h"
#include "../DataStructures/HashTable.h"
#include "../DataStructures/PolylineCompressor.h"
#include "../Util/StrIngUtil.h"
struct DescriptorConfig {
DescriptorConfig() : instructions(true), geometry(true), z(18) {}
DescriptorConfig() : instructions(true), geometry(true), encodeGeometry(false), z(18) {}
bool instructions;
bool geometry;
bool encodeGeometry;
unsigned short z;
PolylineCompressor pc;
};
template<class SearchEngineT>

View File

@ -19,6 +19,7 @@ or see http://www.gnu.org/licenses/agpl.txt.
*/
#include "BaseDescriptor.h"
#include "../DataStructures/PolylineCompressor.h"
#ifndef JSONDESCRIPTOR_H_
#define JSONDESCRIPTOR_H_
@ -29,6 +30,7 @@ template<class SearchEngineT>
class JSONDescriptor : public BaseDescriptor<SearchEngineT> {
private:
DescriptorConfig config;
vector<_Coordinate> polyline;
public:
JSONDescriptor() {}
void SetConfig(const DescriptorConfig c) {
@ -104,13 +106,7 @@ public:
routeInstructionString += direction;
//put start coord to linestring;
convertLatLon(phantomNodes->startCoord.lat, tmp);
routeGeometryString += "[";
routeGeometryString += tmp;
routeGeometryString += ", ";
convertLatLon(phantomNodes->startCoord.lon, tmp);
routeGeometryString += tmp;
routeGeometryString += "],";
polyline.push_back(phantomNodes->startCoord);
_Coordinate previous(phantomNodes->startCoord.lat, phantomNodes->startCoord.lon);
_Coordinate next, current, lastPlace, startOfSegment;
@ -147,13 +143,8 @@ public:
// std::cout << "Area for: " << area << std::endl;
if(area > areaThresholds[config.z] || 19 == config.z) {
painted++;
convertLatLon(current.lat, tmp);
routeGeometryString += "[";
routeGeometryString += tmp;
routeGeometryString += ", ";
convertLatLon(current.lon, tmp);
routeGeometryString += tmp;
routeGeometryString += "],";
polyline.push_back(current);
position++;
startOfSegment = current;
} else {
@ -200,8 +191,6 @@ public:
routeInstructionString += "],";
string lat; string lon;
convertLatLon(lastPlace.lon, lon);
convertLatLon(lastPlace.lat, lat);
lastPlace = current;
routeInstructionString += "[\"";
@ -264,13 +253,7 @@ public:
string lat; string lon;
//put targetCoord to linestring
convertLatLon(phantomNodes->targetCoord.lat, tmp);
routeGeometryString += "[";
routeGeometryString += tmp;
routeGeometryString += ", ";
convertLatLon(phantomNodes->targetCoord.lon, tmp);
routeGeometryString += tmp;
routeGeometryString += "]";
polyline.push_back(phantomNodes->targetCoord);
position++;
//give complete distance in meters;
@ -305,6 +288,11 @@ public:
reply.content += "},";
reply.content += "\"route_geometry\": [";
if(config.geometry) {
if(config.encodeGeometry)
config.pc.printEncodedString(polyline, routeGeometryString);
else
config.pc.printUnencodedString(polyline, routeGeometryString);
reply.content += routeGeometryString;
}
reply.content += "],";

View File

@ -119,6 +119,9 @@ public:
descriptorConfig.geometry = false;
}
if("cmp" == routeParameters.options.Find("geomformat") || "cmp6" == routeParameters.options.Find("geomformat") ) {
descriptorConfig.encodeGeometry = true;
}
switch(descriptorType){
case 0: