| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557 |
- /* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for
- * full list of contributors). Published under the 2-clause BSD license.
- * See license.txt in the OpenLayers distribution or repository for the
- * full text of the license. */
- /**
- * @requires OpenLayers/Format.js
- * @requires OpenLayers/Feature/Vector.js
- */
- /**
- * Class: OpenLayers.Format.EncodedPolyline
- * Class for reading and writing encoded polylines. Create a new instance
- * with the <OpenLayers.Format.EncodedPolyline> constructor.
- *
- * Inherits from:
- * - <OpenLayers.Format>
- */
- OpenLayers.Format.EncodedPolyline = OpenLayers.Class(OpenLayers.Format, {
- /**
- * APIProperty: geometryType
- * {String} Geometry type to output. One of: linestring (default),
- * linearring, point, multipoint or polygon. If the geometryType is
- * point, only the first point of the string is returned.
- */
- geometryType: "linestring",
- /**
- * Constructor: OpenLayers.Format.EncodedPolyline
- * Create a new parser for encoded polylines
- *
- * Parameters:
- * options - {Object} An optional object whose properties will be set on
- * this instance
- *
- * Returns:
- * {<OpenLayers.Format.EncodedPolyline>} A new encoded polylines parser.
- */
- initialize: function(options) {
- OpenLayers.Format.prototype.initialize.apply(this, [options]);
- },
- /**
- * APIMethod: read
- * Deserialize an encoded polyline string and return a vector feature.
- *
- * Parameters:
- * encoded - {String} An encoded polyline string
- *
- * Returns:
- * {<OpenLayers.Feature.Vector>} A vector feature with a linestring.
- */
- read: function(encoded) {
- var geomType;
- if (this.geometryType == "linestring")
- geomType = OpenLayers.Geometry.LineString;
- else if (this.geometryType == "linearring")
- geomType = OpenLayers.Geometry.LinearRing;
- else if (this.geometryType == "multipoint")
- geomType = OpenLayers.Geometry.MultiPoint;
- else if (this.geometryType != "point" && this.geometryType != "polygon")
- return null;
- var flatPoints = this.decodeDeltas(encoded, 2);
- var flatPointsLength = flatPoints.length;
- var pointGeometries = [];
- for (var i = 0; i + 1 < flatPointsLength;) {
- var y = flatPoints[i++], x = flatPoints[i++];
- pointGeometries.push(new OpenLayers.Geometry.Point(x, y));
- }
- if (this.geometryType == "point")
- return new OpenLayers.Feature.Vector(
- pointGeometries[0]
- );
- if (this.geometryType == "polygon")
- return new OpenLayers.Feature.Vector(
- new OpenLayers.Geometry.Polygon([
- new OpenLayers.Geometry.LinearRing(pointGeometries)
- ])
- );
- return new OpenLayers.Feature.Vector(
- new geomType(pointGeometries)
- );
- },
- /**
- * APIMethod: decode
- * Deserialize an encoded string and return an array of n-dimensional
- * points.
- *
- * Parameters:
- * encoded - {String} An encoded string
- * dims - {int} The dimension of the points that are returned
- *
- * Returns:
- * {Array(Array(int))} An array containing n-dimensional arrays of
- * coordinates.
- */
- decode: function(encoded, dims, opt_factor) {
- var factor = opt_factor || 1e5;
- var flatPoints = this.decodeDeltas(encoded, dims, factor);
- var flatPointsLength = flatPoints.length;
- var points = [];
- for (var i = 0; i + (dims - 1) < flatPointsLength;) {
- var point = [];
- for (var dim = 0; dim < dims; ++dim) {
- point.push(flatPoints[i++])
- }
- points.push(point);
- }
- return points;
- },
- /**
- * APIMethod: write
- * Serialize a feature or array of features into a WKT string.
- *
- * Parameters:
- * features - {<OpenLayers.Feature.Vector>|Array} A feature or array of
- * features
- *
- * Returns:
- * {String} The WKT string representation of the input geometries
- */
- write: function(features) {
- var feature;
- if (features.constructor == Array)
- feature = features[0];
- else
- feature = features;
- var geometry = feature.geometry;
- var type = geometry.CLASS_NAME.split('.')[2].toLowerCase();
- var pointGeometries;
- if (type == "point")
- pointGeometries = new Array(geometry);
- else if (type == "linestring" ||
- type == "linearring" ||
- type == "multipoint")
- pointGeometries = geometry.components;
- else if (type == "polygon")
- pointGeometries = geometry.components[0].components;
- else
- return null;
- var flatPoints = [];
- var pointGeometriesLength = pointGeometries.length;
- for (var i = 0; i < pointGeometriesLength; ++i) {
- var pointGeometry = pointGeometries[i];
- flatPoints.push(pointGeometry.y);
- flatPoints.push(pointGeometry.x);
- }
- return this.encodeDeltas(flatPoints, 2);
- },
- /**
- * APIMethod: encode
- * Serialize an array of n-dimensional points and return an encoded string
- *
- * Parameters:
- * points - {Array(Array(int))} An array containing n-dimensional
- * arrays of coordinates
- * dims - {int} The dimension of the points that should be read
- *
- * Returns:
- * {String} An encoded string
- */
- encode: function (points, dims, opt_factor) {
- var factor = opt_factor || 1e5;
- var flatPoints = [];
- var pointsLength = points.length;
- for (var i = 0; i < pointsLength; ++i) {
- var point = points[i];
- for (var dim = 0; dim < dims; ++dim) {
- flatPoints.push(point[dim]);
- }
- }
- return this.encodeDeltas(flatPoints, dims, factor);
- },
- /**
- * APIMethod: encodeDeltas
- * Encode a list of n-dimensional points and return an encoded string
- *
- * Attention: This function will modify the passed array!
- *
- * Parameters:
- * numbers - {Array.<number>} A list of n-dimensional points.
- * dimension - {number} The dimension of the points in the list.
- * opt_factor - {number=} The factor by which the numbers will be
- * multiplied. The remaining decimal places will get rounded away.
- *
- * Returns:
- * {string} The encoded string.
- */
- encodeDeltas: function(numbers, dimension, opt_factor) {
- var factor = opt_factor || 1e5;
- var d;
- var lastNumbers = new Array(dimension);
- for (d = 0; d < dimension; ++d) {
- lastNumbers[d] = 0;
- }
- var numbersLength = numbers.length;
- for (var i = 0; i < numbersLength;) {
- for (d = 0; d < dimension; ++d, ++i) {
- var num = numbers[i];
- var delta = num - lastNumbers[d];
- lastNumbers[d] = num;
- numbers[i] = delta;
- }
- }
- return this.encodeFloats(numbers, factor);
- },
- /**
- * APIMethod: decodeDeltas
- * Decode a list of n-dimensional points from an encoded string
- *
- * Parameters:
- * encoded - {string} An encoded string.
- * dimension - {number} The dimension of the points in the encoded string.
- * opt_factor - {number=} The factor by which the resulting numbers will
- * be divided.
- *
- * Returns:
- * {Array.<number>} A list of n-dimensional points.
- */
- decodeDeltas: function(encoded, dimension, opt_factor) {
- var factor = opt_factor || 1e5;
- var d;
- var lastNumbers = new Array(dimension);
- for (d = 0; d < dimension; ++d) {
- lastNumbers[d] = 0;
- }
- var numbers = this.decodeFloats(encoded, factor);
- var numbersLength = numbers.length;
- for (var i = 0; i < numbersLength;) {
- for (d = 0; d < dimension; ++d, ++i) {
- lastNumbers[d] += numbers[i];
- numbers[i] = lastNumbers[d];
- }
- }
- return numbers;
- },
- /**
- * APIMethod: encodeFloats
- * Encode a list of floating point numbers and return an encoded string
- *
- * Attention: This function will modify the passed array!
- *
- * Parameters:
- * numbers - {Array.<number>} A list of floating point numbers.
- * opt_factor - {number=} The factor by which the numbers will be
- * multiplied. The remaining decimal places will get rounded away.
- *
- * Returns:
- * {string} The encoded string.
- */
- encodeFloats: function(numbers, opt_factor) {
- var factor = opt_factor || 1e5;
- var numbersLength = numbers.length;
- for (var i = 0; i < numbersLength; ++i) {
- numbers[i] = Math.round(numbers[i] * factor);
- }
- return this.encodeSignedIntegers(numbers);
- },
- /**
- * APIMethod: decodeFloats
- * Decode a list of floating point numbers from an encoded string
- *
- * Parameters:
- * encoded - {string} An encoded string.
- * opt_factor - {number=} The factor by which the result will be divided.
- *
- * Returns:
- * {Array.<number>} A list of floating point numbers.
- */
- decodeFloats: function(encoded, opt_factor) {
- var factor = opt_factor || 1e5;
- var numbers = this.decodeSignedIntegers(encoded);
- var numbersLength = numbers.length;
- for (var i = 0; i < numbersLength; ++i) {
- numbers[i] /= factor;
- }
- return numbers;
- },
- /**
- * APIMethod: encodeSignedIntegers
- * Encode a list of signed integers and return an encoded string
- *
- * Attention: This function will modify the passed array!
- *
- * Parameters:
- * numbers - {Array.<number>} A list of signed integers.
- *
- * Returns:
- * {string} The encoded string.
- */
- encodeSignedIntegers: function(numbers) {
- var numbersLength = numbers.length;
- for (var i = 0; i < numbersLength; ++i) {
- var num = numbers[i];
- var signedNum = num << 1;
- if (num < 0) {
- signedNum = ~(signedNum);
- }
- numbers[i] = signedNum;
- }
- return this.encodeUnsignedIntegers(numbers);
- },
- /**
- * APIMethod: decodeSignedIntegers
- * Decode a list of signed integers from an encoded string
- *
- * Parameters:
- * encoded - {string} An encoded string.
- *
- * Returns:
- * {Array.<number>} A list of signed integers.
- */
- decodeSignedIntegers: function(encoded) {
- var numbers = this.decodeUnsignedIntegers(encoded);
- var numbersLength = numbers.length;
- for (var i = 0; i < numbersLength; ++i) {
- var num = numbers[i];
- numbers[i] = (num & 1) ? ~(num >> 1) : (num >> 1);
- }
- return numbers;
- },
- /**
- * APIMethod: encodeUnsignedIntegers
- * Encode a list of unsigned integers and return an encoded string
- *
- * Parameters:
- * numbers - {Array.<number>} A list of unsigned integers.
- *
- * Returns:
- * {string} The encoded string.
- */
- encodeUnsignedIntegers: function(numbers) {
- var encoded = '';
- var numbersLength = numbers.length;
- for (var i = 0; i < numbersLength; ++i) {
- encoded += this.encodeUnsignedInteger(numbers[i]);
- }
- return encoded;
- },
- /**
- * APIMethod: decodeUnsignedIntegers
- * Decode a list of unsigned integers from an encoded string
- *
- * Parameters:
- * encoded - {string} An encoded string.
- *
- * Returns:
- * {Array.<number>} A list of unsigned integers.
- */
- decodeUnsignedIntegers: function(encoded) {
- var numbers = [];
- var current = 0;
- var shift = 0;
- var encodedLength = encoded.length;
- for (var i = 0; i < encodedLength; ++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;
- },
- /**
- * Method: encodeFloat
- * Encode one single floating point number and return an encoded string
- *
- * Parameters:
- * num - {number} Floating point number that should be encoded.
- * opt_factor - {number=} The factor by which num will be multiplied.
- * The remaining decimal places will get rounded away.
- *
- * Returns:
- * {string} The encoded string.
- */
- encodeFloat: function(num, opt_factor) {
- num = Math.round(num * (opt_factor || 1e5));
- return this.encodeSignedInteger(num);
- },
- /**
- * Method: decodeFloat
- * Decode one single floating point number from an encoded string
- *
- * Parameters:
- * encoded - {string} An encoded string.
- * opt_factor - {number=} The factor by which the result will be divided.
- *
- * Returns:
- * {number} The decoded floating point number.
- */
- decodeFloat: function(encoded, opt_factor) {
- var result = this.decodeSignedInteger(encoded);
- return result / (opt_factor || 1e5);
- },
- /**
- * Method: encodeSignedInteger
- * Encode one single signed integer and return an encoded string
- *
- * Parameters:
- * num - {number} Signed integer that should be encoded.
- *
- * Returns:
- * {string} The encoded string.
- */
- encodeSignedInteger: function(num) {
- var signedNum = num << 1;
- if (num < 0) {
- signedNum = ~(signedNum);
- }
- return this.encodeUnsignedInteger(signedNum);
- },
- /**
- * Method: decodeSignedInteger
- * Decode one single signed integer from an encoded string
- *
- * Parameters:
- * encoded - {string} An encoded string.
- *
- * Returns:
- * {number} The decoded signed integer.
- */
- decodeSignedInteger: function(encoded) {
- var result = this.decodeUnsignedInteger(encoded);
- return ((result & 1) ? ~(result >> 1) : (result >> 1));
- },
- /**
- * Method: encodeUnsignedInteger
- * Encode one single unsigned integer and return an encoded string
- *
- * Parameters:
- * num - {number} Unsigned integer that should be encoded.
- *
- * Returns:
- * {string} The encoded string.
- */
- 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;
- },
- /**
- * Method: decodeUnsignedInteger
- * Decode one single unsigned integer from an encoded string
- *
- * Parameters:
- * encoded - {string} An encoded string.
- *
- * Returns:
- * {number} The decoded unsigned integer.
- */
- decodeUnsignedInteger: function(encoded) {
- var result = 0;
- var shift = 0;
- var encodedLength = encoded.length;
- for (var i = 0; i < encodedLength; ++i) {
- var b = encoded.charCodeAt(i) - 63;
- result |= (b & 0x1f) << shift;
- if (b < 0x20)
- break;
- shift += 5;
- }
- return result;
- },
- CLASS_NAME: "OpenLayers.Format.EncodedPolyline"
- });
|