-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathpolyline.js
126 lines (102 loc) · 3.55 KB
/
polyline.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
/**
* Polyline CommonJS Module
*
* Module that allows you to easily encode / decode polyline coordinates hashes used by the likes of Google for compressing
* Map routes - works great so making it available for the Appcelerati
*
* This is from the MapBox project.
* Completely cut and past this from https://github.com/mapbox/polyline/blob/master/src/polyline.js
*
*/
var polyline = {};
// Based off of [the offical Google document](https://developers.google.com/maps/documentation/utilities/polylinealgorithm)
//
// Some parts from [this implementation](http://facstaff.unca.edu/mcmcclur/GoogleMaps/EncodePolyline/PolylineEncoder.js)
// by [Mark McClure](http://facstaff.unca.edu/mcmcclur/)
polyline.encodeCoordinate = function(coordinate) {
coordinate = Math.round(coordinate * 1e5);
coordinate <<= 1;
if (coordinate < 0) {
coordinate = ~coordinate;
}
var output = '';
while (coordinate >= 0x20) {
output += String.fromCharCode((0x20 | (coordinate & 0x1f)) + 63);
coordinate >>= 5;
}
output += String.fromCharCode(coordinate + 63);
return output;
};
// See http://facstaff.unca.edu/mcmcclur/GoogleMaps/EncodePolyline/decode.js
polyline.decodeCoordinate = function(str) {
for (var i = 0; i < str.length; i++) {
var binary = str.charCodeAt(i) - 63;
result |= (b & 0x1f) << shift;
shift += 5;
}
};
// This is adapted from the implementation in Project-OSRM
// https://github.com/DennisOSRM/Project-OSRM-Web/blob/master/WebContent/routing/OSRM.RoutingGeometry.js
polyline.decodeLine = function(str) {
var index = 0,
lat = 0,
lng = 0,
coordinates = [],
shift = 0,
result = 0,
byte = null,
latitude_change,
longitude_change;
// Coordinates have variable length when encoded, so just keep
// track of whether we've hit the end of the string. In each
// loop iteration, a single coordinate is decoded.
while (index < str.length) {
// Reset shift, result, and byte
byte = null;
shift = 0;
result = 0;
do {
byte = str.charCodeAt(index++) - 63;
result |= (byte & 0x1f) << shift;
shift += 5;
} while (byte >= 0x20);
latitude_change = ((result & 1) ? ~(result >> 1) : (result >> 1));
shift = result = 0;
do {
byte = str.charCodeAt(index++) - 63;
result |= (byte & 0x1f) << shift;
shift += 5;
} while (byte >= 0x20);
longitude_change = ((result & 1) ? ~(result >> 1) : (result >> 1));
lat += latitude_change;
lng += longitude_change;
var precision = Math.pow(10, -5);
coordinates.push({latitude: lat * precision, longitude:lng * precision});
}
return coordinates;
};
// Simple encoding of a point, simply encoding two coordinates
polyline.encodePoint = function(x, y) {
return this.encodeCoordinate(x) + this.encodeCoordinate(y);
};
polyline.encodeLine = function(coordinates) {
var previous_point,
output = '',
longitude = 0,
latitude = 0;
for (var i = 0; i < coordinates.length; i++) {
var pt = [
coordinates[i][0],
coordinates[i][1]];
if (latitude || longitude) {
pt = [
pt[0] - latitude,
pt[1] - longitude];
}
output += this.encodePoint(pt[0], pt[1]);
latitude = pt[0];
longitude = pt[1];
}
return output;
};
if (typeof module !== undefined) module.exports = polyline;