foliage 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/LICENSE.txt +22 -0
- data/README.md +9 -0
- data/app/assets/images/.keep +0 -0
- data/app/assets/images/map/marker/icon-2x.png +0 -0
- data/app/assets/images/map/marker/icon.png +0 -0
- data/app/assets/images/map/marker/icon.svg +67 -0
- data/app/assets/images/map/marker/shadow.png +0 -0
- data/app/assets/javascripts/core_ext.js.coffee +61 -0
- data/app/assets/javascripts/foliage.js.coffee +23 -0
- data/app/assets/javascripts/foliage/band.js.coffee +99 -0
- data/app/assets/javascripts/foliage/bubbles.js.coffee +77 -0
- data/app/assets/javascripts/foliage/categories.js.coffee +70 -0
- data/app/assets/javascripts/foliage/choropleth.js.coffee +51 -0
- data/app/assets/javascripts/foliage/color.js.coffee +39 -0
- data/app/assets/javascripts/foliage/gradient.js.coffee +72 -0
- data/app/assets/javascripts/foliage/heatmap.js.coffee +49 -0
- data/app/assets/javascripts/foliage/leaf.js.coffee +422 -0
- data/app/assets/javascripts/foliage/path.js.coffee +76 -0
- data/app/assets/javascripts/foliage/paths.js.coffee +131 -0
- data/app/assets/javascripts/foliage/point_group.js.coffee +83 -0
- data/app/assets/javascripts/foliage/points.js.coffee +79 -0
- data/app/assets/javascripts/foliage/simple.js.coffee +35 -0
- data/app/assets/javascripts/leaflet/geographic_util.js.coffee +23 -0
- data/app/assets/javascripts/leaflet/ghost_label.js.coffee +100 -0
- data/app/assets/javascripts/leaflet/ghost_label_cluster.js.coffee +192 -0
- data/app/assets/javascripts/leaflet/layers_scheduler.js.coffee +57 -0
- data/app/assets/javascripts/leaflet/reactive_measure.js.coffee +414 -0
- data/app/assets/stylesheets/all.scss +16 -0
- data/app/assets/stylesheets/application.css +15 -0
- data/app/assets/stylesheets/compass/reset.scss +3 -0
- data/app/assets/stylesheets/compass/reset/utilities.scss +142 -0
- data/app/assets/stylesheets/leaflet.scss +1093 -0
- data/app/assets/stylesheets/leaflet/label.scss +40 -0
- data/app/assets/stylesheets/leaflet/tooltip.scss +42 -0
- data/app/assets/stylesheets/mixins.scss +131 -0
- data/app/assets/stylesheets/reset.scss +89 -0
- data/app/assets/stylesheets/variables.scss +47 -0
- data/app/helpers/foliage_helper.rb +23 -0
- data/lib/foliage.rb +9 -0
- data/lib/foliage/leaf.rb +235 -0
- data/lib/foliage/rails.rb +2 -0
- data/lib/foliage/rails/engine.rb +7 -0
- data/lib/foliage/rails/integration.rb +8 -0
- data/lib/foliage/version.rb +3 -0
- data/vendor/assets/javascripts/.keep +0 -0
- data/vendor/assets/javascripts/autosize.js +211 -0
- data/vendor/assets/javascripts/geographiclib.js +3074 -0
- data/vendor/assets/javascripts/leaflet.js.erb +9175 -0
- data/vendor/assets/javascripts/leaflet/draw.js +3573 -0
- data/vendor/assets/javascripts/leaflet/easy-button.js +366 -0
- data/vendor/assets/javascripts/leaflet/fullscreen.js +162 -0
- data/vendor/assets/javascripts/leaflet/heatmap.js +142 -0
- data/vendor/assets/javascripts/leaflet/label.js +545 -0
- data/vendor/assets/javascripts/leaflet/measure.js +6966 -0
- data/vendor/assets/javascripts/leaflet/modal.js +364 -0
- data/vendor/assets/javascripts/leaflet/providers.js +479 -0
- data/vendor/assets/javascripts/rbush.js +621 -0
- data/vendor/assets/stylesheets/.keep +0 -0
- data/vendor/assets/stylesheets/bootstrap/mixins.scss +55 -0
- data/vendor/assets/stylesheets/bootstrap/variables.scss +10 -0
- data/vendor/assets/stylesheets/leaflet.scss +479 -0
- data/vendor/assets/stylesheets/leaflet/draw.scss +282 -0
- data/vendor/assets/stylesheets/leaflet/easy-button.scss +56 -0
- data/vendor/assets/stylesheets/leaflet/fullscreen.scss +2 -0
- data/vendor/assets/stylesheets/leaflet/measure.scss +168 -0
- data/vendor/assets/stylesheets/leaflet/modal.scss +85 -0
- metadata +171 -0
@@ -0,0 +1,364 @@
|
|
1
|
+
/**
|
2
|
+
* Leaflet modal control
|
3
|
+
*
|
4
|
+
* @license MIT
|
5
|
+
* @author Alexander Milevski <info@w8r.name>
|
6
|
+
* @preserve
|
7
|
+
*/
|
8
|
+
|
9
|
+
"use strict";
|
10
|
+
|
11
|
+
/**
|
12
|
+
* "foo bar baz" -> ".foo.bar.baz"
|
13
|
+
* @param {String} classString
|
14
|
+
* @return {String}
|
15
|
+
*/
|
16
|
+
L.DomUtil.classNameToSelector = function(classString) {
|
17
|
+
return (' ' + classString).split(' ').join('.').replace(/^\s+|\s+$/g, '');
|
18
|
+
};
|
19
|
+
|
20
|
+
/**
|
21
|
+
* Modal handler
|
22
|
+
* @class {L.Map.Modal}
|
23
|
+
* @extends {L.Mixin.Events}
|
24
|
+
* @extends {L.Handler}
|
25
|
+
*/
|
26
|
+
L.Map.Modal = L.Handler.extend( /** @lends {L.Map.Hadler.prototype} */ {
|
27
|
+
|
28
|
+
includes: L.Mixin.Events,
|
29
|
+
|
30
|
+
/**
|
31
|
+
* @static
|
32
|
+
* @type {Object}
|
33
|
+
*/
|
34
|
+
statics: {
|
35
|
+
BASE_CLS: 'leaflet-modal',
|
36
|
+
HIDE: 'modal.hide',
|
37
|
+
SHOW_START: 'modal.showStart',
|
38
|
+
SHOW: 'modal.show',
|
39
|
+
CHANGED: 'modal.changed'
|
40
|
+
},
|
41
|
+
|
42
|
+
/**
|
43
|
+
* @type {Object}
|
44
|
+
*/
|
45
|
+
options: {
|
46
|
+
OVERLAY_CLS: 'overlay',
|
47
|
+
MODAL_CLS: 'modal',
|
48
|
+
MODAL_CONTENT_CLS: 'modal-content',
|
49
|
+
INNER_CONTENT_CLS: 'modal-inner',
|
50
|
+
SHOW_CLS: 'show',
|
51
|
+
CLOSE_CLS: 'close',
|
52
|
+
|
53
|
+
closeTitle: 'close',
|
54
|
+
zIndex: 10000,
|
55
|
+
transitionDuration: 300,
|
56
|
+
|
57
|
+
wrapperTemplate: [
|
58
|
+
'<div class="{OVERLAY_CLS}"></div>',
|
59
|
+
'<div class="{MODAL_CLS}"><div class="{MODAL_CONTENT_CLS}">',
|
60
|
+
'<span class="{CLOSE_CLS}" title="{closeTitle}">×</span>',
|
61
|
+
'<div class="{INNER_CONTENT_CLS}">{_content}</div>',
|
62
|
+
'</div></div>'
|
63
|
+
].join(''),
|
64
|
+
|
65
|
+
template: '{content}',
|
66
|
+
content: ''
|
67
|
+
|
68
|
+
},
|
69
|
+
|
70
|
+
/**
|
71
|
+
* @constructor
|
72
|
+
* @param {L.Map} map
|
73
|
+
* @param {Object=} options
|
74
|
+
*/
|
75
|
+
initialize: function(map, options) {
|
76
|
+
L.Handler.prototype.initialize.call(this, map);
|
77
|
+
L.Util.setOptions(this, options);
|
78
|
+
|
79
|
+
this._visible = false;
|
80
|
+
|
81
|
+
var container = this._container =
|
82
|
+
L.DomUtil.create('div', L.Map.Modal.BASE_CLS, map._container);
|
83
|
+
container.style.zIndex = this.options.zIndex;
|
84
|
+
container.style.position = 'absolute';
|
85
|
+
this._map._controlContainer.appendChild(container);
|
86
|
+
|
87
|
+
L.DomEvent
|
88
|
+
.disableClickPropagation(container)
|
89
|
+
.disableScrollPropagation(container);
|
90
|
+
L.DomEvent.on(container, 'contextmenu', L.DomEvent.stopPropagation);
|
91
|
+
|
92
|
+
this.enable();
|
93
|
+
},
|
94
|
+
|
95
|
+
/**
|
96
|
+
* Add events and keyboard handlers
|
97
|
+
*/
|
98
|
+
addHooks: function() {
|
99
|
+
L.DomEvent.on(document, 'keydown', this._onKeyDown, this);
|
100
|
+
this._map.on({
|
101
|
+
modal: this._show
|
102
|
+
}, this);
|
103
|
+
},
|
104
|
+
|
105
|
+
/**
|
106
|
+
* Disable handlers
|
107
|
+
*/
|
108
|
+
removeHooks: function() {
|
109
|
+
L.DomEvent.off(document, 'keydown', this._onKeyDown, this);
|
110
|
+
this._map.off({
|
111
|
+
modal: this._show
|
112
|
+
}, this);
|
113
|
+
},
|
114
|
+
|
115
|
+
/**
|
116
|
+
* @return {L.Map.Modal}
|
117
|
+
*/
|
118
|
+
hide: function() {
|
119
|
+
this._hide();
|
120
|
+
return this;
|
121
|
+
},
|
122
|
+
|
123
|
+
/**
|
124
|
+
* @return {Boolean}
|
125
|
+
*/
|
126
|
+
isVisible: function() {
|
127
|
+
return this._visible;
|
128
|
+
},
|
129
|
+
|
130
|
+
/**
|
131
|
+
* Show again, or just resize and re-position
|
132
|
+
* @param {Object=} options
|
133
|
+
*/
|
134
|
+
update: function(options) {
|
135
|
+
if (options) {
|
136
|
+
this._show(options);
|
137
|
+
} else {
|
138
|
+
this._updatePosition();
|
139
|
+
}
|
140
|
+
},
|
141
|
+
|
142
|
+
/**
|
143
|
+
* @param {String} content
|
144
|
+
*/
|
145
|
+
setContent: function(content) {
|
146
|
+
this._getInnerContentContainer().innerHTML = content;
|
147
|
+
this.update();
|
148
|
+
},
|
149
|
+
|
150
|
+
/**
|
151
|
+
* Update container position
|
152
|
+
*/
|
153
|
+
_updatePosition: function() {
|
154
|
+
var content = this._getContentContainer();
|
155
|
+
var mapSize = this._map.getSize();
|
156
|
+
|
157
|
+
if (content.offsetHeight < mapSize.y) {
|
158
|
+
content.style.marginTop = ((mapSize.y - content.offsetHeight) / 2) + 'px';
|
159
|
+
} else {
|
160
|
+
content.style.marginTop = '';
|
161
|
+
}
|
162
|
+
},
|
163
|
+
|
164
|
+
/**
|
165
|
+
* @param {Object} options
|
166
|
+
*/
|
167
|
+
_show: function(options) {
|
168
|
+
if (this._visible) {
|
169
|
+
this._hide();
|
170
|
+
}
|
171
|
+
options = L.Util.extend({}, this.options, options);
|
172
|
+
|
173
|
+
this._render(options);
|
174
|
+
this._setContainerSize(options);
|
175
|
+
|
176
|
+
this._updatePosition();
|
177
|
+
|
178
|
+
L.Util.requestAnimFrame(function() {
|
179
|
+
var contentContainer = this._getContentContainer();
|
180
|
+
L.DomEvent.on(contentContainer, 'transitionend', this._onTransitionEnd, this);
|
181
|
+
L.DomEvent.disableClickPropagation(contentContainer);
|
182
|
+
L.DomUtil.addClass(this._container, this.options.SHOW_CLS);
|
183
|
+
|
184
|
+
if (!L.Browser.any3d) {
|
185
|
+
L.Util.requestAnimFrame(this._onTransitionEnd, this);
|
186
|
+
}
|
187
|
+
}, this);
|
188
|
+
|
189
|
+
var closeBtn = this._container.querySelector('.' + this.options.CLOSE_CLS);
|
190
|
+
if (closeBtn) {
|
191
|
+
L.DomEvent.on(closeBtn, 'click', this._onCloseClick, this);
|
192
|
+
}
|
193
|
+
|
194
|
+
var modal = this._container.querySelector('.' + this.options.MODAL_CLS);
|
195
|
+
if (modal) {
|
196
|
+
L.DomEvent.on(modal, 'mousedown', this._onMouseDown, this);
|
197
|
+
}
|
198
|
+
|
199
|
+
// callbacks
|
200
|
+
if (typeof options.onShow === 'function') {
|
201
|
+
this._map.once(L.Map.Modal.SHOW, options.onShow);
|
202
|
+
}
|
203
|
+
|
204
|
+
if (typeof options.onHide === 'function') {
|
205
|
+
this._map.once(L.Map.Modal.HIDE, options.onHide);
|
206
|
+
}
|
207
|
+
|
208
|
+
// fire event
|
209
|
+
this._map.fire(L.Map.Modal.SHOW_START, {
|
210
|
+
modal: this
|
211
|
+
});
|
212
|
+
},
|
213
|
+
|
214
|
+
/**
|
215
|
+
* Show transition ended
|
216
|
+
* @param {TransitionEvent=} e
|
217
|
+
*/
|
218
|
+
_onTransitionEnd: function(e) {
|
219
|
+
var data = {
|
220
|
+
modal: this
|
221
|
+
};
|
222
|
+
var map = this._map;
|
223
|
+
if (!this._visible) {
|
224
|
+
if (L.DomUtil.hasClass(this._container, this.options.SHOW_CLS)) {
|
225
|
+
this._visible = true;
|
226
|
+
map.fire(L.Map.Modal.SHOW, data);
|
227
|
+
} else {
|
228
|
+
map.fire(L.Map.Modal.HIDE, data);
|
229
|
+
}
|
230
|
+
} else {
|
231
|
+
map.fire(L.Map.Modal.CHANGED, data);
|
232
|
+
}
|
233
|
+
},
|
234
|
+
|
235
|
+
/**
|
236
|
+
* @param {L.MouseEvent} evt
|
237
|
+
*/
|
238
|
+
_onCloseClick: function(evt) {
|
239
|
+
L.DomEvent.stop(evt);
|
240
|
+
this._hide();
|
241
|
+
},
|
242
|
+
|
243
|
+
/**
|
244
|
+
* Render template
|
245
|
+
* @param {Object} options
|
246
|
+
*/
|
247
|
+
_render: function(options) {
|
248
|
+
this._container.innerHTML = L.Util.template(
|
249
|
+
options.wrapperTemplate,
|
250
|
+
L.Util.extend({}, options, {
|
251
|
+
_content: L.Util.template(options.template, options)
|
252
|
+
})
|
253
|
+
);
|
254
|
+
if (options.element) {
|
255
|
+
var contentContainer = this._container.querySelector(
|
256
|
+
L.DomUtil.classNameToSelector(this.options.MODAL_CONTENT_CLS));
|
257
|
+
if (contentContainer) {
|
258
|
+
contentContainer.appendChild(options.element);
|
259
|
+
}
|
260
|
+
}
|
261
|
+
},
|
262
|
+
|
263
|
+
/**
|
264
|
+
* @return {Element}
|
265
|
+
*/
|
266
|
+
_getContentContainer: function() {
|
267
|
+
return this._container.querySelector(
|
268
|
+
L.DomUtil.classNameToSelector(this.options.MODAL_CONTENT_CLS));
|
269
|
+
},
|
270
|
+
|
271
|
+
/**
|
272
|
+
* Inner content, don't touch destroy button
|
273
|
+
* @return {Element}
|
274
|
+
*/
|
275
|
+
_getInnerContentContainer: function() {
|
276
|
+
return this._container.querySelector(
|
277
|
+
L.DomUtil.classNameToSelector(this.options.INNER_CONTENT_CLS))
|
278
|
+
},
|
279
|
+
|
280
|
+
/**
|
281
|
+
* @param {Object} options
|
282
|
+
* @param {Number} options.width
|
283
|
+
* @param {Number} options.height
|
284
|
+
*/
|
285
|
+
_setContainerSize: function(options) {
|
286
|
+
var content = this._getContentContainer();
|
287
|
+
|
288
|
+
if (options.width) {
|
289
|
+
content.style.width = options.width + 'px';
|
290
|
+
}
|
291
|
+
|
292
|
+
if (options.height) {
|
293
|
+
content.style.height = options.height + 'px';
|
294
|
+
}
|
295
|
+
},
|
296
|
+
|
297
|
+
/**
|
298
|
+
* Hide blocks immediately
|
299
|
+
*/
|
300
|
+
_hideInternal: function() {
|
301
|
+
this._visible = false;
|
302
|
+
L.DomUtil.removeClass(this._container, this.options.SHOW_CLS);
|
303
|
+
},
|
304
|
+
|
305
|
+
/**
|
306
|
+
* Hide modal
|
307
|
+
*/
|
308
|
+
_hide: function() {
|
309
|
+
if (this._visible) {
|
310
|
+
this._hideInternal();
|
311
|
+
|
312
|
+
if (!L.Browser.any3d) {
|
313
|
+
L.Util.requestAnimFrame(this._onTransitionEnd, this);
|
314
|
+
}
|
315
|
+
}
|
316
|
+
},
|
317
|
+
|
318
|
+
/**
|
319
|
+
* Mouse down on overlay
|
320
|
+
* @param {L.MouseEvent} evt
|
321
|
+
*/
|
322
|
+
_onMouseDown: function(evt) {
|
323
|
+
L.DomEvent.stop(evt);
|
324
|
+
var target = (evt.target || evt.srcElement);
|
325
|
+
if (L.DomUtil.hasClass(target, this.options.MODAL_CLS)) {
|
326
|
+
this._hide();
|
327
|
+
}
|
328
|
+
},
|
329
|
+
|
330
|
+
/**
|
331
|
+
* Key stroke(escape)
|
332
|
+
* @param {KeyboardEvent} evt
|
333
|
+
*/
|
334
|
+
_onKeyDown: function(evt) {
|
335
|
+
var key = evt.keyCode || evt.which;
|
336
|
+
if (key === 27) {
|
337
|
+
this._hide();
|
338
|
+
}
|
339
|
+
}
|
340
|
+
|
341
|
+
});
|
342
|
+
|
343
|
+
// register hook
|
344
|
+
L.Map.addInitHook('addHandler', 'modal', L.Map.Modal);
|
345
|
+
|
346
|
+
L.Map.include( /** @lends {L.Map.prototype} */ {
|
347
|
+
|
348
|
+
/**
|
349
|
+
* @param {Object} options
|
350
|
+
* @return {L.Map}
|
351
|
+
*/
|
352
|
+
openModal: function(options) {
|
353
|
+
return this.fire('modal', options);
|
354
|
+
},
|
355
|
+
|
356
|
+
/**
|
357
|
+
* @return {L.Map}
|
358
|
+
*/
|
359
|
+
closeModal: function() {
|
360
|
+
this.modal.hide();
|
361
|
+
return this;
|
362
|
+
}
|
363
|
+
|
364
|
+
});
|
@@ -0,0 +1,479 @@
|
|
1
|
+
(function () {
|
2
|
+
'use strict';
|
3
|
+
|
4
|
+
L.TileLayer.Provider = L.TileLayer.extend({
|
5
|
+
initialize: function (arg, options) {
|
6
|
+
var providers = L.TileLayer.Provider.providers;
|
7
|
+
|
8
|
+
var parts = arg.split('.');
|
9
|
+
|
10
|
+
var providerName = parts[0];
|
11
|
+
var variantName = parts[1];
|
12
|
+
|
13
|
+
if (!providers[providerName]) {
|
14
|
+
throw 'No such provider (' + providerName + ')';
|
15
|
+
}
|
16
|
+
|
17
|
+
var provider = {
|
18
|
+
url: providers[providerName].url,
|
19
|
+
options: providers[providerName].options
|
20
|
+
};
|
21
|
+
|
22
|
+
// overwrite values in provider from variant.
|
23
|
+
if (variantName && 'variants' in providers[providerName]) {
|
24
|
+
if (!(variantName in providers[providerName].variants)) {
|
25
|
+
throw 'No such name in provider (' + variantName + ')';
|
26
|
+
}
|
27
|
+
var variant = providers[providerName].variants[variantName];
|
28
|
+
provider = {
|
29
|
+
url: variant.url || provider.url,
|
30
|
+
options: L.Util.extend({}, provider.options, variant.options)
|
31
|
+
};
|
32
|
+
} else if (typeof provider.url === 'function') {
|
33
|
+
provider.url = provider.url(parts.splice(1).join('.'));
|
34
|
+
}
|
35
|
+
|
36
|
+
// replace attribution placeholders with their values from toplevel provider attribution,
|
37
|
+
// recursively
|
38
|
+
var attributionReplacer = function (attr) {
|
39
|
+
if (attr.indexOf('{attribution.') === -1) {
|
40
|
+
return attr;
|
41
|
+
}
|
42
|
+
return attr.replace(/\{attribution.(\w*)\}/,
|
43
|
+
function (match, attributionName) {
|
44
|
+
return attributionReplacer(providers[attributionName].options.attribution);
|
45
|
+
}
|
46
|
+
);
|
47
|
+
};
|
48
|
+
provider.options.attribution = attributionReplacer(provider.options.attribution);
|
49
|
+
|
50
|
+
// Compute final options combining provider options with any user overrides
|
51
|
+
var layerOpts = L.Util.extend({}, provider.options, options);
|
52
|
+
L.TileLayer.prototype.initialize.call(this, provider.url, layerOpts);
|
53
|
+
}
|
54
|
+
});
|
55
|
+
|
56
|
+
/**
|
57
|
+
* Definition of providers.
|
58
|
+
* see http://leafletjs.com/reference.html#tilelayer for options in the options map.
|
59
|
+
*/
|
60
|
+
|
61
|
+
//jshint maxlen:220
|
62
|
+
L.TileLayer.Provider.providers = {
|
63
|
+
OpenStreetMap: {
|
64
|
+
url: 'http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png',
|
65
|
+
options: {
|
66
|
+
attribution:
|
67
|
+
'© <a href="http://openstreetmap.org">OpenStreetMap</a> contributors, ' +
|
68
|
+
'<a href="http://creativecommons.org/licenses/by-sa/2.0/">CC-BY-SA</a>'
|
69
|
+
},
|
70
|
+
variants: {
|
71
|
+
Mapnik: {},
|
72
|
+
BlackAndWhite: {
|
73
|
+
url: 'http://{s}.www.toolserver.org/tiles/bw-mapnik/{z}/{x}/{y}.png'
|
74
|
+
},
|
75
|
+
DE: {
|
76
|
+
url: 'http://{s}.tile.openstreetmap.de/tiles/osmde/{z}/{x}/{y}.png'
|
77
|
+
},
|
78
|
+
HOT: {
|
79
|
+
url: 'http://{s}.tile.openstreetmap.fr/hot/{z}/{x}/{y}.png',
|
80
|
+
options: {
|
81
|
+
attribution: '{attribution.OpenStreetMap}, Tiles courtesy of <a href="http://hot.openstreetmap.org/" target="_blank">Humanitarian OpenStreetMap Team</a>'
|
82
|
+
}
|
83
|
+
}
|
84
|
+
}
|
85
|
+
},
|
86
|
+
OpenCycleMap: {
|
87
|
+
url: 'http://{s}.tile.opencyclemap.org/cycle/{z}/{x}/{y}.png',
|
88
|
+
options: {
|
89
|
+
attribution:
|
90
|
+
'© <a href="http://www.opencyclemap.org">OpenCycleMap</a>, {attribution.OpenStreetMap}'
|
91
|
+
}
|
92
|
+
},
|
93
|
+
OpenSeaMap: {
|
94
|
+
url: 'http://tiles.openseamap.org/seamark/{z}/{x}/{y}.png',
|
95
|
+
options: {
|
96
|
+
attribution: 'Map data: © <a href="http://www.openseamap.org">OpenSeaMap</a> contributors'
|
97
|
+
}
|
98
|
+
},
|
99
|
+
Thunderforest: {
|
100
|
+
url: 'http://{s}.tile.opencyclemap.org/cycle/{z}/{x}/{y}.png',
|
101
|
+
options: {
|
102
|
+
attribution: '{attribution.OpenCycleMap}'
|
103
|
+
},
|
104
|
+
variants: {
|
105
|
+
OpenCycleMap: {},
|
106
|
+
Transport: {
|
107
|
+
url: 'http://{s}.tile2.opencyclemap.org/transport/{z}/{x}/{y}.png'
|
108
|
+
},
|
109
|
+
Landscape: {
|
110
|
+
url: 'http://{s}.tile3.opencyclemap.org/landscape/{z}/{x}/{y}.png'
|
111
|
+
},
|
112
|
+
Outdoors: {
|
113
|
+
url: 'http://{s}.tile.thunderforest.com/outdoors/{z}/{x}/{y}.png'
|
114
|
+
}
|
115
|
+
}
|
116
|
+
},
|
117
|
+
OpenMapSurfer: {
|
118
|
+
url: 'http://openmapsurfer.uni-hd.de/tiles/roads/x={x}&y={y}&z={z}',
|
119
|
+
options: {
|
120
|
+
attribution: 'Imagery from <a href="http://giscience.uni-hd.de/">GIScience Research Group @ University of Heidelberg</a> — Map data {attribution.OpenStreetMap}'
|
121
|
+
},
|
122
|
+
variants: {
|
123
|
+
Roads: {},
|
124
|
+
AdminBounds: {
|
125
|
+
url: 'http://openmapsurfer.uni-hd.de/tiles/adminb/x={x}&y={y}&z={z}'
|
126
|
+
},
|
127
|
+
Grayscale: {
|
128
|
+
url: 'http://openmapsurfer.uni-hd.de/tiles/roadsg/x={x}&y={y}&z={z}'
|
129
|
+
}
|
130
|
+
}
|
131
|
+
},
|
132
|
+
MapQuestOpen: {
|
133
|
+
url: 'http://otile{s}.mqcdn.com/tiles/1.0.0/map/{z}/{x}/{y}.jpeg',
|
134
|
+
options: {
|
135
|
+
attribution:
|
136
|
+
'Tiles Courtesy of <a href="http://www.mapquest.com/">MapQuest</a> — ' +
|
137
|
+
'Map data {attribution.OpenStreetMap}',
|
138
|
+
subdomains: '1234'
|
139
|
+
},
|
140
|
+
variants: {
|
141
|
+
OSM: {},
|
142
|
+
Aerial: {
|
143
|
+
url: 'http://oatile{s}.mqcdn.com/tiles/1.0.0/sat/{z}/{x}/{y}.jpg',
|
144
|
+
options: {
|
145
|
+
attribution:
|
146
|
+
'Tiles Courtesy of <a href="http://www.mapquest.com/">MapQuest</a> — ' +
|
147
|
+
'Portions Courtesy NASA/JPL-Caltech and U.S. Depart. of Agriculture, Farm Service Agency'
|
148
|
+
}
|
149
|
+
}
|
150
|
+
}
|
151
|
+
},
|
152
|
+
MapBox: {
|
153
|
+
url: function (id) {
|
154
|
+
return 'http://{s}.tiles.mapbox.com/v3/' + id + '/{z}/{x}/{y}.png';
|
155
|
+
},
|
156
|
+
options: {
|
157
|
+
attribution:
|
158
|
+
'Imagery from <a href="http://mapbox.com/about/maps/">MapBox</a> — ' +
|
159
|
+
'Map data {attribution.OpenStreetMap}',
|
160
|
+
subdomains: 'abcd'
|
161
|
+
}
|
162
|
+
},
|
163
|
+
Stamen: {
|
164
|
+
url: 'http://{s}.tile.stamen.com/toner/{z}/{x}/{y}.png',
|
165
|
+
options: {
|
166
|
+
attribution:
|
167
|
+
'Map tiles by <a href="http://stamen.com">Stamen Design</a>, ' +
|
168
|
+
'<a href="http://creativecommons.org/licenses/by/3.0">CC BY 3.0</a> — ' +
|
169
|
+
'Map data {attribution.OpenStreetMap}',
|
170
|
+
subdomains: 'abcd',
|
171
|
+
minZoom: 0,
|
172
|
+
maxZoom: 20
|
173
|
+
},
|
174
|
+
variants: {
|
175
|
+
Toner: {},
|
176
|
+
TonerBackground: {
|
177
|
+
url: 'http://{s}.tile.stamen.com/toner-background/{z}/{x}/{y}.png'
|
178
|
+
},
|
179
|
+
TonerHybrid: {
|
180
|
+
url: 'http://{s}.tile.stamen.com/toner-hybrid/{z}/{x}/{y}.png'
|
181
|
+
},
|
182
|
+
TonerLines: {
|
183
|
+
url: 'http://{s}.tile.stamen.com/toner-lines/{z}/{x}/{y}.png'
|
184
|
+
},
|
185
|
+
TonerLabels: {
|
186
|
+
url: 'http://{s}.tile.stamen.com/toner-labels/{z}/{x}/{y}.png'
|
187
|
+
},
|
188
|
+
TonerLite: {
|
189
|
+
url: 'http://{s}.tile.stamen.com/toner-lite/{z}/{x}/{y}.png'
|
190
|
+
},
|
191
|
+
Terrain: {
|
192
|
+
url: 'http://{s}.tile.stamen.com/terrain/{z}/{x}/{y}.jpg',
|
193
|
+
options: {
|
194
|
+
minZoom: 4,
|
195
|
+
maxZoom: 18
|
196
|
+
}
|
197
|
+
},
|
198
|
+
TerrainBackground: {
|
199
|
+
url: 'http://{s}.tile.stamen.com/terrain-background/{z}/{x}/{y}.jpg',
|
200
|
+
options: {
|
201
|
+
minZoom: 4,
|
202
|
+
maxZoom: 18
|
203
|
+
}
|
204
|
+
},
|
205
|
+
Watercolor: {
|
206
|
+
url: 'http://{s}.tile.stamen.com/watercolor/{z}/{x}/{y}.jpg',
|
207
|
+
options: {
|
208
|
+
minZoom: 3,
|
209
|
+
maxZoom: 16
|
210
|
+
}
|
211
|
+
}
|
212
|
+
}
|
213
|
+
},
|
214
|
+
Esri: {
|
215
|
+
url: 'http://server.arcgisonline.com/ArcGIS/rest/services/World_Street_Map/MapServer/tile/{z}/{y}/{x}',
|
216
|
+
options: {
|
217
|
+
attribution: 'Tiles © Esri'
|
218
|
+
},
|
219
|
+
variants: {
|
220
|
+
WorldStreetMap: {
|
221
|
+
options: {
|
222
|
+
attribution:
|
223
|
+
'{attribution.Esri} — ' +
|
224
|
+
'Source: Esri, DeLorme, NAVTEQ, USGS, Intermap, iPC, NRCAN, Esri Japan, METI, Esri China (Hong Kong), Esri (Thailand), TomTom, 2012'
|
225
|
+
}
|
226
|
+
},
|
227
|
+
DeLorme: {
|
228
|
+
url: 'http://server.arcgisonline.com/ArcGIS/rest/services/Specialty/DeLorme_World_Base_Map/MapServer/tile/{z}/{y}/{x}',
|
229
|
+
options: {
|
230
|
+
minZoom: 1,
|
231
|
+
maxZoom: 11,
|
232
|
+
attribution: '{attribution.Esri} — Copyright: ©2012 DeLorme'
|
233
|
+
}
|
234
|
+
},
|
235
|
+
WorldTopoMap: {
|
236
|
+
url: 'http://server.arcgisonline.com/ArcGIS/rest/services/World_Topo_Map/MapServer/tile/{z}/{y}/{x}',
|
237
|
+
options: {
|
238
|
+
attribution:
|
239
|
+
'{attribution.Esri} — ' +
|
240
|
+
'Esri, DeLorme, NAVTEQ, TomTom, Intermap, iPC, USGS, FAO, NPS, NRCAN, GeoBase, Kadaster NL, Ordnance Survey, Esri Japan, METI, Esri China (Hong Kong), and the GIS User Community'
|
241
|
+
}
|
242
|
+
},
|
243
|
+
WorldImagery: {
|
244
|
+
url: 'http://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}',
|
245
|
+
options: {
|
246
|
+
attribution:
|
247
|
+
'{attribution.Esri} — ' +
|
248
|
+
'Source: Esri, i-cubed, USDA, USGS, AEX, GeoEye, Getmapping, Aerogrid, IGN, IGP, UPR-EGP, and the GIS User Community'
|
249
|
+
}
|
250
|
+
},
|
251
|
+
WorldTerrain: {
|
252
|
+
url: 'http://server.arcgisonline.com/ArcGIS/rest/services/World_Terrain_Base/MapServer/tile/{z}/{y}/{x}',
|
253
|
+
options: {
|
254
|
+
maxZoom: 13,
|
255
|
+
attribution:
|
256
|
+
'{attribution.Esri} — ' +
|
257
|
+
'Source: USGS, Esri, TANA, DeLorme, and NPS'
|
258
|
+
}
|
259
|
+
},
|
260
|
+
WorldShadedRelief: {
|
261
|
+
url: 'http://server.arcgisonline.com/ArcGIS/rest/services/World_Shaded_Relief/MapServer/tile/{z}/{y}/{x}',
|
262
|
+
options: {
|
263
|
+
maxZoom: 13,
|
264
|
+
attribution: '{attribution.Esri} — Source: Esri'
|
265
|
+
}
|
266
|
+
},
|
267
|
+
WorldPhysical: {
|
268
|
+
url: 'http://server.arcgisonline.com/ArcGIS/rest/services/World_Physical_Map/MapServer/tile/{z}/{y}/{x}',
|
269
|
+
options: {
|
270
|
+
maxZoom: 8,
|
271
|
+
attribution: '{attribution.Esri} — Source: US National Park Service'
|
272
|
+
}
|
273
|
+
},
|
274
|
+
OceanBasemap: {
|
275
|
+
url: 'http://services.arcgisonline.com/ArcGIS/rest/services/Ocean_Basemap/MapServer/tile/{z}/{y}/{x}',
|
276
|
+
options: {
|
277
|
+
maxZoom: 13,
|
278
|
+
attribution: '{attribution.Esri} — Sources: GEBCO, NOAA, CHS, OSU, UNH, CSUMB, National Geographic, DeLorme, NAVTEQ, and Esri'
|
279
|
+
}
|
280
|
+
},
|
281
|
+
NatGeoWorldMap: {
|
282
|
+
url: 'http://services.arcgisonline.com/ArcGIS/rest/services/NatGeo_World_Map/MapServer/tile/{z}/{y}/{x}',
|
283
|
+
options: {
|
284
|
+
maxZoom: 16,
|
285
|
+
attribution: '{attribution.Esri} — National Geographic, Esri, DeLorme, NAVTEQ, UNEP-WCMC, USGS, NASA, ESA, METI, NRCAN, GEBCO, NOAA, iPC'
|
286
|
+
}
|
287
|
+
},
|
288
|
+
WorldGrayCanvas: {
|
289
|
+
url: 'http://server.arcgisonline.com/ArcGIS/rest/services/Canvas/World_Light_Gray_Base/MapServer/tile/{z}/{y}/{x}',
|
290
|
+
options: {
|
291
|
+
maxZoom: 16,
|
292
|
+
attribution: '{attribution.Esri} — Esri, DeLorme, NAVTEQ'
|
293
|
+
}
|
294
|
+
}
|
295
|
+
}
|
296
|
+
},
|
297
|
+
OpenWeatherMap: {
|
298
|
+
options: {
|
299
|
+
attribution: 'Map data © <a href="http://openweathermap.org">OpenWeatherMap</a>',
|
300
|
+
opacity: 0.5
|
301
|
+
},
|
302
|
+
variants: {
|
303
|
+
Clouds: {
|
304
|
+
url: 'http://{s}.tile.openweathermap.org/map/clouds/{z}/{x}/{y}.png'
|
305
|
+
},
|
306
|
+
CloudsClassic: {
|
307
|
+
url: 'http://{s}.tile.openweathermap.org/map/clouds_cls/{z}/{x}/{y}.png'
|
308
|
+
},
|
309
|
+
Precipitation: {
|
310
|
+
url: 'http://{s}.tile.openweathermap.org/map/precipitation/{z}/{x}/{y}.png'
|
311
|
+
},
|
312
|
+
PrecipitationClassic: {
|
313
|
+
url: 'http://{s}.tile.openweathermap.org/map/precipitation_cls/{z}/{x}/{y}.png'
|
314
|
+
},
|
315
|
+
Rain: {
|
316
|
+
url: 'http://{s}.tile.openweathermap.org/map/rain/{z}/{x}/{y}.png'
|
317
|
+
},
|
318
|
+
RainClassic: {
|
319
|
+
url: 'http://{s}.tile.openweathermap.org/map/rain_cls/{z}/{x}/{y}.png'
|
320
|
+
},
|
321
|
+
Pressure: {
|
322
|
+
url: 'http://{s}.tile.openweathermap.org/map/pressure/{z}/{x}/{y}.png'
|
323
|
+
},
|
324
|
+
PressureContour: {
|
325
|
+
url: 'http://{s}.tile.openweathermap.org/map/pressure_cntr/{z}/{x}/{y}.png'
|
326
|
+
},
|
327
|
+
Wind: {
|
328
|
+
url: 'http://{s}.tile.openweathermap.org/map/wind/{z}/{x}/{y}.png'
|
329
|
+
},
|
330
|
+
Temperature: {
|
331
|
+
url: 'http://{s}.tile.openweathermap.org/map/temp/{z}/{x}/{y}.png'
|
332
|
+
},
|
333
|
+
Snow: {
|
334
|
+
url: 'http://{s}.tile.openweathermap.org/map/snow/{z}/{x}/{y}.png'
|
335
|
+
}
|
336
|
+
}
|
337
|
+
},
|
338
|
+
Nokia: {
|
339
|
+
options: {
|
340
|
+
attribution:
|
341
|
+
'Map © <a href="http://developer.here.com">Nokia</a>, Data © NAVTEQ 2012',
|
342
|
+
subdomains: '1234',
|
343
|
+
devID: 'xyz', //These basemaps are free and you can sign up here: http://developer.here.com/plans
|
344
|
+
appID: 'abc'
|
345
|
+
},
|
346
|
+
variants: {
|
347
|
+
normalDay: {
|
348
|
+
url: 'http://{s}.maptile.lbs.ovi.com/maptiler/v2/maptile/newest/normal.day/{z}/{x}/{y}/256/png8?token={devID}&app_id={appID}'
|
349
|
+
},
|
350
|
+
normalGreyDay: {
|
351
|
+
url: 'http://{s}.maptile.lbs.ovi.com/maptiler/v2/maptile/newest/normal.day.grey/{z}/{x}/{y}/256/png8?token={devID}&app_id={appID}'
|
352
|
+
},
|
353
|
+
satelliteNoLabelsDay: {
|
354
|
+
url: 'http://{s}.maptile.lbs.ovi.com/maptiler/v2/maptile/newest/satellite.day/{z}/{x}/{y}/256/png8?token={devID}&app_id={appID}'
|
355
|
+
},
|
356
|
+
satelliteYesLabelsDay: {
|
357
|
+
url: 'http://{s}.maptile.lbs.ovi.com/maptiler/v2/maptile/newest/hybrid.day/{z}/{x}/{y}/256/png8?token={devID}&app_id={appID}'
|
358
|
+
},
|
359
|
+
terrainDay: {
|
360
|
+
url: 'http://{s}.maptile.lbs.ovi.com/maptiler/v2/maptile/newest/terrain.day/{z}/{x}/{y}/256/png8?token={devID}&app_id={appID}'
|
361
|
+
}
|
362
|
+
}
|
363
|
+
},
|
364
|
+
Acetate: {
|
365
|
+
url: 'http://a{s}.acetate.geoiq.com/tiles/acetate-hillshading/{z}/{x}/{y}.png',
|
366
|
+
options: {
|
367
|
+
attribution:
|
368
|
+
'©2012 Esri & Stamen, Data from OSM and Natural Earth',
|
369
|
+
subdomains: '0123',
|
370
|
+
minZoom: 2,
|
371
|
+
maxZoom: 18
|
372
|
+
},
|
373
|
+
variants: {
|
374
|
+
all: {},
|
375
|
+
basemap: {
|
376
|
+
url: 'http://a{s}.acetate.geoiq.com/tiles/acetate-base/{z}/{x}/{y}.png'
|
377
|
+
},
|
378
|
+
terrain: {
|
379
|
+
url: 'http://a{s}.acetate.geoiq.com/tiles/terrain/{z}/{x}/{y}.png'
|
380
|
+
},
|
381
|
+
foreground: {
|
382
|
+
url: 'http://a{s}.acetate.geoiq.com/tiles/acetate-fg/{z}/{x}/{y}.png'
|
383
|
+
},
|
384
|
+
roads: {
|
385
|
+
url: 'http://a{s}.acetate.geoiq.com/tiles/acetate-roads/{z}/{x}/{y}.png'
|
386
|
+
},
|
387
|
+
labels: {
|
388
|
+
url: 'http://a{s}.acetate.geoiq.com/tiles/acetate-labels/{z}/{x}/{y}.png'
|
389
|
+
},
|
390
|
+
hillshading: {
|
391
|
+
url: 'http://a{s}.acetate.geoiq.com/tiles/hillshading/{z}/{x}/{y}.png'
|
392
|
+
}
|
393
|
+
}
|
394
|
+
},
|
395
|
+
CloudMade: {
|
396
|
+
url: 'http://{s}.tile.cloudmade.com/{apiKey}/{styleID}/256/{z}/{x}/{y}.png',
|
397
|
+
options: {
|
398
|
+
attribution:
|
399
|
+
'Map data © <a href="http://openstreetmap.org">OpenStreetMap</a> contributors, ' +
|
400
|
+
'<a href="http://creativecommons.org/licenses/by-sa/2.0/">CC-BY-SA</a>, ' +
|
401
|
+
'Map tile imagery © <a href="http://cloudmade.com">CloudMade</a>',
|
402
|
+
minZoom: 0,
|
403
|
+
apiKey: 'abc', // Sign up for an API key at http://cloudmade.com/ - first 500,000 tile requests are free
|
404
|
+
styleID: '1'
|
405
|
+
},
|
406
|
+
variants: {
|
407
|
+
standardResolution: {
|
408
|
+
maxZoom: 18
|
409
|
+
},
|
410
|
+
highResolution: {
|
411
|
+
url: 'http://{s}.tile.cloudmade.com/{apiKey}/{styleID}@2x/256/{z}/{x}/{y}.png',
|
412
|
+
maxZoom: 19
|
413
|
+
}
|
414
|
+
}
|
415
|
+
}
|
416
|
+
};
|
417
|
+
|
418
|
+
L.tileLayer.provider = function (provider, options) {
|
419
|
+
return new L.TileLayer.Provider(provider, options);
|
420
|
+
};
|
421
|
+
|
422
|
+
L.Control.Layers.Provided = L.Control.Layers.extend({
|
423
|
+
initialize: function (base, overlay, options) {
|
424
|
+
var first;
|
425
|
+
|
426
|
+
var labelFormatter = function (label) {
|
427
|
+
return label.replace(/\./g, ': ').replace(/([a-z])([A-Z])/g, '$1 $2');
|
428
|
+
};
|
429
|
+
|
430
|
+
if (base.length) {
|
431
|
+
(function () {
|
432
|
+
var out = {},
|
433
|
+
len = base.length,
|
434
|
+
i = 0;
|
435
|
+
|
436
|
+
while (i < len) {
|
437
|
+
if (typeof base[i] === 'string') {
|
438
|
+
if (i === 0) {
|
439
|
+
first = L.tileLayer.provider(base[0]);
|
440
|
+
out[labelFormatter(base[i])] = first;
|
441
|
+
} else {
|
442
|
+
out[labelFormatter(base[i])] = L.tileLayer.provider(base[i]);
|
443
|
+
}
|
444
|
+
}
|
445
|
+
i++;
|
446
|
+
}
|
447
|
+
base = out;
|
448
|
+
}());
|
449
|
+
this._first = first;
|
450
|
+
}
|
451
|
+
|
452
|
+
if (overlay && overlay.length) {
|
453
|
+
(function () {
|
454
|
+
var out = {},
|
455
|
+
len = overlay.length,
|
456
|
+
i = 0;
|
457
|
+
|
458
|
+
while (i < len) {
|
459
|
+
if (typeof base[i] === 'string') {
|
460
|
+
out[labelFormatter(overlay[i])] = L.tileLayer.provider(overlay[i]);
|
461
|
+
}
|
462
|
+
i++;
|
463
|
+
}
|
464
|
+
overlay = out;
|
465
|
+
}());
|
466
|
+
}
|
467
|
+
L.Control.Layers.prototype.initialize.call(this, base, overlay, options);
|
468
|
+
},
|
469
|
+
onAdd: function (map) {
|
470
|
+
this._first.addTo(map);
|
471
|
+
return L.Control.Layers.prototype.onAdd.call(this, map);
|
472
|
+
}
|
473
|
+
});
|
474
|
+
|
475
|
+
L.control.layers.provided = function (baseLayers, overlays, options) {
|
476
|
+
return new L.Control.Layers.Provided(baseLayers, overlays, options);
|
477
|
+
};
|
478
|
+
}());
|
479
|
+
|