1(function ($) { 2 3 Drupal.behaviors.leaflet = { 4 attach:function (context, settings) { 5 6 $(settings.leaflet).each(function () { 7 // skip to the next iteration if the map already exists 8 var container = L.DomUtil.get(this.mapId); 9 if (!container || container._leaflet_id) { 10 return; 11 } 12 13 // load a settings object with all of our map settings 14 var settings = {}; 15 for (var setting in this.map.settings) { 16 settings[setting] = this.map.settings[setting]; 17 } 18 19 // instantiate our new map 20 var lMap = new L.Map(this.mapId, settings); 21 lMap.bounds = []; 22 23 // add map layers 24 var layers = {}, overlays = {}; 25 var i = 0; 26 for (var key in this.map.layers) { 27 var layer = this.map.layers[key]; 28 var map_layer = Drupal.leaflet.create_layer(layer, key); 29 //layers[key] = map_layer; 30 31 // Distinguish between "base layers" and "overlays". 32 // Fall back to "base" in case "layer_type" has not been defined in 33 // hook_leaflet_map_info() 34 layer.layer_type = (typeof layer.layer_type === 'undefined') ? 'base' : layer.layer_type; 35 // As stated in http://leafletjs.com/examples/layers-control, 36 // when using multiple base layers, only one of them should be added 37 // to the map at instantiation, but all of them should be present in 38 // the base layers object when creating the layers control. 39 // See statement L.control.layers(layers, overlays) much further below. 40 switch (layer.layer_type) { 41 case 'overlay': 42 //lMap.addLayer(map_layer); 43 overlays[key] = map_layer; 44 break; 45 default: 46 if (i === 0 /*|| !this.map.settings.layerControl*/) { 47 lMap.addLayer(map_layer); 48 i++; 49 } 50 layers[key] = map_layer; 51 break; 52 } 53 i++; 54 } 55 56 var switchEnable = false; 57 for (var key in layers) { 58 if (layers[key].options.switchLayer) { 59 layers[key].setSwitchLayer(layers[layers[key].options.switchLayer]); 60 switchEnable = true; 61 } 62 } 63 if (switchEnable) { 64 switchManager = new SwitchLayerManager(lMap, {baseLayers: layers}); 65 } 66 67 // keep an instance of leaflet layers 68 this.map.lLayers = layers; 69 70 // keep an instance of map_id 71 this.map.map_id = this.mapId; 72 73 // add features 74 for (i = 0; i < this.features.length; i++) { 75 var feature = this.features[i]; 76 var lFeature; 77 78 // dealing with a layer group 79 if (feature.group) { 80 var lGroup = new L.LayerGroup(); 81 for (var groupKey in feature.features) { 82 var groupFeature = feature.features[groupKey]; 83 lFeature = leaflet_create_feature(groupFeature, lMap); 84 if (groupFeature.popup) { 85 lFeature.bindPopup(groupFeature.popup); 86 } 87 lGroup.addLayer(lFeature); 88 89 // Allow others to do something with the feature within a group. 90 $(document).trigger('leaflet.feature', [lFeature, feature]); 91 } 92 93 // add the group to the layer switcher 94 overlays[feature.label] = lGroup; 95 96 lMap.addLayer(lGroup); 97 } 98 else { 99 lFeature = leaflet_create_feature(feature, lMap); 100 lMap.addLayer(lFeature); 101 102 if (feature.popup) { 103 lFeature.bindPopup(feature.popup); 104 } 105 106 // Allow others to do something with the feature. 107 $(document).trigger('leaflet.feature', [lFeature, feature]); 108 } 109 110 } 111 112 // add layer switcher 113 if (this.map.settings.layerControl) { 114 L.control.layers(layers, overlays).addTo(lMap); 115 } 116 117 // center the map 118 var zoom = this.map.settings.zoom ? this.map.settings.zoom : this.map.settings.zoomDefault; 119 if (this.map.center && (this.map.center.force || this.features.length === 0)) {
120 lMap.setView(new L.LatLng(this.map.center.lat, this.map.center.lon), zoom); 121 } 122 else if (this.features.length > 0) { 123 Drupal.leaflet.fitbounds(lMap); 124 if (this.map.settings.zoom) { // or: if (zoom) ? 125 lMap.setZoom(zoom); 126 } 127 } 128 129 // add attribution 130 if (this.map.settings.attributionControl && this.map.attribution) { 131 lMap.attributionControl.setPrefix(this.map.attribution.prefix); 132 lMap.attributionControl.addAttribution(this.map.attribution.text); 133 } 134 135 // add the leaflet map to our settings object to make it accessible 136 this.lMap = lMap; 137 138 // allow other modules to get access to the map object using jQuery's trigger method 139 $(document).trigger('leaflet.map', [this.map, lMap]); 140 141 // Destroy features so that an AJAX reload does not get parts of the old set. 142 // Required when the View has "Use AJAX" set to Yes. 143 this.features = null; 144 }); 145 146 function leaflet_create_feature(feature, lMap) { 147 var lFeature; 148 switch (feature.type) { 149 case 'point': 150 lFeature = Drupal.leaflet.create_point(feature, lMap); 151 break; 152 case 'linestring': 153 lFeature = Drupal.leaflet.create_linestring(feature, lMap); 154 break; 155 case 'polygon': 156 lFeature = Drupal.leaflet.create_polygon(feature, lMap); 157 break; 158 case 'multipolyline': 159 feature.multipolyline = true; 160 // no break; 161 case 'multipolygon': 162 lFeature = Drupal.leaflet.create_multipoly(feature, lMap); 163 break; 164 case 'json': 165 lFeature = Drupal.leaflet.create_json(feature.json, lMap); 166 break; 167 case 'popup': 168 lFeature = Drupal.leaflet.create_popup(feature, lMap); 169 break; 170 case 'circle': 171 lFeature = Drupal.leaflet.create_circle(feature, lMap); 172 break; 173 case 'circlemarker': 174 lFeature = Drupal.leaflet.create_circlemarker(feature, lMap); 175 break; 176 case 'rectangle': 177 lFeature = Drupal.leaflet.create_rectangle(feature, lMap); 178 break; 179 } 180 181 // assign our given unique ID, useful for associating nodes 182 if (feature.leaflet_id) { 183 lFeature._leaflet_id = feature.leaflet_id; 184 } 185 186 var options = {}; 187 if (feature.options) { 188 for (var option in feature.options) { 189 options[option] = feature.options[option]; 190 } 191 lFeature.setStyle(options); 192 } 193 194 return lFeature; 195 } 196 197 } 198 }; 199 200 Drupal.leaflet = { 201 202 isOldVersion: function () { 203 return !(parseInt(L.version) >= 1); // version may start with '0' or '.' 204 }, 205 206 create_layer: function (layer, key) { 207 // Use a Zoomswitch Layer extension to enable zoom-switch option. 208 var map_layer = new L.TileLayerZoomSwitch(layer.urlTemplate); 209 map_layer._leaflet_id = key; 210 211 if (layer.options) { 212 for (var option in layer.options) { 213 map_layer.options[option] = layer.options[option]; 214 } 215 } 216 217 // layers served from TileStream need this correction in the y coordinates 218 // TODO: Need to explore this more and find a more elegant solution 219 if (layer.type == 'tilestream') { 220 map_layer.getTileUrl = function (tilePoint) { 221 this._adjustTilePoint(tilePoint); 222 var zoom = this._getZoomForUrl(); 223 return L.Util.template(this._url, L.Util.extend({ 224 s: this._getSubdomain(tilePoint), 225 z: zoom, 226 x: tilePoint.x, 227 y: Math.pow(2, zoom) - tilePoint.y - 1 228 }, this.options)); 229 }; 230 } 231 return map_layer; 232 }, 233 234 create_circle: function(circle, lMap) { 235 var latLng = new L.LatLng(circle.lat, circle.lon); 236 latLng = latLng.wrap(); 237 lMap.bounds.push(latLng); 238 if (circle.radius) { 239 // @deprecated 240 return L.circle(latLng, circle.radius, circle.options); 241 } 242 return new L.Circle(latLng, circle.options); 243 }, 244 245 create_circlemarker: function(circle, lMap) { 246 var latLng = new L.LatLng(circle.lat, circle.lon); 247 latLng = latLng.wrap(); 248 lMap.bounds.push(latLng); 249 return new L.CircleMarker(latLng, circle.options); 250 }, 251 252 create_rectangle: function(box, lMap) { 253 var bounds = box.bounds, 254 southWest = new L.LatLng(bounds.s, bounds.w), 255 northEast = new L.LatLng(bounds.n, bounds.e), 256 latLng = new L.LatLngBounds(southWest, northEast); 257 lMap.bounds.push(latLng); 258 return new L.Rectangle(latLng, box.settings); 259 }, 260 261 create_point: function(marker, lMap) { 262 var latLng = new L.LatLng(marker.lat, marker.lon); 263 latLng = latLng.wrap(); 264 lMap.bounds.push(latLng); 265 var lMarker; 266 267 if (marker.html) { 268 if (marker.html_class) { 269 var icon = new L.DivIcon({html: marker.html, className: marker.html_class}); 270 } 271 else { 272 var icon = new L.DivIcon({html: marker.html}); 273 } 274 // override applicable marker defaults 275 if (marker.icon.iconSize) { 276 icon.options.iconSize = new L.Point(parseInt(marker.icon.iconSize.x, 10), parseInt(marker.icon.iconSize.y, 10)); 277 } 278 if (marker.icon.iconAnchor) { 279 icon.options.iconAnchor = new L.Point(parseFloat(marker.icon.iconAnchor.x), parseFloat(marker.icon.iconAnchor.y)); 280 } 281 lMarker = new L.Marker(latLng, {icon:icon}); 282 } 283 else if (marker.icon) { 284 var icon = new L.Icon({iconUrl: marker.icon.iconUrl}); 285 286 // override applicable marker defaults 287 if (marker.icon.iconSize) { 288 icon.options.iconSize = new L.Point(parseInt(marker.icon.iconSize.x, 10), parseInt(marker.icon.iconSize.y, 10)); 289 } 290 if (marker.icon.iconAnchor) { 291 icon.options.iconAnchor = new L.Point(parseFloat(marker.icon.iconAnchor.x), parseFloat(marker.icon.iconAnchor.y)); 292 } 293 if (marker.icon.popupAnchor) { 294 icon.options.popupAnchor = new L.Point(parseFloat(marker.icon.popupAnchor.x), parseFloat(marker.icon.popupAnchor.y)); 295 } 296 if (marker.icon.shadowUrl !== undefined) { 297 icon.options.shadowUrl = marker.icon.shadowUrl; 298 } 299 if (marker.icon.shadowSize) { 300 icon.options.shadowSize = new L.Point(parseInt(marker.icon.shadowSize.x, 10), parseInt(marker.icon.shadowSize.y, 10)); 301 } 302 if (marker.icon.shadowAnchor) { 303 icon.options.shadowAnchor = new L.Point(parseInt(marker.icon.shadowAnchor.x, 10), parseInt(marker.icon.shadowAnchor.y, 10)); 304 } 305 if (marker.icon.zIndexOffset) { 306 icon.options.zIndexOffset = marker.icon.zIndexOffset; 307 } 308 if (marker.icon.className) { 309 icon.options.className = marker.icon.className; 310 } 311 var options = {icon:icon}; 312 if (marker.zIndexOffset) { 313 options.zIndexOffset = marker.zIndexOffset; 314 } 315 lMarker = new L.Marker(latLng, options); 316 } 317 else { 318 lMarker = new L.Marker(latLng); 319 } 320 321 if (marker.label) { 322 lMarker.options.title = marker.label; 323 } 324 325 return lMarker; 326 }, 327 328 create_linestring: function(polyline, lMap) { 329 var latlngs = []; 330 for (var i = 0; i < polyline.points.length; i++) { 331 var latlng = new L.LatLng(polyline.points[i].lat, polyline.points[i].lon); 332 latlng = latlng.wrap(); 333 latlngs.push(latlng); 334 lMap.bounds.push(latlng); 335 } 336 return new L.Polyline(latlngs); 337 }, 338
339 create_polygon: function(polygon, lMap) { 340 var latlngs = []; 341 for (var i = 0; i < polygon.points.length; i++) { 342 var latlng = new L.LatLng(polygon.points[i].lat, polygon.points[i].lon); 343 latlng = latlng.wrap(); 344 latlngs.push(latlng); 345 lMap.bounds.push(latlng); 346 } 347 return new L.Polygon(latlngs); 348 }, 349 350 create_multipoly: function(multipoly, lMap) { 351 var polygons = []; 352 for (var x = 0; x < multipoly.component.length; x++) { 353 var latlngs = []; 354 var polygon = multipoly.component[x]; 355 for (var i = 0; i < polygon.points.length; i++) { 356 var latlng = new L.LatLng(polygon.points[i].lat, polygon.points[i].lon); 357 latlng = latlng.wrap(); 358 latlngs.push(latlng); 359 lMap.bounds.push(latlng); 360 } 361 polygons.push(latlngs); 362 } 363 if (this.isOldVersion()) { 364 return multipoly.multipolyline ? new L.MultiPolyline(polygons) : new L.MultiPolygon(polygons); 365 } 366 return multipoly.multipolyline ? new L.Polyline(polygons): new L.Polygon(polygons); 367 }, 368 369 create_json:function(json, lMap) { 370 lJSON = new L.GeoJSON(json, { 371 onEachFeature:function (feature, layer) { 372 var has_properties = (typeof feature.properties != 'undefined'); 373 374 // bind popups 375 if (has_properties && typeof feature.properties.popup != 'undefined') { 376 layer.bindPopup(feature.properties.popup); 377 } 378 379 for (var layer_id in layer._layers) { 380 for (var i in layer._layers[layer_id]._latlngs) { 381 lMap.bounds.push(layer._layers[layer_id]._latlngs[i]); 382 } 383 } 384 385 if (has_properties && typeof feature.properties.style != 'undefined') { 386 layer.setStyle(feature.properties.style); 387 } 388 389 if (has_properties && typeof feature.properties.leaflet_id != 'undefined') { 390 layer._leaflet_id = feature.properties.leaflet_id; 391 } 392 } 393 }); 394 395 return lJSON; 396 }, 397 398 create_popup: function(popup) { 399 var latLng = new L.LatLng(popup.lat, popup.lon); 400 this.bounds.push(latLng); 401 var lPopup = new L.Popup(); 402 lPopup.setLatLng(latLng); 403 if (popup.content) { 404 lPopup.setContent(popup.content); 405 } 406 return lPopup; 407 }, 408 409 fitbounds:function (lMap) { 410 if (lMap.bounds.length > 0) { 411 lMap.fitBounds(new L.LatLngBounds(lMap.bounds)); 412 } 413 } 414 }; 415 416 // Zoomswitch method cribbed liberally from: 417 // http://www.makina-corpus.org/blog/leaflet-zoom-switcher 418 L.TileLayerZoomSwitch = L.TileLayer.extend({ 419 includes: L.Mixin.Events, 420 421 options: { 422 // switchZoomUnder: when zoom < switchZoomUnder, then switch to switchLayer 423 switchZoomUnder: -1, 424 // switchZoomAbove: when zoom >= switchZoomAbove, then switch to switchLayer 425 switchZoomAbove: -1, 426 switchLayer: null 427 }, 428 429 setSwitchLayer: function (layer) { 430 this.options.switchLayer = layer; 431 }, 432 433 getSwitchZoomUnder: function () { 434 return this.options.switchZoomUnder; 435 }, 436 437 getSwitchZoomAbove: function () { 438 return this.options.switchZoomAbove; 439 }, 440 441 getSwitchLayer: function () { 442 return this.options.switchLayer; 443 } 444 445 }); 446 447 L.tileLayerZoomSwitch = function (url, options) { 448 return new L.TileLayerZoomSwitch(url, options); 449 }; 450 451 /* 452 * SwitchLayerManager is a custom class for managing base layer automatic switching according to the current zoom level 453 */ 454 455 SwitchLayerManager = L.Class.extend({ 456 457 _map: null, 458 459 options: { 460 baseLayers: null 461 }, 462 463 initialize: function (map, options) { 464 this._map = map; 465 L.Util.setOptions(this, options); 466 467 this._map.on({ 468 'zoomend': this._update 469 }, this) 470 471 }, 472 473 _update: function (e) { 474 var zoom = this._map.getZoom(); 475 476 for (var i in this.options.baseLayers) { 477 var curBL = this.options.baseLayers[i]; 478 var zoomUnder = curBL.getSwitchZoomUnder(); 479 var zoomAbove = curBL.getSwitchZoomAbove(); 480 var switchLayer = curBL.getSwitchLayer(); 481 482 // If layer got a switchlayer, and if layer actually displayed 483 if (switchLayer && curBL._map != null) { 484 //if (switchLayer) { 485 if(zoomUnder != -1 && zoom < zoomUnder) { 486 this._map.removeLayer(curBL); 487 this._map.addLayer(switchLayer, false); 488 } 489 490 if(zoomAbove != -1 && zoom >= zoomAbove) { 491 this._map.removeLayer(curBL); 492 this._map.addLayer(switchLayer, false); 493 } 494 } 495 } 496 } 497 }); 498 499})(jQuery);
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.