Restructure libraries.
11
assets/geojson.php
Normal file
@@ -0,0 +1,11 @@
|
||||
<?php
|
||||
|
||||
use Netzmacht\Contao\Leaflet\Controller\GeoJsonController;
|
||||
|
||||
define('TL_MODE', 'FE');
|
||||
require(dirname(dirname(dirname($_SERVER['SCRIPT_FILENAME']))) . '/system/initialize.php');
|
||||
|
||||
$container = $GLOBALS['container'];
|
||||
$controller = new GeoJsonController($container['leaflet.map.service'], $container['input']);
|
||||
|
||||
$controller->execute();
|
||||
140
assets/libs/control-geocoder/Control.Geocoder.css
Normal file
@@ -0,0 +1,140 @@
|
||||
.leaflet-control-geocoder {
|
||||
background: white;
|
||||
box-shadow: 0 1px 7px rgba(0,0,0,0.65);
|
||||
-webkit-border-radius: 4px;
|
||||
border-radius: 4px;
|
||||
line-height: 26px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.leaflet-touch .leaflet-control-geocoder {
|
||||
box-shadow: none;
|
||||
border: 2px solid rgba(0,0,0,0.2);
|
||||
background-clip: padding-box;
|
||||
line-height: 30px;
|
||||
}
|
||||
|
||||
.leaflet-control-geocoder-form {
|
||||
display: inline;
|
||||
}
|
||||
|
||||
.leaflet-control-geocoder-form input, .leaflet-control-geocoder-form ul, .leaflet-control-geocoder-error {
|
||||
border: 0;
|
||||
color: transparent;
|
||||
background: white;
|
||||
}
|
||||
|
||||
.leaflet-control-geocoder-form input {
|
||||
font-size: 16px;
|
||||
width: 0;
|
||||
transition: width 0.125s ease-in;
|
||||
}
|
||||
|
||||
.leaflet-touch .leaflet-control-geocoder-form input {
|
||||
font-size: 22px;
|
||||
}
|
||||
|
||||
.leaflet-control-geocoder-icon {
|
||||
width: 26px;
|
||||
height: 26px;
|
||||
background-image: url('images/geocoder.png');
|
||||
background-repeat: no-repeat;
|
||||
background-position: center;
|
||||
float: right;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.leaflet-touch .leaflet-control-geocoder-icon {
|
||||
margin-top: 2px;
|
||||
width: 30px;
|
||||
}
|
||||
|
||||
.leaflet-control-geocoder-throbber .leaflet-control-geocoder-icon {
|
||||
background-image: url('images/throbber.gif');
|
||||
}
|
||||
|
||||
.leaflet-control-geocoder-expanded input, .leaflet-control-geocoder-error {
|
||||
width: 226px;
|
||||
margin: 0 0 0 4px;
|
||||
padding: 0 0 0 4px;
|
||||
vertical-align: middle;
|
||||
color: #000;
|
||||
}
|
||||
|
||||
.leaflet-control-geocoder-form input:focus {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.leaflet-control-geocoder-form button {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.leaflet-control-geocoder-form-no-error {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.leaflet-control-geocoder-error {
|
||||
margin-top: 8px;
|
||||
display: block;
|
||||
color: #444;
|
||||
}
|
||||
|
||||
ul.leaflet-control-geocoder-alternatives {
|
||||
width: 260px;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
list-style: none;
|
||||
padding: 0;
|
||||
transition: height 0.125s ease-in;
|
||||
}
|
||||
|
||||
.leaflet-control-geocoder-alternatives-minimized {
|
||||
width: 0 !important;
|
||||
height: 0;
|
||||
overflow: hidden;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.leaflet-control-geocoder-alternatives li {
|
||||
width: 100%;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
border-bottom: 1px solid #eee;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
|
||||
.leaflet-control-geocoder-alternatives li:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
.leaflet-control-geocoder-alternatives a {
|
||||
display: block;
|
||||
text-decoration: none;
|
||||
color: black;
|
||||
padding: 6px 8px 16px 6px;
|
||||
font-size: 14px;
|
||||
line-height: 1;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.leaflet-touch .leaflet-control-geocoder-alternatives a {
|
||||
font-size: 18px;
|
||||
}
|
||||
|
||||
.leaflet-control-geocoder-alternatives a:hover, .leaflet-control-geocoder-selected {
|
||||
background-color: #ddd;
|
||||
}
|
||||
|
||||
.leaflet-control-geocoder-address-detail {
|
||||
font-size: 12px;
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
.leaflet-control-geocoder-address-context {
|
||||
color: #666;
|
||||
font-size: 12px;
|
||||
font-weight: lighter;
|
||||
}
|
||||
735
assets/libs/control-geocoder/Control.Geocoder.js
Normal file
@@ -0,0 +1,735 @@
|
||||
(function (factory) {
|
||||
// Packaging/modules magic dance
|
||||
var L;
|
||||
if (typeof define === 'function' && define.amd) {
|
||||
// AMD
|
||||
define(['leaflet'], factory);
|
||||
} else if (typeof module !== 'undefined') {
|
||||
// Node/CommonJS
|
||||
L = require('leaflet');
|
||||
module.exports = factory(L);
|
||||
} else {
|
||||
// Browser globals
|
||||
if (typeof window.L === 'undefined')
|
||||
throw 'Leaflet must be loaded first';
|
||||
factory(window.L);
|
||||
}
|
||||
}(function (L) {
|
||||
'use strict';
|
||||
L.Control.Geocoder = L.Control.extend({
|
||||
options: {
|
||||
showResultIcons: false,
|
||||
collapsed: true,
|
||||
expand: 'click',
|
||||
position: 'topright',
|
||||
placeholder: 'Search...',
|
||||
errorMessage: 'Nothing found.'
|
||||
},
|
||||
|
||||
_callbackId: 0,
|
||||
|
||||
initialize: function (options) {
|
||||
L.Util.setOptions(this, options);
|
||||
if (!this.options.geocoder) {
|
||||
this.options.geocoder = new L.Control.Geocoder.Nominatim();
|
||||
}
|
||||
},
|
||||
|
||||
onAdd: function (map) {
|
||||
var className = 'leaflet-control-geocoder',
|
||||
container = L.DomUtil.create('div', className),
|
||||
icon = L.DomUtil.create('div', 'leaflet-control-geocoder-icon', container),
|
||||
form = this._form = L.DomUtil.create('form', className + '-form', container),
|
||||
input;
|
||||
|
||||
this._map = map;
|
||||
this._container = container;
|
||||
input = this._input = L.DomUtil.create('input');
|
||||
input.type = 'text';
|
||||
input.placeholder = this.options.placeholder;
|
||||
|
||||
L.DomEvent.addListener(input, 'keydown', this._keydown, this);
|
||||
//L.DomEvent.addListener(input, 'onpaste', this._clearResults, this);
|
||||
//L.DomEvent.addListener(input, 'oninput', this._clearResults, this);
|
||||
|
||||
this._errorElement = document.createElement('div');
|
||||
this._errorElement.className = className + '-form-no-error';
|
||||
this._errorElement.innerHTML = this.options.errorMessage;
|
||||
|
||||
this._alts = L.DomUtil.create('ul', className + '-alternatives leaflet-control-geocoder-alternatives-minimized');
|
||||
|
||||
form.appendChild(input);
|
||||
form.appendChild(this._errorElement);
|
||||
container.appendChild(this._alts);
|
||||
|
||||
L.DomEvent.addListener(form, 'submit', this._geocode, this);
|
||||
|
||||
if (this.options.collapsed) {
|
||||
if (this.options.expand === 'click') {
|
||||
L.DomEvent.addListener(icon, 'click', function(e) {
|
||||
// TODO: touch
|
||||
if (e.button === 0 && e.detail !== 2) {
|
||||
this._toggle();
|
||||
}
|
||||
}, this);
|
||||
} else {
|
||||
L.DomEvent.addListener(icon, 'mouseover', this._expand, this);
|
||||
L.DomEvent.addListener(icon, 'mouseout', this._collapse, this);
|
||||
this._map.on('movestart', this._collapse, this);
|
||||
}
|
||||
} else {
|
||||
this._expand();
|
||||
}
|
||||
|
||||
L.DomEvent.disableClickPropagation(container);
|
||||
|
||||
return container;
|
||||
},
|
||||
|
||||
_geocodeResult: function (results) {
|
||||
L.DomUtil.removeClass(this._container, 'leaflet-control-geocoder-throbber');
|
||||
if (results.length === 1) {
|
||||
this._geocodeResultSelected(results[0]);
|
||||
} else if (results.length > 0) {
|
||||
this._alts.innerHTML = '';
|
||||
this._results = results;
|
||||
L.DomUtil.removeClass(this._alts, 'leaflet-control-geocoder-alternatives-minimized');
|
||||
for (var i = 0; i < results.length; i++) {
|
||||
this._alts.appendChild(this._createAlt(results[i], i));
|
||||
}
|
||||
} else {
|
||||
L.DomUtil.addClass(this._errorElement, 'leaflet-control-geocoder-error');
|
||||
}
|
||||
},
|
||||
|
||||
markGeocode: function(result) {
|
||||
this._map.fitBounds(result.bbox);
|
||||
|
||||
if (this._geocodeMarker) {
|
||||
this._map.removeLayer(this._geocodeMarker);
|
||||
}
|
||||
|
||||
this._geocodeMarker = new L.Marker(result.center)
|
||||
.bindPopup(result.html || result.name)
|
||||
.addTo(this._map)
|
||||
.openPopup();
|
||||
|
||||
return this;
|
||||
},
|
||||
|
||||
_geocode: function(event) {
|
||||
L.DomEvent.preventDefault(event);
|
||||
|
||||
L.DomUtil.addClass(this._container, 'leaflet-control-geocoder-throbber');
|
||||
this._clearResults();
|
||||
this.options.geocoder.geocode(this._input.value, this._geocodeResult, this);
|
||||
|
||||
return false;
|
||||
},
|
||||
|
||||
_geocodeResultSelected: function(result) {
|
||||
if (this.options.collapsed) {
|
||||
this._collapse();
|
||||
} else {
|
||||
this._clearResults();
|
||||
}
|
||||
this.markGeocode(result);
|
||||
},
|
||||
|
||||
_toggle: function() {
|
||||
if (this._container.className.indexOf('leaflet-control-geocoder-expanded') >= 0) {
|
||||
this._collapse();
|
||||
} else {
|
||||
this._expand();
|
||||
}
|
||||
},
|
||||
|
||||
_expand: function () {
|
||||
L.DomUtil.addClass(this._container, 'leaflet-control-geocoder-expanded');
|
||||
this._input.select();
|
||||
},
|
||||
|
||||
_collapse: function () {
|
||||
this._container.className = this._container.className.replace(' leaflet-control-geocoder-expanded', '');
|
||||
L.DomUtil.addClass(this._alts, 'leaflet-control-geocoder-alternatives-minimized');
|
||||
L.DomUtil.removeClass(this._errorElement, 'leaflet-control-geocoder-error');
|
||||
},
|
||||
|
||||
_clearResults: function () {
|
||||
L.DomUtil.addClass(this._alts, 'leaflet-control-geocoder-alternatives-minimized');
|
||||
this._selection = null;
|
||||
L.DomUtil.removeClass(this._errorElement, 'leaflet-control-geocoder-error');
|
||||
},
|
||||
|
||||
_createAlt: function(result, index) {
|
||||
var li = document.createElement('li'),
|
||||
a = L.DomUtil.create('a', '', li),
|
||||
icon = this.options.showResultIcons && result.icon ? L.DomUtil.create('img', '', a) : null,
|
||||
text = result.html ? undefined : document.createTextNode(result.name);
|
||||
|
||||
if (icon) {
|
||||
icon.src = result.icon;
|
||||
}
|
||||
|
||||
a.href = '#';
|
||||
a.setAttribute('data-result-index', index);
|
||||
|
||||
if (result.html) {
|
||||
a.innerHTML = result.html;
|
||||
} else {
|
||||
a.appendChild(text);
|
||||
}
|
||||
|
||||
L.DomEvent.addListener(li, 'click', function clickHandler(e) {
|
||||
L.DomEvent.preventDefault(e);
|
||||
this._geocodeResultSelected(result);
|
||||
}, this);
|
||||
|
||||
return li;
|
||||
},
|
||||
|
||||
_keydown: function(e) {
|
||||
var _this = this,
|
||||
select = function select(dir) {
|
||||
if (_this._selection) {
|
||||
L.DomUtil.removeClass(_this._selection.firstChild, 'leaflet-control-geocoder-selected');
|
||||
_this._selection = _this._selection[dir > 0 ? 'nextSibling' : 'previousSibling'];
|
||||
}
|
||||
if (!_this._selection) {
|
||||
_this._selection = _this._alts[dir > 0 ? 'firstChild' : 'lastChild'];
|
||||
}
|
||||
|
||||
if (_this._selection) {
|
||||
L.DomUtil.addClass(_this._selection.firstChild, 'leaflet-control-geocoder-selected');
|
||||
}
|
||||
};
|
||||
|
||||
switch (e.keyCode) {
|
||||
// Escape
|
||||
case 27:
|
||||
if (this.options.collapsed) {
|
||||
this._collapse();
|
||||
}
|
||||
break;
|
||||
// Up
|
||||
case 38:
|
||||
select(-1);
|
||||
L.DomEvent.preventDefault(e);
|
||||
break;
|
||||
// Up
|
||||
case 40:
|
||||
select(1);
|
||||
L.DomEvent.preventDefault(e);
|
||||
break;
|
||||
// Enter
|
||||
case 13:
|
||||
if (this._selection) {
|
||||
var index = parseInt(this._selection.firstChild.getAttribute('data-result-index'), 10);
|
||||
this._geocodeResultSelected(this._results[index]);
|
||||
this._clearResults();
|
||||
L.DomEvent.preventDefault(e);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
});
|
||||
|
||||
L.Control.geocoder = function(id, options) {
|
||||
return new L.Control.Geocoder(id, options);
|
||||
};
|
||||
|
||||
L.Control.Geocoder.callbackId = 0;
|
||||
L.Control.Geocoder.jsonp = function(url, params, callback, context, jsonpParam) {
|
||||
var callbackId = '_l_geocoder_' + (L.Control.Geocoder.callbackId++);
|
||||
params[jsonpParam || 'callback'] = callbackId;
|
||||
window[callbackId] = L.Util.bind(callback, context);
|
||||
var script = document.createElement('script');
|
||||
script.type = 'text/javascript';
|
||||
script.src = url + L.Util.getParamString(params);
|
||||
script.id = callbackId;
|
||||
document.getElementsByTagName('head')[0].appendChild(script);
|
||||
};
|
||||
L.Control.Geocoder.getJSON = function(url, params, callback) {
|
||||
var xmlHttp = new XMLHttpRequest();
|
||||
xmlHttp.open( "GET", url + L.Util.getParamString(params), true);
|
||||
xmlHttp.send(null);
|
||||
xmlHttp.onreadystatechange = function () {
|
||||
if (xmlHttp.readyState != 4) return;
|
||||
if (xmlHttp.status != 200 && req.status != 304) return;
|
||||
callback(JSON.parse(xmlHttp.response));
|
||||
};
|
||||
};
|
||||
|
||||
L.Control.Geocoder.template = function (str, data, htmlEscape) {
|
||||
return str.replace(/\{ *([\w_]+) *\}/g, function (str, key) {
|
||||
var value = data[key];
|
||||
if (value === undefined) {
|
||||
value = '';
|
||||
} else if (typeof value === 'function') {
|
||||
value = value(data);
|
||||
}
|
||||
return L.Control.Geocoder.htmlEscape(value);
|
||||
});
|
||||
};
|
||||
|
||||
// Adapted from handlebars.js
|
||||
// https://github.com/wycats/handlebars.js/
|
||||
L.Control.Geocoder.htmlEscape = (function() {
|
||||
var badChars = /[&<>"'`]/g;
|
||||
var possible = /[&<>"'`]/;
|
||||
var escape = {
|
||||
'&': '&',
|
||||
'<': '<',
|
||||
'>': '>',
|
||||
'"': '"',
|
||||
'\'': ''',
|
||||
'`': '`'
|
||||
};
|
||||
|
||||
function escapeChar(chr) {
|
||||
return escape[chr];
|
||||
}
|
||||
|
||||
return function(string) {
|
||||
if (string == null) {
|
||||
return '';
|
||||
} else if (!string) {
|
||||
return string + '';
|
||||
}
|
||||
|
||||
// Force a string conversion as this will be done by the append regardless and
|
||||
// the regex test will do this transparently behind the scenes, causing issues if
|
||||
// an object's to string has escaped characters in it.
|
||||
string = '' + string;
|
||||
|
||||
if (!possible.test(string)) {
|
||||
return string;
|
||||
}
|
||||
return string.replace(badChars, escapeChar);
|
||||
};
|
||||
})();
|
||||
|
||||
L.Control.Geocoder.Nominatim = L.Class.extend({
|
||||
options: {
|
||||
serviceUrl: '//nominatim.openstreetmap.org/',
|
||||
geocodingQueryParams: {},
|
||||
reverseQueryParams: {},
|
||||
htmlTemplate: function(r) {
|
||||
var a = r.address,
|
||||
parts = [];
|
||||
if (a.road || a.building) {
|
||||
parts.push('{building} {road} {house_number}');
|
||||
}
|
||||
|
||||
if (a.city || a.town || a.village) {
|
||||
parts.push('<span class="' + (parts.length > 0 ? 'leaflet-control-geocoder-address-detail' : '') +
|
||||
'">{postcode} {city}{town}{village}</span>');
|
||||
}
|
||||
|
||||
if (a.state || a.country) {
|
||||
parts.push('<span class="' + (parts.length > 0 ? 'leaflet-control-geocoder-address-context' : '') +
|
||||
'">{state} {country}</span>');
|
||||
}
|
||||
|
||||
return L.Control.Geocoder.template(parts.join('<br/>'), a, true);
|
||||
}
|
||||
},
|
||||
|
||||
initialize: function(options) {
|
||||
L.Util.setOptions(this, options);
|
||||
},
|
||||
|
||||
geocode: function(query, cb, context) {
|
||||
L.Control.Geocoder.jsonp(this.options.serviceUrl + 'search/', L.extend({
|
||||
q: query,
|
||||
limit: 5,
|
||||
format: 'json',
|
||||
addressdetails: 1
|
||||
}, this.options.geocodingQueryParams),
|
||||
function(data) {
|
||||
var results = [];
|
||||
for (var i = data.length - 1; i >= 0; i--) {
|
||||
var bbox = data[i].boundingbox;
|
||||
for (var j = 0; j < 4; j++) bbox[j] = parseFloat(bbox[j]);
|
||||
results[i] = {
|
||||
icon: data[i].icon,
|
||||
name: data[i].display_name,
|
||||
html: this.options.htmlTemplate ?
|
||||
this.options.htmlTemplate(data[i])
|
||||
: undefined,
|
||||
bbox: L.latLngBounds([bbox[0], bbox[2]], [bbox[1], bbox[3]]),
|
||||
center: L.latLng(data[i].lat, data[i].lon),
|
||||
properties: data[i]
|
||||
};
|
||||
}
|
||||
cb.call(context, results);
|
||||
}, this, 'json_callback');
|
||||
},
|
||||
|
||||
reverse: function(location, scale, cb, context) {
|
||||
L.Control.Geocoder.jsonp(this.options.serviceUrl + 'reverse/', L.extend({
|
||||
lat: location.lat,
|
||||
lon: location.lng,
|
||||
zoom: Math.round(Math.log(scale / 256) / Math.log(2)),
|
||||
addressdetails: 1,
|
||||
format: 'json'
|
||||
}, this.options.reverseQueryParams), function(data) {
|
||||
var result = [],
|
||||
loc;
|
||||
|
||||
if (data && data.lat && data.lon) {
|
||||
loc = L.latLng(data.lat, data.lon);
|
||||
result.push({
|
||||
name: data.display_name,
|
||||
html: this.options.htmlTemplate ?
|
||||
this.options.htmlTemplate(data)
|
||||
: undefined,
|
||||
center: loc,
|
||||
bounds: L.latLngBounds(loc, loc),
|
||||
properties: data
|
||||
});
|
||||
}
|
||||
|
||||
cb.call(context, result);
|
||||
}, this, 'json_callback');
|
||||
}
|
||||
});
|
||||
|
||||
L.Control.Geocoder.nominatim = function(options) {
|
||||
return new L.Control.Geocoder.Nominatim(options);
|
||||
};
|
||||
|
||||
L.Control.Geocoder.Bing = L.Class.extend({
|
||||
initialize: function(key) {
|
||||
this.key = key;
|
||||
},
|
||||
|
||||
geocode : function (query, cb, context) {
|
||||
L.Control.Geocoder.jsonp('//dev.virtualearth.net/REST/v1/Locations', {
|
||||
query: query,
|
||||
key : this.key
|
||||
}, function(data) {
|
||||
var results = [];
|
||||
for (var i = data.resourceSets[0].resources.length - 1; i >= 0; i--) {
|
||||
var resource = data.resourceSets[0].resources[i],
|
||||
bbox = resource.bbox;
|
||||
results[i] = {
|
||||
name: resource.name,
|
||||
bbox: L.latLngBounds([bbox[0], bbox[1]], [bbox[2], bbox[3]]),
|
||||
center: L.latLng(resource.point.coordinates)
|
||||
};
|
||||
}
|
||||
cb.call(context, results);
|
||||
}, this, 'jsonp');
|
||||
},
|
||||
|
||||
reverse: function(location, scale, cb, context) {
|
||||
L.Control.Geocoder.jsonp('//dev.virtualearth.net/REST/v1/Locations/' + location.lat + ',' + location.lng, {
|
||||
key : this.key
|
||||
}, function(data) {
|
||||
var results = [];
|
||||
for (var i = data.resourceSets[0].resources.length - 1; i >= 0; i--) {
|
||||
var resource = data.resourceSets[0].resources[i],
|
||||
bbox = resource.bbox;
|
||||
results[i] = {
|
||||
name: resource.name,
|
||||
bbox: L.latLngBounds([bbox[0], bbox[1]], [bbox[2], bbox[3]]),
|
||||
center: L.latLng(resource.point.coordinates)
|
||||
};
|
||||
}
|
||||
cb.call(context, results);
|
||||
}, this, 'jsonp');
|
||||
}
|
||||
});
|
||||
|
||||
L.Control.Geocoder.bing = function(key) {
|
||||
return new L.Control.Geocoder.Bing(key);
|
||||
};
|
||||
|
||||
L.Control.Geocoder.RaveGeo = L.Class.extend({
|
||||
options: {
|
||||
querySuffix: '',
|
||||
deepSearch: true,
|
||||
wordBased: false
|
||||
},
|
||||
|
||||
jsonp: function(params, callback, context) {
|
||||
var callbackId = '_l_geocoder_' + (L.Control.Geocoder.callbackId++),
|
||||
paramParts = [];
|
||||
params.prepend = callbackId + '(';
|
||||
params.append = ')';
|
||||
for (var p in params) {
|
||||
paramParts.push(p + '=' + escape(params[p]));
|
||||
}
|
||||
|
||||
window[callbackId] = L.Util.bind(callback, context);
|
||||
var script = document.createElement('script');
|
||||
script.type = 'text/javascript';
|
||||
script.src = this._serviceUrl + '?' + paramParts.join('&');
|
||||
script.id = callbackId;
|
||||
document.getElementsByTagName('head')[0].appendChild(script);
|
||||
},
|
||||
|
||||
initialize: function(serviceUrl, scheme, options) {
|
||||
L.Util.setOptions(this, options);
|
||||
|
||||
this._serviceUrl = serviceUrl;
|
||||
this._scheme = scheme;
|
||||
},
|
||||
|
||||
geocode: function(query, cb, context) {
|
||||
L.Control.Geocoder.jsonp(this._serviceUrl, {
|
||||
address: query + this.options.querySuffix,
|
||||
scheme: this._scheme,
|
||||
outputFormat: 'jsonp',
|
||||
deepSearch: this.options.deepSearch,
|
||||
wordBased: this.options.wordBased
|
||||
}, function(data) {
|
||||
var results = [];
|
||||
for (var i = data.length - 1; i >= 0; i--) {
|
||||
var r = data[i],
|
||||
c = L.latLng(r.y, r.x);
|
||||
results[i] = {
|
||||
name: r.address,
|
||||
bbox: L.latLngBounds([c]),
|
||||
center: c
|
||||
};
|
||||
}
|
||||
cb.call(context, results);
|
||||
}, this);
|
||||
}
|
||||
});
|
||||
|
||||
L.Control.Geocoder.raveGeo = function(serviceUrl, scheme, options) {
|
||||
return new L.Control.Geocoder.RaveGeo(serviceUrl, scheme, options);
|
||||
};
|
||||
|
||||
L.Control.Geocoder.MapQuest = L.Class.extend({
|
||||
initialize: function(key) {
|
||||
// MapQuest seems to provide URI encoded API keys,
|
||||
// so to avoid encoding them twice, we decode them here
|
||||
this._key = decodeURIComponent(key);
|
||||
},
|
||||
|
||||
_formatName: function() {
|
||||
var r = [],
|
||||
i;
|
||||
for (i = 0; i < arguments.length; i++) {
|
||||
if (arguments[i]) {
|
||||
r.push(arguments[i]);
|
||||
}
|
||||
}
|
||||
|
||||
return r.join(', ');
|
||||
},
|
||||
|
||||
geocode: function(query, cb, context) {
|
||||
L.Control.Geocoder.jsonp('//www.mapquestapi.com/geocoding/v1/address', {
|
||||
key: this._key,
|
||||
location: query,
|
||||
limit: 5,
|
||||
outFormat: 'json'
|
||||
}, function(data) {
|
||||
var results = [],
|
||||
loc,
|
||||
latLng;
|
||||
if (data.results && data.results[0].locations) {
|
||||
for (var i = data.results[0].locations.length - 1; i >= 0; i--) {
|
||||
loc = data.results[0].locations[i];
|
||||
latLng = L.latLng(loc.latLng);
|
||||
results[i] = {
|
||||
name: this._formatName(loc.street, loc.adminArea4, loc.adminArea3, loc.adminArea1),
|
||||
bbox: L.latLngBounds(latLng, latLng),
|
||||
center: latLng
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
cb.call(context, results);
|
||||
}, this);
|
||||
},
|
||||
|
||||
reverse: function(location, scale, cb, context) {
|
||||
L.Control.Geocoder.jsonp('//www.mapquestapi.com/geocoding/v1/reverse', {
|
||||
key: this._key,
|
||||
location: location.lat + ',' + location.lng,
|
||||
outputFormat: 'json'
|
||||
}, function(data) {
|
||||
var results = [],
|
||||
loc,
|
||||
latLng;
|
||||
if (data.results && data.results[0].locations) {
|
||||
for (var i = data.results[0].locations.length - 1; i >= 0; i--) {
|
||||
loc = data.results[0].locations[i];
|
||||
latLng = L.latLng(loc.latLng);
|
||||
results[i] = {
|
||||
name: this._formatName(loc.street, loc.adminArea4, loc.adminArea3, loc.adminArea1),
|
||||
bbox: L.latLngBounds(latLng, latLng),
|
||||
center: latLng
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
cb.call(context, results);
|
||||
}, this);
|
||||
}
|
||||
});
|
||||
|
||||
L.Control.Geocoder.mapQuest = function(key) {
|
||||
return new L.Control.Geocoder.MapQuest(key);
|
||||
};
|
||||
|
||||
L.Control.Geocoder.Mapbox = L.Class.extend({
|
||||
options: {
|
||||
service_url: 'https://api.tiles.mapbox.com/v4/geocode/mapbox.places-v1/'
|
||||
},
|
||||
|
||||
initialize: function(access_token) {
|
||||
this._access_token = access_token;
|
||||
},
|
||||
|
||||
geocode: function(query, cb, context) {
|
||||
L.Control.Geocoder.getJSON(this.options.service_url + encodeURIComponent(query) + '.json', {
|
||||
access_token: this._access_token,
|
||||
}, function(data) {
|
||||
var results = [],
|
||||
loc,
|
||||
latLng,
|
||||
latLngBounds;
|
||||
if (data.features && data.features.length) {
|
||||
for (var i = 0; i <= data.features.length - 1; i++) {
|
||||
loc = data.features[i];
|
||||
latLng = L.latLng(loc.center.reverse());
|
||||
if(loc.hasOwnProperty('bbox'))
|
||||
{
|
||||
latLngBounds = L.latLngBounds(L.latLng(loc.bbox.slice(0, 2).reverse()), L.latLng(loc.bbox.slice(2, 4).reverse()));
|
||||
}
|
||||
else
|
||||
{
|
||||
latLngBounds = L.latLngBounds(latLng, latLng);
|
||||
}
|
||||
results[i] = {
|
||||
name: loc.place_name,
|
||||
bbox: latLngBounds,
|
||||
center: latLng
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
cb.call(context, results);
|
||||
});
|
||||
},
|
||||
|
||||
reverse: function(location, scale, cb, context) {
|
||||
L.Control.Geocoder.getJSON(this.options.service_url + encodeURIComponent(location.lng) + ',' + encodeURIComponent(location.lat) + '.json', {
|
||||
access_token: this._access_token,
|
||||
}, function(data) {
|
||||
var results = [],
|
||||
loc,
|
||||
latLng,
|
||||
latLngBounds;
|
||||
if (data.features && data.features.length) {
|
||||
for (var i = 0; i <= data.features.length - 1; i++) {
|
||||
loc = data.features[i];
|
||||
latLng = L.latLng(loc.center.reverse());
|
||||
if(loc.hasOwnProperty('bbox'))
|
||||
{
|
||||
latLngBounds = L.latLngBounds(L.latLng(loc.bbox.slice(0, 2).reverse()), L.latLng(loc.bbox.slice(2, 4).reverse()));
|
||||
}
|
||||
else
|
||||
{
|
||||
latLngBounds = L.latLngBounds(latLng, latLng);
|
||||
}
|
||||
results[i] = {
|
||||
name: loc.place_name,
|
||||
bbox: latLngBounds,
|
||||
center: latLng
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
cb.call(context, results);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
L.Control.Geocoder.mapbox = function(access_token) {
|
||||
return new L.Control.Geocoder.Mapbox(access_token);
|
||||
};
|
||||
|
||||
L.Control.Geocoder.Google = L.Class.extend({
|
||||
options: {
|
||||
service_url: 'https://maps.googleapis.com/maps/api/geocode/json'
|
||||
},
|
||||
|
||||
initialize: function(key) {
|
||||
this._key = key;
|
||||
},
|
||||
|
||||
geocode: function(query, cb, context) {
|
||||
var params = {
|
||||
address: query,
|
||||
};
|
||||
if(this._key && this._key.length)
|
||||
{
|
||||
params['key'] = this._key
|
||||
}
|
||||
|
||||
L.Control.Geocoder.getJSON(this.options.service_url, params, function(data) {
|
||||
var results = [],
|
||||
loc,
|
||||
latLng,
|
||||
latLngBounds;
|
||||
if (data.results && data.results.length) {
|
||||
for (var i = 0; i <= data.results.length - 1; i++) {
|
||||
loc = data.results[i];
|
||||
latLng = L.latLng(loc.geometry.location);
|
||||
latLngBounds = L.latLngBounds(L.latLng(loc.geometry.viewport.northeast), L.latLng(loc.geometry.viewport.southwest));
|
||||
results[i] = {
|
||||
name: loc.formatted_address,
|
||||
bbox: latLngBounds,
|
||||
center: latLng
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
cb.call(context, results);
|
||||
});
|
||||
},
|
||||
|
||||
reverse: function(location, scale, cb, context) {
|
||||
var params = {
|
||||
latlng: encodeURIComponent(location.lat) + ',' + encodeURIComponent(location.lng)
|
||||
};
|
||||
if(this._key && this._key.length)
|
||||
{
|
||||
params['key'] = this._key
|
||||
}
|
||||
L.Control.Geocoder.getJSON(this.options.service_url, params, function(data) {
|
||||
var results = [],
|
||||
loc,
|
||||
latLng,
|
||||
latLngBounds;
|
||||
if (data.results && data.results.length) {
|
||||
for (var i = 0; i <= data.results.length - 1; i++) {
|
||||
loc = data.results[i];
|
||||
latLng = L.latLng(loc.geometry.location);
|
||||
latLngBounds = L.latLngBounds(L.latLng(loc.geometry.viewport.northeast), L.latLng(loc.geometry.viewport.southwest));
|
||||
results[i] = {
|
||||
name: loc.formatted_address,
|
||||
bbox: latLngBounds,
|
||||
center: latLng
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
cb.call(context, results);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
L.Control.Geocoder.google = function(key) {
|
||||
return new L.Control.Geocoder.Google(key);
|
||||
};
|
||||
return L.Control.Geocoder;
|
||||
}));
|
||||
23
assets/libs/control-geocoder/LICENSE
Normal file
@@ -0,0 +1,23 @@
|
||||
Copyright (c) 2012 sa3m (https://github.com/sa3m)
|
||||
Copyright (c) 2013 Per Liedman
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification, are
|
||||
permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
of conditions and the following disclaimer in the documentation and/or other materials
|
||||
provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
|
||||
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
|
||||
TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
156
assets/libs/control-geocoder/README.md
Normal file
@@ -0,0 +1,156 @@
|
||||
## A few words on diversity in tech
|
||||
|
||||
I need to take some of your time. I can't believe we let shit like [the Kathy Sierra incident](http://www.wired.com/2014/10/trolls-will-always-win/) or [what happened to Brianna Wu](https://twitter.com/Spacekatgal/status/520739878993420290) happen over and over again. I can't believe we, the open source community, let [sexist, misogynous shit happen over and over again](http://geekfeminism.wikia.com/wiki/Timeline_of_incidents).
|
||||
|
||||
I strongly believe that it is my — and your — duty to make the open source community, as well as the tech community at large, a community where everyone feel welcome and is accepted. At the very minimum, that means making sure the community and its forums both _are_ safe, and are perceived as safe. It means being friendly and inclusive, even when you disagree with people. It means not shrugging of discussions about sexism and inclusiveness with [handwaving about censorship and free speech](https://josm.openstreetmap.de/ticket/10568). For a more elaborate document on what that means, [the NPM Code of Conduct](http://www.npmjs.com/policies/conduct) is a good start, [Geek Feminism's resources for allies](http://geekfeminism.wikia.com/wiki/Resources_for_allies) contains much more.
|
||||
|
||||
While I can't force anyone to do anything, if you happen to disagree with this, I ask of you not to use any of the open source I have published. Nor am I interested in contributions from people who can't accept or act respectfully towards other humans regardless of gender identity, sexual orientation, disability, ethnicity, religion, age, physical appearance, body size, race, or similar personal characteristics. If you think feminism, anti-racism or the LGBT movement is somehow wrong, disturbing or irrelevant, I ask you to go elsewhere to find software.
|
||||
|
||||
Leaflet Control Geocoder [](http://badge.fury.io/js/leaflet-control-geocoder)
|
||||
=============================
|
||||
|
||||
A simple geocoder for [Leaflet](http://leafletjs.com/) that by default uses [OSM](http://www.openstreetmap.org/)/[Nominatim](http://wiki.openstreetmap.org/wiki/Nominatim).
|
||||
|
||||
The plugin supports many different data providers:
|
||||
|
||||
* [OSM](http://www.openstreetmap.org/)/[Nominatim](http://wiki.openstreetmap.org/wiki/Nominatim)
|
||||
* [Bing Locations API](http://msdn.microsoft.com/en-us/library/ff701715.aspx)
|
||||
* [Google Geocoding API](https://developers.google.com/maps/documentation/geocoding/)
|
||||
* [Mapbox Geocoding](https://www.mapbox.com/developers/api/geocoding/)
|
||||
* [MapQuest Geocoding API](http://developer.mapquest.com/web/products/dev-services/geocoding-ws)
|
||||
* [RaveGeo](http://www2.idevio.com/ravegeo-server.html)
|
||||
|
||||
The plugin can easily be extended to support other providers.
|
||||
|
||||
See the [Leaflet Control Geocoder Demo](http://perliedman.github.com/leaflet-control-geocoder/).
|
||||
|
||||
# Usage
|
||||
|
||||
Load the CSS and Javascript:
|
||||
|
||||
```HTML
|
||||
<link rel="stylesheet" href="../Control.Geocoder.css" />
|
||||
<script src="Control.Geocoder.js"></script>
|
||||
```
|
||||
|
||||
Add the control to a map instance:
|
||||
|
||||
```javascript
|
||||
var map = L.map('map').setView([0, 0], 2);
|
||||
L.tileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png', {
|
||||
attribution: '© <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
|
||||
}).addTo(map);
|
||||
L.Control.geocoder().addTo(map);
|
||||
```
|
||||
|
||||
# Customizing
|
||||
|
||||
By default, when a geocoding result is found, the control will center the map on it and place
|
||||
a marker at its location. This can be customized by overwriting the control's ```markGeocode```
|
||||
function, to perform any action desired.
|
||||
|
||||
For example:
|
||||
|
||||
```javascript
|
||||
var geocoder = L.Control.geocoder().addTo(map);
|
||||
|
||||
geocoder.markGeocode = function(result) {
|
||||
var bbox = result.bbox;
|
||||
L.polygon([
|
||||
bbox.getSouthEast(),
|
||||
bbox.getNorthEast(),
|
||||
bbox.getNorthWest(),
|
||||
bbox.getSouthWest()
|
||||
]).addTo(map);
|
||||
};
|
||||
```
|
||||
|
||||
This will add a polygon representing the result's boundingbox when a result is selected.
|
||||
|
||||
# API
|
||||
|
||||
## L.Control.Geocoder
|
||||
|
||||
This is the geocoder control. It works like any other Leaflet control, and is added to the map.
|
||||
|
||||
### Constructor
|
||||
|
||||
```js
|
||||
L.Control.Geocoder(options)
|
||||
```
|
||||
|
||||
### Options
|
||||
|
||||
| Option | Type | Default | Description |
|
||||
| --------------- | ---------------- | ----------------- | ----------- |
|
||||
| collapsed | Boolean | true | Collapse control unless hovered/clicked |
|
||||
| position | String | "topright" | Control [position](http://leafletjs.com/reference.html#control-positions) |
|
||||
| placeholder | String | "Search..." | Placeholder text for text input
|
||||
| errorMessage | String | "Nothing found." | Message when no result found / geocoding error occurs |
|
||||
| geocoder | IGeocoder | new L.Control.Geocoder.Nominatim() | Object to perform the actual geocoding queries |
|
||||
| showResultIcons | Boolean | false | Show icons for geocoding results (if available); supported by Nominatim |
|
||||
|
||||
### Methods
|
||||
|
||||
| Method | Returns | Description |
|
||||
| ------------------------------------- | ------------------- | ----------------- |
|
||||
| markGeocode(<GeocodingResult> result) | this | Marks a geocoding result on the map |
|
||||
|
||||
## L.Control.Geocoder.Nominatim
|
||||
|
||||
Uses [Nominatim](http://wiki.openstreetmap.org/wiki/Nominatim) to respond to geocoding queries. This is the default
|
||||
geocoding service used by the control, unless otherwise specified in the options. Implements ```IGeocoder```.
|
||||
|
||||
Unless using your own Nominatim installation, please refer to the [Nominatim usage policy](http://wiki.openstreetmap.org/wiki/Nominatim_usage_policy).
|
||||
|
||||
### Constructor
|
||||
|
||||
```js
|
||||
L.Control.Geocoder.Nominatim(options)
|
||||
```
|
||||
|
||||
## Options
|
||||
|
||||
| Option | Type | Default | Description |
|
||||
| --------------- | ---------------- | ----------------- | ----------- |
|
||||
| serviceUrl | String | "http://nominatim.openstreetmap.org/" | URL of the service |
|
||||
| geocodingQueryParams | Object | {} | Additional URL parameters (strings) that will be added to geocoding requests; can be used to restrict results to a specific country for example, by providing the [`countrycodes`](http://wiki.openstreetmap.org/wiki/Nominatim#Parameters) parameter to Nominatim |
|
||||
| reverseQueryParams | Object | {} | Additional URL parameters (strings) that will be added to reverse geocoding requests |
|
||||
| htmlTemplate | function | special | A function that takes an GeocodingResult as argument and returns an HTML formatted string that represents the result. Default function breaks up address in parts from most to least specific, in attempt to increase readability compared to Nominatim's naming
|
||||
|
||||
## L.Control.Geocoder.Bing
|
||||
|
||||
Uses [Bing Locations API](http://msdn.microsoft.com/en-us/library/ff701715.aspx) to respond to geocoding queries. Implements ```IGeocoder```.
|
||||
|
||||
Note that you need an API key to use this service.
|
||||
|
||||
### Constructor
|
||||
|
||||
```
|
||||
L.Control.Geocoder.Bing(<String> key)
|
||||
```
|
||||
|
||||
## IGeocoder
|
||||
|
||||
An interface implemented to respond to geocoding queries.
|
||||
|
||||
### Methods
|
||||
|
||||
| Method | Returns | Description |
|
||||
| ------------------------------------- | ------------------- | ----------------- |
|
||||
| geocode(<String> query, callback, context) | GeocodingResult[] | Performs a geocoding query and returns the results to the callback in the provided context |
|
||||
| reverse(<L.LatLng> location, <Number> scale, callback, context) | GeocodingResult[] | Performs a reverse geocoding query and returns the results to the callback in the provided context |
|
||||
|
||||
## GeocodingResult
|
||||
|
||||
An object that represents a result from a geocoding query.
|
||||
|
||||
### Properties
|
||||
|
||||
| Property | Type | Description |
|
||||
| ---------- | ---------------- | ------------------------------------- |
|
||||
| name | String | Name of found location |
|
||||
| bounds | L.LatLngBounds | The bounds of the location |
|
||||
| center | L.LatLng | The center coordinate of the location |
|
||||
| icon | String | URL for icon representing result; optional |
|
||||
| html | String | (optional) HTML formatted representation of the name |
|
||||
BIN
assets/libs/control-geocoder/images/geocoder.png
Normal file
|
After Width: | Height: | Size: 466 B |
BIN
assets/libs/control-geocoder/images/throbber.gif
Normal file
|
After Width: | Height: | Size: 4.7 KiB |
26
assets/libs/control-geocoder/package.json
Normal file
@@ -0,0 +1,26 @@
|
||||
{
|
||||
"name": "leaflet-control-geocoder",
|
||||
"version": "1.0.0",
|
||||
"description": "Extendable geocoder with builtin OSM/Nominatim support",
|
||||
"main": "Control.Geocoder.js",
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git://github.com/perliedman/leaflet-control-geocoder.git"
|
||||
},
|
||||
"keywords": [
|
||||
"leaflet",
|
||||
"geocoder",
|
||||
"nominatim"
|
||||
],
|
||||
"author": "Per Liedman <per@liedman.net>",
|
||||
"license": "BSD-2-Clause",
|
||||
"bugs": {
|
||||
"url": "https://github.com/perliedman/leaflet-control-geocoder/issues"
|
||||
},
|
||||
"dependencies": {
|
||||
"leaflet": "~0.7.2"
|
||||
}
|
||||
}
|
||||
75
assets/libs/leaflet-ajax/README.md
Normal file
@@ -0,0 +1,75 @@
|
||||
leaflet-ajax
|
||||
===========
|
||||
|
||||
Allows you to call JSON via an Ajax call with a jsonp fallback.
|
||||
|
||||
```javascript
|
||||
var geojsonLayer = new L.GeoJSON.AJAX("geojson.json");
|
||||
```
|
||||
for jsonp add the option "dataType" and set it to "jsonp"
|
||||
``` javascript
|
||||
var geojsonLayer = L.geoJson.ajax("http:webhost.fake/geojson.jsonp",{dataType:"jsonp"});
|
||||
```
|
||||
Note that data starts to download when the layer is created NOT when it’s added to the map in order to get a head start.
|
||||
|
||||
You may pass either a url string or an array of url strings if you want to download multiple things (handy
|
||||
if your downloading data from an ESRI based thing which will have separate line, point, and poly features).
|
||||
|
||||
As you see you can also use lower case methods without creating new objects
|
||||
|
||||
For weirder jsonp you can set "callbackParam" for if you need to change the name of the callback parameter to something besides "callback", e.g. [Mapquest Nominative Open](http://open.mapquestapi.com/nominatim/) uses "json_callback" instead of "callback".
|
||||
|
||||
If you want to use `eval` to parse JSON in older browsers you need to pass an option `evil` set to something truthy.
|
||||
|
||||
If you want to be able to load stuff from the file system (with appropriate custom flags set) set local to true.
|
||||
|
||||
Gives off three events `data:loading`, `data:progress` and `data:loaded`.
|
||||
|
||||
- `data:loading` fires before we start downloading things, note if the constructor is given a url it won't wait to be added to the map
|
||||
to start downloading the data, but it does do an async wait so you have time to add a listener to it (and so [leaflet.spin](https://github.com/makinacorpus/Leaflet.Spin) will work with it).
|
||||
- `data:progress` is called each time a file is downloaded and passes the downloaded geojson as event data.
|
||||
- `data:loaded` is called when all files have downloaded, this is mainly different from `data:progress` when you are downloading multiple things.
|
||||
|
||||
You can also add a middleware function which is called after you download the data but before you add it to leaflet:
|
||||
|
||||
```javascript
|
||||
var geojsonLayer = L.geoJson.ajax("route/to/esri.json",{
|
||||
middleware:function(data){
|
||||
return esri2geoOrSomething(json);
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
addUrl does not clear the current layers but adds to the current one, e.g.:
|
||||
|
||||
```javascript
|
||||
var geojsonLayer = L.geoJson.ajax("data.json");
|
||||
geojsonLayer.addUrl("data2.json");//we now have 2 layers
|
||||
geojsonLayer.refresh();//redownload the most recent layer
|
||||
geojsonLayer.refresh("new1.json");//add a new layer replacing whatever is there
|
||||
```
|
||||
|
||||
last but now least we can refilter layers without re adding them
|
||||
|
||||
```javascript
|
||||
var geojsonLayer = L.geoJson.ajax("data.json");
|
||||
geojsonLayer.refilter(function(feature){
|
||||
return feature.properties.key === values;
|
||||
});
|
||||
```
|
||||
|
||||
Behind the scenes are two new classes L.Util.ajax = function (url) for same origin requests and L.Util.jsonp = function (url,options) cross origin ones. Both return promises, which have an additional abort method that will abort the ajax request.
|
||||
|
||||
```js
|
||||
L.Util.ajax("url/same/origin.xml").then(function(data){
|
||||
doStuff(data);
|
||||
});
|
||||
//or
|
||||
L.Util.jsonp("http://www.dif.ori/gin").then(function(data){
|
||||
doStuff(data);
|
||||
});
|
||||
```
|
||||
|
||||
In related news `L.Util.Promise` is now a constructor for a promise, it takes one argument, a resolver function.
|
||||
|
||||
Some of the jsonp code inspired by/taken from [this interesting looking plugin](https://github.com/stefanocudini/leaflet-search) that I have failed to make heads nor tails of (the plugin, not the jsonp code)
|
||||
740
assets/libs/leaflet-ajax/leaflet.ajax.js
Normal file
@@ -0,0 +1,740 @@
|
||||
;(function(){
|
||||
|
||||
/**
|
||||
* Require the given path.
|
||||
*
|
||||
* @param {String} path
|
||||
* @return {Object} exports
|
||||
* @api public
|
||||
*/
|
||||
|
||||
function require(path, parent, orig) {
|
||||
var resolved = require.resolve(path);
|
||||
|
||||
// lookup failed
|
||||
if (null == resolved) {
|
||||
orig = orig || path;
|
||||
parent = parent || 'root';
|
||||
var err = new Error('Failed to require "' + orig + '" from "' + parent + '"');
|
||||
err.path = orig;
|
||||
err.parent = parent;
|
||||
err.require = true;
|
||||
throw err;
|
||||
}
|
||||
|
||||
var module = require.modules[resolved];
|
||||
|
||||
// perform real require()
|
||||
// by invoking the module's
|
||||
// registered function
|
||||
if (!module.exports) {
|
||||
module.exports = {};
|
||||
module.client = module.component = true;
|
||||
module.call(this, module.exports, require.relative(resolved), module);
|
||||
}
|
||||
|
||||
return module.exports;
|
||||
}
|
||||
|
||||
/**
|
||||
* Registered modules.
|
||||
*/
|
||||
|
||||
require.modules = {};
|
||||
|
||||
/**
|
||||
* Registered aliases.
|
||||
*/
|
||||
|
||||
require.aliases = {};
|
||||
|
||||
/**
|
||||
* Resolve `path`.
|
||||
*
|
||||
* Lookup:
|
||||
*
|
||||
* - PATH/index.js
|
||||
* - PATH.js
|
||||
* - PATH
|
||||
*
|
||||
* @param {String} path
|
||||
* @return {String} path or null
|
||||
* @api private
|
||||
*/
|
||||
|
||||
require.resolve = function(path) {
|
||||
if (path.charAt(0) === '/') path = path.slice(1);
|
||||
|
||||
var paths = [
|
||||
path,
|
||||
path + '.js',
|
||||
path + '.json',
|
||||
path + '/index.js',
|
||||
path + '/index.json'
|
||||
];
|
||||
|
||||
for (var i = 0; i < paths.length; i++) {
|
||||
var path = paths[i];
|
||||
if (require.modules.hasOwnProperty(path)) return path;
|
||||
if (require.aliases.hasOwnProperty(path)) return require.aliases[path];
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Normalize `path` relative to the current path.
|
||||
*
|
||||
* @param {String} curr
|
||||
* @param {String} path
|
||||
* @return {String}
|
||||
* @api private
|
||||
*/
|
||||
|
||||
require.normalize = function(curr, path) {
|
||||
var segs = [];
|
||||
|
||||
if ('.' != path.charAt(0)) return path;
|
||||
|
||||
curr = curr.split('/');
|
||||
path = path.split('/');
|
||||
|
||||
for (var i = 0; i < path.length; ++i) {
|
||||
if ('..' == path[i]) {
|
||||
curr.pop();
|
||||
} else if ('.' != path[i] && '' != path[i]) {
|
||||
segs.push(path[i]);
|
||||
}
|
||||
}
|
||||
|
||||
return curr.concat(segs).join('/');
|
||||
};
|
||||
|
||||
/**
|
||||
* Register module at `path` with callback `definition`.
|
||||
*
|
||||
* @param {String} path
|
||||
* @param {Function} definition
|
||||
* @api private
|
||||
*/
|
||||
|
||||
require.register = function(path, definition) {
|
||||
require.modules[path] = definition;
|
||||
};
|
||||
|
||||
/**
|
||||
* Alias a module definition.
|
||||
*
|
||||
* @param {String} from
|
||||
* @param {String} to
|
||||
* @api private
|
||||
*/
|
||||
|
||||
require.alias = function(from, to) {
|
||||
if (!require.modules.hasOwnProperty(from)) {
|
||||
throw new Error('Failed to alias "' + from + '", it does not exist');
|
||||
}
|
||||
require.aliases[to] = from;
|
||||
};
|
||||
|
||||
/**
|
||||
* Return a require function relative to the `parent` path.
|
||||
*
|
||||
* @param {String} parent
|
||||
* @return {Function}
|
||||
* @api private
|
||||
*/
|
||||
|
||||
require.relative = function(parent) {
|
||||
var p = require.normalize(parent, '..');
|
||||
|
||||
/**
|
||||
* lastIndexOf helper.
|
||||
*/
|
||||
|
||||
function lastIndexOf(arr, obj) {
|
||||
var i = arr.length;
|
||||
while (i--) {
|
||||
if (arr[i] === obj) return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* The relative require() itself.
|
||||
*/
|
||||
|
||||
function localRequire(path) {
|
||||
var resolved = localRequire.resolve(path);
|
||||
return require(resolved, parent, path);
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolve relative to the parent.
|
||||
*/
|
||||
|
||||
localRequire.resolve = function(path) {
|
||||
var c = path.charAt(0);
|
||||
if ('/' == c) return path.slice(1);
|
||||
if ('.' == c) return require.normalize(p, path);
|
||||
|
||||
// resolve deps by returning
|
||||
// the dep in the nearest "deps"
|
||||
// directory
|
||||
var segs = parent.split('/');
|
||||
var i = lastIndexOf(segs, 'deps') + 1;
|
||||
if (!i) i = 0;
|
||||
path = segs.slice(0, i + 1).join('/') + '/deps/' + path;
|
||||
return path;
|
||||
};
|
||||
|
||||
/**
|
||||
* Check if module is defined at `path`.
|
||||
*/
|
||||
|
||||
localRequire.exists = function(path) {
|
||||
return require.modules.hasOwnProperty(localRequire.resolve(path));
|
||||
};
|
||||
|
||||
return localRequire;
|
||||
};
|
||||
require.register("calvinmetcalf-setImmediate/lib/index.js", function(exports, require, module){
|
||||
"use strict";
|
||||
var types = [
|
||||
require("./nextTick"),
|
||||
require("./mutation"),
|
||||
require("./postMessage"),
|
||||
require("./messageChannel"),
|
||||
require("./stateChange"),
|
||||
require("./timeout")
|
||||
];
|
||||
var handlerQueue = [];
|
||||
|
||||
function drainQueue() {
|
||||
var i = 0,
|
||||
task,
|
||||
innerQueue = handlerQueue;
|
||||
handlerQueue = [];
|
||||
/*jslint boss: true */
|
||||
while (task = innerQueue[i++]) {
|
||||
task();
|
||||
}
|
||||
}
|
||||
var nextTick;
|
||||
types.some(function (obj) {
|
||||
var t = obj.test();
|
||||
if (t) {
|
||||
nextTick = obj.install(drainQueue);
|
||||
}
|
||||
return t;
|
||||
});
|
||||
var retFunc = function (task) {
|
||||
var len, args;
|
||||
if (arguments.length > 1 && typeof task === "function") {
|
||||
args = Array.prototype.slice.call(arguments, 1);
|
||||
args.unshift(undefined);
|
||||
task = task.bind.apply(task, args);
|
||||
}
|
||||
if ((len = handlerQueue.push(task)) === 1) {
|
||||
nextTick(drainQueue);
|
||||
}
|
||||
return len;
|
||||
};
|
||||
retFunc.clear = function (n) {
|
||||
if (n <= handlerQueue.length) {
|
||||
handlerQueue[n - 1] = function () {};
|
||||
}
|
||||
return this;
|
||||
};
|
||||
module.exports = retFunc;
|
||||
|
||||
});
|
||||
require.register("calvinmetcalf-setImmediate/lib/nextTick.js", function(exports, require, module){
|
||||
"use strict";
|
||||
exports.test = function () {
|
||||
// Don't get fooled by e.g. browserify environments.
|
||||
return typeof process === "object" && Object.prototype.toString.call(process) === "[object process]";
|
||||
};
|
||||
|
||||
exports.install = function () {
|
||||
return process.nextTick;
|
||||
};
|
||||
});
|
||||
require.register("calvinmetcalf-setImmediate/lib/postMessage.js", function(exports, require, module){
|
||||
"use strict";
|
||||
var globe = require("./global");
|
||||
exports.test = function () {
|
||||
// The test against `importScripts` prevents this implementation from being installed inside a web worker,
|
||||
// where `global.postMessage` means something completely different and can"t be used for this purpose.
|
||||
|
||||
if (!globe.postMessage || globe.importScripts) {
|
||||
return false;
|
||||
}
|
||||
|
||||
var postMessageIsAsynchronous = true;
|
||||
var oldOnMessage = globe.onmessage;
|
||||
globe.onmessage = function () {
|
||||
postMessageIsAsynchronous = false;
|
||||
};
|
||||
globe.postMessage("", "*");
|
||||
globe.onmessage = oldOnMessage;
|
||||
|
||||
return postMessageIsAsynchronous;
|
||||
};
|
||||
|
||||
exports.install = function (func) {
|
||||
var codeWord = "com.calvinmetcalf.setImmediate" + Math.random();
|
||||
function globalMessage(event) {
|
||||
if (event.source === globe && event.data === codeWord) {
|
||||
func();
|
||||
}
|
||||
}
|
||||
if (globe.addEventListener) {
|
||||
globe.addEventListener("message", globalMessage, false);
|
||||
} else {
|
||||
globe.attachEvent("onmessage", globalMessage);
|
||||
}
|
||||
return function () {
|
||||
globe.postMessage(codeWord, "*");
|
||||
};
|
||||
};
|
||||
});
|
||||
require.register("calvinmetcalf-setImmediate/lib/messageChannel.js", function(exports, require, module){
|
||||
"use strict";
|
||||
var globe = require("./global");
|
||||
exports.test = function () {
|
||||
return !!globe.MessageChannel;
|
||||
};
|
||||
|
||||
exports.install = function (func) {
|
||||
var channel = new globe.MessageChannel();
|
||||
channel.port1.onmessage = func;
|
||||
return function () {
|
||||
channel.port2.postMessage(0);
|
||||
};
|
||||
};
|
||||
});
|
||||
require.register("calvinmetcalf-setImmediate/lib/stateChange.js", function(exports, require, module){
|
||||
"use strict";
|
||||
var globe = require("./global");
|
||||
exports.test = function () {
|
||||
return "document" in globe && "onreadystatechange" in globe.document.createElement("script");
|
||||
};
|
||||
|
||||
exports.install = function (handle) {
|
||||
return function () {
|
||||
|
||||
// Create a <script> element; its readystatechange event will be fired asynchronously once it is inserted
|
||||
// into the document. Do so, thus queuing up the task. Remember to clean up once it's been called.
|
||||
var scriptEl = globe.document.createElement("script");
|
||||
scriptEl.onreadystatechange = function () {
|
||||
handle();
|
||||
|
||||
scriptEl.onreadystatechange = null;
|
||||
scriptEl.parentNode.removeChild(scriptEl);
|
||||
scriptEl = null;
|
||||
};
|
||||
globe.document.documentElement.appendChild(scriptEl);
|
||||
|
||||
return handle;
|
||||
};
|
||||
};
|
||||
});
|
||||
require.register("calvinmetcalf-setImmediate/lib/timeout.js", function(exports, require, module){
|
||||
"use strict";
|
||||
exports.test = function () {
|
||||
return true;
|
||||
};
|
||||
|
||||
exports.install = function (t) {
|
||||
return function () {
|
||||
setTimeout(t, 0);
|
||||
};
|
||||
};
|
||||
});
|
||||
require.register("calvinmetcalf-setImmediate/lib/global.js", function(exports, require, module){
|
||||
module.exports = typeof global === "object" && global ? global : this;
|
||||
});
|
||||
require.register("calvinmetcalf-setImmediate/lib/mutation.js", function(exports, require, module){
|
||||
"use strict";
|
||||
//based off rsvp
|
||||
//https://github.com/tildeio/rsvp.js/blob/master/lib/rsvp/async.js
|
||||
var globe = require("./global");
|
||||
|
||||
var MutationObserver = globe.MutationObserver || globe.WebKitMutationObserver;
|
||||
|
||||
exports.test = function () {
|
||||
return MutationObserver;
|
||||
};
|
||||
|
||||
exports.install = function (handle) {
|
||||
var observer = new MutationObserver(handle);
|
||||
var element = globe.document.createElement("div");
|
||||
observer.observe(element, { attributes: true });
|
||||
|
||||
// Chrome Memory Leak: https://bugs.webkit.org/show_bug.cgi?id=93661
|
||||
globe.addEventListener("unload", function () {
|
||||
observer.disconnect();
|
||||
observer = null;
|
||||
}, false);
|
||||
return function () {
|
||||
element.setAttribute("drainQueue", "drainQueue");
|
||||
};
|
||||
};
|
||||
});
|
||||
require.register("lie/lie.js", function(exports, require, module){
|
||||
var immediate = require('immediate');
|
||||
// Creates a deferred: an object with a promise and corresponding resolve/reject methods
|
||||
function Promise(resolver) {
|
||||
if (!(this instanceof Promise)) {
|
||||
return new Promise(resolver);
|
||||
}
|
||||
var queue = [];
|
||||
var resolved = false;
|
||||
// The `handler` variable points to the function that will
|
||||
// 1) handle a .then(onFulfilled, onRejected) call
|
||||
// 2) handle a .resolve or .reject call (if not fulfilled)
|
||||
// Before 2), `handler` holds a queue of callbacks.
|
||||
// After 2), `handler` is a simple .then handler.
|
||||
// We use only one function to save memory and complexity.
|
||||
// Case 1) handle a .then(onFulfilled, onRejected) call
|
||||
function pending(onFulfilled, onRejected){
|
||||
return Promise(function(resolver,rejecter){
|
||||
queue.push({
|
||||
resolve: onFulfilled,
|
||||
reject: onRejected,
|
||||
resolver:resolver,
|
||||
rejecter:rejecter
|
||||
});
|
||||
});
|
||||
}
|
||||
function then(onFulfilled, onRejected) {
|
||||
return resolved?resolved(onFulfilled, onRejected):pending(onFulfilled, onRejected);
|
||||
}
|
||||
// Case 2) handle a .resolve or .reject call
|
||||
// (`onFulfilled` acts as a sentinel)
|
||||
// The actual function signature is
|
||||
// .re[ject|solve](sentinel, success, value)
|
||||
function resolve(success, value){
|
||||
var action = success ? 'resolve' : 'reject';
|
||||
var queued;
|
||||
var callback;
|
||||
for (var i = 0, l = queue.length; i < l; i++) {
|
||||
queued = queue[i];
|
||||
callback = queued[action];
|
||||
if (typeof callback === 'function') {
|
||||
immediate(execute,callback, value, queued.resolver, queued.rejecter);
|
||||
}else if(success){
|
||||
queued.resolver(value);
|
||||
}else{
|
||||
queued.rejecter(value);
|
||||
}
|
||||
}
|
||||
// Replace this handler with a simple resolved or rejected handler
|
||||
resolved = createHandler(then, value, success);
|
||||
}
|
||||
this.then = then;
|
||||
function yes(value) {
|
||||
if (!resolved) {
|
||||
resolve(true, value);
|
||||
}
|
||||
}
|
||||
function no (reason) {
|
||||
if (!resolved) {
|
||||
resolve(false, reason);
|
||||
}
|
||||
}
|
||||
try{
|
||||
resolver(function(a){
|
||||
if(a && typeof a.then==='function'){
|
||||
a.then(yes,no);
|
||||
}else{
|
||||
yes(a);
|
||||
}
|
||||
},no);
|
||||
}catch(e){
|
||||
no(e);
|
||||
}
|
||||
}
|
||||
|
||||
// Creates a fulfilled or rejected .then function
|
||||
function createHandler(then, value, success) {
|
||||
return function(onFulfilled, onRejected) {
|
||||
var callback = success ? onFulfilled : onRejected;
|
||||
if (typeof callback !== 'function') {
|
||||
return Promise(function(resolve,reject){
|
||||
then(resolve,reject);
|
||||
});
|
||||
}
|
||||
return Promise(function(resolve,reject){
|
||||
immediate(execute,callback,value,resolve,reject);
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
// Executes the callback with the specified value,
|
||||
// resolving or rejecting the deferred
|
||||
function execute(callback, value, resolve, reject) {
|
||||
try {
|
||||
var result = callback(value);
|
||||
if (result && typeof result.then === 'function') {
|
||||
result.then(resolve, reject);
|
||||
}
|
||||
else {
|
||||
resolve(result);
|
||||
}
|
||||
}
|
||||
catch (error) {
|
||||
reject(error);
|
||||
}
|
||||
}
|
||||
module.exports = Promise;
|
||||
|
||||
});
|
||||
require.alias("calvinmetcalf-setImmediate/lib/index.js", "lie/deps/immediate/lib/index.js");
|
||||
require.alias("calvinmetcalf-setImmediate/lib/nextTick.js", "lie/deps/immediate/lib/nextTick.js");
|
||||
require.alias("calvinmetcalf-setImmediate/lib/postMessage.js", "lie/deps/immediate/lib/postMessage.js");
|
||||
require.alias("calvinmetcalf-setImmediate/lib/messageChannel.js", "lie/deps/immediate/lib/messageChannel.js");
|
||||
require.alias("calvinmetcalf-setImmediate/lib/stateChange.js", "lie/deps/immediate/lib/stateChange.js");
|
||||
require.alias("calvinmetcalf-setImmediate/lib/timeout.js", "lie/deps/immediate/lib/timeout.js");
|
||||
require.alias("calvinmetcalf-setImmediate/lib/global.js", "lie/deps/immediate/lib/global.js");
|
||||
require.alias("calvinmetcalf-setImmediate/lib/mutation.js", "lie/deps/immediate/lib/mutation.js");
|
||||
require.alias("calvinmetcalf-setImmediate/lib/index.js", "lie/deps/immediate/index.js");
|
||||
require.alias("calvinmetcalf-setImmediate/lib/index.js", "immediate/index.js");
|
||||
require.alias("calvinmetcalf-setImmediate/lib/index.js", "calvinmetcalf-setImmediate/index.js");
|
||||
|
||||
require.alias("lie/lie.js", "lie/index.js");
|
||||
|
||||
L.Util.Promise = require("lie");
|
||||
})();
|
||||
|
||||
L.Util.ajax = function(url, options) {
|
||||
'use strict';
|
||||
options = options || {};
|
||||
if (options.jsonp) {
|
||||
return L.Util.ajax.jsonp(url, options);
|
||||
}
|
||||
var request;
|
||||
var cancel;
|
||||
var out = L.Util.Promise(function(resolve,reject){
|
||||
var Ajax;
|
||||
cancel=reject;
|
||||
// the following is from JavaScript: The Definitive Guide
|
||||
if (window.XMLHttpRequest === undefined) {
|
||||
Ajax = function() {
|
||||
try {
|
||||
return new ActiveXObject('Microsoft.XMLHTTP.6.0');
|
||||
}
|
||||
catch (e1) {
|
||||
try {
|
||||
return new ActiveXObject('Microsoft.XMLHTTP.3.0');
|
||||
}
|
||||
catch (e2) {
|
||||
reject('XMLHttpRequest is not supported');
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
else {
|
||||
Ajax = window.XMLHttpRequest;
|
||||
}
|
||||
var response;
|
||||
request = new Ajax();
|
||||
request.open('GET', url);
|
||||
request.onreadystatechange = function() {
|
||||
/*jslint evil: true */
|
||||
if (request.readyState === 4) {
|
||||
if((request.status < 400&&options.local)|| request.status===200) {
|
||||
if (window.JSON) {
|
||||
response = JSON.parse(request.responseText);
|
||||
} else if (options.evil) {
|
||||
response = eval('(' + request.responseText + ')');
|
||||
}
|
||||
resolve(response);
|
||||
} else {
|
||||
if(!request.status){
|
||||
reject('Attempted cross origin request without CORS enabled');
|
||||
}else{
|
||||
reject(request.statusText);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
request.send();
|
||||
});
|
||||
out.then(null,function(reason){
|
||||
request.abort();
|
||||
return reason;
|
||||
});
|
||||
out.abort = cancel;
|
||||
return out;
|
||||
};
|
||||
|
||||
L.Util.jsonp = function(url, options) {
|
||||
options = options || {};
|
||||
var head = document.getElementsByTagName('head')[0];
|
||||
var scriptNode = L.DomUtil.create('script', '', head);
|
||||
var cbName, ourl, cbSuffix, cancel;
|
||||
var out = L.Util.Promise(function(resolve, reject){
|
||||
cancel=reject;
|
||||
var cbParam = options.cbParam || 'callback';
|
||||
if (options.callbackName) {
|
||||
cbName = options.callbackName;
|
||||
}
|
||||
else {
|
||||
cbSuffix = '_' + ('' + Math.random()).slice(2);
|
||||
cbName = 'L.Util.jsonp.cb.' + cbSuffix;
|
||||
}
|
||||
scriptNode.type = 'text/javascript';
|
||||
if (cbSuffix) {
|
||||
L.Util.jsonp.cb[cbSuffix] = function(data) {
|
||||
head.removeChild(scriptNode);
|
||||
delete L.Util.jsonp.cb[cbSuffix];
|
||||
resolve(data);
|
||||
};
|
||||
}
|
||||
if (url.indexOf('?') === -1) {
|
||||
ourl = url + '?' + cbParam + '=' + cbName;
|
||||
}
|
||||
else {
|
||||
ourl = url + '&' + cbParam + '=' + cbName;
|
||||
}
|
||||
scriptNode.src = ourl;
|
||||
}).then(null,function(reason){
|
||||
head.removeChild(scriptNode);
|
||||
delete L.Util.ajax.cb[cbSuffix];
|
||||
return reason;
|
||||
});
|
||||
out.abort = cancel;
|
||||
return out;
|
||||
};
|
||||
L.Util.jsonp.cb = {};
|
||||
|
||||
L.GeoJSON.AJAX = L.GeoJSON.extend({
|
||||
defaultAJAXparams: {
|
||||
dataType: 'json',
|
||||
callbackParam: 'callback',
|
||||
local:false,
|
||||
middleware: function(f) {
|
||||
return f;
|
||||
}
|
||||
},
|
||||
initialize: function(url, options) {
|
||||
|
||||
this.urls = [];
|
||||
if (url) {
|
||||
if (typeof url === 'string') {
|
||||
this.urls.push(url);
|
||||
}
|
||||
else if (typeof url.pop === 'function') {
|
||||
this.urls = this.urls.concat(url);
|
||||
}
|
||||
else {
|
||||
options = url;
|
||||
url = undefined;
|
||||
}
|
||||
}
|
||||
var ajaxParams = L.Util.extend({}, this.defaultAJAXparams);
|
||||
|
||||
for (var i in options) {
|
||||
if (this.defaultAJAXparams.hasOwnProperty(i)) {
|
||||
ajaxParams[i] = options[i];
|
||||
}
|
||||
}
|
||||
this.ajaxParams = ajaxParams;
|
||||
this._layers = {};
|
||||
L.Util.setOptions(this, options);
|
||||
this.on('data:loaded', function() {
|
||||
if (this.filter) {
|
||||
this.refilter(this.filter);
|
||||
}
|
||||
}, this);
|
||||
var self = this;
|
||||
if (this.urls.length > 0) {
|
||||
L.Util.Promise(function(yes){
|
||||
yes();
|
||||
}).then(function(){
|
||||
self.addUrl();
|
||||
});
|
||||
}
|
||||
},
|
||||
clearLayers: function() {
|
||||
this.urls = [];
|
||||
L.GeoJSON.prototype.clearLayers.call(this);
|
||||
return this;
|
||||
},
|
||||
addUrl: function(url) {
|
||||
var self = this;
|
||||
if (url) {
|
||||
if (typeof url === 'string') {
|
||||
self.urls.push(url);
|
||||
}
|
||||
else if (typeof url.pop === 'function') {
|
||||
self.urls = self.urls.concat(url);
|
||||
}
|
||||
}
|
||||
var loading = self.urls.length;
|
||||
var done = 0;
|
||||
self.fire('data:loading');
|
||||
self.urls.forEach(function(url) {
|
||||
if (self.ajaxParams.dataType.toLowerCase() === 'json') {
|
||||
L.Util.ajax(url,self.ajaxParams).then(function(d) {
|
||||
var data = self.ajaxParams.middleware(d);
|
||||
self.addData(data);
|
||||
self.fire('data:progress',data);
|
||||
},function(err){
|
||||
self.fire('data:progress',{error:err});
|
||||
});
|
||||
}
|
||||
else if (self.ajaxParams.dataType.toLowerCase() === 'jsonp') {
|
||||
L.Util.jsonp(url,self.ajaxParams).then(function(d) {
|
||||
var data = self.ajaxParams.middleware(d);
|
||||
self.addData(data);
|
||||
self.fire('data:progress',data);
|
||||
},function(err){
|
||||
self.fire('data:progress',{error:err});
|
||||
});
|
||||
}
|
||||
});
|
||||
self.on('data:progress', function() {
|
||||
if (++done === loading) {
|
||||
self.fire('data:loaded');
|
||||
}
|
||||
});
|
||||
},
|
||||
refresh: function(url) {
|
||||
url = url || this.urls;
|
||||
this.clearLayers();
|
||||
this.addUrl(url);
|
||||
},
|
||||
refilter: function(func) {
|
||||
if (typeof func !== 'function') {
|
||||
this.filter = false;
|
||||
this.eachLayer(function(a) {
|
||||
a.setStyle({
|
||||
stroke: true,
|
||||
clickable: true
|
||||
});
|
||||
});
|
||||
}
|
||||
else {
|
||||
this.filter = func;
|
||||
this.eachLayer(function(a) {
|
||||
|
||||
if (func(a.feature)) {
|
||||
a.setStyle({
|
||||
stroke: true,
|
||||
clickable: true
|
||||
});
|
||||
}
|
||||
else {
|
||||
a.setStyle({
|
||||
stroke: false,
|
||||
clickable: false
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
L.geoJson.ajax = function(geojson, options) {
|
||||
return new L.GeoJSON.AJAX(geojson, options);
|
||||
};
|
||||
1
assets/libs/leaflet-ajax/leaflet.ajax.min.js
vendored
Normal file
7
assets/libs/leaflet-ajax/license.md
Normal file
@@ -0,0 +1,7 @@
|
||||
#Copyright (c) 2012-2013 Calvin Metcalf
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
|
||||
_THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE._
|
||||
29
assets/libs/leaflet-ajax/package.json
Normal file
@@ -0,0 +1,29 @@
|
||||
{
|
||||
"name": "leaflet.ajax",
|
||||
"version": "1.1.0",
|
||||
"description": "AJAX and JSONP in Leaflet",
|
||||
"main": "dist/leaflet.ajax.js",
|
||||
"directories": {
|
||||
"example": "example"
|
||||
},
|
||||
"devDependencies": {
|
||||
"grunt": "~0.4.1",
|
||||
"grunt-contrib-concat": "~0.3.0",
|
||||
"grunt-contrib-uglify": "~0.2.4",
|
||||
"grunt-contrib-jshint": "~0.6.4"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git://github.com/calvinmetcalf/leaflet-ajax.git"
|
||||
},
|
||||
"keywords": [
|
||||
"leaflet",
|
||||
"ajax",
|
||||
"geojson"
|
||||
],
|
||||
"author": "Calvin Metcalf",
|
||||
"license": "MIT",
|
||||
"bugs": {
|
||||
"url": "https://github.com/calvinmetcalf/leaflet-ajax/issues"
|
||||
}
|
||||
}
|
||||
10
assets/libs/leaflet-providers/CONTRIBUTING.md
Normal file
@@ -0,0 +1,10 @@
|
||||
So you want to add a layer?
|
||||
=======
|
||||
|
||||
Yay! go add it to the leaflet-providers.js as long as it follows the following
|
||||
rules:
|
||||
|
||||
- Don't violate a providers TOS (if it exists, include a link to it)
|
||||
- Don't pre-populate api keys with working keys.
|
||||
- It should be a basic tile source, no exteral libraries etc.
|
||||
- The owner hasn't asked us to remove it (hasn't happened yet)
|
||||
63
assets/libs/leaflet-providers/README.md
Normal file
@@ -0,0 +1,63 @@
|
||||
Leaflet-providers
|
||||
=================
|
||||
An extension to [Leaflet](http://leafletjs.com/) that contains configurations for various free tile providers.
|
||||
|
||||
# Usage
|
||||
Leaflet-providers [providers](#providers) are refered to with a `provider[.<variant>]`-string. Let's say you want to add the nice [Watercolor](http://maps.stamen.com/#watercolor/) style from Stamen to your map, you pass `Stamen.Watercolor` to the `L.tileLayer.provider`-constructor, which will return a [L.TileLayer](http://leafletjs.com/reference.html#tilelayer) instance for Stamens Watercolor tile layer.
|
||||
|
||||
```Javascript
|
||||
// add Stamen Watercolor to map.
|
||||
L.tileLayer.provider('Stamen.Watercolor').addTo(map);
|
||||
```
|
||||
|
||||
# Providers
|
||||
|
||||
Leaflet-providers provides tile layers from different providers, including *OpenStreetMap*, *MapQuestOpen*, *Stamen*, *Esri* and *OpenWeatherMap*. The full listing of free to use layers can be [previewed](http://leaflet-extras.github.io/leaflet-providers/preview/index.html). The page will show you the name to use with `leaflet-providers.js` and the code to use it without dependencies.
|
||||
|
||||
## Providers requiring registration
|
||||
|
||||
In addition to the providers you are free to use, we support some layers which require registration.
|
||||
|
||||
### HERE (formerly Nokia).
|
||||
|
||||
In order to use HERE basemaps, you must [register](http://developer.here.com/get-started). With your `app_id` and `app_code` specified in the options. The available layers are:
|
||||
|
||||
* HERE.normalDay
|
||||
* HERE.normalGreyDay
|
||||
* HERE.satelliteNoLabelsDay
|
||||
* HERE.satelliteYesLabelsDay
|
||||
* HERE.terrainDay
|
||||
|
||||
For example:
|
||||
```Javascript
|
||||
L.tileLayer.provider('HERE.terrainDay', {
|
||||
app_id: 'insert ID here',
|
||||
app_code: 'insert ID here'
|
||||
}).addTo(map);
|
||||
```
|
||||
|
||||
### Mapbox
|
||||
|
||||
In order to use Mapbox maps, you must [register](https://tiles.mapbox.com/signup). If your user name is `YourName` and your map is called `MyMap` you can add it with
|
||||
```JavaScript
|
||||
L.tileLayer.provider('MapBox.YourName.MyMap');
|
||||
```
|
||||
|
||||
### Esri/ArcGIS
|
||||
|
||||
In order to use ArcGIS maps, you must [register](https://developers.arcgis.com/en/sign-up/) and abide by the [terms of service](https://developers.arcgis.com/en/terms/). Available layers are...
|
||||
|
||||
* Esri.WorldStreetMap
|
||||
* Esri.DeLorme
|
||||
* Esri.WorldTopoMap
|
||||
* Esri.WorldImagery
|
||||
* Esri.WorldTerrain
|
||||
* Esri.WorldShadedRelief
|
||||
* Esri.WorldPhysical
|
||||
* Esri.OceanBasemap
|
||||
* Esri.NatGeoWorldMap
|
||||
* Esri.WorldGrayCanvas
|
||||
|
||||
# Attribution
|
||||
|
||||
This work was inspired from <https://gist.github.com/1804938>, and originally created by [Stefan Seelmann](https://github.com/seelmann).
|
||||
22
assets/libs/leaflet-providers/bower.json
Normal file
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"name": "leaflet-providers",
|
||||
"version": "1.0.12",
|
||||
"homepage": "https://github.com/leaflet-extras/leaflet-providers",
|
||||
"description": "An extension to Leaflet that contains configurations for various free tile providers.",
|
||||
"main": "leaflet-providers.js",
|
||||
"keywords": [
|
||||
"leaflet",
|
||||
"stamen",
|
||||
"osm"
|
||||
],
|
||||
"license": "BSD-2-Clause",
|
||||
"ignore": [
|
||||
"**/.*",
|
||||
"node_modules",
|
||||
"bower_components",
|
||||
"test",
|
||||
"tests",
|
||||
"preview",
|
||||
"*.html"
|
||||
]
|
||||
}
|
||||
97
assets/libs/leaflet-providers/index.html
Normal file
@@ -0,0 +1,97 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<title>Leaflet Provider Demo</title>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
||||
<!-- Leaflet style. REQUIRED! -->
|
||||
<link rel="stylesheet" href="http://cdn.leafletjs.com/leaflet-0.7/leaflet.css" />
|
||||
<style>
|
||||
html { height: 100% }
|
||||
body { height: 100%; margin: 0; padding: 0;}
|
||||
.map { height: 100% }
|
||||
</style>
|
||||
<!--Fork Me on Github ribbon, we're using the awsome version from simonwhitaker available at https://github.com/simonwhitaker/github-fork-ribbon-css -->
|
||||
<link rel="stylesheet" href="css/gh-fork-ribbon.css" />
|
||||
<!--[if IE]>
|
||||
<link rel="stylesheet" href="css/gh-fork-ribbon.ie.css" />
|
||||
<![endif]-->
|
||||
</head>
|
||||
<body>
|
||||
<div class="github-fork-ribbon-wrapper left">
|
||||
<div class="github-fork-ribbon">
|
||||
<a href="https://github.com/leaflet-extras/leaflet-providers">Fork me on GitHub</a>
|
||||
</div>
|
||||
</div>
|
||||
<div id="map" class="map"></div>
|
||||
|
||||
<script src="http://cdn.leafletjs.com/leaflet-0.7/leaflet-src.js"></script>
|
||||
<script src="leaflet-providers.js"></script>
|
||||
<script>
|
||||
var map = L.map('map', {
|
||||
center: [48, -3],
|
||||
zoom: 5,
|
||||
zoomControl: false
|
||||
});
|
||||
|
||||
var defaultLayer = L.tileLayer.provider('OpenStreetMap.Mapnik').addTo(map);
|
||||
|
||||
var baseLayers = {
|
||||
'OpenStreetMap Default': defaultLayer,
|
||||
'OpenStreetMap German Style': L.tileLayer.provider('OpenStreetMap.DE'),
|
||||
'OpenStreetMap Black and White': L.tileLayer.provider('OpenStreetMap.BlackAndWhite'),
|
||||
'OpenStreetMap H.O.T.': L.tileLayer.provider('OpenStreetMap.HOT'),
|
||||
'Thunderforest OpenCycleMap': L.tileLayer.provider('Thunderforest.OpenCycleMap'),
|
||||
'Thunderforest Transport': L.tileLayer.provider('Thunderforest.Transport'),
|
||||
'Thunderforest Landscape': L.tileLayer.provider('Thunderforest.Landscape'),
|
||||
'Hydda Full': L.tileLayer.provider('Hydda.Full'),
|
||||
'MapQuest OSM': L.tileLayer.provider('MapQuestOpen.OSM'),
|
||||
'MapQuest Aerial': L.tileLayer.provider('MapQuestOpen.Aerial'),
|
||||
'MapBox Example': L.tileLayer.provider('MapBox.examples.map-zr0njcqy'),
|
||||
'Stamen Toner': L.tileLayer.provider('Stamen.Toner'),
|
||||
'Stamen Terrain': L.tileLayer.provider('Stamen.Terrain'),
|
||||
'Stamen Watercolor': L.tileLayer.provider('Stamen.Watercolor'),
|
||||
'Esri WorldStreetMap': L.tileLayer.provider('Esri.WorldStreetMap'),
|
||||
'Esri DeLorme': L.tileLayer.provider('Esri.DeLorme'),
|
||||
'Esri WorldTopoMap': L.tileLayer.provider('Esri.WorldTopoMap'),
|
||||
'Esri WorldImagery': L.tileLayer.provider('Esri.WorldImagery'),
|
||||
'Esri WorldTerrain': L.tileLayer.provider('Esri.WorldTerrain'),
|
||||
'Esri WorldShadedRelief': L.tileLayer.provider('Esri.WorldShadedRelief'),
|
||||
'Esri WorldPhysical': L.tileLayer.provider('Esri.WorldPhysical'),
|
||||
'Esri OceanBasemap': L.tileLayer.provider('Esri.OceanBasemap'),
|
||||
'Esri NatGeoWorldMap': L.tileLayer.provider('Esri.NatGeoWorldMap'),
|
||||
'Esri WorldGrayCanvas': L.tileLayer.provider('Esri.WorldGrayCanvas'),
|
||||
'Acetate': L.tileLayer.provider('Acetate')
|
||||
};
|
||||
|
||||
var overlayLayers = {
|
||||
'OpenSeaMap': L.tileLayer.provider('OpenSeaMap'),
|
||||
'OpenWeatherMap Clouds': L.tileLayer.provider('OpenWeatherMap.Clouds'),
|
||||
'OpenWeatherMap CloudsClassic': L.tileLayer.provider('OpenWeatherMap.CloudsClassic'),
|
||||
'OpenWeatherMap Precipitation': L.tileLayer.provider('OpenWeatherMap.Precipitation'),
|
||||
'OpenWeatherMap PrecipitationClassic': L.tileLayer.provider('OpenWeatherMap.PrecipitationClassic'),
|
||||
'OpenWeatherMap Rain': L.tileLayer.provider('OpenWeatherMap.Rain'),
|
||||
'OpenWeatherMap RainClassic': L.tileLayer.provider('OpenWeatherMap.RainClassic'),
|
||||
'OpenWeatherMap Pressure': L.tileLayer.provider('OpenWeatherMap.Pressure'),
|
||||
'OpenWeatherMap PressureContour': L.tileLayer.provider('OpenWeatherMap.PressureContour'),
|
||||
'OpenWeatherMap Wind': L.tileLayer.provider('OpenWeatherMap.Wind'),
|
||||
'OpenWeatherMap Temperature': L.tileLayer.provider('OpenWeatherMap.Temperature'),
|
||||
'OpenWeatherMap Snow': L.tileLayer.provider('OpenWeatherMap.Snow')
|
||||
};
|
||||
|
||||
var layerControl = L.control.layers(baseLayers, overlayLayers, {collapsed: false}).addTo(map);
|
||||
|
||||
// resize layers control to fit into view.
|
||||
function resizeLayerControl() {
|
||||
var layerControlHeight = document.body.clientHeight - (10 + 50);
|
||||
var layerControl = document.getElementsByClassName('leaflet-control-layers-expanded')[0];
|
||||
|
||||
layerControl.style.overflowY = 'auto';
|
||||
layerControl.style.maxHeight = layerControlHeight + 'px';
|
||||
}
|
||||
map.on('resize', resizeLayerControl);
|
||||
resizeLayerControl();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
460
assets/libs/leaflet-providers/leaflet-providers.js
Normal file
@@ -0,0 +1,460 @@
|
||||
(function () {
|
||||
'use strict';
|
||||
|
||||
L.TileLayer.Provider = L.TileLayer.extend({
|
||||
initialize: function (arg, options) {
|
||||
var providers = L.TileLayer.Provider.providers;
|
||||
|
||||
var parts = arg.split('.');
|
||||
|
||||
var providerName = parts[0];
|
||||
var variantName = parts[1];
|
||||
|
||||
if (!providers[providerName]) {
|
||||
throw 'No such provider (' + providerName + ')';
|
||||
}
|
||||
|
||||
var provider = {
|
||||
url: providers[providerName].url,
|
||||
options: providers[providerName].options
|
||||
};
|
||||
|
||||
// overwrite values in provider from variant.
|
||||
if (variantName && 'variants' in providers[providerName]) {
|
||||
if (!(variantName in providers[providerName].variants)) {
|
||||
throw 'No such variant of ' + providerName + ' (' + variantName + ')';
|
||||
}
|
||||
var variant = providers[providerName].variants[variantName];
|
||||
var variantOptions;
|
||||
if (typeof variant === 'string') {
|
||||
variantOptions = {
|
||||
variant: variant
|
||||
};
|
||||
} else {
|
||||
variantOptions = variant.options;
|
||||
}
|
||||
provider = {
|
||||
url: variant.url || provider.url,
|
||||
options: L.Util.extend({}, provider.options, variantOptions)
|
||||
};
|
||||
} else if (typeof provider.url === 'function') {
|
||||
provider.url = provider.url(parts.splice(1, parts.length - 1).join('.'));
|
||||
}
|
||||
|
||||
// replace attribution placeholders with their values from toplevel provider attribution,
|
||||
// recursively
|
||||
var attributionReplacer = function (attr) {
|
||||
if (attr.indexOf('{attribution.') === -1) {
|
||||
return attr;
|
||||
}
|
||||
return attr.replace(/\{attribution.(\w*)\}/,
|
||||
function (match, attributionName) {
|
||||
return attributionReplacer(providers[attributionName].options.attribution);
|
||||
}
|
||||
);
|
||||
};
|
||||
provider.options.attribution = attributionReplacer(provider.options.attribution);
|
||||
|
||||
// Compute final options combining provider options with any user overrides
|
||||
var layerOpts = L.Util.extend({}, provider.options, options);
|
||||
L.TileLayer.prototype.initialize.call(this, provider.url, layerOpts);
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Definition of providers.
|
||||
* see http://leafletjs.com/reference.html#tilelayer for options in the options map.
|
||||
*/
|
||||
|
||||
//jshint maxlen:220
|
||||
L.TileLayer.Provider.providers = {
|
||||
OpenStreetMap: {
|
||||
url: 'http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png',
|
||||
options: {
|
||||
attribution:
|
||||
'© <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a>'
|
||||
},
|
||||
variants: {
|
||||
Mapnik: {},
|
||||
BlackAndWhite: {
|
||||
url: 'http://{s}.tiles.wmflabs.org/bw-mapnik/{z}/{x}/{y}.png'
|
||||
},
|
||||
DE: {
|
||||
url: 'http://{s}.tile.openstreetmap.de/tiles/osmde/{z}/{x}/{y}.png'
|
||||
},
|
||||
HOT: {
|
||||
url: 'http://{s}.tile.openstreetmap.fr/hot/{z}/{x}/{y}.png',
|
||||
options: {
|
||||
attribution: '{attribution.OpenStreetMap}, Tiles courtesy of <a href="http://hot.openstreetmap.org/" target="_blank">Humanitarian OpenStreetMap Team</a>'
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
OpenSeaMap: {
|
||||
url: 'http://tiles.openseamap.org/seamark/{z}/{x}/{y}.png',
|
||||
options: {
|
||||
attribution: 'Map data: © <a href="http://www.openseamap.org">OpenSeaMap</a> contributors'
|
||||
}
|
||||
},
|
||||
Thunderforest: {
|
||||
url: 'http://{s}.tile.thunderforest.com/{variant}/{z}/{x}/{y}.png',
|
||||
options: {
|
||||
attribution:
|
||||
'© <a href="http://www.opencyclemap.org">OpenCycleMap</a>, {attribution.OpenStreetMap}',
|
||||
variant: 'cycle'
|
||||
},
|
||||
variants: {
|
||||
OpenCycleMap: 'cycle',
|
||||
Transport: 'transport',
|
||||
Landscape: 'landscape',
|
||||
Outdoors: 'outdoors'
|
||||
}
|
||||
},
|
||||
OpenMapSurfer: {
|
||||
url: 'http://openmapsurfer.uni-hd.de/tiles/{variant}/x={x}&y={y}&z={z}',
|
||||
options: {
|
||||
minZoom: 0,
|
||||
maxZoom: 20,
|
||||
variant: 'roads',
|
||||
attribution: 'Imagery from <a href="http://giscience.uni-hd.de/">GIScience Research Group @ University of Heidelberg</a> — Map data {attribution.OpenStreetMap}'
|
||||
},
|
||||
variants: {
|
||||
Roads: 'roads',
|
||||
AdminBounds: {
|
||||
options: {
|
||||
variant: 'adminb',
|
||||
maxZoom: 19
|
||||
}
|
||||
},
|
||||
Grayscale: {
|
||||
options: {
|
||||
variant: 'roadsg',
|
||||
maxZoom: 19
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
Hydda: {
|
||||
url: 'http://{s}.tile.openstreetmap.se/hydda/{variant}/{z}/{x}/{y}.png',
|
||||
options: {
|
||||
minZoom: 0,
|
||||
maxZoom: 18,
|
||||
variant: 'full',
|
||||
attribution: 'Tiles courtesy of <a href="http://openstreetmap.se/" target="_blank">OpenStreetMap Sweden</a> — Map data {attribution.OpenStreetMap}'
|
||||
},
|
||||
variants: {
|
||||
Full: 'full',
|
||||
Base: 'base',
|
||||
RoadsAndLabels: 'roads_and_labels',
|
||||
}
|
||||
},
|
||||
MapQuestOpen: {
|
||||
url: 'http://otile{s}.mqcdn.com/tiles/1.0.0/map/{z}/{x}/{y}.jpeg',
|
||||
options: {
|
||||
attribution:
|
||||
'Tiles Courtesy of <a href="http://www.mapquest.com/">MapQuest</a> — ' +
|
||||
'Map data {attribution.OpenStreetMap}',
|
||||
subdomains: '1234'
|
||||
},
|
||||
variants: {
|
||||
OSM: {},
|
||||
Aerial: {
|
||||
url: 'http://oatile{s}.mqcdn.com/tiles/1.0.0/sat/{z}/{x}/{y}.jpg',
|
||||
options: {
|
||||
attribution:
|
||||
'Tiles Courtesy of <a href="http://www.mapquest.com/">MapQuest</a> — ' +
|
||||
'Portions Courtesy NASA/JPL-Caltech and U.S. Depart. of Agriculture, Farm Service Agency'
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
MapBox: {
|
||||
url: function (id) {
|
||||
return 'http://{s}.tiles.mapbox.com/v3/' + id + '/{z}/{x}/{y}.png';
|
||||
},
|
||||
options: {
|
||||
attribution:
|
||||
'Imagery from <a href="http://mapbox.com/about/maps/">MapBox</a> — ' +
|
||||
'Map data {attribution.OpenStreetMap}',
|
||||
subdomains: 'abcd'
|
||||
}
|
||||
},
|
||||
Stamen: {
|
||||
url: 'http://{s}.tile.stamen.com/{variant}/{z}/{x}/{y}.png',
|
||||
options: {
|
||||
attribution:
|
||||
'Map tiles by <a href="http://stamen.com">Stamen Design</a>, ' +
|
||||
'<a href="http://creativecommons.org/licenses/by/3.0">CC BY 3.0</a> — ' +
|
||||
'Map data {attribution.OpenStreetMap}',
|
||||
subdomains: 'abcd',
|
||||
minZoom: 0,
|
||||
maxZoom: 20,
|
||||
variant: 'toner'
|
||||
},
|
||||
variants: {
|
||||
Toner: 'toner',
|
||||
TonerBackground: 'toner-background',
|
||||
TonerHybrid: 'toner-hybrid',
|
||||
TonerLines: 'toner-lines',
|
||||
TonerLabels: 'toner-labels',
|
||||
TonerLite: 'toner-lite',
|
||||
Terrain: {
|
||||
options: {
|
||||
variant: 'terrain',
|
||||
minZoom: 4,
|
||||
maxZoom: 18
|
||||
}
|
||||
},
|
||||
TerrainBackground: {
|
||||
options: {
|
||||
variant: 'terrain-background',
|
||||
minZoom: 4,
|
||||
maxZoom: 18
|
||||
}
|
||||
},
|
||||
Watercolor: {
|
||||
options: {
|
||||
variant: 'watercolor',
|
||||
minZoom: 1,
|
||||
maxZoom: 16
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
Esri: {
|
||||
url: 'http://server.arcgisonline.com/ArcGIS/rest/services/{variant}/MapServer/tile/{z}/{y}/{x}',
|
||||
options: {
|
||||
variant: 'World_Street_Map',
|
||||
attribution: 'Tiles © Esri'
|
||||
},
|
||||
variants: {
|
||||
WorldStreetMap: {
|
||||
options: {
|
||||
attribution:
|
||||
'{attribution.Esri} — ' +
|
||||
'Source: Esri, DeLorme, NAVTEQ, USGS, Intermap, iPC, NRCAN, Esri Japan, METI, Esri China (Hong Kong), Esri (Thailand), TomTom, 2012'
|
||||
}
|
||||
},
|
||||
DeLorme: {
|
||||
options: {
|
||||
variant: 'Specialty/DeLorme_World_Base_Map',
|
||||
minZoom: 1,
|
||||
maxZoom: 11,
|
||||
attribution: '{attribution.Esri} — Copyright: ©2012 DeLorme'
|
||||
}
|
||||
},
|
||||
WorldTopoMap: {
|
||||
options: {
|
||||
variant: 'World_Topo_Map',
|
||||
attribution:
|
||||
'{attribution.Esri} — ' +
|
||||
'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'
|
||||
}
|
||||
},
|
||||
WorldImagery: {
|
||||
options: {
|
||||
variant: 'World_Imagery',
|
||||
attribution:
|
||||
'{attribution.Esri} — ' +
|
||||
'Source: Esri, i-cubed, USDA, USGS, AEX, GeoEye, Getmapping, Aerogrid, IGN, IGP, UPR-EGP, and the GIS User Community'
|
||||
}
|
||||
},
|
||||
WorldTerrain: {
|
||||
options: {
|
||||
variant: 'World_Terrain_Base',
|
||||
maxZoom: 13,
|
||||
attribution:
|
||||
'{attribution.Esri} — ' +
|
||||
'Source: USGS, Esri, TANA, DeLorme, and NPS'
|
||||
}
|
||||
},
|
||||
WorldShadedRelief: {
|
||||
options: {
|
||||
variant: 'World_Shaded_Relief',
|
||||
maxZoom: 13,
|
||||
attribution: '{attribution.Esri} — Source: Esri'
|
||||
}
|
||||
},
|
||||
WorldPhysical: {
|
||||
options: {
|
||||
variant: 'World_Physical_Map',
|
||||
maxZoom: 8,
|
||||
attribution: '{attribution.Esri} — Source: US National Park Service'
|
||||
}
|
||||
},
|
||||
OceanBasemap: {
|
||||
options: {
|
||||
variant: 'Ocean_Basemap',
|
||||
maxZoom: 13,
|
||||
attribution: '{attribution.Esri} — Sources: GEBCO, NOAA, CHS, OSU, UNH, CSUMB, National Geographic, DeLorme, NAVTEQ, and Esri'
|
||||
}
|
||||
},
|
||||
NatGeoWorldMap: {
|
||||
options: {
|
||||
variant: 'NatGeo_World_Map',
|
||||
maxZoom: 16,
|
||||
attribution: '{attribution.Esri} — National Geographic, Esri, DeLorme, NAVTEQ, UNEP-WCMC, USGS, NASA, ESA, METI, NRCAN, GEBCO, NOAA, iPC'
|
||||
}
|
||||
},
|
||||
WorldGrayCanvas: {
|
||||
options: {
|
||||
variant: 'Canvas/World_Light_Gray_Base',
|
||||
maxZoom: 16,
|
||||
attribution: '{attribution.Esri} — Esri, DeLorme, NAVTEQ'
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
OpenWeatherMap: {
|
||||
url: 'http://{s}.tile.openweathermap.org/map/{variant}/{z}/{x}/{y}.png',
|
||||
options: {
|
||||
attribution: 'Map data © <a href="http://openweathermap.org">OpenWeatherMap</a>',
|
||||
opacity: 0.5
|
||||
},
|
||||
variants: {
|
||||
Clouds: 'clouds',
|
||||
CloudsClassic: 'clouds_cls',
|
||||
Precipitation: 'precipitation',
|
||||
PrecipitationClassic: 'precipitation_cls',
|
||||
Rain: 'rain',
|
||||
RainClassic: 'rain_cls',
|
||||
Pressure: 'pressure',
|
||||
PressureContour: 'pressure_cntr',
|
||||
Wind: 'wind',
|
||||
Temperature: 'temp',
|
||||
Snow: 'snow'
|
||||
}
|
||||
},
|
||||
HERE: {
|
||||
/*
|
||||
* HERE maps, formerly Nokia maps.
|
||||
* These basemaps are free, but you need an API key. Please sign up at
|
||||
* http://developer.here.com/getting-started
|
||||
*
|
||||
* Note that the base urls contain '.cit' whichs is HERE's
|
||||
* 'Customer Integration Testing' environment. Please remove for production
|
||||
* envirionments.
|
||||
*/
|
||||
url:
|
||||
'http://{s}.{base}.maps.cit.api.here.com/maptile/2.1/' +
|
||||
'maptile/{mapID}/{variant}/{z}/{x}/{y}/256/png8?' +
|
||||
'app_id={app_id}&app_code={app_code}',
|
||||
options: {
|
||||
attribution:
|
||||
'Map © 1987-2014 <a href="http://developer.here.com">HERE</a>',
|
||||
subdomains: '1234',
|
||||
mapID: 'newest',
|
||||
'app_id': '<insert your app_id here>',
|
||||
'app_code': '<insert your app_code here>',
|
||||
base: 'base',
|
||||
variant: 'normal.day',
|
||||
minZoom: 0,
|
||||
maxZoom: 20
|
||||
},
|
||||
variants: {
|
||||
normalDay: 'normal.day',
|
||||
normalDayCustom: 'normal.day.custom',
|
||||
normalDayGrey: 'normal.day.grey',
|
||||
normalDayMobile: 'normal.day.mobile',
|
||||
normalDayGreyMobile: 'normal.day.grey.mobile',
|
||||
normalDayTransit: 'normal.day.transit',
|
||||
normalDayTransitMobile: 'normal.day.transit.mobile',
|
||||
normalNight: 'normal.night',
|
||||
normalNightMobile: 'normal.night.mobile',
|
||||
normalNightGrey: 'normal.night.grey',
|
||||
normalNightGreyMobile: 'normal.night.grey.mobile',
|
||||
|
||||
carnavDayGrey: 'carnav.day.grey',
|
||||
hybridDay: {
|
||||
options: {
|
||||
base: 'aerial',
|
||||
variant: 'hybrid.day'
|
||||
}
|
||||
},
|
||||
hybridDayMobile: {
|
||||
options: {
|
||||
base: 'aerial',
|
||||
variant: 'hybrid.day.mobile'
|
||||
}
|
||||
},
|
||||
pedestrianDay: 'pedestrian.day',
|
||||
pedestrianNight: 'pedestrian.night',
|
||||
satelliteDay: {
|
||||
options: {
|
||||
base: 'aerial',
|
||||
variant: 'satellite.day'
|
||||
}
|
||||
},
|
||||
terrainDay: {
|
||||
options: {
|
||||
base: 'aerial',
|
||||
variant: 'terrain.day'
|
||||
}
|
||||
},
|
||||
terrainDayMobile: {
|
||||
options: {
|
||||
base: 'aerial',
|
||||
variant: 'terrain.day.mobile'
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
Acetate: {
|
||||
url: 'http://a{s}.acetate.geoiq.com/tiles/{variant}/{z}/{x}/{y}.png',
|
||||
options: {
|
||||
attribution:
|
||||
'©2012 Esri & Stamen, Data from OSM and Natural Earth',
|
||||
subdomains: '0123',
|
||||
minZoom: 2,
|
||||
maxZoom: 18,
|
||||
variant: 'acetate-base'
|
||||
},
|
||||
variants: {
|
||||
basemap: 'acetate-base',
|
||||
terrain: 'terrain',
|
||||
all: 'acetate-hillshading',
|
||||
foreground: 'acetate-fg',
|
||||
roads: 'acetate-roads',
|
||||
labels: 'acetate-labels',
|
||||
hillshading: 'hillshading'
|
||||
}
|
||||
},
|
||||
FreeMapSK: {
|
||||
url: 'http://{s}.freemap.sk/T/{z}/{x}/{y}.jpeg',
|
||||
options: {
|
||||
minZoom: 8,
|
||||
maxZoom: 16,
|
||||
subdomains: ['t1', 't2', 't3', 't4'],
|
||||
attribution:
|
||||
'{attribution.OpenStreetMap}, vizualization CC-By-SA 2.0 <a href="http://freemap.sk">Freemap.sk</a>'
|
||||
}
|
||||
},
|
||||
MtbMap: {
|
||||
url: 'http://tile.mtbmap.cz/mtbmap_tiles/{z}/{x}/{y}.png',
|
||||
options: {
|
||||
attribution:
|
||||
'{attribution.OpenStreetMap} & USGS'
|
||||
}
|
||||
},
|
||||
CartoDB: {
|
||||
url: 'http://{s}.basemaps.cartocdn.com/{variant}/{z}/{x}/{y}.png',
|
||||
options: {
|
||||
attribution: '{attribution.OpenStreetMap} © <a href="http://cartodb.com/attributions">CartoDB</a>',
|
||||
subdomains: 'abcd',
|
||||
minZoom: 0,
|
||||
maxZoom: 18,
|
||||
variant: 'light_all'
|
||||
},
|
||||
variants: {
|
||||
Positron: 'light_all',
|
||||
PositronNoLabels: 'light_nolabels',
|
||||
DarkMatter: 'dark_all',
|
||||
DarkMatterNoLabels: 'dark_nolabels'
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
L.tileLayer.provider = function (provider, options) {
|
||||
return new L.TileLayer.Provider(provider, options);
|
||||
};
|
||||
}());
|
||||
9
assets/libs/leaflet-providers/license.md
Normal file
@@ -0,0 +1,9 @@
|
||||
Copyright (c) 2013 Leaflet Providers contributors
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
|
||||
|
||||
_THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE._
|
||||
24
assets/libs/leaflet-providers/package.json
Normal file
@@ -0,0 +1,24 @@
|
||||
{
|
||||
"name": "leaflet-providers",
|
||||
"version": "1.0.12",
|
||||
"description": "An extension to Leaflet that contains configurations for various free tile providers.",
|
||||
"main": "leaflet-providers.js",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git://github.com/leaflet-extras/leaflet-providers.git"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "jshint leaflet-providers.js preview/*.js",
|
||||
"min": "uglifyjs leaflet-providers.js -mc -o leaflet-providers.min.js",
|
||||
"release": "mversion patch -m"
|
||||
},
|
||||
"license": "BSD-2-Clause",
|
||||
"bugs": {
|
||||
"url": "https://github.com/leaflet-extras/leaflet-providers/issues"
|
||||
},
|
||||
"devDependencies": {
|
||||
"jshint": "~2.1.11",
|
||||
"mversion": "^1.3.0",
|
||||
"uglify-js": "^2.4.15"
|
||||
}
|
||||
}
|
||||
BIN
assets/libs/leaflet/images/layers-2x.png
Normal file
|
After Width: | Height: | Size: 2.8 KiB |
BIN
assets/libs/leaflet/images/layers.png
Normal file
|
After Width: | Height: | Size: 1.5 KiB |
BIN
assets/libs/leaflet/images/marker-icon-2x.png
Normal file
|
After Width: | Height: | Size: 3.9 KiB |
BIN
assets/libs/leaflet/images/marker-icon.png
Normal file
|
After Width: | Height: | Size: 1.7 KiB |
BIN
assets/libs/leaflet/images/marker-shadow.png
Normal file
|
After Width: | Height: | Size: 797 B |
9180
assets/libs/leaflet/leaflet-src.js
Normal file
478
assets/libs/leaflet/leaflet.css
Normal file
@@ -0,0 +1,478 @@
|
||||
/* required styles */
|
||||
|
||||
.leaflet-map-pane,
|
||||
.leaflet-tile,
|
||||
.leaflet-marker-icon,
|
||||
.leaflet-marker-shadow,
|
||||
.leaflet-tile-pane,
|
||||
.leaflet-tile-container,
|
||||
.leaflet-overlay-pane,
|
||||
.leaflet-shadow-pane,
|
||||
.leaflet-marker-pane,
|
||||
.leaflet-popup-pane,
|
||||
.leaflet-overlay-pane svg,
|
||||
.leaflet-zoom-box,
|
||||
.leaflet-image-layer,
|
||||
.leaflet-layer {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
}
|
||||
.leaflet-container {
|
||||
overflow: hidden;
|
||||
-ms-touch-action: none;
|
||||
}
|
||||
.leaflet-tile,
|
||||
.leaflet-marker-icon,
|
||||
.leaflet-marker-shadow {
|
||||
-webkit-user-select: none;
|
||||
-moz-user-select: none;
|
||||
user-select: none;
|
||||
-webkit-user-drag: none;
|
||||
}
|
||||
.leaflet-marker-icon,
|
||||
.leaflet-marker-shadow {
|
||||
display: block;
|
||||
}
|
||||
/* map is broken in FF if you have max-width: 100% on tiles */
|
||||
.leaflet-container img {
|
||||
max-width: none !important;
|
||||
}
|
||||
/* stupid Android 2 doesn't understand "max-width: none" properly */
|
||||
.leaflet-container img.leaflet-image-layer {
|
||||
max-width: 15000px !important;
|
||||
}
|
||||
.leaflet-tile {
|
||||
filter: inherit;
|
||||
visibility: hidden;
|
||||
}
|
||||
.leaflet-tile-loaded {
|
||||
visibility: inherit;
|
||||
}
|
||||
.leaflet-zoom-box {
|
||||
width: 0;
|
||||
height: 0;
|
||||
}
|
||||
/* workaround for https://bugzilla.mozilla.org/show_bug.cgi?id=888319 */
|
||||
.leaflet-overlay-pane svg {
|
||||
-moz-user-select: none;
|
||||
}
|
||||
|
||||
.leaflet-tile-pane { z-index: 2; }
|
||||
.leaflet-objects-pane { z-index: 3; }
|
||||
.leaflet-overlay-pane { z-index: 4; }
|
||||
.leaflet-shadow-pane { z-index: 5; }
|
||||
.leaflet-marker-pane { z-index: 6; }
|
||||
.leaflet-popup-pane { z-index: 7; }
|
||||
|
||||
.leaflet-vml-shape {
|
||||
width: 1px;
|
||||
height: 1px;
|
||||
}
|
||||
.lvml {
|
||||
behavior: url(#default#VML);
|
||||
display: inline-block;
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
|
||||
/* control positioning */
|
||||
|
||||
.leaflet-control {
|
||||
position: relative;
|
||||
z-index: 7;
|
||||
pointer-events: auto;
|
||||
}
|
||||
.leaflet-top,
|
||||
.leaflet-bottom {
|
||||
position: absolute;
|
||||
z-index: 1000;
|
||||
pointer-events: none;
|
||||
}
|
||||
.leaflet-top {
|
||||
top: 0;
|
||||
}
|
||||
.leaflet-right {
|
||||
right: 0;
|
||||
}
|
||||
.leaflet-bottom {
|
||||
bottom: 0;
|
||||
}
|
||||
.leaflet-left {
|
||||
left: 0;
|
||||
}
|
||||
.leaflet-control {
|
||||
float: left;
|
||||
clear: both;
|
||||
}
|
||||
.leaflet-right .leaflet-control {
|
||||
float: right;
|
||||
}
|
||||
.leaflet-top .leaflet-control {
|
||||
margin-top: 10px;
|
||||
}
|
||||
.leaflet-bottom .leaflet-control {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
.leaflet-left .leaflet-control {
|
||||
margin-left: 10px;
|
||||
}
|
||||
.leaflet-right .leaflet-control {
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
|
||||
/* zoom and fade animations */
|
||||
|
||||
.leaflet-fade-anim .leaflet-tile,
|
||||
.leaflet-fade-anim .leaflet-popup {
|
||||
opacity: 0;
|
||||
-webkit-transition: opacity 0.2s linear;
|
||||
-moz-transition: opacity 0.2s linear;
|
||||
-o-transition: opacity 0.2s linear;
|
||||
transition: opacity 0.2s linear;
|
||||
}
|
||||
.leaflet-fade-anim .leaflet-tile-loaded,
|
||||
.leaflet-fade-anim .leaflet-map-pane .leaflet-popup {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.leaflet-zoom-anim .leaflet-zoom-animated {
|
||||
-webkit-transition: -webkit-transform 0.25s cubic-bezier(0,0,0.25,1);
|
||||
-moz-transition: -moz-transform 0.25s cubic-bezier(0,0,0.25,1);
|
||||
-o-transition: -o-transform 0.25s cubic-bezier(0,0,0.25,1);
|
||||
transition: transform 0.25s cubic-bezier(0,0,0.25,1);
|
||||
}
|
||||
.leaflet-zoom-anim .leaflet-tile,
|
||||
.leaflet-pan-anim .leaflet-tile,
|
||||
.leaflet-touching .leaflet-zoom-animated {
|
||||
-webkit-transition: none;
|
||||
-moz-transition: none;
|
||||
-o-transition: none;
|
||||
transition: none;
|
||||
}
|
||||
|
||||
.leaflet-zoom-anim .leaflet-zoom-hide {
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
|
||||
/* cursors */
|
||||
|
||||
.leaflet-clickable {
|
||||
cursor: pointer;
|
||||
}
|
||||
.leaflet-container {
|
||||
cursor: -webkit-grab;
|
||||
cursor: -moz-grab;
|
||||
}
|
||||
.leaflet-popup-pane,
|
||||
.leaflet-control {
|
||||
cursor: auto;
|
||||
}
|
||||
.leaflet-dragging .leaflet-container,
|
||||
.leaflet-dragging .leaflet-clickable {
|
||||
cursor: move;
|
||||
cursor: -webkit-grabbing;
|
||||
cursor: -moz-grabbing;
|
||||
}
|
||||
|
||||
|
||||
/* visual tweaks */
|
||||
|
||||
.leaflet-container {
|
||||
background: #ddd;
|
||||
outline: 0;
|
||||
}
|
||||
.leaflet-container a {
|
||||
color: #0078A8;
|
||||
}
|
||||
.leaflet-container a.leaflet-active {
|
||||
outline: 2px solid orange;
|
||||
}
|
||||
.leaflet-zoom-box {
|
||||
border: 2px dotted #38f;
|
||||
background: rgba(255,255,255,0.5);
|
||||
}
|
||||
|
||||
|
||||
/* general typography */
|
||||
.leaflet-container {
|
||||
font: 12px/1.5 "Helvetica Neue", Arial, Helvetica, sans-serif;
|
||||
}
|
||||
|
||||
|
||||
/* general toolbar styles */
|
||||
|
||||
.leaflet-bar {
|
||||
box-shadow: 0 1px 5px rgba(0,0,0,0.65);
|
||||
border-radius: 4px;
|
||||
}
|
||||
.leaflet-bar a,
|
||||
.leaflet-bar a:hover {
|
||||
background-color: #fff;
|
||||
border-bottom: 1px solid #ccc;
|
||||
width: 26px;
|
||||
height: 26px;
|
||||
line-height: 26px;
|
||||
display: block;
|
||||
text-align: center;
|
||||
text-decoration: none;
|
||||
color: black;
|
||||
}
|
||||
.leaflet-bar a,
|
||||
.leaflet-control-layers-toggle {
|
||||
background-position: 50% 50%;
|
||||
background-repeat: no-repeat;
|
||||
display: block;
|
||||
}
|
||||
.leaflet-bar a:hover {
|
||||
background-color: #f4f4f4;
|
||||
}
|
||||
.leaflet-bar a:first-child {
|
||||
border-top-left-radius: 4px;
|
||||
border-top-right-radius: 4px;
|
||||
}
|
||||
.leaflet-bar a:last-child {
|
||||
border-bottom-left-radius: 4px;
|
||||
border-bottom-right-radius: 4px;
|
||||
border-bottom: none;
|
||||
}
|
||||
.leaflet-bar a.leaflet-disabled {
|
||||
cursor: default;
|
||||
background-color: #f4f4f4;
|
||||
color: #bbb;
|
||||
}
|
||||
|
||||
.leaflet-touch .leaflet-bar a {
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
line-height: 30px;
|
||||
}
|
||||
|
||||
|
||||
/* zoom control */
|
||||
|
||||
.leaflet-control-zoom-in,
|
||||
.leaflet-control-zoom-out {
|
||||
font: bold 18px 'Lucida Console', Monaco, monospace;
|
||||
text-indent: 1px;
|
||||
}
|
||||
.leaflet-control-zoom-out {
|
||||
font-size: 20px;
|
||||
}
|
||||
|
||||
.leaflet-touch .leaflet-control-zoom-in {
|
||||
font-size: 22px;
|
||||
}
|
||||
.leaflet-touch .leaflet-control-zoom-out {
|
||||
font-size: 24px;
|
||||
}
|
||||
|
||||
|
||||
/* layers control */
|
||||
|
||||
.leaflet-control-layers {
|
||||
box-shadow: 0 1px 5px rgba(0,0,0,0.4);
|
||||
background: #fff;
|
||||
border-radius: 5px;
|
||||
}
|
||||
.leaflet-control-layers-toggle {
|
||||
background-image: url('images/layers.png');
|
||||
width: 36px;
|
||||
height: 36px;
|
||||
}
|
||||
.leaflet-retina .leaflet-control-layers-toggle {
|
||||
background-image: url('images/layers-2x.png');
|
||||
background-size: 26px 26px;
|
||||
}
|
||||
.leaflet-touch .leaflet-control-layers-toggle {
|
||||
width: 44px;
|
||||
height: 44px;
|
||||
}
|
||||
.leaflet-control-layers .leaflet-control-layers-list,
|
||||
.leaflet-control-layers-expanded .leaflet-control-layers-toggle {
|
||||
display: none;
|
||||
}
|
||||
.leaflet-control-layers-expanded .leaflet-control-layers-list {
|
||||
display: block;
|
||||
position: relative;
|
||||
}
|
||||
.leaflet-control-layers-expanded {
|
||||
padding: 6px 10px 6px 6px;
|
||||
color: #333;
|
||||
background: #fff;
|
||||
}
|
||||
.leaflet-control-layers-selector {
|
||||
margin-top: 2px;
|
||||
position: relative;
|
||||
top: 1px;
|
||||
}
|
||||
.leaflet-control-layers label {
|
||||
display: block;
|
||||
}
|
||||
.leaflet-control-layers-separator {
|
||||
height: 0;
|
||||
border-top: 1px solid #ddd;
|
||||
margin: 5px -10px 5px -6px;
|
||||
}
|
||||
|
||||
|
||||
/* attribution and scale controls */
|
||||
|
||||
.leaflet-container .leaflet-control-attribution {
|
||||
background: #fff;
|
||||
background: rgba(255, 255, 255, 0.7);
|
||||
margin: 0;
|
||||
}
|
||||
.leaflet-control-attribution,
|
||||
.leaflet-control-scale-line {
|
||||
padding: 0 5px;
|
||||
color: #333;
|
||||
}
|
||||
.leaflet-control-attribution a {
|
||||
text-decoration: none;
|
||||
}
|
||||
.leaflet-control-attribution a:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
.leaflet-container .leaflet-control-attribution,
|
||||
.leaflet-container .leaflet-control-scale {
|
||||
font-size: 11px;
|
||||
}
|
||||
.leaflet-left .leaflet-control-scale {
|
||||
margin-left: 5px;
|
||||
}
|
||||
.leaflet-bottom .leaflet-control-scale {
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
.leaflet-control-scale-line {
|
||||
border: 2px solid #777;
|
||||
border-top: none;
|
||||
line-height: 1.1;
|
||||
padding: 2px 5px 1px;
|
||||
font-size: 11px;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
-moz-box-sizing: content-box;
|
||||
box-sizing: content-box;
|
||||
|
||||
background: #fff;
|
||||
background: rgba(255, 255, 255, 0.5);
|
||||
}
|
||||
.leaflet-control-scale-line:not(:first-child) {
|
||||
border-top: 2px solid #777;
|
||||
border-bottom: none;
|
||||
margin-top: -2px;
|
||||
}
|
||||
.leaflet-control-scale-line:not(:first-child):not(:last-child) {
|
||||
border-bottom: 2px solid #777;
|
||||
}
|
||||
|
||||
.leaflet-touch .leaflet-control-attribution,
|
||||
.leaflet-touch .leaflet-control-layers,
|
||||
.leaflet-touch .leaflet-bar {
|
||||
box-shadow: none;
|
||||
}
|
||||
.leaflet-touch .leaflet-control-layers,
|
||||
.leaflet-touch .leaflet-bar {
|
||||
border: 2px solid rgba(0,0,0,0.2);
|
||||
background-clip: padding-box;
|
||||
}
|
||||
|
||||
|
||||
/* popup */
|
||||
|
||||
.leaflet-popup {
|
||||
position: absolute;
|
||||
text-align: center;
|
||||
}
|
||||
.leaflet-popup-content-wrapper {
|
||||
padding: 1px;
|
||||
text-align: left;
|
||||
border-radius: 12px;
|
||||
}
|
||||
.leaflet-popup-content {
|
||||
margin: 13px 19px;
|
||||
line-height: 1.4;
|
||||
}
|
||||
.leaflet-popup-content p {
|
||||
margin: 18px 0;
|
||||
}
|
||||
.leaflet-popup-tip-container {
|
||||
margin: 0 auto;
|
||||
width: 40px;
|
||||
height: 20px;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
.leaflet-popup-tip {
|
||||
width: 17px;
|
||||
height: 17px;
|
||||
padding: 1px;
|
||||
|
||||
margin: -10px auto 0;
|
||||
|
||||
-webkit-transform: rotate(45deg);
|
||||
-moz-transform: rotate(45deg);
|
||||
-ms-transform: rotate(45deg);
|
||||
-o-transform: rotate(45deg);
|
||||
transform: rotate(45deg);
|
||||
}
|
||||
.leaflet-popup-content-wrapper,
|
||||
.leaflet-popup-tip {
|
||||
background: white;
|
||||
|
||||
box-shadow: 0 3px 14px rgba(0,0,0,0.4);
|
||||
}
|
||||
.leaflet-container a.leaflet-popup-close-button {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
padding: 4px 4px 0 0;
|
||||
text-align: center;
|
||||
width: 18px;
|
||||
height: 14px;
|
||||
font: 16px/14px Tahoma, Verdana, sans-serif;
|
||||
color: #c3c3c3;
|
||||
text-decoration: none;
|
||||
font-weight: bold;
|
||||
background: transparent;
|
||||
}
|
||||
.leaflet-container a.leaflet-popup-close-button:hover {
|
||||
color: #999;
|
||||
}
|
||||
.leaflet-popup-scrolled {
|
||||
overflow: auto;
|
||||
border-bottom: 1px solid #ddd;
|
||||
border-top: 1px solid #ddd;
|
||||
}
|
||||
|
||||
.leaflet-oldie .leaflet-popup-content-wrapper {
|
||||
zoom: 1;
|
||||
}
|
||||
.leaflet-oldie .leaflet-popup-tip {
|
||||
width: 24px;
|
||||
margin: 0 auto;
|
||||
|
||||
-ms-filter: "progid:DXImageTransform.Microsoft.Matrix(M11=0.70710678, M12=0.70710678, M21=-0.70710678, M22=0.70710678)";
|
||||
filter: progid:DXImageTransform.Microsoft.Matrix(M11=0.70710678, M12=0.70710678, M21=-0.70710678, M22=0.70710678);
|
||||
}
|
||||
.leaflet-oldie .leaflet-popup-tip-container {
|
||||
margin-top: -1px;
|
||||
}
|
||||
|
||||
.leaflet-oldie .leaflet-control-zoom,
|
||||
.leaflet-oldie .leaflet-control-layers,
|
||||
.leaflet-oldie .leaflet-popup-content-wrapper,
|
||||
.leaflet-oldie .leaflet-popup-tip {
|
||||
border: 1px solid #999;
|
||||
}
|
||||
|
||||
|
||||
/* div icon */
|
||||
|
||||
.leaflet-div-icon {
|
||||
background: #fff;
|
||||
border: 1px solid #666;
|
||||
}
|
||||