1L.Control.ResetView = L.Control.extend({ 2 statics: { 3 ICON: 'url(images/reset-view.png)', 4 TITLE: "Reset view" 5 }, 6 7 options: { 8 position: 'topleft' 9 }, 10 11 initialize: function (bounds, options) { 12 // Accept function as argument to bounds 13 this.getBounds = typeof(bounds) == 'function' ? bounds : 14 function () { 15 return bounds; 16 }; 17 18 L.Util.setOptions(this, options); 19 }, 20 21 onAdd: function (map) { 22 if (map.resetviewControl) { 23 map.removeControl(map.resetviewControl); 24 } 25 map.resetviewControl = this; 26 27 var container = L.DomUtil.create('div', 'leaflet-control-zoom leaflet-bar'); 28 var link = L.DomUtil.create('a', 'leaflet-control-zoom-out leaflet-bar-part', container); 29 link.href = '#'; 30 link.title = L.Control.ResetView.TITLE; 31 link.style.backgroundImage = L.Control.ResetView.ICON; 32 33 L.DomEvent.addListener(link, 'click', L.DomEvent.stopPropagation) 34 .addListener(link, 'click', L.DomEvent.preventDefault) 35 .addListener(link, 'click', L.Util.bind(function () { 36 map.fitBounds(this.getBounds()); 37 }, this)); 38 return container; 39 } 40}); 41 42 43L.Map.DjangoMap = L.Map.extend({ 44 45 initialize: function (id, options) { 46 // Merge compatible options 47 // (can be undefined) 48 var djoptions = options.djoptions; 49 options.zoom = djoptions.zoom; 50 options.center = djoptions.center; 51 52 if (!isNaN(parseInt(djoptions.minzoom, 10))) 53 options.minZoom = djoptions.minzoom; 54 55 if (!isNaN(parseInt(djoptions.maxzoom, 10))) 56 options.maxZoom = djoptions.maxzoom; 57 58 // Translate to native options 59 options = L.Util.extend(options, 60 this._projectionOptions(djoptions)); 61 if (djoptions.extent) { 62 options.maxBounds = djoptions.extent; 63 } 64 65 L.Map.prototype.initialize.call(this, id, options); 66 67 this._djAddLayers(); 68 this._djSetupControls(); 69 70 if (djoptions.fitextent && djoptions.extent && !(djoptions.center || djoptions.zoom)) { 71 this.fitBounds(options.maxBounds); 72 } 73 }, 74 75 _projectionOptions: function (djoptions) { 76 if (!djoptions.srid) 77 return {}; 78 79 var projopts = {}; 80 81 var bbox = djoptions.tilesextent, 82 maxResolution = computeMaxResolution(bbox); 83 // See https://github.com/ajashton/TileCache/blob/master/tilecache/TileCache/Layer.py#L197 84 var resolutions = []; 85 for (var z = 0; z < 20; z++) { 86 resolutions.push(maxResolution / Math.pow(2, z)); 87 } 88 var crs = new L.Proj.CRS('EPSG:' + djoptions.srid, 89 Proj4js.defs['EPSG:' + djoptions.srid], 90 { 91 origin: [bbox[0], bbox[3]], 92 resolutions: resolutions 93 }); 94 return { 95 crs: crs, 96 scale: crs.scale, 97 continuousWorld: true 98 }; 99 100 function computeMaxResolution(bbox) { 101 // See https://github.com/ajashton/TileCache/blob/master/tilecache/TileCache/Layer.py#L185-L196 102 var size = 256, 103 width = bbox[2] - bbox[0], 104 height = bbox[3] - bbox[1]; 105 var aspect = Math.floor(Math.max(width, height) / Math.min(width, height) + 0.5); 106 return Math.max(width, height) / (size * aspect); 107 } 108 }, 109 110 _djAddLayers: function () { 111 var layers = this.options.djoptions.layers; 112 var overlays = this.options.djoptions.overlays || []; 113 var continuousWorld = this.options.continuousWorld; 114 115 if (!layers || !layers.length) { 116 // No layers, we're done (ignoring overlays) 117 return; 118 } 119 120 if (layers.length == 1 && overlays.length == 0) { 121 var layer = l2d(layers[0]); 122 // Make the only layer match the map max/min_zoom 123 layer.options = L.Util.extend(layer.options, { 124 minZoom: this.options.minZoom, 125 maxZoom: this.options.maxZoom 126 }); 127 L.tileLayer(layer.url, layer.options).addTo(this); 128 return; 129 } 130 131 this.layerscontrol = L.control.layers().addTo(this); 132 for (var i = 0, n = layers.length; i < n; i++) { 133 var layer = l2d(layers[i]), 134 l = L.tileLayer(layer.url, layer.options); 135 this.layerscontrol.addBaseLayer(l, layer.name); 136 // Show first one as default 137 if (i === 0) l.addTo(this); 138 } 139 for (var i = 0, n = overlays.length; i < n; i++) { 140 var layer = l2d(overlays[i]), 141 l = L.tileLayer(layer.url, layer.options); 142 this.layerscontrol.addOverlay(l, layer.name); 143 } 144 145 function l2d(l) { 146 var options = {'continuousWorld': continuousWorld}; 147 if (typeof l[2] === 'string') { 148 // remain compatible with django-leaflet <= 0.15.0 149 options = L.Util.extend(options, {'attribution': l[2]}); 150 } else { 151 options = L.Util.extend(options, l[2]); 152 } 153 return {name: l[0], url: l[1], options: options}; 154 } 155 }, 156 157 _djSetupControls: function () { 158 // Attribution prefix ? 159 if (this.attributionControl && 160 this.options.djoptions.attributionprefix !== null) { 161 this.attributionControl.setPrefix(this.options.djoptions.attributionprefix); 162 } 163 164 // Scale control ? 165 if (this.options.djoptions.scale) { 166 this.whenReady(function () { 167 var scale_opt = this.options.djoptions.scale; 168 var show_imperial = /both|imperial/.test(scale_opt); 169 var show_metric = /both|metric/.test(scale_opt); 170 new L.Control.Scale({imperial: show_imperial, metric: show_metric}).addTo(this); 171 }, this); 172 } 173 174 // Minimap control ? 175 if (this.options.djoptions.minimap) { 176 for (var firstLayer in this._layers) break; 177 var url = this._layers[firstLayer]._url; 178 var layer = L.tileLayer(url); 179 this.minimapcontrol = null; 180 this.whenReady(function () { 181 this.minimapcontrol = new L.Control.MiniMap(layer, 182 {toggleDisplay: true}).addTo(this); 183 }, this); 184 } 185 186 // ResetView control ? 187 if (this.options.djoptions.resetview) { 188 var bounds = this.options.djoptions.extent; 189 if (bounds) { 190 // Add reset view control 191 this.whenReady(function () { 192 new L.Control.ResetView(bounds).addTo(this); 193 }, this); 194 } 195 } 196 } 197 198}); 199 200 201L.Map.djangoMap = function (id, options) { 202 var container = L.DomUtil.get(id); 203 if (container._leaflet) // Already initialized 204 return; 205 206 var map = new L.Map.DjangoMap(id, options); 207 208 if (options.globals) { 209 // Register document maps, like window.forms :) 210 window.maps = window.maps || []; 211 window.maps.push(map); 212 } 213 214 if (options.callback === null) { 215 /* 216 * Deprecate django-leaflet < 0.7 default callback 217 */ 218 var defaultcb = window[id + 'Init']; 219 if (typeof(defaultcb) == 'function') { 220 options.callback = defaultcb; 221 if (console) console.warn('DEPRECATED: Use of default callback ' + defaultcb.name + '() is deprecated (see documentation).'); 222 } 223 } 224 225 /* 226 * Trigger custom map:init Event 227 */ 228 triggerEvent(window, 'map:init', {id: id, map: map, options: options}); 229 230 /* 231 * Run callback if specified 232 */ 233 if (typeof(options.callback) == 'function') { 234 options.callback(map, options); 235 } 236 237 return map; 238 239 240 function triggerEvent(target, type, data) { 241 if (typeof window.CustomEvent == 'function') { 242 var evt = new CustomEvent(type, {detail: data}); 243 target.dispatchEvent(evt); 244 } 245 else if (window.jQuery) { 246 var evt = jQuery.Event(type); 247 evt.detail = data; 248 jQuery(target).trigger(evt); 249 } 250 } 251};
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.