/**!
* The MIT License
*
* Copyright (c) 2013 the angular-leaflet-directive Team, http://tombatossals.github.io/angular-leaflet-directive
*
* 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.
*
* angular-leaflet-directive
* https://github.com/tombatossals/angular-leaflet-directive
*
* @authors https://github.com/tombatossals/angular-leaflet-directive/graphs/contributors
*/
/*! angular-leaflet-directive 06-05-2014 */
!function(){"use strict";angular.module("leaflet-directive",[]).directive("leaflet",["$q","leafletData","leafletMapDefaults","leafletHelpers","leafletEvents",function(a,b,c,d,e){var f;return{restrict:"EA",replace:!0,scope:{center:"=center",defaults:"=defaults",maxbounds:"=maxbounds",bounds:"=bounds",markers:"=markers",legend:"=legend",geojson:"=geojson",paths:"=paths",tiles:"=tiles",layers:"=layers",controls:"=controls",eventBroadcast:"=eventBroadcast"},template:'
',controller:["$scope",function(b){f=a.defer(),this.getMap=function(){return f.promise},this.getLeafletScope=function(){return b}}],link:function(a,g,h){var i=d.isDefined,j=c.setDefaults(a.defaults,h.id),k=e.genDispatchMapEvent,l=e.getAvailableMapEvents();i(h.width)&&(isNaN(h.width)?g.css("width",h.width):g.css("width",h.width+"px")),i(h.height)&&(isNaN(h.height)?g.css("height",h.height):g.css("height",h.height+"px"));var m=new L.Map(g[0],c.getMapCreationDefaults(h.id));if(f.resolve(m),i(h.center)||m.setView([j.center.lat,j.center.lng],j.center.zoom),!i(h.tiles)&&!i(h.layers)){var n=L.tileLayer(j.tileLayer,j.tileLayerOptions);n.addTo(m),b.setTiles(n,h.id)}if(i(m.zoomControl)&&i(j.zoomControlPosition)&&m.zoomControl.setPosition(j.zoomControlPosition),i(m.zoomControl)&&j.zoomControl===!1&&m.zoomControl.removeFrom(m),i(m.zoomsliderControl)&&i(j.zoomsliderControl)&&j.zoomsliderControl===!1&&m.zoomsliderControl.removeFrom(m),!i(h.eventBroadcast))for(var o="broadcast",p=0;pe.center.zoom?{setView:!0,maxZoom:c.zoom}:i(e.maxZoom)?{setView:!0,maxZoom:e.maxZoom}:{setView:!0})):void(s&&k(c,b)||(b.setView([c.lat,c.lng],c.zoom),g.notifyCenterChangedToBounds(q,b))):void a.warn("[AngularJS - Leaflet] invalid 'center'")},!0),b.whenReady(function(){s=!0}),b.on("moveend",function(){h.resolve(),g.notifyCenterUrlHashChanged(q,b,n,c.search()),k(r,b)||l(q,function(a){a.center={lat:b.getCenter().lat,lng:b.getCenter().lng,zoom:b.getZoom(),autoDiscover:!1},g.notifyCenterChangedToBounds(q,b)})}),r.autoDiscover===!0&&b.on("locationerror",function(){a.warn("[AngularJS - Leaflet] The Geolocation API is unauthorized on this page."),m(r)?(b.setView([r.lat,r.lng],r.zoom),g.notifyCenterChangedToBounds(q,b)):(b.setView([e.center.lat,e.center.lng],e.center.zoom),g.notifyCenterChangedToBounds(q,b))})})}}}]),angular.module("leaflet-directive").directive("tiles",["$log","leafletData","leafletMapDefaults","leafletHelpers",function(a,b,c,d){return{restrict:"A",scope:!1,replace:!1,require:"leaflet",link:function(e,f,g,h){var i=d.isDefined,j=h.getLeafletScope(),k=j.tiles;return i(k)||i(k.url)?void h.getMap().then(function(a){var d,e=c.getDefaults(g.id);j.$watch("tiles",function(c){var f=e.tileLayerOptions,h=e.tileLayer;return!i(c.url)&&i(d)?void a.removeLayer(d):i(d)?i(c.url)&&i(c.options)&&!angular.equals(c.options,f)?(a.removeLayer(d),f=e.tileLayerOptions,angular.copy(c.options,f),h=c.url,d=L.tileLayer(h,f),d.addTo(a),void b.setTiles(d,g.id)):void(i(c.url)&&d.setUrl(c.url)):(i(c.options)&&angular.copy(c.options,f),i(c.url)&&(h=c.url),d=L.tileLayer(h,f),d.addTo(a),void b.setTiles(d,g.id))},!0)}):void a.warn("[AngularJS - Leaflet] The 'tiles' definition doesn't have the 'url' property.")}}}]),angular.module("leaflet-directive").directive("legend",["$log","$http","leafletHelpers","leafletLegendHelpers",function(a,b,c,d){return{restrict:"A",scope:!1,replace:!1,require:"leaflet",link:function(e,f,g,h){var i,j=c.isArray,k=c.isDefined,l=c.isFunction,m=h.getLeafletScope(),n=m.legend,o=n.legendClass?n.legendClass:"legend",p=n.position||"bottomright";h.getMap().then(function(c){k(n.url)||j(n.colors)&&j(n.labels)&&n.colors.length===n.labels.length?k(n.url)?a.info("[AngularJS - Leaflet] loading arcgis legend service."):(i=L.control({position:p}),i.onAdd=d.getOnAddArrayLegend(n,o),i.addTo(c)):a.warn("[AngularJS - Leaflet] legend.colors and legend.labels must be set."),m.$watch("legend.url",function(e){k(e)&&b.get(e).success(function(a){k(i)?d.updateArcGISLegend(i.getContainer(),a):(i=L.control({position:p}),i.onAdd=d.getOnAddArcGISLegend(a,o),i.addTo(c)),k(n.loadedData)&&l(n.loadedData)&&n.loadedData()}).error(function(){a.warn("[AngularJS - Leaflet] legend.url not loaded.")})})})}}}]),angular.module("leaflet-directive").directive("geojson",["$log","$rootScope","leafletData","leafletHelpers",function(a,b,c,d){return{restrict:"A",scope:!1,replace:!1,require:"leaflet",link:function(a,e,f,g){var h=d.safeApply,i=d.isDefined,j=g.getLeafletScope(),k={};g.getMap().then(function(a){j.$watch("geojson",function(e){if(i(k)&&a.hasLayer(k)&&a.removeLayer(k),i(e)&&i(e.data)){var f=e.resetStyleOnMouseout,g=e.onEachFeature;g||(g=function(a,c){d.LabelPlugin.isLoaded()&&i(e.label)&&c.bindLabel(a.properties.description),c.on({mouseover:function(c){h(j,function(){e.selected=a,b.$broadcast("leafletDirectiveMap.geojsonMouseover",c)})},mouseout:function(a){f&&k.resetStyle(a.target),h(j,function(){e.selected=void 0,b.$broadcast("leafletDirectiveMap.geojsonMouseout",a)})},click:function(c){h(j,function(){e.selected=a,b.$broadcast("leafletDirectiveMap.geojsonClick",e.selected,c)})}})}),e.options={style:e.style,filter:e.filter,onEachFeature:g,pointToLayer:e.pointToLayer},k=L.geoJson(e.data,e.options),c.setGeoJSON(k),k.addTo(a)}})})}}}]),angular.module("leaflet-directive").directive("layers",["$log","$q","leafletData","leafletHelpers","leafletLayerHelpers","leafletControlHelpers",function(a,b,c,d,e,f){var g;return{restrict:"A",scope:!1,replace:!1,require:"leaflet",controller:function(){g=b.defer(),this.getLayers=function(){return g.promise}},link:function(b,h,i,j){var k=d.isDefined,l={},m=j.getLeafletScope(),n=m.layers,o=e.createLayer,p=f.updateLayersControl,q=!1;j.getMap().then(function(b){if(!k(n)||!k(n.baselayers)||0===Object.keys(n.baselayers).length)return void a.error("[AngularJS - Leaflet] At least one baselayer has to be defined");g.resolve(l),c.setLayers(l,i.id),l.baselayers={},l.overlays={};var d=i.id,e=!1;for(var f in n.baselayers){var h=o(n.baselayers[f]);k(h)?(l.baselayers[f]=h,n.baselayers[f].top===!0&&(b.addLayer(l.baselayers[f]),e=!0)):delete n.baselayers[f]}!e&&Object.keys(l.baselayers).length>0&&b.addLayer(l.baselayers[Object.keys(n.baselayers)[0]]);for(f in n.overlays){var j=o(n.overlays[f]);k(j)?(l.overlays[f]=j,n.overlays[f].visible===!0&&b.addLayer(l.overlays[f])):delete n.overlays[f]}m.$watch("layers.baselayers",function(c){for(var e in l.baselayers)k(c[e])||(b.hasLayer(l.baselayers[e])&&b.removeLayer(l.baselayers[e]),delete l.baselayers[e]);for(var f in c)if(!k(l.baselayers[f])){var g=o(c[f]);k(g)&&(l.baselayers[f]=g,c[f].top===!0&&b.addLayer(l.baselayers[f]))}if(0===Object.keys(l.baselayers).length)return void a.error("[AngularJS - Leaflet] At least one baselayer has to be defined");var h=!1;for(var i in l.baselayers)if(b.hasLayer(l.baselayers[i])){h=!0;break}h||b.addLayer(l.baselayers[Object.keys(n.baselayers)[0]]),q=p(b,d,q,c,n.overlays,l)},!0),m.$watch("layers.overlays",function(a){for(var c in l.overlays)k(a[c])||(b.hasLayer(l.overlays[c])&&b.removeLayer(l.overlays[c]),delete l.overlays[c]);for(var e in a){if(!k(l.overlays[e])){var f=o(a[e]);k(f)&&(l.overlays[e]=f,a[e].visible===!0&&b.addLayer(l.overlays[e]))}a[e].visible&&!b.hasLayer(l.overlays[e])?b.addLayer(l.overlays[e]):a[e].visible===!1&&b.hasLayer(l.overlays[e])&&b.removeLayer(l.overlays[e])}q=p(b,d,q,n.baselayers,a,l)},!0)})}}}]),angular.module("leaflet-directive").directive("bounds",["$log","$timeout","leafletHelpers","leafletBoundsHelpers",function(a,b,c,d){return{restrict:"A",scope:!1,replace:!1,require:["leaflet","center"],link:function(b,e,f,g){var h=c.isDefined,i=d.createLeafletBounds,j=g[0].getLeafletScope(),k=g[0],l=function(a){return 0===a._southWest.lat&&0===a._southWest.lng&&0===a._northEast.lat&&0===a._northEast.lng?!0:!1};k.getMap().then(function(b){j.$on("boundsChanged",function(a){var c=a.currentScope,d=b.getBounds();if(!l(d)){var e={northEast:{lat:d._northEast.lat,lng:d._northEast.lng},southWest:{lat:d._southWest.lat,lng:d._southWest.lng}};angular.equals(c.bounds,e)||(c.bounds=e)}}),j.$watch("bounds",function(c){if(!h(c))return void a.error("[AngularJS - Leaflet] Invalid bounds");var d=i(c);d&&!b.getBounds().equals(d)&&b.fitBounds(d)},!0)})}}}]),angular.module("leaflet-directive").directive("markers",["$log","$rootScope","$q","leafletData","leafletHelpers","leafletMapDefaults","leafletMarkersHelpers","leafletEvents",function(a,b,c,d,e,f,g,h){return{restrict:"A",scope:!1,replace:!1,require:["leaflet","?layers"],link:function(b,f,i,j){var k=j[0],l=e,m=e.isDefined,n=e.isString,o=k.getLeafletScope(),p=o.markers,q=g.deleteMarker,r=g.addMarkerWatcher,s=g.listenMarkerEvents,t=g.addMarkerToGroup,u=h.bindMarkerEvents,v=g.createMarker;k.getMap().then(function(b){var e,f={};e=m(j[1])?j[1].getLayers:function(){var a=c.defer();return a.resolve(),a.promise},m(p)&&e().then(function(c){d.setMarkers(f,i.id),o.$watch("markers",function(d){for(var e in f)m(d)&&m(d[e])||(q(f[e],b,c),delete f[e]);for(var g in d)if(-1===g.search("-")){if(!m(f[g])){var h=d[g],j=v(h);if(!m(j)){a.error("[AngularJS - Leaflet] Received invalid data on the marker "+g+".");continue}if(f[g]=j,m(h.message)&&j.bindPopup(h.message,h.popupOptions),m(h.group)&&t(j,h.group,b),l.LabelPlugin.isLoaded()&&m(h.label)&&m(h.label.message)&&j.bindLabel(h.label.message,h.label.options),m(h)&&m(h.layer)){if(!n(h.layer)){a.error("[AngularJS - Leaflet] A layername must be a string");continue}if(!m(c)){a.error("[AngularJS - Leaflet] You must add layers to the directive if the markers are going to use this functionality.");continue}if(!m(c.overlays)||!m(c.overlays[h.layer])){a.error('[AngularJS - Leaflet] A marker can only be added to a layer of type "group"');continue}var k=c.overlays[h.layer];if(!(k instanceof L.LayerGroup)){a.error('[AngularJS - Leaflet] Adding a marker to an overlay needs a overlay of the type "group"');continue}k.addLayer(j),b.hasLayer(j)&&h.focus===!0&&j.openPopup()}else m(h.group)||(b.addLayer(j),h.focus===!0&&j.openPopup(),l.LabelPlugin.isLoaded()&&m(h.label)&&m(h.label.options)&&h.label.options.noHide===!0&&j.showLabel());var p=!m(i.watchMarkers)||"true"===i.watchMarkers;p&&(r(j,g,o,c,b),s(j,h,o)),u(j,g,h,o)}}else a.error('The marker can\'t use a "-" on his key name: "'+g+'".')},!0)})})}}}]),angular.module("leaflet-directive").directive("paths",["$log","leafletData","leafletMapDefaults","leafletHelpers","leafletPathsHelpers","leafletEvents",function(a,b,c,d,e,f){return{restrict:"A",scope:!1,replace:!1,require:"leaflet",link:function(g,h,i,j){var k=d.isDefined,l=j.getLeafletScope(),m=l.paths,n=e.createPath,o=f.bindPathEvents,p=e.setPathOptions;j.getMap().then(function(e){var f=c.getDefaults(i.id);if(k(m)){var g={};b.setPaths(g,i.id);var h=function(a,b){var c=l.$watch("paths."+b,function(b){return k(b)?void p(a,b.type,b):(e.removeLayer(a),void c())},!0)};l.$watch("paths",function(b){for(var c in b)if(-1===c.search("-")){if(!k(g[c])){var i=b[c],j=n(c,b[c],f);k(j)&&k(i.message)&&j.bindPopup(i.message),d.LabelPlugin.isLoaded()&&k(i.label)&&k(i.label.message)&&j.bindLabel(i.label.message,i.label.options),k(j)&&(g[c]=j,e.addLayer(j),h(j,c)),o(j,c,i,l)}}else a.error('[AngularJS - Leaflet] The path name "'+c+'" is not valid. It must not include "-" and a number.');for(var m in g)k(b[m])||delete g[m]},!0)}})}}}]),angular.module("leaflet-directive").directive("controls",["$log","leafletHelpers",function(a,b){return{restrict:"A",scope:!1,replace:!1,require:"?^leaflet",link:function(a,c,d,e){if(e){var f=b.isDefined,g=e.getLeafletScope(),h=g.controls;e.getMap().then(function(a){if(f(L.Control.Draw)&&f(h.draw)){var b=new L.FeatureGroup;a.addLayer(b);var c={edit:{featureGroup:b}};angular.extend(c,h.draw.options);var d=new L.Control.Draw(c);a.addControl(d)}if(f(h.custom))for(var e in h.custom)a.addControl(h.custom[e])})}}}}]),angular.module("leaflet-directive").directive("eventBroadcast",["$log","$rootScope","leafletHelpers","leafletEvents",function(a,b,c,d){return{restrict:"A",scope:!1,replace:!1,require:"leaflet",link:function(b,e,f,g){var h=c.isObject,i=g.getLeafletScope(),j=i.eventBroadcast,k=d.getAvailableMapEvents(),l=d.genDispatchMapEvent;g.getMap().then(function(b){var c,d,e=[],f="broadcast";if(h(j)){if(void 0===j.map||null===j.map)e=k;else if("object"!=typeof j.map)a.warn("[AngularJS - Leaflet] event-broadcast.map must be an object check your model.");else{void 0!==j.map.logic&&null!==j.map.logic&&("emit"!==j.map.logic&&"broadcast"!==j.map.logic?a.warn("[AngularJS - Leaflet] Available event propagation logic are: 'emit' or 'broadcast'."):"emit"===j.map.logic&&(f="emit"));var g=!1,m=!1;if(void 0!==j.map.enable&&null!==j.map.enable&&"object"==typeof j.map.enable&&(g=!0),void 0!==j.map.disable&&null!==j.map.disable&&"object"==typeof j.map.disable&&(m=!0),g&&m)a.warn("[AngularJS - Leaflet] can not enable and disable events at the time");else if(g||m)if(g)for(c=0;cOpenStreetMap contributors'},path:{weight:10,opacity:1,color:"#0000ff"},center:{lat:0,lng:0,zoom:1}}}var d=b.isDefined,e=b.obtainEffectiveMapId,f={};return{getDefaults:function(a){var b=e(f,a);return f[b]},getMapCreationDefaults:function(a){var b=e(f,a),c=f[b],g={maxZoom:c.maxZoom,keyboard:c.keyboard,dragging:c.dragging,zoomControl:c.zoomControl,doubleClickZoom:c.doubleClickZoom,scrollWheelZoom:c.scrollWheelZoom,attributionControl:c.attributionControl,worldCopyJump:c.worldCopyJump,crs:c.crs};if(d(c.minZoom)&&(g.minZoom=c.minZoom),d(c.zoomAnimation)&&(g.zoomAnimation=c.zoomAnimation),d(c.fadeAnimation)&&(g.fadeAnimation=c.fadeAnimation),d(c.markerZoomAnimation)&&(g.markerZoomAnimation=c.markerZoomAnimation),c.map)for(var h in c.map)g[h]=c.map[h];return g},setDefaults:function(a,b){var g=c();d(a)&&(g.doubleClickZoom=d(a.doubleClickZoom)?a.doubleClickZoom:g.doubleClickZoom,g.scrollWheelZoom=d(a.scrollWheelZoom)?a.scrollWheelZoom:g.doubleClickZoom,g.zoomControl=d(a.zoomControl)?a.zoomControl:g.zoomControl,g.zoomsliderControl=d(a.zoomsliderControl)?a.zoomsliderControl:g.zoomsliderControl,g.attributionControl=d(a.attributionControl)?a.attributionControl:g.attributionControl,g.tileLayer=d(a.tileLayer)?a.tileLayer:g.tileLayer,g.zoomControlPosition=d(a.zoomControlPosition)?a.zoomControlPosition:g.zoomControlPosition,g.keyboard=d(a.keyboard)?a.keyboard:g.keyboard,g.dragging=d(a.dragging)?a.dragging:g.dragging,d(a.controls)&&angular.extend(g.controls,a.controls),d(a.crs)&&d(L.CRS[a.crs])&&(g.crs=L.CRS[a.crs]),d(a.tileLayerOptions)&&angular.copy(a.tileLayerOptions,g.tileLayerOptions),d(a.maxZoom)&&(g.maxZoom=a.maxZoom),d(a.minZoom)&&(g.minZoom=a.minZoom),d(a.zoomAnimation)&&(g.zoomAnimation=a.zoomAnimation),d(a.fadeAnimation)&&(g.fadeAnimation=a.fadeAnimation),d(a.markerZoomAnimation)&&(g.markerZoomAnimation=a.markerZoomAnimation),d(a.worldCopyJump)&&(g.worldCopyJump=a.worldCopyJump),d(a.map)&&(g.map=a.map));var h=e(f,b);return f[h]=g,g}}}]),angular.module("leaflet-directive").factory("leafletEvents",["$rootScope","$q","$log","leafletHelpers",function(a,b,c,d){var e=d.safeApply,f=d.isDefined,g=d.isObject,h=d,i=function(){return["click","dblclick","mousedown","mouseover","mouseout","contextmenu"]},j=function(a,b,c,d){for(var e=i(),f="markers."+d,g=0;g1},i=function(a){var b,c=d.getDefaults(a),e={collapsed:c.controls.layers.collapsed,position:c.controls.layers.position};return b=c.controls.layers&&g(c.controls.layers.control)?c.controls.layers.control.apply(this,[[],[],e]):new L.control.layers([],[],e)};return{layersControlMustBeVisible:h,updateLayersControl:function(a,b,c,d,f,j){var k,l=h(d,f);if(g(e)&&c){for(k in j.baselayers)e.removeLayer(j.baselayers[k]);for(k in j.overlays)e.removeLayer(j.overlays[k]);e.removeFrom(a)}if(l){e=i(b);for(k in d)g(j.baselayers[k])&&e.addBaseLayer(j.baselayers[k],d[k].name);for(k in f)g(j.overlays[k])&&e.addOverlay(j.overlays[k],f[k].name);e.addTo(a)}return l}}}]),angular.module("leaflet-directive").factory("leafletLegendHelpers",function(){var a=function(a,b){if(a.innerHTML="",b.error)a.innerHTML+=''+b.error.message+"
";else for(var c=0;c'+d.layerName+"";for(var e=0;e'+f.label+"
"}}},b=function(b,c){return function(){var d=L.DomUtil.create("div",c);return L.Browser.touch?L.DomEvent.on(d,"click",L.DomEvent.stopPropagation):(L.DomEvent.disableClickPropagation(d),L.DomEvent.on(d,"mousewheel",L.DomEvent.stopPropagation)),a(d,b),d}},c=function(a,b){return function(){for(var c=L.DomUtil.create("div",b),d=0;d'+a.labels[d]+"
";return L.Browser.touch?L.DomEvent.on(c,"click",L.DomEvent.stopPropagation):(L.DomEvent.disableClickPropagation(c),L.DomEvent.on(c,"mousewheel",L.DomEvent.stopPropagation)),c}};return{getOnAddArcGISLegend:b,getOnAddArrayLegend:c,updateArcGISLegend:a}}),angular.module("leaflet-directive").factory("leafletPathsHelpers",["$rootScope","$log","leafletHelpers",function(a,b,c){function d(a){return a.filter(function(a){return k(a)}).map(function(a){return new L.LatLng(a.lat,a.lng)})}function e(a){return new L.LatLng(a.lat,a.lng)}function f(a){return a.map(function(a){return d(a)})}function g(a,b){for(var c=["stroke","weight","color","opacity","fill","fillColor","fillOpacity","dashArray","lineCap","lineJoin","clickable","pointerEvents","className","smoothFactor","noClip"],d={},e=0;e