compression of polylines is now a lot faster
This commit is contained in:
parent
3bcd262099
commit
c8b0f96251
@ -27,53 +27,47 @@ or see http://www.gnu.org/licenses/agpl.txt.
|
|||||||
|
|
||||||
class PolylineCompressor {
|
class PolylineCompressor {
|
||||||
private:
|
private:
|
||||||
inline string encodeSignedNumber(const int number) const {
|
inline void encodeVectorSignedNumber(vector<int> & numbers, string & output) {
|
||||||
int signedNumber = number << 1;
|
for(unsigned i = 0; i < numbers.size(); ++i) {
|
||||||
if (number < 0) {
|
numbers[i] <<= 1;
|
||||||
signedNumber = ~(signedNumber);
|
if (numbers[i] < 0) {
|
||||||
|
numbers[i] = ~(numbers[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for(unsigned i = 0; i < numbers.size(); ++i) {
|
||||||
|
encodeNumber(numbers[i], output);
|
||||||
}
|
}
|
||||||
return (encodeNumber(signedNumber));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inline string encodeNumber(int numberToEncode) const {
|
inline void encodeNumber(int numberToEncode, string & output) {
|
||||||
string encodeString;
|
|
||||||
|
|
||||||
while (numberToEncode >= 0x20) {
|
while (numberToEncode >= 0x20) {
|
||||||
int nextValue = (0x20 | (numberToEncode & 0x1f)) + 63;
|
int nextValue = (0x20 | (numberToEncode & 0x1f)) + 63;
|
||||||
encodeString += (static_cast<char> (nextValue));
|
output += (static_cast<char> (nextValue));
|
||||||
|
if(92 == nextValue)
|
||||||
|
output += (static_cast<char> (nextValue));
|
||||||
numberToEncode >>= 5;
|
numberToEncode >>= 5;
|
||||||
}
|
}
|
||||||
|
|
||||||
numberToEncode += 63;
|
numberToEncode += 63;
|
||||||
encodeString += (static_cast<char> (numberToEncode));
|
output += (static_cast<char> (numberToEncode));
|
||||||
|
if(92 == numberToEncode)
|
||||||
return encodeString;
|
output += (static_cast<char> (numberToEncode));
|
||||||
}
|
|
||||||
|
|
||||||
inline void replaceBackslash(string & str) {
|
|
||||||
size_t found = 0;
|
|
||||||
do {
|
|
||||||
found = str.find("\\", found);
|
|
||||||
if(found ==string::npos)
|
|
||||||
break;
|
|
||||||
str.insert(found, "\\");
|
|
||||||
found+=2;
|
|
||||||
} while(true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
inline void printEncodedString(vector<_Coordinate>& polyline, string &output) {
|
inline void printEncodedString(const vector<_Coordinate>& polyline, string &output) {
|
||||||
|
vector<int> deltaNumbers(2*polyline.size());
|
||||||
output += "\"";
|
output += "\"";
|
||||||
if(!polyline.empty()) {
|
if(!polyline.empty()) {
|
||||||
output += encodeSignedNumber(polyline[0].lat);
|
deltaNumbers[0] = polyline[0].lat;
|
||||||
output += encodeSignedNumber(polyline[0].lon);
|
deltaNumbers[1] = polyline[0].lon;
|
||||||
|
for(unsigned i = 1; i < polyline.size(); ++i) {
|
||||||
|
deltaNumbers[(2*i)] = (polyline[i].lat - polyline[i-1].lat);
|
||||||
|
deltaNumbers[(2*i)+1] = (polyline[i].lon - polyline[i-1].lon);
|
||||||
}
|
}
|
||||||
for(unsigned i = 1; i < polyline.size(); i++) {
|
encodeVectorSignedNumber(deltaNumbers, output);
|
||||||
output += encodeSignedNumber(polyline[i].lat - polyline[i-1].lat);
|
|
||||||
output += encodeSignedNumber(polyline[i].lon - polyline[i-1].lon);
|
|
||||||
}
|
}
|
||||||
output += "\"";
|
output += "\"";
|
||||||
replaceBackslash(output);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void printUnencodedString(vector<_Coordinate> & polyline, string & output) {
|
inline void printUnencodedString(vector<_Coordinate> & polyline, string & output) {
|
||||||
|
Loading…
Reference in New Issue
Block a user