| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499 |
- (function ($) {
- Drupal.behaviors.leaflet = {
- attach:function (context, settings) {
- $(settings.leaflet).each(function () {
- // skip to the next iteration if the map already exists
- var container = L.DomUtil.get(this.mapId);
- if (!container || container._leaflet) {
- return;
- }
- // load a settings object with all of our map settings
- var settings = {};
- for (var setting in this.map.settings) {
- settings[setting] = this.map.settings[setting];
- }
- // instantiate our new map
- var lMap = new L.Map(this.mapId, settings);
- lMap.bounds = [];
- // add map layers
- var layers = {}, overlays = {};
- var i = 0;
- for (var key in this.map.layers) {
- var layer = this.map.layers[key];
- var map_layer = Drupal.leaflet.create_layer(layer, key);
- layers[key] = map_layer;
- // keep the reference of first layer
- // Distinguish between "base layers" and "overlays", fallback to "base"
- // in case "layer_type" has not been defined in hook_leaflet_map_info()
- layer.layer_type = (typeof layer.layer_type === 'undefined') ? 'base' : layer.layer_type;
- // as written in the doc (http://leafletjs.com/examples/layers-control.html)
- // Always add overlays layers when instantiate, and keep track of
- // them for Control.Layers.
- // Only add the very first "base layer" when instantiating the map
- // if we have map controls enabled
- switch (layer.layer_type) {
- case 'overlay':
- lMap.addLayer(map_layer);
- overlays[key] = map_layer;
- break;
- default:
- if (i === 0 || !this.map.settings.layerControl) {
- lMap.addLayer(map_layer);
- i++;
- }
- layers[key] = map_layer;
- break;
- }
- i++;
- }
- // We loop through the layers once they have all been created to connect them to their switchlayer if necessary.
- var switchEnable = false;
- for (var key in layers) {
- if (layers[key].options.switchLayer) {
- layers[key].setSwitchLayer(layers[layers[key].options.switchLayer]);
- switchEnable = true;
- }
- }
- if (switchEnable) {
- switchManager = new SwitchLayerManager(lMap, {baseLayers: layers});
- }
- // keep an instance of leaflet layers
- this.map.lLayers = layers;
- // keep an instance of map_id
- this.map.map_id = this.mapId;
- // add features
- for (i = 0; i < this.features.length; i++) {
- var feature = this.features[i];
- var lFeature;
- // dealing with a layer group
- if (feature.group) {
- var lGroup = new L.LayerGroup();
- for (var groupKey in feature.features) {
- var groupFeature = feature.features[groupKey];
- lFeature = leaflet_create_feature(groupFeature, lMap);
- if (groupFeature.popup) {
- lFeature.bindPopup(groupFeature.popup);
- }
- lGroup.addLayer(lFeature);
- // Allow others to do something with the feature within a group.
- $(document).trigger('leaflet.feature', [lFeature, feature]);
- }
- // add the group to the layer switcher
- overlays[feature.label] = lGroup;
- lMap.addLayer(lGroup);
- }
- else {
- lFeature = leaflet_create_feature(feature, lMap);
- lMap.addLayer(lFeature);
- if (feature.popup) {
- lFeature.bindPopup(feature.popup);
- }
- // Allow others to do something with the feature.
- $(document).trigger('leaflet.feature', [lFeature, feature]);
- }
- }
- // add layer switcher
- if (this.map.settings.layerControl) {
- lMap.addControl(new L.Control.Layers(layers, overlays));
- }
- // center the map
- var zoom = this.map.settings.zoom ? this.map.settings.zoom : this.map.settings.zoomDefault;
- if (this.map.center && (this.map.center.force || this.features.length === 0)) {
- lMap.setView(new L.LatLng(this.map.center.lat, this.map.center.lon), zoom);
- }
- else if (this.features.length > 0) {
- Drupal.leaflet.fitbounds(lMap);
- if (this.map.settings.zoom) { // or: if (zoom) ?
- lMap.setZoom(zoom);
- }
- }
- // add attribution
- if (this.map.settings.attributionControl && this.map.attribution) {
- lMap.attributionControl.setPrefix(this.map.attribution.prefix);
- lMap.attributionControl.addAttribution(this.map.attribution.text);
- }
- // add the leaflet map to our settings object to make it accessible
- this.lMap = lMap;
- // allow other modules to get access to the map object using jQuery's trigger method
- $(document).trigger('leaflet.map', [this.map, lMap]);
- // Destroy features so that an AJAX reload does not get parts of the old set.
- // Required when the View has "Use AJAX" set to Yes.
- this.features = null;
- });
- function leaflet_create_feature(feature, lMap) {
- var lFeature;
- switch (feature.type) {
- case 'point':
- lFeature = Drupal.leaflet.create_point(feature, lMap);
- break;
- case 'linestring':
- lFeature = Drupal.leaflet.create_linestring(feature, lMap);
- break;
- case 'polygon':
- lFeature = Drupal.leaflet.create_polygon(feature, lMap);
- break;
- case 'multipolyline':
- feature.multipolyline = true;
- // no break;
- case 'multipolygon':
- lFeature = Drupal.leaflet.create_multipoly(feature, lMap);
- break;
- case 'json':
- lFeature = Drupal.leaflet.create_json(feature.json, lMap);
- break;
- case 'popup':
- lFeature = Drupal.leaflet.create_popup(feature, lMap);
- break;
- case 'circle':
- lFeature = Drupal.leaflet.create_circle(feature, lMap);
- break;
- case 'circlemarker':
- lFeature = Drupal.leaflet.create_circlemarker(feature, lMap);
- break;
- case 'rectangle':
- lFeature = Drupal.leaflet.create_rectangle(feature, lMap);
- break;
- }
- // assign our given unique ID, useful for associating nodes
- if (feature.leaflet_id) {
- lFeature._leaflet_id = feature.leaflet_id;
- }
- var options = {};
- if (feature.options) {
- for (var option in feature.options) {
- options[option] = feature.options[option];
- }
- lFeature.setStyle(options);
- }
- return lFeature;
- }
- }
- };
- Drupal.leaflet = {
- isOldVersion: function () {
- return !(parseInt(L.version) >= 1); // version may start with '0' or '.'
- },
- create_layer: function (layer, key) {
- // Use a Zoomswitch Layer extension to enable zoom-switch option.
- var map_layer = new L.TileLayerZoomSwitch(layer.urlTemplate);
- map_layer._leaflet_id = key;
- if (layer.options) {
- for (var option in layer.options) {
- map_layer.options[option] = layer.options[option];
- }
- }
- // layers served from TileStream need this correction in the y coordinates
- // TODO: Need to explore this more and find a more elegant solution
- if (layer.type == 'tilestream') {
- map_layer.getTileUrl = function (tilePoint) {
- this._adjustTilePoint(tilePoint);
- var zoom = this._getZoomForUrl();
- return L.Util.template(this._url, L.Util.extend({
- s: this._getSubdomain(tilePoint),
- z: zoom,
- x: tilePoint.x,
- y: Math.pow(2, zoom) - tilePoint.y - 1
- }, this.options));
- };
- }
- return map_layer;
- },
- create_circle: function(circle, lMap) {
- var latLng = new L.LatLng(circle.lat, circle.lon);
- latLng = latLng.wrap();
- lMap.bounds.push(latLng);
- if (circle.radius) {
- // @deprecated
- return L.circle(latLng, circle.radius, circle.options);
- }
- return new L.Circle(latLng, circle.options);
- },
- create_circlemarker: function(circle, lMap) {
- var latLng = new L.LatLng(circle.lat, circle.lon);
- latLng = latLng.wrap();
- lMap.bounds.push(latLng);
- return new L.CircleMarker(latLng, circle.options);
- },
- create_rectangle: function(box, lMap) {
- var bounds = box.bounds,
- southWest = new L.LatLng(bounds.s, bounds.w),
- northEast = new L.LatLng(bounds.n, bounds.e),
- latLng = new L.LatLngBounds(southWest, northEast);
- lMap.bounds.push(latLng);
- return new L.Rectangle(latLng, box.settings);
- },
- create_point: function(marker, lMap) {
- var latLng = new L.LatLng(marker.lat, marker.lon);
- latLng = latLng.wrap();
- lMap.bounds.push(latLng);
- var lMarker;
- if (marker.html) {
- if (marker.html_class) {
- var icon = new L.DivIcon({html: marker.html, className: marker.html_class});
- }
- else {
- var icon = new L.DivIcon({html: marker.html});
- }
- // override applicable marker defaults
- if (marker.icon.iconSize) {
- icon.options.iconSize = new L.Point(parseInt(marker.icon.iconSize.x, 10), parseInt(marker.icon.iconSize.y, 10));
- }
- if (marker.icon.iconAnchor) {
- icon.options.iconAnchor = new L.Point(parseFloat(marker.icon.iconAnchor.x), parseFloat(marker.icon.iconAnchor.y));
- }
- lMarker = new L.Marker(latLng, {icon:icon});
- }
- else if (marker.icon) {
- var icon = new L.Icon({iconUrl: marker.icon.iconUrl});
- // override applicable marker defaults
- if (marker.icon.iconSize) {
- icon.options.iconSize = new L.Point(parseInt(marker.icon.iconSize.x, 10), parseInt(marker.icon.iconSize.y, 10));
- }
- if (marker.icon.iconAnchor) {
- icon.options.iconAnchor = new L.Point(parseFloat(marker.icon.iconAnchor.x), parseFloat(marker.icon.iconAnchor.y));
- }
- if (marker.icon.popupAnchor) {
- icon.options.popupAnchor = new L.Point(parseFloat(marker.icon.popupAnchor.x), parseFloat(marker.icon.popupAnchor.y));
- }
- if (marker.icon.shadowUrl !== undefined) {
- icon.options.shadowUrl = marker.icon.shadowUrl;
- }
- if (marker.icon.shadowSize) {
- icon.options.shadowSize = new L.Point(parseInt(marker.icon.shadowSize.x, 10), parseInt(marker.icon.shadowSize.y, 10));
- }
- if (marker.icon.shadowAnchor) {
- icon.options.shadowAnchor = new L.Point(parseInt(marker.icon.shadowAnchor.x, 10), parseInt(marker.icon.shadowAnchor.y, 10));
- }
- if (marker.icon.zIndexOffset) {
- icon.options.zIndexOffset = marker.icon.zIndexOffset;
- }
- if (marker.icon.className) {
- icon.options.className = marker.icon.className;
- }
- var options = {icon:icon};
- if (marker.zIndexOffset) {
- options.zIndexOffset = marker.zIndexOffset;
- }
- lMarker = new L.Marker(latLng, options);
- }
- else {
- lMarker = new L.Marker(latLng);
- }
- if (marker.label) {
- lMarker.options.title = marker.label;
- }
- return lMarker;
- },
- create_linestring: function(polyline, lMap) {
- var latlngs = [];
- for (var i = 0; i < polyline.points.length; i++) {
- var latlng = new L.LatLng(polyline.points[i].lat, polyline.points[i].lon);
- latlng = latlng.wrap();
- latlngs.push(latlng);
- lMap.bounds.push(latlng);
- }
- return new L.Polyline(latlngs);
- },
- create_polygon: function(polygon, lMap) {
- var latlngs = [];
- for (var i = 0; i < polygon.points.length; i++) {
- var latlng = new L.LatLng(polygon.points[i].lat, polygon.points[i].lon);
- latlng = latlng.wrap();
- latlngs.push(latlng);
- lMap.bounds.push(latlng);
- }
- return new L.Polygon(latlngs);
- },
- create_multipoly: function(multipoly, lMap) {
- var polygons = [];
- for (var x = 0; x < multipoly.component.length; x++) {
- var latlngs = [];
- var polygon = multipoly.component[x];
- for (var i = 0; i < polygon.points.length; i++) {
- var latlng = new L.LatLng(polygon.points[i].lat, polygon.points[i].lon);
- latlng = latlng.wrap();
- latlngs.push(latlng);
- lMap.bounds.push(latlng);
- }
- polygons.push(latlngs);
- }
- if (this.isOldVersion()) {
- return multipoly.multipolyline ? new L.MultiPolyline(polygons) : new L.MultiPolygon(polygons);
- }
- return multipoly.multipolyline ? new L.Polyline(polygons): new L.Polygon(polygons);
- },
- create_json:function(json, lMap) {
- lJSON = new L.GeoJSON(json, {
- onEachFeature:function (feature, layer) {
- var has_properties = (typeof feature.properties != 'undefined');
- // bind popups
- if (has_properties && typeof feature.properties.popup != 'undefined') {
- layer.bindPopup(feature.properties.popup);
- }
- for (var layer_id in layer._layers) {
- for (var i in layer._layers[layer_id]._latlngs) {
- lMap.bounds.push(layer._layers[layer_id]._latlngs[i]);
- }
- }
- if (has_properties && typeof feature.properties.style != 'undefined') {
- layer.setStyle(feature.properties.style);
- }
- if (has_properties && typeof feature.properties.leaflet_id != 'undefined') {
- layer._leaflet_id = feature.properties.leaflet_id;
- }
- }
- });
- return lJSON;
- },
- create_popup: function(popup) {
- var latLng = new L.LatLng(popup.lat, popup.lon);
- this.bounds.push(latLng);
- var lPopup = new L.Popup();
- lPopup.setLatLng(latLng);
- if (popup.content) {
- lPopup.setContent(popup.content);
- }
- return lPopup;
- },
- fitbounds:function (lMap) {
- if (lMap.bounds.length > 0) {
- lMap.fitBounds(new L.LatLngBounds(lMap.bounds));
- }
- }
- };
- // Zoomswitch method cribbed liberally from:
- // http://www.makina-corpus.org/blog/leaflet-zoom-switcher
- L.TileLayerZoomSwitch = L.TileLayer.extend({
- includes: L.Mixin.Events,
- options: {
- // switchZoomUnder: when zoom < switchZoomUnder, then switch to switchLayer
- switchZoomUnder: -1,
- // switchZoomAbove: when zoom >= switchZoomAbove, then switch to switchLayer
- switchZoomAbove: -1,
- switchLayer: null
- },
- setSwitchLayer: function (layer) {
- this.options.switchLayer = layer;
- },
- getSwitchZoomUnder: function () {
- return this.options.switchZoomUnder;
- },
- getSwitchZoomAbove: function () {
- return this.options.switchZoomAbove;
- },
- getSwitchLayer: function () {
- return this.options.switchLayer;
- }
- });
- L.tileLayerZoomSwitch = function (url, options) {
- return new L.TileLayerZoomSwitch(url, options);
- };
- /*
- * SwitchLayerManager is a custom class for managing base layer automatic switching according to the current zoom level
- */
- SwitchLayerManager = L.Class.extend({
- _map: null,
- options: {
- baseLayers: null
- },
- initialize: function (map, options) {
- this._map = map;
- L.Util.setOptions(this, options);
- this._map.on({
- 'zoomend': this._update
- }, this)
- },
- _update: function (e) {
- var zoom = this._map.getZoom();
- for (var i in this.options.baseLayers) {
- var curBL = this.options.baseLayers[i];
- var zoomUnder = curBL.getSwitchZoomUnder();
- var zoomAbove = curBL.getSwitchZoomAbove();
- var switchLayer = curBL.getSwitchLayer();
- // If layer got a switchlayer, and if layer actually displayed
- if (switchLayer && curBL._map != null) {
- //if (switchLayer) {
- if(zoomUnder != -1 && zoom < zoomUnder) {
- this._map.removeLayer(curBL);
- this._map.addLayer(switchLayer, false);
- }
- if(zoomAbove != -1 && zoom >= zoomAbove) {
- this._map.removeLayer(curBL);
- this._map.addLayer(switchLayer, false);
- }
- }
- }
- }
- });
- })(jQuery);
|