Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
epsylon
GitHub Repository: epsylon/ufonet
Path: blob/master/core/js/rlayer-src.js
1205 views
1
/*
2
RaphaelLayer, a JavaScript library for overlaying Raphael objects onto Leaflet interactive maps. http://dynmeth.github.com/RaphaelLayer
3
(c) 2012-2013, David Howell, Dynamic Methods Pty Ltd
4
5
Version 0.1.3
6
*/
7
8
(function() {
9
10
var R, originalR;
11
12
if (typeof exports != 'undefined') {
13
R = exports;
14
} else {
15
R = {};
16
17
originalR = window.R;
18
19
R.noConflict = function() {
20
window.R = originalR;
21
return R;
22
};
23
24
window.R = R;
25
}
26
27
R.version = '0.1.3';
28
29
R.Layer = L.Class.extend({
30
includes: L.Mixin.Events,
31
32
initialize: function(options) {
33
34
},
35
36
onAdd: function (map) {
37
this._map = map;
38
this._map._initRaphaelRoot();
39
this._paper = this._map._paper;
40
this._set = this._paper.set();
41
42
map.on('viewreset', this.projectLatLngs, this);
43
this.projectLatLngs();
44
},
45
46
onRemove: function(map) {
47
map.off('viewreset', this.projectLatLngs, this);
48
this._map = null;
49
this._set.forEach(function(item) {
50
item.remove();
51
}, this);
52
this._set.clear();
53
},
54
55
projectLatLngs: function() {
56
57
},
58
59
animate: function(attr, ms, easing, callback) {
60
this._set.animate(attr, ms, easing, callback);
61
62
return this;
63
},
64
65
hover: function(f_in, f_out, icontext, ocontext) {
66
this._set.hover(f_in, f_out, icontext, ocontext);
67
68
return this;
69
},
70
71
attr: function(name, value) {
72
this._set.attr(name, value);
73
74
return this;
75
}
76
});
77
78
L.Map.include({
79
_initRaphaelRoot: function () {
80
if (!this._raphaelRoot) {
81
this._raphaelRoot = this._panes.overlayPane;
82
this._paper = Raphael(this._raphaelRoot);
83
84
this.on('moveend', this._updateRaphaelViewport);
85
this._updateRaphaelViewport();
86
}
87
},
88
89
_updateRaphaelViewport: function () {
90
var p = 0.02,
91
size = this.getSize(),
92
panePos = L.DomUtil.getPosition(this._mapPane),
93
min = panePos.multiplyBy(-1)._subtract(size.multiplyBy(p)),
94
max = min.add(size.multiplyBy(1 + p*2)),
95
width = max.x - min.x,
96
height = max.y - min.y,
97
root = this._raphaelRoot,
98
pane = this._panes.overlayPane;
99
100
this._paper.setSize(width, height);
101
102
L.DomUtil.setPosition(root, min);
103
104
root.setAttribute('width', width);
105
root.setAttribute('height', height);
106
107
this._paper.setViewBox(min.x, min.y, width, height, false);
108
109
}
110
});
111
112
R.Marker = R.Layer.extend({
113
initialize: function(latlng, pathString, attr, options) {
114
R.Layer.prototype.initialize.call(this, options);
115
116
this._latlng = latlng;
117
this._pathString = (typeof pathString == 'string' ? pathString : 'M16,3.5c-4.142,0-7.5,3.358-7.5,7.5c0,4.143,7.5,18.121,7.5,18.121S23.5,15.143,23.5,11C23.5,6.858,20.143,3.5,16,3.5z M16,14.584c-1.979,0-3.584-1.604-3.584-3.584S14.021,7.416,16,7.416S19.584,9.021,19.584,11S17.979,14.584,16,14.584z');
118
this._attr = (typeof pathString == 'object' ? pathString : (attr ? attr : {'fill': '#000'}));
119
},
120
121
projectLatLngs: function() {
122
if (this._path) this._path.remove();
123
124
var p = this._map.latLngToLayerPoint(this._latlng);
125
var r = Raphael.pathBBox(this._pathString);
126
127
this._path = this._paper.path(this._pathString)
128
.attr(this._attr)
129
.translate(p.x - 1.05*r.width, p.y - 1.15*r.height)
130
.toFront();
131
132
this._set.push(this._path);
133
}
134
});
135
136
R.Pulse = R.Layer.extend({
137
initialize: function(latlng, radius, attr, pulseAttr, options) {
138
R.Layer.prototype.initialize.call(this, options);
139
140
this._latlng = latlng;
141
this._radius = (typeof radius == 'number' ? radius : 6);
142
this._attr = (typeof radius == 'object' ? radius : (typeof attr == 'object' ? attr : {'fill': '#30a3ec', 'stroke': '#30a3ec'}));
143
this._pulseAttr = (typeof radius == 'object' ? attr : typeof pulseAttr == 'object' ? pulseAttr : {
144
'stroke-width': 3,
145
'stroke': this._attr.stroke
146
});
147
this._repeat = 3;
148
},
149
150
onRemove: function (map) {
151
R.Layer.prototype.onRemove.call(this, map);
152
153
if(this._marker) this._marker.remove();
154
if(this._pulse) this._pulse.remove();
155
},
156
157
projectLatLngs: function() {
158
if(this._marker) this._marker.remove();
159
if(this._pulse) this._pulse.remove();
160
161
var p = this._map.latLngToLayerPoint(this._latlng);
162
163
this._marker = this._paper.circle(p.x, p.y, this._radius).attr(this._attr);
164
this._pulse = this._paper.circle(p.x, p.y, this._radius).attr(this._pulseAttr);
165
166
var anim = Raphael.animation({
167
'0%': {transform: 's0.3', opacity: 1.0},
168
'100%': {transform: 's3.0', opacity: 0.0, easing: '<'}
169
}, 1000);
170
171
this._pulse.animate(anim.repeat(this._repeat));
172
}
173
});
174
175
R.Polyline = R.Layer.extend({
176
177
initialize: function(latlngs, attr, options) {
178
R.Layer.prototype.initialize.call(this, options);
179
180
this._latlngs = latlngs;
181
this._attr = attr || {'fill': '#000', 'stroke': '#000'};
182
},
183
184
projectLatLngs: function() {
185
this._set.clear();
186
if (this._path) this._path.remove();
187
188
this._path = this._paper.path(this.getPathString())
189
.attr(this._attr)
190
.toBack();
191
192
this._set.push(this._path);
193
},
194
195
getPathString: function() {
196
for(var i=0, len=this._latlngs.length, str=''; i<len; i++) {
197
var p = this._map.latLngToLayerPoint(this._latlngs[i]);
198
str += (i ? 'L' : 'M') + p.x + ' ' + p.y;
199
}
200
return str;
201
}
202
});
203
204
R.Polygon = R.Layer.extend({
205
206
initialize: function(latlngs, attr, options) {
207
R.Layer.prototype.initialize.call(this, options);
208
209
if(latlngs.length == 1) {
210
if(latlngs[0] instanceof Array) {
211
latlngs = latlngs[0];
212
}
213
}
214
215
this._latlngs = latlngs;
216
this._attr = attr || {'fill': 'rgba(255, 0, 0, 0.5)', 'stroke': '#f00', 'stroke-width': 2};
217
},
218
219
projectLatLngs: function() {
220
if (this._path) this._path.remove();
221
222
this._path = this._paper.path(this.getPathString())
223
.attr(this._attr)
224
.toBack();
225
226
this._set.push(this._path);
227
},
228
229
getPathString: function() {
230
for(var i=0, len=this._latlngs.length, str=''; i<len; i++) {
231
var p = this._map.latLngToLayerPoint(this._latlngs[i]);
232
str += (i ? 'L' : 'M') + p.x + ' ' + p.y;
233
}
234
str += 'Z';
235
236
return str;
237
}
238
});
239
240
R.PolygonGlow = R.Layer.extend({
241
initialize: function(latlngs, attr, options) {
242
R.Layer.prototype.initialize.call(this, options);
243
244
this._latlngs = latlngs;
245
this._attr = attr || {'fill': 'rgba(255, 0, 0, 1)', 'stroke': '#f00', 'stroke-width': 3};
246
},
247
248
onRemove: function(map) {
249
R.Layer.prototype.onRemove.call(this, map);
250
251
if(this._path) this._path.remove();
252
},
253
254
projectLatLngs: function() {
255
if (this._path) this._path.remove();
256
257
this._path = this._paper.path(this.getPathString())
258
.attr(this._attr)
259
.toBack();
260
261
var p = this._path;
262
263
var fadeIn = function() {
264
p.animate({
265
'fill-opacity': 0.25
266
}, 1000, '<', fadeOut);
267
};
268
269
var fadeOut = function() {
270
p.animate({
271
'fill-opacity': 1
272
}, 1000, '<', fadeIn);
273
};
274
275
fadeOut();
276
},
277
278
getPathString: function() {
279
for(var i=0, len=this._latlngs.length, str=''; i<len; i++) {
280
var p = this._map.latLngToLayerPoint(this._latlngs[i]);
281
str += (i ? 'L' : 'M') + p.x + ' ' + p.y;
282
}
283
str += 'Z';
284
285
return str;
286
}
287
});
288
289
R.Bezier = R.Layer.extend({
290
initialize: function(latlngs, attr, options) {
291
R.Layer.prototype.initialize.call(this, options);
292
293
this._latlngs = latlngs;
294
this._attr = attr;
295
},
296
297
projectLatLngs: function() {
298
if(this._path) this._path.remove();
299
300
var start = this._map.latLngToLayerPoint(this._latlngs[0]),
301
end = this._map.latLngToLayerPoint(this._latlngs[1]),
302
cp = this.getControlPoint(start, end);
303
304
this._path = this._paper.path('M' + start.x + ' ' + start.y + 'Q' + cp.x + ' ' + cp.y + ' ' + end.x + ' ' + end.y)
305
.attr(this._attr)
306
.toBack();
307
308
this._set.push(this._path);
309
},
310
311
getControlPoint: function(start, end) {
312
var cp = { x: 0, y: 0 };
313
cp.x = start.x + (end.x - [start.x]) / 2;
314
cp.y = start.y + (end.y - [start.y]) / 2;
315
var amp = 0;
316
317
if (this.closeTo(start.x, end.x) && !this.closeTo(start.y, end.y)) {
318
amp = (start.x - end.x) * 1 + 15 * (start.x >= end.x ? 1 : -1);
319
cp.x = Math.max(start.x, end.x) + amp;
320
} else {
321
amp = (end.y - start.y) * 1.5 + 15 * (start.y < end.y ? 1 : -1);
322
cp.y = Math.min(start.y, end.y) + amp;
323
}
324
return cp;
325
},
326
327
closeTo: function(a, b) {
328
var t = 15;
329
return (a - b > -t && a - b < t);
330
}
331
});
332
333
R.BezierAnim = R.Layer.extend({
334
initialize: function(latlngs, attr, cb, options) {
335
R.Layer.prototype.initialize.call(this, options);
336
337
this._latlngs = latlngs;
338
this._attr = attr;
339
this._cb = cb;
340
},
341
342
onRemove: function (map) {
343
R.Layer.prototype.onRemove.call(this, map);
344
345
if(this._path) this._path.remove();
346
if(this._sub) this._sub.remove();
347
},
348
349
projectLatLngs: function() {
350
if(this._path) this._path.remove();
351
if(this._sub) this._sub.remove();
352
353
var self = this,
354
start = this._map.latLngToLayerPoint(this._latlngs[0]),
355
end = this._map.latLngToLayerPoint(this._latlngs[1]),
356
cp = this.getControlPoint(start, end),
357
pathString="M"+start.x+" "+start.y+" L"+end.x+" "+end.y,
358
line = this._paper.path(pathString).hide();
359
360
this._paper.customAttributes.alongBezier = function(a) {
361
var r = this.data('reverse');
362
var len = this.data('pathLength');
363
364
return {
365
path: this.data('bezierPath').getSubpath(r ? (1-a)*len : 0, r ? len : a*len)
366
};
367
};
368
369
var sub = this._sub = this._paper.path()
370
.data('bezierPath', line)
371
.data('pathLength', line.getTotalLength())
372
.data('reverse', false)
373
.attr({
374
'stroke': '#BE1E2D',
375
'alongBezier': 0,
376
'stroke-width': 2
377
});
378
379
sub.stop().animate({
380
alongBezier: 1
381
}, 2000, function() {
382
//self._cb();
383
sub.data('reverse', true);
384
// sub.stop().animate({
385
// 'alongBezier': 0
386
// }, 500, function() { sub.remove(); });
387
});
388
},
389
390
getControlPoint: function(start, end) {
391
var cp = { x: 0, y: 0 };
392
cp.x = start.x + (end.x - [start.x]) / 2;
393
cp.y = start.y + (end.y - [start.y]) / 2;
394
var amp = 0;
395
396
if (this.closeTo(start.x, end.x) && !this.closeTo(start.y, end.y)) {
397
amp = (start.x - end.x) * 1 + 15 * (start.x >= end.x ? 1 : -1);
398
cp.x = Math.max(start.x, end.x) + amp;
399
} else {
400
amp = (end.y - start.y) * 1.5 + 15 * (start.y < end.y ? 1 : -1);
401
cp.y = Math.min(start.y, end.y) + amp;
402
}
403
return cp;
404
},
405
406
closeTo: function(a, b) {
407
var t = 15;
408
return (a - b > -t && a - b < t);
409
}
410
});
411
412
R.FeatureGroup = L.FeatureGroup.extend({
413
initialize: function(layers, options) {
414
L.FeatureGroup.prototype.initialize.call(this, layers, options);
415
},
416
417
animate: function(attr, ms, easing, callback) {
418
this.eachLayer(function(layer) {
419
layer.animate(attr, ms, easing, callback);
420
});
421
},
422
423
onAdd: function(map) {
424
L.FeatureGroup.prototype.onAdd.call(this,map);
425
426
this._set = this._map._paper.set();
427
428
for(i in this._layers) {
429
this._set.push(this._layers[i]._set);
430
}
431
},
432
433
hover: function(h_in, h_out, c_in, c_out) {
434
this.eachLayer(function(layer) {
435
layer.hover(h_in, h_out, c_in, c_out);
436
});
437
438
return this;
439
},
440
441
attr: function(name, value) {
442
this.eachLayer(function(layer) {
443
layer.attr(name, value);
444
});
445
446
return this;
447
}
448
});
449
450
/*
451
* Contains L.MultiPolyline and L.MultiPolygon layers.
452
*/
453
454
(function () {
455
function createMulti(Klass) {
456
return R.FeatureGroup.extend({
457
initialize: function (latlngs, options) {
458
this._layers = {};
459
this._options = options;
460
this.setLatLngs(latlngs);
461
},
462
463
setLatLngs: function (latlngs) {
464
var i = 0, len = latlngs.length;
465
466
this.eachLayer(function (layer) {
467
if (i < len) {
468
layer.setLatLngs(latlngs[i++]);
469
} else {
470
this.removeLayer(layer);
471
}
472
}, this);
473
474
while (i < len) {
475
this.addLayer(new Klass(latlngs[i++], this._options));
476
}
477
478
return this;
479
}
480
});
481
}
482
483
R.MultiPolyline = createMulti(R.Polyline);
484
R.MultiPolygon = createMulti(R.Polygon);
485
}());
486
487
R.GeoJSON = R.FeatureGroup.extend({
488
initialize: function (geojson, options) {
489
L.Util.setOptions(this, options);
490
491
this._geojson = geojson;
492
this._layers = {};
493
494
if (geojson) {
495
this.addGeoJSON(geojson);
496
}
497
},
498
499
addGeoJSON: function (geojson) {
500
var features = geojson.features,
501
i, len;
502
503
if (features) {
504
for (i = 0, len = features.length; i < len; i++) {
505
this.addGeoJSON(features[i]);
506
}
507
return;
508
}
509
510
var isFeature = (geojson.type === 'Feature'),
511
geometry = isFeature ? geojson.geometry : geojson,
512
layer = R.GeoJSON.geometryToLayer(geometry, this.options.pointToLayer);
513
514
this.fire('featureparse', {
515
layer: layer,
516
properties: geojson.properties,
517
geometryType: geometry.type,
518
bbox: geojson.bbox,
519
id: geojson.id,
520
geometry: geojson.geometry
521
});
522
523
this.addLayer(layer);
524
}
525
});
526
527
L.Util.extend(R.GeoJSON, {
528
geometryToLayer: function (geometry, pointToLayer) {
529
var coords = geometry.coordinates,
530
layers = [],
531
latlng, latlngs, i, len, layer;
532
533
switch (geometry.type) {
534
case 'Point':
535
latlng = this.coordsToLatLng(coords);
536
return pointToLayer ? pointToLayer(latlng) : new R.Marker(latlng);
537
538
case 'MultiPoint':
539
for (i = 0, len = coords.length; i < len; i++) {
540
latlng = this.coordsToLatLng(coords[i]);
541
layer = pointToLayer ? pointToLayer(latlng) : new R.Marker(latlng);
542
layers.push(layer);
543
}
544
return new R.FeatureGroup(layers);
545
546
case 'LineString':
547
latlngs = this.coordsToLatLngs(coords);
548
return new R.Polyline(latlngs);
549
550
case 'Polygon':
551
latlngs = this.coordsToLatLngs(coords, 1);
552
return new R.Polygon(latlngs);
553
554
case 'MultiLineString':
555
latlngs = this.coordsToLatLngs(coords, 1);
556
return new R.MultiPolyline(latlngs);
557
558
case "MultiPolygon":
559
latlngs = this.coordsToLatLngs(coords, 2);
560
return new R.MultiPolygon(latlngs);
561
562
case "GeometryCollection":
563
for (i = 0, len = geometry.geometries.length; i < len; i++) {
564
layer = this.geometryToLayer(geometry.geometries[i], pointToLayer);
565
layers.push(layer);
566
}
567
return new R.FeatureGroup(layers);
568
569
default:
570
throw new Error('Invalid GeoJSON object.');
571
}
572
},
573
574
coordsToLatLng: function (coords, reverse) { // (Array, Boolean) -> LatLng
575
var lat = parseFloat(coords[reverse ? 0 : 1]),
576
lng = parseFloat(coords[reverse ? 1 : 0]);
577
578
return new L.LatLng(lat, lng, true);
579
},
580
581
coordsToLatLngs: function (coords, levelsDeep, reverse) { // (Array, Number, Boolean) -> Array
582
var latlng,
583
latlngs = [],
584
i, len;
585
586
for (i = 0, len = coords.length; i < len; i++) {
587
latlng = levelsDeep ?
588
this.coordsToLatLngs(coords[i], levelsDeep - 1, reverse) :
589
this.coordsToLatLng(coords[i], reverse);
590
latlngs.push(latlng);
591
}
592
593
return latlngs;
594
}
595
});
596
597
598
599
}());
600