Files
rogaining_srv/static/leaflet/leaflet.extras.js

257 lines
8.3 KiB
JavaScript

L.Control.ResetView = L.Control.extend({
statics: {
ICON: 'url(images/reset-view.png)',
TITLE: "Reset view"
},
options: {
position: 'topleft'
},
initialize: function (bounds, options) {
// Accept function as argument to bounds
this.getBounds = typeof(bounds) == 'function' ? bounds :
function () {
return bounds;
};
L.Util.setOptions(this, options);
},
onAdd: function (map) {
if (map.resetviewControl) {
map.removeControl(map.resetviewControl);
}
map.resetviewControl = this;
var container = L.DomUtil.create('div', 'leaflet-control-zoom leaflet-bar');
var link = L.DomUtil.create('a', 'leaflet-control-zoom-out leaflet-bar-part', container);
link.href = '#';
link.title = L.Control.ResetView.TITLE;
link.style.backgroundImage = L.Control.ResetView.ICON;
L.DomEvent.addListener(link, 'click', L.DomEvent.stopPropagation)
.addListener(link, 'click', L.DomEvent.preventDefault)
.addListener(link, 'click', L.Util.bind(function () {
map.fitBounds(this.getBounds());
}, this));
return container;
}
});
L.Map.DjangoMap = L.Map.extend({
initialize: function (id, options) {
// Merge compatible options
// (can be undefined)
var djoptions = options.djoptions;
options.zoom = djoptions.zoom;
options.center = djoptions.center;
if (!isNaN(parseInt(djoptions.minzoom, 10)))
options.minZoom = djoptions.minzoom;
if (!isNaN(parseInt(djoptions.maxzoom, 10)))
options.maxZoom = djoptions.maxzoom;
// Translate to native options
options = L.Util.extend(options,
this._projectionOptions(djoptions));
if (djoptions.extent) {
options.maxBounds = djoptions.extent;
}
L.Map.prototype.initialize.call(this, id, options);
this._djAddLayers();
this._djSetupControls();
if (djoptions.fitextent && djoptions.extent && !(djoptions.center || djoptions.zoom)) {
this.fitBounds(options.maxBounds);
}
},
_projectionOptions: function (djoptions) {
if (!djoptions.srid)
return {};
var projopts = {};
var bbox = djoptions.tilesextent,
maxResolution = computeMaxResolution(bbox);
// See https://github.com/ajashton/TileCache/blob/master/tilecache/TileCache/Layer.py#L197
var resolutions = [];
for (var z = 0; z < 20; z++) {
resolutions.push(maxResolution / Math.pow(2, z));
}
if (L.CRS['EPSG' + djoptions.srid] !== undefined) {
var crs = L.CRS['EPSG' + djoptions.srid];
} else {
var crs = new L.Proj.CRS('EPSG:' + djoptions.srid,
proj4.defs['EPSG:' + djoptions.srid],
{
origin: [bbox[0], bbox[3]],
resolutions: resolutions
}
);
}
return {
crs: crs,
scale: crs.scale,
continuousWorld: true
};
function computeMaxResolution(bbox) {
// See https://github.com/ajashton/TileCache/blob/master/tilecache/TileCache/Layer.py#L185-L196
var size = 256,
width = bbox[2] - bbox[0],
height = bbox[3] - bbox[1];
var aspect = Math.floor(Math.max(width, height) / Math.min(width, height) + 0.5);
return Math.max(width, height) / (size * aspect);
}
},
_djAddLayers: function () {
var layers = this.options.djoptions.layers;
var overlays = this.options.djoptions.overlays || [];
var continuousWorld = this.options.continuousWorld;
if (!layers || !layers.length) {
// No layers, we're done (ignoring overlays)
return;
}
if (layers.length == 1 && overlays.length == 0) {
var layer = l2d(layers[0]);
// Make the only layer match the map max/min_zoom
layer.options = L.Util.extend(layer.options, {
minZoom: this.options.minZoom,
maxZoom: this.options.maxZoom
});
L.tileLayer(layer.url, layer.options).addTo(this);
return;
}
this.layerscontrol = L.control.layers().addTo(this);
for (var i = 0, n = layers.length; i < n; i++) {
var layer = l2d(layers[i]),
l = L.tileLayer(layer.url, layer.options);
this.layerscontrol.addBaseLayer(l, layer.name);
// Show first one as default
if (i === 0) l.addTo(this);
}
for (var i = 0, n = overlays.length; i < n; i++) {
var layer = l2d(overlays[i]),
l = L.tileLayer(layer.url, layer.options);
this.layerscontrol.addOverlay(l, layer.name);
}
function l2d(l) {
var options = {'continuousWorld': continuousWorld};
if (typeof l[2] === 'string') {
// remain compatible with django-leaflet <= 0.15.0
options = L.Util.extend(options, {'attribution': l[2]});
} else {
options = L.Util.extend(options, l[2]);
}
return {name: l[0], url: l[1], options: options};
}
},
_djSetupControls: function () {
// Attribution prefix ?
if (this.attributionControl &&
this.options.djoptions.attributionprefix !== null) {
this.attributionControl.setPrefix(this.options.djoptions.attributionprefix);
}
// Scale control ?
if (this.options.djoptions.scale) {
this.whenReady(function () {
var scale_opt = this.options.djoptions.scale;
var show_imperial = /both|imperial/.test(scale_opt);
var show_metric = /both|metric/.test(scale_opt);
new L.Control.Scale({imperial: show_imperial, metric: show_metric}).addTo(this);
}, this);
}
// Minimap control ?
if (this.options.djoptions.minimap) {
for (var firstLayer in this._layers) break;
var url = this._layers[firstLayer]._url;
var layer = L.tileLayer(url);
this.minimapcontrol = null;
this.whenReady(function () {
this.minimapcontrol = new L.Control.MiniMap(layer,
{toggleDisplay: true}).addTo(this);
}, this);
}
// ResetView control ?
if (this.options.djoptions.resetview) {
var bounds = this.options.djoptions.extent;
if (bounds) {
// Add reset view control
this.whenReady(function () {
new L.Control.ResetView(bounds).addTo(this);
}, this);
}
}
}
});
L.Map.djangoMap = function (id, options) {
var container = L.DomUtil.get(id);
if (container._leaflet) // Already initialized
return;
var map = new L.Map.DjangoMap(id, options);
if (options.globals) {
// Register document maps, like window.forms :)
window.maps = window.maps || [];
window.maps.push(map);
}
if (options.callback === null) {
/*
* Deprecate django-leaflet < 0.7 default callback
*/
var defaultcb = window[id + 'Init'];
if (typeof(defaultcb) == 'function') {
options.callback = defaultcb;
if (console) console.warn('DEPRECATED: Use of default callback ' + defaultcb.name + '() is deprecated (see documentation).');
}
}
/*
* Trigger custom map:init Event
*/
triggerEvent(window, 'map:init', {id: id, map: map, options: options});
/*
* Run callback if specified
*/
if (typeof(options.callback) == 'function') {
options.callback(map, options);
}
return map;
function triggerEvent(target, type, data) {
if (typeof window.CustomEvent == 'function') {
var evt = new CustomEvent(type, {detail: data});
target.dispatchEvent(evt);
}
else if (window.jQuery) {
var evt = jQuery.Event(type);
evt.detail = data;
jQuery(target).trigger(evt);
}
}
};