forked from jieter/Leaflet.encoded
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Polyline.encoded.js
158 lines (135 loc) · 3.76 KB
/
Polyline.encoded.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
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
/*
* L.PolylineUtil contains utilify functions for polylines, two methods
* are added to the L.Polyline object to support creation of polylines
* from an encoded string and converting existing polylines to an
* encoded string.
*
* - L.Polyline.fromEncoded(encoded [, options]) returns a L.Polyline
* - L.Polyline.encodePath() returns a string
*
* Actual code from:
* http://facstaff.unca.edu/mcmcclur/GoogleMaps/EncodePolyline/\
*/
/*jshint browser:true, debug: true, strict:false, globalstrict:false, indent:4, white:true, smarttabs:true*/
/*global L:true, console:true*/
(function () {
// This function is very similar to Google's, but I added
// some stuff to deal with the double slash issue.
var encodeNumber = function (num) {
var encodeString = "";
var nextValue, finalValue;
while (num >= 0x20) {
nextValue = (0x20 | (num & 0x1f)) + 63;
encodeString += (String.fromCharCode(nextValue));
num >>= 5;
}
finalValue = num + 63;
encodeString += (String.fromCharCode(finalValue));
return encodeString;
};
// This one is Google's verbatim.
var encodeSignedNumber = function (num) {
var sgn_num = num << 1;
if (num < 0) {
sgn_num = ~(sgn_num);
}
return encodeNumber(sgn_num);
};
var getLat = function (latlng) {
if (latlng.lat) {
return latlng.lat;
} else {
return latlng[0];
}
};
var getLng = function (latlng) {
if (latlng.lng) {
return latlng.lng;
} else {
return latlng[1];
}
};
var PolylineUtil = {
encode: function (latlngs, precision) {
var i, dlat, dlng;
var plat = 0;
var plng = 0;
var encoded_points = "";
if (typeof(precision) === 'undefined') precision = 5;
precision = Math.pow(10, precision);
for (i = 0; i < latlngs.length; i++) {
var lat = getLat(latlngs[i]);
var lng = getLng(latlngs[i]);
var late5 = Math.floor(lat * precision);
var lnge5 = Math.floor(lng * precision);
dlat = late5 - plat;
dlng = lnge5 - plng;
plat = late5;
plng = lnge5;
encoded_points += encodeSignedNumber(dlat) + encodeSignedNumber(dlng);
}
return encoded_points;
},
decode: function (encoded, precision) {
var len = encoded.length;
var index = 0;
var latlngs = [];
var lat = 0;
var lng = 0;
if (typeof(precision) === 'undefined') precision = 5;
precision = Math.pow(10, -precision);
while (index < len) {
var b;
var shift = 0;
var result = 0;
do {
b = encoded.charCodeAt(index++) - 63;
result |= (b & 0x1f) << shift;
shift += 5;
} while (b >= 0x20);
var dlat = ((result & 1) ? ~(result >> 1) : (result >> 1));
lat += dlat;
shift = 0;
result = 0;
do {
b = encoded.charCodeAt(index++) - 63;
result |= (b & 0x1f) << shift;
shift += 5;
} while (b >= 0x20);
var dlng = ((result & 1) ? ~(result >> 1) : (result >> 1));
lng += dlng;
latlngs.push([lat * precision, lng * precision]);
}
return latlngs;
}
};
// Export Node module
if (typeof module === 'object' && typeof module.exports === 'object') {
module.exports = PolylineUtil;
}
// Inject functionality into Leaflet
if (typeof L === 'object') {
if (!(L.Polyline.prototype.fromEncoded)) {
L.Polyline.fromEncoded = function (encoded, options) {
return new L.Polyline(PolylineUtil.decode(encoded), options);
};
}
if (!(L.Polygon.prototype.fromEncoded)) {
L.Polygon.fromEncoded = function (encoded, options) {
return new L.Polygon(PolylineUtil.decode(encoded), options);
};
}
var encodeMixin = {
encodePath: function () {
return PolylineUtil.encode(this.getLatLngs());
}
};
if (!L.Polyline.prototype.encodePath) {
L.Polyline.include(encodeMixin);
}
if (!L.Polygon.prototype.encodePath) {
L.Polygon.include(encodeMixin);
}
L.PolylineUtil = PolylineUtil;
}
})();