1'use strict'; 2 3/** 4 * Based off of [the offical Google document](https://developers.google.com/maps/documentation/utilities/polylinealgorithm) 5 * 6 * Some parts from [this implementation](http://facstaff.unca.edu/mcmcclur/GoogleMaps/EncodePolyline/PolylineEncoder.js) 7 * by [Mark McClure](http://facstaff.unca.edu/mcmcclur/) 8 * 9 * @module polyline 10 */ 11 12var polyline = {}; 13 14function encode(coord, factor) { 15 var coordinate = Math.round(coord * factor); 16 coordinate <<= 1; 17 if (coord < 0) { 18 coordinate = ~coordinate; 19 } 20 var output = ''; 21 while (coordinate >= 0x20) { 22 output += String.fromCharCode((0x20 | (coordinate & 0x1f)) + 63); 23 coordinate >>= 5; 24 } 25 output += String.fromCharCode(coordinate + 63); 26 return output; 27} 28 29/** 30 * Decodes to a [latitude, longitude] coordinates array. 31 * 32 * This is adapted from the implementation in Project-OSRM. 33 * 34 * @param {String} str 35 * @param {Number} precision 36 * @returns {Array} 37 * 38 * @see https://github.com/Project-OSRM/osrm-frontend/blob/master/WebContent/routing/OSRM.RoutingGeometry.js 39 */ 40polyline.decode = function(str, precision) { 41 var index = 0, 42 lat = 0, 43 lng = 0, 44 coordinates = [], 45 shift = 0, 46 result = 0, 47 byte = null, 48 latitude_change, 49 longitude_change, 50 factor = Math.pow(10, precision || 5); 51 52 // Coordinates have variable length when encoded, so just keep 53 // track of whether we've hit the end of the string. In each 54 // loop iteration, a single coordinate is decoded. 55 while (index < str.length) { 56 57 // Reset shift, result, and byte 58 byte = null; 59 shift = 0; 60 result = 0; 61 62 do { 63 byte = str.charCodeAt(index++) - 63; 64 result |= (byte & 0x1f) << shift; 65 shift += 5; 66 } while (byte >= 0x20); 67 68 latitude_change = ((result & 1) ? ~(result >> 1) : (result >> 1)); 69 70 shift = result = 0; 71 72 do { 73 byte = str.charCodeAt(index++) - 63; 74 result |= (byte & 0x1f) << shift; 75 shift += 5; 76 } while (byte >= 0x20); 77 78 longitude_change = ((result & 1) ? ~(result >> 1) : (result >> 1)); 79 80 lat += latitude_change; 81 lng += longitude_change; 82 83 coordinates.push([lat / factor, lng / factor]); 84 } 85 86 return coordinates; 87}; 88 89/** 90 * Encodes the given [latitude, longitude] coordinates array. 91 * 92 * @param {Array.<Array.<Number>>} coordinates 93 * @param {Number} precision 94 * @returns {String} 95 */ 96polyline.encode = function(coordinates, precision) { 97 if (!coordinates.length) { return ''; } 98 99 var factor = Math.pow(10, precision || 5), 100 output = encode(coordinates[0][0], factor) + encode(coordinates[0][1], factor); 101 102 for (var i = 1; i < coordinates.length; i++) { 103 var a = coordinates[i], b = coordinates[i - 1]; 104 output += encode(a[0] - b[0], factor); 105 output += encode(a[1] - b[1], factor); 106 } 107 108 return output; 109}; 110 111function flipped(coords) { 112 var flipped = []; 113 for (var i = 0; i < coords.length; i++) { 114 flipped.push(coords[i].slice().reverse()); 115 } 116 return flipped; 117} 118 119/** 120 * Encodes a GeoJSON LineString feature/geometry. 121 * 122 * @param {Object} geojson 123 * @param {Number} precision 124 * @returns {String} 125 */ 126polyline.fromGeoJSON = function(geojson, precision) { 127 if (geojson && geojson.type === 'Feature') { 128 geojson = geojson.geometry; 129 } 130 if (!geojson || geojson.type !== 'LineString') { 131 throw new Error('Input must be a GeoJSON LineString'); 132 } 133 return polyline.encode(flipped(geojson.coordinates), precision); 134}; 135 136/** 137 * Decodes to a GeoJSON LineString geometry. 138 * 139 * @param {String} str 140 * @param {Number} precision 141 * @returns {Object} 142 */ 143polyline.toGeoJSON = function(str, precision) { 144 var coords = polyline.decode(str, precision); 145 return { 146 type: 'LineString', 147 coordinates: flipped(coords) 148 }; 149}; 150 151if (typeof module === 'object' && module.exports) { 152 module.exports = polyline; 153}
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.