-// Inject functionality into Leaflet
-(function (L) {
- if (!(L.Polyline.prototype.fromEncoded)) {
- L.Polyline.fromEncoded = function (encoded, options) {
- return new L.Polyline(L.PolylineUtil.decode(encoded), options);
- };
- }
- if (!(L.Polygon.prototype.fromEncoded)) {
- L.Polygon.fromEncoded = function (encoded, options) {
- return new L.Polygon(L.PolylineUtil.decode(encoded), options);
- };
- }
+ options.precision = options.precision || 5;
+ options.factor = options.factor || Math.pow(10, options.precision);
+ options.dimension = options.dimension || 2;
+ return options;
+ };
+
+ var PolylineUtil = {
+ encode: function (points, options) {
+ options = defaultOptions(options);
+
+ var flatPoints = [];
+ for (var i = 0, len = points.length; i < len; ++i) {
+ var point = points[i];
+
+ if (options.dimension === 2) {
+ flatPoints.push(point.lat || point[0]);
+ flatPoints.push(point.lng || point[1]);
+ } else {
+ for (var dim = 0; dim < options.dimension; ++dim) {
+ flatPoints.push(point[dim]);
+ }
+ }
+ }
+
+ return this.encodeDeltas(flatPoints, options);
+ },
+
+ decode: function (encoded, options) {
+ options = defaultOptions(options);
+
+ var flatPoints = this.decodeDeltas(encoded, options);
+
+ var points = [];
+ for (var i = 0, len = flatPoints.length; i + (options.dimension - 1) < len;) {
+ var point = [];
+
+ for (var dim = 0; dim < options.dimension; ++dim) {
+ point.push(flatPoints[i++]);
+ }
+
+ points.push(point);
+ }
+
+ 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;
+ }