Update to latest upstream polyline decoder

This commit is contained in:
Tom Hughes 2015-02-01 15:09:15 +00:00
parent fb70a89a36
commit 8adb0846b4
3 changed files with 222 additions and 112 deletions

View file

@ -33,6 +33,10 @@ folder 'vendor/assets' do
from 'git://github.com/jfirebaugh/leaflet-osm.git' do from 'git://github.com/jfirebaugh/leaflet-osm.git' do
file 'leaflet.osm.js', 'leaflet-osm.js' file 'leaflet.osm.js', 'leaflet-osm.js'
end end
from 'git://github.com/jieter/Leaflet.encoded.git' do
file 'leaflet.polyline.js', 'Polyline.encoded.js'
end
end end
folder 'ohauth' do folder 'ohauth' do

View file

@ -54,11 +54,9 @@ function OSRMEngine() {
previousPoints = points; previousPoints = points;
hintData = data.hint_data; hintData = data.hint_data;
var line = L.PolylineUtil.decode(data.route_geometry); var line = L.PolylineUtil.decode(data.route_geometry, {
for (var i = 0; i < line.length; i++) { precision: 6
line[i].lat /= 10; });
line[i].lng /= 10;
}
var steps = []; var steps = [];
for (i = 0; i < data.route_instructions.length; i++) { for (i = 0; i < data.route_instructions.length; i++) {

322
vendor/assets/leaflet/leaflet.polyline.js vendored Executable file → Normal file
View file

@ -1,127 +1,235 @@
/* /*
* L.PolylineUtil contains utilify functions for polylines, two methods * Utility functions to decode/encode numbers and array's of numbers
* are added to the L.Polyline object to support creation of polylines * to/from strings (Google maps polyline encoding)
* from an encoded string and converting existing polylines to an
* encoded string.
* *
* - L.Polyline.fromEncoded(encoded [, options]) returns a L.Polyline * Extends the L.Polyline and L.Polygon object with methods to convert
* - L.Polyline.encodePath() returns a string * to and create from these strings.
* *
* Actual code from: * Jan Pieter Waagmeester <jieter@jieter.nl>
* http://facstaff.unca.edu/mcmcclur/GoogleMaps/EncodePolyline/\ *
* Original code from:
* http://facstaff.unca.edu/mcmcclur/GoogleMaps/EncodePolyline/
* (which is down as of december 2014)
*/ */
/*jshint browser:true, debug: true, strict:false, globalstrict:false, indent:4, white:true, smarttabs:true*/ (function () {
/*global L:true, console:true*/ 'use strict';
var defaultOptions = function (options) {
// Inject functionality into Leaflet if (typeof options === 'number') {
(function (L) { // Legacy
if (!(L.Polyline.prototype.fromEncoded)) { options = { precision: options };
L.Polyline.fromEncoded = function (encoded, options) { } else {
return new L.Polyline(L.PolylineUtil.decode(encoded), options); options = options || {};
};
}
if (!(L.Polygon.prototype.fromEncoded)) {
L.Polygon.fromEncoded = function (encoded, options) {
return new L.Polygon(L.PolylineUtil.decode(encoded), options);
};
}
var encodeMixin = {
encodePath: function () {
return L.PolylineUtil.encode(this.getLatLngs());
} }
options.precision = options.precision || 5;
options.factor = options.factor || Math.pow(10, options.precision);
options.dimension = options.dimension || 2;
return options;
}; };
if (!L.Polyline.prototype.encodePath) { var PolylineUtil = {
L.Polyline.include(encodeMixin); encode: function (points, options) {
} options = defaultOptions(options);
if (!L.Polygon.prototype.encodePath) {
L.Polygon.include(encodeMixin);
}
})(L);
// Utility functions. var flatPoints = [];
L.PolylineUtil = {}; for (var i = 0, len = points.length; i < len; ++i) {
var point = points[i];
L.PolylineUtil.encode = function (latlngs) { if (options.dimension === 2) {
var i, dlat, dlng; flatPoints.push(point.lat || point[0]);
var plat = 0; flatPoints.push(point.lng || point[1]);
var plng = 0; } else {
var encoded_points = ""; for (var dim = 0; dim < options.dimension; ++dim) {
flatPoints.push(point[dim]);
}
}
}
for (i = 0; i < latlngs.length; i++) { return this.encodeDeltas(flatPoints, options);
var lat = latlngs[i].lat; },
var lng = latlngs[i].lng;
var late5 = Math.floor(lat * 1e5);
var lnge5 = Math.floor(lng * 1e5);
dlat = late5 - plat;
dlng = lnge5 - plng;
plat = late5;
plng = lnge5;
encoded_points +=
L.PolylineUtil.encodeSignedNumber(dlat) +
L.PolylineUtil.encodeSignedNumber(dlng);
}
return encoded_points;
};
// This function is very similar to Google's, but I added decode: function (encoded, options) {
// some stuff to deal with the double slash issue. options = defaultOptions(options);
L.PolylineUtil.encodeNumber = function (num) {
var encodeString = "";
var nextValue, finalValue;
while (num >= 0x20) {
nextValue = (0x20 | (num & 0x1f)) + 63;
encodeString += (String.fromCharCode(nextValue));
num >>= 5;
}
finalValue = num + 63;
encodeString += (String.fromCharCode(finalValue));
return encodeString;
};
// This one is Google's verbatim. var flatPoints = this.decodeDeltas(encoded, options);
L.PolylineUtil.encodeSignedNumber = function (num) {
var sgn_num = num << 1;
if (num < 0) {
sgn_num = ~(sgn_num);
}
return (L.PolylineUtil.encodeNumber(sgn_num));
};
L.PolylineUtil.decode = function (encoded) { var points = [];
var len = encoded.length; for (var i = 0, len = flatPoints.length; i + (options.dimension - 1) < len;) {
var index = 0; var point = [];
var latlngs = [];
var lat = 0;
var lng = 0;
while (index < len) { for (var dim = 0; dim < options.dimension; ++dim) {
var b; point.push(flatPoints[i++]);
var shift = 0; }
var result = 0;
do {
b = encoded.charCodeAt(index++) - 63;
result |= (b & 0x1f) << shift;
shift += 5;
} while (b >= 0x20);
var dlat = ((result & 1) ? ~(result >> 1) : (result >> 1));
lat += dlat;
shift = 0; points.push(point);
result = 0; }
do {
b = encoded.charCodeAt(index++) - 63;
result |= (b & 0x1f) << shift;
shift += 5;
} while (b >= 0x20);
var dlng = ((result & 1) ? ~(result >> 1) : (result >> 1));
lng += dlng;
latlngs.push(new L.LatLng(lat * 1e-5, lng * 1e-5)); return points;
},
encodeDeltas: function(numbers, options) {
options = defaultOptions(options);
var lastNumbers = [];
for (var i = 0, len = numbers.length; i < len;) {
for (var d = 0; d < options.dimension; ++d, ++i) {
var num = numbers[i];
var delta = num - (lastNumbers[d] || 0);
lastNumbers[d] = num;
numbers[i] = delta;
}
}
return this.encodeFloats(numbers, options);
},
decodeDeltas: function(encoded, options) {
options = defaultOptions(options);
var lastNumbers = [];
var numbers = this.decodeFloats(encoded, options);
for (var i = 0, len = numbers.length; i < len;) {
for (var d = 0; d < options.dimension; ++d, ++i) {
numbers[i] = lastNumbers[d] = numbers[i] + (lastNumbers[d] || 0);
}
}
return numbers;
},
encodeFloats: function(numbers, options) {
options = defaultOptions(options);
for (var i = 0, len = numbers.length; i < len; ++i) {
numbers[i] = Math.round(numbers[i] * options.factor);
}
return this.encodeSignedIntegers(numbers);
},
decodeFloats: function(encoded, options) {
options = defaultOptions(options);
var numbers = this.decodeSignedIntegers(encoded);
for (var i = 0, len = numbers.length; i < len; ++i) {
numbers[i] /= options.factor;
}
return numbers;
},
/* jshint bitwise:false */
encodeSignedIntegers: function(numbers) {
for (var i = 0, len = numbers.length; i < len; ++i) {
var num = numbers[i];
numbers[i] = (num < 0) ? ~(num << 1) : (num << 1);
}
return this.encodeUnsignedIntegers(numbers);
},
decodeSignedIntegers: function(encoded) {
var numbers = this.decodeUnsignedIntegers(encoded);
for (var i = 0, len = numbers.length; i < len; ++i) {
var num = numbers[i];
numbers[i] = (num & 1) ? ~(num >> 1) : (num >> 1);
}
return numbers;
},
encodeUnsignedIntegers: function(numbers) {
var encoded = '';
for (var i = 0, len = numbers.length; i < len; ++i) {
encoded += this.encodeUnsignedInteger(numbers[i]);
}
return encoded;
},
decodeUnsignedIntegers: function(encoded) {
var numbers = [];
var current = 0;
var shift = 0;
for (var i = 0, len = encoded.length; i < len; ++i) {
var b = encoded.charCodeAt(i) - 63;
current |= (b & 0x1f) << shift;
if (b < 0x20) {
numbers.push(current);
current = 0;
shift = 0;
} else {
shift += 5;
}
}
return numbers;
},
encodeSignedInteger: function (num) {
num = (num < 0) ? ~(num << 1) : (num << 1);
return this.encodeUnsignedInteger(num);
},
// This function is very similar to Google's, but I added
// some stuff to deal with the double slash issue.
encodeUnsignedInteger: function (num) {
var value, encoded = '';
while (num >= 0x20) {
value = (0x20 | (num & 0x1f)) + 63;
encoded += (String.fromCharCode(value));
num >>= 5;
}
value = num + 63;
encoded += (String.fromCharCode(value));
return encoded;
}
/* jshint bitwise:true */
};
// Export Node module
if (typeof module === 'object' && typeof module.exports === 'object') {
module.exports = PolylineUtil;
} }
return latlngs; // Inject functionality into Leaflet
}; if (typeof L === 'object') {
if (!(L.Polyline.prototype.fromEncoded)) {
L.Polyline.fromEncoded = function (encoded, options) {
return new L.Polyline(PolylineUtil.decode(encoded), options);
};
}
if (!(L.Polygon.prototype.fromEncoded)) {
L.Polygon.fromEncoded = function (encoded, options) {
return new L.Polygon(PolylineUtil.decode(encoded), options);
};
}
var encodeMixin = {
encodePath: function () {
return PolylineUtil.encode(this.getLatLngs());
}
};
if (!L.Polyline.prototype.encodePath) {
L.Polyline.include(encodeMixin);
}
if (!L.Polygon.prototype.encodePath) {
L.Polygon.include(encodeMixin);
}
L.PolylineUtil = PolylineUtil;
}
})();