leaflet-geodesic-rails 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: a10437447f4ecbedb10278f52a2c96e175c67311
4
+ data.tar.gz: 8eb2076cfead12eece7edba2bce9637167a6ffeb
5
+ SHA512:
6
+ metadata.gz: 3633df28e6b19f1df6e3d6f31c52b96519723099b2ce662bb8381a75c891d003eaa4670cc45bb7f9a3900dc3c8a15d7c5b5cd38d5667d3733da00fe996597014
7
+ data.tar.gz: 4279f33c5ff7dcb5fec1595ce27ad73013a32da8bd9f11fff43d971b34ff224b93a797c41bd9457367b5daf917f0c6337a06abd1438b655b48949410984551a0
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 Volker Wiegand
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,30 @@
1
+ # Leaflet.Geodesic for Rails
2
+
3
+ Engine wrapper for the Leaflet Geodesic library by @henrythasler.
4
+
5
+ https://github.com/henrythasler/Leaflet.Geodesic.git
6
+
7
+ ## Installation
8
+
9
+ Add this line to your application's Gemfile:
10
+
11
+ gem 'leaflet-geodesic-rails'
12
+
13
+ And then execute:
14
+
15
+ $ bundle
16
+
17
+ Or install it yourself as:
18
+
19
+ $ gem install leaflet-geodesic-rails
20
+
21
+ ## Usage
22
+
23
+ Provides the following assets:
24
+
25
+ leaflet.geodesic.js
26
+
27
+ ## License
28
+ MIT License, full text of license see [here][License]
29
+
30
+ [License]: https://github.com/henrythasler/Leaflet.Geodesic/blob/master/LICENSE "LICENSE"
@@ -0,0 +1,9 @@
1
+ require "leaflet/geodesic/rails/version"
2
+
3
+ module Leaflet
4
+ module Geodesic
5
+ module Rails
6
+ # Your code goes here...
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,7 @@
1
+ module Leaflet
2
+ module Geodesic
3
+ module Rails
4
+ VERSION = "0.7.0"
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,409 @@
1
+ // This file is part of Leaflet.Geodesic.
2
+ // Copyright (C) 2014 Henry Thasler
3
+ // based on code by Chris Veness Copyright (C) 2014 https://github.com/chrisveness/geodesy
4
+ //
5
+ // Leaflet.Geodesic is free software: you can redistribute it and/or modify
6
+ // it under the terms of the GNU General Public License as published by
7
+ // the Free Software Foundation, either version 3 of the License, or
8
+ // (at your option) any later version.
9
+ //
10
+ // Leaflet.Geodesic is distributed in the hope that it will be useful,
11
+ // but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ // GNU General Public License for more details.
14
+ //
15
+ // You should have received a copy of the GNU General Public License
16
+ // along with Leaflet.Geodesic. If not, see <http://www.gnu.org/licenses/>.
17
+
18
+
19
+
20
+ /** Extend Number object with method to convert numeric degrees to radians */
21
+ if (typeof Number.prototype.toRadians == 'undefined') {
22
+ Number.prototype.toRadians = function() { return this * Math.PI / 180; }
23
+ }
24
+
25
+ /** Extend Number object with method to convert radians to numeric (signed) degrees */
26
+ if (typeof Number.prototype.toDegrees == 'undefined') {
27
+ Number.prototype.toDegrees = function() { return this * 180 / Math.PI; }
28
+ }
29
+
30
+ var INTERSECT_LNG = 179.999; // Lng used for intersection and wrap around on map edges
31
+
32
+ L.Geodesic = L.MultiPolyline.extend({
33
+ options: {
34
+ color:'blue',
35
+ steps: 10,
36
+ dash: 1
37
+ },
38
+
39
+ initialize: function (latlngs, options) {
40
+ this.options = this._merge_options(this.options, options);
41
+ this.datum = {};
42
+ this.datum.ellipsoid = { a: 6378137, b: 6356752.3142, f: 1/298.257223563 }; // WGS-84
43
+ L.MultiPolyline.prototype.initialize.call(this, latlngs, this.options);
44
+ },
45
+
46
+ setLatLngs: function (latlngs) {
47
+ this._latlngs = (this.options.dash<1)?this._generate_GeodesicDashed(latlngs):this._generate_Geodesic(latlngs);
48
+ L.MultiPolyline.prototype.setLatLngs.call(this, this._latlngs);
49
+ },
50
+
51
+ /**
52
+ * Calculates some statistic values of current geodesic multipolyline
53
+ * @returns (Object} Object with several properties (e.g. overall distance)
54
+ */
55
+ getStats: function () {
56
+ var obj={ distance: 0,
57
+ points: 0,
58
+ polygons: this._latlngs.length
59
+ }, poly, points;
60
+
61
+ for(poly=0; poly<this._latlngs.length;poly++) {
62
+ obj.points+=this._latlngs[poly].length;
63
+ for(points=0;points<(this._latlngs[poly].length-1);points++) {
64
+ obj.distance += this._vincenty_inverse(this._latlngs[poly][points], this._latlngs[poly][points+1]).distance;
65
+ }
66
+ }
67
+ return obj;
68
+ },
69
+
70
+ /**
71
+ * Creates a great circle. Replaces all current lines.
72
+ * @param {Object} center - geographic position
73
+ * @param {number} radius - radius of the circle in meters
74
+ */
75
+ createCircle: function (center, radius) {
76
+ var _geo = [], _geocnt=0;
77
+ var prev = {lat:0, lng:0, brg:0};//new L.LatLng(0, 0);
78
+ var s;
79
+
80
+ _geo[_geocnt] = [];
81
+ for(s=0; s<=this.options.steps; ) {
82
+ var direct = this._vincenty_direct(center, 360/this.options.steps*s, radius);
83
+ var gp = new L.LatLng(direct.lat, direct.lng);
84
+ if(Math.abs(gp.lng-prev.lng) > 180) {
85
+ var inverse = this._vincenty_inverse(prev, gp);
86
+ var sec = this._intersection(prev, inverse.initialBearing, {lat: -89, lng:((gp.lng-prev.lng)>0)?-INTERSECT_LNG:INTERSECT_LNG}, 0);
87
+ if(sec) {
88
+ _geo[_geocnt].push(new L.LatLng(sec.lat, sec.lng));
89
+ _geocnt++;
90
+ _geo[_geocnt] = [];
91
+ prev = new L.LatLng(sec.lat, -sec.lng);
92
+ _geo[_geocnt].push(prev);
93
+ }
94
+ else {
95
+ _geocnt++;
96
+ _geo[_geocnt] = [];
97
+ _geo[_geocnt].push(gp);
98
+ prev = gp;
99
+ s++;
100
+ }
101
+ }
102
+ else {
103
+ _geo[_geocnt].push(gp);
104
+ prev = gp;
105
+ s++;
106
+ }
107
+ }
108
+
109
+ this._latlngs = _geo;
110
+ L.MultiPolyline.prototype.setLatLngs.call(this, this._latlngs);
111
+ },
112
+
113
+ /**
114
+ * Creates a geodesic MultiPolyline from given coordinates
115
+ * @param {Object} latlngs - One or more polylines as an array. See Leaflet doc about MultiPolyline
116
+ * @returns (Object} An array of arrays of geographical points.
117
+ */
118
+ _generate_Geodesic: function (latlngs) {
119
+ var _geo = [], _geocnt=0, s, poly, points;
120
+ // _geo = latlngs; // bypass
121
+
122
+ for(poly=0; poly<latlngs.length;poly++) {
123
+ _geo[_geocnt] = [];
124
+ for(points=0;points<(latlngs[poly].length-1);points++) {
125
+ var inverse = this._vincenty_inverse(latlngs[poly][points], latlngs[poly][points+1]);
126
+ var prev = latlngs[poly][points];
127
+ _geo[_geocnt].push(prev);
128
+ for(s=1; s<=this.options.steps; ) {
129
+ var direct = this._vincenty_direct(latlngs[poly][points], inverse.initialBearing, inverse.distance/this.options.steps*s);
130
+ var gp = new L.LatLng(direct.lat, direct.lng);
131
+ if(Math.abs(gp.lng-prev.lng) > 180) {
132
+ var sec = this._intersection(latlngs[poly][points], inverse.initialBearing, {lat: -89, lng:((gp.lng-prev.lng)>0)?-INTERSECT_LNG:INTERSECT_LNG}, 0);
133
+ if(sec) {
134
+ _geo[_geocnt].push(new L.LatLng(sec.lat, sec.lng));
135
+ _geocnt++;
136
+ _geo[_geocnt] = [];
137
+ prev = new L.LatLng(sec.lat, -sec.lng);
138
+ _geo[_geocnt].push(prev);
139
+ }
140
+ else {
141
+ _geocnt++;
142
+ _geo[_geocnt] = [];
143
+ _geo[_geocnt].push(gp);
144
+ prev = gp;
145
+ s++;
146
+ }
147
+ }
148
+ else {
149
+ _geo[_geocnt].push(gp);
150
+ prev = gp;
151
+ s++;
152
+ }
153
+ }
154
+ }
155
+ _geocnt++;
156
+ }
157
+ return _geo;
158
+ },
159
+
160
+
161
+ /**
162
+ * Creates a dashed geodesic MultiPolyline from given coordinates - under work
163
+ * @param {Object} latlngs - One or more polylines as an array. See Leaflet doc about MultiPolyline
164
+ * @returns (Object} An array of arrays of geographical points.
165
+ */
166
+ _generate_GeodesicDashed: function (latlngs) {
167
+ var _geo = [], _geocnt=0, s, poly, points;
168
+ // _geo = latlngs; // bypass
169
+
170
+ for(poly=0; poly<latlngs.length;poly++) {
171
+ _geo[_geocnt] = [];
172
+ for(points=0;points<(latlngs[poly].length-1);points++) {
173
+ var inverse = this._vincenty_inverse(latlngs[poly][points], latlngs[poly][points+1]);
174
+ var prev = latlngs[poly][points];
175
+ _geo[_geocnt].push(prev);
176
+ for(s=1; s<=this.options.steps; ) {
177
+ var direct = this._vincenty_direct(latlngs[poly][points], inverse.initialBearing, inverse.distance/this.options.steps*s-inverse.distance/this.options.steps*(1-this.options.dash));
178
+ var gp = new L.LatLng(direct.lat, direct.lng);
179
+ if(Math.abs(gp.lng-prev.lng) > 180) {
180
+ var sec = this._intersection(latlngs[poly][points], inverse.initialBearing, {lat: -89, lng:((gp.lng-prev.lng)>0)?-INTERSECT_LNG:INTERSECT_LNG}, 0);
181
+ if(sec) {
182
+ _geo[_geocnt].push(new L.LatLng(sec.lat, sec.lng));
183
+ _geocnt++;
184
+ _geo[_geocnt] = [];
185
+ prev = new L.LatLng(sec.lat, -sec.lng);
186
+ _geo[_geocnt].push(prev);
187
+ }
188
+ else {
189
+ _geocnt++;
190
+ _geo[_geocnt] = [];
191
+ _geo[_geocnt].push(gp);
192
+ prev = gp;
193
+ s++;
194
+ }
195
+ }
196
+ else {
197
+ _geo[_geocnt].push(gp);
198
+ _geocnt++;
199
+ var direct2 = this._vincenty_direct(latlngs[poly][points], inverse.initialBearing, inverse.distance/this.options.steps*s);
200
+ _geo[_geocnt] = [];
201
+ _geo[_geocnt].push(new L.LatLng(direct2.lat, direct2.lng));
202
+ s++;
203
+ }
204
+ }
205
+ }
206
+ _geocnt++;
207
+ }
208
+ return _geo;
209
+ },
210
+
211
+
212
+ /**
213
+ * Vincenty direct calculation.
214
+ * based on the work of Chris Veness (https://github.com/chrisveness/geodesy)
215
+ *
216
+ * @private
217
+ * @param {number} initialBearing - Initial bearing in degrees from north.
218
+ * @param {number} distance - Distance along bearing in metres.
219
+ * @returns (Object} Object including point (destination point), finalBearing.
220
+ */
221
+
222
+ _vincenty_direct : function (p1, initialBearing, distance) {
223
+ var φ1 = p1.lat.toRadians(), λ1 = p1.lng.toRadians();
224
+ var α1 = initialBearing.toRadians();
225
+ var s = distance;
226
+
227
+ var a = this.datum.ellipsoid.a, b = this.datum.ellipsoid.b, f = this.datum.ellipsoid.f;
228
+
229
+ var sinα1 = Math.sin(α1);
230
+ var cosα1 = Math.cos(α1);
231
+
232
+ var tanU1 = (1-f) * Math.tan(φ1), cosU1 = 1 / Math.sqrt((1 + tanU1*tanU1)), sinU1 = tanU1 * cosU1;
233
+ var σ1 = Math.atan2(tanU1, cosα1);
234
+ var sinα = cosU1 * sinα1;
235
+ var cosSqα = 1 - sinα*sinα;
236
+ var uSq = cosSqα * (a*a - b*b) / (b*b);
237
+ var A = 1 + uSq/16384*(4096+uSq*(-768+uSq*(320-175*uSq)));
238
+ var B = uSq/1024 * (256+uSq*(-128+uSq*(74-47*uSq)));
239
+
240
+ var σ = s / (b*A), σʹ, iterations = 0;
241
+ do {
242
+ var cos2σM = Math.cos(2*σ1 + σ);
243
+ var sinσ = Math.sin(σ);
244
+ var cosσ = Math.cos(σ);
245
+ var Δσ = B*sinσ*(cos2σM+B/4*(cosσ*(-1+2*cos2σM*cos2σM)-
246
+ B/6*cos2σM*(-3+4*sinσ*sinσ)*(-3+4*cos2σM*cos2σM)));
247
+ σʹ = σ;
248
+ σ = s / (b*A) + Δσ;
249
+ } while (Math.abs(σ-σʹ) > 1e-12 && ++iterations);
250
+
251
+ var x = sinU1*sinσ - cosU1*cosσ*cosα1;
252
+ var φ2 = Math.atan2(sinU1*cosσ + cosU1*sinσ*cosα1, (1-f)*Math.sqrt(sinα*sinα + x*x));
253
+ var λ = Math.atan2(sinσ*sinα1, cosU1*cosσ - sinU1*sinσ*cosα1);
254
+ var C = f/16*cosSqα*(4+f*(4-3*cosSqα));
255
+ var L = λ - (1-C) * f * sinα *
256
+ (σ + C*sinσ*(cos2σM+C*cosσ*(-1+2*cos2σM*cos2σM)));
257
+ var λ2 = (λ1+L+3*Math.PI)%(2*Math.PI) - Math.PI; // normalise to -180...+180
258
+
259
+ var revAz = Math.atan2(sinα, -x);
260
+
261
+ return {lat: φ2.toDegrees(),
262
+ lng: λ2.toDegrees(),
263
+ finalBearing: revAz.toDegrees()
264
+ };
265
+ },
266
+
267
+ /**
268
+ * Vincenty inverse calculation.
269
+ * based on the work of Chris Veness (https://github.com/chrisveness/geodesy)
270
+ *
271
+ * @private
272
+ * @param {LatLng} p1 - Latitude/longitude of start point.
273
+ * @param {LatLng} p2 - Latitude/longitude of destination point.
274
+ * @returns {Object} Object including distance, initialBearing, finalBearing.
275
+ * @throws {Error} If formula failed to converge.
276
+ */
277
+ _vincenty_inverse: function (p1, p2) {
278
+ var φ1 = p1.lat.toRadians(), λ1 = p1.lng.toRadians();
279
+ var φ2 = p2.lat.toRadians(), λ2 = p2.lng.toRadians();
280
+
281
+ var a = this.datum.ellipsoid.a, b = this.datum.ellipsoid.b, f = this.datum.ellipsoid.f;
282
+
283
+ var L = λ2 - λ1;
284
+ var tanU1 = (1-f) * Math.tan(φ1), cosU1 = 1 / Math.sqrt((1 + tanU1*tanU1)), sinU1 = tanU1 * cosU1;
285
+ var tanU2 = (1-f) * Math.tan(φ2), cosU2 = 1 / Math.sqrt((1 + tanU2*tanU2)), sinU2 = tanU2 * cosU2;
286
+
287
+ var λ = L, λʹ, iterations = 0;
288
+ do {
289
+ var sinλ = Math.sin(λ), cosλ = Math.cos(λ);
290
+ var sinSqσ = (cosU2*sinλ) * (cosU2*sinλ) + (cosU1*sinU2-sinU1*cosU2*cosλ) * (cosU1*sinU2-sinU1*cosU2*cosλ);
291
+ var sinσ = Math.sqrt(sinSqσ);
292
+ if (sinσ==0) return 0; // co-incident points
293
+ var cosσ = sinU1*sinU2 + cosU1*cosU2*cosλ;
294
+ var σ = Math.atan2(sinσ, cosσ);
295
+ var sinα = cosU1 * cosU2 * sinλ / sinσ;
296
+ var cosSqα = 1 - sinα*sinα;
297
+ var cos2σM = cosσ - 2*sinU1*sinU2/cosSqα;
298
+ if (isNaN(cos2σM)) cos2σM = 0; // equatorial line: cosSqα=0 (§6)
299
+ var C = f/16*cosSqα*(4+f*(4-3*cosSqα));
300
+ λʹ = λ;
301
+ λ = L + (1-C) * f * sinα * (σ + C*sinσ*(cos2σM+C*cosσ*(-1+2*cos2σM*cos2σM)));
302
+ } while (Math.abs(λ-λʹ) > 1e-12 && ++iterations<100);
303
+ if (iterations>=100) {
304
+ console.log('Formula failed to converge. Altering target position.')
305
+ return this._vincenty_inverse(p1, {lat: p2.lat, lng:p2.lng-0.01})
306
+ // throw new Error('Formula failed to converge');
307
+ }
308
+
309
+ var uSq = cosSqα * (a*a - b*b) / (b*b);
310
+ var A = 1 + uSq/16384*(4096+uSq*(-768+uSq*(320-175*uSq)));
311
+ var B = uSq/1024 * (256+uSq*(-128+uSq*(74-47*uSq)));
312
+ var Δσ = B*sinσ*(cos2σM+B/4*(cosσ*(-1+2*cos2σM*cos2σM)-
313
+ B/6*cos2σM*(-3+4*sinσ*sinσ)*(-3+4*cos2σM*cos2σM)));
314
+
315
+ var s = b*A*(σ-Δσ);
316
+
317
+ var fwdAz = Math.atan2(cosU2*sinλ, cosU1*sinU2-sinU1*cosU2*cosλ);
318
+ var revAz = Math.atan2(cosU1*sinλ, -sinU1*cosU2+cosU1*sinU2*cosλ);
319
+
320
+ s = Number(s.toFixed(3)); // round to 1mm precision
321
+ return { distance: s, initialBearing: fwdAz.toDegrees(), finalBearing: revAz.toDegrees() };
322
+ },
323
+
324
+
325
+ /**
326
+ * Returns the point of intersection of two paths defined by point and bearing.
327
+ * based on the work of Chris Veness (https://github.com/chrisveness/geodesy)
328
+ *
329
+ * @param {LatLon} p1 - First point.
330
+ * @param {number} brng1 - Initial bearing from first point.
331
+ * @param {LatLon} p2 - Second point.
332
+ * @param {number} brng2 - Initial bearing from second point.
333
+ * @returns {Object} containing lat/lng information of intersection.
334
+ *
335
+ * @example
336
+ * var p1 = LatLon(51.8853, 0.2545), brng1 = 108.55;
337
+ * var p2 = LatLon(49.0034, 2.5735), brng2 = 32.44;
338
+ * var pInt = LatLon.intersection(p1, brng1, p2, brng2); // pInt.toString(): 50.9078°N, 4.5084°E
339
+ */
340
+ _intersection : function(p1, brng1, p2, brng2) {
341
+ // see http://williams.best.vwh.net/avform.htm#Intersection
342
+
343
+ var φ1 = p1.lat.toRadians(), λ1 = p1.lng.toRadians();
344
+ var φ2 = p2.lat.toRadians(), λ2 = p2.lng.toRadians();
345
+ var θ13 = Number(brng1).toRadians(), θ23 = Number(brng2).toRadians();
346
+ var Δφ = φ2-φ1, Δλ = λ2-λ1;
347
+
348
+ var δ12 = 2*Math.asin( Math.sqrt( Math.sin(Δφ/2)*Math.sin(Δφ/2) +
349
+ Math.cos(φ1)*Math.cos(φ2)*Math.sin(Δλ/2)*Math.sin(Δλ/2) ) );
350
+ if (δ12 == 0) return null;
351
+
352
+ // initial/final bearings between points
353
+ var θ1 = Math.acos( ( Math.sin(φ2) - Math.sin(φ1)*Math.cos(δ12) ) /
354
+ ( Math.sin(δ12)*Math.cos(φ1) ) );
355
+ if (isNaN(θ1)) θ1 = 0; // protect against rounding
356
+ var θ2 = Math.acos( ( Math.sin(φ1) - Math.sin(φ2)*Math.cos(δ12) ) /
357
+ ( Math.sin(δ12)*Math.cos(φ2) ) );
358
+
359
+ if (Math.sin(λ2-λ1) > 0) {
360
+ var θ12 = θ1;
361
+ var θ21 = 2*Math.PI - θ2;
362
+ } else {
363
+ var θ12 = 2*Math.PI - θ1;
364
+ var θ21 = θ2;
365
+ }
366
+
367
+ var α1 = (θ13 - θ12 + Math.PI) % (2*Math.PI) - Math.PI; // angle 2-1-3
368
+ var α2 = (θ21 - θ23 + Math.PI) % (2*Math.PI) - Math.PI; // angle 1-2-3
369
+
370
+ if (Math.sin(α1)==0 && Math.sin(α2)==0) return null; // infinite intersections
371
+ if (Math.sin(α1)*Math.sin(α2) < 0) return null; // ambiguous intersection
372
+
373
+ //α1 = Math.abs(α1);
374
+ //α2 = Math.abs(α2);
375
+ // ... Ed Williams takes abs of α1/α2, but seems to break calculation?
376
+
377
+ var α3 = Math.acos( -Math.cos(α1)*Math.cos(α2) +
378
+ Math.sin(α1)*Math.sin(α2)*Math.cos(δ12) );
379
+ var δ13 = Math.atan2( Math.sin(δ12)*Math.sin(α1)*Math.sin(α2),
380
+ Math.cos(α2)+Math.cos(α1)*Math.cos(α3) )
381
+ var φ3 = Math.asin( Math.sin(φ1)*Math.cos(δ13) +
382
+ Math.cos(φ1)*Math.sin(δ13)*Math.cos(θ13) );
383
+ var Δλ13 = Math.atan2( Math.sin(θ13)*Math.sin(δ13)*Math.cos(φ1),
384
+ Math.cos(δ13)-Math.sin(φ1)*Math.sin(φ3) );
385
+ var λ3 = λ1 + Δλ13;
386
+ λ3 = (λ3+3*Math.PI) % (2*Math.PI) - Math.PI; // normalise to -180..+180º
387
+
388
+ return {lat: φ3.toDegrees(),
389
+ lng: λ3.toDegrees()
390
+ };
391
+ },
392
+
393
+ /**
394
+ * Overwrites obj1's values with obj2's and adds obj2's if non existent in obj1
395
+ * @param obj1
396
+ * @param obj2
397
+ * @returns obj3 a new object based on obj1 and obj2
398
+ */
399
+ _merge_options: function(obj1,obj2){
400
+ var obj3 = {};
401
+ for (var attrname in obj1) { obj3[attrname] = obj1[attrname]; }
402
+ for (var attrname in obj2) { obj3[attrname] = obj2[attrname]; }
403
+ return obj3;
404
+ }
405
+ });
406
+
407
+ L.geodesic = function(latlngs, options) {
408
+ return new L.Geodesic(latlngs, options);
409
+ };
metadata ADDED
@@ -0,0 +1,63 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: leaflet-geodesic-rails
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.7.0
5
+ platform: ruby
6
+ authors:
7
+ - Volker Wiegand
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-10-15 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: railties
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '3.1'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '3.1'
27
+ description: Rails engine for the Leaflet.Geodesic code
28
+ email:
29
+ - volker.wiegand@cvw.de
30
+ executables: []
31
+ extensions: []
32
+ extra_rdoc_files: []
33
+ files:
34
+ - LICENSE.txt
35
+ - README.md
36
+ - lib/leaflet/geodesic/rails.rb
37
+ - lib/leaflet/geodesic/rails/version.rb
38
+ - vendor/assets/javascripts/leaflet.geodesic.js
39
+ homepage: https://github.com/volkerwiegand/leaflet-geodesic-rails
40
+ licenses:
41
+ - MIT
42
+ metadata: {}
43
+ post_install_message:
44
+ rdoc_options: []
45
+ require_paths:
46
+ - lib
47
+ required_ruby_version: !ruby/object:Gem::Requirement
48
+ requirements:
49
+ - - ">="
50
+ - !ruby/object:Gem::Version
51
+ version: '0'
52
+ required_rubygems_version: !ruby/object:Gem::Requirement
53
+ requirements:
54
+ - - ">="
55
+ - !ruby/object:Gem::Version
56
+ version: '0'
57
+ requirements: []
58
+ rubyforge_project:
59
+ rubygems_version: 2.4.2
60
+ signing_key:
61
+ specification_version: 4
62
+ summary: Add-on to draw geodesic lines with Leaflet.
63
+ test_files: []