diff --git a/src/ol/parser/polyline.js b/src/ol/parser/polyline.js index 72b9b9bc6f..8d76ba7f92 100644 --- a/src/ol/parser/polyline.js +++ b/src/ol/parser/polyline.js @@ -1,6 +1,73 @@ goog.provide('ol.parser.polyline'); +/** + * Encode a list of coordinates in a flat array and return an encoded string + * + * @param {Array.} flat_points A flat array of coordinates. + * @param {number=} opt_dimension The dimension of the coordinates in the array. + * @return {string} The encoded string. + */ +ol.parser.polyline.encodeFlatCoordinates = + function(flat_points, opt_dimension) { + var dimension = opt_dimension || 2; + + var last_point = new Array(dimension); + for (var i = 0; i < dimension; ++i) + last_point[i] = 0; + + var encoded = '', flat_points_length = flat_points.length; + for (var i = 0; i < flat_points_length;) { + for (var d = 0; d < dimension; ++d) { + var part = Math.round(flat_points[i++] * 1e5); + var delta = part - last_point[d]; + last_point[d] = part; + + encoded += ol.parser.polyline.encodeSignedInteger(delta); + } + } + + return encoded; +}; + + +/** + * Decode a list of coordinates from an encoded string into a flat array + * + * @param {string} encoded An encoded string. + * @param {number=} opt_dimension The dimension of the coordinates in the + * encoded string. + * @return {Array.} A flat array of coordinates. + */ +ol.parser.polyline.decodeFlatCoordinates = function(encoded, opt_dimension) { + var dimension = opt_dimension || 2; + + var last_point = new Array(dimension); + for (var i = 0; i < dimension; ++i) + last_point[i] = 0; + + var flat_points = new Array(), encoded_length = encoded.length; + for (var i = 0; i < encoded_length;) { + for (var d = 0; d < dimension; ++d) { + var result = 0; + var shift = 0; + + var b; + do { + b = encoded.charCodeAt(i++) - 63; + result |= (b & 0x1f) << shift; + shift += 5; + } while (b >= 0x20); + + last_point[d] += (result & 1) ? ~(result >> 1) : (result >> 1); + flat_points.push(last_point[d] / 1e5); + } + } + + return flat_points; +}; + + /** * Encode one single floating point number and return an encoded string * diff --git a/test/spec/ol/parser/polyline.test.js b/test/spec/ol/parser/polyline.test.js index ac8fa35d13..baba3223a6 100644 --- a/test/spec/ol/parser/polyline.test.js +++ b/test/spec/ol/parser/polyline.test.js @@ -2,6 +2,28 @@ goog.provide('ol.test.parser.polyline'); describe('ol.parser.polyline', function() { + var flat_points = [38.50000, -120.20000, + 40.70000, -120.95000, + 43.25200, -126.45300]; + + describe('encodeFlatCoordinates', function() { + it('returns expected value', function() { + var encodeFlatCoordinates = ol.parser.polyline.encodeFlatCoordinates; + + expect(encodeFlatCoordinates( + flat_points)).toEqual('_p~iF~ps|U_ulLnnqC_mqNvxq`@'); + }); + }); + + describe('decodeFlatCoordinates', function() { + it('returns expected value', function() { + var decodeFlatCoordinates = ol.parser.polyline.decodeFlatCoordinates; + + expect(decodeFlatCoordinates( + '_p~iF~ps|U_ulLnnqC_mqNvxq`@')).toEqual(flat_points); + }); + }); + describe('encodeFloat', function() { it('returns expected value', function() { var encodeFloat = ol.parser.polyline.encodeFloat;